Taichi Masuyama 4 years ago
parent
commit
b636667e2a

+ 3 - 3
packages/app/src/components/Fab.jsx

@@ -6,7 +6,7 @@ import loggerFactory from '~/utils/logger';
 
 import AppContainer from '~/client/services/AppContainer';
 import NavigationContainer from '~/client/services/NavigationContainer';
-import { usePageCreateModalOpened } from '~/stores/ui';
+import { useCreateModalStatus } from '~/stores/ui';
 
 import { withUnstatedContainers } from './UnstatedUtils';
 import CreatePageIcon from './Icons/CreatePageIcon';
@@ -18,7 +18,7 @@ const Fab = (props) => {
   const { navigationContainer, appContainer } = props;
   const { currentUser } = appContainer;
 
-  const { mutate: mutatePageCreateModalOpened } = usePageCreateModalOpened();
+  const { mutate: mutateModalStatus } = useCreateModalStatus();
 
   const [animateClasses, setAnimateClasses] = useState('invisible');
   const [buttonClasses, setButtonClasses] = useState('');
@@ -56,7 +56,7 @@ const Fab = (props) => {
           <button
             type="button"
             className={`btn btn-lg btn-create-page btn-primary rounded-circle p-0 waves-effect waves-light ${buttonClasses}`}
-            onClick={() => mutatePageCreateModalOpened(true)}
+            onClick={async() => mutateModalStatus({ isOpened: true })}
           >
             <CreatePageIcon />
           </button>

+ 4 - 4
packages/app/src/components/Hotkeys/Subscribers/CreatePage.jsx

@@ -1,19 +1,19 @@
 import React, { useEffect } from 'react';
 import PropTypes from 'prop-types';
 
-import { usePageCreateModalOpened } from '~/stores/ui';
+import { useCreateModalStatus } from '~/stores/ui';
 
 const CreatePage = React.memo((props) => {
 
-  const { mutate } = usePageCreateModalOpened();
+  const { mutate: mutateModalStatus } = useCreateModalStatus();
 
   // setup effect
   useEffect(() => {
-    mutate(true);
+    mutateModalStatus({ isOpened: true });
 
     // remove this
     props.onDeleteRender(this);
-  }, [mutate, props]);
+  }, [mutateModalStatus, props]);
 
   return <></>;
 });

+ 3 - 3
packages/app/src/components/Navbar/GrowiNavbar.tsx

@@ -7,7 +7,7 @@ import { UncontrolledTooltip } from 'reactstrap';
 
 import AppContainer from '~/client/services/AppContainer';
 import { IUser } from '~/interfaces/user';
-import { useIsDeviceSmallerThanMd, usePageCreateModalOpened } from '~/stores/ui';
+import { useIsDeviceSmallerThanMd, useCreateModalStatus } from '~/stores/ui';
 
 import { withUnstatedContainers } from '../UnstatedUtils';
 import GrowiLogo from '../Icons/GrowiLogo';
@@ -20,7 +20,7 @@ type NavbarRightProps = {
 }
 const NavbarRight: FC<NavbarRightProps> = memo((props: NavbarRightProps) => {
   const { t } = useTranslation();
-  const { mutate: mutatePageCreateModalOpened } = usePageCreateModalOpened();
+  const { mutate: mutateModalStatus } = useCreateModalStatus();
 
   const { currentUser } = props;
 
@@ -35,7 +35,7 @@ const NavbarRight: FC<NavbarRightProps> = memo((props: NavbarRightProps) => {
         <button
           className="px-md-2 nav-link btn-create-page border-0 bg-transparent"
           type="button"
-          onClick={() => mutatePageCreateModalOpened(true)}
+          onClick={() => mutateModalStatus({ isOpened: true })}
         >
           <i className="icon-pencil mr-2"></i>
           <span className="d-none d-lg-block">{ t('New') }</span>

+ 4 - 4
packages/app/src/components/Navbar/GrowiNavbarBottom.jsx

@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 
 import NavigationContainer from '~/client/services/NavigationContainer';
-import { usePageCreateModalOpened, useIsDeviceSmallerThanMd, useDrawerOpened } from '~/stores/ui';
+import { useCreateModalStatus, useIsDeviceSmallerThanMd, useDrawerOpened } from '~/stores/ui';
 
 import { withUnstatedContainers } from '../UnstatedUtils';
 import GlobalSearch from './GlobalSearch';
@@ -15,7 +15,7 @@ const GrowiNavbarBottom = (props) => {
 
   const { data: isDrawerOpened, mutate: mutateDrawerOpened } = useDrawerOpened();
   const { data: isDeviceSmallerThanMd } = useIsDeviceSmallerThanMd();
-  const { mutate: mutatePageCreateModalOpened } = usePageCreateModalOpened();
+  const { mutate: mutateModalStatus } = useCreateModalStatus();
 
   const additionalClasses = ['grw-navbar-bottom'];
   if (isDrawerOpened) {
@@ -40,7 +40,7 @@ const GrowiNavbarBottom = (props) => {
             <a
               role="button"
               className="nav-link btn-lg"
-              onClick={() => mutateDrawerOpened(true)}
+              onClick={() => mutateModalStatus({ isOpened: true })}
             >
               <i className="icon-menu"></i>
             </a>
@@ -59,7 +59,7 @@ const GrowiNavbarBottom = (props) => {
             <a
               role="button"
               className="nav-link btn-lg"
-              onClick={() => mutatePageCreateModalOpened(true)}
+              onClick={() => mutateModalStatus(true)}
             >
               <i className="icon-pencil"></i>
             </a>

+ 9 - 9
packages/app/src/components/PageCreateModal.jsx

@@ -13,8 +13,7 @@ import { pagePathUtils, pathUtils } from '@growi/core';
 import AppContainer from '~/client/services/AppContainer';
 import { withUnstatedContainers } from './UnstatedUtils';
 import { toastError } from '~/client/util/apiNotification';
-import { useCurrentPagePath } from '~/stores/context';
-import { usePageCreateModalOpened, usePageCreateModalPagePath } from '~/stores/ui';
+import { useCreateModalStatus, useCreateModalOpened, useCreateModalPath } from '~/stores/ui';
 
 import PagePathAutoComplete from './PagePathAutoComplete';
 
@@ -25,13 +24,14 @@ const {
 const PageCreateModal = (props) => {
   const { t, appContainer } = props;
 
-  const { data: isPageCreateModalOpened, mutate: mutatePageCreateModalOpened } = usePageCreateModalOpened();
-  const { data: currentPagePath } = useCurrentPagePath();
-  const { data: selectedPagePath } = usePageCreateModalPagePath();
+  const { mutate: mutateModalStatus } = useCreateModalStatus();
+  const { data: isOpened } = useCreateModalOpened();
+  const { data: path } = useCreateModalPath();
+
 
   const config = appContainer.getConfig();
   const isReachable = config.isSearchServiceReachable;
-  const pathname = selectedPagePath || currentPagePath;
+  const pathname = path || '';
   const userPageRootPath = userPageRoot(appContainer.currentUser);
   const pageNameInputInitialValue = isCreatablePage(pathname) ? pathUtils.addTrailingSlash(pathname) : '/';
   const now = format(new Date(), 'yyyy/MM/dd');
@@ -274,12 +274,12 @@ const PageCreateModal = (props) => {
   return (
     <Modal
       size="lg"
-      isOpen={isPageCreateModalOpened}
-      toggle={() => mutatePageCreateModalOpened(false)}
+      isOpen={isOpened}
+      toggle={() => mutateModalStatus({ isOpened: false })}
       className="grw-create-page"
       autoFocus={false}
     >
-      <ModalHeader tag="h4" toggle={() => mutatePageCreateModalOpened(false)} className="bg-primary text-light">
+      <ModalHeader tag="h4" toggle={() => mutateModalStatus({ isOpened: false })} className="bg-primary text-light">
         {t('New Page')}
       </ModalHeader>
       <ModalBody>

+ 5 - 8
packages/app/src/components/Sidebar/PageTree/Item.tsx

@@ -6,7 +6,7 @@ import nodePath from 'path';
 import { ItemNode } from './ItemNode';
 import { useSWRxPageChildren } from '../../../stores/page-listing';
 import { usePageId } from '../../../stores/context';
-import { usePageCreateModalOpened, usePageCreateModalPagePath } from '../../../stores/ui';
+import { useCreateModalStatus } from '../../../stores/ui';
 
 
 interface ItemProps {
@@ -81,8 +81,7 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
   const { data: targetId } = usePageId();
   const { data, error } = useSWRxPageChildren(isOpen ? page._id : null);
 
-  const { mutate: mutatePageCreateModalOpened } = usePageCreateModalOpened();
-  const { mutate: mutateSelectedPagePath } = usePageCreateModalPagePath();
+  const { mutate: mutateModalStatus } = useCreateModalStatus();
 
   const hasChildren = useCallback((): boolean => {
     return currentChildren != null && currentChildren.length > 0;
@@ -92,11 +91,9 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
     setIsOpen(!isOpen);
   }, [isOpen]);
 
-  const onClickOpenModalButtonHandler = useCallback(async() => {
-    await mutateSelectedPagePath(page.path);
-
-    mutatePageCreateModalOpened(true);
-  }, [mutateSelectedPagePath, mutatePageCreateModalOpened, page]);
+  const onClickOpenModalButtonHandler = useCallback(() => {
+    mutateModalStatus({ isOpened: true, path: page.path });
+  }, [mutateModalStatus, page]);
 
   // didMount
   useEffect(() => {

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

@@ -12,6 +12,7 @@ import loggerFactory from '~/utils/logger';
 import { sessionStorageMiddleware } from './middlewares/sync-to-storage';
 import { useStaticSWR } from './use-static-swr';
 import { IUserUISettings } from '~/interfaces/user-ui-settings';
+import { useCurrentPagePath } from './context';
 
 const logger = loggerFactory('growi:stores:ui');
 
@@ -234,12 +235,33 @@ export const useSidebarResizeDisabled = (isDisabled?: boolean): SWRResponse<bool
   return useStaticSWR('isSidebarResizeDisabled', isDisabled || null, { fallbackData: initialData });
 };
 
-export const usePageCreateModalOpened = (isOpened?: boolean): SWRResponse<boolean, Error> => {
-  const initialData = false;
-  return useStaticSWR('isPageCreateModalOpened', isOpened || null, { fallbackData: initialData });
+type ModalStatus = {
+  isOpened: boolean,
+  path?: string,
+}
+
+export const useCreateModalStatus = (status?: ModalStatus): SWRResponse<ModalStatus, Error> => {
+  return useStaticSWR('modalStatus', status || null);
 };
 
-export const usePageCreateModalPagePath = (path?: string): SWRResponse<string, Error> => {
-  const initialData = '';
-  return useStaticSWR('pageCreateModalPagePath', path || null, { fallbackData: initialData });
+export const useCreateModalOpened = (): SWRResponse<boolean, Error> => {
+  const { data } = useCreateModalStatus();
+  return useSWR(
+    data != null ? ['isModalOpened', data] : null,
+    () => {
+      return data != null ? data.isOpened : false;
+    },
+  );
+};
+
+export const useCreateModalPath = (): SWRResponse<string, Error> => {
+  const { data: currentPagePath } = useCurrentPagePath();
+  const { data: status } = useCreateModalStatus();
+
+  return useSWR(
+    [currentPagePath, status],
+    (currentPagePath, status) => {
+      return status.path || currentPagePath;
+    },
+  );
 };