mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-02 02:00:49 +08:00
091bac1047
Close [BS-3624](https://linear.app/affine-design/issue/BS-3624/page模式单选图片的时候希望有comment-按钮) #### PR Dependency Tree * **PR #13304** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a comment button to the image and surface reference block toolbars for easier commenting. * **Refactor** * Simplified array flattening operations across multiple components and utilities by replacing `.map(...).flat()` with `.flatMap(...)`, improving code readability and maintainability. * **Bug Fixes** * Improved comment creation logic to allow adding comments even when selections exist. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
import { FrameBlockModel, GroupElementModel } from '@blocksuite/affine-model';
|
|
import {
|
|
deserializeXYWH,
|
|
getQuadBoundWithRotation,
|
|
} from '@blocksuite/global/gfx';
|
|
import type { GfxBlockElementModel, GfxModel } from '@blocksuite/std/gfx';
|
|
import type { BlockModel } from '@blocksuite/store';
|
|
|
|
export function getSelectedRect(selected: GfxModel[]): DOMRect {
|
|
if (selected.length === 0) {
|
|
return new DOMRect();
|
|
}
|
|
|
|
const lockedElementsByFrame = selected.flatMap(selectable => {
|
|
if (selectable instanceof FrameBlockModel && selectable.isLocked()) {
|
|
return selectable.descendantElements;
|
|
}
|
|
return [];
|
|
});
|
|
|
|
selected = [...new Set([...selected, ...lockedElementsByFrame])];
|
|
|
|
if (selected.length === 1) {
|
|
const [x, y, w, h] = deserializeXYWH(selected[0].xywh);
|
|
return new DOMRect(x, y, w, h);
|
|
}
|
|
|
|
return getElementsWithoutGroup(selected).reduce(
|
|
(bounds, selectable, index) => {
|
|
const rotate = isTopLevelBlock(selectable) ? 0 : selectable.rotate;
|
|
const [x, y, w, h] = deserializeXYWH(selectable.xywh);
|
|
let { left, top, right, bottom } = getQuadBoundWithRotation({
|
|
x,
|
|
y,
|
|
w,
|
|
h,
|
|
rotate,
|
|
});
|
|
|
|
if (index !== 0) {
|
|
left = Math.min(left, bounds.left);
|
|
top = Math.min(top, bounds.top);
|
|
right = Math.max(right, bounds.right);
|
|
bottom = Math.max(bottom, bounds.bottom);
|
|
}
|
|
|
|
bounds.x = left;
|
|
bounds.y = top;
|
|
bounds.width = right - left;
|
|
bounds.height = bottom - top;
|
|
|
|
return bounds;
|
|
},
|
|
new DOMRect()
|
|
);
|
|
}
|
|
|
|
export function getElementsWithoutGroup(elements: GfxModel[]) {
|
|
const set = new Set<GfxModel>();
|
|
|
|
elements.forEach(element => {
|
|
if (element instanceof GroupElementModel) {
|
|
element.descendantElements
|
|
.filter(descendant => !(descendant instanceof GroupElementModel))
|
|
.forEach(descendant => set.add(descendant));
|
|
} else {
|
|
set.add(element);
|
|
}
|
|
});
|
|
return Array.from(set);
|
|
}
|
|
|
|
export function isTopLevelBlock(
|
|
selectable: BlockModel | GfxModel | null
|
|
): selectable is GfxBlockElementModel {
|
|
return !!selectable && 'flavour' in selectable;
|
|
}
|