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

Merge pull request #6580 from weseek/fix/rendering-button-on-UserPage

fix: Rendering button on UserPages
Yuki Takei 3 лет назад
Родитель
Сommit
d71899a77d

+ 2 - 2
packages/app/src/client/services/ContextExtractor.tsx

@@ -16,7 +16,7 @@ import { useSetupGlobalSocket, useSetupGlobalAdminSocket } from '~/stores/websoc
 import {
   useSiteUrl,
   useDeleteUsername, useDeletedAt, useHasChildren, useHasDraftOnHackmd,
-  useIsNotCreatable, useIsTrashPage, useIsUserPage, useLastUpdateUsername,
+  useIsTrashPage, useIsUserPage, useLastUpdateUsername,
   useCurrentPageId, usePageIdOnHackmd, usePageUser, useCurrentPagePath, useRevisionCreatedAt, useRevisionId, useRevisionIdHackmdSynced,
   useShareLinkId, useShareLinksNumber, useTemplateTagData, useCurrentUser, useTargetAndAncestors,
   useIsSearchPage, useIsForbidden, useIsIdenticalPath, useHasParent,
@@ -143,7 +143,7 @@ const ContextExtractorOnce: FC = () => {
   useHasChildren(hasChildren);
   useHasDraftOnHackmd(hasDraftOnHackmd);
   useIsIdenticalPath(isIdenticalPath);
-  useIsNotCreatable(isNotCreatable);
+  // useIsNotCreatable(isNotCreatable);
   useIsForbidden(isForbidden);
   // useIsTrashPage(isTrashPage);
   useIsUserPage(isUserPage);

+ 3 - 1
packages/app/src/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -15,7 +15,7 @@ import { IResTagsUpdateApiv1 } from '~/interfaces/tag';
 import { OnDuplicatedFunction, OnRenamedFunction, OnDeletedFunction } from '~/interfaces/ui';
 import {
   useCurrentPageId,
-  useCurrentPathname,
+  useCurrentPathname, useIsNotFound,
   useCurrentUser, useIsGuestUser, useIsSharedUser, useShareLinkId, useTemplateTagData,
 } from '~/stores/context';
 import { usePageTagsForEditors } from '~/stores/editor';
@@ -180,6 +180,7 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isSharedUser } = useIsSharedUser();
   const { data: shareLinkId } = useShareLinkId();
+  const { data: isNotFound } = useIsNotFound();
 
   const { data: isAbleToShowPageManagement } = useIsAbleToShowPageManagement();
   const { data: isAbleToShowTagLabel } = useIsAbleToShowTagLabel();
@@ -374,6 +375,7 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
       isGuestUser={isGuestUser}
       isDrawerMode={isDrawerMode}
       isCompactMode={isCompactMode}
+      isNotFound={isNotFound}
       tags={isViewMode ? tagsInfoData?.tags : tagsForEditors}
       tagsUpdatedHandler={isViewMode ? tagsUpdatedHandlerForViewMode : tagsUpdatedHandlerForEditMode}
       controls={ControlComponents}

+ 20 - 24
packages/app/src/components/Navbar/GrowiSubNavigation.tsx

@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from 'react';
+import React from 'react';
 
 import dynamic from 'next/dynamic';
 
@@ -35,6 +35,7 @@ export type GrowiSubNavigationProps = {
   isGuestUser?: boolean,
   isDrawerMode?: boolean,
   isCompactMode?: boolean,
+  isNotFound?: boolean,
   tags?: string[],
   tagsUpdatedHandler?: (newTags: string[]) => Promise<void> | void,
   controls: React.FunctionComponent,
@@ -44,12 +45,11 @@ export type GrowiSubNavigationProps = {
 export const GrowiSubNavigation = (props: GrowiSubNavigationProps): JSX.Element => {
 
   const { data: editorMode } = useEditorMode();
-  const [isControls, setControls] = useState(false);
 
   const {
     page,
     showDrawerToggler, showTagLabel, showPageAuthors,
-    isGuestUser, isDrawerMode, isCompactMode,
+    isGuestUser, isDrawerMode, isCompactMode, isNotFound,
     tags, tagsUpdatedHandler,
     controls: Controls,
     additionalClasses = [],
@@ -64,12 +64,6 @@ export const GrowiSubNavigation = (props: GrowiSubNavigationProps): JSX.Element
     createdAt, updatedAt,
   } = page;
 
-  useEffect(() => {
-    if (Controls != null) {
-      setControls(true);
-    }
-  }, [Controls]);
-
   if (path == null) {
     return <></>;
   }
@@ -93,21 +87,23 @@ export const GrowiSubNavigation = (props: GrowiSubNavigationProps): JSX.Element
           <PagePathNav pageId={pageId} pagePath={path} isSingleLineMode={isEditorMode} isCompactMode={isCompactMode} />
         </div>
       </div>
-      {/* Right side */}
-      <div className="d-flex">
-        { isControls && <Controls /> }
-        {/* Page Authors */}
-        { (showPageAuthors && !isCompactMode) && (
-          <ul className={`${AuthorInfoStyles['grw-author-info']} text-nowrap border-left d-none d-lg-block d-edit-none py-2 pl-4 mb-0 ml-3`}>
-            <li className="pb-1">
-              <AuthorInfo user={creator as IUser} date={createdAt} locate="subnav" />
-            </li>
-            <li className="mt-1 pt-1 border-top">
-              <AuthorInfo user={lastUpdateUser as IUser} date={updatedAt} mode="update" locate="subnav" />
-            </li>
-          </ul>
-        ) }
-      </div>
+      {/* Right side. isNotFound for avoid flicker when called ForbiddenPage.tsx */}
+      { !isNotFound && (
+        <div className="d-flex">
+          <Controls />
+          {/* Page Authors */}
+          { (showPageAuthors && !isCompactMode) && (
+            <ul className={`${AuthorInfoStyles['grw-author-info']} text-nowrap border-left d-none d-lg-block d-edit-none py-2 pl-4 mb-0 ml-3`}>
+              <li className="pb-1">
+                <AuthorInfo user={creator as IUser} date={createdAt} locate="subnav" />
+              </li>
+              <li className="mt-1 pt-1 border-top">
+                <AuthorInfo user={lastUpdateUser as IUser} date={updatedAt} mode="update" locate="subnav" />
+              </li>
+            </ul>
+          ) }
+        </div>
+      ) }
     </div>
   );
 };

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

@@ -6,7 +6,7 @@ import dynamic from 'next/dynamic';
 
 // import { smoothScrollIntoView } from '~/client/util/smooth-scroll';
 import {
-  useCurrentPagePath, useIsSharedUser, useIsEditable, useIsUserPage, usePageUser, useShareLinkId, useIsNotFound, useIsNotCreatable,
+  useCurrentPagePath, useIsSharedUser, useIsEditable, useIsUserPage, usePageUser, useShareLinkId, useIsNotFound,
 } from '~/stores/context';
 import { useDescendantsPageListModal } from '~/stores/modal';
 import { useSWRxCurrentPage } from '~/stores/page';

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

@@ -59,7 +59,7 @@ import {
   useIsEnabledStaleNotification, useIsIdenticalPath,
   useIsSearchServiceConfigured, useIsSearchServiceReachable, useDisableLinkSharing,
   useHackmdUri,
-  useIsAclEnabled, useIsUserPage, useIsNotCreatable,
+  useIsAclEnabled, useIsUserPage,
   useCsrfToken, useIsSearchScopeChildrenAsDefault, useCurrentPageId, useCurrentPathname,
   useIsSlackConfigured, useRendererConfig, useEditingMarkdown,
   useEditorConfig, useIsAllReplyShown, useIsUploadableFile, useIsUploadableImage,
@@ -136,7 +136,7 @@ type Props = CommonProps & {
   isIdenticalPathPage?: boolean,
   isForbidden: boolean,
   isNotFound: boolean,
-  IsNotCreatable: boolean,
+  IsNotCreatablePage: boolean,
   // isAbleToDeleteCompletely: boolean,
 
   isSearchServiceConfigured: boolean,
@@ -196,7 +196,7 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
   // useOwnerOfCurrentPage(props.pageUser != null ? JSON.parse(props.pageUser) : null);
   useIsForbidden(props.isForbidden);
   useIsNotFound(props.isNotFound);
-  useIsNotCreatable(props.IsNotCreatable);
+  // useIsNotCreatable(props.IsNotCreatable);
   useRedirectFrom(props.redirectFrom);
   // useShared();
   // useShareLinkId(props.shareLinkId);
@@ -242,7 +242,7 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
   useCurrentPageId(pageId);
   useSWRxCurrentPage(undefined, pageWithMeta?.data); // store initial data
   useIsUserPage(isUserPage(pagePath));
-  useIsNotCreatable(props.isForbidden || !isCreatablePage(pagePath)); // TODO: need to include props.isIdentical
+  // useIsNotCreatable(props.isForbidden || !isCreatablePage(pagePath)); // TODO: need to include props.isIdentical
   useCurrentPagePath(pagePath);
   useCurrentPathname(props.currentPathname);
   useEditingMarkdown(pageWithMeta?.data.revision?.body);
@@ -310,8 +310,8 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
                   <>
                     <PageAlerts />
                     { props.isForbidden && <ForbiddenPage /> }
-                    { props.IsNotCreatable && <NotCreatablePage />}
-                    { !props.isForbidden && !props.IsNotCreatable && <DisplaySwitcher />}
+                    { props.IsNotCreatablePage && <NotCreatablePage />}
+                    { !props.isForbidden && !props.IsNotCreatablePage && <DisplaySwitcher />}
                     {/* <DisplaySwitcher /> */}
                     {/* <PageStatusAlert /> */}
                   </>
@@ -434,7 +434,7 @@ async function injectRoutingInformation(context: GetServerSidePropsContext, prop
   }
   else if (page == null) {
     props.isNotFound = true;
-    props.IsNotCreatable = !isCreatablePage(currentPathname);
+    props.IsNotCreatablePage = !isCreatablePage(currentPathname);
     // check the page is forbidden or just does not exist.
     const count = isPermalink ? await Page.count({ _id: pageId }) : await Page.count({ path: currentPathname });
     props.isForbidden = count > 0;

+ 8 - 8
packages/app/src/stores/context.tsx

@@ -87,10 +87,9 @@ export const useIsTrashPage = (initialData?: boolean): SWRResponse<boolean, Erro
   return useStaticSWR<boolean, Error>('isTrashPage', initialData, { fallbackData: false });
 };
 
-export const useIsNotCreatable = (initialData?: boolean): SWRResponse<boolean, Error> => {
-  return useStaticSWR<boolean, Error>('isNotCreatable', initialData, { fallbackData: false });
-};
-
+// export const useIsNotCreatable = (initialData?: boolean): SWRResponse<boolean, Error> => {
+//   return useStaticSWR<boolean, Error>('isNotCreatable', initialData, { fallbackData: false });
+// };
 export const useIsForbidden = (initialData?: boolean): SWRResponse<boolean, Error> => {
   return useStaticSWR<boolean, Error>('isForbidden', initialData, { fallbackData: false });
 };
@@ -275,13 +274,14 @@ export const useIsGuestUser = (): SWRResponse<boolean, Error> => {
 
 export const useIsEditable = (): SWRResponse<boolean, Error> => {
   const { data: isGuestUser } = useIsGuestUser();
-  const { data: isNotCreatable } = useIsNotCreatable();
+  const { data: isForbidden } = useIsForbidden();
+  const { data: isIdenticalPath } = useIsIdenticalPath();
   const { data: isTrashPage } = useIsTrashPage();
 
   return useSWRImmutable(
-    ['isEditable', isGuestUser, isTrashPage, isNotCreatable],
-    (key: Key, isGuestUser: boolean, isTrashPage: boolean, isNotCreatable: boolean) => {
-      return (!isNotCreatable && !isTrashPage && !isGuestUser);
+    ['isEditable', isGuestUser, isForbidden, isIdenticalPath, isTrashPage],
+    (key: Key, isGuestUser: boolean, isForbidden: boolean, isIdenticalPath: boolean, isTrashPage: boolean) => {
+      return (!isTrashPage && !isForbidden && !isIdenticalPath && !isGuestUser);
     },
   );
 };

+ 4 - 6
packages/app/src/stores/ui.tsx

@@ -22,7 +22,7 @@ import loggerFactory from '~/utils/logger';
 
 import {
   useCurrentPageId, useCurrentPagePath, useIsEditable, useIsTrashPage, useIsUserPage, useIsGuestUser,
-  useIsNotCreatable, useIsSharedUser, useIsForbidden, useIsIdenticalPath, useCurrentUser, useIsNotFound, useShareLinkId,
+  useIsSharedUser, useIsIdenticalPath, useCurrentUser, useIsNotFound, useShareLinkId,
 } from './context';
 import { localStorageMiddleware } from './middlewares/sync-to-storage';
 import { useStaticSWR } from './use-static-swr';
@@ -445,16 +445,14 @@ export const useIsAbleToShowTagLabel = (): SWRResponse<boolean, Error> => {
 
 export const useIsAbleToShowPageEditorModeManager = (): SWRResponse<boolean, Error> => {
   const key = 'isAbleToShowPageEditorModeManager';
-  const { data: isNotCreatable } = useIsNotCreatable();
-  const { data: isForbidden } = useIsForbidden();
-  const { data: isTrashPage } = useIsTrashPage();
+  const { data: isEditable } = useIsEditable();
   const { data: isSharedUser } = useIsSharedUser();
 
-  const includesUndefined = [isNotCreatable, isForbidden, isTrashPage, isSharedUser].some(v => v === undefined);
+  const includesUndefined = [isEditable, isSharedUser].some(v => v === undefined);
 
   return useSWRImmutable(
     includesUndefined ? null : key,
-    () => !isNotCreatable && !isForbidden && !isTrashPage && !isSharedUser,
+    () => !!isEditable && !isSharedUser,
   );
 };