diff --git a/ui/desktop/src/components/settings/dictation/DictationSettings.tsx b/ui/desktop/src/components/settings/dictation/DictationSettings.tsx index a24acf04f33f..00ef58b227ab 100644 --- a/ui/desktop/src/components/settings/dictation/DictationSettings.tsx +++ b/ui/desktop/src/components/settings/dictation/DictationSettings.tsx @@ -7,12 +7,18 @@ import { Button } from '../../ui/button'; import { trackSettingToggled } from '../../../utils/analytics'; import { LocalModelManager } from './LocalModelManager'; import { DICTATION_ALL_PROVIDERS_ENABLED } from '../../../updates'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuTrigger, +} from '../../ui/dropdown-menu'; const CORE_PROVIDERS: DictationProvider[] = ['openai', 'local']; export const DictationSettings = () => { const [provider, setProvider] = useState(null); - const [showProviderDropdown, setShowProviderDropdown] = useState(false); const [providerStatuses, setProviderStatuses] = useState>( {} ); @@ -20,6 +26,11 @@ export const DictationSettings = () => { const [isEditingKey, setIsEditingKey] = useState(false); const { read, upsert, remove } = useConfig(); + const refreshStatuses = async () => { + const audioConfig = await getDictationConfig(); + setProviderStatuses(audioConfig.data || {}); + }; + useEffect(() => { const loadSettings = async () => { const providerValue = await read('voice_dictation_provider', false); @@ -35,36 +46,19 @@ export const DictationSettings = () => { } setProvider(loadedProvider); - - const audioConfig = await getDictationConfig(); - setProviderStatuses(audioConfig.data || {}); + await refreshStatuses(); }; loadSettings(); }, [read, upsert]); - const saveProvider = async (newProvider: DictationProvider | null) => { - console.log('Saving dictation provider to backend config:', newProvider); + const handleProviderChange = (value: string) => { + const newProvider = value === 'disabled' ? null : (value as DictationProvider); setProvider(newProvider); - await upsert('voice_dictation_provider', newProvider || '', false); + upsert('voice_dictation_provider', newProvider || '', false); trackSettingToggled('voice_dictation', newProvider !== null); }; - const handleProviderChange = (newProvider: DictationProvider | null) => { - saveProvider(newProvider); - setShowProviderDropdown(false); - }; - - const handleDropdownToggle = async () => { - const newShowState = !showProviderDropdown; - setShowProviderDropdown(newShowState); - - if (newShowState) { - const audioConfig = await getDictationConfig(); - setProviderStatuses(audioConfig.data || {}); - } - }; - const handleSaveKey = async () => { if (!provider) return; const providerConfig = providerStatuses[provider]; @@ -77,9 +71,7 @@ export const DictationSettings = () => { await upsert(keyName, trimmedKey, true); setApiKey(''); setIsEditingKey(false); - - const audioConfig = await getDictationConfig(); - setProviderStatuses(audioConfig.data || {}); + await refreshStatuses(); }; const handleRemoveKey = async () => { @@ -91,9 +83,7 @@ export const DictationSettings = () => { await remove(keyName, true); setApiKey(''); setIsEditingKey(false); - - const audioConfig = await getDictationConfig(); - setProviderStatuses(audioConfig.data || {}); + await refreshStatuses(); }; const handleCancelEdit = () => { @@ -101,11 +91,15 @@ export const DictationSettings = () => { setIsEditingKey(false); }; - const getProviderLabel = (provider: DictationProvider | null): string => { - if (!provider) return 'Disabled'; - return provider.charAt(0).toUpperCase() + provider.slice(1); + const getProviderLabel = (p: DictationProvider | null): string => { + if (!p) return 'Disabled'; + return p.charAt(0).toUpperCase() + p.slice(1); }; + const visibleProviders = (Object.keys(providerStatuses) as DictationProvider[]).filter( + (p) => DICTATION_ALL_PROVIDERS_ENABLED || CORE_PROVIDERS.includes(p) + ); + return (
@@ -115,49 +109,28 @@ export const DictationSettings = () => { Choose how voice is converted to text

-
- - - {showProviderDropdown && ( -
- - - {(Object.keys(providerStatuses) as DictationProvider[]) - .filter((p) => DICTATION_ALL_PROVIDERS_ENABLED || CORE_PROVIDERS.includes(p)) - .map((p) => ( - - ))} -
- )} -
+ + + + Disabled + {visibleProviders.map((p) => ( + + {getProviderLabel(p)} + {!providerStatuses[p]?.configured && ( + (not configured) + )} + + ))} + + +
{provider && providerStatuses[provider] && (