feat: add page mode filter (#2601)

Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
Whitewater
2023-05-30 20:15:23 -07:00
committed by GitHub
parent 617350fc7d
commit 0bb6e362bf
6 changed files with 75 additions and 38 deletions

View File

@@ -139,3 +139,6 @@ export const workspaceRecentViresWriteAtom = atom<null, [string, View], View[]>(
return record[id]; return record[id];
} }
); );
export type PageModeOption = 'all' | 'page' | 'edgeless';
export const pageModeSelectAtom = atom<PageModeOption>('all');

View File

@@ -13,9 +13,11 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { EdgelessIcon, PageIcon } from '@blocksuite/icons'; import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store'; import type { PageMeta } from '@blocksuite/store';
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta'; import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
import { useAtom } from 'jotai';
import type React from 'react'; import type React from 'react';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { pageModeSelectAtom } from '../../../atoms';
import { useBlockSuiteMetaHelper } from '../../../hooks/affine/use-block-suite-meta-helper'; import { useBlockSuiteMetaHelper } from '../../../hooks/affine/use-block-suite-meta-helper';
import type { BlockSuiteWorkspace } from '../../../shared'; import type { BlockSuiteWorkspace } from '../../../shared';
import { toast } from '../../../utils'; import { toast } from '../../../utils';
@@ -80,25 +82,40 @@ export const BlockSuitePageList: React.FC<BlockSuitePageListProps> = ({
permanentlyDeletePage, permanentlyDeletePage,
cancelPublicPage, cancelPublicPage,
} = useBlockSuiteMetaHelper(blockSuiteWorkspace); } = useBlockSuiteMetaHelper(blockSuiteWorkspace);
const [filterMode] = useAtom(pageModeSelectAtom);
const { createPage, createEdgeless, importFile, isPreferredEdgeless } = const { createPage, createEdgeless, importFile, isPreferredEdgeless } =
usePageHelper(blockSuiteWorkspace); usePageHelper(blockSuiteWorkspace);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const list = useMemo( const list = useMemo(
() => () =>
pageMetas.filter(pageMeta => { pageMetas
if (!filter[listType](pageMeta, pageMetas)) { .filter(pageMeta => {
return false; if (filterMode === 'all') {
} return true;
if (!view) { }
if (filterMode === 'edgeless') {
return isPreferredEdgeless(pageMeta.id);
}
if (filterMode === 'page') {
return !isPreferredEdgeless(pageMeta.id);
}
console.error('unknown filter mode', pageMeta, filterMode);
return true; return true;
} })
return filterByFilterList(view.filterList, { .filter(pageMeta => {
Favorite: !!pageMeta.favorite, if (!filter[listType](pageMeta, pageMetas)) {
Created: pageMeta.createDate, return false;
Updated: pageMeta.updatedDate ?? pageMeta.createDate, }
}); if (!view) {
}), return true;
[pageMetas, listType, view] }
return filterByFilterList(view.filterList, {
Favorite: !!pageMeta.favorite,
Created: pageMeta.createDate,
Updated: pageMeta.updatedDate ?? pageMeta.createDate,
});
}),
[pageMetas, filterMode, isPreferredEdgeless, listType, view]
); );
if (list.length === 0) { if (list.length === 0) {
return <PageListEmpty listType={listType} />; return <PageListEmpty listType={listType} />;

View File

@@ -1,8 +1,11 @@
import { RadioButton, RadioButtonGroup } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useSetAtom } from 'jotai'; import { useSetAtom } from 'jotai';
import { useAtom } from "jotai";
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import type React from 'react'; import type React from 'react';
import { openQuickSearchModalAtom } from '../../../atoms'; import { openQuickSearchModalAtom, pageModeSelectAtom } from "../../../atoms";
import type { HeaderProps } from '../../blocksuite/workspace-header/header'; import type { HeaderProps } from '../../blocksuite/workspace-header/header';
import { Header } from '../../blocksuite/workspace-header/header'; import { Header } from '../../blocksuite/workspace-header/header';
import * as styles from '../../blocksuite/workspace-header/styles.css'; import * as styles from '../../blocksuite/workspace-header/styles.css';
@@ -34,3 +37,30 @@ export const WorkspaceTitle: React.FC<WorkspaceTitleProps> = ({
</Header> </Header>
); );
}; };
export const WorkspaceModeFilterTab = ({ ...props }: WorkspaceTitleProps) => {
const t = useAFFiNEI18N();
const [value, setMode] = useAtom(pageModeSelectAtom);
const handleValueChange = (value: string) => {
if (value !== 'all' && value !== 'page' && value !== 'edgeless') {
throw new Error('Invalid value for page mode option');
}
setMode(value);
};
return (
<Header {...props}>
<div className={styles.pageListTitleWrapper}>
<RadioButtonGroup
defaultValue={value}
onValueChange={handleValueChange}
>
<RadioButton value="all" style={{ textTransform: 'capitalize' }}>
{t['all']()}
</RadioButton>
<RadioButton value="page">{t['Page']()}</RadioButton>
<RadioButton value="edgeless">{t['Edgeless']()}</RadioButton>
</RadioButtonGroup>
</div>
</Header>
);
};

View File

@@ -9,19 +9,13 @@ import { config } from '@affine/env';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { WorkspaceHeaderProps } from '@affine/workspace/type'; import type { WorkspaceHeaderProps } from '@affine/workspace/type';
import { WorkspaceFlavour, WorkspaceSubPath } from '@affine/workspace/type'; import { WorkspaceFlavour, WorkspaceSubPath } from '@affine/workspace/type';
import { import { SettingsIcon } from '@blocksuite/icons';
DeleteTemporarilyIcon,
FolderIcon,
SettingsIcon,
ShareIcon,
} from '@blocksuite/icons';
import { RESET } from 'jotai/utils'; import { RESET } from 'jotai/utils';
import type { ReactElement } from 'react'; import type { ReactElement } from 'react';
import React from 'react';
import { NIL } from 'uuid'; import { NIL } from 'uuid';
import { BlockSuiteEditorHeader } from './blocksuite/workspace-header'; import { BlockSuiteEditorHeader } from './blocksuite/workspace-header';
import { WorkspaceTitle } from './pure/workspace-title'; import { WorkspaceModeFilterTab, WorkspaceTitle } from './pure/workspace-title';
export function WorkspaceHeader({ export function WorkspaceHeader({
currentWorkspace, currentWorkspace,
@@ -64,18 +58,14 @@ export function WorkspaceHeader({
</div> </div>
</div> </div>
); );
return ( return (
<> <>
<WorkspaceTitle <WorkspaceModeFilterTab
workspace={currentWorkspace} workspace={currentWorkspace}
currentPage={null} currentPage={null}
isPublic={false} isPublic={false}
icon={<FolderIcon />}
leftSlot={leftSlot} leftSlot={leftSlot}
> />
{t['All pages']()}
</WorkspaceTitle>
{filterContainer} {filterContainer}
</> </>
); );
@@ -92,25 +82,19 @@ export function WorkspaceHeader({
); );
} else if (currentEntry.subPath === WorkspaceSubPath.SHARED) { } else if (currentEntry.subPath === WorkspaceSubPath.SHARED) {
return ( return (
<WorkspaceTitle <WorkspaceModeFilterTab
workspace={currentWorkspace} workspace={currentWorkspace}
currentPage={null} currentPage={null}
isPublic={false} isPublic={false}
icon={<ShareIcon />} />
>
{t['Shared Pages']()}
</WorkspaceTitle>
); );
} else if (currentEntry.subPath === WorkspaceSubPath.TRASH) { } else if (currentEntry.subPath === WorkspaceSubPath.TRASH) {
return ( return (
<WorkspaceTitle <WorkspaceModeFilterTab
workspace={currentWorkspace} workspace={currentWorkspace}
currentPage={null} currentPage={null}
isPublic={false} isPublic={false}
icon={<DeleteTemporarilyIcon />} />
>
{t['Trash']()}
</WorkspaceTitle>
); );
} }
} else if ('pageId' in currentEntry) { } else if ('pageId' in currentEntry) {

View File

@@ -1,3 +1,4 @@
export * from './button'; export * from './button';
export * from './icon-button'; export * from './icon-button';
export * from './radio';
export * from './text-button'; export * from './text-button';

View File

@@ -91,4 +91,6 @@ export const radioButtonGroup = style({
background: 'var(--affine-hover-color)', background: 'var(--affine-hover-color)',
borderRadius: '10px', borderRadius: '10px',
padding: '2px', padding: '2px',
// @ts-expect-error - fix electron drag
WebkitAppRegion: 'no-drag',
}); });