From 6caf934d474b239efa00bc6052ef09c224a51576 Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Mon, 10 Jul 2023 18:32:15 +0800 Subject: [PATCH] refactor: follow correct react rules (#3119) --- apps/web/src/atoms/index.ts | 17 +++++-- .../components/affine/onboarding-modal.tsx | 20 +++++++++ .../src/components/pure/help-island/index.tsx | 6 +-- .../src/components/pure/onboarding-modal.tsx | 45 ------------------- apps/web/src/layouts/workspace-layout.tsx | 32 ++++++++----- .../workspace/[workspaceId]/[pageId].tsx | 9 +--- apps/web/src/providers/modal-provider.tsx | 15 +------ 7 files changed, 60 insertions(+), 84 deletions(-) create mode 100644 apps/web/src/components/affine/onboarding-modal.tsx delete mode 100644 apps/web/src/components/pure/onboarding-modal.tsx diff --git a/apps/web/src/atoms/index.ts b/apps/web/src/atoms/index.ts index 669ef17dc0..938b38a1b2 100644 --- a/apps/web/src/atoms/index.ts +++ b/apps/web/src/atoms/index.ts @@ -55,9 +55,16 @@ export const recentPageSettingsAtom = atom( } ); +const defaultPageSetting = { + mode: 'page', +} satisfies PageLocalSetting; + export const pageSettingFamily = atomFamily((pageId: string) => atom( - get => get(pageSettingsBaseAtom)[pageId], + get => + get(pageSettingsBaseAtom)[pageId] ?? { + ...defaultPageSetting, + }, ( get, set, @@ -69,11 +76,15 @@ export const pageSettingFamily = atomFamily((pageId: string) => // pick 3 recent page ids return [...new Set([pageId, ...ids]).values()].slice(0, 3); }); + const prevSetting = { + ...defaultPageSetting, + ...get(pageSettingsBaseAtom)[pageId], + }; set(pageSettingsBaseAtom, settings => ({ ...settings, [pageId]: { - ...settings[pageId], - ...(typeof patch === 'function' ? patch(settings[pageId]) : patch), + ...prevSetting, + ...(typeof patch === 'function' ? patch(prevSetting) : patch), }, })); } diff --git a/apps/web/src/components/affine/onboarding-modal.tsx b/apps/web/src/components/affine/onboarding-modal.tsx new file mode 100644 index 0000000000..f8f2ede363 --- /dev/null +++ b/apps/web/src/components/affine/onboarding-modal.tsx @@ -0,0 +1,20 @@ +import { TourModal } from '@affine/component/tour-modal'; +import { useAtom } from 'jotai'; +import type { FC } from 'react'; +import { memo, useCallback } from 'react'; + +import { openOnboardingModalAtom } from '../../atoms'; +import { guideOnboardingAtom } from '../../atoms/guide'; + +export const OnboardingModal: FC = memo(function OnboardingModal() { + const [open, setOpen] = useAtom(openOnboardingModalAtom); + const [guideOpen, setShowOnboarding] = useAtom(guideOnboardingAtom); + const onCloseTourModal = useCallback(() => { + setShowOnboarding(false); + setOpen(false); + }, [setOpen, setShowOnboarding]); + + return ( + + ); +}); diff --git a/apps/web/src/components/pure/help-island/index.tsx b/apps/web/src/components/pure/help-island/index.tsx index 9820c7134a..70c1af9a43 100644 --- a/apps/web/src/components/pure/help-island/index.tsx +++ b/apps/web/src/components/pure/help-island/index.tsx @@ -1,7 +1,7 @@ import { MuiFade, Tooltip } from '@affine/component'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { CloseIcon, NewIcon, UserGuideIcon } from '@blocksuite/icons'; -import { useAtom } from 'jotai'; +import { useSetAtom } from 'jotai'; import { useCallback, useState } from 'react'; import { openOnboardingModalAtom, openSettingModalAtom } from '../../../atoms'; @@ -28,8 +28,8 @@ export const HelpIsland = ({ showList?: IslandItemNames[]; }) => { const mode = useCurrentMode(); - const [, setOpenOnboarding] = useAtom(openOnboardingModalAtom); - const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom); + const setOpenOnboarding = useSetAtom(openOnboardingModalAtom); + const setOpenSettingModalAtom = useSetAtom(openSettingModalAtom); const [spread, setShowSpread] = useState(false); const t = useAFFiNEI18N(); diff --git a/apps/web/src/components/pure/onboarding-modal.tsx b/apps/web/src/components/pure/onboarding-modal.tsx deleted file mode 100644 index 9accbb2066..0000000000 --- a/apps/web/src/components/pure/onboarding-modal.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { TourModal } from '@affine/component/tour-modal'; -import { useAtom } from 'jotai'; -import { useCallback, useEffect, useMemo } from 'react'; - -import { openOnboardingModalAtom } from '../../atoms'; -import { guideOnboardingAtom } from '../../atoms/guide'; - -type OnboardingModalProps = { - onClose: () => void; - open: boolean; -}; - -const getHelperGuide = (): { onBoarding: boolean } | null => { - const helperGuide = localStorage.getItem('helper-guide'); - if (helperGuide) { - return JSON.parse(helperGuide); - } - return null; -}; - -export const OnboardingModal: React.FC = ({ - open, - onClose, -}) => { - const [, setShowOnboarding] = useAtom(guideOnboardingAtom); - const [, setOpenOnboarding] = useAtom(openOnboardingModalAtom); - const onCloseTourModal = useCallback(() => { - setShowOnboarding(false); - onClose(); - }, [onClose, setShowOnboarding]); - - const shouldShow = useMemo(() => { - const helperGuide = getHelperGuide(); - return helperGuide?.onBoarding ?? true; - }, []); - - useEffect(() => { - if (shouldShow) { - setOpenOnboarding(true); - } - }, [shouldShow, setOpenOnboarding]); - return ; -}; - -export default OnboardingModal; diff --git a/apps/web/src/layouts/workspace-layout.tsx b/apps/web/src/layouts/workspace-layout.tsx index dd177dc044..db6a083403 100644 --- a/apps/web/src/layouts/workspace-layout.tsx +++ b/apps/web/src/layouts/workspace-layout.tsx @@ -214,20 +214,28 @@ export const WorkspaceLayoutInner: FC = ({ children }) => { //#endregion //#region check if page is valid - if ( - typeof router.query.pageId === 'string' && - router.pathname === '/workspace/[workspaceId]/[pageId]' && - currentPageId - ) { - if (currentPageId !== router.query.pageId) { - setCurrentPageId(router.query.pageId); - } else { - const page = currentWorkspace.blockSuiteWorkspace.getPage(currentPageId); - if (!page) { - router.push('/404').catch(console.error); + useEffect(() => { + if ( + typeof router.query.pageId === 'string' && + router.pathname === '/workspace/[workspaceId]/[pageId]' && + currentPageId + ) { + if (currentPageId !== router.query.pageId) { + setCurrentPageId(router.query.pageId); + } else { + const page = + currentWorkspace.blockSuiteWorkspace.getPage(currentPageId); + if (!page) { + router.push('/404').catch(console.error); + } } } - } + }, [ + currentPageId, + currentWorkspace.blockSuiteWorkspace, + router, + setCurrentPageId, + ]); //#endregion usePassiveWorkspaceEffect(currentWorkspace.blockSuiteWorkspace); diff --git a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx index 637c976b4c..83598a4c85 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -8,13 +8,12 @@ import { rootCurrentPageIdAtom } from '@affine/workspace/atom'; import type { EditorContainer } from '@blocksuite/editor'; import { assertExists } from '@blocksuite/global/utils'; import type { Page } from '@blocksuite/store'; -import { useAtom, useAtomValue } from 'jotai'; +import { useAtomValue } from 'jotai'; import { useRouter } from 'next/router'; import type React from 'react'; import { useCallback } from 'react'; import { getUIAdapter } from '../../../adapters/workspace'; -import { pageSettingFamily } from '../../../atoms'; import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; import { useRouterHelper } from '../../../hooks/use-router-helper'; import { WorkspaceLayout } from '../../../layouts/workspace-layout'; @@ -28,13 +27,7 @@ const WorkspaceDetail: React.FC = () => { assertExists(currentWorkspace); assertExists(currentPageId); const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace; - const [setting, setSetting] = useAtom(pageSettingFamily(currentPageId)); const collectionManager = useCollectionManager(); - if (!setting) { - setSetting({ - mode: 'page', - }); - } const onLoad = useCallback( (page: Page, editor: EditorContainer) => { const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => { diff --git a/apps/web/src/providers/modal-provider.tsx b/apps/web/src/providers/modal-provider.tsx index 0627b42310..743ce35220 100644 --- a/apps/web/src/providers/modal-provider.tsx +++ b/apps/web/src/providers/modal-provider.tsx @@ -14,7 +14,6 @@ import type { SettingAtom } from '../atoms'; import { openCreateWorkspaceModalAtom, openDisableCloudAlertModalAtom, - openOnboardingModalAtom, openSettingModalAtom, openWorkspacesModalAtom, } from '../atoms'; @@ -48,7 +47,7 @@ const TmpDisableAffineCloudModal = lazy(() => ); const OnboardingModal = lazy(() => - import('../components/pure/onboarding-modal').then(module => ({ + import('../components/affine/onboarding-modal').then(module => ({ default: module.OnboardingModal, })) ); @@ -90,13 +89,6 @@ export function CurrentWorkspaceModals() { const [openDisableCloudAlertModal, setOpenDisableCloudAlertModal] = useAtom( openDisableCloudAlertModalAtom ); - const [openOnboardingModal, setOpenOnboardingModal] = useAtom( - openOnboardingModalAtom - ); - - const onCloseOnboardingModal = useCallback(() => { - setOpenOnboardingModal(false); - }, [setOpenOnboardingModal]); return ( <> @@ -109,10 +101,7 @@ export function CurrentWorkspaceModals() { {environment.isDesktop && ( - + )} {currentWorkspace && }