@@ -3,22 +3,14 @@ import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
3
3
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker' ;
4
4
import CompilerWorker from '../../src/workers/compiler?worker' ;
5
5
import FormatterWorker from '../../src/workers/formatter?worker' ;
6
- import {
7
- batch ,
8
- createEffect ,
9
- createResource ,
10
- createSignal ,
11
- lazy ,
12
- onCleanup ,
13
- onMount ,
14
- ParentComponent ,
15
- Suspense ,
16
- } from 'solid-js' ;
6
+ import { batch , createEffect , createResource , createSignal , lazy , Suspense } from 'solid-js' ;
17
7
import { useParams } from 'solid-app-router' ;
18
8
import { API , useAppContext } from '../context' ;
19
9
import { debounce } from '@solid-primitives/scheduled' ;
20
- import { createTabList , Tab } from '../../src' ;
10
+ import { createTabList , defaultTabs , Tab } from '../../src' ;
21
11
import type { APIRepl } from './home' ;
12
+ import { Header } from '../components/header' ;
13
+ import { compressToURL } from '@amoutonbrady/lz-string' ;
22
14
23
15
const Repl = lazy ( ( ) => import ( '../../src/components/repl' ) ) ;
24
16
@@ -36,22 +28,7 @@ const Repl = lazy(() => import('../../src/components/repl'));
36
28
} ,
37
29
} ;
38
30
39
- const RenderHeader : ParentComponent = ( props ) => {
40
- onMount ( ( ) => {
41
- const projectName = document . getElementById ( 'project-name' ) ! ;
42
- const content = projectName . firstChild ! ;
43
- content . remove ( ) ;
44
- const children = props . children as HTMLElement ;
45
- projectName . appendChild ( children ) ;
46
- onCleanup ( ( ) => {
47
- projectName . appendChild ( content ) ;
48
- projectName . removeChild ( children ) ;
49
- } ) ;
50
- } ) ;
51
- return < > </ > ;
52
- } ;
53
-
54
- export const Edit = ( props : { horizontal : boolean } ) => {
31
+ export const Edit = ( props : { horizontal : boolean ; scratchpad ?: boolean } ) => {
55
32
const compiler = new CompilerWorker ( ) ;
56
33
const formatter = new FormatterWorker ( ) ;
57
34
@@ -63,10 +40,30 @@ export const Edit = (props: { horizontal: boolean }) => {
63
40
const [ tabs , setTabs ] = createTabList ( [ ] ) ;
64
41
context . setTabs ( tabs ) ;
65
42
const [ current , setCurrent ] = createSignal < string > ( ) ;
66
- const [ resource , { mutate } ] = createResource < APIRepl , string > ( params . repl , async ( repl ) => {
43
+ const [ resource , { mutate } ] = createResource < APIRepl , string > ( async ( ) => {
44
+ const repl = params . repl ;
45
+
67
46
let output : APIRepl ;
68
- if ( params . user == 'local' ) {
69
- output = JSON . parse ( localStorage . getItem ( repl ) ! ) ;
47
+ if ( props . scratchpad ) {
48
+ const scratchpad = localStorage . getItem ( 'scratchpad' ) ;
49
+ if ( ! scratchpad ) {
50
+ output = {
51
+ id : 'scratchpad' ,
52
+ title : 'Scratchpad' ,
53
+ public : true ,
54
+ version : '1.0' ,
55
+ labels : [ ] ,
56
+ size : 0 ,
57
+ created_at : new Date ( ) . toISOString ( ) ,
58
+ files : defaultTabs . map ( ( x ) => ( {
59
+ name : x . name ,
60
+ content : x . source . split ( '\n' ) ,
61
+ } ) ) ,
62
+ } ;
63
+ localStorage . setItem ( 'scratchpad' , JSON . stringify ( output ) ) ;
64
+ } else {
65
+ output = JSON . parse ( scratchpad ) ;
66
+ }
70
67
} else {
71
68
output = await fetch ( `${ API } /repl/${ repl } ` , {
72
69
headers : { authorization : context . token ? `Bearer ${ context . token } ` : '' } ,
@@ -91,20 +88,13 @@ export const Edit = (props: { horizontal: boolean }) => {
91
88
( ) => {
92
89
const repl = resource . latest ;
93
90
if ( ! repl ) return ;
91
+
94
92
const files = tabMapper ( tabs ( ) ) ;
95
- if ( params . user == 'local' ) {
96
- localStorage . setItem (
97
- params . repl ,
98
- JSON . stringify ( {
99
- title : repl . title ,
100
- version : repl . version ,
101
- public : repl . public ,
102
- labels : repl . labels ,
103
- files,
104
- } ) ,
105
- ) ;
93
+ if ( props . scratchpad ) {
94
+ localStorage . setItem ( 'scratchpad' , JSON . stringify ( { ...repl , files } ) ) ;
106
95
return ;
107
96
}
97
+
108
98
if ( ! context . token || context . user ( ) ?. display != params . user ) return ;
109
99
fetch ( `${ API } /repl/${ params . repl } ` , {
110
100
method : 'PUT' ,
@@ -131,43 +121,76 @@ export const Edit = (props: { horizontal: boolean }) => {
131
121
} ) ;
132
122
133
123
return (
134
- < Suspense
135
- fallback = {
136
- < svg
137
- class = "animate-spin h-12 w-12 text-white m-auto"
138
- xmlns = "http://www.w3.org/2000/svg"
139
- fill = "none"
140
- viewBox = "0 0 24 24"
141
- >
142
- < circle class = "opacity-25" cx = "12" cy = "12" r = "10" stroke = "currentColor" stroke-width = "4" > </ circle >
143
- < path
144
- class = "opacity-75"
145
- fill = "currentColor"
146
- d = "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
147
- > </ path >
148
- </ svg >
149
- }
150
- >
151
- < Repl
152
- compiler = { compiler }
153
- formatter = { formatter }
154
- isHorizontal = { props . horizontal }
155
- dark = { context . dark ( ) }
156
- tabs = { tabs ( ) }
157
- setTabs = { setTabs }
158
- current = { current ( ) }
159
- setCurrent = { setCurrent }
160
- id = "repl"
161
- />
162
- < RenderHeader >
163
- < input
164
- class = "bg-transparent"
165
- value = { resource ( ) ?. title || '' }
166
- onChange = { ( e ) => {
167
- mutate ( ( x ) => x && { ...x , title : e . currentTarget . value } ) ;
168
- } }
124
+ < >
125
+ < Header
126
+ fork = { ( ) => { } }
127
+ share = { ( ) => {
128
+ if ( props . scratchpad ) {
129
+ let url = new URL ( location . origin ) ;
130
+ url . hash = compressToURL ( JSON . stringify ( context . tabs ( ) ) ) ;
131
+ console . log ( 'Shareable url:' , url . href ) ;
132
+
133
+ return fetch ( '/' , { method : 'PUT' , body : `{"url":"${ url . href } "}` } )
134
+ . then ( ( response ) => {
135
+ if ( response . status >= 400 ) {
136
+ throw new Error ( response . statusText ) ;
137
+ }
138
+
139
+ return response . text ( ) ;
140
+ } )
141
+ . then ( ( hash ) => {
142
+ const tinyUrl = new URL ( location . origin ) ;
143
+ tinyUrl . searchParams . set ( 'hash' , hash ) ;
144
+
145
+ return tinyUrl . toString ( ) ;
146
+ } )
147
+ . catch ( ( ) => {
148
+ return url . href ;
149
+ } ) ;
150
+ } else {
151
+ return Promise . resolve ( location . href ) ;
152
+ }
153
+ } }
154
+ >
155
+ { resource ( ) ?. title && (
156
+ < input
157
+ class = "bg-transparent"
158
+ value = { resource ( ) ?. title }
159
+ onChange = { ( e ) => {
160
+ mutate ( ( x ) => x && { ...x , title : e . currentTarget . value } ) ;
161
+ } }
162
+ />
163
+ ) }
164
+ </ Header >
165
+ < Suspense
166
+ fallback = {
167
+ < svg
168
+ class = "animate-spin h-12 w-12 text-white m-auto"
169
+ xmlns = "http://www.w3.org/2000/svg"
170
+ fill = "none"
171
+ viewBox = "0 0 24 24"
172
+ >
173
+ < circle class = "opacity-25" cx = "12" cy = "12" r = "10" stroke = "currentColor" stroke-width = "4" > </ circle >
174
+ < path
175
+ class = "opacity-75"
176
+ fill = "currentColor"
177
+ d = "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
178
+ > </ path >
179
+ </ svg >
180
+ }
181
+ >
182
+ < Repl
183
+ compiler = { compiler }
184
+ formatter = { formatter }
185
+ isHorizontal = { props . horizontal }
186
+ dark = { context . dark ( ) }
187
+ tabs = { tabs ( ) }
188
+ setTabs = { setTabs }
189
+ current = { current ( ) }
190
+ setCurrent = { setCurrent }
191
+ id = "repl"
169
192
/>
170
- </ RenderHeader >
171
- </ Suspense >
193
+ </ Suspense >
194
+ </ >
172
195
) ;
173
196
} ;
0 commit comments