diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-cards.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-cards.ts index 4d36762d31..2b428b1d2e 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-cards.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-cards.ts @@ -6,7 +6,14 @@ import { NoteDisplayMode, } from '@blocksuite/blocks'; import type { BlockModel } from '@blocksuite/store'; -import { css, html, LitElement, nothing, type PropertyValues } from 'lit'; +import { + css, + html, + LitElement, + nothing, + type PropertyValues, + type TemplateResult, +} from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; import { styleMap } from 'lit/directives/style-map.js'; @@ -107,6 +114,7 @@ export class ChatCards extends WithDisposable(LitElement) { @state() accessor cards: Card[] = []; + private _currentDocId: string | null = null; private _selectedCardId: number = 0; static renderText({ text }: CardText) { @@ -153,6 +161,7 @@ export class ChatCards extends WithDisposable(LitElement) { style=${styleMap({ display: 'flex', flexDirection: 'column', + maxWidth: 'calc(100% - 72px)', })} >
@@ -172,14 +181,66 @@ export class ChatCards extends WithDisposable(LitElement) { `; } - static renderDoc(_: CardBlock) { + static renderDoc({ text, images }: CardBlock) { + let textTpl = html`you've chosen within the doc`; + let imageTpl: TemplateResult<1> | typeof nothing = nothing; + let hasImage = false; + + if (text?.length) { + const lines = text.split('\n'); + textTpl = html`${repeat( + lines.slice(0, 2), + line => line, + line => html` +
+ ${line} +
+ ` + )}`; + } + + if (images?.length) { + hasImage = true; + imageTpl = html` + + `; + } + return html` -
-
- ${DocIcon} -
Start with this doc
+
+
+
+ ${DocIcon} +
Start with this doc
+
+
${textTpl}
-
you've chosen within the doc
+ ${imageTpl}
`; } @@ -218,7 +279,7 @@ export class ChatCards extends WithDisposable(LitElement) { card.images = images; } - private async _handleClick(card: Card) { + private async _selectCard(card: Card) { AIProvider.slots.toggleChatCards.emit({ visible: false }); this._selectedCardId = card.id; @@ -361,19 +422,27 @@ export class ChatCards extends WithDisposable(LitElement) { protected override async updated(changedProperties: PropertyValues) { if (changedProperties.has('host')) { + if (this._currentDocId === this.host.doc.id) return; + this._currentDocId = this.host.doc.id; + this.cards = []; + const { text, images } = await this._extractAll(); const hasText = text.length > 0; const hasImages = images.length > 0; // Currently only supports checking on first load - if ( - (hasText || hasImages) && - !this.cards.some(card => card.type === CardType.Doc) - ) { - this._updateCards({ + if (hasText || hasImages) { + const card: CardBlock = { id: Date.now(), type: CardType.Doc, - }); + }; + if (hasText) { + card.text = text; + } + if (hasImages) { + card.images = images; + } + this._updateCards(card); } } } @@ -388,6 +457,13 @@ export class ChatCards extends WithDisposable(LitElement) { } else { await this._extract(); } + + if (this.cards.length > 0) { + const card = this.cards[0]; + if (card.type === CardType.Doc) return; + + await this._selectCard(card); + } }) ); @@ -408,7 +484,7 @@ export class ChatCards extends WithDisposable(LitElement) { this.cards, card => card.id, card => html` -
this._handleClick(card)}> +
this._selectCard(card)}> ${this._renderCard(card)}
` diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-input.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-input.ts index 2f477e74fb..efa836a573 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-input.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-input.ts @@ -106,12 +106,7 @@ export class ChatPanelInput extends WithDisposable(LitElement) { margin-left: auto; } - .chat-history-clear { - background-color: var(--affine-white); - } - .image-upload { - background-color: var(--affine-white); display: flex; justify-content: center; align-items: center;