[eric] dictation: with no cursor anywhere the transcript opens the composer typed-in, never dropped

This commit is contained in:
ciregenz
2026-08-05 15:54:23 -07:00
parent 71edd68dc0
commit 73f564574f
2 changed files with 15 additions and 2 deletions
@@ -225,6 +225,17 @@ export function useDashboardController(dashboardId: string, isActive: boolean) {
}
}, [toolbarOpen, toolbarPrefill, toolbarPrefillMode]);
// Dictation with no field focused lands HERE instead of vanishing: the composer opens with the transcript typed in, unsent.
useEffect(() => {
if (!isActive) return;
const onDictation = (e: Event): void => {
const text = (e as CustomEvent).detail?.text;
if (typeof text === 'string' && text.trim()) handleStarter(text);
};
window.addEventListener('openswarm:dictation-fallback', onDictation);
return () => window.removeEventListener('openswarm:dictation-fallback', onDictation);
}, [isActive, handleStarter]);
useDashboardClipboard({
isActive,
dashboardId,
+4 -2
View File
@@ -4,7 +4,7 @@ import { getWebview } from '@/shared/browserRegistry';
// Dictation lands where the user's cursor actually is, like every real dictation tool: a focused
// in-app field gets the text typed in (undo-friendly, fires React input events), a focused browser
// card forwards into the guest page's field, anything else falls back to the OS-level paste.
export type InjectTarget = 'field' | 'webview' | null;
export type InjectTarget = 'field' | 'webview' | 'composer' | null;
export function injectAtFocus(text: string): InjectTarget {
const active = document.activeElement as HTMLElement | null;
@@ -40,5 +40,7 @@ export function injectAtFocus(text: string): InjectTarget {
try { wv.focus?.(); void wv.insertText(text); return 'webview'; } catch { /* fall through */ }
}
}
return null;
// No cursor anywhere: open the dashboard composer with the transcript typed in. Words are never dropped.
window.dispatchEvent(new CustomEvent('openswarm:dictation-fallback', { detail: { text } }));
return 'composer';
}