mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-11-25 05:42:49 +03:00
fix: improve navigate (#3420)
This commit is contained in:
parent
115f46a4fa
commit
b47fbde479
12
.eslintrc.js
12
.eslintrc.js
@ -22,10 +22,15 @@ const createPattern = packageName => [
|
||||
allowTypeImports: false,
|
||||
},
|
||||
{
|
||||
group: ['@blocksuite/store'],
|
||||
group: ['@blocksuite /store'],
|
||||
message: "Import from '@blocksuite/global/utils'",
|
||||
importNames: ['assertExists', 'assertEquals'],
|
||||
},
|
||||
{
|
||||
group: ['react-router-dom'],
|
||||
message: 'Use `useNavigateHelper` instead',
|
||||
importNames: ['useNavigate'],
|
||||
},
|
||||
];
|
||||
|
||||
const allPackages = [
|
||||
@ -144,6 +149,11 @@ const config = {
|
||||
message: "Import from '@blocksuite/global/utils'",
|
||||
importNames: ['assertExists', 'assertEquals'],
|
||||
},
|
||||
{
|
||||
group: ['react-router-dom'],
|
||||
message: 'Use `useNavigateHelper` instead',
|
||||
importNames: ['useNavigate'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useAtom } from 'jotai';
|
||||
import { atomWithStorage, createJSONStorage } from 'jotai/utils';
|
||||
import { useCallback } from 'react';
|
||||
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { router } from '../router';
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
DeleteTemporarilyIcon,
|
||||
@ -9,23 +10,27 @@ import type { FC, SVGProps } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { openSettingModalAtom } from '../../../atoms';
|
||||
import { pathGenerator } from '../../../shared';
|
||||
|
||||
export const useSwitchToConfig = (
|
||||
workspaceId: string
|
||||
): {
|
||||
title: string;
|
||||
href?: string;
|
||||
onClick?: () => void;
|
||||
icon: FC<SVGProps<SVGSVGElement>>;
|
||||
}[] => {
|
||||
export type Config =
|
||||
| {
|
||||
title: string;
|
||||
icon: FC<SVGProps<SVGSVGElement>>;
|
||||
subPath: WorkspaceSubPath;
|
||||
}
|
||||
| {
|
||||
title: string;
|
||||
icon: FC<SVGProps<SVGSVGElement>>;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
export const useSwitchToConfig = (workspaceId: string): Config[] => {
|
||||
const t = useAFFiNEI18N();
|
||||
const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom);
|
||||
return useMemo(
|
||||
() => [
|
||||
{
|
||||
title: t['All pages'](),
|
||||
href: pathGenerator.all(workspaceId),
|
||||
subPath: WorkspaceSubPath.ALL,
|
||||
icon: FolderIcon,
|
||||
},
|
||||
{
|
||||
@ -41,7 +46,7 @@ export const useSwitchToConfig = (
|
||||
},
|
||||
{
|
||||
title: t['Trash'](),
|
||||
href: pathGenerator.trash(workspaceId),
|
||||
subPath: WorkspaceSubPath.TRASH,
|
||||
icon: DeleteTemporarilyIcon,
|
||||
},
|
||||
],
|
||||
|
@ -2,8 +2,7 @@ import { Modal, ModalWrapper } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { Command } from 'cmdk';
|
||||
import { startTransition } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import type { AllWorkspace } from '../../../shared';
|
||||
import { Footer } from './footer';
|
||||
@ -37,15 +36,7 @@ export const QuickSearchModal: React.FC<QuickSearchModalProps> = ({
|
||||
_setQuery(query);
|
||||
});
|
||||
}, []);
|
||||
const location = useLocation();
|
||||
const isPublicWorkspace = useMemo(
|
||||
() => location.pathname.startsWith('/public-workspace'),
|
||||
[location]
|
||||
);
|
||||
const [showCreatePage, setShowCreatePage] = useState(true);
|
||||
const isPublicAndNoQuery = useCallback(() => {
|
||||
return isPublicWorkspace && query.length === 0;
|
||||
}, [isPublicWorkspace, query.length]);
|
||||
const handleClose = useCallback(() => {
|
||||
setOpen(false);
|
||||
}, [setOpen]);
|
||||
@ -88,7 +79,7 @@ export const QuickSearchModal: React.FC<QuickSearchModalProps> = ({
|
||||
width={608}
|
||||
style={{
|
||||
maxHeight: '80vh',
|
||||
minHeight: isPublicAndNoQuery() ? '72px' : '412px',
|
||||
minHeight: '412px',
|
||||
top: '80px',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
@ -134,13 +125,9 @@ export const QuickSearchModal: React.FC<QuickSearchModalProps> = ({
|
||||
: 'Ctrl + K'}
|
||||
</StyledShortcut>
|
||||
</StyledModalHeader>
|
||||
<StyledModalDivider
|
||||
style={{ display: isPublicAndNoQuery() ? 'none' : '' }}
|
||||
/>
|
||||
<StyledModalDivider />
|
||||
<Command.List>
|
||||
<StyledContent
|
||||
style={{ display: isPublicAndNoQuery() ? 'none' : '' }}
|
||||
>
|
||||
<StyledContent>
|
||||
<Results
|
||||
query={query}
|
||||
onClose={handleClose}
|
||||
@ -148,7 +135,7 @@ export const QuickSearchModal: React.FC<QuickSearchModalProps> = ({
|
||||
setShowCreatePage={setShowCreatePage}
|
||||
/>
|
||||
</StyledContent>
|
||||
{isPublicWorkspace ? null : showCreatePage ? (
|
||||
{showCreatePage ? (
|
||||
<>
|
||||
<StyledModalDivider />
|
||||
<StyledModalFooter>
|
||||
|
@ -7,8 +7,6 @@ import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suit
|
||||
import { Command } from 'cmdk';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type { Dispatch, FC, SetStateAction } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { recentPageSettingsAtom } from '../../../atoms';
|
||||
import { useNavigateHelper } from '../../../hooks/use-navigate-helper';
|
||||
@ -32,12 +30,11 @@ export const Results: FC<ResultsProps> = ({
|
||||
useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
|
||||
const pageList = useBlockSuitePageMeta(blockSuiteWorkspace);
|
||||
assertExists(blockSuiteWorkspace.id);
|
||||
const List = useSwitchToConfig(workspace.id);
|
||||
const list = useSwitchToConfig(workspace.id);
|
||||
|
||||
const recentPageSetting = useAtomValue(recentPageSettingsAtom);
|
||||
const t = useAFFiNEI18N();
|
||||
const navigate = useNavigate();
|
||||
const { jumpToPage } = useNavigateHelper();
|
||||
const { jumpToPage, jumpToSubPath } = useNavigateHelper();
|
||||
const results = blockSuiteWorkspace.search({ query });
|
||||
|
||||
// remove `space:` prefix
|
||||
@ -55,10 +52,7 @@ export const Results: FC<ResultsProps> = ({
|
||||
return page.trash !== true;
|
||||
}
|
||||
});
|
||||
useEffect(() => {
|
||||
setShowCreatePage(!resultsPageMeta.length);
|
||||
//Determine whether to display the ‘+ New page’
|
||||
}, [resultsPageMeta.length, setShowCreatePage]);
|
||||
setShowCreatePage(resultsPageMeta.length === 0);
|
||||
if (!query) {
|
||||
return (
|
||||
<>
|
||||
@ -90,15 +84,20 @@ export const Results: FC<ResultsProps> = ({
|
||||
</Command.Group>
|
||||
)}
|
||||
<Command.Group heading={t['Jump to']()}>
|
||||
{List.map(link => {
|
||||
{list.map(link => {
|
||||
return (
|
||||
<Command.Item
|
||||
key={link.title}
|
||||
value={link.title}
|
||||
onSelect={() => {
|
||||
onClose();
|
||||
link.href && navigate(link.href);
|
||||
link.onClick?.();
|
||||
if ('subPath' in link) {
|
||||
jumpToSubPath(blockSuiteWorkspace.id, link.subPath);
|
||||
} else if ('onClick' in link) {
|
||||
link.onClick();
|
||||
} else {
|
||||
throw new Error('Invalid link');
|
||||
}
|
||||
}}
|
||||
>
|
||||
<StyledListItem>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { useCallback } from 'react';
|
||||
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
|
||||
export enum RouteLogic {
|
||||
|
@ -12,7 +12,7 @@ import { useAtomValue } from 'jotai';
|
||||
import { useAtom } from 'jotai/react';
|
||||
import { type ReactElement, useCallback, useEffect } from 'react';
|
||||
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 { useCurrentWorkspace } from '../../hooks/current/use-current-workspace';
|
||||
@ -71,7 +71,7 @@ const DetailPageImpl = (): ReactElement => {
|
||||
export const DetailPage = (): ReactElement => {
|
||||
const { workspaceId, pageId } = useParams();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { jumpTo404 } = useNavigateHelper();
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const [currentPageId, setCurrentPageId] = useAtom(currentPageIdAtom);
|
||||
const page = currentPageId
|
||||
@ -91,7 +91,7 @@ export const DetailPage = (): ReactElement => {
|
||||
const page =
|
||||
currentWorkspace.blockSuiteWorkspace.getPage(currentPageId);
|
||||
if (!page) {
|
||||
navigate('/404');
|
||||
jumpTo404();
|
||||
} else {
|
||||
// fixme: cleanup jumpOnce in the right time
|
||||
if (page.meta.jumpOnce) {
|
||||
@ -106,8 +106,8 @@ export const DetailPage = (): ReactElement => {
|
||||
currentPageId,
|
||||
currentWorkspace.blockSuiteWorkspace,
|
||||
currentWorkspace.id,
|
||||
jumpTo404,
|
||||
location.pathname,
|
||||
navigate,
|
||||
pageId,
|
||||
setCurrentPageId,
|
||||
workspaceId,
|
||||
|
Loading…
Reference in New Issue
Block a user