ryoji-s 2 лет назад
Родитель
Сommit
0ddb7907b3

+ 1 - 4
apps/app/src/components/PageEditor/PageEditor.tsx

@@ -158,8 +158,6 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
     // set to ref
     initialValueRef.current = initialValue;
   }, [initialValue]);
-
-  const [userList, setUserList] = useState<IUserHasId[]>([]);
   const [markdownToPreview, setMarkdownToPreview] = useState<string>(initialValue);
   const setMarkdownPreviewWithDebounce = useMemo(() => debounce(100, throttle(150, (value: string) => {
     setMarkdownToPreview(value);
@@ -430,7 +428,7 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
   return (
     <div data-testid="page-editor" id="page-editor" className={`flex-expand-vert ${props.visibility ? '' : 'd-none'}`}>
       <div className="px-4 py-2">
-        <PageHeader userList={userList} />
+        <PageHeader />
       </div>
       <div className={`flex-expand-horiz ${props.visibility ? '' : 'd-none'}`}>
         <div className="page-editor-editor-container flex-expand-vert">
@@ -457,7 +455,6 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
             pageId={pageId ?? undefined}
             initialValue={initialValue}
             onOpenEditor={markdown => setMarkdownToPreview(markdown)}
-            onEditorsUpdated={setUserList}
             editorTheme={editorSettings?.theme}
             editorKeymap={editorSettings?.keymapMode}
           />

+ 4 - 8
apps/app/src/components/PageHeader/PageHeader.tsx

@@ -1,7 +1,7 @@
 import type { FC } from 'react';
 
-import type { IUserHasId } from '@growi/core';
 import { DevidedPagePath } from '@growi/core/dist/models';
+import { useEditingUsers } from '@growi/core/dist/swr';
 
 import { useSWRxCurrentPage } from '~/stores/page';
 
@@ -13,13 +13,9 @@ import styles from './PageHeader.module.scss';
 
 const moduleClass = styles['page-header'] ?? '';
 
-type Props = {
-  userList: IUserHasId[]
-}
-
-export const PageHeader: FC<Props> = (props) => {
-  const { userList } = props;
+export const PageHeader: FC = () => {
   const { data: currentPage } = useSWRxCurrentPage();
+  const { data: EditingUsers } = useEditingUsers();
 
   if (currentPage == null) {
     return <></>;
@@ -39,7 +35,7 @@ export const PageHeader: FC<Props> = (props) => {
         />
         <EditingUserList
           className={`z-2 ${dPagePath.isRoot ? '' : 'col mt-2'}`}
-          userList={userList}
+          userList={EditingUsers?.userList ?? []}
         />
       </div>
     </div>

+ 1 - 0
packages/core/src/swr/index.ts

@@ -1,3 +1,4 @@
 export * from './use-swr-static';
 export * from './with-utils';
 export * from './use-global-socket';
+export * from './use-editing-users';

+ 33 - 0
packages/core/src/swr/use-editing-users.ts

@@ -0,0 +1,33 @@
+import type { SWRResponse } from 'swr';
+
+import { IUserHasId } from '..';
+
+import { useSWRStatic } from './use-swr-static';
+
+type EditingUsersStatus = {
+  userList: IUserHasId[],
+}
+
+type EditingUsersStatusUtils = {
+  onEditorsUpdated(
+    userList: IUserHasId[],
+  ): void,
+}
+
+export const useEditingUsers = (status?: EditingUsersStatus): SWRResponse<EditingUsersStatus, Error> & EditingUsersStatusUtils => {
+  const initialData: EditingUsersStatus = {
+    userList: [],
+  };
+  const swrResponse = useSWRStatic<EditingUsersStatus, Error>('editingUsers', status, { fallbackData: initialData });
+
+  const { mutate } = swrResponse;
+
+  const onEditorsUpdated = (userList: IUserHasId[]): void => {
+    mutate({ userList });
+  };
+
+  return {
+    ...swrResponse,
+    onEditorsUpdated,
+  };
+};

+ 2 - 3
packages/editor/src/components/CodeMirrorEditorMain.tsx

@@ -22,7 +22,6 @@ type Props = CodeMirrorEditorProps & {
   pageId?: string,
   initialValue?: string,
   onOpenEditor?: (markdown: string) => void,
-  onEditorsUpdated?: (userList: IUserHasId[]) => void,
 }
 
 export const CodeMirrorEditorMain = (props: Props): JSX.Element => {
@@ -30,12 +29,12 @@ export const CodeMirrorEditorMain = (props: Props): JSX.Element => {
     acceptedUploadFileType,
     indentSize, user, pageId, initialValue,
     editorTheme, editorKeymap,
-    onSave, onChange, onUpload, onScroll, onOpenEditor, onEditorsUpdated,
+    onSave, onChange, onUpload, onScroll, onOpenEditor,
   } = props;
 
   const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(GlobalCodeMirrorEditorKey.MAIN);
 
-  useCollaborativeEditorMode(user, pageId, initialValue, onOpenEditor, onEditorsUpdated, codeMirrorEditor);
+  useCollaborativeEditorMode(user, pageId, initialValue, onOpenEditor, codeMirrorEditor);
 
   // setup additional extensions
   useEffect(() => {

+ 10 - 9
packages/editor/src/stores/use-collaborative-editor-mode.ts

@@ -1,7 +1,7 @@
 import { useEffect, useState } from 'react';
 
 import { GlobalSocketEventName, type IUserHasId } from '@growi/core/dist/interfaces';
-import { useGlobalSocket, GLOBAL_SOCKET_NS } from '@growi/core/dist/swr';
+import { useGlobalSocket, GLOBAL_SOCKET_NS, useEditingUsers } from '@growi/core/dist/swr';
 // see: https://github.com/yjs/y-codemirror.next#example
 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
 // @ts-ignore
@@ -24,7 +24,6 @@ export const useCollaborativeEditorMode = (
     pageId?: string,
     initialValue?: string,
     onOpenEditor?: (markdown: string) => void,
-    onEditorsUpdated?: (userList: IUserHasId[]) => void,
     codeMirrorEditor?: UseCodeMirrorEditor,
 ): void => {
   const [ydoc, setYdoc] = useState<Y.Doc | null>(null);
@@ -32,6 +31,7 @@ export const useCollaborativeEditorMode = (
   const [isInit, setIsInit] = useState(false);
   const [cPageId, setCPageId] = useState(pageId);
 
+  const { onEditorsUpdated } = useEditingUsers();
   const { data: socket } = useGlobalSocket();
 
   const cleanupYDocAndProvider = () => {
@@ -51,6 +51,9 @@ export const useCollaborativeEditorMode = (
 
     setIsInit(false);
     setCPageId(pageId);
+
+    // reset editors
+    onEditorsUpdated([]);
   };
 
   const setupYDoc = () => {
@@ -96,12 +99,10 @@ export const useCollaborativeEditorMode = (
 
     // update args type see: SocketIOProvider.Awareness.awarenessUpdate
     socketIOProvider.awareness.on('update', (update: any) => {
-      if (onEditorsUpdated) {
-        const { added, removed } = update;
-        if (added.length > 0 || removed.length > 0) {
-          const userList: IUserHasId[] = Array.from(socketIOProvider.awareness.states.values(), value => value.user.user && value.user.user);
-          onEditorsUpdated(userList);
-        }
+      const { added, removed } = update;
+      if (added.length > 0 || removed.length > 0) {
+        const userList: IUserHasId[] = Array.from(socketIOProvider.awareness.states.values(), value => value.user.user && value.user.user);
+        onEditorsUpdated(userList);
       }
     });
 
@@ -135,7 +136,7 @@ export const useCollaborativeEditorMode = (
     setIsInit(true);
   };
 
-  useEffect(cleanupYDocAndProvider, [cPageId, pageId, provider, socket, ydoc]);
+  useEffect(cleanupYDocAndProvider, [cPageId, onEditorsUpdated, pageId, provider, socket, ydoc]);
   useEffect(setupYDoc, [provider, ydoc]);
   useEffect(setupProvider, [initialValue, onEditorsUpdated, pageId, provider, socket, user, ydoc]);
   useEffect(setupYDocExtensions, [codeMirrorEditor, provider, ydoc]);