import type { Dispatch, SetStateAction } from "react"; import { useTranslation } from "react-i18next"; import { ProviderPicker } from "@/components/settings/shared/ModelControls"; import { NumberInput, RestartSettingsFooter, SettingsGroup, SettingsRow, SettingsSectionTitle, StatusPill, } from "@/components/settings/shared/SettingsControls"; import { ToggleButton } from "@/components/settings/ToggleButton"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import type { SettingsPayload, TranscriptionSettingsUpdate } from "@/lib/types"; export const DEFAULT_TRANSCRIPTION_FORM: TranscriptionSettingsUpdate = { enabled: true, provider: "groq", model: "", language: "", maxDurationSec: 120, maxUploadMb: 25, }; export const DEFAULT_TRANSCRIPTION_SETTINGS: NonNullable = { enabled: true, provider: "groq", provider_configured: false, model: "whisper-large-v3", language: null, max_duration_sec: 120, max_upload_mb: 25, providers: [], }; export function transcriptionFormFromPayload(payload: SettingsPayload): TranscriptionSettingsUpdate { const transcription = payload.transcription ?? DEFAULT_TRANSCRIPTION_SETTINGS; return { enabled: transcription.enabled, provider: transcription.provider, model: transcription.model, language: transcription.language ?? "", maxDurationSec: transcription.max_duration_sec, maxUploadMb: transcription.max_upload_mb, }; } export function TranscriptionSettings({ settings, form, dirty, saving, onChangeForm, onSave, onOpenProviders, showBrandLogos, onRestart, isRestarting, requiresRestartPending, }: { settings: SettingsPayload; form: TranscriptionSettingsUpdate; dirty: boolean; saving: boolean; onChangeForm: Dispatch>; onSave: () => void; onOpenProviders: () => void; showBrandLogos: boolean; onRestart?: () => void; isRestarting?: boolean; requiresRestartPending: boolean; }) { const { t } = useTranslation(); const tx = (key: string, fallback: string) => t(key, { defaultValue: fallback }); const transcription = settings.transcription ?? DEFAULT_TRANSCRIPTION_SETTINGS; const selectedProvider = transcription.providers.find((provider) => provider.name === form.provider) ?? transcription.providers[0]; const providerConfigured = !!selectedProvider?.configured; return (
{tx("settings.sections.voiceInput", "Voice input")} onChangeForm((prev) => ({ ...prev, enabled }))} ariaLabel={tx("settings.rows.transcription", "Transcription")} label={form.enabled ? tx("settings.values.on", "On") : tx("settings.values.off", "Off")} /> onChangeForm((prev) => ({ ...prev, provider }))} />
{providerConfigured ? tx("settings.values.configured", "Configured") : tx("settings.values.notConfigured", "Not configured")} {!providerConfigured ? ( ) : null}
onChangeForm((prev) => ({ ...prev, model: event.target.value }))} className="h-8 w-[min(300px,70vw)] rounded-full text-[13px]" /> onChangeForm((prev) => ({ ...prev, language: event.target.value }))} placeholder={tx("settings.voice.languageAuto", "Auto")} className="h-8 w-[min(180px,60vw)] rounded-full text-[13px]" />
onChangeForm((prev) => ({ ...prev, maxDurationSec }))} /> onChangeForm((prev) => ({ ...prev, maxUploadMb }))} />
); }