-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApp.tsx
More file actions
119 lines (108 loc) · 3.61 KB
/
App.tsx
File metadata and controls
119 lines (108 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { Component, createSignal, onMount, onCleanup, Switch, Match, For } from 'solid-js';
import { Layout } from './components/Layout';
import { CreatePaste } from './components/CreatePaste';
import { ViewPaste } from './components/ViewPaste';
import { AboutPage } from './components/AboutPage';
const App: Component = () => {
const [route, setRoute] = createSignal<'create' | 'view' | 'about'>('create');
const [viewParams, setViewParams] = createSignal<{ id: string; key: string | null } | null>(null);
const [createKey, setCreateKey] = createSignal(0);
const [forkData, setForkData] = createSignal<{ content: string; language: string } | null>(null);
// Safe hash parsing that won't crash if location is restricted
const parseHash = () => {
try {
const hash = window.location.hash;
if (hash.startsWith('#view/')) {
const content = hash.replace('#view/', '');
const [id, keyPart] = content.split('&key=');
const key = keyPart ? decodeURIComponent(keyPart) : null;
return { route: 'view' as const, params: { id, key } };
} else if (hash === '#about') {
return { route: 'about' as const, params: null };
}
} catch (e) {
// Fallback or ignore if location access is denied
}
return { route: 'create' as const, params: null };
};
const handleHashChange = () => {
const { route: newRoute, params } = parseHash();
setRoute(newRoute);
setViewParams(params);
};
onMount(() => {
window.addEventListener('hashchange', handleHashChange);
// Initial sync
handleHashChange();
});
onCleanup(() => {
window.removeEventListener('hashchange', handleHashChange);
});
const handleNavigate = (dest: string) => {
if (dest === 'create') {
setRoute('create');
setViewParams(null);
setForkData(null);
setCreateKey(prev => prev + 1);
// Attempt to clear URL hash, but gracefully fail if blocked by sandbox
try {
if (window.location.hash !== '') {
window.location.hash = '';
}
} catch (e) {
console.warn('Navigation hash update blocked:', e);
}
} else if (dest === 'about') {
setRoute('about');
setViewParams(null);
try {
if (window.location.hash !== '#about') {
window.location.hash = '#about';
}
} catch (e) {
console.warn('Navigation hash update blocked:', e);
}
}
};
const handleFork = (content: string, language: string) => {
setForkData({ content, language });
setRoute('create');
setViewParams(null);
setCreateKey(prev => prev + 1);
try {
if (window.location.hash !== '') {
window.location.hash = '';
}
} catch (e) {
console.warn('Navigation hash update blocked:', e);
}
};
return (
<Layout onNavigate={handleNavigate}>
<Switch>
<Match when={route() === 'create'}>
<div class="max-w-4xl mx-auto">
{/* Force remount when createKey changes using For */}
<For each={[createKey()]}>
{() => <CreatePaste initialData={forkData()} />}
</For>
</div>
</Match>
<Match when={route() === 'view' && viewParams()}>
<div class="max-w-5xl mx-auto">
<ViewPaste
pasteId={viewParams()!.id}
decryptionKey={viewParams()!.key}
onBack={() => handleNavigate('create')}
onFork={handleFork}
/>
</div>
</Match>
<Match when={route() === 'about'}>
<AboutPage />
</Match>
</Switch>
</Layout>
);
};
export default App;