mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-18 00:15:30 +01:00
🔀 refactor: Modularize TTS Logic for Improved Browser support (#3657)
* WIP: message audio refactor * WIP: use MessageAudio by provider * fix: Update MessageAudio component to use TTSEndpoints enum * feat: Update useTextToSpeechBrowser hook to handle errors and improve error logging * feat: Add voice dropdown components for different TTS engines * docs: update incorrect `voices` example changed `voice: ''` to `voices: ['alloy']` * feat: Add brwoser support check for Edge TTS engine component with error toast if not supported --------- Co-authored-by: Marco Beretta <81851188+berry-13@users.noreply.github.com>
This commit is contained in:
parent
bcde0beb47
commit
dba704079c
18 changed files with 784 additions and 187 deletions
|
|
@ -1,37 +1,21 @@
|
|||
import React from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import type { Option } from '~/common';
|
||||
import DropdownNoState from '~/components/ui/DropdownNoState';
|
||||
import { useLocalize, useTextToSpeech } from '~/hooks';
|
||||
import { logger } from '~/utils';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import {
|
||||
EdgeVoiceDropdown,
|
||||
BrowserVoiceDropdown,
|
||||
ExternalVoiceDropdown,
|
||||
} from '~/components/Audio/Voices';
|
||||
import store from '~/store';
|
||||
import { TTSEndpoints } from '~/common';
|
||||
|
||||
const voiceDropdownComponentsMap = {
|
||||
[TTSEndpoints.edge]: EdgeVoiceDropdown,
|
||||
[TTSEndpoints.browser]: BrowserVoiceDropdown,
|
||||
[TTSEndpoints.external]: ExternalVoiceDropdown,
|
||||
};
|
||||
|
||||
export default function VoiceDropdown() {
|
||||
const localize = useLocalize();
|
||||
const { voices = [] } = useTextToSpeech();
|
||||
const [voice, setVoice] = useRecoilState(store.voice);
|
||||
const engineTTS = useRecoilValue<string>(store.engineTTS);
|
||||
const VoiceDropdownComponent = voiceDropdownComponentsMap[engineTTS];
|
||||
|
||||
const handleVoiceChange = (newValue?: string | Option) => {
|
||||
logger.log('Voice changed:', newValue);
|
||||
const newVoice = typeof newValue === 'string' ? newValue : newValue?.value;
|
||||
if (newVoice != null) {
|
||||
return setVoice(newVoice.toString());
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between">
|
||||
<div>{localize('com_nav_voice_select')}</div>
|
||||
<DropdownNoState
|
||||
key={`voice-dropdown-${engineTTS}-${voices.length}`}
|
||||
value={voice}
|
||||
options={voices}
|
||||
onChange={handleVoiceChange}
|
||||
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
|
||||
anchor="bottom start"
|
||||
testId="VoiceDropdown"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
return <VoiceDropdownComponent />;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue