| import React from 'react'; |
| import { useRecoilState } from 'recoil'; |
| import { Dropdown } from '@librechat/client'; |
| import type { Option } from '~/common'; |
| import { useLocalize, useTTSBrowser, useTTSExternal } from '~/hooks'; |
| import { logger } from '~/utils'; |
| import store from '~/store'; |
|
|
| export function BrowserVoiceDropdown() { |
| const localize = useLocalize(); |
| const { voices = [] } = useTTSBrowser(); |
| const [voice, setVoice] = useRecoilState(store.voice); |
|
|
| const handleVoiceChange = (newValue?: string | Option) => { |
| logger.log('Browser Voice changed:', newValue); |
| const newVoice = typeof newValue === 'string' ? newValue : newValue?.value; |
| if (newVoice != null) { |
| return setVoice(newVoice.toString()); |
| } |
| }; |
|
|
| const labelId = 'browser-voice-dropdown-label'; |
|
|
| return ( |
| <div className="flex items-center justify-between"> |
| <div id={labelId}>{localize('com_nav_voice_select')}</div> |
| <Dropdown |
| key={`browser-voice-dropdown-${voices.length}`} |
| value={voice ?? ''} |
| options={voices} |
| onChange={handleVoiceChange} |
| sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]" |
| testId="BrowserVoiceDropdown" |
| className="z-50" |
| aria-labelledby={labelId} |
| /> |
| </div> |
| ); |
| } |
|
|
| export function ExternalVoiceDropdown() { |
| const localize = useLocalize(); |
| const { voices = [] } = useTTSExternal(); |
| const [voice, setVoice] = useRecoilState(store.voice); |
|
|
| const handleVoiceChange = (newValue?: string | Option) => { |
| logger.log('External Voice changed:', newValue); |
| const newVoice = typeof newValue === 'string' ? newValue : newValue?.value; |
| if (newVoice != null) { |
| return setVoice(newVoice.toString()); |
| } |
| }; |
|
|
| const labelId = 'external-voice-dropdown-label'; |
|
|
| return ( |
| <div className="flex items-center justify-between"> |
| <div id={labelId}>{localize('com_nav_voice_select')}</div> |
| <Dropdown |
| key={`external-voice-dropdown-${voices.length}`} |
| value={voice ?? ''} |
| options={voices} |
| onChange={handleVoiceChange} |
| sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]" |
| testId="ExternalVoiceDropdown" |
| className="z-50" |
| aria-labelledby={labelId} |
| /> |
| </div> |
| ); |
| } |
|
|