refactor(editor): remove legacy dnd config (#9291)
This commit is contained in:
@@ -8,16 +8,8 @@ import {
|
|||||||
EMBED_CARD_MIN_WIDTH,
|
EMBED_CARD_MIN_WIDTH,
|
||||||
EMBED_CARD_WIDTH,
|
EMBED_CARD_WIDTH,
|
||||||
} from '@blocksuite/affine-shared/consts';
|
} from '@blocksuite/affine-shared/consts';
|
||||||
import {
|
import { DocModeProvider } from '@blocksuite/affine-shared/services';
|
||||||
DocModeProvider,
|
import type { BlockService } from '@blocksuite/block-std';
|
||||||
DragHandleConfigExtension,
|
|
||||||
} from '@blocksuite/affine-shared/services';
|
|
||||||
import {
|
|
||||||
captureEventTarget,
|
|
||||||
convertDragPreviewDocToEdgeless,
|
|
||||||
convertDragPreviewEdgelessToDoc,
|
|
||||||
} from '@blocksuite/affine-shared/utils';
|
|
||||||
import { type BlockService, isGfxBlockComponent } from '@blocksuite/block-std';
|
|
||||||
import type { GfxCompatibleProps } from '@blocksuite/block-std/gfx';
|
import type { GfxCompatibleProps } from '@blocksuite/block-std/gfx';
|
||||||
import type { BlockModel } from '@blocksuite/store';
|
import type { BlockModel } from '@blocksuite/store';
|
||||||
import type { TemplateResult } from 'lit';
|
import type { TemplateResult } from 'lit';
|
||||||
@@ -26,48 +18,6 @@ import { query } from 'lit/decorators.js';
|
|||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
import { type StyleInfo, styleMap } from 'lit/directives/style-map.js';
|
import { type StyleInfo, styleMap } from 'lit/directives/style-map.js';
|
||||||
|
|
||||||
export const EmbedDragHandleOption = DragHandleConfigExtension({
|
|
||||||
flavour: /affine:embed-*/,
|
|
||||||
edgeless: true,
|
|
||||||
onDragEnd: props => {
|
|
||||||
const { state, draggingElements } = props;
|
|
||||||
if (
|
|
||||||
draggingElements.length !== 1 ||
|
|
||||||
draggingElements[0].model.flavour.match(/affine:embed-*/) === null
|
|
||||||
)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const blockComponent = draggingElements[0] as EmbedBlockComponent;
|
|
||||||
const isInSurface = isGfxBlockComponent(blockComponent);
|
|
||||||
const target = captureEventTarget(state.raw.target);
|
|
||||||
const isTargetEdgelessContainer =
|
|
||||||
target?.classList.contains('edgeless-container');
|
|
||||||
|
|
||||||
if (isInSurface) {
|
|
||||||
const style = blockComponent._cardStyle;
|
|
||||||
const targetStyle =
|
|
||||||
style === 'vertical' || style === 'cube' ? 'horizontal' : style;
|
|
||||||
return convertDragPreviewEdgelessToDoc({
|
|
||||||
blockComponent,
|
|
||||||
style: targetStyle,
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
} else if (isTargetEdgelessContainer) {
|
|
||||||
const style = blockComponent._cardStyle;
|
|
||||||
|
|
||||||
return convertDragPreviewDocToEdgeless({
|
|
||||||
blockComponent,
|
|
||||||
cssSelector: '.embed-block-container',
|
|
||||||
width: EMBED_CARD_WIDTH[style],
|
|
||||||
height: EMBED_CARD_HEIGHT[style],
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export class EmbedBlockComponent<
|
export class EmbedBlockComponent<
|
||||||
Model extends BlockModel<GfxCompatibleProps> = BlockModel<GfxCompatibleProps>,
|
Model extends BlockModel<GfxCompatibleProps> = BlockModel<GfxCompatibleProps>,
|
||||||
Service extends BlockService = BlockService,
|
Service extends BlockService = BlockService,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { ExtensionType } from '@blocksuite/block-std';
|
import type { ExtensionType } from '@blocksuite/block-std';
|
||||||
|
|
||||||
import { EmbedDragHandleOption } from './common/embed-block-element.js';
|
|
||||||
import { EmbedFigmaBlockSpec } from './embed-figma-block/index.js';
|
import { EmbedFigmaBlockSpec } from './embed-figma-block/index.js';
|
||||||
import { EmbedGithubBlockSpec } from './embed-github-block/index.js';
|
import { EmbedGithubBlockSpec } from './embed-github-block/index.js';
|
||||||
import { EmbedHtmlBlockSpec } from './embed-html-block/index.js';
|
import { EmbedHtmlBlockSpec } from './embed-html-block/index.js';
|
||||||
@@ -10,7 +9,6 @@ import { EmbedSyncedDocBlockSpec } from './embed-synced-doc-block/index.js';
|
|||||||
import { EmbedYoutubeBlockSpec } from './embed-youtube-block/index.js';
|
import { EmbedYoutubeBlockSpec } from './embed-youtube-block/index.js';
|
||||||
|
|
||||||
export const EmbedExtensions: ExtensionType[] = [
|
export const EmbedExtensions: ExtensionType[] = [
|
||||||
EmbedDragHandleOption,
|
|
||||||
EmbedFigmaBlockSpec,
|
EmbedFigmaBlockSpec,
|
||||||
EmbedGithubBlockSpec,
|
EmbedGithubBlockSpec,
|
||||||
EmbedHtmlBlockSpec,
|
EmbedHtmlBlockSpec,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './adapters/index.js';
|
export * from './adapters/index.js';
|
||||||
|
export { correctNumberedListsOrderToPrev } from './commands/utils';
|
||||||
export * from './list-block.js';
|
export * from './list-block.js';
|
||||||
export * from './list-service.js';
|
export * from './list-service.js';
|
||||||
export * from './list-spec.js';
|
export * from './list-spec.js';
|
||||||
|
|||||||
@@ -1,33 +1,6 @@
|
|||||||
import { ListBlockSchema } from '@blocksuite/affine-model';
|
import { ListBlockSchema } from '@blocksuite/affine-model';
|
||||||
import { DragHandleConfigExtension } from '@blocksuite/affine-shared/services';
|
|
||||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
|
||||||
import type { BlockComponent } from '@blocksuite/block-std';
|
|
||||||
import { BlockService } from '@blocksuite/block-std';
|
import { BlockService } from '@blocksuite/block-std';
|
||||||
|
|
||||||
import { correctNumberedListsOrderToPrev } from './commands/utils.js';
|
|
||||||
|
|
||||||
export class ListBlockService extends BlockService {
|
export class ListBlockService extends BlockService {
|
||||||
static override readonly flavour = ListBlockSchema.model.flavour;
|
static override readonly flavour = ListBlockSchema.model.flavour;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ListDragHandleOption = DragHandleConfigExtension({
|
|
||||||
flavour: ListBlockSchema.model.flavour,
|
|
||||||
onDragEnd: ({ draggingElements, editorHost }) => {
|
|
||||||
draggingElements.forEach((el: BlockComponent) => {
|
|
||||||
const model = el.model;
|
|
||||||
const doc = el.doc;
|
|
||||||
if (matchFlavours(model, ['affine:list']) && model.type === 'numbered') {
|
|
||||||
const next = el.doc.getNext(model);
|
|
||||||
editorHost.updateComplete
|
|
||||||
.then(() => {
|
|
||||||
correctNumberedListsOrderToPrev(doc, model);
|
|
||||||
if (next) {
|
|
||||||
correctNumberedListsOrderToPrev(doc, next);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(console.error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { literal } from 'lit/static-html.js';
|
|||||||
import { ListBlockAdapterExtensions } from './adapters/extension.js';
|
import { ListBlockAdapterExtensions } from './adapters/extension.js';
|
||||||
import { commands } from './commands/index.js';
|
import { commands } from './commands/index.js';
|
||||||
import { ListKeymapExtension, ListTextKeymapExtension } from './list-keymap.js';
|
import { ListKeymapExtension, ListTextKeymapExtension } from './list-keymap.js';
|
||||||
import { ListBlockService, ListDragHandleOption } from './list-service.js';
|
import { ListBlockService } from './list-service.js';
|
||||||
|
|
||||||
export const ListBlockSpec: ExtensionType[] = [
|
export const ListBlockSpec: ExtensionType[] = [
|
||||||
FlavourExtension('affine:list'),
|
FlavourExtension('affine:list'),
|
||||||
@@ -18,6 +18,5 @@ export const ListBlockSpec: ExtensionType[] = [
|
|||||||
BlockViewExtension('affine:list', literal`affine-list`),
|
BlockViewExtension('affine:list', literal`affine-list`),
|
||||||
ListKeymapExtension,
|
ListKeymapExtension,
|
||||||
ListTextKeymapExtension,
|
ListTextKeymapExtension,
|
||||||
ListDragHandleOption,
|
|
||||||
ListBlockAdapterExtensions,
|
ListBlockAdapterExtensions,
|
||||||
].flat();
|
].flat();
|
||||||
|
|||||||
@@ -1,23 +1,14 @@
|
|||||||
import { FileDropConfigExtension } from '@blocksuite/affine-components/drag-indicator';
|
import { FileDropConfigExtension } from '@blocksuite/affine-components/drag-indicator';
|
||||||
import { AttachmentBlockSchema } from '@blocksuite/affine-model';
|
import { AttachmentBlockSchema } from '@blocksuite/affine-model';
|
||||||
|
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
DragHandleConfigExtension,
|
|
||||||
TelemetryProvider,
|
|
||||||
} from '@blocksuite/affine-shared/services';
|
|
||||||
import {
|
|
||||||
captureEventTarget,
|
|
||||||
convertDragPreviewDocToEdgeless,
|
|
||||||
convertDragPreviewEdgelessToDoc,
|
|
||||||
isInsideEdgelessEditor,
|
isInsideEdgelessEditor,
|
||||||
matchFlavours,
|
matchFlavours,
|
||||||
} from '@blocksuite/affine-shared/utils';
|
} from '@blocksuite/affine-shared/utils';
|
||||||
import { BlockService } from '@blocksuite/block-std';
|
import { BlockService } from '@blocksuite/block-std';
|
||||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||||
|
|
||||||
import { EMBED_CARD_HEIGHT, EMBED_CARD_WIDTH } from '../_common/consts.js';
|
|
||||||
import { addAttachments } from '../root-block/edgeless/utils/common.js';
|
import { addAttachments } from '../root-block/edgeless/utils/common.js';
|
||||||
import type { AttachmentBlockComponent } from './attachment-block.js';
|
|
||||||
import { AttachmentEdgelessBlockComponent } from './attachment-edgeless-block.js';
|
|
||||||
import { addSiblingAttachmentBlocks } from './utils.js';
|
import { addSiblingAttachmentBlocks } from './utils.js';
|
||||||
|
|
||||||
// bytes.parse('2GB')
|
// bytes.parse('2GB')
|
||||||
@@ -71,57 +62,3 @@ export const AttachmentDropOption = FileDropConfigExtension({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AttachmentDragHandleOption = DragHandleConfigExtension({
|
|
||||||
flavour: AttachmentBlockSchema.model.flavour,
|
|
||||||
edgeless: true,
|
|
||||||
onDragEnd: props => {
|
|
||||||
const { state, draggingElements, editorHost } = props;
|
|
||||||
if (
|
|
||||||
draggingElements.length !== 1 ||
|
|
||||||
!matchFlavours(draggingElements[0].model, [
|
|
||||||
AttachmentBlockSchema.model.flavour,
|
|
||||||
])
|
|
||||||
)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const blockComponent = draggingElements[0] as
|
|
||||||
| AttachmentBlockComponent
|
|
||||||
| AttachmentEdgelessBlockComponent;
|
|
||||||
const isInSurface =
|
|
||||||
blockComponent instanceof AttachmentEdgelessBlockComponent;
|
|
||||||
const target = captureEventTarget(state.raw.target);
|
|
||||||
const isTargetEdgelessContainer =
|
|
||||||
target?.classList.contains('edgeless-container');
|
|
||||||
|
|
||||||
if (isInSurface) {
|
|
||||||
const style = blockComponent.model.style;
|
|
||||||
const targetStyle = style === 'cubeThick' ? 'horizontalThin' : style;
|
|
||||||
return convertDragPreviewEdgelessToDoc({
|
|
||||||
blockComponent,
|
|
||||||
style: targetStyle,
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
} else if (isTargetEdgelessContainer) {
|
|
||||||
let style = blockComponent.model.style ?? 'cubeThick';
|
|
||||||
const embed = blockComponent.model.embed;
|
|
||||||
if (embed) {
|
|
||||||
style = 'cubeThick';
|
|
||||||
editorHost.doc.updateBlock(blockComponent.model, {
|
|
||||||
style,
|
|
||||||
embed: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return convertDragPreviewDocToEdgeless({
|
|
||||||
blockComponent,
|
|
||||||
cssSelector: '.affine-attachment-container',
|
|
||||||
width: EMBED_CARD_WIDTH[style],
|
|
||||||
height: EMBED_CARD_HEIGHT[style],
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { literal } from 'lit/static-html.js';
|
|||||||
import { AttachmentBlockNotionHtmlAdapterExtension } from './adapters/notion-html.js';
|
import { AttachmentBlockNotionHtmlAdapterExtension } from './adapters/notion-html.js';
|
||||||
import {
|
import {
|
||||||
AttachmentBlockService,
|
AttachmentBlockService,
|
||||||
AttachmentDragHandleOption,
|
|
||||||
AttachmentDropOption,
|
AttachmentDropOption,
|
||||||
} from './attachment-service.js';
|
} from './attachment-service.js';
|
||||||
import {
|
import {
|
||||||
@@ -25,7 +24,6 @@ export const AttachmentBlockSpec: ExtensionType[] = [
|
|||||||
: literal`affine-attachment`;
|
: literal`affine-attachment`;
|
||||||
}),
|
}),
|
||||||
AttachmentDropOption,
|
AttachmentDropOption,
|
||||||
AttachmentDragHandleOption,
|
|
||||||
AttachmentEmbedConfigExtension(),
|
AttachmentEmbedConfigExtension(),
|
||||||
AttachmentEmbedService,
|
AttachmentEmbedService,
|
||||||
AttachmentBlockNotionHtmlAdapterExtension,
|
AttachmentBlockNotionHtmlAdapterExtension,
|
||||||
|
|||||||
@@ -1,21 +1,7 @@
|
|||||||
import { LinkPreviewer } from '@blocksuite/affine-block-embed';
|
import { LinkPreviewer } from '@blocksuite/affine-block-embed';
|
||||||
import { BookmarkBlockSchema } from '@blocksuite/affine-model';
|
import { BookmarkBlockSchema } from '@blocksuite/affine-model';
|
||||||
import {
|
|
||||||
EMBED_CARD_HEIGHT,
|
|
||||||
EMBED_CARD_WIDTH,
|
|
||||||
} from '@blocksuite/affine-shared/consts';
|
|
||||||
import { DragHandleConfigExtension } from '@blocksuite/affine-shared/services';
|
|
||||||
import {
|
|
||||||
captureEventTarget,
|
|
||||||
convertDragPreviewDocToEdgeless,
|
|
||||||
convertDragPreviewEdgelessToDoc,
|
|
||||||
matchFlavours,
|
|
||||||
} from '@blocksuite/affine-shared/utils';
|
|
||||||
import { BlockService } from '@blocksuite/block-std';
|
import { BlockService } from '@blocksuite/block-std';
|
||||||
|
|
||||||
import type { BookmarkBlockComponent } from './bookmark-block.js';
|
|
||||||
import { BookmarkEdgelessBlockComponent } from './bookmark-edgeless-block.js';
|
|
||||||
|
|
||||||
export class BookmarkBlockService extends BlockService {
|
export class BookmarkBlockService extends BlockService {
|
||||||
static override readonly flavour = BookmarkBlockSchema.model.flavour;
|
static override readonly flavour = BookmarkBlockSchema.model.flavour;
|
||||||
|
|
||||||
@@ -28,50 +14,3 @@ export class BookmarkBlockService extends BlockService {
|
|||||||
return BookmarkBlockService.linkPreviewer.query(url, signal);
|
return BookmarkBlockService.linkPreviewer.query(url, signal);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BookmarkDragHandleOption = DragHandleConfigExtension({
|
|
||||||
flavour: BookmarkBlockSchema.model.flavour,
|
|
||||||
edgeless: true,
|
|
||||||
onDragEnd: props => {
|
|
||||||
const { state, draggingElements } = props;
|
|
||||||
if (
|
|
||||||
draggingElements.length !== 1 ||
|
|
||||||
!matchFlavours(draggingElements[0].model, [
|
|
||||||
BookmarkBlockSchema.model.flavour,
|
|
||||||
])
|
|
||||||
)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const blockComponent = draggingElements[0] as
|
|
||||||
| BookmarkBlockComponent
|
|
||||||
| BookmarkEdgelessBlockComponent;
|
|
||||||
const isInSurface =
|
|
||||||
blockComponent instanceof BookmarkEdgelessBlockComponent;
|
|
||||||
const target = captureEventTarget(state.raw.target);
|
|
||||||
const isTargetEdgelessContainer =
|
|
||||||
target?.classList.contains('edgeless-container');
|
|
||||||
|
|
||||||
if (isInSurface) {
|
|
||||||
const style = blockComponent.model.style;
|
|
||||||
const targetStyle =
|
|
||||||
style === 'vertical' || style === 'cube' ? 'horizontal' : style;
|
|
||||||
return convertDragPreviewEdgelessToDoc({
|
|
||||||
blockComponent,
|
|
||||||
style: targetStyle,
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
} else if (isTargetEdgelessContainer) {
|
|
||||||
const style = blockComponent.model.style;
|
|
||||||
|
|
||||||
return convertDragPreviewDocToEdgeless({
|
|
||||||
blockComponent,
|
|
||||||
cssSelector: 'bookmark-card',
|
|
||||||
width: EMBED_CARD_WIDTH[style],
|
|
||||||
height: EMBED_CARD_HEIGHT[style],
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ import {
|
|||||||
import { literal } from 'lit/static-html.js';
|
import { literal } from 'lit/static-html.js';
|
||||||
|
|
||||||
import { BookmarkBlockAdapterExtensions } from './adapters/extension.js';
|
import { BookmarkBlockAdapterExtensions } from './adapters/extension.js';
|
||||||
import {
|
import { BookmarkBlockService } from './bookmark-service.js';
|
||||||
BookmarkBlockService,
|
|
||||||
BookmarkDragHandleOption,
|
|
||||||
} from './bookmark-service.js';
|
|
||||||
import { commands } from './commands/index.js';
|
import { commands } from './commands/index.js';
|
||||||
|
|
||||||
export const BookmarkBlockSpec: ExtensionType[] = [
|
export const BookmarkBlockSpec: ExtensionType[] = [
|
||||||
@@ -22,6 +19,5 @@ export const BookmarkBlockSpec: ExtensionType[] = [
|
|||||||
? literal`affine-edgeless-bookmark`
|
? literal`affine-edgeless-bookmark`
|
||||||
: literal`affine-bookmark`;
|
: literal`affine-bookmark`;
|
||||||
}),
|
}),
|
||||||
BookmarkDragHandleOption,
|
|
||||||
BookmarkBlockAdapterExtensions,
|
BookmarkBlockAdapterExtensions,
|
||||||
].flat();
|
].flat();
|
||||||
|
|||||||
@@ -1,60 +1,6 @@
|
|||||||
import type { MenuOptions } from '@blocksuite/affine-components/context-menu';
|
import type { MenuOptions } from '@blocksuite/affine-components/context-menu';
|
||||||
import {
|
import { type DatabaseBlockModel } from '@blocksuite/affine-model';
|
||||||
type DatabaseBlockModel,
|
|
||||||
DatabaseBlockSchema,
|
|
||||||
} from '@blocksuite/affine-model';
|
|
||||||
import { DragHandleConfigExtension } from '@blocksuite/affine-shared/services';
|
|
||||||
import { captureEventTarget } from '@blocksuite/affine-shared/utils';
|
|
||||||
|
|
||||||
export interface DatabaseOptionsConfig {
|
export interface DatabaseOptionsConfig {
|
||||||
configure: (model: DatabaseBlockModel, options: MenuOptions) => MenuOptions;
|
configure: (model: DatabaseBlockModel, options: MenuOptions) => MenuOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
let canDrop = false;
|
|
||||||
export const DatabaseDragHandleOption = DragHandleConfigExtension({
|
|
||||||
flavour: DatabaseBlockSchema.model.flavour,
|
|
||||||
onDragMove: ({ state }) => {
|
|
||||||
const target = captureEventTarget(state.raw.target);
|
|
||||||
const database = target?.closest('affine-database');
|
|
||||||
if (!database) return false;
|
|
||||||
const view = database.view;
|
|
||||||
if (view && target instanceof HTMLElement && database.contains(target)) {
|
|
||||||
canDrop = view.showIndicator?.(state.raw) ?? false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (canDrop) {
|
|
||||||
view?.hideIndicator?.();
|
|
||||||
canDrop = false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
onDragEnd: ({ state, draggingElements, editorHost }) => {
|
|
||||||
const target = state.raw.target;
|
|
||||||
const targetEl = captureEventTarget(state.raw.target);
|
|
||||||
const database = targetEl?.closest('affine-database');
|
|
||||||
if (!database) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const view = database.view;
|
|
||||||
if (
|
|
||||||
canDrop &&
|
|
||||||
view &&
|
|
||||||
view.moveTo &&
|
|
||||||
target instanceof HTMLElement &&
|
|
||||||
database.parentElement?.contains(target)
|
|
||||||
) {
|
|
||||||
const blocks = draggingElements.map(v => v.model);
|
|
||||||
editorHost.doc.moveBlocks(blocks, database.model);
|
|
||||||
blocks.forEach(model => {
|
|
||||||
view.moveTo?.(model.id, state.raw);
|
|
||||||
});
|
|
||||||
view.hideIndicator?.();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (canDrop) {
|
|
||||||
view?.hideIndicator?.();
|
|
||||||
canDrop = false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { literal } from 'lit/static-html.js';
|
|||||||
|
|
||||||
import { DatabaseBlockAdapterExtensions } from './adapters/extension.js';
|
import { DatabaseBlockAdapterExtensions } from './adapters/extension.js';
|
||||||
import { commands } from './commands.js';
|
import { commands } from './commands.js';
|
||||||
import { DatabaseDragHandleOption } from './config.js';
|
|
||||||
import { DatabaseBlockService } from './database-service.js';
|
import { DatabaseBlockService } from './database-service.js';
|
||||||
|
|
||||||
export const DatabaseBlockSpec: ExtensionType[] = [
|
export const DatabaseBlockSpec: ExtensionType[] = [
|
||||||
@@ -17,7 +16,6 @@ export const DatabaseBlockSpec: ExtensionType[] = [
|
|||||||
DatabaseBlockService,
|
DatabaseBlockService,
|
||||||
CommandExtension(commands),
|
CommandExtension(commands),
|
||||||
BlockViewExtension('affine:database', literal`affine-database`),
|
BlockViewExtension('affine:database', literal`affine-database`),
|
||||||
DatabaseDragHandleOption,
|
|
||||||
DatabaseSelectionExtension,
|
DatabaseSelectionExtension,
|
||||||
DatabaseBlockAdapterExtensions,
|
DatabaseBlockAdapterExtensions,
|
||||||
].flat();
|
].flat();
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
import { FileDropConfigExtension } from '@blocksuite/affine-components/drag-indicator';
|
import { FileDropConfigExtension } from '@blocksuite/affine-components/drag-indicator';
|
||||||
import { ImageBlockSchema, MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
|
import { ImageBlockSchema, MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
|
||||||
|
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
DragHandleConfigExtension,
|
|
||||||
TelemetryProvider,
|
|
||||||
} from '@blocksuite/affine-shared/services';
|
|
||||||
import {
|
|
||||||
captureEventTarget,
|
|
||||||
convertDragPreviewDocToEdgeless,
|
|
||||||
convertDragPreviewEdgelessToDoc,
|
|
||||||
isInsideEdgelessEditor,
|
isInsideEdgelessEditor,
|
||||||
matchFlavours,
|
matchFlavours,
|
||||||
} from '@blocksuite/affine-shared/utils';
|
} from '@blocksuite/affine-shared/utils';
|
||||||
@@ -16,8 +10,6 @@ import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
|||||||
|
|
||||||
import { setImageProxyMiddlewareURL } from '../_common/transformers/middlewares.js';
|
import { setImageProxyMiddlewareURL } from '../_common/transformers/middlewares.js';
|
||||||
import { addImages } from '../root-block/edgeless/utils/common.js';
|
import { addImages } from '../root-block/edgeless/utils/common.js';
|
||||||
import type { ImageBlockComponent } from './image-block.js';
|
|
||||||
import { ImageEdgelessBlockComponent } from './image-edgeless-block.js';
|
|
||||||
import { addSiblingImageBlock } from './utils.js';
|
import { addSiblingImageBlock } from './utils.js';
|
||||||
|
|
||||||
// bytes.parse('2GB')
|
// bytes.parse('2GB')
|
||||||
@@ -69,38 +61,3 @@ export const ImageDropOption = FileDropConfigExtension({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ImageDragHandleOption = DragHandleConfigExtension({
|
|
||||||
flavour: ImageBlockSchema.model.flavour,
|
|
||||||
edgeless: true,
|
|
||||||
onDragEnd: props => {
|
|
||||||
const { state, draggingElements } = props;
|
|
||||||
if (
|
|
||||||
draggingElements.length !== 1 ||
|
|
||||||
!matchFlavours(draggingElements[0].model, [
|
|
||||||
ImageBlockSchema.model.flavour,
|
|
||||||
])
|
|
||||||
)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const blockComponent = draggingElements[0] as ImageBlockComponent;
|
|
||||||
const isInSurface = blockComponent instanceof ImageEdgelessBlockComponent;
|
|
||||||
const target = captureEventTarget(state.raw.target);
|
|
||||||
const isTargetEdgelessContainer =
|
|
||||||
target?.classList.contains('edgeless-container');
|
|
||||||
|
|
||||||
if (isInSurface) {
|
|
||||||
return convertDragPreviewEdgelessToDoc({
|
|
||||||
blockComponent,
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
} else if (isTargetEdgelessContainer) {
|
|
||||||
return convertDragPreviewDocToEdgeless({
|
|
||||||
blockComponent,
|
|
||||||
cssSelector: '.drag-target',
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -10,11 +10,7 @@ import { literal } from 'lit/static-html.js';
|
|||||||
|
|
||||||
import { ImageBlockAdapterExtensions } from './adapters/extension.js';
|
import { ImageBlockAdapterExtensions } from './adapters/extension.js';
|
||||||
import { commands } from './commands/index.js';
|
import { commands } from './commands/index.js';
|
||||||
import {
|
import { ImageBlockService, ImageDropOption } from './image-service.js';
|
||||||
ImageBlockService,
|
|
||||||
ImageDragHandleOption,
|
|
||||||
ImageDropOption,
|
|
||||||
} from './image-service.js';
|
|
||||||
|
|
||||||
export const ImageBlockSpec: ExtensionType[] = [
|
export const ImageBlockSpec: ExtensionType[] = [
|
||||||
FlavourExtension('affine:image'),
|
FlavourExtension('affine:image'),
|
||||||
@@ -32,7 +28,6 @@ export const ImageBlockSpec: ExtensionType[] = [
|
|||||||
WidgetViewMapExtension('affine:image', {
|
WidgetViewMapExtension('affine:image', {
|
||||||
imageToolbar: literal`affine-image-toolbar-widget`,
|
imageToolbar: literal`affine-image-toolbar-widget`,
|
||||||
}),
|
}),
|
||||||
ImageDragHandleOption,
|
|
||||||
ImageDropOption,
|
ImageDropOption,
|
||||||
ImageSelectionExtension,
|
ImageSelectionExtension,
|
||||||
ImageBlockAdapterExtensions,
|
ImageBlockAdapterExtensions,
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import type { NoteBlockModel } from '@blocksuite/affine-model';
|
|
||||||
import { NoteBlockSchema } from '@blocksuite/affine-model';
|
import { NoteBlockSchema } from '@blocksuite/affine-model';
|
||||||
import { DragHandleConfigExtension } from '@blocksuite/affine-shared/services';
|
|
||||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||||
import {
|
import {
|
||||||
type BaseSelection,
|
type BaseSelection,
|
||||||
@@ -15,7 +13,6 @@ import { moveBlockConfigs } from '../_common/configs/move-block.js';
|
|||||||
import { quickActionConfig } from '../_common/configs/quick-action/config.js';
|
import { quickActionConfig } from '../_common/configs/quick-action/config.js';
|
||||||
import { textConversionConfigs } from '../_common/configs/text-conversion.js';
|
import { textConversionConfigs } from '../_common/configs/text-conversion.js';
|
||||||
import { onModelElementUpdated } from '../root-block/utils/callback.js';
|
import { onModelElementUpdated } from '../root-block/utils/callback.js';
|
||||||
import { getDuplicateBlocks } from '../root-block/widgets/drag-handle/utils.js';
|
|
||||||
|
|
||||||
export class NoteBlockService extends BlockService {
|
export class NoteBlockService extends BlockService {
|
||||||
static override readonly flavour = NoteBlockSchema.model.flavour;
|
static override readonly flavour = NoteBlockSchema.model.flavour;
|
||||||
@@ -587,56 +584,3 @@ export class NoteBlockService extends BlockService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const NoteDragHandleOption = DragHandleConfigExtension({
|
|
||||||
flavour: NoteBlockSchema.model.flavour,
|
|
||||||
edgeless: true,
|
|
||||||
onDragEnd: ({
|
|
||||||
draggingElements,
|
|
||||||
dropBlockId,
|
|
||||||
dropType,
|
|
||||||
state,
|
|
||||||
editorHost,
|
|
||||||
}) => {
|
|
||||||
if (
|
|
||||||
draggingElements.length !== 1 ||
|
|
||||||
!matchFlavours(draggingElements[0].model, [NoteBlockSchema.model.flavour])
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dropType === 'in') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const noteBlock = draggingElements[0].model as NoteBlockModel;
|
|
||||||
const targetBlock = editorHost.doc.getBlockById(dropBlockId);
|
|
||||||
const parentBlock = editorHost.doc.getParent(dropBlockId);
|
|
||||||
if (!targetBlock || !parentBlock) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const altKey = state.raw.altKey;
|
|
||||||
if (altKey) {
|
|
||||||
const duplicateBlocks = getDuplicateBlocks(noteBlock.children);
|
|
||||||
|
|
||||||
const parentIndex =
|
|
||||||
parentBlock.children.indexOf(targetBlock) +
|
|
||||||
(dropType === 'after' ? 1 : 0);
|
|
||||||
|
|
||||||
editorHost.doc.addBlocks(duplicateBlocks, parentBlock, parentIndex);
|
|
||||||
} else {
|
|
||||||
editorHost.doc.moveBlocks(
|
|
||||||
noteBlock.children,
|
|
||||||
parentBlock,
|
|
||||||
targetBlock,
|
|
||||||
dropType === 'before'
|
|
||||||
);
|
|
||||||
|
|
||||||
editorHost.doc.deleteBlock(noteBlock);
|
|
||||||
editorHost.selection.setGroup('gfx', []);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
EdgelessNoteBlockAdapterExtensions,
|
EdgelessNoteBlockAdapterExtensions,
|
||||||
} from './adapters/index.js';
|
} from './adapters/index.js';
|
||||||
import { commands } from './commands/index.js';
|
import { commands } from './commands/index.js';
|
||||||
import { NoteBlockService, NoteDragHandleOption } from './note-service.js';
|
import { NoteBlockService } from './note-service.js';
|
||||||
|
|
||||||
export const NoteBlockSpec: ExtensionType[] = [
|
export const NoteBlockSpec: ExtensionType[] = [
|
||||||
FlavourExtension('affine:note'),
|
FlavourExtension('affine:note'),
|
||||||
@@ -26,6 +26,5 @@ export const EdgelessNoteBlockSpec: ExtensionType[] = [
|
|||||||
NoteBlockService,
|
NoteBlockService,
|
||||||
CommandExtension(commands),
|
CommandExtension(commands),
|
||||||
BlockViewExtension('affine:note', literal`affine-edgeless-note`),
|
BlockViewExtension('affine:note', literal`affine-edgeless-note`),
|
||||||
NoteDragHandleOption,
|
|
||||||
EdgelessNoteBlockAdapterExtensions,
|
EdgelessNoteBlockAdapterExtensions,
|
||||||
].flat();
|
].flat();
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { correctNumberedListsOrderToPrev } from '@blocksuite/affine-block-list';
|
||||||
|
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||||
|
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||||
|
import type { JobMiddleware } from '@blocksuite/store';
|
||||||
|
|
||||||
|
export const reorderList =
|
||||||
|
(std: BlockStdScope): JobMiddleware =>
|
||||||
|
({ slots }) => {
|
||||||
|
slots.afterImport.on(payload => {
|
||||||
|
if (payload.type === 'block') {
|
||||||
|
const model = payload.model;
|
||||||
|
if (
|
||||||
|
matchFlavours(model, ['affine:list']) &&
|
||||||
|
model.type === 'numbered'
|
||||||
|
) {
|
||||||
|
const next = std.doc.getNext(model);
|
||||||
|
correctNumberedListsOrderToPrev(std.doc, model);
|
||||||
|
if (next) {
|
||||||
|
correctNumberedListsOrderToPrev(std.doc, next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -34,6 +34,7 @@ import { DropIndicator } from '../components/drop-indicator.js';
|
|||||||
import { AFFINE_DRAG_HANDLE_WIDGET } from '../consts.js';
|
import { AFFINE_DRAG_HANDLE_WIDGET } from '../consts.js';
|
||||||
import type { AffineDragHandleWidget } from '../drag-handle.js';
|
import type { AffineDragHandleWidget } from '../drag-handle.js';
|
||||||
import { newIdCrossDoc } from '../middleware/new-id-cross-doc.js';
|
import { newIdCrossDoc } from '../middleware/new-id-cross-doc.js';
|
||||||
|
import { reorderList } from '../middleware/reorder-list';
|
||||||
import { surfaceRefToEmbed } from '../middleware/surface-ref-to-embed.js';
|
import { surfaceRefToEmbed } from '../middleware/surface-ref-to-embed.js';
|
||||||
import { containBlock, includeTextSelection } from '../utils.js';
|
import { containBlock, includeTextSelection } from '../utils.js';
|
||||||
|
|
||||||
@@ -537,7 +538,11 @@ export class DragEventWatcher {
|
|||||||
const std = this._std;
|
const std = this._std;
|
||||||
return new Job({
|
return new Job({
|
||||||
collection: std.collection,
|
collection: std.collection,
|
||||||
middlewares: [newIdCrossDoc(std), surfaceRefToEmbed(std)],
|
middlewares: [
|
||||||
|
newIdCrossDoc(std),
|
||||||
|
reorderList(std),
|
||||||
|
surfaceRefToEmbed(std),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,10 +109,9 @@ test('move drag handle in nested block', async ({ page }) => {
|
|||||||
await expect(page.locator('.affine-drag-indicator')).toBeHidden();
|
await expect(page.locator('.affine-drag-indicator')).toBeHidden();
|
||||||
await assertRichTexts(page, ['1', '2', '22', '23', '21', '3']);
|
await assertRichTexts(page, ['1', '2', '22', '23', '21', '3']);
|
||||||
|
|
||||||
// FIXME(DND)
|
await dragHandleFromBlockToBlockBottomById(page, '3', '8');
|
||||||
// await dragHandleFromBlockToBlockBottomById(page, '3', '8');
|
await expect(page.locator('.affine-drag-indicator')).toBeHidden();
|
||||||
// await expect(page.locator('.affine-drag-indicator')).toBeHidden();
|
await assertRichTexts(page, ['2', '22', '23', '21', '3', '1']);
|
||||||
// await assertRichTexts(page, ['2', '22', '23', '21', '3', '1']);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('move drag handle into another block', async ({ page }) => {
|
test('move drag handle into another block', async ({ page }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user