Просмотр исходного кода

add hook and get caretline from it

reiji-h 1 год назад
Родитель
Сommit
8c5a706c30

+ 2 - 0
apps/app/src/client/components/Page/DisplaySwitcher.tsx

@@ -1,6 +1,7 @@
 import dynamic from 'next/dynamic';
 
 import { useHashChangedEffect } from '~/client/services/side-effects/hash-changed';
+import { useSaveNextCaretLine } from '~/client/services/side-effects/save-next-caret-line';
 import { useIsEditable } from '~/stores-universal/context';
 import { EditorMode, useEditorMode } from '~/stores-universal/ui';
 import { useIsLatestRevision } from '~/stores/page';
@@ -18,6 +19,7 @@ export const DisplaySwitcher = (): JSX.Element => {
   const { data: isLatestRevision } = useIsLatestRevision();
 
   useHashChangedEffect();
+  useSaveNextCaretLine();
 
   return (
     <LazyRenderer shouldRender={isEditable === true && editorMode === EditorMode.Editor}>

+ 5 - 12
apps/app/src/client/components/PageEditor/PageEditor.tsx

@@ -19,6 +19,7 @@ import { useTranslation } from 'next-i18next';
 import { throttle, debounce } from 'throttle-debounce';
 
 import { useUpdateStateAfterSave } from '~/client/services/page-operation';
+import { useSaveNextCaretLine } from '~/client/services/side-effects/save-next-caret-line';
 import { updatePage, extractRemoteRevisionDataFromErrorObj } from '~/client/services/update-page';
 import { uploadAttachments } from '~/client/services/upload-attachments';
 import { toastError, toastSuccess, toastWarning } from '~/client/util/toastr';
@@ -109,6 +110,7 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
   const { data: user } = useCurrentUser();
   const { onEditorsUpdated } = useEditingUsers();
   const onConflict = useConflictResolver();
+  const { pick: pickNextCaretLine } = useSaveNextCaretLine();
 
   const { data: rendererOptions } = usePreviewOptions();
 
@@ -300,19 +302,10 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
 
   // set handler to set caret line
   useEffect(() => {
-    const handler = (lineNumber?: number) => {
-      codeMirrorEditor?.setCaretLine(lineNumber, true);
-    };
-    globalEmitter.on('setCaretLine', handler);
-    if (globalEmitter.listenerCount('getCaretLine') >= 1 && codeMirrorEditor?.view != null) {
-      globalEmitter.emit('getCaretLine', handler);
-      globalEmitter.removeAllListeners('getCaretLine');
+    if (editorMode === EditorMode.Editor) {
+      codeMirrorEditor?.setCaretLine(pickNextCaretLine() ?? 0, true);
     }
-
-    return function cleanup() {
-      globalEmitter.removeListener('setCaretLine', handler);
-    };
-  }, [codeMirrorEditor, codeMirrorEditor?.view]);
+  }, [codeMirrorEditor, editorMode, pickNextCaretLine]);
 
   // TODO: Check the reproduction conditions that made this code necessary and confirm reproduction
   // // when transitioning to a different page, if the initialValue is the same,

+ 1 - 1
apps/app/src/client/components/ReactMarkdownComponents/Header.tsx

@@ -27,7 +27,7 @@ declare global {
 
 function setCaretLine(line?: number): void {
   if (line != null) {
-    globalEmitter.emit('setCaretLine', line);
+    globalEmitter.emit('saveNextCaretLine', line);
   }
 }
 

+ 44 - 0
apps/app/src/client/services/side-effects/save-next-caret-line.ts

@@ -0,0 +1,44 @@
+import { useCallback, useEffect } from 'react';
+
+import type EventEmitter from 'events';
+
+import { useSWRStatic } from '@growi/core/dist/swr';
+import type { SWRResponse } from 'swr';
+
+declare global {
+  // eslint-disable-next-line vars-on-top, no-var
+  var globalEmitter: EventEmitter;
+}
+
+type SaveNextCaretLineUtils = {
+  pick(): number | undefined,
+}
+
+export const useSaveNextCaretLine = (initialData?: number): SWRResponse<number> & SaveNextCaretLineUtils => {
+
+  const swrResponse = useSWRStatic('saveNextCaretLine', initialData, { fallbackData: 0 });
+  const { data, mutate } = swrResponse;
+
+  const pick = useCallback(() => {
+    const tmp = data;
+    mutate(0);
+    return tmp;
+  }, [data, mutate]);
+
+  useEffect(() => {
+    const handler = (lineNumber: number) => {
+      mutate(lineNumber);
+    };
+
+    globalEmitter.on('saveNextCaretLine', handler);
+
+    return function cleanup() {
+      globalEmitter.removeListener('saveNextCaretLine', handler);
+    };
+  }, [mutate]);
+
+  return {
+    ...swrResponse,
+    pick,
+  };
+};