feat(dictation): add resilient rpc retries and status toasts
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { View, Text, Pressable, ActivityIndicator } from "react-native";
|
||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||
import { X, ArrowUp } from "lucide-react-native";
|
||||
import { X, ArrowUp, RefreshCcw } from "lucide-react-native";
|
||||
import { VolumeMeter } from "./volume-meter";
|
||||
import { FOOTER_HEIGHT } from "@/contexts/footer-controls-context";
|
||||
import type { DictationStatus } from "@/hooks/use-dictation";
|
||||
|
||||
interface VoiceNoteRecordingOverlayProps {
|
||||
volume: number;
|
||||
@@ -10,6 +11,9 @@ interface VoiceNoteRecordingOverlayProps {
|
||||
onCancel: () => void;
|
||||
onSend: () => void;
|
||||
isTranscribing?: boolean;
|
||||
status?: DictationStatus;
|
||||
onRetry?: () => void;
|
||||
onDiscardFailed?: () => void;
|
||||
}
|
||||
|
||||
function formatDuration(seconds: number): string {
|
||||
@@ -24,13 +28,25 @@ export function VoiceNoteRecordingOverlay({
|
||||
onCancel,
|
||||
onSend,
|
||||
isTranscribing = false,
|
||||
status = "idle",
|
||||
onRetry,
|
||||
onDiscardFailed,
|
||||
}: VoiceNoteRecordingOverlayProps) {
|
||||
const { theme } = useUnistyles();
|
||||
const isRetrying = status === "retrying";
|
||||
const isFailed = status === "failed";
|
||||
const primaryDisabled = isTranscribing || isRetrying;
|
||||
const handlePrimary = isFailed ? onRetry ?? onSend : onSend;
|
||||
const handleCancel = isFailed && onDiscardFailed ? onDiscardFailed : onCancel;
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor: theme.colors.palette.blue[600] }]}>
|
||||
{/* Cancel button */}
|
||||
<Pressable onPress={onCancel} disabled={isTranscribing} style={[styles.cancelButton, isTranscribing && styles.buttonDisabled]}>
|
||||
<Pressable
|
||||
onPress={handleCancel}
|
||||
disabled={isTranscribing}
|
||||
style={[styles.cancelButton, isTranscribing && styles.buttonDisabled]}
|
||||
>
|
||||
<X size={24} color={theme.colors.palette.white} strokeWidth={2.5} />
|
||||
</Pressable>
|
||||
|
||||
@@ -49,9 +65,17 @@ export function VoiceNoteRecordingOverlay({
|
||||
</View>
|
||||
|
||||
{/* Send button */}
|
||||
<Pressable onPress={onSend} disabled={isTranscribing} style={[styles.sendButton, { backgroundColor: theme.colors.palette.white }]}>
|
||||
{isTranscribing ? (
|
||||
<Pressable
|
||||
onPress={handlePrimary}
|
||||
disabled={primaryDisabled}
|
||||
style={[styles.sendButton, { backgroundColor: theme.colors.palette.white }, primaryDisabled && styles.buttonDisabled]}
|
||||
>
|
||||
{isRetrying ? (
|
||||
<ActivityIndicator size="small" color={theme.colors.palette.blue[600]} />
|
||||
) : isTranscribing ? (
|
||||
<ActivityIndicator size="small" color={theme.colors.palette.blue[600]} />
|
||||
) : isFailed ? (
|
||||
<RefreshCcw size={24} color={theme.colors.palette.blue[600]} strokeWidth={2.5} />
|
||||
) : (
|
||||
<ArrowUp size={24} color={theme.colors.palette.blue[600]} strokeWidth={2.5} />
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user