♻️(app-impress) refacto pad store to add the editor

To spread the data editor to different feature
of our app, we add the editor in the pad store.
It will give an easy access to the editor data.
This commit is contained in:
Anthony LC
2024-04-10 12:25:24 +02:00
committed by Anthony LC
parent 272b18ae02
commit a5a8a64350
5 changed files with 102 additions and 48 deletions

View File

@@ -1,10 +1,12 @@
import { BlockNoteView, useCreateBlockNote } from '@blocknote/react';
import '@blocknote/react/style.css';
import React, { useCallback } from 'react';
import React, { useEffect, useState } from 'react';
import { WebrtcProvider } from 'y-webrtc';
import { Box } from '@/components';
import { useAuthStore } from '@/core/auth';
import { PadStore, usePadStore } from '../store';
import { usePadStore } from '../stores';
import { Pad } from '../types';
import { randomColor } from '../utils';
@@ -13,19 +15,34 @@ interface BlockNoteEditorProps {
}
export const BlockNoteEditor = ({ pad }: BlockNoteEditorProps) => {
const { userData } = useAuthStore();
const getProvider = useCallback(
(state: PadStore) => {
if (!state.providers[pad.id]) {
return state.createProvider(pad.id);
}
return state.providers[pad.id];
},
[pad.id],
const { createProvider, padsStore } = usePadStore();
const [provider, setProvider] = useState<WebrtcProvider>(
padsStore?.[pad.id]?.provider,
);
const provider = usePadStore(getProvider);
useEffect(() => {
if (provider) {
return;
}
setProvider(createProvider(pad.id));
}, [createProvider, pad.id, provider]);
if (!provider) {
return null;
}
return <BlockNoteContent pad={pad} provider={provider} />;
};
interface BlockNoteContentProps {
pad: Pad;
provider: WebrtcProvider;
}
export const BlockNoteContent = ({ pad, provider }: BlockNoteContentProps) => {
const { userData } = useAuthStore();
const { setEditor } = usePadStore();
const editor = useCreateBlockNote({
collaboration: {
@@ -38,5 +55,19 @@ export const BlockNoteEditor = ({ pad }: BlockNoteEditorProps) => {
},
});
return <BlockNoteView editor={editor} />;
useEffect(() => {
setEditor(pad.id, editor);
}, [setEditor, pad.id, editor]);
return (
<Box
$css={`
&, & > .bn-container, & .ProseMirror {
height:100%
};
`}
>
<BlockNoteView editor={editor} />
</Box>
);
};

View File

@@ -1,3 +1,4 @@
export * from './api';
export * from './components';
export * from './stores';
export * from './types';

View File

@@ -1,34 +0,0 @@
import { WebrtcProvider } from 'y-webrtc';
import * as Y from 'yjs';
import { create } from 'zustand';
import { Pad } from '../types';
export interface PadStore {
providers: { [padId: Pad['id']]: WebrtcProvider };
createProvider: (padId: Pad['id']) => WebrtcProvider;
}
const initialState = {
providers: {},
};
export const usePadStore = create<PadStore>((set) => ({
providers: initialState.providers,
createProvider: (padId: string) => {
const provider = new WebrtcProvider(padId, new Y.Doc(), {
signaling: [process.env.NEXT_PUBLIC_SIGNALING_URL || ''],
});
set(({ providers }) => {
return {
providers: {
...providers,
[padId]: provider,
},
};
});
return provider;
},
}));

View File

@@ -0,0 +1,56 @@
import { BlockNoteEditor } from '@blocknote/core';
import { WebrtcProvider } from 'y-webrtc';
import * as Y from 'yjs';
import { create } from 'zustand';
import { Pad } from '../types';
export interface PadStore {
padsStore: {
[padId: Pad['id']]: {
provider: WebrtcProvider;
editor?: BlockNoteEditor;
};
};
createProvider: (padId: Pad['id']) => WebrtcProvider;
setEditor: (padId: Pad['id'], editor: BlockNoteEditor) => void;
}
const initialState = {
padsStore: {},
};
export const usePadStore = create<PadStore>((set) => ({
padsStore: initialState.padsStore,
createProvider: (padId: string) => {
const provider = new WebrtcProvider(padId, new Y.Doc(), {
signaling: [process.env.NEXT_PUBLIC_SIGNALING_URL || ''],
});
set(({ padsStore }) => {
return {
padsStore: {
...padsStore,
[padId]: {
provider,
},
},
};
});
return provider;
},
setEditor: (padId, editor) => {
set(({ padsStore }) => {
return {
padsStore: {
...padsStore,
[padId]: {
...padsStore[padId],
editor,
},
},
};
});
},
}));