♻️(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:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './api';
|
||||
export * from './components';
|
||||
export * from './stores';
|
||||
export * from './types';
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
}));
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
}));
|
||||
Reference in New Issue
Block a user