diff --git a/apps/client/src/features/editor/page-editor.tsx b/apps/client/src/features/editor/page-editor.tsx index d8036333..3893ea5e 100644 --- a/apps/client/src/features/editor/page-editor.tsx +++ b/apps/client/src/features/editor/page-editor.tsx @@ -4,6 +4,7 @@ import { IndexeddbPersistence } from "y-indexeddb"; import * as Y from "yjs"; import { HocuspocusProvider, + onStatusParameters, onAuthenticationFailedParameters, WebSocketStatus, } from "@hocuspocus/provider"; @@ -72,7 +73,7 @@ export default function PageEditor({ ydocRef.current = new Y.Doc(); } const ydoc = ydocRef.current; - const [isLocalSynced, setLocalSynced] = useState(false); + const [isLocalSynced, setIsLocalSynced] = useState(false); const [isRemoteSynced, setRemoteSynced] = useState(false); const [yjsConnectionStatus, setYjsConnectionStatus] = useAtom( yjsConnectionStatusAtom, @@ -100,29 +101,31 @@ export default function PageEditor({ // Track when collaborative provider is ready and synced const [collabReady, setCollabReady] = useState(false); - /* + useEffect(() => { if ( - remoteProvider?.status === WebSocketStatus.Connected && + remoteProvider?.configuration.websocketProvider.status === + WebSocketStatus.Connected && isLocalSynced && isRemoteSynced ) { setCollabReady(true); } - }, [remoteProvider?.status, isLocalSynced, isRemoteSynced]); - */ + }, [ + remoteProvider?.configuration.websocketProvider.status, + isLocalSynced, + isRemoteSynced, + ]); useEffect(() => { if (!providersRef.current) { const local = new IndexeddbPersistence(documentName, ydoc); - local.on("synced", () => setLocalSynced(true)); + local.on("synced", () => setIsLocalSynced(true)); const remote = new HocuspocusProvider({ name: documentName, url: collaborationURL, document: ydoc, token: collabQuery?.token, - //connect: true, - //preserveConnection: false, onAuthenticationFailed: (auth: onAuthenticationFailedParameters) => { const payload = jwtDecode(collabQuery?.token); const now = Date.now().valueOf() / 1000; @@ -130,25 +133,28 @@ export default function PageEditor({ if (isTokenExpired) { refetchCollabToken().then((result) => { if (result.data?.token) { - remote.disconnect(); + remote.configuration.websocketProvider.disconnect(); setTimeout(() => { remote.configuration.token = result.data.token; - remote.connect(); + remote.configuration.websocketProvider.connect(); }, 100); } }); } }, - //onStatus: (status) => { - // if (status.status === "connected") { - // setYjsConnectionStatus(status.status); - // } - // }, }); + remote.on("synced", () => setRemoteSynced(true)); - remote.on("disconnect", () => { - setYjsConnectionStatus(WebSocketStatus.Disconnected); - }); + + const handleSocketStatus = (status: onStatusParameters) => { + if (status.status === "connected") { + setYjsConnectionStatus(WebSocketStatus.Connected); + } else if (status.status === "disconnected") { + setYjsConnectionStatus(WebSocketStatus.Disconnected); + } + }; + remote.configuration.websocketProvider.on("status", handleSocketStatus); + providersRef.current = { local, remote }; setProvidersReady(true); } else { @@ -178,29 +184,29 @@ export default function PageEditor({ */ // Only connect/disconnect on tab/idle, not destroy - /* useEffect(() => { if (!providersReady || !providersRef.current) return; const remoteProvider = providersRef.current.remote; if ( isIdle && documentState === "hidden" && - remoteProvider === WebSocketStatus.Connected + remoteProvider.configuration.websocketProvider.status === + WebSocketStatus.Connected ) { - remoteProvider.disconnect(); + remoteProvider.configuration.websocketProvider.disconnect(); setIsCollabReady(false); return; } if ( documentState === "visible" && - remoteProvider.status === WebSocketStatus.Disconnected + remoteProvider.configuration.websocketProvider.status === + WebSocketStatus.Disconnected ) { resetIdle(); - remoteProvider.connect(); + remoteProvider.configuration.websocketProvider.connect(); setTimeout(() => setIsCollabReady(true), 500); } }, [isIdle, documentState, providersReady, resetIdle]); - */ const extensions = useMemo(() => { if (!remoteProvider || !currentUser?.user) return mainExtensions; @@ -316,32 +322,37 @@ export default function PageEditor({ setAsideState({ tab: "", isAsideOpen: false }); }, [pageId]); - /* useEffect(() => { - if (remoteProvider?.status === WebSocketStatus.Connecting) { + if ( + remoteProvider?.configuration.websocketProvider.status === + WebSocketStatus.Connecting + ) { const timeout = setTimeout(() => { setYjsConnectionStatus(WebSocketStatus.Disconnected); }, 5000); return () => clearTimeout(timeout); } - }, [remoteProvider?.status]); -*/ + }, [remoteProvider?.configuration.websocketProvider.status]); + const isSynced = isLocalSynced && isRemoteSynced; - /* useEffect(() => { const collabReadyTimeout = setTimeout(() => { if ( !isCollabReady && isSynced && - remoteProvider?.status === WebSocketStatus.Connected + remoteProvider?.configuration.websocketProvider.status === + WebSocketStatus.Connected ) { setIsCollabReady(true); } }, 500); return () => clearTimeout(collabReadyTimeout); - }, [isRemoteSynced, isLocalSynced, remoteProvider?.status]); - */ + }, [ + isRemoteSynced, + isLocalSynced, + remoteProvider?.configuration.websocketProvider.status, + ]); useEffect(() => { // Only honor user default page edit mode preference and permissions @@ -359,18 +370,18 @@ export default function PageEditor({ }, [userPageEditMode, editor, editable]); const hasConnectedOnceRef = useRef(false); - const [showStatic, setShowStatic] = useState(false); + const [showStatic, setShowStatic] = useState(true); - /* useEffect(() => { if ( !hasConnectedOnceRef.current && - remoteProvider?.status === WebSocketStatus.Connected + remoteProvider?.configuration.websocketProvider.status === + WebSocketStatus.Connected ) { hasConnectedOnceRef.current = true; setShowStatic(false); } - }, [remoteProvider?.status]);*/ + }, [remoteProvider?.configuration.websocketProvider.status]); if (showStatic) { return ( diff --git a/package.json b/package.json index 0653a1b7..76165682 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "@tiptap/suggestion": "^3.0.9", "@types/qrcode": "^1.5.5", "bytes": "^3.1.2", - "core": "link:highlight.js/lib/core", "cross-env": "^7.0.3", "date-fns": "^4.1.0", "dompurify": "^3.2.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b78ab192..2707f75c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -136,9 +136,6 @@ importers: bytes: specifier: ^3.1.2 version: 3.1.2 - core: - specifier: link:highlight.js/lib/core - version: link:highlight.js/lib/core cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -683,11 +680,7 @@ importers: specifier: ^8.24.1 version: 8.24.1(eslint@9.20.1(jiti@1.21.0))(typescript@5.7.3) - packages/editor-ext: - dependencies: - '@tiptap/extension-code-block': - specifier: ^3.0.9 - version: 3.0.9(@tiptap/core@3.0.9(@tiptap/pm@3.0.9))(@tiptap/pm@3.0.9) + packages/editor-ext: {} packages: