mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-07 20:31:33 +08:00
feat(core): disable pin chat while generating AI answers (#13131)
Close [AI-316](https://linear.app/affine-design/issue/AI-316) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Chat status is now displayed and updated in the chat panel and toolbar, allowing users to see when the chat is generating a response. * The pin button in the chat toolbar is disabled while the chat is generating a response, preventing pin actions during this time and providing feedback via a notification if attempted. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -30,6 +30,7 @@ import type {
|
||||
AIPlaygroundConfig,
|
||||
AIReasoningConfig,
|
||||
} from '../components/ai-chat-input';
|
||||
import type { ChatStatus } from '../components/ai-chat-messages';
|
||||
import { createPlaygroundModal } from '../components/playground/modal';
|
||||
import { AIProvider } from '../provider';
|
||||
import type { AppSidebarConfig } from './chat-config';
|
||||
@@ -138,6 +139,9 @@ export class ChatPanel extends SignalWatcher(
|
||||
@state()
|
||||
accessor embeddingProgress: [number, number] = [0, 0];
|
||||
|
||||
@state()
|
||||
accessor status: ChatStatus = 'idle';
|
||||
|
||||
private isSidebarOpen: Signal<boolean | undefined> = signal(false);
|
||||
|
||||
private sidebarWidth: Signal<number | undefined> = signal(undefined);
|
||||
@@ -171,6 +175,7 @@ export class ChatPanel extends SignalWatcher(
|
||||
.session=${this.session}
|
||||
.workspaceId=${this.doc.workspace.id}
|
||||
.docId=${this.doc.id}
|
||||
.status=${this.status}
|
||||
.onNewSession=${this.newSession}
|
||||
.onTogglePin=${this.togglePin}
|
||||
.onOpenSession=${this.openSession}
|
||||
@@ -359,6 +364,7 @@ export class ChatPanel extends SignalWatcher(
|
||||
private readonly onContextChange = async (
|
||||
context: Partial<ChatContextValue>
|
||||
) => {
|
||||
this.status = context.status ?? 'idle';
|
||||
if (context.status === 'success') {
|
||||
await this.rebindSession();
|
||||
}
|
||||
|
||||
+27
-1
@@ -15,6 +15,7 @@ import { css, html } from 'lit';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
|
||||
import type { DocDisplayConfig } from '../ai-chat-chips';
|
||||
import type { ChatStatus } from '../ai-chat-messages';
|
||||
|
||||
export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
@property({ attribute: false })
|
||||
@@ -26,6 +27,9 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
@property({ attribute: false })
|
||||
accessor docId: string | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor status!: ChatStatus;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onNewSession!: () => void;
|
||||
|
||||
@@ -49,6 +53,10 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
|
||||
private abortController: AbortController | null = null;
|
||||
|
||||
get isGenerating() {
|
||||
return this.status === 'transmitting' || this.status === 'loading';
|
||||
}
|
||||
|
||||
static override styles = css`
|
||||
.ai-chat-toolbar {
|
||||
display: flex;
|
||||
@@ -72,6 +80,10 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
height: 16px;
|
||||
color: ${unsafeCSSVarV2('icon/primary')};
|
||||
}
|
||||
|
||||
&[data-disabled='true'] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -84,7 +96,11 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
${PlusIcon()}
|
||||
<affine-tooltip>New Chat</affine-tooltip>
|
||||
</div>
|
||||
<div class="chat-toolbar-icon" @click=${this.onTogglePin}>
|
||||
<div
|
||||
class="chat-toolbar-icon"
|
||||
@click=${this.onPinClick}
|
||||
data-disabled=${this.isGenerating}
|
||||
>
|
||||
${pinned ? PinedIcon() : PinIcon()}
|
||||
<affine-tooltip>
|
||||
${pinned ? 'Unpin this Chat' : 'Pin this Chat'}
|
||||
@@ -101,6 +117,16 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
`;
|
||||
}
|
||||
|
||||
private readonly onPinClick = async () => {
|
||||
if (this.isGenerating) {
|
||||
this.notificationService.toast(
|
||||
'Cannot pin a chat while generating an answer'
|
||||
);
|
||||
return;
|
||||
}
|
||||
await this.onTogglePin();
|
||||
};
|
||||
|
||||
private readonly unpinConfirm = async () => {
|
||||
if (this.session && this.session.pinned) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user