mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-27 19:02:23 +08:00
feat: add page mode filter (#2601)
Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
@@ -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');
|
||||||
|
|||||||
@@ -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} />;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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',
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user