From 756847d3cb8357bce39f8d003042cabc0c18fa3b Mon Sep 17 00:00:00 2001 From: yoyoyohamapi <8338436+yoyoyohamapi@users.noreply.github.com> Date: Fri, 30 May 2025 03:40:11 +0000 Subject: [PATCH] fix(core): prevent ai input tip loop-play (#12600) ### TL;DR * fix(core): prevent ai input tip loop-play ## Summary by CodeRabbit - **New Features** - Added an option to control whether tips in the AI chat composer scroll continuously or stop after the last tip. - **Style** - Improved layout and spacing in the embedding status tooltip for better readability and alignment. - **Refactor** - Updated the structure of elements in the embedding status tooltip for more consistent formatting. --- .../ai-chat-composer/ai-chat-composer-tip.ts | 35 ++++++++++++++++--- .../ai-chat-composer/ai-chat-composer.ts | 1 + .../ai-chat-input/embedding-status-tooltip.ts | 17 ++++++--- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/packages/frontend/core/src/blocksuite/ai/components/ai-chat-composer/ai-chat-composer-tip.ts b/packages/frontend/core/src/blocksuite/ai/components/ai-chat-composer/ai-chat-composer-tip.ts index 8a31ffc45..28627aa19 100644 --- a/packages/frontend/core/src/blocksuite/ai/components/ai-chat-composer/ai-chat-composer-tip.ts +++ b/packages/frontend/core/src/blocksuite/ai/components/ai-chat-composer/ai-chat-composer-tip.ts @@ -34,10 +34,14 @@ export class AIChatComposerTip extends LitElement { @property({ attribute: false }) accessor tips: TemplateResult[] = []; + @property({ attribute: false }) + accessor loop: boolean = true; + private readonly _interval = 5000; private readonly _animDuration = 500; private _tipIntervalId: number | null = null; private _tipListElement: HTMLDivElement | null = null; + private _currentIndex: number = 0; override connectedCallback() { super.connectedCallback(); @@ -76,6 +80,10 @@ export class AIChatComposerTip extends LitElement { private _startAutoScroll() { this._stopAutoScroll(); + if (!this.loop && this._currentIndex >= this.tips.length - 1) { + return; + } + this._currentIndex = 0; this._tipIntervalId = window.setInterval(() => { this._scrollToNext(); }, this._interval); @@ -91,6 +99,11 @@ export class AIChatComposerTip extends LitElement { private _scrollToNext() { if (this.tips.length <= 1 || !this._tipListElement) return; + if (!this.loop && this._currentIndex >= this.tips.length - 1) { + this._stopAutoScroll(); + return; + } + const list = this._tipListElement; const firstItem = list.firstElementChild as HTMLElement; @@ -100,11 +113,23 @@ export class AIChatComposerTip extends LitElement { list.style.transition = 'margin-top ' + this._animDuration + 'ms'; list.style.marginTop = '-' + TIP_HEIGHT + 'px'; - // After the animation ends: reorder the list and reset the position - setTimeout(function () { - list.style.transition = 'none'; // Immediately disable transition to reset position instantly without animation - list.append(firstItem); // Move the original first item to the bottom to achieve cyclic order - list.style.marginTop = '0'; // Reset the list position to the initial state + setTimeout(() => { + list.style.transition = 'none'; + if (this.loop) { + list.append(firstItem); + list.style.marginTop = '0'; + this._currentIndex++; + } else { + // Non-looping: only scroll if not at the last tip + if (this._currentIndex < this.tips.length - 1) { + list.append(firstItem); + list.style.marginTop = '0'; + this._currentIndex++; + } else { + // When reaching the last tip, keep the position unchanged + list.style.marginTop = '0'; + } + } }, this._animDuration); } diff --git a/packages/frontend/core/src/blocksuite/ai/components/ai-chat-composer/ai-chat-composer.ts b/packages/frontend/core/src/blocksuite/ai/components/ai-chat-composer/ai-chat-composer.ts index a09407aaf..8bfea17c4 100644 --- a/packages/frontend/core/src/blocksuite/ai/components/ai-chat-composer/ai-chat-composer.ts +++ b/packages/frontend/core/src/blocksuite/ai/components/ai-chat-composer/ai-chat-composer.ts @@ -153,6 +153,7 @@ export class AIChatComposer extends SignalWatcher( html`AI outputs can be misleading or wrong`, html``, ]} + .loop=${false} > `; diff --git a/packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/embedding-status-tooltip.ts b/packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/embedding-status-tooltip.ts index a5e1529cb..e0b638027 100644 --- a/packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/embedding-status-tooltip.ts +++ b/packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/embedding-status-tooltip.ts @@ -9,9 +9,14 @@ import { AIProvider } from '../../provider/ai-provider'; export class AIChatEmbeddingStatusTooltip extends SignalWatcher(LitElement) { static override styles = css` + :host { + width: 100%; + } .embedding-status { display: flex; + width: 100%; align-items: center; + justify-content: space-between; gap: 4px; user-select: none; } @@ -80,17 +85,19 @@ export class AIChatEmbeddingStatusTooltip extends SignalWatcher(LitElement) { class="embedding-status" data-testid="ai-chat-embedding-status-tooltip" > - +
Better results after embedding finished. - - +
Check status - - ${this.progressText} + ${this.progressText} +
`; }