mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-24 01:42:55 +08:00
refactor(editor): extract drag handle widget (#9415)
This commit is contained in:
@@ -4,8 +4,10 @@ import {
|
||||
DocDisplayMetaService,
|
||||
DocModeService,
|
||||
EmbedOptionService,
|
||||
PageViewportServiceExtension,
|
||||
ThemeService,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { AFFINE_DRAG_HANDLE_WIDGET } from '@blocksuite/affine-widget-drag-handle';
|
||||
import {
|
||||
AFFINE_DOC_REMOTE_SELECTION_WIDGET,
|
||||
AFFINE_EDGELESS_REMOTE_SELECTION_WIDGET,
|
||||
@@ -25,7 +27,6 @@ import { literal, unsafeStatic } from 'lit/static-html.js';
|
||||
import { ExportManagerExtension } from '../../_common/export-manager/export-manager.js';
|
||||
import { RootBlockAdapterExtensions } from '../adapters/extension.js';
|
||||
import { commands } from '../commands/index.js';
|
||||
import { AFFINE_DRAG_HANDLE_WIDGET } from '../widgets/drag-handle/consts.js';
|
||||
import { AFFINE_EDGELESS_AUTO_CONNECT_WIDGET } from '../widgets/edgeless-auto-connect/edgeless-auto-connect.js';
|
||||
import { AFFINE_EDGELESS_ZOOM_TOOLBAR_WIDGET } from '../widgets/edgeless-zoom-toolbar/index.js';
|
||||
import { EDGELESS_ELEMENT_TOOLBAR_WIDGET } from '../widgets/element-toolbar/index.js';
|
||||
@@ -97,6 +98,7 @@ const EdgelessCommonExtension: ExtensionType[] = [
|
||||
ExportManagerExtension,
|
||||
ToolController,
|
||||
DNDAPIExtension,
|
||||
PageViewportServiceExtension,
|
||||
DocDisplayMetaService,
|
||||
RootBlockAdapterExtensions,
|
||||
FileDropExtension,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { SurfaceBlockComponent } from '@blocksuite/affine-block-surface';
|
||||
import { addNote } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
DEFAULT_NOTE_WIDTH,
|
||||
@@ -11,7 +12,6 @@ import { Point } from '@blocksuite/global/utils';
|
||||
import { effect } from '@preact/signals-core';
|
||||
|
||||
import { hasClassNameInList } from '../../../_common/utils/index.js';
|
||||
import { addNote } from '../utils/common.js';
|
||||
import { EXCLUDING_MOUSE_OUT_CLASS_LIST } from '../utils/consts.js';
|
||||
import { DraggingNoteOverlay, NoteOverlay } from '../utils/tool-overlay.js';
|
||||
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
|
||||
import {
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
DEFAULT_NOTE_WIDTH,
|
||||
NOTE_MIN_HEIGHT,
|
||||
type NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
|
||||
import { handleNativeRangeAtPoint } from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||
import {
|
||||
type IPoint,
|
||||
type Point,
|
||||
serializeXYWH,
|
||||
} from '@blocksuite/global/utils';
|
||||
|
||||
import { DEFAULT_NOTE_OFFSET_X, DEFAULT_NOTE_OFFSET_Y } from './consts.js';
|
||||
|
||||
export function addNoteAtPoint(
|
||||
std: BlockStdScope,
|
||||
/**
|
||||
* The point is in browser coordinate
|
||||
*/
|
||||
point: IPoint,
|
||||
options: {
|
||||
width?: number;
|
||||
height?: number;
|
||||
parentId?: string;
|
||||
noteIndex?: number;
|
||||
offsetX?: number;
|
||||
offsetY?: number;
|
||||
scale?: number;
|
||||
} = {}
|
||||
) {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
const crud = std.get(EdgelessCRUDIdentifier);
|
||||
const {
|
||||
width = DEFAULT_NOTE_WIDTH,
|
||||
height = DEFAULT_NOTE_HEIGHT,
|
||||
offsetX = DEFAULT_NOTE_OFFSET_X,
|
||||
offsetY = DEFAULT_NOTE_OFFSET_Y,
|
||||
parentId = gfx.doc.root?.id,
|
||||
noteIndex,
|
||||
scale = 1,
|
||||
} = options;
|
||||
const [x, y] = gfx.viewport.toModelCoord(point.x, point.y);
|
||||
const blockId = crud.addBlock(
|
||||
'affine:note',
|
||||
{
|
||||
xywh: serializeXYWH(
|
||||
x - offsetX * scale,
|
||||
y - offsetY * scale,
|
||||
width,
|
||||
height
|
||||
),
|
||||
displayMode: NoteDisplayMode.EdgelessOnly,
|
||||
},
|
||||
parentId,
|
||||
noteIndex
|
||||
);
|
||||
|
||||
std.getOptional(TelemetryProvider)?.track('CanvasElementAdded', {
|
||||
control: 'canvas:draw',
|
||||
page: 'whiteboard editor',
|
||||
module: 'toolbar',
|
||||
segment: 'toolbar',
|
||||
type: 'note',
|
||||
});
|
||||
|
||||
return blockId;
|
||||
}
|
||||
|
||||
type NoteOptions = {
|
||||
childFlavour: NoteChildrenFlavour;
|
||||
childType: string | null;
|
||||
collapse: boolean;
|
||||
};
|
||||
|
||||
export function addNote(
|
||||
std: BlockStdScope,
|
||||
point: Point,
|
||||
options: NoteOptions,
|
||||
width = DEFAULT_NOTE_WIDTH,
|
||||
height = DEFAULT_NOTE_HEIGHT
|
||||
) {
|
||||
const noteId = addNoteAtPoint(std, point, {
|
||||
width,
|
||||
height,
|
||||
});
|
||||
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
const doc = std.doc;
|
||||
|
||||
const blockId = doc.addBlock(
|
||||
options.childFlavour,
|
||||
{ type: options.childType },
|
||||
noteId
|
||||
);
|
||||
if (options.collapse && height > NOTE_MIN_HEIGHT) {
|
||||
const note = doc.getBlockById(noteId) as NoteBlockModel;
|
||||
doc.updateBlock(note, () => {
|
||||
note.edgeless.collapse = true;
|
||||
note.edgeless.collapsedHeight = height;
|
||||
});
|
||||
}
|
||||
gfx.tool.setTool('default');
|
||||
|
||||
// Wait for edgelessTool updated
|
||||
requestAnimationFrame(() => {
|
||||
const blocks =
|
||||
(doc.root?.children.filter(
|
||||
child => child.flavour === 'affine:note'
|
||||
) as BlockSuite.EdgelessBlockModelType[]) ?? [];
|
||||
const element = blocks.find(b => b.id === noteId);
|
||||
if (element) {
|
||||
gfx.selection.set({
|
||||
elements: [element.id],
|
||||
editing: true,
|
||||
});
|
||||
|
||||
// Waiting dom updated, `note mask` is removed
|
||||
if (blockId) {
|
||||
focusTextModel(gfx.std, blockId);
|
||||
} else {
|
||||
// Cannot reuse `handleNativeRangeClick` directly here,
|
||||
// since `retargetClick` will re-target to pervious editor
|
||||
handleNativeRangeAtPoint(point.x, point.y);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -6,8 +6,6 @@ import {
|
||||
StrokeStyle,
|
||||
} from '@blocksuite/affine-model';
|
||||
|
||||
export const DEFAULT_NOTE_OFFSET_X = 30;
|
||||
export const DEFAULT_NOTE_OFFSET_Y = 40;
|
||||
export const NOTE_OVERLAY_OFFSET_X = 6;
|
||||
export const NOTE_OVERLAY_OFFSET_Y = 6;
|
||||
export const NOTE_OVERLAY_WIDTH = 100;
|
||||
|
||||
Reference in New Issue
Block a user