fix(core): prevent ai input tip loop-play (#12600)
### TL;DR * fix(core): prevent ai input tip loop-play <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## 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. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -34,10 +34,14 @@ export class AIChatComposerTip extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor tips: TemplateResult[] = [];
|
accessor tips: TemplateResult[] = [];
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
accessor loop: boolean = true;
|
||||||
|
|
||||||
private readonly _interval = 5000;
|
private readonly _interval = 5000;
|
||||||
private readonly _animDuration = 500;
|
private readonly _animDuration = 500;
|
||||||
private _tipIntervalId: number | null = null;
|
private _tipIntervalId: number | null = null;
|
||||||
private _tipListElement: HTMLDivElement | null = null;
|
private _tipListElement: HTMLDivElement | null = null;
|
||||||
|
private _currentIndex: number = 0;
|
||||||
|
|
||||||
override connectedCallback() {
|
override connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
@@ -76,6 +80,10 @@ export class AIChatComposerTip extends LitElement {
|
|||||||
|
|
||||||
private _startAutoScroll() {
|
private _startAutoScroll() {
|
||||||
this._stopAutoScroll();
|
this._stopAutoScroll();
|
||||||
|
if (!this.loop && this._currentIndex >= this.tips.length - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._currentIndex = 0;
|
||||||
this._tipIntervalId = window.setInterval(() => {
|
this._tipIntervalId = window.setInterval(() => {
|
||||||
this._scrollToNext();
|
this._scrollToNext();
|
||||||
}, this._interval);
|
}, this._interval);
|
||||||
@@ -91,6 +99,11 @@ export class AIChatComposerTip extends LitElement {
|
|||||||
private _scrollToNext() {
|
private _scrollToNext() {
|
||||||
if (this.tips.length <= 1 || !this._tipListElement) return;
|
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 list = this._tipListElement;
|
||||||
const firstItem = list.firstElementChild as HTMLElement;
|
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.transition = 'margin-top ' + this._animDuration + 'ms';
|
||||||
list.style.marginTop = '-' + TIP_HEIGHT + 'px';
|
list.style.marginTop = '-' + TIP_HEIGHT + 'px';
|
||||||
|
|
||||||
// After the animation ends: reorder the list and reset the position
|
setTimeout(() => {
|
||||||
setTimeout(function () {
|
list.style.transition = 'none';
|
||||||
list.style.transition = 'none'; // Immediately disable transition to reset position instantly without animation
|
if (this.loop) {
|
||||||
list.append(firstItem); // Move the original first item to the bottom to achieve cyclic order
|
list.append(firstItem);
|
||||||
list.style.marginTop = '0'; // Reset the list position to the initial state
|
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);
|
}, this._animDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ export class AIChatComposer extends SignalWatcher(
|
|||||||
html`<span>AI outputs can be misleading or wrong</span>`,
|
html`<span>AI outputs can be misleading or wrong</span>`,
|
||||||
html`<ai-chat-embedding-status-tooltip .host=${this.host} />`,
|
html`<ai-chat-embedding-status-tooltip .host=${this.host} />`,
|
||||||
]}
|
]}
|
||||||
|
.loop=${false}
|
||||||
></ai-chat-composer-tip>
|
></ai-chat-composer-tip>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|||||||
@@ -9,9 +9,14 @@ import { AIProvider } from '../../provider/ai-provider';
|
|||||||
|
|
||||||
export class AIChatEmbeddingStatusTooltip extends SignalWatcher(LitElement) {
|
export class AIChatEmbeddingStatusTooltip extends SignalWatcher(LitElement) {
|
||||||
static override styles = css`
|
static override styles = css`
|
||||||
|
:host {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.embedding-status {
|
.embedding-status {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
@@ -80,17 +85,19 @@ export class AIChatEmbeddingStatusTooltip extends SignalWatcher(LitElement) {
|
|||||||
class="embedding-status"
|
class="embedding-status"
|
||||||
data-testid="ai-chat-embedding-status-tooltip"
|
data-testid="ai-chat-embedding-status-tooltip"
|
||||||
>
|
>
|
||||||
<span class="embedding-status-text">
|
<div class="embedding-status-text">
|
||||||
Better results after embedding finished.
|
Better results after embedding finished.
|
||||||
</span>
|
</div>
|
||||||
<span
|
<div
|
||||||
class="check-status"
|
class="check-status"
|
||||||
data-testid="ai-chat-embedding-status-tooltip-check"
|
data-testid="ai-chat-embedding-status-tooltip-check"
|
||||||
@mouseenter=${this._handleCheckStatusMouseEnter}
|
@mouseenter=${this._handleCheckStatusMouseEnter}
|
||||||
>
|
>
|
||||||
Check status
|
Check status
|
||||||
</span>
|
<affine-tooltip tip-position="top-start"
|
||||||
<affine-tooltip>${this.progressText}</affine-tooltip>
|
>${this.progressText}</affine-tooltip
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user