mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
feat(core): frame editor settings (#9970)
Co-authored-by: L-Sun <zover.v@gmail.com> Co-authored-by: Mirone <Saul-Mirone@outlook.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"type": "page",
|
||||
"meta": {
|
||||
"id": "gIUEIHL42k",
|
||||
"title": "FrameDoc",
|
||||
"createDate": 1738858597791,
|
||||
"tags": []
|
||||
},
|
||||
"blocks": {
|
||||
"type": "block",
|
||||
"id": "MCYCDPz_QH",
|
||||
"flavour": "affine:page",
|
||||
"version": 2,
|
||||
"props": {
|
||||
"title": {
|
||||
"$blocksuite:internal:text$": true,
|
||||
"delta": [
|
||||
{
|
||||
"insert": "FrameDoc"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "block",
|
||||
"id": "I_s0rS2Pbl",
|
||||
"flavour": "affine:surface",
|
||||
"version": 5,
|
||||
"props": {
|
||||
"elements": {}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "block",
|
||||
"id": "mHE8GI9UWx",
|
||||
"flavour": "affine:frame",
|
||||
"version": 1,
|
||||
"props": {
|
||||
"title": {
|
||||
"$blocksuite:internal:text$": true,
|
||||
"delta": [
|
||||
{
|
||||
"insert": "Frame 1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"background": "transparent",
|
||||
"xywh": "[-186.37939453125,-68.03814697265625,375.8616943359375,114.787109375]",
|
||||
"index": "Zz",
|
||||
"childElementIds": {},
|
||||
"presentationIndex": "a00zHdtY37OLhj7JOhCr9ywYQXy1SbAI6kM",
|
||||
"lockedBySelf": false
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,8 @@ export type DocName =
|
||||
| 'flow'
|
||||
| 'text'
|
||||
| 'connector'
|
||||
| 'mindmap';
|
||||
| 'mindmap'
|
||||
| 'frame';
|
||||
|
||||
const docMap = new Map<DocName, Promise<Store | undefined>>();
|
||||
|
||||
@@ -40,6 +41,10 @@ async function loadShape() {
|
||||
return (await import('./shape.json')).default;
|
||||
}
|
||||
|
||||
async function loadFrame() {
|
||||
return (await import('./frame.json')).default;
|
||||
}
|
||||
|
||||
async function loadFlow() {
|
||||
return (await import('./flow.json')).default;
|
||||
}
|
||||
@@ -60,6 +65,7 @@ const loaders = {
|
||||
note: loadNote,
|
||||
pen: loadPen,
|
||||
shape: loadShape,
|
||||
frame: loadFrame,
|
||||
flow: loadFlow,
|
||||
text: loadText,
|
||||
connector: loadConnector,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { SettingWrapper } from '@affine/component/setting-components';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
|
||||
import { ConnectorSettings } from './connector';
|
||||
import { FrameSettings } from './frame';
|
||||
import { GeneralEdgelessSetting } from './general';
|
||||
import { MindMapSettings } from './mind-map';
|
||||
import { NoteSettings } from './note';
|
||||
@@ -17,6 +18,7 @@ export const Edgeless = () => {
|
||||
<NoteSettings />
|
||||
<TextSettings />
|
||||
<ShapeSettings />
|
||||
<FrameSettings />
|
||||
<ConnectorSettings />
|
||||
<PenSettings />
|
||||
<MindMapSettings />
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import { MenuItem, MenuTrigger } from '@affine/component';
|
||||
import { SettingRow } from '@affine/component/setting-components';
|
||||
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { DefaultTheme } from '@blocksuite/affine/blocks';
|
||||
import type { Store } from '@blocksuite/affine/store';
|
||||
import { useFramework, useLiveData } from '@toeverything/infra';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { DropdownMenu } from '../menu';
|
||||
import { menuTrigger } from '../style.css';
|
||||
import { usePalettes } from '../utils';
|
||||
import { Point } from './point';
|
||||
import { EdgelessSnapshot } from './snapshot';
|
||||
|
||||
export const FrameSettings = () => {
|
||||
const t = useI18n();
|
||||
const framework = useFramework();
|
||||
const { editorSetting } = framework.get(EditorSettingService);
|
||||
const settings = useLiveData(editorSetting.settings$);
|
||||
const { palettes, getCurrentColor } = usePalettes(
|
||||
[
|
||||
{ key: 'Transparent', value: DefaultTheme.transparent },
|
||||
...DefaultTheme.FillColorPalettes,
|
||||
],
|
||||
DefaultTheme.transparent
|
||||
);
|
||||
|
||||
const { background } = settings['affine:frame'];
|
||||
const currentColor = useMemo(() => {
|
||||
return getCurrentColor(background);
|
||||
}, [getCurrentColor, background]);
|
||||
|
||||
const colorItems = useMemo(() => {
|
||||
return palettes.map(({ key, value, resolvedValue }) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('affine:frame', { background: value });
|
||||
};
|
||||
const isSelected = isEqual(background, value);
|
||||
return (
|
||||
<MenuItem
|
||||
key={key}
|
||||
onSelect={handler}
|
||||
selected={isSelected}
|
||||
prefix={<Point color={resolvedValue} />}
|
||||
>
|
||||
{key}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, background, palettes]);
|
||||
|
||||
const getElements = useCallback((doc: Store) => {
|
||||
return doc.getBlocksByFlavour('affine:frame') || [];
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EdgelessSnapshot
|
||||
title={t['com.affine.settings.editorSettings.edgeless.frame']()}
|
||||
docName="frame"
|
||||
keyName="affine:frame"
|
||||
getElements={getElements}
|
||||
/>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.frame.background'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
{currentColor ? (
|
||||
<DropdownMenu
|
||||
items={colorItems}
|
||||
trigger={
|
||||
<MenuTrigger
|
||||
className={menuTrigger}
|
||||
prefix={<Point color={currentColor.resolvedValue} />}
|
||||
>
|
||||
{currentColor.key}
|
||||
</MenuTrigger>
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
</SettingRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -115,7 +115,8 @@ export const EdgelessSnapshot = (props: Props) => {
|
||||
doc.readonly = false;
|
||||
edgelessBlock.editorViewportSelector = 'ref-viewport';
|
||||
const frame = getFrameBlock(doc);
|
||||
if (frame) {
|
||||
if (frame && docName !== 'frame') {
|
||||
// docName with value 'frame' shouldn't be deleted, it is a part of frame settings
|
||||
boundMap.set(docName, Bound.deserialize(frame.xywh));
|
||||
doc.deleteBlock(frame);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user