Files
paseo/packages/app/src/hooks/use-dictation.shared.ts
T
Mohamed BoudraandGitHub 2ead7e7719 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.
2026-07-20 19:32:50 +02:00

45 lines
1.4 KiB
TypeScript

import { i18n } from "@/i18n/i18next";
export type DictationStatus = "idle" | "recording" | "uploading" | "failed";
export interface UseDictationOptions {
client: import("@getpaseo/client/internal/daemon-client").DaemonClient | null;
onTranscript: (text: string, meta: { requestId: string }) => void;
onPartialTranscript?: (text: string, meta: { requestId: string }) => void;
onError?: (error: Error) => void;
onPermanentFailure?: (error: Error, context: { requestId: string }) => void;
canStart?: () => boolean;
canConfirm?: () => boolean;
enableDuration?: boolean;
}
export interface UseDictationResult {
isRecording: boolean;
isRecordingActive: () => boolean;
isProcessing: boolean;
partialTranscript: string;
volume: number;
duration: number;
error: string | null;
status: DictationStatus;
startDictation: () => Promise<void>;
cancelDictation: () => Promise<void>;
confirmDictation: () => Promise<void>;
retryFailedDictation: () => Promise<void>;
discardFailedDictation: () => void;
reset: () => void;
}
export const DURATION_TICK_MS = 1000;
export const PCM_DICTATION_FORMAT = "audio/pcm;rate=16000;bits=16";
export const toError = (error: unknown): Error => {
if (error instanceof Error) {
return error;
}
if (typeof error === "string" && error.trim().length > 0) {
return new Error(error);
}
return new Error(i18n.t("common.errors.unexpectedDictationError"));
};