Skip to content

Commit b0423ca

Browse files
committed
appcontext
1 parent d67ceac commit b0423ca

File tree

10 files changed

+163
-181
lines changed

10 files changed

+163
-181
lines changed

playground/app.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import { Show, onCleanup, createEffect, createSignal, JSX } from 'solid-js';
2-
32
import { Routes, Route } from 'solid-app-router';
43
import { eventBus } from './utils/eventBus';
5-
64
import { Update } from './components/update';
75
import { Header } from './components/header';
8-
96
import { useZoom } from '../src/hooks/useZoom';
107
import { isDarkTheme } from './utils/isDarkTheme';
11-
import { Edit } from './edit';
12-
import { Home } from './home';
8+
import { Edit } from './pages/edit';
9+
import { Home } from './pages/home';
10+
import { Login } from './pages/login';
1311

1412
let swUpdatedBeforeRender = false;
1513
eventBus.on('sw-update', () => (swUpdatedBeforeRender = true));
@@ -58,6 +56,7 @@ export const App = (): JSX.Element => {
5856
<Route path="/:user/:repl" element={<Edit dark={dark()} />} />
5957
<Route path="/:id" element={<Home />} />
6058
<Route path="/" element={<Home />} />
59+
<Route path="/login" element={<Login />} />
6160
</Routes>
6261

6362
<Show when={newUpdate()} children={<Update onDismiss={() => setNewUpdate(false)} />} />

playground/components/header.tsx

Lines changed: 13 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import Dismiss from 'solid-dismiss';
22
import { Icon } from 'solid-heroicons';
3-
import { compressToURL as encode } from '@amoutonbrady/lz-string';
43
import { Component, onCleanup, createSignal, Show } from 'solid-js';
5-
import { share, link, download, xCircle, menu, moon, sun } from 'solid-heroicons/outline';
4+
import { download, xCircle, menu, moon, sun } from 'solid-heroicons/outline';
65

76
import logo from '../assets/logo.svg?url';
87
import type { Tab } from '../../src';
98
import { exportToZip } from '../utils/exportFiles';
109
import { ZoomDropdown } from './zoomDropdown';
10+
import { useAppContext } from '../context';
1111

1212
export const Header: Component<{
1313
dark: boolean;
1414
toggleDark: () => void;
1515
tabs: Tab[];
1616
}> = (props) => {
17-
const [copy, setCopy] = createSignal(false);
17+
const context = useAppContext()!;
1818
const [showMenu, setShowMenu] = createSignal(false);
1919
let menuBtnEl!: HTMLButtonElement;
2020

@@ -27,37 +27,6 @@ export const Header: Component<{
2727
setShowMenu(false);
2828
}
2929

30-
function shareLink() {
31-
const url = new URL(location.href);
32-
33-
url.hash = encode(JSON.stringify(props.tabs));
34-
history.replaceState(null, '', url.toString());
35-
36-
fetch('/', { method: 'PUT', body: `{"url":"${url.href}"}` })
37-
.then((response) => {
38-
if (response.status >= 400) {
39-
throw new Error(response.statusText);
40-
}
41-
42-
return response.text();
43-
})
44-
.then((hash) => {
45-
const tinyUrl = new URL(location.origin);
46-
tinyUrl.searchParams.set('hash', hash);
47-
48-
navigator.clipboard.writeText(tinyUrl.toString()).then(() => {
49-
setCopy(true);
50-
setTimeout(setCopy, 750, false);
51-
});
52-
})
53-
.catch(() => {
54-
navigator.clipboard.writeText(url.href).then(() => {
55-
setCopy(true);
56-
setTimeout(setCopy, 750, false);
57-
});
58-
});
59-
}
60-
6130
return (
6231
<header class="p-1 flex text-sm justify-between items-center border-slate-200 dark:border-neutral-800 border-b-2px">
6332
<h1 class="flex items-center space-x-4 uppercase leading-0 tracking-widest pl-1">
@@ -112,21 +81,6 @@ export const Header: Component<{
11281
<Icon path={download} class="h-6" style={{ margin: '0' }} />
11382
<span class="text-xs md:sr-only">Export to Zip</span>
11483
</button>
115-
<button
116-
type="button"
117-
onClick={shareLink}
118-
class="flex flex-row space-x-2 items-center md:px-1 px-2 py-2 focus:outline-none focus:ring-1 rounded"
119-
classList={{
120-
'opacity-80 hover:opacity-100': !copy(),
121-
'text-green-100': copy() && !showMenu(),
122-
'rounded-none active:bg-gray-300 hover:bg-gray-300 dark:hover:text-black focus:outline-none focus:highlight-none active:highlight-none focus:ring-0 active:outline-none':
123-
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>
13084
<ZoomDropdown showMenu={showMenu()} />
13185
</div>
13286
</Dismiss>
@@ -146,7 +100,16 @@ export const Header: Component<{
146100
<span class="sr-only">Show menu</span>
147101
</button>
148102
<div class="mx-5 -mb-1 leading-snug cursor-pointer">
149-
<a href={`https://api.solidjs.com/auth/login?redirect=${window.location.origin}/login?auth=success`}>Login</a>
103+
<Show
104+
when={context.user()?.display}
105+
fallback={
106+
<a href={`https://api.solidjs.com/auth/login?redirect=${window.location.origin}/login?auth=success`}>
107+
Login
108+
</a>
109+
}
110+
>
111+
{(x) => x}
112+
</Show>
150113
</div>
151114
</div>
152115
</header>

playground/components/zoomDropdown.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,12 @@ export const ZoomDropdown: Component<{ showMenu: boolean }> = (props) => {
6565
createEffect(() => {
6666
if (!open()) {
6767
if (containerEl) {
68-
containerEl.removeEventListener('mousemove', onMouseMove);
68+
containerEl.removeEventListener('mouseenter', onMouseMove);
6969
}
7070
stealFocus = true;
7171
} else {
7272
if (containerEl) {
73-
containerEl.addEventListener('mousemove', onMouseMove, { once: true });
73+
containerEl.addEventListener('mouseenter', onMouseMove, { once: true });
7474
}
7575
}
7676
});

playground/context.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { createContext, createResource, createSignal, ParentComponent, Resource, useContext } from 'solid-js';
2+
3+
interface AppContextType {
4+
token: string;
5+
user: Resource<{ display: any; avatar: any } | undefined>;
6+
}
7+
8+
const AppContext = createContext<AppContextType>();
9+
10+
// const API = "http://localhost:8787";
11+
export const API = 'https://api.solidjs.com';
12+
13+
export const AppContextProvider: ParentComponent = (props) => {
14+
const [token, setToken] = createSignal(localStorage.getItem('token') || '');
15+
const [user] = createResource(token, async (token) => {
16+
if (!token)
17+
return {
18+
display: '',
19+
avatar: '',
20+
};
21+
const result = await fetch(`${API}/profile`, {
22+
headers: {
23+
authorization: `Bearer ${token}`,
24+
},
25+
});
26+
const body = await result.json();
27+
return {
28+
display: body.display,
29+
avatar: body.avatar,
30+
};
31+
});
32+
return (
33+
<AppContext.Provider
34+
value={{
35+
get token() {
36+
return token();
37+
},
38+
set token(x) {
39+
setToken(x);
40+
localStorage.setItem('token', x);
41+
},
42+
user,
43+
}}
44+
>
45+
{props.children}
46+
</AppContext.Provider>
47+
);
48+
};
49+
50+
export const useAppContext = () => useContext(AppContext);

playground/home.tsx

Lines changed: 0 additions & 35 deletions
This file was deleted.

playground/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { Router } from 'solid-app-router';
22
import { render } from 'solid-js/web';
33
import { App } from './app';
4+
import { AppContextProvider } from './context';
45
import { registerServiceWorker } from './utils/serviceWorker';
56

67
render(
78
() => (
89
<Router>
9-
<App />
10+
<AppContextProvider>
11+
<App />
12+
</AppContextProvider>
1013
</Router>
1114
),
1215
document.querySelector('#app')!,

playground/edit.tsx renamed to playground/pages/edit.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
22
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
33
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
4-
import { parseHash } from './utils/parseHash';
5-
import { isValidUrl } from './utils/isValidUrl';
4+
import { parseHash } from '../utils/parseHash';
5+
import { isValidUrl } from '../utils/isValidUrl';
66

7-
import CompilerWorker from '../src/workers/compiler?worker';
8-
import FormatterWorker from '../src/workers/formatter?worker';
9-
import { exportToJSON } from './utils/exportFiles';
10-
import { createTabList, defaultTabs, processImport, Repl, Tab } from '../src';
7+
import CompilerWorker from '../../src/workers/compiler?worker';
8+
import FormatterWorker from '../../src/workers/formatter?worker';
9+
import { createTabList, defaultTabs, processImport, Repl, Tab } from '../../src';
1110
import { createSignal } from 'solid-js';
1211

1312
(window as any).MonacoEnvironment = {
@@ -45,10 +44,6 @@ export const Edit = (props: { dark: boolean }) => {
4544

4645
const isHorizontal = 'isHorizontal' in params;
4746

48-
if (params.format === 'json') {
49-
exportToJSON(tabs());
50-
}
51-
5247
return (
5348
<Repl
5449
compiler={compiler}

playground/pages/home.tsx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { useRouteData } from 'solid-app-router';
2+
import { Icon } from 'solid-heroicons';
3+
import { eye, eyeOff, plus, x } from 'solid-heroicons/outline';
4+
import { createResource, For } from 'solid-js';
5+
import { API, useAppContext } from '../context';
6+
7+
interface Repls {
8+
total: number;
9+
list: {
10+
id: string;
11+
title: string;
12+
labels: string[];
13+
files: unknown;
14+
version: string;
15+
public: boolean;
16+
size: number;
17+
created_at: string;
18+
updated_at?: string;
19+
}[];
20+
}
21+
22+
export const Home = () => {
23+
const user = useRouteData();
24+
const context = useAppContext()!;
25+
26+
const [repls] = createResource(
27+
() => user || context.user()?.display,
28+
async (user) => {
29+
if (!user) return { total: 0, list: [] };
30+
const result = await fetch(`${API}/repls/${user}/list`);
31+
return (await result.json()) as Repls;
32+
},
33+
);
34+
35+
return (
36+
<div class="bg-brand-other h-full m-8">
37+
<button class="bg-solid-lightgray shadow-md dark:bg-solid-darkLighterBg rounded-xl p-4 text-3xl flex mx-auto" onClick={
38+
() => {
39+
fetch(`${API}/repls`, {
40+
method: "POST",
41+
})
42+
}
43+
}>
44+
<Icon path={plus} class="w-8" /> Create new REPL
45+
</button>
46+
47+
<table class="w-128 mx-auto my-8">
48+
<thead>
49+
<tr class="border-b border-neutral-600">
50+
<td>Title</td>
51+
<td>Edited</td>
52+
<td>Options</td>
53+
</tr>
54+
</thead>
55+
<tbody>
56+
<For each={repls()?.list}>
57+
{(repl) => (
58+
<tr>
59+
<td>{repl.title}</td>
60+
<td>{repl.created_at}</td>
61+
<td>
62+
<Icon path={repl.public ? eye : eyeOff} class="w-6 inline m-2 ml-0" />
63+
<Icon path={x} class="w-6 inline m-2 mr-0 text-red-700" />
64+
</td>
65+
</tr>
66+
)}
67+
</For>
68+
</tbody>
69+
</table>
70+
</div>
71+
);
72+
};

playground/pages/login.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Navigate, useSearchParams } from 'solid-app-router';
2+
import { useAppContext } from '../context';
3+
4+
export const Login = () => {
5+
const [params] = useSearchParams();
6+
const context = useAppContext()!;
7+
context.token = params.token;
8+
return <Navigate href="/" />;
9+
};

0 commit comments

Comments
 (0)