feat: add voice capability status reporting to client
This commit is contained in:
@@ -4,7 +4,6 @@ import {
|
||||
Text,
|
||||
ActivityIndicator,
|
||||
Platform,
|
||||
Alert,
|
||||
} from "react-native";
|
||||
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
|
||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||
@@ -32,6 +31,7 @@ import { encodeImages } from "@/utils/encode-images";
|
||||
import { useKeyboardNavStore } from "@/stores/keyboard-nav-store";
|
||||
import { focusWithRetries } from "@/utils/web-focus";
|
||||
import { useVoiceOptional } from "@/contexts/voice-context";
|
||||
import { useToast } from "@/contexts/toast-context";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { Shortcut } from "@/components/ui/shortcut";
|
||||
|
||||
@@ -80,6 +80,7 @@ export function AgentInputArea({
|
||||
const client = useSessionStore(
|
||||
(state) => state.sessions[serverId]?.client ?? null
|
||||
);
|
||||
const toast = useToast();
|
||||
const voice = useVoiceOptional();
|
||||
const isConnected = client?.isConnected ?? false;
|
||||
|
||||
@@ -470,10 +471,17 @@ export function AgentInputArea({
|
||||
}
|
||||
void voice.startVoice(serverId, agentId).catch((error) => {
|
||||
console.error("[AgentInputArea] Failed to start voice mode", error);
|
||||
const message = error instanceof Error ? error.message : "Voice features are not available right now.";
|
||||
Alert.alert("Voice unavailable", message);
|
||||
const message =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: typeof error === "string"
|
||||
? error
|
||||
: null;
|
||||
if (message && message.trim().length > 0) {
|
||||
toast.error(message);
|
||||
}
|
||||
});
|
||||
}, [agentId, isConnected, serverId, voice]);
|
||||
}, [agentId, isConnected, serverId, toast, voice]);
|
||||
|
||||
function handleEditQueuedMessage(id: string) {
|
||||
const item = queuedMessages.find((q) => q.id === id);
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
Image,
|
||||
Platform,
|
||||
BackHandler,
|
||||
Alert,
|
||||
} from "react-native";
|
||||
import {
|
||||
useState,
|
||||
@@ -34,6 +33,7 @@ import type { DaemonClient } from "@server/client/daemon-client";
|
||||
import { usePanelStore } from "@/stores/panel-store";
|
||||
import { useSessionStore } from "@/stores/session-store";
|
||||
import { useVoiceOptional } from "@/contexts/voice-context";
|
||||
import { useToast } from "@/contexts/toast-context";
|
||||
import { resolveVoiceUnavailableMessage } from "@/utils/server-info-capabilities";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { Shortcut } from "@/components/ui/shortcut";
|
||||
@@ -136,6 +136,7 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
||||
ref
|
||||
) {
|
||||
const { theme } = useUnistyles();
|
||||
const toast = useToast();
|
||||
const voice = useVoiceOptional();
|
||||
const toggleAgentList = usePanelStore((state) => state.toggleAgentList);
|
||||
const toggleFileExplorer = usePanelStore((state) => state.toggleFileExplorer);
|
||||
@@ -288,11 +289,11 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
||||
|
||||
const startDictationIfAvailable = useCallback(async () => {
|
||||
if (dictationUnavailableMessage) {
|
||||
Alert.alert("Dictation unavailable", dictationUnavailableMessage);
|
||||
toast.error(dictationUnavailableMessage);
|
||||
return;
|
||||
}
|
||||
await startDictation();
|
||||
}, [dictationUnavailableMessage, startDictation]);
|
||||
}, [dictationUnavailableMessage, startDictation, toast]);
|
||||
|
||||
// Cmd+D to start/submit dictation, Cmd+Shift+D toggles realtime voice, Escape cancels dictation
|
||||
useEffect(() => {
|
||||
@@ -324,8 +325,15 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
||||
}
|
||||
void voice.startVoice(voiceServerId, voiceAgentId).catch((error) => {
|
||||
console.error("[MessageInput] Failed to start realtime voice", error);
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
Alert.alert("Voice unavailable", message);
|
||||
const message =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: typeof error === "string"
|
||||
? error
|
||||
: null;
|
||||
if (message && message.trim().length > 0) {
|
||||
toast.error(message);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -396,6 +404,7 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
||||
isRealtimeVoiceForCurrentAgent,
|
||||
isScreenFocused,
|
||||
startDictationIfAvailable,
|
||||
toast,
|
||||
voiceAgentId,
|
||||
voiceServerId,
|
||||
voice,
|
||||
@@ -490,13 +499,21 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
||||
}
|
||||
void voice.startVoice(voiceServerId, voiceAgentId).catch((error) => {
|
||||
console.error("[MessageInput] Failed to start realtime voice", error);
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
Alert.alert("Voice unavailable", message);
|
||||
const message =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: typeof error === "string"
|
||||
? error
|
||||
: null;
|
||||
if (message && message.trim().length > 0) {
|
||||
toast.error(message);
|
||||
}
|
||||
});
|
||||
}, [
|
||||
disabled,
|
||||
handleStopRealtimeVoice,
|
||||
isConnected,
|
||||
toast,
|
||||
voice,
|
||||
voiceAgentId,
|
||||
voiceServerId,
|
||||
|
||||
Reference in New Issue
Block a user