refactor(editor): use lodash (#10657)
This commit is contained in:
@@ -57,7 +57,7 @@ import {
|
||||
type SerializedXYWH,
|
||||
Vec,
|
||||
} from '@blocksuite/global/gfx';
|
||||
import { assertType, DisposableGroup, nToLast } from '@blocksuite/global/utils';
|
||||
import { assertType, DisposableGroup } from '@blocksuite/global/utils';
|
||||
import {
|
||||
type BlockSnapshot,
|
||||
BlockSnapshotSchema,
|
||||
@@ -1168,13 +1168,13 @@ export class EdgelessClipboardController extends PageClipboard {
|
||||
const bGroups = b.groups as SurfaceGroupLikeModel[];
|
||||
|
||||
let i = 1;
|
||||
let aGroup: GfxModel | undefined = nToLast(aGroups, i);
|
||||
let bGroup: GfxModel | undefined = nToLast(bGroups, i);
|
||||
let aGroup: GfxModel | undefined = aGroups.at(-i);
|
||||
let bGroup: GfxModel | undefined = bGroups.at(-i);
|
||||
|
||||
while (aGroup === bGroup && aGroup) {
|
||||
++i;
|
||||
aGroup = nToLast(aGroups, i);
|
||||
bGroup = nToLast(bGroups, i);
|
||||
aGroup = aGroups.at(-i);
|
||||
bGroup = bGroups.at(-i);
|
||||
}
|
||||
|
||||
aGroup = aGroup ?? a;
|
||||
|
||||
@@ -56,7 +56,7 @@ import {
|
||||
normalizeDegAngle,
|
||||
} from '@blocksuite/global/gfx';
|
||||
import type { Disposable } from '@blocksuite/global/utils';
|
||||
import { assertType, pickValues, Slot } from '@blocksuite/global/utils';
|
||||
import { assertType, Slot } from '@blocksuite/global/utils';
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
@@ -1310,13 +1310,17 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
|
||||
gfx.viewport.viewportUpdated.on(this._updateOnViewportChange)
|
||||
);
|
||||
|
||||
pickValues(gfx.surface!, [
|
||||
'elementAdded',
|
||||
'elementRemoved',
|
||||
'elementUpdated',
|
||||
]).forEach(slot => {
|
||||
_disposables.add(slot.on(this._updateOnElementChange));
|
||||
});
|
||||
if (gfx.surface) {
|
||||
_disposables.add(
|
||||
gfx.surface.elementAdded.on(this._updateOnElementChange)
|
||||
);
|
||||
_disposables.add(
|
||||
gfx.surface.elementRemoved.on(this._updateOnElementChange)
|
||||
);
|
||||
_disposables.add(
|
||||
gfx.surface.elementUpdated.on(this._updateOnElementChange)
|
||||
);
|
||||
}
|
||||
|
||||
_disposables.add(
|
||||
this.doc.slots.blockUpdated.on(this._updateOnElementChange)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { keys } from '@blocksuite/global/utils';
|
||||
|
||||
import type {
|
||||
Template,
|
||||
TemplateCategory,
|
||||
@@ -40,7 +38,7 @@ const flat = <T>(arr: T[][]) =>
|
||||
}, []);
|
||||
|
||||
export const builtInTemplates = {
|
||||
list: async (category: string) => {
|
||||
list: async (category: string): Promise<Template[]> => {
|
||||
const extendTemplates = flat(
|
||||
await Promise.all(extendTemplate.map(manager => manager.list(category)))
|
||||
);
|
||||
@@ -52,15 +50,12 @@ export const builtInTemplates = {
|
||||
const result: Template[] =
|
||||
cate.templates instanceof Function
|
||||
? await cate.templates()
|
||||
: await Promise.all(
|
||||
// @ts-expect-error FIXME: ts error
|
||||
keys(cate.templates).map(key => cate.templates[key]())
|
||||
);
|
||||
: await Promise.all(Object.values(cate.templates));
|
||||
|
||||
return result.concat(extendTemplates);
|
||||
},
|
||||
|
||||
categories: async () => {
|
||||
categories: async (): Promise<string[]> => {
|
||||
const extendCates = flat(
|
||||
await Promise.all(extendTemplate.map(manager => manager.categories()))
|
||||
);
|
||||
@@ -69,7 +64,7 @@ export const builtInTemplates = {
|
||||
return templates.map(cate => cate.name).concat(extendCates);
|
||||
},
|
||||
|
||||
search: async (keyword: string, cateName?: string) => {
|
||||
search: async (keyword: string, cateName?: string): Promise<Template[]> => {
|
||||
const candidates: Template[] = flat(
|
||||
await Promise.all(
|
||||
extendTemplate.map(manager => manager.search(keyword, cateName))
|
||||
@@ -86,18 +81,15 @@ export const builtInTemplates = {
|
||||
}
|
||||
|
||||
if (categroy.templates instanceof Function) {
|
||||
return;
|
||||
return categroy.templates();
|
||||
}
|
||||
|
||||
return Promise.all(
|
||||
keys(categroy.templates).map(async name => {
|
||||
Object.entries(categroy.templates).map(async ([name, template]) => {
|
||||
if (
|
||||
lcs(keyword, (name as string).toLocaleLowerCase()) ===
|
||||
keyword.length
|
||||
) {
|
||||
// @ts-expect-error FIXME: ts error
|
||||
const template = await categroy.templates[name]();
|
||||
|
||||
candidates.push(template);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { PointerEventState } from '@blocksuite/block-std';
|
||||
import type { GfxElementModelView } from '@blocksuite/block-std/gfx';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { last } from '@blocksuite/global/utils';
|
||||
import last from 'lodash-es/last';
|
||||
|
||||
import { DefaultModeDragType, DefaultToolExt } from './ext.js';
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
type MindmapRoot,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { last } from '@blocksuite/global/utils';
|
||||
import last from 'lodash-es/last';
|
||||
|
||||
const isOnEdge = (node: MindmapNode, direction: 'tail' | 'head') => {
|
||||
let current = node;
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
toRadian,
|
||||
Vec,
|
||||
} from '@blocksuite/global/gfx';
|
||||
import { last } from '@blocksuite/global/utils';
|
||||
import last from 'lodash-es/last';
|
||||
|
||||
export class MindMapIndicatorOverlay extends Overlay {
|
||||
static INDICATOR_SIZE = [48, 22];
|
||||
|
||||
@@ -43,9 +43,10 @@ import {
|
||||
} from '@blocksuite/block-std/gfx';
|
||||
import type { IVec } from '@blocksuite/global/gfx';
|
||||
import { Bound, getCommonBoundWithRotation, Vec } from '@blocksuite/global/gfx';
|
||||
import { DisposableGroup, last, noop } from '@blocksuite/global/utils';
|
||||
import { DisposableGroup, noop } from '@blocksuite/global/utils';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import clamp from 'lodash-es/clamp';
|
||||
import last from 'lodash-es/last';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
||||
import { prepareCloneData } from '../utils/clone-utils.js';
|
||||
|
||||
@@ -19,8 +19,8 @@ import {
|
||||
type SerializedElement,
|
||||
} from '@blocksuite/block-std/gfx';
|
||||
import { getCommonBoundWithRotation } from '@blocksuite/global/gfx';
|
||||
import { groupBy } from '@blocksuite/global/utils';
|
||||
import { type BlockSnapshot, BlockSnapshotSchema } from '@blocksuite/store';
|
||||
import groupBy from 'lodash-es/groupBy';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
||||
import { getSortedCloneElements, prepareCloneData } from './clone-utils.js';
|
||||
|
||||
@@ -19,10 +19,12 @@ import {
|
||||
} from '@blocksuite/affine-model';
|
||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { html, LitElement, nothing } from 'lit';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
import countBy from 'lodash-es/countBy';
|
||||
import maxBy from 'lodash-es/maxBy';
|
||||
|
||||
import type { LineWidthEvent } from '../../edgeless/components/panel/line-width-panel.js';
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
} from '@blocksuite/affine-model';
|
||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import {
|
||||
AddTextIcon,
|
||||
ConnectorCIcon,
|
||||
@@ -51,6 +51,8 @@ import { join } from 'lit/directives/join.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
import countBy from 'lodash-es/countBy';
|
||||
import maxBy from 'lodash-es/maxBy';
|
||||
|
||||
import {
|
||||
type LineStyleEvent,
|
||||
|
||||
@@ -23,12 +23,14 @@ import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||
import { matchModels } from '@blocksuite/affine-shared/utils';
|
||||
import { GfxExtensionIdentifier } from '@blocksuite/block-std/gfx';
|
||||
import { deserializeXYWH, serializeXYWH } from '@blocksuite/global/gfx';
|
||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { EditIcon, PageIcon, UngroupIcon } from '@blocksuite/icons/lit';
|
||||
import { html, LitElement, nothing } from 'lit';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import { join } from 'lit/directives/join.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
import countBy from 'lodash-es/countBy';
|
||||
import maxBy from 'lodash-es/maxBy';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||
import { mountFrameTitleEditor } from '../../edgeless/utils/text.js';
|
||||
|
||||
@@ -11,12 +11,14 @@ import type {
|
||||
} from '@blocksuite/affine-model';
|
||||
import { LayoutType, MindmapStyle } from '@blocksuite/affine-model';
|
||||
import { EditPropsStore } from '@blocksuite/affine-shared/services';
|
||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { RadiantIcon, RightLayoutIcon, StyleIcon } from '@blocksuite/icons/lit';
|
||||
import { css, html, LitElement, nothing, type TemplateResult } from 'lit';
|
||||
import { property, state } from 'lit/decorators.js';
|
||||
import { join } from 'lit/directives/join.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
import countBy from 'lodash-es/countBy';
|
||||
import maxBy from 'lodash-es/maxBy';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||
import { SmallArrowDownIcon } from './icons.js';
|
||||
|
||||
@@ -31,7 +31,7 @@ import {
|
||||
ThemeProvider,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import {
|
||||
AutoHeightIcon,
|
||||
CornerIcon,
|
||||
@@ -46,6 +46,8 @@ import { property, query } from 'lit/decorators.js';
|
||||
import { join } from 'lit/directives/join.js';
|
||||
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
import countBy from 'lodash-es/countBy';
|
||||
import maxBy from 'lodash-es/maxBy';
|
||||
|
||||
import {
|
||||
type LineStyleEvent,
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
} from '@blocksuite/affine-model';
|
||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import {
|
||||
AddTextIcon,
|
||||
ShapeIcon,
|
||||
@@ -43,7 +43,9 @@ import { choose } from 'lit/directives/choose.js';
|
||||
import { join } from 'lit/directives/join.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import countBy from 'lodash-es/countBy';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import maxBy from 'lodash-es/maxBy';
|
||||
|
||||
import {
|
||||
type LineStyleEvent,
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import {
|
||||
TextAlignCenterIcon,
|
||||
TextAlignLeftIcon,
|
||||
@@ -43,6 +43,8 @@ import { property, query } from 'lit/decorators.js';
|
||||
import { choose } from 'lit/directives/choose.js';
|
||||
import { join } from 'lit/directives/join.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
import countBy from 'lodash-es/countBy';
|
||||
import maxBy from 'lodash-es/maxBy';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||
import { SmallArrowDownIcon } from './icons.js';
|
||||
|
||||
@@ -31,11 +31,11 @@ import { requestConnectedFrame } from '@blocksuite/affine-shared/utils';
|
||||
import { WidgetComponent } from '@blocksuite/block-std';
|
||||
import type { GfxModel } from '@blocksuite/block-std/gfx';
|
||||
import { clamp, getCommonBoundWithRotation } from '@blocksuite/global/gfx';
|
||||
import { atLeastNMatches, groupBy, pickValues } from '@blocksuite/global/utils';
|
||||
import { ConnectorCIcon } from '@blocksuite/icons/lit';
|
||||
import { css, html, nothing, type TemplateResult, unsafeCSS } from 'lit';
|
||||
import { property, state } from 'lit/decorators.js';
|
||||
import { join } from 'lit/directives/join.js';
|
||||
import groupBy from 'lodash-es/groupBy';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||
import {
|
||||
@@ -270,11 +270,8 @@ export class EdgelessElementToolbarWidget extends WidgetComponent<
|
||||
edgelessText,
|
||||
mindmap: mindmaps,
|
||||
} = groupedSelected;
|
||||
const selectedAtLeastTwoTypes = atLeastNMatches(
|
||||
Object.values(groupedSelected),
|
||||
e => !!e.length,
|
||||
2
|
||||
);
|
||||
const selectedAtLeastTwoTypes =
|
||||
Object.values(groupedSelected).filter(e => !!e.length).length >= 2;
|
||||
|
||||
const quickConnectButton =
|
||||
selectedElements.length === 1 && !connector?.length
|
||||
@@ -385,10 +382,16 @@ export class EdgelessElementToolbarWidget extends WidgetComponent<
|
||||
})
|
||||
);
|
||||
|
||||
pickValues(this.edgeless.service.surface, [
|
||||
'elementAdded',
|
||||
'elementUpdated',
|
||||
]).forEach(slot => _disposables.add(slot.on(this._updateOnSelectedChange)));
|
||||
_disposables.add(
|
||||
this.edgeless.service.surface.elementAdded.on(
|
||||
this._updateOnSelectedChange
|
||||
)
|
||||
);
|
||||
_disposables.add(
|
||||
this.edgeless.service.surface.elementUpdated.on(
|
||||
this._updateOnSelectedChange
|
||||
)
|
||||
);
|
||||
|
||||
_disposables.add(
|
||||
this.doc.slots.blockUpdated.on(this._updateOnSelectedChange)
|
||||
|
||||
@@ -25,15 +25,13 @@
|
||||
"@lit/context": "^1.1.2",
|
||||
"@preact/signals-core": "^1.8.0",
|
||||
"@toeverything/theme": "^1.1.12",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"fractional-indexing": "^3.2.0",
|
||||
"lit": "^3.2.0",
|
||||
"lodash.chunk": "^4.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nanoid": "^5.0.7",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash.chunk": "^4.2.9"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./effects": "./src/effects.ts"
|
||||
|
||||
@@ -23,17 +23,17 @@
|
||||
"@lit/context": "^1.1.2",
|
||||
"@preact/signals-core": "^1.8.0",
|
||||
"@toeverything/theme": "^1.1.12",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"fractional-indexing": "^3.2.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"lit": "^3.2.0",
|
||||
"lodash.chunk": "^4.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nanoid": "^5.0.7",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"yjs": "^13.6.21",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash.chunk": "^4.2.9",
|
||||
"vitest": "3.0.7"
|
||||
},
|
||||
"exports": {
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
type GfxModel,
|
||||
} from '@blocksuite/block-std/gfx';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import chunk from 'lodash.chunk';
|
||||
import chunk from 'lodash-es/chunk';
|
||||
|
||||
const ALIGN_HEIGHT = 200;
|
||||
const ALIGN_PADDING = 20;
|
||||
|
||||
@@ -32,8 +32,9 @@ import {
|
||||
toRadian,
|
||||
Vec,
|
||||
} from '@blocksuite/global/gfx';
|
||||
import { assertType, last } from '@blocksuite/global/utils';
|
||||
import { assertType } from '@blocksuite/global/utils';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import last from 'lodash-es/last';
|
||||
|
||||
import { Overlay } from '../renderer/overlay.js';
|
||||
import { AStarRunner } from '../utils/a-star.js';
|
||||
@@ -602,7 +603,7 @@ function mergePath(points: IVec[] | IVec3[]) {
|
||||
continue;
|
||||
result.push([cur[0], cur[1]]);
|
||||
}
|
||||
result.push(last(points) as IVec);
|
||||
result.push(last(points as IVec[]) as IVec);
|
||||
for (let i = 0; i < result.length - 1; i++) {
|
||||
const cur = result[i];
|
||||
const next = result[i + 1];
|
||||
|
||||
@@ -8,7 +8,8 @@ import type {
|
||||
} from '@blocksuite/block-std/gfx';
|
||||
import type { IBound } from '@blocksuite/global/gfx';
|
||||
import { getBoundWithRotation, intersects } from '@blocksuite/global/gfx';
|
||||
import { DisposableGroup, last, Slot } from '@blocksuite/global/utils';
|
||||
import { DisposableGroup, Slot } from '@blocksuite/global/utils';
|
||||
import last from 'lodash-es/last';
|
||||
|
||||
import type { SurfaceElementModel } from '../element-model/base.js';
|
||||
import { RoughCanvas } from '../utils/rough/canvas.js';
|
||||
|
||||
@@ -14,7 +14,9 @@ import {
|
||||
type SurfaceBlockModel,
|
||||
} from '@blocksuite/block-std/gfx';
|
||||
import type { IVec } from '@blocksuite/global/gfx';
|
||||
import { assertType, isEqual, last } from '@blocksuite/global/utils';
|
||||
import { assertType } from '@blocksuite/global/utils';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import last from 'lodash-es/last';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { fitContent } from '../../renderer/elements/shape/utils.js';
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
"@lit/context": "^1.1.2",
|
||||
"@preact/signals-core": "^1.8.0",
|
||||
"@toeverything/theme": "^1.1.12",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"date-fns": "^4.0.0",
|
||||
"lit": "^3.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"yjs": "^13.6.21",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ShadowlessElement } from '@blocksuite/block-std';
|
||||
import { isEqual } from '@blocksuite/global/utils';
|
||||
import { type Text } from '@blocksuite/store';
|
||||
import { css, html } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
import { createRef, ref } from 'lit/directives/ref.js';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { t } from '../../../../core/index.js';
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
"@blocksuite/inline": "workspace:*",
|
||||
"@blocksuite/store": "workspace:*",
|
||||
"@toeverything/theme": "^1.1.12",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"fractional-indexing": "^3.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"yjs": "^13.6.21",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
} from '@blocksuite/block-std/gfx';
|
||||
import type { IVec, PointLocation } from '@blocksuite/global/gfx';
|
||||
import { Bound, linePolygonIntersects } from '@blocksuite/global/gfx';
|
||||
import { keys } from '@blocksuite/global/utils';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
type GroupElementProps = BaseElementProps & {
|
||||
@@ -44,7 +43,7 @@ export class GroupElementModel extends GfxGroupLikeElementModel<GroupElementProp
|
||||
if (props.children && !(props.children instanceof Y.Map)) {
|
||||
const children = new Y.Map() as Y.Map<boolean>;
|
||||
|
||||
keys(props.children).forEach(key => {
|
||||
Object.keys(props.children).forEach(key => {
|
||||
children.set(key as string, true);
|
||||
});
|
||||
|
||||
|
||||
@@ -14,8 +14,10 @@ import {
|
||||
} from '@blocksuite/block-std/gfx';
|
||||
import type { Bound, SerializedXYWH, XYWH } from '@blocksuite/global/gfx';
|
||||
import { deserializeXYWH } from '@blocksuite/global/gfx';
|
||||
import { assertType, keys, last, noop, pick } from '@blocksuite/global/utils';
|
||||
import { assertType, noop } from '@blocksuite/global/utils';
|
||||
import { generateKeyBetween } from 'fractional-indexing';
|
||||
import last from 'lodash-es/last';
|
||||
import pick from 'lodash-es/pick';
|
||||
import * as Y from 'yjs';
|
||||
import { z } from 'zod';
|
||||
|
||||
@@ -182,11 +184,11 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
|
||||
) {
|
||||
const children: Y.Map<NodeDetail> = new Y.Map();
|
||||
|
||||
keys(props.children).forEach(key => {
|
||||
const detail = pick<Record<string, unknown>, keyof NodeDetail>(
|
||||
props.children![key],
|
||||
['index', 'parent']
|
||||
);
|
||||
Object.entries(props.children).forEach(([key, value]) => {
|
||||
const detail = pick<Record<string, unknown>, keyof NodeDetail>(value, [
|
||||
'index',
|
||||
'parent',
|
||||
]);
|
||||
children.set(key as string, detail as NodeDetail);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { isEqual, last } from '@blocksuite/global/utils';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import last from 'lodash-es/last';
|
||||
|
||||
import { ConnectorMode } from '../../consts/connector.js';
|
||||
import { MindmapStyle } from '../../consts/mindmap.js';
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
import {
|
||||
atLeastNMatches,
|
||||
countBy,
|
||||
groupBy,
|
||||
maxBy,
|
||||
} from '@blocksuite/global/utils';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
describe('countBy', () => {
|
||||
it('basic', () => {
|
||||
const items = [
|
||||
{ name: 'a', classroom: 'c1' },
|
||||
{ name: 'b', classroom: 'c2' },
|
||||
{ name: 'a', classroom: 'c2' },
|
||||
];
|
||||
const counted = countBy(items, i => i.name);
|
||||
expect(counted).toEqual({ a: 2, b: 1 });
|
||||
});
|
||||
|
||||
it('empty items', () => {
|
||||
const counted = countBy([], i => i);
|
||||
expect(Object.keys(counted).length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('maxBy', () => {
|
||||
it('basic', () => {
|
||||
const items = [{ n: 1 }, { n: 2 }];
|
||||
const max = maxBy(items, i => i.n);
|
||||
expect(max).toBe(items[1]);
|
||||
});
|
||||
|
||||
it('empty items', () => {
|
||||
expect(maxBy([], i => i)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('atLeastNMatches', () => {
|
||||
it('basic', () => {
|
||||
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
const isEven = (num: number): boolean => num % 2 === 0;
|
||||
const isGreaterThan5 = (num: number): boolean => num > 5;
|
||||
const isNegative = (num: number): boolean => num < 0;
|
||||
|
||||
expect(atLeastNMatches(arr, isEven, 3)).toBe(true);
|
||||
expect(atLeastNMatches(arr, isGreaterThan5, 5)).toBe(false);
|
||||
expect(atLeastNMatches(arr, isNegative, 1)).toBe(false);
|
||||
|
||||
const strArr = ['apple', 'banana', 'orange', 'kiwi', 'mango'];
|
||||
const startsWithA = (str: string): boolean => str[0].toLowerCase() === 'a';
|
||||
const longerThan5 = (str: string): boolean => str.length > 5;
|
||||
|
||||
expect(atLeastNMatches(strArr, startsWithA, 1)).toBe(true);
|
||||
expect(atLeastNMatches(strArr, longerThan5, 3)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('groupBy', () => {
|
||||
it('basic', () => {
|
||||
const students = [
|
||||
{ name: 'Alice', age: 25 },
|
||||
{ name: 'Bob', age: 23 },
|
||||
{ name: 'Cathy', age: 25 },
|
||||
{ name: 'David', age: 23 },
|
||||
];
|
||||
|
||||
const groupedByAge = groupBy(students, student => student.age.toString());
|
||||
const expectedGroupedByAge = {
|
||||
'23': [
|
||||
{ name: 'Bob', age: 23 },
|
||||
{ name: 'David', age: 23 },
|
||||
],
|
||||
'25': [
|
||||
{ name: 'Alice', age: 25 },
|
||||
{ name: 'Cathy', age: 25 },
|
||||
],
|
||||
};
|
||||
expect(groupedByAge).toMatchObject(expectedGroupedByAge);
|
||||
});
|
||||
|
||||
it('empty', () => {
|
||||
const emptyArray: string[] = [];
|
||||
const groupedEmptyArray = groupBy(emptyArray, item => item);
|
||||
expect(Object.keys(groupedEmptyArray).length).toBe(0);
|
||||
});
|
||||
});
|
||||
@@ -2,9 +2,9 @@ import {
|
||||
createIdentifier,
|
||||
type ServiceIdentifier,
|
||||
} from '@blocksuite/global/di';
|
||||
import { isEqual } from '@blocksuite/global/utils';
|
||||
import type { DeltaInsert } from '@blocksuite/inline';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
|
||||
import type { AffineTextAttributes } from '../../types/index.js';
|
||||
import {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ReferenceParams } from '@blocksuite/affine-model';
|
||||
import { isEqual } from '@blocksuite/global/utils';
|
||||
import type { DeltaInsert } from '@blocksuite/inline';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
|
||||
const mergeDeltas = (
|
||||
acc: DeltaInsert[],
|
||||
|
||||
@@ -54,7 +54,7 @@ import {
|
||||
Rect,
|
||||
type SerializedXYWH,
|
||||
} from '@blocksuite/global/gfx';
|
||||
import { assertType, groupBy, last } from '@blocksuite/global/utils';
|
||||
import { assertType } from '@blocksuite/global/utils';
|
||||
import {
|
||||
type BlockModel,
|
||||
type BlockSnapshot,
|
||||
@@ -63,6 +63,8 @@ import {
|
||||
type SliceSnapshot,
|
||||
toDraftModel,
|
||||
} from '@blocksuite/store';
|
||||
import groupBy from 'lodash-es/groupBy';
|
||||
import last from 'lodash-es/last';
|
||||
|
||||
import type { AffineDragHandleWidget } from '../drag-handle.js';
|
||||
import { PreviewHelper } from '../helpers/preview-helper.js';
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
GfxControllerIdentifier,
|
||||
type GfxModel,
|
||||
} from '@blocksuite/block-std/gfx';
|
||||
import { pickValues } from '@blocksuite/global/utils';
|
||||
import { MultiCursorDuotoneIcon } from '@blocksuite/icons/lit';
|
||||
import type { UserInfo } from '@blocksuite/store';
|
||||
import { css, html, nothing } from 'lit';
|
||||
@@ -183,13 +182,17 @@ export class EdgelessRemoteSelectionWidget extends WidgetComponent<RootBlockMode
|
||||
|
||||
const { _disposables, doc } = this;
|
||||
|
||||
pickValues(this.surface!, [
|
||||
'elementAdded',
|
||||
'elementRemoved',
|
||||
'elementUpdated',
|
||||
]).forEach(slot => {
|
||||
_disposables.add(slot.on(this._updateOnElementChange));
|
||||
});
|
||||
if (this.surface) {
|
||||
_disposables.add(
|
||||
this.surface.elementAdded.on(this._updateOnElementChange)
|
||||
);
|
||||
_disposables.add(
|
||||
this.surface.elementRemoved.on(this._updateOnElementChange)
|
||||
);
|
||||
_disposables.add(
|
||||
this.surface.elementUpdated.on(this._updateOnElementChange)
|
||||
);
|
||||
}
|
||||
|
||||
_disposables.add(doc.slots.blockUpdated.on(this._updateOnElementChange));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user