diff --git a/CHANGELOG.md b/CHANGELOG.md
index 981e3b80..2a6657a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@ and this project adheres to
- 🔨(frontend) encapsulated title to its own component #474
- 🐛(frontend) Fix hidden menu on Firefox #468
- ⚡️(backend) optimize number of queries on document list view #411
+- ♻️(frontend) stop to use provider with version #480
- 🚚(collaboration) change the websocket key name #480
diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx
index 8c04127b..cafecdbf 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx
+++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx
@@ -6,6 +6,7 @@ import { useCreateBlockNote } from '@blocknote/react';
import { HocuspocusProvider } from '@hocuspocus/provider';
import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
+import * as Y from 'yjs';
import { Box, TextErrors } from '@/components';
import { useAuthStore } from '@/core/auth';
@@ -65,19 +66,14 @@ const cssEditor = (readonly: boolean) => `
interface BlockNoteEditorProps {
doc: Doc;
provider: HocuspocusProvider;
- storeId: string;
}
-export const BlockNoteEditor = ({
- doc,
- provider,
- storeId,
-}: BlockNoteEditorProps) => {
- const isVersion = doc.id !== storeId;
+export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
const { userData } = useAuthStore();
const { setEditor } = useEditorStore();
const { t } = useTranslation();
- const readOnly = !doc.abilities.partial_update || isVersion;
+
+ const readOnly = !doc.abilities.partial_update;
useSaveDoc(doc.id, provider.document, !readOnly);
const { setHeadings, resetHeadings } = useHeadingStore();
const { i18n } = useTranslation();
@@ -174,3 +170,46 @@ export const BlockNoteEditor = ({
);
};
+
+interface BlockNoteEditorVersionProps {
+ initialContent: Y.XmlFragment;
+}
+
+export const BlockNoteEditorVersion = ({
+ initialContent,
+}: BlockNoteEditorVersionProps) => {
+ const readOnly = true;
+ const { setHeadings, resetHeadings } = useHeadingStore();
+
+ const editor = useCreateBlockNote(
+ {
+ collaboration: {
+ fragment: initialContent,
+ user: {
+ name: '',
+ color: '',
+ },
+ provider: undefined,
+ },
+ },
+ [initialContent],
+ );
+
+ useEffect(() => {
+ setHeadings(editor);
+
+ editor?.onEditorContentChange(() => {
+ setHeadings(editor);
+ });
+
+ return () => {
+ resetHeadings();
+ };
+ }, [editor, resetHeadings, setHeadings]);
+
+ return (
+
+
+
+ );
+};
diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx
index 50b2b73a..58cce28f 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx
+++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx
@@ -1,19 +1,23 @@
import { Alert, Loader, VariantType } from '@openfun/cunningham-react';
import { useRouter } from 'next/router';
-import React, { useEffect } from 'react';
+import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
+import * as Y from 'yjs';
import { Box, Card, Text, TextErrors } from '@/components';
-import { useCollaborationUrl } from '@/core';
import { useCunninghamTheme } from '@/cunningham';
import { DocHeader } from '@/features/docs/doc-header';
-import { Doc, useDocStore } from '@/features/docs/doc-management';
+import {
+ Doc,
+ base64ToBlocknoteXmlFragment,
+ useDocStore,
+} from '@/features/docs/doc-management';
import { Versions, useDocVersion } from '@/features/docs/doc-versioning/';
import { useResponsiveStore } from '@/stores';
import { useHeadingStore } from '../stores';
-import { BlockNoteEditor } from './BlockNoteEditor';
+import { BlockNoteEditor, BlockNoteEditorVersion } from './BlockNoteEditor';
import { IconOpenPanelEditor, PanelEditor } from './PanelEditor';
interface DocEditorProps {
@@ -41,7 +45,7 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
return (
<>
-
+
{!doc.abilities.partial_update && (
@@ -71,9 +75,9 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
$position="relative"
>
{isVersion ? (
-
+
) : (
-
+
)}
{!isMobile && }
@@ -84,35 +88,34 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
};
interface DocVersionEditorProps {
- doc: Doc;
+ docId: Doc['id'];
versionId: Versions['version_id'];
}
-export const DocVersionEditor = ({ doc, versionId }: DocVersionEditorProps) => {
+export const DocVersionEditor = ({
+ docId,
+ versionId,
+}: DocVersionEditorProps) => {
const {
data: version,
isLoading,
isError,
error,
} = useDocVersion({
- docId: doc.id,
+ docId,
versionId,
});
- const { createProvider, providers } = useDocStore();
- const collaborationUrl = useCollaborationUrl(versionId);
const { replace } = useRouter();
+ const [initialContent, setInitialContent] = useState();
useEffect(() => {
- if (!version?.id || !collaborationUrl) {
+ if (!version?.content) {
return;
}
- const provider = providers?.[version.id];
- if (!provider || provider.document.guid !== version.id) {
- createProvider(collaborationUrl, version.id, version.content);
- }
- }, [createProvider, providers, version, collaborationUrl]);
+ setInitialContent(base64ToBlocknoteXmlFragment(version.content));
+ }, [version?.content]);
if (isError && error) {
if (error.status === 404) {
@@ -136,7 +139,7 @@ export const DocVersionEditor = ({ doc, versionId }: DocVersionEditorProps) => {
);
}
- if (isLoading || !version) {
+ if (isLoading || !version || !initialContent) {
return (
@@ -144,11 +147,5 @@ export const DocVersionEditor = ({ doc, versionId }: DocVersionEditorProps) => {
);
}
- const provider = providers?.[version.id];
-
- if (!provider) {
- return null;
- }
-
- return ;
+ return ;
};
diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx
index 0e565b10..d169044a 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx
+++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx
@@ -5,7 +5,6 @@ import { css } from 'styled-components';
import { Box, Card, StyledLink, Text } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
import { Doc, currentDocRole, useTrans } from '@/features/docs/doc-management';
-import { Versions } from '@/features/docs/doc-versioning';
import { useDate } from '@/hook';
import { useResponsiveStore } from '@/stores';
@@ -15,10 +14,9 @@ import { DocToolBox } from './DocToolBox';
interface DocHeaderProps {
doc: Doc;
- versionId?: Versions['version_id'];
}
-export const DocHeader = ({ doc, versionId }: DocHeaderProps) => {
+export const DocHeader = ({ doc }: DocHeaderProps) => {
const { colorsTokens } = useCunninghamTheme();
const { t } = useTranslation();
const { formatDate } = useDate();
@@ -69,7 +67,7 @@ export const DocHeader = ({ doc, versionId }: DocHeaderProps) => {
$align="center"
>
-
+
{
+export const DocToolBox = ({ doc }: DocToolBoxProps) => {
+ const {
+ query: { versionId },
+ } = useRouter();
const { t } = useTranslation();
const [isModalShareOpen, setIsModalShareOpen] = useState(false);
const [isModalRemoveOpen, setIsModalRemoveOpen] = useState(false);
@@ -194,7 +197,7 @@ export const DocToolBox = ({ doc, versionId }: DocToolBoxProps) => {
setIsModalVersionOpen(false)}
docId={doc.id}
- versionId={versionId}
+ versionId={versionId as string}
/>
)}
diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts b/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts
index 7ba6571a..198c913c 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts
+++ b/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts
@@ -28,3 +28,14 @@ export const blocksToYDoc = (blocks: BasicBlock[], doc: Y.Doc) => {
xmlFragment.push([xmlElement]);
});
};
+
+export const base64ToYDoc = (base64: string) => {
+ const uint8Array = Buffer.from(base64, 'base64');
+ const ydoc = new Y.Doc();
+ Y.applyUpdate(ydoc, uint8Array);
+ return ydoc;
+};
+
+export const base64ToBlocknoteXmlFragment = (base64: string) => {
+ return base64ToYDoc(base64).getXmlFragment('document-store');
+};
diff --git a/src/frontend/apps/impress/src/features/docs/doc-versioning/components/ModalVersion.tsx b/src/frontend/apps/impress/src/features/docs/doc-versioning/components/ModalVersion.tsx
index 7bc45046..8ffba2db 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-versioning/components/ModalVersion.tsx
+++ b/src/frontend/apps/impress/src/features/docs/doc-versioning/components/ModalVersion.tsx
@@ -8,12 +8,16 @@ import {
} from '@openfun/cunningham-react';
import { useRouter } from 'next/router';
import { useTranslation } from 'react-i18next';
-import * as Y from 'yjs';
import { Box, Text } from '@/components';
-import { toBase64 } from '@/features/docs/doc-editor';
-import { Doc, useDocStore, useUpdateDoc } from '@/features/docs/doc-management';
+import {
+ Doc,
+ base64ToYDoc,
+ useDocStore,
+ useUpdateDoc,
+} from '@/features/docs/doc-management';
+import { useDocVersion } from '../api';
import { KEY_LIST_DOC_VERSIONS } from '../api/useDocVersions';
import { Versions } from '../types';
import { revertUpdate } from '../utils';
@@ -21,7 +25,6 @@ import { revertUpdate } from '../utils';
interface ModalVersionProps {
onClose: () => void;
docId: Doc['id'];
-
versionId: Versions['version_id'];
}
@@ -30,6 +33,10 @@ export const ModalVersion = ({
docId,
versionId,
}: ModalVersionProps) => {
+ const { data: version } = useDocVersion({
+ docId,
+ versionId,
+ });
const { t } = useTranslation();
const { toast } = useToastProvider();
const { push } = useRouter();
@@ -42,7 +49,7 @@ export const ModalVersion = ({
void push(`/docs/${docId}`);
};
- if (!providers?.[docId] || !providers?.[versionId]) {
+ if (!providers?.[docId] || !version?.content) {
onDisplaySuccess();
return;
}
@@ -50,7 +57,7 @@ export const ModalVersion = ({
revertUpdate(
providers[docId].document,
providers[docId].document,
- providers[versionId].document,
+ base64ToYDoc(version.content),
);
onDisplaySuccess();
@@ -79,13 +86,13 @@ export const ModalVersion = ({
color="primary"
fullWidth
onClick={() => {
- const newDoc = toBase64(
- Y.encodeStateAsUpdate(providers?.[versionId].document),
- );
+ if (!version?.content) {
+ return;
+ }
updateDoc({
id: docId,
- content: newDoc,
+ content: version.content,
});
onClose();