mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-10 13:38:49 +08:00
chore: merge blocksuite source code (#9213)
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
import {
|
||||
CaptionedBlockComponent,
|
||||
SelectedStyle,
|
||||
} from '@blocksuite/affine-components/caption';
|
||||
import type { EmbedCardStyle } from '@blocksuite/affine-model';
|
||||
import {
|
||||
EMBED_CARD_HEIGHT,
|
||||
EMBED_CARD_MIN_WIDTH,
|
||||
EMBED_CARD_WIDTH,
|
||||
} from '@blocksuite/affine-shared/consts';
|
||||
import {
|
||||
DocModeProvider,
|
||||
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 { BlockModel } from '@blocksuite/store';
|
||||
import type { TemplateResult } from 'lit';
|
||||
import { html } from 'lit';
|
||||
import { query } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-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<
|
||||
Model extends BlockModel<GfxCompatibleProps> = BlockModel<GfxCompatibleProps>,
|
||||
Service extends BlockService = BlockService,
|
||||
WidgetName extends string = string,
|
||||
> extends CaptionedBlockComponent<Model, Service, WidgetName> {
|
||||
private _fetchAbortController = new AbortController();
|
||||
|
||||
_cardStyle: EmbedCardStyle = 'horizontal';
|
||||
|
||||
/**
|
||||
* The actual rendered scale of the embed card.
|
||||
* By default, it is set to 1.
|
||||
*/
|
||||
protected _scale = 1;
|
||||
|
||||
blockDraggable = true;
|
||||
|
||||
/**
|
||||
* The style of the embed card.
|
||||
* You can use this to change the height and width of the card.
|
||||
* By default, the height and width are set to `_cardHeight` and `_cardWidth` respectively.
|
||||
*/
|
||||
protected embedContainerStyle: StyleInfo = {};
|
||||
|
||||
renderEmbed = (content: () => TemplateResult) => {
|
||||
if (
|
||||
this._cardStyle === 'horizontal' ||
|
||||
this._cardStyle === 'horizontalThin' ||
|
||||
this._cardStyle === 'list'
|
||||
) {
|
||||
this.style.display = 'block';
|
||||
|
||||
const mode = this.std.get(DocModeProvider).getEditorMode();
|
||||
if (mode === 'edgeless') {
|
||||
this.style.minWidth = `${EMBED_CARD_MIN_WIDTH}px`;
|
||||
}
|
||||
}
|
||||
|
||||
const selected = !!this.selected?.is('block');
|
||||
return html`
|
||||
<div
|
||||
draggable="${this.blockDraggable ? 'true' : 'false'}"
|
||||
class=${classMap({
|
||||
'embed-block-container': true,
|
||||
'selected-style': selected,
|
||||
})}
|
||||
style=${styleMap({
|
||||
height: `${this._cardHeight}px`,
|
||||
width: '100%',
|
||||
...this.embedContainerStyle,
|
||||
})}
|
||||
>
|
||||
${content()}
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
|
||||
/**
|
||||
* The height of the current embed card. Changes based on the card style.
|
||||
*/
|
||||
get _cardHeight() {
|
||||
return EMBED_CARD_HEIGHT[this._cardStyle];
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the current embed card. Changes based on the card style.
|
||||
*/
|
||||
get _cardWidth() {
|
||||
return EMBED_CARD_WIDTH[this._cardStyle];
|
||||
}
|
||||
|
||||
get fetchAbortController() {
|
||||
return this._fetchAbortController;
|
||||
}
|
||||
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
if (this._fetchAbortController.signal.aborted)
|
||||
this._fetchAbortController = new AbortController();
|
||||
|
||||
this.contentEditable = 'false';
|
||||
}
|
||||
|
||||
override disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
this._fetchAbortController.abort();
|
||||
}
|
||||
|
||||
protected override accessor blockContainerStyles: StyleInfo | undefined = {
|
||||
margin: '18px 0',
|
||||
};
|
||||
|
||||
@query('.embed-block-container')
|
||||
protected accessor embedBlock!: HTMLDivElement;
|
||||
|
||||
override accessor selectedStyle = SelectedStyle.Border;
|
||||
|
||||
override accessor useCaptionEditor = true;
|
||||
|
||||
override accessor useZeroWidth = true;
|
||||
}
|
||||
Reference in New Issue
Block a user