fix collaboration

This commit is contained in:
Philipinho
2025-08-03 18:24:55 -07:00
parent 66a3dad632
commit 63ea2f7663
3 changed files with 48 additions and 45 deletions
+47 -36
View File
@@ -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 (
-1
View File
@@ -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",
+1 -8
View File
@@ -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: