Kaynağa Gözat

render CustomSidebar with suspense

Yuki Takei 2 yıl önce
ebeveyn
işleme
fdd7831a59

+ 7 - 27
apps/app/src/components/Sidebar/Custom/CustomSidebar.tsx

@@ -1,30 +1,20 @@
-import dynamic from 'next/dynamic';
+import { Suspense } from 'react';
+
 import Link from 'next/link';
 import { useTranslation } from 'react-i18next';
 
 import { useSWRxPageByPath } from '~/stores/page';
-import { useCustomSidebarOptions } from '~/stores/renderer';
 
 import { SidebarHeaderReloadButton } from '../SidebarHeaderReloadButton';
 import DefaultContentSkeleton from '../Skeleton/DefaultContentSkeleton';
 
-import { SidebarNotFound } from './CustomSidebarNotFound';
-
+import { CustomSidebarSubstance } from './CustomSidebarSubstance';
 
-const CustomSidebarSubstance = dynamic(
-  () => import('./CustomSidebarSubstance').then(mod => mod.CustomSidebarSubstance),
-  { ssr: false, loading: DefaultContentSkeleton },
-);
 
 export const CustomSidebar = (): JSX.Element => {
   const { t } = useTranslation();
 
-  const { data: rendererOptions, isLoading: isLoadingRendererOptions } = useCustomSidebarOptions();
-  const { data: page, mutate, isLoading: isLoadingPage } = useSWRxPageByPath('/Sidebar');
-
-  const isLoading = isLoadingPage || isLoadingRendererOptions;
-
-  const markdown = page?.revision.body;
+  const { mutate, isLoading } = useSWRxPageByPath('/Sidebar');
 
   return (
     <div className="px-3">
@@ -36,19 +26,9 @@ export const CustomSidebar = (): JSX.Element => {
         { !isLoading && <SidebarHeaderReloadButton onClick={() => mutate()} /> }
       </div>
 
-      { isLoading
-        ? <DefaultContentSkeleton />
-        : (
-          <>
-            { rendererOptions != null && markdown != null && (
-              <CustomSidebarSubstance markdown={markdown} rendererOptions={rendererOptions} />
-            ) }
-            { markdown === undefined && (
-              <SidebarNotFound />
-            ) }
-          </>
-        )
-      }
+      <Suspense fallback={<DefaultContentSkeleton />}>
+        <CustomSidebarSubstance />
+      </Suspense>
     </div>
   );
 };

+ 19 - 11
apps/app/src/components/Sidebar/Custom/CustomSidebarSubstance.tsx

@@ -1,29 +1,37 @@
 import React from 'react';
 
 import RevisionRenderer from '~/components/Page/RevisionRenderer';
-import type { RendererOptions } from '~/interfaces/renderer-options';
+import { useSWRxPageByPath } from '~/stores/page';
+import { useCustomSidebarOptions } from '~/stores/renderer';
 import loggerFactory from '~/utils/logger';
 
+import { SidebarNotFound } from './CustomSidebarNotFound';
+
 import styles from './CustomSidebarSubstance.module.scss';
 
 
 const logger = loggerFactory('growi:components:CustomSidebarSubstance');
 
 
-type Props = {
-  markdown: string,
-  rendererOptions: RendererOptions
-}
+export const CustomSidebarSubstance = (): JSX.Element => {
+  const { data: rendererOptions } = useCustomSidebarOptions({ suspense: true });
+  const { data: page } = useSWRxPageByPath('/Sidebar', { suspense: true });
+
+  if (rendererOptions == null) return <></>;
 
-export const CustomSidebarSubstance = (props: Props): JSX.Element => {
-  const { markdown, rendererOptions } = props;
+  const markdown = page?.revision.body;
 
   return (
     <div className={`py-3 grw-custom-sidebar-content ${styles['grw-custom-sidebar-content']}`}>
-      <RevisionRenderer
-        rendererOptions={rendererOptions}
-        markdown={markdown}
-      />
+      { markdown === undefined
+        ? <SidebarNotFound />
+        : (
+          <RevisionRenderer
+            rendererOptions={rendererOptions}
+            markdown={markdown}
+          />
+        )
+      }
     </div>
   );
 };

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

@@ -18,11 +18,14 @@ import DrawerToggler from '../Navbar/DrawerToggler';
 import { StickyStretchableScrollerProps } from '../StickyStretchableScroller';
 
 import { NavigationResizeHexagon } from './NavigationResizeHexagon';
-import { SidebarContents } from './SidebarContents';
 import { SidebarNav } from './SidebarNav';
 
 import styles from './Sidebar.module.scss';
 
+
+const SidebarContents = dynamic(() => import('./SidebarContents').then(mod => mod.SidebarContents), { ssr: false });
+
+
 const StickyStretchableScroller = dynamic<StickyStretchableScrollerProps>(() => import('../StickyStretchableScroller')
   .then(mod => mod.StickyStretchableScroller), { ssr: false });
 

+ 1 - 1
apps/app/src/components/Sidebar/SidebarContents.tsx

@@ -4,7 +4,7 @@ import { SidebarContentsType } from '~/interfaces/ui';
 import { useCurrentSidebarContents } from '~/stores/ui';
 
 import { Bookmarks } from './Bookmarks';
-import CustomSidebar from './CustomSidebar';
+import { CustomSidebar } from './Custom';
 import PageTree from './PageTree';
 import RecentChanges from './RecentChanges';
 import Tag from './Tag';

+ 5 - 2
apps/app/src/stores/page.tsx

@@ -8,7 +8,9 @@ import type {
   IRevision, IRevisionHasId,
 } from '@growi/core';
 import { isClient, pagePathUtils } from '@growi/core/dist/utils';
-import useSWR, { mutate, useSWRConfig, type SWRResponse } from 'swr';
+import useSWR, {
+  mutate, useSWRConfig, type SWRResponse, type SWRConfiguration,
+} from 'swr';
 import useSWRImmutable from 'swr/immutable';
 import useSWRInfinite, { type SWRInfiniteResponse } from 'swr/infinite';
 import useSWRMutation, { type SWRMutationResponse } from 'swr/mutation';
@@ -105,11 +107,12 @@ export const useSWRMUTxCurrentPage = (): SWRMutationResponse<IPagePopulatedToSho
   );
 };
 
-export const useSWRxPageByPath = (path?: string): SWRResponse<IPagePopulatedToShowRevision, Error> => {
+export const useSWRxPageByPath = (path?: string, config?: SWRConfiguration): SWRResponse<IPagePopulatedToShowRevision, Error> => {
   return useSWR(
     path != null ? ['/page', path] : null,
     ([endpoint, path]) => apiv3Get<{ page: IPagePopulatedToShowRevision }>(endpoint, { path }).then(result => result.data.page),
     {
+      ...config,
       keepPreviousData: true,
       revalidateOnFocus: false,
       revalidateOnReconnect: false,

+ 3 - 2
apps/app/src/stores/renderer.tsx

@@ -1,7 +1,7 @@
 import { useCallback } from 'react';
 
 import type { HtmlElementNode } from 'rehype-toc';
-import useSWR, { type SWRResponse } from 'swr';
+import useSWR, { type SWRConfiguration, type SWRResponse } from 'swr';
 
 import { getGrowiFacade } from '~/features/growi-plugin/client/utils/growi-facade-utils';
 import type { RendererOptions } from '~/interfaces/renderer-options';
@@ -147,7 +147,7 @@ export const useSearchResultOptions = useSelectedPagePreviewOptions;
 
 export const useTimelineOptions = useSelectedPagePreviewOptions;
 
-export const useCustomSidebarOptions = (): SWRResponse<RendererOptions, Error> => {
+export const useCustomSidebarOptions = (config?: SWRConfiguration): SWRResponse<RendererOptions, Error> => {
   const { data: rendererConfig } = useRendererConfig();
 
   const isAllDataValid = rendererConfig != null;
@@ -161,6 +161,7 @@ export const useCustomSidebarOptions = (): SWRResponse<RendererOptions, Error> =
       return generateSimpleViewOptions(rendererConfig, '/');
     },
     {
+      ...config,
       keepPreviousData: true,
       revalidateOnFocus: false,
       revalidateOnReconnect: false,