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

Merge pull request #5043 from weseek/imprv/switching-editor-mode-behavior

imprv: Switching editor mode behavior
Yuki Takei 4 лет назад
Родитель
Сommit
74df66d147

+ 9 - 10
packages/app/src/components/EventListeneres/HashChanged.tsx

@@ -1,23 +1,22 @@
 import { FC, useCallback, useEffect } from 'react';
 
-import { EditorMode, useEditorMode } from '~/stores/ui';
+import { useEditorMode, determineEditorModeByHash } from '~/stores/ui';
 import { useIsEditable } from '~/stores/context';
 
+/**
+ * Change editorMode by browser forward/back operation
+ */
 const HashChanged: FC<void> = () => {
   const { data: isEditable } = useIsEditable();
-  const { mutate: mutateEditorMode } = useEditorMode();
+  const { data: editorMode, mutate: mutateEditorMode } = useEditorMode();
 
   const hashchangeHandler = useCallback(() => {
-    const { hash } = window.location;
+    const newEditorMode = determineEditorModeByHash();
 
-    if (hash == null) {
-      return;
-    }
-
-    if (hash === '#edit') {
-      mutateEditorMode(EditorMode.Editor);
+    if (editorMode !== newEditorMode) {
+      mutateEditorMode(newEditorMode);
     }
-  }, [mutateEditorMode]);
+  }, [editorMode, mutateEditorMode]);
 
   // setup effect
   useEffect(() => {

+ 33 - 22
packages/app/src/stores/ui.tsx

@@ -51,15 +51,13 @@ export const useIsMobile = (): SWRResponse<boolean|null, Error> => {
   return useStaticSWR(key, null, configuration);
 };
 
-
-const updateBodyClassesForEditorMode = (newEditorMode: EditorMode) => {
+const updateBodyClassesByEditorMode = (newEditorMode: EditorMode) => {
   switch (newEditorMode) {
     case EditorMode.View:
       $('body').removeClass('on-edit');
       $('body').removeClass('builtin-editor');
       $('body').removeClass('hackmd');
       $('body').removeClass('pathname-sidebar');
-      window.history.replaceState(null, '', window.location.pathname);
       break;
     case EditorMode.Editor:
       $('body').addClass('on-edit');
@@ -69,38 +67,50 @@ const updateBodyClassesForEditorMode = (newEditorMode: EditorMode) => {
       if (window.location.pathname === '/Sidebar') {
         $('body').addClass('pathname-sidebar');
       }
-      window.location.hash = '#edit';
       break;
     case EditorMode.HackMD:
       $('body').addClass('on-edit');
       $('body').addClass('hackmd');
       $('body').removeClass('builtin-editor');
       $('body').removeClass('pathname-sidebar');
-      window.location.hash = '#hackmd';
       break;
   }
 };
 
-export const useEditorModeByHash = (): SWRResponse<EditorMode, Error> => {
-  return useSWRImmutable(
-    ['initialEditorMode', window.location.hash],
-    (key: Key, hash: string) => {
-      switch (hash) {
-        case '#edit':
-          return EditorMode.Editor;
-        case '#hackmd':
-          return EditorMode.HackMD;
-        default:
-          return EditorMode.View;
-      }
-    },
-  );
+const updateHashByEditorMode = (newEditorMode: EditorMode) => {
+  const { pathname } = window.location;
+
+  switch (newEditorMode) {
+    case EditorMode.View:
+      window.history.replaceState(null, '', pathname);
+      break;
+    case EditorMode.Editor:
+      window.history.replaceState(null, '', `${pathname}#edit`);
+      break;
+    case EditorMode.HackMD:
+      window.history.replaceState(null, '', `${pathname}#hackmd`);
+      break;
+  }
+};
+
+export const determineEditorModeByHash = (): EditorMode => {
+  const { hash } = window.location;
+
+  switch (hash) {
+    case '#edit':
+      return EditorMode.Editor;
+    case '#hackmd':
+      return EditorMode.HackMD;
+    default:
+      return EditorMode.View;
+  }
 };
 
 let isEditorModeLoaded = false;
 export const useEditorMode = (): SWRResponse<EditorMode, Error> => {
   const { data: _isEditable } = useIsEditable();
-  const { data: editorModeByHash } = useEditorModeByHash();
+
+  const editorModeByHash = determineEditorModeByHash();
 
   const isLoading = _isEditable === undefined;
   const isEditable = !isLoading && _isEditable;
@@ -115,7 +125,7 @@ export const useEditorMode = (): SWRResponse<EditorMode, Error> => {
   // initial updating
   if (!isEditorModeLoaded && !isLoading && swrResponse.data != null) {
     if (isEditable) {
-      updateBodyClassesForEditorMode(swrResponse.data);
+      updateBodyClassesByEditorMode(swrResponse.data);
     }
     isEditorModeLoaded = true;
   }
@@ -128,7 +138,8 @@ export const useEditorMode = (): SWRResponse<EditorMode, Error> => {
       if (!isEditable) {
         return Promise.resolve(EditorMode.View); // fixed if not editable
       }
-      updateBodyClassesForEditorMode(editorMode);
+      updateBodyClassesByEditorMode(editorMode);
+      updateHashByEditorMode(editorMode);
       return swrResponse.mutate(editorMode, shouldRevalidate);
     },
   };