Skip to content

Commit 149d718

Browse files
committed
fix oversync
1 parent 713189a commit 149d718

File tree

5 files changed

+76
-95
lines changed

5 files changed

+76
-95
lines changed

playground/pages/edit.tsx

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -55,36 +55,7 @@ export const Edit = (props: { horizontal: boolean }) => {
5555
},
5656
set source(source: string) {
5757
this._source = source;
58-
if (readonly()) {
59-
const myScratchpad = localStorage.getItem('scratchpad');
60-
let output: APIRepl;
61-
if (!myScratchpad) {
62-
output = {
63-
id: 'scratchpad',
64-
title: resource.latest?.title + ' - Forked',
65-
public: true,
66-
version: '1.0',
67-
labels: [],
68-
size: 0,
69-
created_at: new Date().toISOString(),
70-
files: tabs()!.map((x) => ({
71-
name: x.name,
72-
content: x.source.split('\n'),
73-
})),
74-
};
75-
} else {
76-
output = JSON.parse(myScratchpad);
77-
output.files = tabs()!.map((x) => ({
78-
name: x.name,
79-
content: x.source.split('\n'),
80-
}));
81-
}
82-
localStorage.setItem('scratchpad', JSON.stringify(output));
83-
disableFetch = true;
84-
navigate('/scratchpad');
85-
} else {
86-
updateRepl();
87-
}
58+
updateRepl();
8859
},
8960
};
9061
});
@@ -137,6 +108,21 @@ export const Edit = (props: { horizontal: boolean }) => {
137108

138109
const updateRepl = debounce(
139110
() => {
111+
if (readonly()) {
112+
localStorage.setItem(
113+
'scratchpad',
114+
JSON.stringify({
115+
files: tabs()!.map((x) => ({
116+
name: x.name,
117+
content: x.source.split('\n'),
118+
})),
119+
}),
120+
);
121+
disableFetch = true;
122+
navigate('/scratchpad');
123+
return;
124+
}
125+
140126
const repl = resource.latest;
141127
if (!repl) return;
142128

playground/pages/home.tsx

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useLocation, useNavigate, useParams } from 'solid-app-router';
22
import { Icon } from 'solid-heroicons';
33
import { eye, eyeOff, plus, x } from 'solid-heroicons/outline';
4-
import { createEffect, createResource, For, Suspense } from 'solid-js';
4+
import { createEffect, createResource, For, Show, Suspense } from 'solid-js';
55
import { createStore, produce } from 'solid-js/store';
66
import { defaultTabs } from '../../src';
77
import { API, useAppContext } from '../context';
@@ -68,20 +68,21 @@ export const Home = () => {
6868
const location = useLocation();
6969

7070
createEffect(() => {
71-
if (!location.hash && context.token) return;
72-
73-
const initialTabs = parseHash(location.hash.slice(1), defaultTabs);
74-
75-
localStorage.setItem(
76-
'scratchpad',
77-
JSON.stringify({
78-
files: initialTabs.map((x) => ({
79-
name: x.name + ((x as any).type ? `.${(x as any).type}` : ''),
80-
content: x.source.split('\n'),
81-
})),
82-
}),
83-
);
84-
navigate(`/scratchpad`);
71+
if (location.hash) {
72+
const initialTabs = parseHash(location.hash.slice(1), defaultTabs);
73+
localStorage.setItem(
74+
'scratchpad',
75+
JSON.stringify({
76+
files: initialTabs.map((x) => ({
77+
name: x.name + ((x as any).type ? `.${(x as any).type}` : ''),
78+
content: x.source.split('\n'),
79+
})),
80+
}),
81+
);
82+
navigate(`/scratchpad`);
83+
} else if (!context.token && !params.user) {
84+
navigate(`/scratchpad`);
85+
}
8586
});
8687

8788
const [repls, setRepls] = createStore<Repls>({ total: 0, list: [] });
@@ -113,39 +114,41 @@ export const Home = () => {
113114
}}
114115
/>
115116
<div class="m-8">
116-
<div class="flex flex-col align-middle">
117-
<button
118-
class="bg-solid-lightgray shadow-md dark:bg-solid-darkLighterBg rounded-xl p-4 text-3xl flex mx-auto"
119-
onClick={async () => {
120-
const result = await fetch(`${API}/repl`, {
121-
method: 'POST',
122-
headers: {
123-
'authorization': `Bearer ${context.token}`,
124-
'Content-Type': 'application/json',
125-
},
126-
body: JSON.stringify({
127-
title: 'Counter Example',
128-
public: true,
129-
labels: [],
130-
version: '1.0',
131-
files: defaultTabs.map((x) => ({ name: x.name, content: x.source.split('\n') })),
132-
}),
133-
});
134-
const { id } = await result.json();
135-
navigate(`/${context.user()?.display}/${id}`);
136-
}}
137-
>
138-
<Icon path={plus} class="w-8" /> Create new REPL
139-
</button>
140-
<p class="text-center text-gray-300 text-sm">
141-
Or{' '}
142-
<a href="/scratchpad" class="hover:underline">
143-
open my scratchpad
144-
</a>
145-
</p>
146-
</div>
117+
<Show when={!params.user}>
118+
<div class="flex flex-col align-middle mb-16">
119+
<button
120+
class="bg-solid-lightgray shadow-md dark:bg-solid-darkLighterBg rounded-xl p-4 text-3xl flex mx-auto"
121+
onClick={async () => {
122+
const result = await fetch(`${API}/repl`, {
123+
method: 'POST',
124+
headers: {
125+
'authorization': `Bearer ${context.token}`,
126+
'Content-Type': 'application/json',
127+
},
128+
body: JSON.stringify({
129+
title: 'Counter Example',
130+
public: true,
131+
labels: [],
132+
version: '1.0',
133+
files: defaultTabs.map((x) => ({ name: x.name, content: x.source.split('\n') })),
134+
}),
135+
});
136+
const { id } = await result.json();
137+
navigate(`/${context.user()?.display}/${id}`);
138+
}}
139+
>
140+
<Icon path={plus} class="w-8" /> Create new REPL
141+
</button>
142+
<p class="text-center text-gray-300 text-sm">
143+
Or{' '}
144+
<a href="/scratchpad" class="hover:underline">
145+
open my scratchpad
146+
</a>
147+
</p>
148+
</div>
149+
</Show>
147150

148-
<h1 class="text-center text-3xl mb-4 mt-16">{params.user || 'My'} Repls</h1>
151+
<h1 class="text-center text-3xl mb-4">{params.user ? `${params.user}'s` : 'My'} Repls</h1>
149152
<table class="w-200 max-w-full mx-auto">
150153
<thead>
151154
<tr class="border-b border-neutral-600">

src/components/editor/index.tsx

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,13 @@ import { liftOff } from './setupSolid';
44
import { useZoom } from '../../hooks/useZoom';
55

66
interface Props {
7-
classList?: {
8-
[k: string]: boolean | undefined;
9-
};
10-
class?: string;
117
url: string;
128
disabled?: true;
139
isDark?: boolean;
1410
withMinimap?: boolean;
1511
formatter?: Worker;
1612
displayErrors?: boolean;
1713
onDocChange?: (code: string) => unknown;
18-
ref?: (editor: mEditor.IStandaloneCodeEditor) => unknown;
1914
}
2015

2116
const Editor: Component<Props> = (props) => {
@@ -76,8 +71,6 @@ const Editor: Component<Props> = (props) => {
7671
editor.onDidChangeModelContent(() => {
7772
props.onDocChange?.(editor.getValue());
7873
});
79-
80-
props.ref?.(editor);
8174
};
8275

8376
// Initialize Monaco
@@ -105,7 +98,7 @@ const Editor: Component<Props> = (props) => {
10598
});
10699
});
107100

108-
return <div class={`p-0 h-full min-h-0 ${props.class || ''}`} classList={props.classList} ref={parent} />;
101+
return <div class="p-0 h-full min-h-0" ref={parent} />;
109102
};
110103

111104
export default Editor;

src/components/editor/monacoTabs.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,27 @@ const MonacoTabs: Component<{ folder: string; tabs: Tab[]; compiled: string }> =
1212

1313
const key = (tab: Tab) => `file:///${props.folder}/${tab.name}`;
1414
let currentTabs = new Map<string, editor.ITextModel>();
15+
let syncing = false;
1516
createEffect(() => {
1617
const newTabs = new Map<string, editor.ITextModel>();
18+
syncing = true;
1719
for (const tab of props.tabs) {
1820
const keyValue = key(tab);
1921
const lookup = currentTabs.get(keyValue);
2022
const source = untrack(() => tab.source);
2123
if (!lookup) {
2224
const uri = Uri.parse(keyValue);
23-
newTabs.set(keyValue, editor.createModel(source, undefined, uri));
25+
const model = editor.createModel(source, undefined, uri);
26+
newTabs.set(keyValue, model);
27+
model.onDidChangeContent(() => {
28+
if (!syncing) tab.source = model.getValue();
29+
});
2430
} else {
2531
lookup.setValue(source);
2632
newTabs.set(keyValue, lookup);
2733
}
2834
}
35+
syncing = false;
2936

3037
for (const [old, model] of currentTabs) {
3138
if (!newTabs.has(old)) model.dispose();

src/components/repl.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,6 @@ const Repl: ReplProps = (props) => {
6767
}
6868
});
6969
}
70-
function setCurrentSource(source: string) {
71-
const idx = props.tabs.findIndex((tab) => tab.name === props.current);
72-
if (idx < 0) return;
73-
74-
const tabs = props.tabs;
75-
tabs[idx].source = source;
76-
compile();
77-
}
7870
function addTab() {
7971
const newTab = {
8072
name: `tab${props.tabs.length}.tsx`,
@@ -270,7 +262,7 @@ const Repl: ReplProps = (props) => {
270262
{(current) => (
271263
<Editor
272264
url={`file:///${props.id}/${current}`}
273-
onDocChange={setCurrentSource}
265+
onDocChange={() => compile()}
274266
formatter={formatter}
275267
isDark={props.dark}
276268
withMinimap={false}

0 commit comments

Comments
 (0)