('qa:dismiss', () => {
+ activeSessionIdRef.current = null;
setSelectionPreview('');
+ setSelectionWarning('');
setComposerText('');
if (embeddedRef.current) {
onRequestCloseRef.current?.();
@@ -231,6 +242,18 @@ export function QaPanel({ embedded = false, onRequestClose }: QaPanelProps = {})
};
}, []);
+ useEffect(() => {
+ if (!closing) return;
+ activeSessionIdRef.current = null;
+ setMessages([]);
+ setStatus('idle');
+ setErrorMsg('');
+ setStreamingAnswer('');
+ setSelectionPreview('');
+ setSelectionWarning('');
+ setComposerText('');
+ }, [closing]);
+
// ── Esc 关闭 ────────────────────────────────────────────────────────
useEffect(() => {
const onKey = (event: KeyboardEvent) => {
@@ -382,6 +405,16 @@ export function QaPanel({ embedded = false, onRequestClose }: QaPanelProps = {})
{status === 'recording' && selectionPreview && (
)}
+ {selectionWarning === 'linux_selection_tools_missing' && (
+
+ {t('qa.linuxSelectionToolsMissing')}
+
+ )}
@@ -547,13 +580,6 @@ function MessageRow({
);
}
-function splitFirstTurnUser(content: string): { selection: string; question: string } {
- // 后端拼法:`# 选区原文\n{sel}\n\n# 我的问题\n{q}`。简单 split,对齐 coordinator.rs 的写法。
- const m = content.match(/^# 选区原文\n([\s\S]*?)\n\n# 我的问题\n([\s\S]+)$/);
- if (!m) return { selection: '', question: content };
- return { selection: m[1].trim(), question: m[2].trim() };
-}
-
/** 录音时的选区上下文条:贴在输入区上方,让用户看到「在追问哪段文字」。 */
function SelectionChip({ text, t }: { text: string; t: ReturnType['t'] }) {
const truncated = useMemo(() => truncate(text, SELECTION_PREVIEW_MAX), [text]);