mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-26 11:32:09 +03:00
refactor: follow correct react rules (#3119)
This commit is contained in:
parent
2f910fbad0
commit
6caf934d47
@ -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),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
20
apps/web/src/components/affine/onboarding-modal.tsx
Normal file
20
apps/web/src/components/affine/onboarding-modal.tsx
Normal 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} />
|
||||||
|
);
|
||||||
|
});
|
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
|
@ -214,6 +214,7 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
|
|||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region check if page is valid
|
//#region check if page is valid
|
||||||
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
typeof router.query.pageId === 'string' &&
|
typeof router.query.pageId === 'string' &&
|
||||||
router.pathname === '/workspace/[workspaceId]/[pageId]' &&
|
router.pathname === '/workspace/[workspaceId]/[pageId]' &&
|
||||||
@ -222,12 +223,19 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
|
|||||||
if (currentPageId !== router.query.pageId) {
|
if (currentPageId !== router.query.pageId) {
|
||||||
setCurrentPageId(router.query.pageId);
|
setCurrentPageId(router.query.pageId);
|
||||||
} else {
|
} else {
|
||||||
const page = currentWorkspace.blockSuiteWorkspace.getPage(currentPageId);
|
const page =
|
||||||
|
currentWorkspace.blockSuiteWorkspace.getPage(currentPageId);
|
||||||
if (!page) {
|
if (!page) {
|
||||||
router.push('/404').catch(console.error);
|
router.push('/404').catch(console.error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, [
|
||||||
|
currentPageId,
|
||||||
|
currentWorkspace.blockSuiteWorkspace,
|
||||||
|
router,
|
||||||
|
setCurrentPageId,
|
||||||
|
]);
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
usePassiveWorkspaceEffect(currentWorkspace.blockSuiteWorkspace);
|
usePassiveWorkspaceEffect(currentWorkspace.blockSuiteWorkspace);
|
||||||
|
@ -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 }) => {
|
||||||
|
@ -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 />}
|
||||||
|
Loading…
Reference in New Issue
Block a user