mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-23 13:29:02 +08:00
fix(editor): merge drag function and fix it (#9329)
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
import type { DropType } from '@blocksuite/affine-shared/services';
|
||||
import type { Rect } from '@blocksuite/global/utils';
|
||||
|
||||
export const DRAG_HANDLE_CONTAINER_HEIGHT = 24;
|
||||
export const DRAG_HANDLE_CONTAINER_WIDTH = 16;
|
||||
export const DRAG_HANDLE_CONTAINER_WIDTH_TOP_LEVEL = 8;
|
||||
@@ -20,9 +17,3 @@ export const HOVER_AREA_RECT_PADDING_TOP_LEVEL = 6;
|
||||
export const NOTE_CONTAINER_PADDING = 24;
|
||||
export const EDGELESS_NOTE_EXTRA_PADDING = 20;
|
||||
export const DRAG_HOVER_RECT_PADDING = 4;
|
||||
|
||||
export type DropResult = {
|
||||
rect: Rect | null;
|
||||
dropBlockId: string;
|
||||
dropType: DropType;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { RootBlockModel } from '@blocksuite/affine-model';
|
||||
import { DocModeProvider } from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
DocModeProvider,
|
||||
type DropType,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
calcDropTarget,
|
||||
type DroppingType,
|
||||
type DropResult,
|
||||
getScrollContainer,
|
||||
isInsideEdgelessEditor,
|
||||
isInsidePageEditor,
|
||||
@@ -27,14 +27,12 @@ import { autoScroll } from '../../../root-block/text-selection/utils.js';
|
||||
import type { EdgelessRootService } from '../../edgeless/index.js';
|
||||
import type { DragPreview } from './components/drag-preview.js';
|
||||
import type { DropIndicator } from './components/drop-indicator.js';
|
||||
import type { DropResult } from './config.js';
|
||||
import type { AFFINE_DRAG_HANDLE_WIDGET } from './consts.js';
|
||||
import { PreviewHelper } from './helpers/preview-helper.js';
|
||||
import { RectHelper } from './helpers/rect-helper.js';
|
||||
import { SelectionHelper } from './helpers/selection-helper.js';
|
||||
import { styles } from './styles.js';
|
||||
import {
|
||||
calcDropTarget,
|
||||
containBlock,
|
||||
containChildBlock,
|
||||
getClosestBlockByPoint,
|
||||
@@ -107,9 +105,6 @@ export class AffineDragHandleWidget extends WidgetComponent<RootBlockModel> {
|
||||
return null;
|
||||
}
|
||||
|
||||
let rect = null;
|
||||
let dropType: DropType = 'before';
|
||||
|
||||
const result = calcDropTarget(
|
||||
point,
|
||||
model,
|
||||
@@ -119,20 +114,9 @@ export class AffineDragHandleWidget extends WidgetComponent<RootBlockModel> {
|
||||
isDraggedElementNote === false
|
||||
);
|
||||
|
||||
if (result) {
|
||||
rect = result.rect;
|
||||
dropType = result.dropType;
|
||||
}
|
||||
if (isDraggedElementNote && result?.type === 'in') return null;
|
||||
|
||||
if (isDraggedElementNote && dropType === 'in') return null;
|
||||
|
||||
const dropIndicator = {
|
||||
rect,
|
||||
dropBlockId: blockId,
|
||||
dropType,
|
||||
};
|
||||
|
||||
return dropIndicator;
|
||||
return result;
|
||||
};
|
||||
|
||||
private readonly _handleEventWatcher = new HandleEventWatcher(this);
|
||||
@@ -181,8 +165,8 @@ export class AffineDragHandleWidget extends WidgetComponent<RootBlockModel> {
|
||||
|
||||
private readonly _updateDropResult = (dropResult: DropResult | null) => {
|
||||
if (!this.dropIndicator) return;
|
||||
this.dropBlockId = dropResult?.dropBlockId ?? '';
|
||||
this.dropType = dropResult?.dropType ?? null;
|
||||
this.dropBlockId = dropResult?.modelState.model.id ?? '';
|
||||
this.dropType = dropResult?.type ?? null;
|
||||
if (dropResult?.rect) {
|
||||
const offsetParentRect =
|
||||
this.dragHandleContainerOffsetParent.getBoundingClientRect();
|
||||
@@ -237,7 +221,7 @@ export class AffineDragHandleWidget extends WidgetComponent<RootBlockModel> {
|
||||
|
||||
dropIndicator: DropIndicator | null = null;
|
||||
|
||||
dropType: DropType | null = null;
|
||||
dropType: DroppingType | null = null;
|
||||
|
||||
edgelessWatcher = new EdgelessWatcher(this);
|
||||
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
import { ParagraphBlockComponent } from '@blocksuite/affine-block-paragraph';
|
||||
import type { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import { BLOCK_CHILDREN_CONTAINER_PADDING_LEFT } from '@blocksuite/affine-shared/consts';
|
||||
import {
|
||||
DocModeProvider,
|
||||
type DropType,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { DocModeProvider } from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
calcDropTarget,
|
||||
type DropResult,
|
||||
findClosestBlockComponent,
|
||||
getBlockProps,
|
||||
getClosestBlockComponentByElement,
|
||||
getClosestBlockComponentByPoint,
|
||||
getDropRectByPoint,
|
||||
getRectByBlockComponent,
|
||||
matchFlavours,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import type {
|
||||
@@ -26,7 +21,6 @@ import {
|
||||
DRAG_HANDLE_CONTAINER_HEIGHT,
|
||||
DRAG_HANDLE_CONTAINER_OFFSET_LEFT,
|
||||
DRAG_HANDLE_CONTAINER_OFFSET_LEFT_LIST,
|
||||
type DropResult,
|
||||
EDGELESS_NOTE_EXTRA_PADDING,
|
||||
NOTE_CONTAINER_PADDING,
|
||||
} from './config.js';
|
||||
@@ -181,116 +175,6 @@ export const getClosestBlockByPoint = (
|
||||
return closestBlock;
|
||||
};
|
||||
|
||||
export function calcDropTarget(
|
||||
point: Point,
|
||||
model: BlockModel,
|
||||
element: Element,
|
||||
draggingElements: BlockComponent[],
|
||||
scale: number,
|
||||
/**
|
||||
* Allow the dragging block to be dropped as sublist
|
||||
*/
|
||||
allowSublist: boolean = true
|
||||
): DropResult | null {
|
||||
let type: DropType | 'none' = 'none';
|
||||
const height = 3 * scale;
|
||||
const dropRect = getDropRectByPoint(point, model, element);
|
||||
if (!dropRect) return null;
|
||||
const { rect: domRect } = dropRect;
|
||||
|
||||
const distanceToTop = Math.abs(domRect.top - point.y);
|
||||
const distanceToBottom = Math.abs(domRect.bottom - point.y);
|
||||
const before = distanceToTop < distanceToBottom;
|
||||
|
||||
type = before ? 'before' : 'after';
|
||||
let offsetY = 4;
|
||||
|
||||
if (type === 'before') {
|
||||
// before
|
||||
let prev;
|
||||
let prevRect;
|
||||
|
||||
prev = element.previousElementSibling;
|
||||
if (prev) {
|
||||
if (
|
||||
draggingElements.length &&
|
||||
prev === draggingElements[draggingElements.length - 1]
|
||||
) {
|
||||
type = 'none';
|
||||
} else {
|
||||
prevRect = getRectByBlockComponent(prev);
|
||||
}
|
||||
} else {
|
||||
prev = element.parentElement?.previousElementSibling;
|
||||
if (prev) {
|
||||
prevRect = prev.getBoundingClientRect();
|
||||
}
|
||||
}
|
||||
|
||||
if (prevRect) {
|
||||
offsetY = (domRect.top - prevRect.bottom) / 2;
|
||||
}
|
||||
} else {
|
||||
// Only consider drop as children when target block is list block.
|
||||
// To drop in, the position must after the target first
|
||||
// If drop in target has children, we can use insert before or after of that children
|
||||
// to achieve the same effect.
|
||||
const hasChild = (element as BlockComponent).childBlocks.length;
|
||||
if (
|
||||
allowSublist &&
|
||||
matchFlavours(model, ['affine:list']) &&
|
||||
!hasChild &&
|
||||
point.x > domRect.x + BLOCK_CHILDREN_CONTAINER_PADDING_LEFT
|
||||
) {
|
||||
type = 'in';
|
||||
}
|
||||
// after
|
||||
let next;
|
||||
let nextRect;
|
||||
|
||||
next = element.nextElementSibling;
|
||||
if (next) {
|
||||
if (
|
||||
type === 'after' &&
|
||||
draggingElements.length &&
|
||||
next === draggingElements[0]
|
||||
) {
|
||||
type = 'none';
|
||||
next = null;
|
||||
}
|
||||
} else {
|
||||
next = getClosestBlockComponentByElement(
|
||||
element.parentElement
|
||||
)?.nextElementSibling;
|
||||
}
|
||||
|
||||
if (next) {
|
||||
nextRect = getRectByBlockComponent(next);
|
||||
offsetY = (nextRect.top - domRect.bottom) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'none') return null;
|
||||
|
||||
let top = domRect.top;
|
||||
if (type === 'before') {
|
||||
top -= offsetY;
|
||||
} else {
|
||||
top += domRect.height + offsetY;
|
||||
}
|
||||
|
||||
if (type === 'in') {
|
||||
domRect.x += BLOCK_CHILDREN_CONTAINER_PADDING_LEFT;
|
||||
domRect.width -= BLOCK_CHILDREN_CONTAINER_PADDING_LEFT;
|
||||
}
|
||||
|
||||
return {
|
||||
rect: Rect.fromLWTH(domRect.left, domRect.width, top - height / 2, height),
|
||||
dropBlockId: model.id,
|
||||
dropType: type,
|
||||
};
|
||||
}
|
||||
|
||||
export const getDropResult = (
|
||||
event: MouseEvent,
|
||||
scale: number = 1
|
||||
|
||||
Reference in New Issue
Block a user