diff --git a/client/src/components/Chat/Input/AutoPlayAudio.tsx b/client/src/components/Chat/Input/AutoPlayAudio.tsx new file mode 100644 index 0000000000..7cc5e4a66b --- /dev/null +++ b/client/src/components/Chat/Input/AutoPlayAudio.tsx @@ -0,0 +1,34 @@ +import { memo } from 'react'; +import { useRecoilValue } from 'recoil'; +import BrowserAudio from './BrowserAudio'; +import StreamAudio from './StreamAudio'; +import { TTSEndpoints } from '~/common'; +import store from '~/store'; + +/** + * Mount point for "Autoplay Latest Message". Playback has to honor the selected TTS engine + * the same way the message speaker button does, otherwise the Browser engine silently falls + * through to the external endpoint and never reaches the Web Speech API. + */ +function AutoPlayAudio({ index = 0 }) { + const engineTTS = useRecoilValue(store.engineTTS); + const speechSettingsInitialized = useRecoilValue(store.speechSettingsInitialized); + + if (!speechSettingsInitialized) { + return null; + } + + const AutoPlayComponents = { + [TTSEndpoints.browser]: BrowserAudio, + [TTSEndpoints.external]: StreamAudio, + }; + + const SelectedAutoPlay = AutoPlayComponents[engineTTS]; + if (!SelectedAutoPlay) { + return null; + } + + return ; +} + +export default memo(AutoPlayAudio); diff --git a/client/src/components/Chat/Input/BrowserAudio.tsx b/client/src/components/Chat/Input/BrowserAudio.tsx new file mode 100644 index 0000000000..262310f7b2 --- /dev/null +++ b/client/src/components/Chat/Input/BrowserAudio.tsx @@ -0,0 +1,57 @@ +import { useEffect } from 'react'; +import { useSetRecoilState } from 'recoil'; +import { useParams } from 'react-router-dom'; +import { parseTextParts } from 'librechat-data-provider'; +import useTextToSpeechBrowser from '~/hooks/Input/useTextToSpeechBrowser'; +import useAutoplayTrigger from '~/hooks/Audio/useAutoplayTrigger'; +import { logger } from '~/utils'; +import store from '~/store'; + +/** + * Autoplay driver for the Browser TTS engine. `StreamAudio` covers the external engine by + * streaming server audio into the global `