feat(core): set doc mode and primary doc mode separately (#8359)

https://github.com/user-attachments/assets/98c282f2-4c53-475f-bf10-936a626c2630
This commit is contained in:
JimmFly
2024-10-17 13:48:45 +00:00
parent 7dae5c5dd5
commit bfb8d582ed
15 changed files with 192 additions and 90 deletions

View File

@@ -1,4 +1,4 @@
import { toast } from '@affine/component';
import { notify } from '@affine/component';
import {
Menu,
MenuItem,
@@ -74,6 +74,7 @@ export const PageHeaderMenuButton = ({
editorService.editor.doc.meta$.map(meta => meta.trash)
);
const currentMode = useLiveData(editorService.editor.mode$);
const primaryMode = useLiveData(editorService.editor.doc.primaryMode$);
const workbench = useService(WorkbenchService).workbench;
@@ -148,16 +149,22 @@ export const PageHeaderMenuButton = ({
}, [rename]);
const handleSwitchMode = useCallback(() => {
editorService.editor.toggleMode();
const mode = primaryMode === 'page' ? 'edgeless' : 'page';
editorService.editor.doc.setPrimaryMode(mode);
track.$.header.docOptions.switchPageMode({
mode: currentMode === 'page' ? 'edgeless' : 'page',
mode,
});
toast(
currentMode === 'page'
? t['com.affine.toastMessage.edgelessMode']()
: t['com.affine.toastMessage.pageMode']()
);
}, [currentMode, editorService, t]);
notify.success({
title:
primaryMode === 'page'
? t['com.affine.toastMessage.defaultMode.edgeless.title']()
: t['com.affine.toastMessage.defaultMode.page.title'](),
message:
primaryMode === 'page'
? t['com.affine.toastMessage.defaultMode.edgeless.message']()
: t['com.affine.toastMessage.defaultMode.page.message'](),
});
}, [primaryMode, editorService, t]);
const handleMenuOpenChange = useCallback((open: boolean) => {
if (open) {
@@ -264,14 +271,13 @@ export const PageHeaderMenuButton = ({
</MenuItem>
)}
<MenuItem
prefixIcon={currentMode === 'page' ? <EdgelessIcon /> : <PageIcon />}
prefixIcon={primaryMode === 'page' ? <EdgelessIcon /> : <PageIcon />}
data-testid="editor-option-menu-edgeless"
onSelect={handleSwitchMode}
>
{t['Convert to ']()}
{currentMode === 'page'
? t['com.affine.pageMode.edgeless']()
: t['com.affine.pageMode.page']()}
{primaryMode === 'page'
? t['com.affine.editorDefaultMode.edgeless']()
: t['com.affine.editorDefaultMode.page']()}
</MenuItem>
<MenuItem
data-testid="editor-option-menu-favorite"

View File

@@ -1,4 +1,4 @@
import { RadioGroup, type RadioItem, toast, Tooltip } from '@affine/component';
import { RadioGroup, type RadioItem, Tooltip } from '@affine/component';
import { registerAffineCommand } from '@affine/core/commands';
import { EditorService } from '@affine/core/modules/editor';
import { useI18n } from '@affine/i18n';
@@ -41,19 +41,15 @@ export const EditorModeSwitch = () => {
if (currentMode === 'page' || isSharedMode || trash) return;
editor.setMode('page');
editor.setSelector(undefined);
editor.doc.setPrimaryMode('page');
toast(t['com.affine.toastMessage.pageMode']());
track.$.header.actions.switchPageMode({ mode: 'page' });
}, [currentMode, editor, isSharedMode, t, trash]);
}, [currentMode, editor, isSharedMode, trash]);
const toggleEdgeless = useCallback(() => {
if (currentMode === 'edgeless' || isSharedMode || trash) return;
editor.setMode('edgeless');
editor.setSelector(undefined);
editor.doc.setPrimaryMode('edgeless');
toast(t['com.affine.toastMessage.edgelessMode']());
track.$.header.actions.switchPageMode({ mode: 'edgeless' });
}, [currentMode, editor, isSharedMode, t, trash]);
}, [currentMode, editor, isSharedMode, trash]);
const onModeChange = useCallback(
(mode: DocMode) => {

View File

@@ -3,6 +3,7 @@ import {
CheckBoxCheckLinearIcon,
CreatedEditedIcon,
DateTimeIcon,
FileIcon,
NumberIcon,
TagIcon,
TextIcon,
@@ -11,6 +12,7 @@ import {
import { CheckboxValue } from './checkbox';
import { CreatedByValue, UpdatedByValue } from './created-updated-by';
import { DateValue } from './date';
import { DocPrimaryModeValue } from './doc-primary-mode';
import { NumberValue } from './number';
import { TagsValue } from './tags';
import { TextValue } from './text';
@@ -54,6 +56,11 @@ export const DocPropertyTypes = {
uniqueId: 'tags',
renameable: false,
},
docPrimaryMode: {
icon: FileIcon,
value: DocPrimaryModeValue,
name: 'com.affine.page-properties.property.docPrimaryMode',
},
} as Record<
string,
{

View File

@@ -0,0 +1,58 @@
import {
notify,
PropertyValue,
RadioGroup,
type RadioItem,
} from '@affine/component';
import { useI18n } from '@affine/i18n';
import type { DocMode } from '@blocksuite/affine/blocks';
import { DocService, useLiveData, useService } from '@toeverything/infra';
import { useCallback, useMemo } from 'react';
export const DocPrimaryModeValue = () => {
const t = useI18n();
const doc = useService(DocService).doc;
const primaryMode = useLiveData(doc.primaryMode$);
const DocModeItems = useMemo<RadioItem[]>(
() => [
{
value: 'page' as DocMode,
label: t['Page'](),
},
{
value: 'edgeless' as DocMode,
label: t['Edgeless'](),
},
],
[t]
);
const handleChange = useCallback(
(mode: DocMode) => {
doc.setPrimaryMode(mode);
notify.success({
title:
mode === 'page'
? t['com.affine.toastMessage.defaultMode.page.title']()
: t['com.affine.toastMessage.defaultMode.edgeless.title'](),
message:
mode === 'page'
? t['com.affine.toastMessage.defaultMode.page.message']()
: t['com.affine.toastMessage.defaultMode.edgeless.message'](),
});
},
[doc, t]
);
return (
<PropertyValue>
<RadioGroup
width={194}
value={primaryMode}
onChange={handleChange}
items={DocModeItems}
/>
</PropertyValue>
);
};