mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-01 01:29:31 +08:00
feat(editor): add edgeless crud extension (#9335)
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
import { updateXYWH } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
EdgelessCRUDIdentifier,
|
||||
updateXYWH,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
AlignBottomIcon,
|
||||
AlignDistributeHorizontallyIcon,
|
||||
@@ -267,7 +270,7 @@ export class EdgelessAlignButton extends WithDisposable(LitElement) {
|
||||
}
|
||||
|
||||
private _updateXYWH(ele: BlockSuite.EdgelessModel, bound: Bound) {
|
||||
const { updateElement } = this.edgeless.service;
|
||||
const { updateElement } = this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
const { updateBlock } = this.edgeless.doc;
|
||||
updateXYWH(ele, bound, updateElement, updateBlock);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import type {
|
||||
BrushElementModel,
|
||||
BrushProps,
|
||||
@@ -57,10 +58,7 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
|
||||
pickColor = (event: PickColorEvent) => {
|
||||
if (event.type === 'pick') {
|
||||
this.elements.forEach(ele =>
|
||||
this.service.updateElement(
|
||||
ele.id,
|
||||
packColor('color', { ...event.detail })
|
||||
)
|
||||
this.crud.updateElement(ele.id, packColor('color', { ...event.detail }))
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -93,6 +91,10 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
|
||||
return this.edgeless.surface;
|
||||
}
|
||||
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
private _setBrushProp<K extends keyof BrushProps>(
|
||||
key: K,
|
||||
value: BrushProps[K]
|
||||
@@ -101,7 +103,7 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
|
||||
this.elements
|
||||
.filter(notEqual(key, value))
|
||||
.forEach(element =>
|
||||
this.service.updateElement(element.id, { [key]: value })
|
||||
this.crud.updateElement(element.id, { [key]: value })
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
AddTextIcon,
|
||||
ConnectorCWithArrowIcon,
|
||||
@@ -222,10 +223,14 @@ const MODE_CHOOSE: [ConnectorMode, () => TemplateResult<1>][] = [
|
||||
] as const;
|
||||
|
||||
export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
pickColor = (event: PickColorEvent) => {
|
||||
if (event.type === 'pick') {
|
||||
this.elements.forEach(ele =>
|
||||
this.service.updateElement(
|
||||
this.crud.updateElement(
|
||||
ele.id,
|
||||
packColor('stroke', { ...event.detail })
|
||||
)
|
||||
@@ -257,7 +262,7 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
|
||||
if (frontEndpointStyle === rearEndpointStyle) return;
|
||||
|
||||
this.elements.forEach(element =>
|
||||
this.service.updateElement(element.id, {
|
||||
this.crud.updateElement(element.id, {
|
||||
frontEndpointStyle: rearEndpointStyle,
|
||||
rearEndpointStyle: frontEndpointStyle,
|
||||
})
|
||||
@@ -286,7 +291,7 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
|
||||
: 'rearEndpointStyle']: style,
|
||||
};
|
||||
this.elements.forEach(element =>
|
||||
this.service.updateElement(element.id, { ...props })
|
||||
this.crud.updateElement(element.id, { ...props })
|
||||
);
|
||||
}
|
||||
|
||||
@@ -297,7 +302,7 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
|
||||
this.elements
|
||||
.filter(notEqual(key, value))
|
||||
.forEach(element =>
|
||||
this.service.updateElement(element.id, { [key]: value })
|
||||
this.crud.updateElement(element.id, { [key]: value })
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -2,6 +2,7 @@ import {
|
||||
getDocContentWithMaxLength,
|
||||
getEmbedCardIcons,
|
||||
} from '@blocksuite/affine-block-embed';
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
CaptionIcon,
|
||||
CenterPeekIcon,
|
||||
@@ -114,6 +115,10 @@ export class EdgelessChangeEmbedCardButton extends WithDisposable(LitElement) {
|
||||
}
|
||||
`;
|
||||
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
private readonly _convertToCardView = () => {
|
||||
if (this._isCardView) {
|
||||
return;
|
||||
@@ -146,7 +151,7 @@ export class EdgelessChangeEmbedCardButton extends WithDisposable(LitElement) {
|
||||
bound.w = EMBED_CARD_WIDTH[targetStyle];
|
||||
bound.h = EMBED_CARD_HEIGHT[targetStyle];
|
||||
|
||||
const newId = this.edgeless.service.addBlock(
|
||||
const newId = this.crud.addBlock(
|
||||
targetFlavour,
|
||||
{ url, xywh: bound.serialize(), style: targetStyle, caption },
|
||||
this.edgeless.surface.model
|
||||
@@ -197,7 +202,7 @@ export class EdgelessChangeEmbedCardButton extends WithDisposable(LitElement) {
|
||||
bound.w = EMBED_CARD_WIDTH[targetStyle];
|
||||
bound.h = EMBED_CARD_HEIGHT[targetStyle];
|
||||
|
||||
const newId = this.edgeless.service.addBlock(
|
||||
const newId = this.crud.addBlock(
|
||||
flavour,
|
||||
{
|
||||
url,
|
||||
@@ -206,6 +211,7 @@ export class EdgelessChangeEmbedCardButton extends WithDisposable(LitElement) {
|
||||
},
|
||||
this.edgeless.surface.model
|
||||
);
|
||||
if (!newId) return;
|
||||
|
||||
this.std.command.exec('reassociateConnectors', {
|
||||
oldId: id,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
NoteIcon,
|
||||
RenameIcon,
|
||||
@@ -51,10 +52,14 @@ function getMostCommonColor(
|
||||
}
|
||||
|
||||
export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
pickColor = (event: PickColorEvent) => {
|
||||
if (event.type === 'pick') {
|
||||
this.frames.forEach(ele =>
|
||||
this.service.updateElement(
|
||||
this.crud.updateElement(
|
||||
ele.id,
|
||||
packColor('background', { ...event.detail })
|
||||
)
|
||||
@@ -116,7 +121,7 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
|
||||
|
||||
private _setFrameBackground(color: string) {
|
||||
this.frames.forEach(frame => {
|
||||
this.service.updateElement(frame.id, { background: color });
|
||||
this.crud.updateElement(frame.id, { background: color });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
ExpandIcon,
|
||||
LineStyleIcon,
|
||||
@@ -78,6 +79,10 @@ function getMostCommonBackground(
|
||||
}
|
||||
|
||||
export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
private readonly _setBorderRadius = (borderRadius: number) => {
|
||||
this.notes.forEach(note => {
|
||||
const props = {
|
||||
@@ -88,7 +93,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
},
|
||||
},
|
||||
};
|
||||
this.edgeless.service.updateElement(note.id, props);
|
||||
this.crud.updateElement(note.id, props);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -111,7 +116,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
if (event.type === 'pick') {
|
||||
this.notes.forEach(element => {
|
||||
const props = packColor('background', { ...event.detail });
|
||||
this.edgeless.service.updateElement(element.id, props);
|
||||
this.crud.updateElement(element.id, props);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -142,7 +147,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
|
||||
private _setBackground(background: string) {
|
||||
this.notes.forEach(element => {
|
||||
this.edgeless.service.updateElement(element.id, { background });
|
||||
this.crud.updateElement(element.id, { background });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,7 +178,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.edgeless.service.updateElement(note.id, { displayMode: newMode });
|
||||
this.crud.updateElement(note.id, { displayMode: newMode });
|
||||
|
||||
const noteParent = this.doc.getParent(note);
|
||||
assertExists(noteParent);
|
||||
@@ -208,7 +213,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
},
|
||||
},
|
||||
};
|
||||
this.edgeless.service.updateElement(note.id, props);
|
||||
this.crud.updateElement(note.id, props);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -222,7 +227,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
},
|
||||
},
|
||||
};
|
||||
this.edgeless.service.updateElement(note.id, props);
|
||||
this.crud.updateElement(note.id, props);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -236,7 +241,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
},
|
||||
},
|
||||
};
|
||||
this.edgeless.service.updateElement(note.id, props);
|
||||
this.crud.updateElement(note.id, props);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
AddTextIcon,
|
||||
ChangeShapeIcon,
|
||||
@@ -155,6 +156,10 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
|
||||
return this.edgeless.service;
|
||||
}
|
||||
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
#pickColor<K extends keyof Pick<ShapeProps, 'fillColor' | 'strokeColor'>>(
|
||||
key: K
|
||||
) {
|
||||
@@ -166,7 +171,7 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
|
||||
if (key === 'fillColor' && !ele.filled) {
|
||||
Object.assign(props, { filled: true });
|
||||
}
|
||||
this.service.updateElement(ele.id, props);
|
||||
this.crud.updateElement(ele.id, props);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -199,25 +204,25 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
|
||||
const filled = !isTransparent(fillColor);
|
||||
const color = this._getTextColor(fillColor);
|
||||
this.elements.forEach(ele =>
|
||||
this.service.updateElement(ele.id, { filled, fillColor, color })
|
||||
this.crud.updateElement(ele.id, { filled, fillColor, color })
|
||||
);
|
||||
}
|
||||
|
||||
private _setShapeStrokeColor(strokeColor: string) {
|
||||
this.elements.forEach(ele =>
|
||||
this.service.updateElement(ele.id, { strokeColor })
|
||||
this.crud.updateElement(ele.id, { strokeColor })
|
||||
);
|
||||
}
|
||||
|
||||
private _setShapeStrokeStyle(strokeStyle: StrokeStyle) {
|
||||
this.elements.forEach(ele =>
|
||||
this.service.updateElement(ele.id, { strokeStyle })
|
||||
this.crud.updateElement(ele.id, { strokeStyle })
|
||||
);
|
||||
}
|
||||
|
||||
private _setShapeStrokeWidth(strokeWidth: number) {
|
||||
this.elements.forEach(ele =>
|
||||
this.service.updateElement(ele.id, { strokeWidth })
|
||||
this.crud.updateElement(ele.id, { strokeWidth })
|
||||
);
|
||||
}
|
||||
|
||||
@@ -226,7 +231,7 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
|
||||
shapeStyle === ShapeStyle.General ? FontFamily.Inter : FontFamily.Kalam;
|
||||
|
||||
this.elements.forEach(ele => {
|
||||
this.service.updateElement(ele.id, { shapeStyle, fontFamily });
|
||||
this.crud.updateElement(ele.id, { shapeStyle, fontFamily });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -257,7 +262,7 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
|
||||
this._shapePanel.slots.select.on(shapeName => {
|
||||
this.edgeless.doc.captureSync();
|
||||
this.elements.forEach(element => {
|
||||
this.service.updateElement(element.id, {
|
||||
this.crud.updateElement(element.id, {
|
||||
shapeType: getShapeType(shapeName),
|
||||
radius: getShapeRadius(shapeName),
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import {
|
||||
ConnectorUtils,
|
||||
EdgelessCRUDIdentifier,
|
||||
normalizeShapeBound,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
@@ -176,6 +176,10 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
||||
}
|
||||
`;
|
||||
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
}
|
||||
|
||||
private readonly _setFontFamily = (fontFamily: FontFamily) => {
|
||||
const currentFontWeight = getMostCommonFontWeight(this.elements);
|
||||
const fontWeight = TextUtils.isFontWeightSupported(
|
||||
@@ -194,7 +198,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
||||
|
||||
const props = { fontFamily, fontWeight, fontStyle };
|
||||
this.elements.forEach(element => {
|
||||
this.service.updateElement(element.id, buildProps(element, props));
|
||||
this.crud.updateElement(element.id, buildProps(element, props));
|
||||
this._updateElementBound(element);
|
||||
});
|
||||
};
|
||||
@@ -202,7 +206,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
||||
private readonly _setFontSize = (fontSize: number) => {
|
||||
const props = { fontSize };
|
||||
this.elements.forEach(element => {
|
||||
this.service.updateElement(element.id, buildProps(element, props));
|
||||
this.crud.updateElement(element.id, buildProps(element, props));
|
||||
this._updateElementBound(element);
|
||||
});
|
||||
};
|
||||
@@ -213,7 +217,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
||||
) => {
|
||||
const props = { fontWeight, fontStyle };
|
||||
this.elements.forEach(element => {
|
||||
this.service.updateElement(element.id, buildProps(element, props));
|
||||
this.crud.updateElement(element.id, buildProps(element, props));
|
||||
this._updateElementBound(element);
|
||||
});
|
||||
};
|
||||
@@ -221,14 +225,14 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
||||
private readonly _setTextAlign = (textAlign: TextAlign) => {
|
||||
const props = { textAlign };
|
||||
this.elements.forEach(element => {
|
||||
this.service.updateElement(element.id, buildProps(element, props));
|
||||
this.crud.updateElement(element.id, buildProps(element, props));
|
||||
});
|
||||
};
|
||||
|
||||
private readonly _setTextColor = ({ detail: color }: ColorEvent) => {
|
||||
const props = { color };
|
||||
this.elements.forEach(element => {
|
||||
this.service.updateElement(element.id, buildProps(element, props));
|
||||
this.crud.updateElement(element.id, buildProps(element, props));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -257,7 +261,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
||||
},
|
||||
Bound.fromXYWH(element.deserializedXYWH)
|
||||
);
|
||||
this.service.updateElement(element.id, {
|
||||
this.crud.updateElement(element.id, {
|
||||
xywh: newBound.serialize(),
|
||||
});
|
||||
} else if (
|
||||
@@ -285,7 +289,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
||||
prevBounds
|
||||
);
|
||||
bounds.center = center;
|
||||
this.service.updateElement(element.id, {
|
||||
this.crud.updateElement(element.id, {
|
||||
labelXYWH: bounds.toXYWH(),
|
||||
});
|
||||
} else if (
|
||||
@@ -296,7 +300,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
||||
element,
|
||||
Bound.fromXYWH(element.deserializedXYWH)
|
||||
);
|
||||
this.service.updateElement(element.id, {
|
||||
this.crud.updateElement(element.id, {
|
||||
xywh: newBound.serialize(),
|
||||
});
|
||||
}
|
||||
@@ -307,7 +311,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
||||
if (event.type === 'pick') {
|
||||
this.elements.forEach(element => {
|
||||
const props = packColor('color', { ...event.detail });
|
||||
this.service.updateElement(element.id, buildProps(element, props));
|
||||
this.crud.updateElement(element.id, buildProps(element, props));
|
||||
this._updateElementBound(element);
|
||||
});
|
||||
return;
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
promptDocTitle,
|
||||
} from '@blocksuite/affine-block-embed';
|
||||
import type { ImageBlockComponent } from '@blocksuite/affine-block-image';
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import { isPeekable, peek } from '@blocksuite/affine-components/peek';
|
||||
import type { MenuItemGroup } from '@blocksuite/affine-components/toolbar';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
@@ -253,8 +254,9 @@ export const conversionsGroup: MenuItemGroup<ElementToolbarMoreMenuContext> = {
|
||||
if (title === null) return;
|
||||
|
||||
const linkedDoc = createLinkedDocFromNote(doc, element, title);
|
||||
const crud = std.get(EdgelessCRUDIdentifier);
|
||||
// insert linked doc card
|
||||
const cardId = service.addBlock(
|
||||
const cardId = crud.addBlock(
|
||||
'affine:embed-synced-doc',
|
||||
{
|
||||
xywh: element.xywh,
|
||||
@@ -300,15 +302,7 @@ export const conversionsGroup: MenuItemGroup<ElementToolbarMoreMenuContext> = {
|
||||
icon: LinkedPageIcon({ width: '20', height: '20' }),
|
||||
label: 'Create linked doc',
|
||||
type: 'create-linked-doc',
|
||||
action: async ({
|
||||
doc,
|
||||
selection,
|
||||
service,
|
||||
surface,
|
||||
edgeless,
|
||||
host,
|
||||
std,
|
||||
}) => {
|
||||
action: async ({ doc, selection, surface, edgeless, host, std }) => {
|
||||
const title = await promptDocTitle(std);
|
||||
if (title === null) return;
|
||||
|
||||
@@ -318,6 +312,7 @@ export const conversionsGroup: MenuItemGroup<ElementToolbarMoreMenuContext> = {
|
||||
elements,
|
||||
title
|
||||
);
|
||||
const crud = std.get(EdgelessCRUDIdentifier);
|
||||
// delete selected elements
|
||||
doc.transact(() => {
|
||||
deleteElements(edgeless, elements);
|
||||
@@ -326,7 +321,7 @@ export const conversionsGroup: MenuItemGroup<ElementToolbarMoreMenuContext> = {
|
||||
const width = 364;
|
||||
const height = 390;
|
||||
const bound = getCommonBoundWithRotation(elements);
|
||||
const cardId = service.addBlock(
|
||||
const cardId = crud.addBlock(
|
||||
'affine:embed-linked-doc',
|
||||
{
|
||||
xywh: `[${bound.center[0] - width / 2}, ${bound.center[1] - height / 2}, ${width}, ${height}]`,
|
||||
|
||||
Reference in New Issue
Block a user