refactor: follow correct react rules (#3119)

This commit is contained in:
Alex Yang 2023-07-10 18:32:15 +08:00 committed by GitHub
parent 2f910fbad0
commit 6caf934d47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 84 deletions

View File

@ -55,9 +55,16 @@ export const recentPageSettingsAtom = atom<PartialPageLocalSettingWithPageId[]>(
} }
); );
const defaultPageSetting = {
mode: 'page',
} satisfies PageLocalSetting;
export const pageSettingFamily = atomFamily((pageId: string) => export const pageSettingFamily = atomFamily((pageId: string) =>
atom( atom(
get => get(pageSettingsBaseAtom)[pageId], get =>
get(pageSettingsBaseAtom)[pageId] ?? {
...defaultPageSetting,
},
( (
get, get,
set, set,
@ -69,11 +76,15 @@ export const pageSettingFamily = atomFamily((pageId: string) =>
// pick 3 recent page ids // pick 3 recent page ids
return [...new Set([pageId, ...ids]).values()].slice(0, 3); return [...new Set([pageId, ...ids]).values()].slice(0, 3);
}); });
const prevSetting = {
...defaultPageSetting,
...get(pageSettingsBaseAtom)[pageId],
};
set(pageSettingsBaseAtom, settings => ({ set(pageSettingsBaseAtom, settings => ({
...settings, ...settings,
[pageId]: { [pageId]: {
...settings[pageId], ...prevSetting,
...(typeof patch === 'function' ? patch(settings[pageId]) : patch), ...(typeof patch === 'function' ? patch(prevSetting) : patch),
}, },
})); }));
} }

View File

@ -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 (
<TourModal open={!open ? guideOpen : open} onClose={onCloseTourModal} />
);
});

View File

@ -1,7 +1,7 @@
import { MuiFade, Tooltip } from '@affine/component'; import { MuiFade, Tooltip } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon, NewIcon, UserGuideIcon } from '@blocksuite/icons'; import { CloseIcon, NewIcon, UserGuideIcon } from '@blocksuite/icons';
import { useAtom } from 'jotai'; import { useSetAtom } from 'jotai';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import { openOnboardingModalAtom, openSettingModalAtom } from '../../../atoms'; import { openOnboardingModalAtom, openSettingModalAtom } from '../../../atoms';
@ -28,8 +28,8 @@ export const HelpIsland = ({
showList?: IslandItemNames[]; showList?: IslandItemNames[];
}) => { }) => {
const mode = useCurrentMode(); const mode = useCurrentMode();
const [, setOpenOnboarding] = useAtom(openOnboardingModalAtom); const setOpenOnboarding = useSetAtom(openOnboardingModalAtom);
const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom); const setOpenSettingModalAtom = useSetAtom(openSettingModalAtom);
const [spread, setShowSpread] = useState(false); const [spread, setShowSpread] = useState(false);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();

View File

@ -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<OnboardingModalProps> = ({
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 <TourModal open={open} onClose={onCloseTourModal} />;
};
export default OnboardingModal;

View File

@ -214,20 +214,28 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
//#endregion //#endregion
//#region check if page is valid //#region check if page is valid
if ( useEffect(() => {
typeof router.query.pageId === 'string' && if (
router.pathname === '/workspace/[workspaceId]/[pageId]' && typeof router.query.pageId === 'string' &&
currentPageId router.pathname === '/workspace/[workspaceId]/[pageId]' &&
) { currentPageId
if (currentPageId !== router.query.pageId) { ) {
setCurrentPageId(router.query.pageId); if (currentPageId !== router.query.pageId) {
} else { setCurrentPageId(router.query.pageId);
const page = currentWorkspace.blockSuiteWorkspace.getPage(currentPageId); } else {
if (!page) { const page =
router.push('/404').catch(console.error); currentWorkspace.blockSuiteWorkspace.getPage(currentPageId);
if (!page) {
router.push('/404').catch(console.error);
}
} }
} }
} }, [
currentPageId,
currentWorkspace.blockSuiteWorkspace,
router,
setCurrentPageId,
]);
//#endregion //#endregion
usePassiveWorkspaceEffect(currentWorkspace.blockSuiteWorkspace); usePassiveWorkspaceEffect(currentWorkspace.blockSuiteWorkspace);

View File

@ -8,13 +8,12 @@ import { rootCurrentPageIdAtom } from '@affine/workspace/atom';
import type { EditorContainer } from '@blocksuite/editor'; import type { EditorContainer } from '@blocksuite/editor';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import type { Page } from '@blocksuite/store'; import type { Page } from '@blocksuite/store';
import { useAtom, useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import type React from 'react'; import type React from 'react';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { getUIAdapter } from '../../../adapters/workspace'; import { getUIAdapter } from '../../../adapters/workspace';
import { pageSettingFamily } from '../../../atoms';
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
import { useRouterHelper } from '../../../hooks/use-router-helper'; import { useRouterHelper } from '../../../hooks/use-router-helper';
import { WorkspaceLayout } from '../../../layouts/workspace-layout'; import { WorkspaceLayout } from '../../../layouts/workspace-layout';
@ -28,13 +27,7 @@ const WorkspaceDetail: React.FC = () => {
assertExists(currentWorkspace); assertExists(currentWorkspace);
assertExists(currentPageId); assertExists(currentPageId);
const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace; const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace;
const [setting, setSetting] = useAtom(pageSettingFamily(currentPageId));
const collectionManager = useCollectionManager(); const collectionManager = useCollectionManager();
if (!setting) {
setSetting({
mode: 'page',
});
}
const onLoad = useCallback( const onLoad = useCallback(
(page: Page, editor: EditorContainer) => { (page: Page, editor: EditorContainer) => {
const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => { const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => {

View File

@ -14,7 +14,6 @@ import type { SettingAtom } from '../atoms';
import { import {
openCreateWorkspaceModalAtom, openCreateWorkspaceModalAtom,
openDisableCloudAlertModalAtom, openDisableCloudAlertModalAtom,
openOnboardingModalAtom,
openSettingModalAtom, openSettingModalAtom,
openWorkspacesModalAtom, openWorkspacesModalAtom,
} from '../atoms'; } from '../atoms';
@ -48,7 +47,7 @@ const TmpDisableAffineCloudModal = lazy(() =>
); );
const OnboardingModal = lazy(() => const OnboardingModal = lazy(() =>
import('../components/pure/onboarding-modal').then(module => ({ import('../components/affine/onboarding-modal').then(module => ({
default: module.OnboardingModal, default: module.OnboardingModal,
})) }))
); );
@ -90,13 +89,6 @@ export function CurrentWorkspaceModals() {
const [openDisableCloudAlertModal, setOpenDisableCloudAlertModal] = useAtom( const [openDisableCloudAlertModal, setOpenDisableCloudAlertModal] = useAtom(
openDisableCloudAlertModalAtom openDisableCloudAlertModalAtom
); );
const [openOnboardingModal, setOpenOnboardingModal] = useAtom(
openOnboardingModalAtom
);
const onCloseOnboardingModal = useCallback(() => {
setOpenOnboardingModal(false);
}, [setOpenOnboardingModal]);
return ( return (
<> <>
<Suspense> <Suspense>
@ -109,10 +101,7 @@ export function CurrentWorkspaceModals() {
</Suspense> </Suspense>
{environment.isDesktop && ( {environment.isDesktop && (
<Suspense> <Suspense>
<OnboardingModal <OnboardingModal />
open={openOnboardingModal}
onClose={onCloseOnboardingModal}
/>
</Suspense> </Suspense>
)} )}
{currentWorkspace && <Setting />} {currentWorkspace && <Setting />}