2
0
Yuki Takei 5 сар өмнө
parent
commit
6ee9ce63ae

+ 8 - 1
apps/app/src/client/services/side-effects/page-updated.ts

@@ -6,6 +6,7 @@ import type { RemoteRevisionData } from '~/states/page';
 import { useGlobalSocket } from '~/states/socket-io';
 import { useEditorMode, EditorMode } from '~/states/ui/editor';
 import { usePageStatusAlertActions } from '~/states/ui/modal/page-status-alert';
+import { useSWRxPageInfo } from '~/stores/page';
 
 
 export const usePageUpdatedEffect = (): void => {
@@ -18,6 +19,8 @@ export const usePageUpdatedEffect = (): void => {
   const { fetchCurrentPage } = useFetchCurrentPage();
   const { open: openPageStatusAlert, close: closePageStatusAlert } = usePageStatusAlertActions();
 
+  const { mutate: mutatePageInfo } = useSWRxPageInfo(currentPage?._id);
+
   const remotePageDataUpdateHandler = useCallback((data) => {
     // Set remote page data
     const { s2cMessagePageUpdated } = data;
@@ -32,6 +35,9 @@ export const usePageUpdatedEffect = (): void => {
     if (currentPage?._id != null && currentPage._id === s2cMessagePageUpdated.pageId) {
       setRemoteLatestPageData(remoteData);
 
+      // Update PageInfo cache
+      mutatePageInfo();
+
       // Open PageStatusAlert
       const currentRevisionId = currentPage?.revision?._id;
       const remoteRevisionId = s2cMessagePageUpdated.revisionId;
@@ -47,7 +53,8 @@ export const usePageUpdatedEffect = (): void => {
         closePageStatusAlert();
       }
     }
-  }, [currentPage?._id, currentPage?.revision?._id, editorMode, fetchCurrentPage, openPageStatusAlert, closePageStatusAlert, setRemoteLatestPageData]);
+  // eslint-disable-next-line max-len
+  }, [currentPage?._id, currentPage?.revision?._id, setRemoteLatestPageData, mutatePageInfo, editorMode, openPageStatusAlert, fetchCurrentPage, closePageStatusAlert]);
 
   // listen socket for someone updating this page
   useEffect(() => {

+ 11 - 1
apps/app/src/pages/[[...path]]/index.page.tsx

@@ -4,8 +4,9 @@ import { useEffect } from 'react';
 import type { GetServerSideProps, GetServerSidePropsContext } from 'next';
 import dynamic from 'next/dynamic';
 import Head from 'next/head';
+import EventEmitter from 'node:events';
+import { isIPageInfo } from '@growi/core';
 import { isClient } from '@growi/core/dist/utils';
-import EventEmitter from 'events';
 
 // biome-ignore-start lint/style/noRestrictedImports: no-problem lazy loaded components
 import { DescendantsPageListModalLazyLoaded } from '~/client/components/DescendantsPageListModal';
@@ -30,6 +31,7 @@ import {
   useSetupGlobalSocketForPage,
 } from '~/states/socket-io';
 import { useSetEditingMarkdown } from '~/states/ui/editor';
+import { useSWRxPageInfo } from '~/stores/page';
 
 import type { NextPageWithLayout } from '../_app.page';
 import { useHydrateBasicLayoutConfigurationAtoms } from '../basic-layout-page/hydrate';
@@ -146,6 +148,14 @@ const Page: NextPageWithLayout<Props> = (props: Props) => {
     }
   }, [currentPagePath, currentPage?.revision?.body, setEditingMarkdown]);
 
+  // Optimistically update PageInfo SWR cache with SSR data
+  const { mutate: mutatePageInfo } = useSWRxPageInfo(currentPage?._id);
+  useEffect(() => {
+    if (isInitialProps(props) && pageMeta != null && isIPageInfo(pageMeta)) {
+      mutatePageInfo(pageMeta, { revalidate: false });
+    }
+  }, [pageMeta, mutatePageInfo, props]);
+
   // If the data on the page changes without router.push, pageWithMeta remains old because getServerSideProps() is not executed
   // So preferentially take page data from useSWRxCurrentPage
   const pagePath = currentPagePath ?? props.currentPathname;

+ 8 - 1
apps/app/src/states/page/use-fetch-current-page.ts

@@ -11,6 +11,7 @@ import { useAtomValue } from 'jotai';
 import { useAtomCallback } from 'jotai/utils';
 
 import { apiv3Get } from '~/client/util/apiv3-client';
+import { useSWRxPageInfo } from '~/stores/page';
 import loggerFactory from '~/utils/logger';
 
 import { useRevisionIdFromUrl } from '../context';
@@ -177,10 +178,13 @@ export const useFetchCurrentPage = (): {
 } => {
   const shareLinkId = useAtomValue(shareLinkIdAtom);
   const revisionIdFromUrl = useRevisionIdFromUrl();
+  const currentPageId = useAtomValue(currentPageIdAtom);
 
   const isLoading = useAtomValue(pageLoadingAtom);
   const error = useAtomValue(pageErrorAtom);
 
+  const { mutate: mutatePageInfo } = useSWRxPageInfo(currentPageId, shareLinkId);
+
   const fetchCurrentPage = useAtomCallback(
     useCallback(
       async (
@@ -234,6 +238,9 @@ export const useFetchCurrentPage = (): {
           set(pageNotFoundAtom, false);
           set(isForbiddenAtom, false);
 
+          // Mutate PageInfo to refetch latest metadata including latestRevisionId
+          mutatePageInfo();
+
           return newData;
         } catch (err) {
           if (!Array.isArray(err) || err.length === 0) {
@@ -260,7 +267,7 @@ export const useFetchCurrentPage = (): {
 
         return null;
       },
-      [shareLinkId, revisionIdFromUrl],
+      [shareLinkId, revisionIdFromUrl, mutatePageInfo],
     ),
   );