diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts index 9080bd779e..ee503dedc7 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts @@ -14,7 +14,7 @@ import { css, html, nothing } from 'lit'; import { property, query, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; import { styleMap } from 'lit/directives/style-map.js'; -import { debounce } from 'lodash-es'; +import { debounce, throttle } from 'lodash-es'; import { EdgelessEditorActions, @@ -132,6 +132,9 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) { @query('.chat-panel-messages') accessor messagesContainer: HTMLDivElement | null = null; + @query('.message:nth-last-child(2)') + accessor lastMessage: HTMLDivElement | null = null; + private _renderAIOnboarding() { return this.isLoading || !this.host?.doc.get(FeatureFlagService).getFlag('enable_ai_onboarding') @@ -189,6 +192,16 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) { 100 ); + private readonly _scrollIntoView = () => { + if (!this.lastMessage) return; + this.lastMessage.scrollIntoView({ behavior: 'smooth' }); + }; + + private readonly _throttledScrollIntoView = throttle( + this._scrollIntoView, + 500 + ); + protected override render() { const { items } = this.chatContextValue; const { isLoading } = this; @@ -243,7 +256,7 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) { } )} - ${this.showDownIndicator + ${this.showDownIndicator && filteredItems.length > 1 ? html`
${DownArrowIcon}
` @@ -287,6 +300,12 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) { ); } + protected override updated() { + if (this.chatContextValue.status === 'transmitting') { + this._throttledScrollIntoView(); + } + } + renderItem(item: ChatItem, isLast: boolean) { const { status, error } = this.chatContextValue; const { host } = this; diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/index.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/index.ts index c9676b15e4..ba273ce5bd 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/index.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/index.ts @@ -205,17 +205,11 @@ export class ChatPanel extends WithDisposable(ShadowlessElement) { if ( !this.isLoading && _changedProperties.has('chatContextValue') && - this.chatContextValue.status !== 'idle' - ) { - if (this.chatContextValue.status === 'transmitting') { - this._scrollToEnd(); - } else if ( - this.chatContextValue.status === 'loading' || + (this.chatContextValue.status === 'loading' || this.chatContextValue.status === 'error' || - this.chatContextValue.status === 'success' - ) { - setTimeout(this._scrollToEnd, 500); - } + this.chatContextValue.status === 'success') + ) { + setTimeout(this._scrollToEnd, 500); } }