Skip to content

Commit ad73d81

Browse files
committed
more tweaks
1 parent 9cbbaf4 commit ad73d81

File tree

7 files changed

+1181
-903
lines changed

7 files changed

+1181
-903
lines changed

package.json

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
"tsc": "tsc"
2424
},
2525
"devDependencies": {
26-
"@babel/core": "^7.18.5",
27-
"@babel/plugin-syntax-jsx": "^7.17.12",
28-
"@babel/types": "^7.18.4",
26+
"@babel/core": "^7.18.6",
27+
"@babel/plugin-syntax-jsx": "^7.18.6",
28+
"@babel/types": "^7.18.7",
2929
"@rollup/plugin-babel": "^5.3.1",
30-
"@rollup/plugin-commonjs": "^22.0.0",
30+
"@rollup/plugin-commonjs": "^22.0.1",
3131
"@rollup/plugin-json": "^4.1.0",
3232
"@rollup/plugin-node-resolve": "^13.3.0",
3333
"@rollup/plugin-replace": "^4.0.0",
@@ -39,37 +39,39 @@
3939
"acorn-jsx": "^5.3.2",
4040
"assert": "^2.0.0",
4141
"fs-extra": "^10.1.0",
42-
"jiti": "^1.13.0",
42+
"jiti": "^1.14.0",
4343
"mime": "^3.0.0",
4444
"monaco-editor": "~0.33.0",
4545
"register-service-worker": "^1.7.2",
4646
"rollup-plugin-delete": "^2.0.0",
4747
"rollup-plugin-import-css": "^3.0.3",
48-
"rollup-plugin-windicss": "^1.8.4",
49-
"solid-app-router": "^0.3.3",
50-
"typescript": "^4.7.3",
51-
"vite": "^2.9.12",
48+
"rollup-plugin-windicss": "^1.8.5",
49+
"solid-app-router": "^0.4.1",
50+
"typescript": "^4.7.4",
51+
"vite": "^2.9.13",
5252
"vite-plugin-solid": "^2.2.6",
53-
"vite-plugin-windicss": "^1.8.4",
54-
"windicss": "^3.5.4",
53+
"vite-plugin-windicss": "^1.8.5",
54+
"windicss": "^3.5.5",
5555
"workbox-cli": "^6.5.3"
5656
},
5757
"dependencies": {
5858
"@amoutonbrady/lz-string": "^0.0.1",
59-
"@babel/preset-typescript": "^7.17.12",
60-
"@babel/standalone": "^7.18.5",
61-
"@solid-primitives/media": "^1.3.0",
59+
"@babel/preset-typescript": "^7.18.6",
60+
"@babel/standalone": "^7.18.7",
61+
"@solid-primitives/media": "^2.0.0",
6262
"@solid-primitives/scheduled": "^1.0.0",
63-
"babel-preset-solid": "1.4.4",
63+
"babel-preset-solid": "1.4.5",
6464
"dedent": "^0.7.0",
6565
"jszip": "^3.10.0",
6666
"monaco-editor-textmate": "^3.0.0",
6767
"monaco-textmate": "^3.0.1",
6868
"onigasm": "^2.2.5",
69-
"prettier": "^2.7.0",
70-
"rollup": "^2.75.6",
69+
"prettier": "^2.7.1",
70+
"rollup": "^2.75.7",
7171
"solid-dismiss": "^1.2.1",
7272
"solid-heroicons": "^2.0.3",
73-
"solid-js": "1.4.4"
73+
"solid-js": "1.4.5",
74+
"y-webrtc": "^10.2.3",
75+
"yjs": "^13.5.39"
7476
}
7577
}

playground/app.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { Show, createEffect, createSignal, JSX, on } from 'solid-js';
1+
import { Show, createSignal, JSX, on } from 'solid-js';
22
import { Routes, Route, useSearchParams } from 'solid-app-router';
33
import { eventBus } from './utils/serviceWorker';
44
import { Update } from './components/update';
55
import { Header } from './components/header';
66
import { useZoom } from '../src/hooks/useZoom';
7-
import { isDarkTheme } from './utils/isDarkTheme';
87
import { Edit } from './pages/edit';
98
import { Home } from './pages/home';
109
import { Login } from './pages/login';
@@ -19,9 +18,6 @@ export const App = (): JSX.Element => {
1918
const [newUpdate, setNewUpdate] = createSignal(eventBus() != undefined);
2019
on(eventBus, () => setNewUpdate(true));
2120

22-
const [dark, setDark] = createSignal(isDarkTheme());
23-
createEffect(() => document.body.classList.toggle('dark', dark()));
24-
2521
const { zoomState, updateZoom } = useZoom();
2622
document.addEventListener('keydown', (e) => {
2723
if (!zoomState.overrideNative) return;

playground/components/header.tsx

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,50 @@
11
import Dismiss from 'solid-dismiss';
22
import { Icon } from 'solid-heroicons';
33
import { Component, onCleanup, createSignal, Show } from 'solid-js';
4-
import { download, xCircle, menu, moon, sun } from 'solid-heroicons/outline';
4+
import { share, link, download, xCircle, menu, moon, sun } from 'solid-heroicons/outline';
55
import { exportToZip } from '../utils/exportFiles';
66
import { ZoomDropdown } from './zoomDropdown';
77
import { API, useAppContext } from '../context';
8+
import { compressToURL } from '@amoutonbrady/lz-string';
9+
810
import logo from '../assets/logo.svg?url';
911

10-
export const Header: Component<{
11-
dark: boolean;
12-
toggleDark: () => void;
13-
}> = (props) => {
12+
export const Header: Component = () => {
13+
const [copy, setCopy] = createSignal(false);
1414
const context = useAppContext()!;
1515
const [showMenu, setShowMenu] = createSignal(false);
1616
let menuBtnEl!: HTMLButtonElement;
1717

18+
function shareLink() {
19+
let url = new URL(location.origin);
20+
url.hash = compressToURL(JSON.stringify(context.tabs()));
21+
console.log('Shareable url:', url.href);
22+
23+
fetch('/', { method: 'PUT', body: `{"url":"${url.href}"}` })
24+
.then((response) => {
25+
if (response.status >= 400) {
26+
throw new Error(response.statusText);
27+
}
28+
29+
return response.text();
30+
})
31+
.then((hash) => {
32+
const tinyUrl = new URL(location.origin);
33+
tinyUrl.searchParams.set('hash', hash);
34+
35+
navigator.clipboard.writeText(tinyUrl.toString()).then(() => {
36+
setCopy(true);
37+
setTimeout(setCopy, 750, false);
38+
});
39+
})
40+
.catch(() => {
41+
navigator.clipboard.writeText(url.href).then(() => {
42+
setCopy(true);
43+
setTimeout(setCopy, 750, false);
44+
});
45+
});
46+
}
47+
1848
window.addEventListener('resize', closeMobileMenu);
1949
onCleanup(() => {
2050
window.removeEventListener('resize', closeMobileMenu);
@@ -53,17 +83,17 @@ export const Header: Component<{
5383
>
5484
<button
5585
type="button"
56-
onClick={props.toggleDark}
86+
onClick={context.toggleDark}
5787
class="flex flex-row space-x-2 items-center md:px-1 px-2 py-2 rounded opacity-80 hover:opacity-100"
5888
classList={{
5989
'rounded-none active:bg-gray-300 hover:bg-gray-300 dark:hover:text-black': showMenu(),
6090
}}
6191
title="Toggle dark mode"
6292
>
63-
<Show when={props.dark} fallback={<Icon path={moon} class="h-6" />}>
93+
<Show when={context.dark()} fallback={<Icon path={moon} class="h-6" />}>
6494
<Icon path={sun} class="h-6" />
6595
</Show>
66-
<span class="text-xs md:sr-only">{props.dark ? 'Light' : 'Dark'} mode</span>
96+
<span class="text-xs md:sr-only">{context.dark() ? 'Light' : 'Dark'} mode</span>
6797
</button>
6898

6999
<Show when={context.tabs()}>
@@ -82,6 +112,21 @@ export const Header: Component<{
82112
</Show>
83113

84114
<ZoomDropdown showMenu={showMenu()} />
115+
116+
<button
117+
type="button"
118+
onClick={shareLink}
119+
class="flex flex-row space-x-2 items-center md:px-1 px-2 py-2 rounded"
120+
classList={{
121+
'opacity-80 hover:opacity-100': !copy(),
122+
'text-green-100': copy() && !showMenu(),
123+
'rounded-none active:bg-gray-300 hover:bg-gray-300 dark:hover:text-black': showMenu(),
124+
}}
125+
title="Share with a minified link"
126+
>
127+
<Icon class="h-6" path={copy() ? link : share} />
128+
<span class="text-xs md:sr-only">{copy() ? 'Copied to clipboard' : 'Share'}</span>
129+
</button>
85130
</div>
86131
</Dismiss>
87132
<button

playground/context.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import { Accessor, createContext, createResource, createSignal, ParentComponent, Resource, useContext } from 'solid-js';
22
import type { Tab } from '../src';
3+
import { isDarkTheme } from './utils/isDarkTheme';
34

45
interface AppContextType {
56
token: string;
67
user: Resource<{ display: string; avatar: string } | undefined>;
78
tabs: Accessor<Tab[] | undefined>;
89
setTabs: (x: Accessor<Tab[] | undefined>) => void;
10+
dark: Accessor<boolean>;
11+
toggleDark: () => void;
912
}
1013

1114
const AppContext = createContext<AppContextType>();
@@ -34,6 +37,9 @@ export const AppContextProvider: ParentComponent = (props) => {
3437
};
3538
});
3639

40+
const [dark, setDark] = createSignal(isDarkTheme());
41+
document.body.classList.toggle('dark', dark());
42+
3743
let [hasTabs, setHasTabs] = createSignal(false);
3844
let tabs: Accessor<Tab[] | undefined>;
3945
return (
@@ -55,6 +61,13 @@ export const AppContextProvider: ParentComponent = (props) => {
5561
tabs = x;
5662
setHasTabs(true);
5763
},
64+
dark,
65+
toggleDark() {
66+
let x = !dark();
67+
document.body.classList.toggle('dark', x);
68+
setDark(x);
69+
localStorage.setItem('dark', String(x));
70+
},
5871
}}
5972
>
6073
{props.children}

playground/pages/edit.tsx

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const RenderHeader: ParentComponent = (props) => {
5151
return <></>;
5252
};
5353

54-
export const Edit = (props: { dark: boolean; horizontal: boolean }) => {
54+
export const Edit = (props: { horizontal: boolean }) => {
5555
const compiler = new CompilerWorker();
5656
const formatter = new FormatterWorker();
5757

@@ -87,39 +87,42 @@ export const Edit = (props: { dark: boolean; horizontal: boolean }) => {
8787
});
8888

8989
const tabMapper = (tabs: Tab[]) => tabs.map((x) => ({ name: x.name, content: x.source.split('\n') }));
90-
const updateRepl = debounce(() => {
91-
const repl = resource.latest;
92-
if (!repl) return;
93-
const files = tabMapper(tabs());
94-
if (params.user == 'local') {
95-
localStorage.setItem(
96-
params.repl,
97-
JSON.stringify({
90+
const updateRepl = debounce(
91+
() => {
92+
const repl = resource.latest;
93+
if (!repl) return;
94+
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+
);
106+
return;
107+
}
108+
if (!context.token || context.user()?.display != params.user) return;
109+
fetch(`${API}/repl/${params.repl}`, {
110+
method: 'PUT',
111+
headers: {
112+
'authorization': `Bearer ${context.token}`,
113+
'Content-Type': 'application/json',
114+
},
115+
body: JSON.stringify({
98116
title: repl.title,
99117
version: repl.version,
100118
public: repl.public,
101119
labels: repl.labels,
102120
files,
103121
}),
104-
);
105-
return;
106-
}
107-
if (!context.token || context.user()?.display != params.user) return;
108-
fetch(`${API}/repl/${params.repl}`, {
109-
method: 'PUT',
110-
headers: {
111-
'authorization': `Bearer ${context.token}`,
112-
'Content-Type': 'application/json',
113-
},
114-
body: JSON.stringify({
115-
title: repl.title,
116-
version: repl.version,
117-
public: repl.public,
118-
labels: repl.labels,
119-
files,
120-
}),
121-
});
122-
}, 1000);
122+
});
123+
},
124+
params.user == 'local' ? 10 : 1000,
125+
);
123126

124127
createEffect(() => {
125128
tabMapper(tabs()); // use the latest value on debounce, and just throw this value away (but use it to track)
@@ -149,7 +152,7 @@ export const Edit = (props: { dark: boolean; horizontal: boolean }) => {
149152
compiler={compiler}
150153
formatter={formatter}
151154
isHorizontal={props.horizontal}
152-
dark={props.dark}
155+
dark={context.dark()}
153156
tabs={tabs()}
154157
setTabs={setTabs}
155158
current={current()}

0 commit comments

Comments
 (0)