fix: improve navigate (#3420)

This commit is contained in:
Alex Yang 2023-07-27 11:06:30 -07:00 committed by GitHub
parent 115f46a4fa
commit b47fbde479
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 46 deletions

View File

@ -22,10 +22,15 @@ const createPattern = packageName => [
allowTypeImports: false, allowTypeImports: false,
}, },
{ {
group: ['@blocksuite/store'], group: ['@blocksuite /store'],
message: "Import from '@blocksuite/global/utils'", message: "Import from '@blocksuite/global/utils'",
importNames: ['assertExists', 'assertEquals'], importNames: ['assertExists', 'assertEquals'],
}, },
{
group: ['react-router-dom'],
message: 'Use `useNavigateHelper` instead',
importNames: ['useNavigate'],
},
]; ];
const allPackages = [ const allPackages = [
@ -144,6 +149,11 @@ const config = {
message: "Import from '@blocksuite/global/utils'", message: "Import from '@blocksuite/global/utils'",
importNames: ['assertExists', 'assertEquals'], importNames: ['assertExists', 'assertEquals'],
}, },
{
group: ['react-router-dom'],
message: 'Use `useNavigateHelper` instead',
importNames: ['useNavigate'],
},
], ],
}, },
], ],

View File

@ -1,6 +1,7 @@
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
import { atomWithStorage, createJSONStorage } from 'jotai/utils'; import { atomWithStorage, createJSONStorage } from 'jotai/utils';
import { useCallback } from 'react'; import { useCallback } from 'react';
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { router } from '../router'; import { router } from '../router';

View File

@ -1,3 +1,4 @@
import { WorkspaceSubPath } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { import {
DeleteTemporarilyIcon, DeleteTemporarilyIcon,
@ -9,23 +10,27 @@ import type { FC, SVGProps } from 'react';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { openSettingModalAtom } from '../../../atoms'; import { openSettingModalAtom } from '../../../atoms';
import { pathGenerator } from '../../../shared';
export const useSwitchToConfig = ( export type Config =
workspaceId: string | {
): { title: string;
title: string; icon: FC<SVGProps<SVGSVGElement>>;
href?: string; subPath: WorkspaceSubPath;
onClick?: () => void; }
icon: FC<SVGProps<SVGSVGElement>>; | {
}[] => { title: string;
icon: FC<SVGProps<SVGSVGElement>>;
onClick: () => void;
};
export const useSwitchToConfig = (workspaceId: string): Config[] => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom); const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom);
return useMemo( return useMemo(
() => [ () => [
{ {
title: t['All pages'](), title: t['All pages'](),
href: pathGenerator.all(workspaceId), subPath: WorkspaceSubPath.ALL,
icon: FolderIcon, icon: FolderIcon,
}, },
{ {
@ -41,7 +46,7 @@ export const useSwitchToConfig = (
}, },
{ {
title: t['Trash'](), title: t['Trash'](),
href: pathGenerator.trash(workspaceId), subPath: WorkspaceSubPath.TRASH,
icon: DeleteTemporarilyIcon, icon: DeleteTemporarilyIcon,
}, },
], ],

View File

@ -2,8 +2,7 @@ import { Modal, ModalWrapper } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Command } from 'cmdk'; import { Command } from 'cmdk';
import { startTransition } from 'react'; import { startTransition } from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useCallback, useEffect, useRef, useState } from 'react';
import { useLocation } from 'react-router-dom';
import type { AllWorkspace } from '../../../shared'; import type { AllWorkspace } from '../../../shared';
import { Footer } from './footer'; import { Footer } from './footer';
@ -37,15 +36,7 @@ export const QuickSearchModal: React.FC<QuickSearchModalProps> = ({
_setQuery(query); _setQuery(query);
}); });
}, []); }, []);
const location = useLocation();
const isPublicWorkspace = useMemo(
() => location.pathname.startsWith('/public-workspace'),
[location]
);
const [showCreatePage, setShowCreatePage] = useState(true); const [showCreatePage, setShowCreatePage] = useState(true);
const isPublicAndNoQuery = useCallback(() => {
return isPublicWorkspace && query.length === 0;
}, [isPublicWorkspace, query.length]);
const handleClose = useCallback(() => { const handleClose = useCallback(() => {
setOpen(false); setOpen(false);
}, [setOpen]); }, [setOpen]);
@ -88,7 +79,7 @@ export const QuickSearchModal: React.FC<QuickSearchModalProps> = ({
width={608} width={608}
style={{ style={{
maxHeight: '80vh', maxHeight: '80vh',
minHeight: isPublicAndNoQuery() ? '72px' : '412px', minHeight: '412px',
top: '80px', top: '80px',
overflow: 'hidden', overflow: 'hidden',
}} }}
@ -134,13 +125,9 @@ export const QuickSearchModal: React.FC<QuickSearchModalProps> = ({
: 'Ctrl + K'} : 'Ctrl + K'}
</StyledShortcut> </StyledShortcut>
</StyledModalHeader> </StyledModalHeader>
<StyledModalDivider <StyledModalDivider />
style={{ display: isPublicAndNoQuery() ? 'none' : '' }}
/>
<Command.List> <Command.List>
<StyledContent <StyledContent>
style={{ display: isPublicAndNoQuery() ? 'none' : '' }}
>
<Results <Results
query={query} query={query}
onClose={handleClose} onClose={handleClose}
@ -148,7 +135,7 @@ export const QuickSearchModal: React.FC<QuickSearchModalProps> = ({
setShowCreatePage={setShowCreatePage} setShowCreatePage={setShowCreatePage}
/> />
</StyledContent> </StyledContent>
{isPublicWorkspace ? null : showCreatePage ? ( {showCreatePage ? (
<> <>
<StyledModalDivider /> <StyledModalDivider />
<StyledModalFooter> <StyledModalFooter>

View File

@ -7,8 +7,6 @@ import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suit
import { Command } from 'cmdk'; import { Command } from 'cmdk';
import { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
import type { Dispatch, FC, SetStateAction } from 'react'; import type { Dispatch, FC, SetStateAction } from 'react';
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { recentPageSettingsAtom } from '../../../atoms'; import { recentPageSettingsAtom } from '../../../atoms';
import { useNavigateHelper } from '../../../hooks/use-navigate-helper'; import { useNavigateHelper } from '../../../hooks/use-navigate-helper';
@ -32,12 +30,11 @@ export const Results: FC<ResultsProps> = ({
useBlockSuiteWorkspaceHelper(blockSuiteWorkspace); useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
const pageList = useBlockSuitePageMeta(blockSuiteWorkspace); const pageList = useBlockSuitePageMeta(blockSuiteWorkspace);
assertExists(blockSuiteWorkspace.id); assertExists(blockSuiteWorkspace.id);
const List = useSwitchToConfig(workspace.id); const list = useSwitchToConfig(workspace.id);
const recentPageSetting = useAtomValue(recentPageSettingsAtom); const recentPageSetting = useAtomValue(recentPageSettingsAtom);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const navigate = useNavigate(); const { jumpToPage, jumpToSubPath } = useNavigateHelper();
const { jumpToPage } = useNavigateHelper();
const results = blockSuiteWorkspace.search({ query }); const results = blockSuiteWorkspace.search({ query });
// remove `space:` prefix // remove `space:` prefix
@ -55,10 +52,7 @@ export const Results: FC<ResultsProps> = ({
return page.trash !== true; return page.trash !== true;
} }
}); });
useEffect(() => { setShowCreatePage(resultsPageMeta.length === 0);
setShowCreatePage(!resultsPageMeta.length);
//Determine whether to display the + New page
}, [resultsPageMeta.length, setShowCreatePage]);
if (!query) { if (!query) {
return ( return (
<> <>
@ -90,15 +84,20 @@ export const Results: FC<ResultsProps> = ({
</Command.Group> </Command.Group>
)} )}
<Command.Group heading={t['Jump to']()}> <Command.Group heading={t['Jump to']()}>
{List.map(link => { {list.map(link => {
return ( return (
<Command.Item <Command.Item
key={link.title} key={link.title}
value={link.title} value={link.title}
onSelect={() => { onSelect={() => {
onClose(); onClose();
link.href && navigate(link.href); if ('subPath' in link) {
link.onClick?.(); jumpToSubPath(blockSuiteWorkspace.id, link.subPath);
} else if ('onClick' in link) {
link.onClick();
} else {
throw new Error('Invalid link');
}
}} }}
> >
<StyledListItem> <StyledListItem>

View File

@ -1,5 +1,6 @@
import type { WorkspaceSubPath } from '@affine/env/workspace'; import type { WorkspaceSubPath } from '@affine/env/workspace';
import { useCallback } from 'react'; import { useCallback } from 'react';
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { useLocation, useNavigate } from 'react-router-dom'; import { useLocation, useNavigate } from 'react-router-dom';
export enum RouteLogic { export enum RouteLogic {

View File

@ -12,7 +12,7 @@ import { useAtomValue } from 'jotai';
import { useAtom } from 'jotai/react'; import { useAtom } from 'jotai/react';
import { type ReactElement, useCallback, useEffect } from 'react'; import { type ReactElement, useCallback, useEffect } from 'react';
import type { LoaderFunction } from 'react-router-dom'; import type { LoaderFunction } from 'react-router-dom';
import { useLocation, useNavigate, useParams } from 'react-router-dom'; import { useLocation, useParams } from 'react-router-dom';
import { getUIAdapter } from '../../adapters/workspace'; import { getUIAdapter } from '../../adapters/workspace';
import { useCurrentWorkspace } from '../../hooks/current/use-current-workspace'; import { useCurrentWorkspace } from '../../hooks/current/use-current-workspace';
@ -71,7 +71,7 @@ const DetailPageImpl = (): ReactElement => {
export const DetailPage = (): ReactElement => { export const DetailPage = (): ReactElement => {
const { workspaceId, pageId } = useParams(); const { workspaceId, pageId } = useParams();
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const { jumpTo404 } = useNavigateHelper();
const [currentWorkspace] = useCurrentWorkspace(); const [currentWorkspace] = useCurrentWorkspace();
const [currentPageId, setCurrentPageId] = useAtom(currentPageIdAtom); const [currentPageId, setCurrentPageId] = useAtom(currentPageIdAtom);
const page = currentPageId const page = currentPageId
@ -91,7 +91,7 @@ export const DetailPage = (): ReactElement => {
const page = const page =
currentWorkspace.blockSuiteWorkspace.getPage(currentPageId); currentWorkspace.blockSuiteWorkspace.getPage(currentPageId);
if (!page) { if (!page) {
navigate('/404'); jumpTo404();
} else { } else {
// fixme: cleanup jumpOnce in the right time // fixme: cleanup jumpOnce in the right time
if (page.meta.jumpOnce) { if (page.meta.jumpOnce) {
@ -106,8 +106,8 @@ export const DetailPage = (): ReactElement => {
currentPageId, currentPageId,
currentWorkspace.blockSuiteWorkspace, currentWorkspace.blockSuiteWorkspace,
currentWorkspace.id, currentWorkspace.id,
jumpTo404,
location.pathname, location.pathname,
navigate,
pageId, pageId,
setCurrentPageId, setCurrentPageId,
workspaceId, workspaceId,