fix(app): keep dictation shortcuts responsive (#2268)
The composer mirrored dictation state in a second ref that could remain stale after the recording surface changed. Route shortcut decisions through the dictation lifecycle's synchronous state so finishing or rejecting a recording cannot leave Command-D latched.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { DaemonClient } from "@getpaseo/client/internal/daemon-client";
|
||||
import type { MessagePayload } from "@/composer/types";
|
||||
import type { MessageInputKeyboardActionKind } from "@/keyboard/actions";
|
||||
|
||||
export type SendBehavior = "interrupt" | "queue";
|
||||
|
||||
@@ -45,6 +46,18 @@ interface SendActionContext {
|
||||
handleQueueMessage: () => void;
|
||||
}
|
||||
|
||||
interface MessageInputKeyboardActions {
|
||||
focusInput: () => void;
|
||||
isDictationRecording: () => boolean;
|
||||
markTranscriptForSend: () => void;
|
||||
confirmDictation: () => void | Promise<void>;
|
||||
cancelDictation: () => void | Promise<void>;
|
||||
startDictation: () => void | Promise<void>;
|
||||
toggleRealtimeVoice: () => void;
|
||||
isRealtimeVoiceActive: boolean;
|
||||
toggleRealtimeVoiceMute: () => void;
|
||||
}
|
||||
|
||||
export function computeCanStartDictation(input: {
|
||||
client: DaemonClient | null;
|
||||
isReadyForDictation: boolean | undefined;
|
||||
@@ -76,6 +89,51 @@ export function runAlternateSendAction(ctx: SendActionContext): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function runMessageInputKeyboardAction(
|
||||
action: MessageInputKeyboardActionKind,
|
||||
actions: MessageInputKeyboardActions,
|
||||
): boolean {
|
||||
if (action === "focus") {
|
||||
actions.focusInput();
|
||||
return true;
|
||||
}
|
||||
if (action === "send" || action === "dictation-confirm") {
|
||||
if (actions.isDictationRecording()) {
|
||||
actions.markTranscriptForSend();
|
||||
void actions.confirmDictation();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (action === "voice-toggle") {
|
||||
actions.toggleRealtimeVoice();
|
||||
return true;
|
||||
}
|
||||
if (action === "voice-mute-toggle") {
|
||||
if (actions.isRealtimeVoiceActive) {
|
||||
actions.toggleRealtimeVoiceMute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (action === "dictation-cancel") {
|
||||
if (actions.isDictationRecording()) {
|
||||
void actions.cancelDictation();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (action === "dictation-toggle") {
|
||||
if (actions.isDictationRecording()) {
|
||||
actions.markTranscriptForSend();
|
||||
void actions.confirmDictation();
|
||||
} else {
|
||||
void actions.startDictation();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function stopRealtimeVoice(ctx: StopRealtimeVoiceContext): Promise<void> {
|
||||
if (!ctx.voice || !ctx.isRealtimeVoiceForCurrentAgent) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user