diff --git a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-error-card.ts b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-error-card.ts
index 8f93938e19..786aa43987 100644
--- a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-error-card.ts
+++ b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-error-card.ts
@@ -11,10 +11,10 @@ import { property, query } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { styleMap } from 'lit/directives/style-map.js';
+import { ERROR_CARD_DEFAULT_HEIGHT } from '../consts';
import type { EmbedIframeStatusCardOptions } from '../types';
const LINK_EDIT_POPUP_OFFSET = 12;
-const ERROR_CARD_DEFAULT_HEIGHT = 114;
export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
static override styles = css`
@@ -24,7 +24,7 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
}
.affine-embed-iframe-error-card {
- container: affine-embed-iframe-error-card / inline-size;
+ container: affine-embed-iframe-error-card / size;
display: flex;
box-sizing: border-box;
user-select: none;
@@ -41,7 +41,6 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
display: flex;
flex-direction: column;
gap: 4px;
- flex: 1 0 0;
.error-title {
display: flex;
@@ -64,6 +63,9 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
font-style: normal;
font-weight: 600;
line-height: 22px; /* 157.143% */
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
}
@@ -119,12 +121,6 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
}
}
}
-
- @container affine-embed-iframe-error-card (width < 480px) {
- .error-banner {
- display: none;
- }
- }
}
.affine-embed-iframe-error-card.horizontal {
@@ -133,12 +129,19 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
.error-content {
align-items: flex-start;
+ flex: 1 0 0;
.error-message {
height: 40px;
align-items: flex-start;
}
}
+
+ @container affine-embed-iframe-error-card (width < 480px) {
+ .error-banner {
+ display: none;
+ }
+ }
}
.affine-embed-iframe-error-card.vertical {
@@ -155,6 +158,18 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
align-items: center;
}
}
+
+ .icon-box {
+ svg {
+ transform: scale(1.6) translateY(-14px);
+ }
+ }
+
+ @container affine-embed-iframe-error-card (height < 300px) or (width < 300px) {
+ .error-banner {
+ display: none;
+ }
+ }
}
`;
@@ -216,10 +231,10 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
-
+
${InformationIcon({ width: '16px', height: '16px' })}
-
-
This link couldn’t be loaded.
+
+
This link couldn’t be loaded.
${this.error?.message || 'Failed to load embedded content'}
@@ -244,8 +259,7 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
-
-
+
${EmbedIframeErrorIcon}
`;
@@ -280,3 +294,25 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
height: ERROR_CARD_DEFAULT_HEIGHT,
};
}
+
+export const EmbedIframeErrorIcon = html``;
diff --git a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-idle-card.ts b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-idle-card.ts
index e80b1f534a..c3ac974c58 100644
--- a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-idle-card.ts
+++ b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-idle-card.ts
@@ -3,16 +3,22 @@ import { WithDisposable } from '@blocksuite/global/lit';
import { EmbedIcon } from '@blocksuite/icons/lit';
import { baseTheme } from '@toeverything/theme';
import { css, html, LitElement, unsafeCSS } from 'lit';
+import { property } from 'lit/decorators.js';
+import { classMap } from 'lit/directives/class-map.js';
+import { styleMap } from 'lit/directives/style-map.js';
+
+import { IDLE_CARD_DEFAULT_HEIGHT } from '../consts';
+import type { EmbedIframeStatusCardOptions } from '../types';
export class EmbedIframeIdleCard extends WithDisposable(LitElement) {
static override styles = css`
:host {
width: 100%;
+ height: 100%;
}
.affine-embed-iframe-idle-card {
- width: 100%;
- height: 48px;
+ container: affine-embed-iframe-idle-card / size;
box-sizing: border-box;
display: flex;
align-items: center;
@@ -23,8 +29,6 @@ export class EmbedIframeIdleCard extends WithDisposable(LitElement) {
.icon {
display: flex;
- width: 24px;
- height: 24px;
justify-content: center;
align-items: center;
color: ${unsafeCSSVarV2('icon/secondary')};
@@ -48,18 +52,81 @@ export class EmbedIframeIdleCard extends WithDisposable(LitElement) {
.affine-embed-iframe-idle-card:hover {
cursor: pointer;
}
+
+ .affine-embed-iframe-idle-card.horizontal {
+ flex-direction: row;
+
+ .icon {
+ width: 24px;
+ height: 24px;
+
+ svg {
+ width: 24px;
+ height: 24px;
+ }
+ }
+ }
+
+ .affine-embed-iframe-idle-card.vertical {
+ flex-direction: column;
+ justify-content: center;
+ overflow: hidden;
+ gap: 12px;
+
+ .icon {
+ width: 176px;
+ height: 112px;
+ overflow-y: hidden;
+
+ svg {
+ width: 112px;
+ height: 112px;
+ transform: rotate(12deg) translateY(18%);
+ }
+ }
+
+ .text {
+ text-align: center;
+ white-space: normal;
+ word-break: break-word;
+ }
+
+ @container affine-embed-iframe-idle-card (height < 180px) {
+ .icon {
+ display: none;
+ }
+ }
+ }
`;
override render() {
+ const { layout, width, height } = this.options;
+ const cardClasses = classMap({
+ 'affine-embed-iframe-idle-card': true,
+ horizontal: layout === 'horizontal',
+ vertical: layout === 'vertical',
+ });
+
+ const cardWidth = width ? `${width}px` : '100%';
+ const cardHeight = height ? `${height}px` : '100%';
+ const cardStyle = styleMap({
+ width: cardWidth,
+ height: cardHeight,
+ });
+
return html`
-
-
- ${EmbedIcon({ width: '24px', height: '24px' })}
-
+
+ ${EmbedIcon()}
Embed anything (Google Drive, Google Docs, Spotify, Miro…)
`;
}
+
+ @property({ attribute: false })
+ accessor options: EmbedIframeStatusCardOptions = {
+ layout: 'horizontal',
+ height: IDLE_CARD_DEFAULT_HEIGHT,
+ };
}
diff --git a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-link-input-base.ts b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-link-input-base.ts
index 9526292317..c3ed81ae58 100644
--- a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-link-input-base.ts
+++ b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-link-input-base.ts
@@ -104,6 +104,7 @@ export class EmbedIframeLinkInputBase extends WithDisposable(LitElement) {
this.disposables.addFromEvent(this, 'cut', stopPropagation);
this.disposables.addFromEvent(this, 'copy', stopPropagation);
this.disposables.addFromEvent(this, 'paste', stopPropagation);
+ this.disposables.addFromEvent(this, 'pointerdown', stopPropagation);
}
get store() {
diff --git a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-loading-card.ts b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-loading-card.ts
index c0bb0432a4..cff2e3136e 100644
--- a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-loading-card.ts
+++ b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-loading-card.ts
@@ -8,10 +8,9 @@ import { classMap } from 'lit/directives/class-map.js';
import { styleMap } from 'lit/directives/style-map.js';
import { getEmbedCardIcons } from '../../common/utils';
+import { LOADING_CARD_DEFAULT_HEIGHT } from '../consts';
import type { EmbedIframeStatusCardOptions } from '../types';
-const LOADING_CARD_DEFAULT_HEIGHT = 114;
-
export class EmbedIframeLoadingCard extends LitElement {
static override styles = css`
:host {
@@ -20,7 +19,7 @@ export class EmbedIframeLoadingCard extends LitElement {
}
.affine-embed-iframe-loading-card {
- container: affine-embed-iframe-loading-card / inline-size;
+ container: affine-embed-iframe-loading-card / size;
display: flex;
box-sizing: border-box;
border-radius: 8px;
@@ -147,6 +146,12 @@ export class EmbedIframeLoadingCard extends LitElement {
}
}
}
+
+ @container affine-embed-iframe-loading-card (height < 240px) {
+ .loading-banner {
+ display: none;
+ }
+ }
}
`;
diff --git a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/consts.ts b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/consts.ts
index 97966c62b5..e0d0a03c28 100644
--- a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/consts.ts
+++ b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/consts.ts
@@ -6,3 +6,7 @@ export const DEFAULT_IFRAME_HEIGHT = 152;
export const DEFAULT_IFRAME_WIDTH = '100%';
export const LINK_CREATE_POPUP_OFFSET = 4;
+
+export const IDLE_CARD_DEFAULT_HEIGHT = 48;
+export const LOADING_CARD_DEFAULT_HEIGHT = 114;
+export const ERROR_CARD_DEFAULT_HEIGHT = 114;
diff --git a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/embed-iframe-block.ts b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/embed-iframe-block.ts
index 7432746f9d..82b7c37371 100644
--- a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/embed-iframe-block.ts
+++ b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/embed-iframe-block.ts
@@ -34,7 +34,10 @@ import {
DEFAULT_IFRAME_HEIGHT,
DEFAULT_IFRAME_WIDTH,
EMBED_IFRAME_DEFAULT_CONTAINER_BORDER_RADIUS,
+ ERROR_CARD_DEFAULT_HEIGHT,
+ IDLE_CARD_DEFAULT_HEIGHT,
LINK_CREATE_POPUP_OFFSET,
+ LOADING_CARD_DEFAULT_HEIGHT,
} from './consts.js';
import { embedIframeBlockStyles } from './style.js';
import type { EmbedIframeStatusCardOptions } from './types.js';
@@ -109,10 +112,23 @@ export class EmbedIframeBlockComponent extends CaptionedBlockComponent
{
@@ -257,19 +273,21 @@ export class EmbedIframeBlockComponent extends CaptionedBlockComponent {
- // We don't need to select the block when the block is in the surface
- if (this.inSurface) {
- return;
- }
-
// when the block is in idle status and the url is not set, clear the selection
// and show the link input popup
if (this.isIdle$.value && !this.model.props.url) {
- this.selectionManager.clear(['block']);
+ // when the block is in the surface, clear the surface selection
+ // otherwise, clear the block selection
+ this.selectionManager.clear([this.inSurface ? 'surface' : 'block']);
this.toggleLinkInputPopup();
return;
}
+ // We don't need to select the block when the block is in the surface
+ if (this.inSurface) {
+ return;
+ }
+
// otherwise, select the block
this._selectBlock();
};
@@ -311,7 +329,9 @@ export class EmbedIframeBlockComponent extends CaptionedBlockComponent {
if (this.isIdle$.value) {
- return html``;
+ return html``;
}
if (this.isLoading$.value) {
@@ -356,6 +376,7 @@ export class EmbedIframeBlockComponent extends CaptionedBlockComponent {
this.refreshData().catch(console.error);
diff --git a/blocksuite/affine/widgets/widget-drag-handle/package.json b/blocksuite/affine/widgets/widget-drag-handle/package.json
index 0bb8adfd5e..7d9c148eeb 100644
--- a/blocksuite/affine/widgets/widget-drag-handle/package.json
+++ b/blocksuite/affine/widgets/widget-drag-handle/package.json
@@ -11,6 +11,7 @@
"license": "MIT",
"dependencies": {
"@blocksuite/affine-block-callout": "workspace:*",
+ "@blocksuite/affine-block-embed": "workspace:*",
"@blocksuite/affine-block-list": "workspace:*",
"@blocksuite/affine-block-note": "workspace:*",
"@blocksuite/affine-block-paragraph": "workspace:*",
diff --git a/blocksuite/affine/widgets/widget-drag-handle/src/watchers/drag-event-watcher.ts b/blocksuite/affine/widgets/widget-drag-handle/src/watchers/drag-event-watcher.ts
index 5fbaf5f3c3..5c2a47666f 100644
--- a/blocksuite/affine/widgets/widget-drag-handle/src/watchers/drag-event-watcher.ts
+++ b/blocksuite/affine/widgets/widget-drag-handle/src/watchers/drag-event-watcher.ts
@@ -1,3 +1,7 @@
+import {
+ EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE,
+ EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE,
+} from '@blocksuite/affine-block-embed';
import { ParagraphBlockComponent } from '@blocksuite/affine-block-paragraph';
import { DropIndicator } from '@blocksuite/affine-components/drop-indicator';
import {
@@ -511,6 +515,7 @@ export class DragEventWatcher {
this._mergeSnapshotToCurDoc(snapshot, point).catch(console.error);
} else {
this._dropAsGfxBlock(snapshot, point);
+ this.widget.selectionHelper.selection.clear(['block']);
}
} else {
this._onPageDrop(dropBlock, dragPayload, dropPayload, point);
@@ -1052,7 +1057,10 @@ export class DragEventWatcher {
Bound.deserialize(block.props.xywh as SerializedXYWH) ??
new Bound(0, 0, 0, 0);
- if (
+ if (block.flavour === 'affine:embed-iframe') {
+ blockBound.w = EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE;
+ blockBound.h = EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE;
+ } else if (
block.flavour === 'affine:attachment' ||
block.flavour === 'affine:bookmark' ||
block.flavour.startsWith('affine:embed-')
@@ -1132,17 +1140,22 @@ export class DragEventWatcher {
this._dropToModel(surfaceSnapshot, this.gfx.surface!.id)
.then(slices => {
slices?.content.forEach((block, idx) => {
- if (
- block.id === content[idx].id &&
- (block.flavour === 'affine:image' ||
+ if (block.id === content[idx].id) {
+ if (block.flavour === 'affine:embed-iframe') {
+ store.updateBlock(block.id, {
+ xywh: content[idx].props.xywh,
+ });
+ } else if (
+ block.flavour === 'affine:image' ||
block.flavour === 'affine:attachment' ||
block.flavour === 'affine:bookmark' ||
- block.flavour.startsWith('affine:embed-'))
- ) {
- store.updateBlock(block.id, {
- xywh: content[idx].props.xywh,
- style: content[idx].props.style,
- });
+ block.flavour.startsWith('affine:embed-')
+ ) {
+ store.updateBlock(block.id, {
+ xywh: content[idx].props.xywh,
+ style: content[idx].props.style,
+ });
+ }
}
});
})
@@ -1160,7 +1173,11 @@ export class DragEventWatcher {
this._dropToModel(pageSnapshot, this.widget.doc.root!.id)
.then(slices => {
slices?.content.forEach((block, idx) => {
- if (
+ if (block.flavour === 'affine:embed-iframe') {
+ store.updateBlock(block.id, {
+ xywh: content[idx].props.xywh,
+ });
+ } else if (
block.flavour === 'affine:attachment' ||
block.flavour.startsWith('affine:embed-')
) {
diff --git a/blocksuite/affine/widgets/widget-drag-handle/tsconfig.json b/blocksuite/affine/widgets/widget-drag-handle/tsconfig.json
index e83cee1b32..0a906357d0 100644
--- a/blocksuite/affine/widgets/widget-drag-handle/tsconfig.json
+++ b/blocksuite/affine/widgets/widget-drag-handle/tsconfig.json
@@ -8,6 +8,7 @@
"include": ["./src"],
"references": [
{ "path": "../../blocks/block-callout" },
+ { "path": "../../blocks/block-embed" },
{ "path": "../../blocks/block-list" },
{ "path": "../../blocks/block-note" },
{ "path": "../../blocks/block-paragraph" },
diff --git a/tools/utils/src/workspace.gen.ts b/tools/utils/src/workspace.gen.ts
index ba26ef2d66..0fde1809cc 100644
--- a/tools/utils/src/workspace.gen.ts
+++ b/tools/utils/src/workspace.gen.ts
@@ -695,6 +695,7 @@ export const PackageList = [
name: '@blocksuite/affine-widget-drag-handle',
workspaceDependencies: [
'blocksuite/affine/blocks/block-callout',
+ 'blocksuite/affine/blocks/block-embed',
'blocksuite/affine/blocks/block-list',
'blocksuite/affine/blocks/block-note',
'blocksuite/affine/blocks/block-paragraph',
diff --git a/yarn.lock b/yarn.lock
index b867235bdd..f924530398 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3470,6 +3470,7 @@ __metadata:
resolution: "@blocksuite/affine-widget-drag-handle@workspace:blocksuite/affine/widgets/widget-drag-handle"
dependencies:
"@blocksuite/affine-block-callout": "workspace:*"
+ "@blocksuite/affine-block-embed": "workspace:*"
"@blocksuite/affine-block-list": "workspace:*"
"@blocksuite/affine-block-note": "workspace:*"
"@blocksuite/affine-block-paragraph": "workspace:*"