From c0dae2367a9a9661556e8d21f4456bd08212cacd Mon Sep 17 00:00:00 2001 From: Xinyi Li Date: Fri, 11 Nov 2022 23:05:28 +0000 Subject: [PATCH 1/3] fix(erro_box): create ydoc when set repo --- ui/src/pages/repo.tsx | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/ui/src/pages/repo.tsx b/ui/src/pages/repo.tsx index 58bd71d4..1182974e 100644 --- a/ui/src/pages/repo.tsx +++ b/ui/src/pages/repo.tsx @@ -96,7 +96,6 @@ function RepoImpl() { const addClient = useStore(store, (state) => state.addClient); const deleteClient = useStore(store, (state) => state.deleteClient); - const { loading, me } = useMe(); useEffect(() => { if (me) { @@ -104,12 +103,6 @@ function RepoImpl() { } }, [me, id, setSessionId]); - useEffect(() => { - if (me) { - setUser(me); - } - }, [me, setUser]); - useEffect(() => { if (provider) { const awareness = provider.awareness; @@ -118,23 +111,27 @@ function RepoImpl() { const states = awareness.getStates(); const nodes = change.added.concat(change.updated); nodes.forEach((clientID) => { - const user = states.get(clientID)?.user - if (user) { - addClient(clientID, user.name, user.color); - } + const user = states.get(clientID)?.user; + if (user) { + addClient(clientID, user.name, user.color); + } }); change.removed.forEach((clientID) => { - deleteClient(clientID); - }) - }) - }}, [provider]); + deleteClient(clientID); + }); + }); + } + }, [provider]); useEffect(() => { resetState(); setRepo(id!); // load the repo. It is actually not a queue, just an async thunk loadRepo(client, id!); - }, [client, id, loadRepo, resetState, setRepo]); + if (!loading && me) { + setUser(me); + } + }, [client, id, loadRepo, resetState, setRepo, me, loading, setUser]); // FIXME Removing queueL. This will cause Repo to be re-rendered a lot of // times, particularly the delete pod action would cause syncstatus and repo From 9d85fcad0fc0abf5ae36cecd97190df3331478bc Mon Sep 17 00:00:00 2001 From: Xinyi Li Date: Fri, 11 Nov 2022 23:06:10 +0000 Subject: [PATCH 2/3] clean up --- ui/src/components/MyMonaco.tsx | 23 +++++++++++++++++------ ui/src/lib/store.tsx | 22 ++++++++++++++++++++-- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/ui/src/components/MyMonaco.tsx b/ui/src/components/MyMonaco.tsx index e16cd5bc..46fb2ba1 100644 --- a/ui/src/components/MyMonaco.tsx +++ b/ui/src/components/MyMonaco.tsx @@ -365,19 +365,30 @@ export function MyMonaco({ awareness ); - // FIXME: make sure the provider.wsconnected is true or it won't display any content. - - provider?.once("synced", () => { - if (!ytext._start) { + const init = () => { + if (!ytext._start && ytext.length === 0) { ytext.insert(0, value); } - }); + }; + + if (!provider || !provider.wsconnected) { + // TODO: consider offline situation later + console.log("editor", provider?.wsconnected, provider, editor.getModel()); + // editor.getModel().setValue(value); + return; + } else if (provider.synced) { + init(); + } else { + provider.once("synced", init); + } + + // FIXME: make sure the provider.wsconnected is true or it won't display any content. } return ( = (set, get) => ({ ...initialState, // FIXME should reset to inital state, not completely empty. - resetState: () => set(initialState), + resetState: () => + // FIXME before rest a state, first + // 1. destroy/disconnect the provider, or it keep the awareness information of the exited page + // 2. set state.provider = null, or it can't be assigned a new provider. + set((state) => { + console.log("user reset state provider", state.provider); + if (state.provider) { + state.provider.destroy(); + state.ydoc.destroy(); + state.provider = null; + } + return initialState; + }), setRepo: (repoId: string) => set( produce((state: BearState) => { state.repoId = repoId; - if (!state.provider) { + state.ydoc = new Doc(); + // console.log("user reset state setrepo", repoId); + if (state.provider) { + console.log("emmm, provider exists", state.provider); + } else { console.log("connecting yjs socket .."); state.provider = new WebsocketProvider( serverURL, @@ -208,6 +225,7 @@ const createRepoSlice: StateCreator< state.ydoc ); // max retry time: 10s + state.provider.connect(); state.provider.maxBackoffTime = 10000; } }) From 87d549472c8e3a0ede8a9c3ad669c41b3d976ff3 Mon Sep 17 00:00:00 2001 From: Xinyi Li Date: Sat, 12 Nov 2022 02:29:08 +0000 Subject: [PATCH 3/3] add clean up function for y-provider --- ui/src/lib/store.tsx | 14 ++++++++++++++ ui/src/pages/repo.tsx | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/ui/src/lib/store.tsx b/ui/src/lib/store.tsx index 60285a0b..8cae736a 100644 --- a/ui/src/lib/store.tsx +++ b/ui/src/lib/store.tsx @@ -184,6 +184,7 @@ export interface RepoSlice { addClient: (clientId: any, name, color) => void; deleteClient: (clientId: any) => void; flipShowLineNumbers: () => void; + disconnect: () => void; } type BearState = RepoSlice & RuntimeSlice; @@ -738,6 +739,19 @@ const createRepoSlice: StateCreator< ), flipShowLineNumbers: () => set((state) => ({ showLineNumbers: !state.showLineNumbers })), + disconnect: () => + set( + // clean up the connected provider after exiting the page + produce((state) => { + if (state.provider) { + state.provider.destroy(); + // just for debug usage, remove it later + console.log("remove awareness", state.provider.awareness); + state.provider = null; + } + state.ydoc.destroy(); + }) + ), }); export const createRepoStore = () => diff --git a/ui/src/pages/repo.tsx b/ui/src/pages/repo.tsx index 1182974e..c5d586c7 100644 --- a/ui/src/pages/repo.tsx +++ b/ui/src/pages/repo.tsx @@ -160,6 +160,13 @@ function RepoImpl() { export default function Repo() { const store = useRef(createRepoStore()).current; + const disconnect = useStore(store, (state) => state.disconnect); + // console.log("load store", useRef(createRepoStore())); + useEffect(() => { + // const provider = useStore(store, (state) => state.provider); + // clean up the connected provider after exiting the page + return disconnect; + }, [store]); return (