chore: show content loader untile the server has synced (#5657)
This commit is contained in:
parent
7f5a898cec
commit
3b0f3ca761
6 changed files with 88 additions and 11 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import React from "react";
|
||||
// components
|
||||
import { PageRenderer } from "@/components/editors";
|
||||
import { DocumentContentLoader, PageRenderer } from "@/components/editors";
|
||||
// constants
|
||||
import { DEFAULT_DISPLAY_CONFIG } from "@/constants/config";
|
||||
// extensions
|
||||
|
|
@ -42,7 +42,7 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
|||
}
|
||||
|
||||
// use document editor
|
||||
const { editor } = useCollaborativeEditor({
|
||||
const { editor, hasServerConnectionFailed, hasServerSynced } = useCollaborativeEditor({
|
||||
disabledExtensions,
|
||||
editorClassName,
|
||||
embedHandler,
|
||||
|
|
@ -67,6 +67,8 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
|||
|
||||
if (!editor) return null;
|
||||
|
||||
if (!hasServerSynced && !hasServerConnectionFailed) return <DocumentContentLoader />;
|
||||
|
||||
return (
|
||||
<PageRenderer
|
||||
displayConfig={displayConfig}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { forwardRef, MutableRefObject } from "react";
|
||||
// components
|
||||
import { PageRenderer } from "@/components/editors";
|
||||
import { DocumentContentLoader, PageRenderer } from "@/components/editors";
|
||||
// constants
|
||||
import { DEFAULT_DISPLAY_CONFIG } from "@/constants/config";
|
||||
// extensions
|
||||
|
|
@ -35,7 +35,7 @@ const CollaborativeDocumentReadOnlyEditor = (props: ICollaborativeDocumentReadOn
|
|||
);
|
||||
}
|
||||
|
||||
const { editor } = useReadOnlyCollaborativeEditor({
|
||||
const { editor, hasServerConnectionFailed, hasServerSynced } = useReadOnlyCollaborativeEditor({
|
||||
editorClassName,
|
||||
extensions,
|
||||
forwardedRef,
|
||||
|
|
@ -52,6 +52,9 @@ const CollaborativeDocumentReadOnlyEditor = (props: ICollaborativeDocumentReadOn
|
|||
});
|
||||
|
||||
if (!editor) return null;
|
||||
|
||||
if (!hasServerSynced && !hasServerConnectionFailed) return <DocumentContentLoader />;
|
||||
|
||||
return (
|
||||
<PageRenderer
|
||||
displayConfig={displayConfig}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
export * from "./collaborative-editor";
|
||||
export * from "./collaborative-read-only-editor";
|
||||
export * from "./loader";
|
||||
export * from "./page-renderer";
|
||||
export * from "./read-only-editor";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
// ui
|
||||
import { Loader } from "@plane/ui";
|
||||
|
||||
export const DocumentContentLoader = () => (
|
||||
<div className="size-full px-5">
|
||||
<Loader className="relative space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="py-2">
|
||||
<Loader.Item width="100%" height="36px" />
|
||||
</div>
|
||||
<Loader.Item width="80%" height="22px" />
|
||||
<div className="relative flex items-center gap-2">
|
||||
<Loader.Item width="30px" height="30px" />
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
</div>
|
||||
<div className="py-2">
|
||||
<Loader.Item width="60%" height="36px" />
|
||||
</div>
|
||||
<Loader.Item width="70%" height="22px" />
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
<div className="relative flex items-center gap-2">
|
||||
<Loader.Item width="30px" height="30px" />
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
</div>
|
||||
<div className="py-2">
|
||||
<Loader.Item width="50%" height="30px" />
|
||||
</div>
|
||||
<Loader.Item width="100%" height="22px" />
|
||||
<div className="py-2">
|
||||
<Loader.Item width="30%" height="30px" />
|
||||
</div>
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
<div className="relative flex items-center gap-2">
|
||||
<div className="py-2">
|
||||
<Loader.Item width="30px" height="30px" />
|
||||
</div>
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
</div>
|
||||
</div>
|
||||
</Loader>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useLayoutEffect, useMemo } from "react";
|
||||
import { useEffect, useLayoutEffect, useMemo, useState } from "react";
|
||||
import { HocuspocusProvider } from "@hocuspocus/provider";
|
||||
import Collaboration from "@tiptap/extension-collaboration";
|
||||
import { IndexeddbPersistence } from "y-indexeddb";
|
||||
|
|
@ -29,6 +29,9 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => {
|
|||
tabIndex,
|
||||
user,
|
||||
} = props;
|
||||
// states
|
||||
const [hasServerConnectionFailed, setHasServerConnectionFailed] = useState(false);
|
||||
const [hasServerSynced, setHasServerSynced] = useState(false);
|
||||
// initialize Hocuspocus provider
|
||||
const provider = useMemo(
|
||||
() =>
|
||||
|
|
@ -38,11 +41,18 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => {
|
|||
// using user id as a token to verify the user on the server
|
||||
token: user.id,
|
||||
url: realtimeConfig.url,
|
||||
onAuthenticationFailed: () => serverHandler?.onServerError?.(),
|
||||
onAuthenticationFailed: () => {
|
||||
serverHandler?.onServerError?.();
|
||||
setHasServerConnectionFailed(true);
|
||||
},
|
||||
onConnect: () => serverHandler?.onConnect?.(),
|
||||
onClose: (data) => {
|
||||
if (data.event.code === 1006) serverHandler?.onServerError?.();
|
||||
if (data.event.code === 1006) {
|
||||
serverHandler?.onServerError?.();
|
||||
setHasServerConnectionFailed(true);
|
||||
}
|
||||
},
|
||||
onSynced: () => setHasServerSynced(true),
|
||||
}),
|
||||
[id, realtimeConfig, serverHandler, user.id]
|
||||
);
|
||||
|
|
@ -94,5 +104,9 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => {
|
|||
tabIndex,
|
||||
});
|
||||
|
||||
return { editor };
|
||||
return {
|
||||
editor,
|
||||
hasServerConnectionFailed,
|
||||
hasServerSynced,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useLayoutEffect, useMemo } from "react";
|
||||
import { useEffect, useLayoutEffect, useMemo, useState } from "react";
|
||||
import { HocuspocusProvider } from "@hocuspocus/provider";
|
||||
import Collaboration from "@tiptap/extension-collaboration";
|
||||
import { IndexeddbPersistence } from "y-indexeddb";
|
||||
|
|
@ -22,6 +22,9 @@ export const useReadOnlyCollaborativeEditor = (props: TReadOnlyCollaborativeEdit
|
|||
serverHandler,
|
||||
user,
|
||||
} = props;
|
||||
// states
|
||||
const [hasServerConnectionFailed, setHasServerConnectionFailed] = useState(false);
|
||||
const [hasServerSynced, setHasServerSynced] = useState(false);
|
||||
// initialize Hocuspocus provider
|
||||
const provider = useMemo(
|
||||
() =>
|
||||
|
|
@ -30,10 +33,18 @@ export const useReadOnlyCollaborativeEditor = (props: TReadOnlyCollaborativeEdit
|
|||
name: id,
|
||||
token: user.id,
|
||||
parameters: realtimeConfig.queryParams,
|
||||
onAuthenticationFailed: () => {
|
||||
serverHandler?.onServerError?.();
|
||||
setHasServerConnectionFailed(true);
|
||||
},
|
||||
onConnect: () => serverHandler?.onConnect?.(),
|
||||
onClose: (data) => {
|
||||
if (data.event.code === 1006) serverHandler?.onServerError?.();
|
||||
if (data.event.code === 1006) {
|
||||
serverHandler?.onServerError?.();
|
||||
setHasServerConnectionFailed(true);
|
||||
}
|
||||
},
|
||||
onSynced: () => setHasServerSynced(true),
|
||||
}),
|
||||
[id, realtimeConfig, user.id]
|
||||
);
|
||||
|
|
@ -69,5 +80,9 @@ export const useReadOnlyCollaborativeEditor = (props: TReadOnlyCollaborativeEdit
|
|||
provider,
|
||||
});
|
||||
|
||||
return { editor, isIndexedDbSynced: true };
|
||||
return {
|
||||
editor,
|
||||
hasServerConnectionFailed,
|
||||
hasServerSynced,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue