mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-11 07:06:28 +08:00
feat(core): show stop modal if clickoutside during generating (#12227)
### TL;DR feat: show stop model if click-outside during ai generating >CLOSE AI-89 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a confirmation dialog when attempting to stop AI content generation by clicking outside the panel, ensuring users can confirm or cancel the stop action. - **Tests** - Introduced an end-to-end test to verify the confirmation dialog appears and AI generation stops as expected when clicking outside during generation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -113,7 +113,11 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
||||
};
|
||||
|
||||
private readonly _clickOutside = () => {
|
||||
this._discardWithConfirmation();
|
||||
if (this.state === 'generating') {
|
||||
this._stopWithConfirmation();
|
||||
} else {
|
||||
this._discardWithConfirmation();
|
||||
}
|
||||
};
|
||||
|
||||
private _discardModalAbort: AbortController | null = null;
|
||||
@@ -169,6 +173,16 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
||||
|
||||
ctx: unknown = null;
|
||||
|
||||
private readonly _stopWithConfirmation = () => {
|
||||
this.showStopModal()
|
||||
.then(stop => {
|
||||
if (stop) {
|
||||
this.stopGenerating();
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
};
|
||||
|
||||
private readonly _discardWithConfirmation = () => {
|
||||
if (this.state === 'hidden') {
|
||||
return;
|
||||
@@ -275,6 +289,24 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
||||
this._autoUpdatePosition(reference);
|
||||
};
|
||||
|
||||
showStopModal = () => {
|
||||
const notification = this.host.std.getOptional(NotificationProvider);
|
||||
if (!notification) {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
this._clearDiscardModal();
|
||||
this._discardModalAbort = new AbortController();
|
||||
return notification
|
||||
.confirm({
|
||||
title: 'Stop generating',
|
||||
message: 'AI is generating content. Do you want to stop generating?',
|
||||
cancelText: 'Cancel',
|
||||
confirmText: 'Stop',
|
||||
abort: this._abortController.signal,
|
||||
})
|
||||
.finally(() => (this._discardModalAbort = null));
|
||||
};
|
||||
|
||||
showDiscardModal = () => {
|
||||
const notification = this.host.std.getOptional(NotificationProvider);
|
||||
if (!notification) {
|
||||
|
||||
@@ -21,6 +21,21 @@ test.describe('AIChatWith/Text', () => {
|
||||
await expect(page.getByTestId('ai-generating')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('should support stop generating when click outside', async ({
|
||||
loggedInPage: page,
|
||||
utils,
|
||||
}) => {
|
||||
await utils.editor.askAIWithText(page, 'Panda');
|
||||
await page.getByTestId('action-generate-image').click();
|
||||
await expect(page.getByTestId('ai-generating')).toBeVisible();
|
||||
await page.mouse.click(0, 0);
|
||||
await expect(
|
||||
page.getByText('AI is generating content. Do you want to stop generating')
|
||||
).toBeVisible();
|
||||
await page.getByTestId('confirm-modal-confirm').click();
|
||||
await expect(page.getByTestId('ai-generating')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('should support copy answer', async ({ loggedInPage: page, utils }) => {
|
||||
const { translate } = await utils.editor.askAIWithText(page, 'Apple');
|
||||
const { answer } = await translate('German');
|
||||
|
||||
Reference in New Issue
Block a user