mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-28 11:41:04 +00:00
fix(cli): /clear dismisses active /btw side-question dialog (#3431)
The /clear command cleared the history log but left an active /btw side-question dialog visible in the fixed bottom area, because /btw stores state in dedicated btwItem state (via setBtwItem) rather than in history items. The ui.clear callback only called clearItems() and clearScreen(), never cancelBtw(), so the pending-btw dialog survived. Call cancelBtw() from ui.clear so /clear (and /reset, /new) abort any in-flight btw request and null out the btwItem state. Fixes #3334 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
f7ebc372f1
commit
6ebe28453d
2 changed files with 51 additions and 0 deletions
|
|
@ -14,6 +14,7 @@ import type {
|
||||||
} from '../commands/types.js';
|
} from '../commands/types.js';
|
||||||
import { CommandKind } from '../commands/types.js';
|
import { CommandKind } from '../commands/types.js';
|
||||||
import type { LoadedSettings } from '../../config/settings.js';
|
import type { LoadedSettings } from '../../config/settings.js';
|
||||||
|
import type { HistoryItemBtw } from '../types.js';
|
||||||
import { MessageType } from '../types.js';
|
import { MessageType } from '../types.js';
|
||||||
import { BuiltinCommandLoader } from '../../services/BuiltinCommandLoader.js';
|
import { BuiltinCommandLoader } from '../../services/BuiltinCommandLoader.js';
|
||||||
import { FileCommandLoader } from '../../services/FileCommandLoader.js';
|
import { FileCommandLoader } from '../../services/FileCommandLoader.js';
|
||||||
|
|
@ -1124,4 +1125,53 @@ describe('useSlashCommandProcessor', () => {
|
||||||
expect(logSlashCommand).not.toHaveBeenCalled();
|
expect(logSlashCommand).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('ui.clear and /btw dialog', () => {
|
||||||
|
it('should dismiss an active btw dialog when ui.clear is called', async () => {
|
||||||
|
const result = setupProcessorHook();
|
||||||
|
await waitFor(() => expect(result.current.commandContext).toBeDefined());
|
||||||
|
|
||||||
|
const btwItem: HistoryItemBtw = {
|
||||||
|
type: MessageType.BTW,
|
||||||
|
btw: { question: 'why?', answer: '', isPending: true },
|
||||||
|
};
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.commandContext.ui.setBtwItem(btwItem);
|
||||||
|
});
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(result.current.commandContext.ui.btwItem).toEqual(btwItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.commandContext.ui.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(result.current.commandContext.ui.btwItem).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should abort the in-flight btw request when ui.clear is called', async () => {
|
||||||
|
const result = setupProcessorHook();
|
||||||
|
await waitFor(() => expect(result.current.commandContext).toBeDefined());
|
||||||
|
|
||||||
|
const abortController = new AbortController();
|
||||||
|
const abortSpy = vi.spyOn(abortController, 'abort');
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.commandContext.ui.btwAbortControllerRef.current =
|
||||||
|
abortController;
|
||||||
|
});
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.commandContext.ui.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(abortSpy).toHaveBeenCalledTimes(1);
|
||||||
|
expect(
|
||||||
|
result.current.commandContext.ui.btwAbortControllerRef.current,
|
||||||
|
).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,7 @@ export const useSlashCommandProcessor = (
|
||||||
ui: {
|
ui: {
|
||||||
addItem,
|
addItem,
|
||||||
clear: () => {
|
clear: () => {
|
||||||
|
cancelBtw();
|
||||||
clearItems();
|
clearItems();
|
||||||
clearScreen();
|
clearScreen();
|
||||||
refreshStatic();
|
refreshStatic();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue