diff --git a/packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/ai-chat-input.ts b/packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/ai-chat-input.ts
index eb19a694a..56a5e9ca8 100644
--- a/packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/ai-chat-input.ts
+++ b/packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/ai-chat-input.ts
@@ -281,12 +281,9 @@ export class AIChatInput extends SignalWatcher(WithDisposable(LitElement)) {
({ input, context, host }) => {
if (this.host === host) {
context && this.updateContext(context);
- const { updateComplete, send } = this;
- updateComplete
- .then(() => {
- return send(input);
- })
- .catch(console.error);
+ setTimeout(() => {
+ this.send(input).catch(console.error);
+ }, 0);
}
}
)
diff --git a/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/components/state/input.ts b/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/components/state/input.ts
index 89d07e221..51f027304 100644
--- a/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/components/state/input.ts
+++ b/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/components/state/input.ts
@@ -84,11 +84,11 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
}
}
- .arrow[data-active] {
+ .arrow[data-active='true'] {
background: ${unsafeCSSVarV2('icon/activated')};
}
- .arrow[data-active]:hover {
+ .arrow[data-active='true']:hover {
cursor: pointer;
}
@@ -140,7 +140,7 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
)};
}
- .arrow[data-active] {
+ .arrow[data-active='true'] {
background: ${unsafeCSS(
lightCssVariablesV2['--affine-v2-icon-activated']
)};
@@ -178,7 +178,7 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
)};
}
- .arrow[data-active] {
+ .arrow[data-active='true'] {
background: ${unsafeCSS(
darkCssVariablesV2['--affine-v2-icon-activated']
)};
@@ -196,13 +196,8 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
this.onInput?.(this.textarea.value);
const value = this.textarea.value.trim();
- if (value.length > 0) {
- this._arrow.dataset.active = '';
- this._hasContent = true;
- } else {
- delete this._arrow.dataset.active;
- this._hasContent = false;
- }
+ this._hasContent = value.length > 0;
+ this._arrow.dataset.active = String(this._hasContent);
};
private readonly _onKeyDown = (e: KeyboardEvent) => {
@@ -264,6 +259,7 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
: nothing}
diff --git a/tests/affine-cloud-copilot/e2e/basic/chat.spec.ts b/tests/affine-cloud-copilot/e2e/basic/chat.spec.ts
index 820d6a17c..cd0c1f5de 100644
--- a/tests/affine-cloud-copilot/e2e/basic/chat.spec.ts
+++ b/tests/affine-cloud-copilot/e2e/basic/chat.spec.ts
@@ -359,4 +359,63 @@ test.describe('AIBasic/Chat', () => {
expect(clipboardText).toBe(content);
}).toPass({ timeout: 5000 });
});
+
+ test('chat with ask ai input in page mode', async ({
+ loggedInPage: page,
+ utils,
+ }) => {
+ await utils.chatPanel.closeChatPanel(page);
+ await utils.editor.askAIWithText(
+ page,
+ 'AFFiNE is an open source all in one workspace.'
+ );
+ await page.keyboard.type('Translate to chinese');
+
+ const sendButton = await page.getByTestId('ai-panel-input-send');
+ await expect(sendButton).toHaveAttribute('data-active', 'true');
+ await sendButton.click();
+
+ await expect(page.getByTestId('sidebar-tab-content-chat')).toBeVisible();
+ await utils.chatPanel.waitForHistory(page, [
+ {
+ role: 'user',
+ content:
+ 'AFFiNE is an open source all in one workspace.\nTranslate to chinese',
+ },
+ {
+ role: 'assistant',
+ status: 'success',
+ },
+ ]);
+ });
+
+ test('chat with ask ai input in edgeless mode', async ({
+ loggedInPage: page,
+ utils,
+ }) => {
+ await utils.chatPanel.closeChatPanel(page);
+ await utils.editor.askAIWithEdgeless(page, async () => {
+ await utils.editor.createShape(page, 'HelloWorld');
+ });
+ await page.waitForTimeout(1000);
+ await page.keyboard.type('What color is it?');
+
+ await page.waitForTimeout(1000);
+ const sendButton = await page.getByTestId('ai-panel-input-send');
+ await expect(sendButton).toHaveAttribute('data-active', 'true');
+ await sendButton.click();
+
+ await expect(page.getByTestId('sidebar-tab-content-chat')).toBeVisible();
+ expect(await page.locator('chat-content-images')).toBeVisible();
+ await utils.chatPanel.waitForHistory(page, [
+ {
+ role: 'user',
+ content: 'What color is it?',
+ },
+ {
+ role: 'assistant',
+ status: 'success',
+ },
+ ]);
+ });
});
diff --git a/tests/affine-cloud-copilot/e2e/utils/chat-panel-utils.ts b/tests/affine-cloud-copilot/e2e/utils/chat-panel-utils.ts
index 7b0550019..c245c43d4 100644
--- a/tests/affine-cloud-copilot/e2e/utils/chat-panel-utils.ts
+++ b/tests/affine-cloud-copilot/e2e/utils/chat-panel-utils.ts
@@ -38,6 +38,13 @@ export class ChatPanelUtils {
await this.disableNetworkSearch(page);
}
+ public static async closeChatPanel(page: Page) {
+ await page.getByTestId('right-sidebar-toggle').click({
+ delay: 200,
+ });
+ await expect(page.getByTestId('sidebar-tab-content-chat')).toBeHidden();
+ }
+
public static async typeChat(page: Page, content: string) {
await page.getByTestId('chat-panel-input').focus();
await page.keyboard.type(content);