Taichi Masuyama 3 лет назад
Родитель
Сommit
d205225ddf

+ 2 - 2
packages/app/src/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -15,7 +15,7 @@ import {
 import { IResTagsUpdateApiv1 } from '~/interfaces/tag';
 import { OnDuplicatedFunction, OnRenamedFunction, OnDeletedFunction } from '~/interfaces/ui';
 import {
-  useCurrentPageId, useCurrentPathname,
+  useCurrentPageId, useCurrentPathname, useIsNotFound,
   useCurrentUser, useIsGuestUser, useIsSharedUser, useShareLinkId, useTemplateTagData,
 } from '~/stores/context';
 import { usePageTagsForEditors } from '~/stores/editor';
@@ -26,7 +26,7 @@ import {
 import { useSWRxCurrentPage, useSWRxTagsInfo } from '~/stores/page';
 import {
   EditorMode, useDrawerMode, useEditorMode, useIsAbleToShowPageManagement, useIsAbleToShowTagLabel,
-  useIsAbleToShowPageEditorModeManager, useIsAbleToShowPageAuthors, useIsNotFound,
+  useIsAbleToShowPageEditorModeManager, useIsAbleToShowPageAuthors,
 } from '~/stores/ui';
 
 import CreateTemplateModal from '../CreateTemplateModal';

+ 2 - 2
packages/app/src/components/Page/DisplaySwitcher.tsx

@@ -7,11 +7,11 @@ import { Link } from 'react-scroll';
 
 import { DEFAULT_AUTO_SCROLL_OPTS } from '~/client/util/smooth-scroll';
 import {
-  useIsSharedUser, useIsEditable, useShareLinkId,
+  useIsSharedUser, useIsEditable, useShareLinkId, useIsNotFound,
 } from '~/stores/context';
 import { useDescendantsPageListModal } from '~/stores/modal';
 import { useCurrentPagePath, useSWRxCurrentPage } from '~/stores/page';
-import { EditorMode, useEditorMode, useIsNotFound } from '~/stores/ui';
+import { EditorMode, useEditorMode } from '~/stores/ui';
 
 import CountBadge from '../Common/CountBadge';
 import { ContentLinkButtonsProps } from '../ContentLinkButtons';

+ 1 - 1
packages/app/src/components/PageAlert/PageAlerts.tsx

@@ -2,7 +2,7 @@ import React from 'react';
 
 import dynamic from 'next/dynamic';
 
-import { useIsNotFound } from '~/stores/ui';
+import { useIsNotFound } from '~/stores/context';
 
 import { FixPageGrantAlert } from './FixPageGrantAlert';
 import { OldRevisionAlert } from './OldRevisionAlert';

+ 5 - 9
packages/app/src/components/PageEditor.tsx

@@ -7,6 +7,7 @@ import EventEmitter from 'events';
 import { envUtils, PageGrant } from '@growi/core';
 import detectIndent from 'detect-indent';
 import { useTranslation } from 'next-i18next';
+import { useRouter } from 'next/router';
 import { throttle, debounce } from 'throttle-debounce';
 
 import { saveOrUpdate } from '~/client/services/page-operation';
@@ -26,7 +27,7 @@ import { useCurrentPagePath, useSWRxCurrentPage } from '~/stores/page';
 import { usePreviewOptions } from '~/stores/renderer';
 import {
   EditorMode,
-  useEditorMode, useIsMobile, useIsNotFound, useSelectedGrant,
+  useEditorMode, useIsMobile, useSelectedGrant,
 } from '~/stores/ui';
 import loggerFactory from '~/utils/logger';
 
@@ -51,11 +52,11 @@ let isOriginOfScrollSyncPreview = false;
 const PageEditor = React.memo((): JSX.Element => {
 
   const { t } = useTranslation();
+  const router = useRouter();
 
-  const { data: pageId, mutate: mutateCurrentPageId } = useCurrentPageId();
+  const { data: pageId } = useCurrentPageId();
   const { data: currentPagePath } = useCurrentPagePath();
   const { data: currentPathname } = useCurrentPathname();
-  const { mutate: mutateIsNotFound } = useIsNotFound();
   const { data: currentPage, mutate: mutateCurrentPage } = useSWRxCurrentPage();
   const { data: grantData, mutate: mutateGrant } = useSelectedGrant();
   const { data: pageTags } = usePageTagsForEditors(pageId);
@@ -135,12 +136,7 @@ const PageEditor = React.memo((): JSX.Element => {
         markdownToSave.current,
       );
 
-      // TODO: Consider to make a function for this process https://redmine.weseek.co.jp/issues/108795
-      await mutateCurrentPageId(page._id);
-      await mutateCurrentPage();
-      if (typeof page?.revision.body === 'string') {
-        await mutateIsNotFound(false);
-      }
+      await router.push(`/${page._id}`);
       mutateIsEnabledUnsavedWarning(false);
       return true;
     }

+ 1 - 1
packages/app/src/components/PagePathNav.tsx

@@ -3,7 +3,7 @@ import React, { FC } from 'react';
 import { DevidedPagePath, pagePathUtils } from '@growi/core';
 import dynamic from 'next/dynamic';
 
-import { useIsNotFound } from '~/stores/ui';
+import { useIsNotFound } from '~/stores/context';
 
 import LinkedPagePath from '../models/linked-page-path';
 

+ 2 - 2
packages/app/src/pages/[[...path]].page.tsx

@@ -41,7 +41,7 @@ import { useRedirectFrom } from '~/stores/page-redirect';
 import {
   EditorMode,
   useEditorMode, useSelectedGrant,
-  usePreferDrawerModeByUser, usePreferDrawerModeOnEditByUser, useSidebarCollapsed, useCurrentSidebarContents, useCurrentProductNavWidth, useIsNotFound,
+  usePreferDrawerModeByUser, usePreferDrawerModeOnEditByUser, useSidebarCollapsed, useCurrentSidebarContents, useCurrentProductNavWidth,
 } from '~/stores/ui';
 import loggerFactory from '~/utils/logger';
 
@@ -62,7 +62,7 @@ import {
   useIsEnabledStaleNotification, useIsIdenticalPath,
   useIsSearchServiceConfigured, useIsSearchServiceReachable, useDisableLinkSharing,
   useDrawioUri, useHackmdUri, useDefaultIndentSize, useIsIndentSizeForced,
-  useIsAclEnabled, useIsSearchPage,
+  useIsAclEnabled, useIsSearchPage, useIsNotFound,
   useCsrfToken, useIsSearchScopeChildrenAsDefault, useCurrentPageId, useCurrentPathname,
   useIsSlackConfigured, useRendererConfig, useEditingMarkdown,
   useEditorConfig, useIsAllReplyShown, useIsUploadableFile, useIsUploadableImage, useCustomizedLogoSrc,

+ 6 - 9
packages/app/src/stores/context.tsx

@@ -56,15 +56,8 @@ export const useCurrentPathname = (initialData?: string): SWRResponse<string, Er
   return useContextSWR('currentPathname', initialData);
 };
 
-// TODO: Consider place https://redmine.weseek.co.jp/issues/108795
-export const useCurrentPageId = (fallbackData?: Nullable<string>): SWRResponse<Nullable<string>, Error> => {
-  const { fallback } = useSWRConfig();
-
-  if (fallbackData !== undefined) {
-    fallback.currentPageId = fallbackData;
-  }
-
-  return useStaticSWR<Nullable<string>, Error>('currentPageId');
+export const useCurrentPageId = (initialData?: Nullable<string>): SWRResponse<Nullable<string>, Error> => {
+  return useStaticSWR<Nullable<string>, Error>('currentPageId', initialData);
 };
 
 export const useIsIdenticalPath = (initialData?: boolean): SWRResponse<boolean, Error> => {
@@ -75,6 +68,10 @@ export const useIsForbidden = (initialData?: boolean): SWRResponse<boolean, Erro
   return useContextSWR<boolean, Error>('isForbidden', initialData, { fallbackData: false });
 };
 
+export const useIsNotFound = (initialData?: boolean): SWRResponse<boolean, Error> => {
+  return useContextSWR<boolean, Error>('isNotFound', initialData, { fallbackData: false });
+};
+
 export const useTemplateTagData = (initialData?: Nullable<string>): SWRResponse<Nullable<string>, Error> => {
   return useContextSWR<Nullable<string>, Error>('templateTagData', initialData);
 };

+ 1 - 7
packages/app/src/stores/ui.tsx

@@ -23,7 +23,7 @@ import loggerFactory from '~/utils/logger';
 
 import {
   useCurrentPageId, useIsEditable, useIsGuestUser,
-  useIsSharedUser, useIsIdenticalPath, useCurrentUser, useShareLinkId,
+  useIsSharedUser, useIsIdenticalPath, useCurrentUser, useShareLinkId, useIsNotFound,
 } from './context';
 import { localStorageMiddleware } from './middlewares/sync-to-storage';
 import { useCurrentPagePath, useIsTrashPage } from './page';
@@ -396,12 +396,6 @@ export const usePageTreeDescCountMap = (initialData?: UpdateDescCountData): SWRR
   };
 };
 
-// TODO: Consider place https://redmine.weseek.co.jp/issues/108795
-export const useIsNotFound = (fallbackData?: boolean): SWRResponse<boolean, Error> => {
-  return useStaticSWR<boolean, Error>('isNotFound', undefined, { fallbackData });
-};
-
-
 /** **********************************************************
  *                          SWR Hooks
  *                Determined value by context

+ 16 - 3
packages/app/src/stores/use-context-swr.tsx

@@ -1,8 +1,10 @@
+import assert from 'assert';
+
 import {
-  Key, SWRConfiguration, SWRResponse,
+  Key, SWRConfiguration, SWRResponse, useSWRConfig,
 } from 'swr';
+import useSWRImmutable from 'swr/immutable';
 
-import { useStaticSWR } from './use-static-swr';
 
 export function useContextSWR<Data, Error>(key: Key): SWRResponse<Data, Error>;
 export function useContextSWR<Data, Error>(key: Key, data: Data | undefined): SWRResponse<Data, Error>;
@@ -16,7 +18,18 @@ export function useContextSWR<Data, Error>(
 ): SWRResponse<Data, Error> {
   const [key, data, configuration] = args;
 
-  const swrResponse = useStaticSWR<Data, Error>(key, data, configuration);
+  assert.notStrictEqual(configuration?.fetcher, null, 'useContextSWR does not support \'configuration.fetcher\'');
+
+  const { cache } = useSWRConfig();
+  const swrResponse = useSWRImmutable(key, null, {
+    ...configuration,
+    fallbackData: configuration?.fallbackData ?? cache.get(key),
+  });
+
+  // write data to cache directly
+  if (data !== undefined) {
+    cache.set(key, data);
+  }
 
   const result = Object.assign(swrResponse, { mutate: () => { throw Error('mutate can not be used in context') } });
 

+ 11 - 10
packages/app/src/stores/use-static-swr.tsx

@@ -1,7 +1,9 @@
+import { useEffect } from 'react';
+
 import assert from 'assert';
 
 import {
-  Key, SWRConfiguration, SWRResponse, useSWRConfig,
+  Key, SWRConfiguration, SWRResponse,
 } from 'swr';
 import useSWRImmutable from 'swr/immutable';
 
@@ -20,16 +22,15 @@ export function useStaticSWR<Data, Error>(
 
   assert.notStrictEqual(configuration?.fetcher, null, 'useStaticSWR does not support \'configuration.fetcher\'');
 
-  const { cache } = useSWRConfig();
-  const swrResponse = useSWRImmutable(key, null, {
-    ...configuration,
-    fallbackData: configuration?.fallbackData ?? cache.get(key),
-  });
+  const swrResponse = useSWRImmutable(key, null, configuration);
 
-  // write data to cache directly
-  if (data !== undefined) {
-    cache.set(key, data);
-  }
+  // Do mutate with `data` from args
+  useEffect(() => {
+    if (data !== undefined) {
+      swrResponse.mutate(data);
+    }
+  // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [data]); // Only depends on `data`
 
   return swrResponse;
 }