🌐 feat: disable external engine if not configured (#3313)

* feat: disable external engine if not configured

* remove comment
This commit is contained in:
Marco Beretta 2024-07-17 16:08:43 +02:00 committed by GitHub
parent 237a0de8b6
commit 73dbf3eb20
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 71 additions and 34 deletions

View file

@ -15,37 +15,43 @@ const getCustomConfig = require('~/server/services/Config/getCustomConfig');
async function getCustomConfigSpeech(req, res) {
try {
const customConfig = await getCustomConfig();
const sttExternal = !!customConfig.speech?.stt;
const ttsExternal = !!customConfig.speech?.tts;
let settings = {
sttExternal,
ttsExternal,
};
if (!customConfig || !customConfig.speech?.speechTab) {
throw new Error('Configuration or speechTab schema is missing');
return res.status(200).send(settings);
}
const ttsSchema = customConfig.speech?.speechTab;
let settings = {};
const speechTab = customConfig.speech.speechTab;
if (ttsSchema.advancedMode !== undefined) {
settings.advancedMode = ttsSchema.advancedMode;
if (speechTab.advancedMode !== undefined) {
settings.advancedMode = speechTab.advancedMode;
}
if (ttsSchema.speechToText) {
for (const key in ttsSchema.speechToText) {
if (ttsSchema.speechToText[key] !== undefined) {
settings[key] = ttsSchema.speechToText[key];
if (speechTab.speechToText) {
for (const key in speechTab.speechToText) {
if (speechTab.speechToText[key] !== undefined) {
settings[key] = speechTab.speechToText[key];
}
}
}
if (ttsSchema.textToSpeech) {
for (const key in ttsSchema.textToSpeech) {
if (ttsSchema.textToSpeech[key] !== undefined) {
settings[key] = ttsSchema.textToSpeech[key];
if (speechTab.textToSpeech) {
for (const key in speechTab.textToSpeech) {
if (speechTab.textToSpeech[key] !== undefined) {
settings[key] = speechTab.textToSpeech[key];
}
}
}
return res.status(200).send(settings);
} catch (error) {
res.status(200).send();
console.error('Failed to get custom config speech settings:', error);
res.status(500).send('Internal Server Error');
}
}

View file

@ -1,15 +1,23 @@
import React from 'react';
import { useRecoilState } from 'recoil';
import { Dropdown } from '~/components/ui';
import { useLocalize } from '~/hooks';
import store from '~/store';
export default function EngineSTTDropdown() {
interface EngineSTTDropdownProps {
external: boolean;
}
const EngineSTTDropdown: React.FC<EngineSTTDropdownProps> = ({ external }) => {
const localize = useLocalize();
const [engineSTT, setEngineSTT] = useRecoilState<string>(store.engineSTT);
const endpointOptions = [
{ value: 'browser', display: localize('com_nav_browser') },
{ value: 'external', display: localize('com_nav_external') },
];
const endpointOptions = external
? [
{ value: 'browser', display: localize('com_nav_browser') },
{ value: 'external', display: localize('com_nav_external') },
]
: [{ value: 'browser', display: localize('com_nav_browser') }];
const handleSelect = (value: string) => {
setEngineSTT(value);
@ -28,4 +36,6 @@ export default function EngineSTTDropdown() {
/>
</div>
);
}
};
export default EngineSTTDropdown;

View file

@ -31,6 +31,8 @@ function Speech() {
const { data } = useGetCustomConfigSpeechQuery();
const isSmallScreen = useMediaQuery('(max-width: 767px)');
const [sttExternal, setSttExternal] = useState(false);
const [ttsExternal, setTtsExternal] = useState(false);
const [advancedMode, setAdvancedMode] = useRecoilState(store.advancedMode);
const [autoTranscribeAudio, setAutoTranscribeAudio] = useRecoilState(store.autoTranscribeAudio);
const [conversationMode, setConversationMode] = useRecoilState(store.conversationMode);
@ -53,6 +55,8 @@ function Speech() {
const updateSetting = useCallback(
(key, newValue) => {
const settings = {
sttExternal: { value: sttExternal, setFunc: setSttExternal },
ttsExternal: { value: ttsExternal, setFunc: setTtsExternal },
conversationMode: { value: conversationMode, setFunc: setConversationMode },
advancedMode: { value: advancedMode, setFunc: setAdvancedMode },
speechToText: { value: speechToText, setFunc: setSpeechToText },
@ -79,6 +83,8 @@ function Speech() {
setting.setFunc(newValue);
},
[
sttExternal,
ttsExternal,
conversationMode,
advancedMode,
speechToText,
@ -95,6 +101,8 @@ function Speech() {
languageTTS,
automaticPlayback,
playbackRate,
setSttExternal,
setTtsExternal,
setConversationMode,
setAdvancedMode,
setSpeechToText,
@ -123,6 +131,9 @@ function Speech() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data]);
console.log(sttExternal);
console.log(ttsExternal);
const contentRef = useRef(null);
useOnClickOutside(contentRef, () => confirmClear && setConfirmClear(false), []);
@ -175,21 +186,21 @@ function Speech() {
<Tabs.Content value={'simple'}>
<div className="flex flex-col gap-3 text-sm text-black dark:text-gray-50">
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<SpeechToTextSwitch />
</div>
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<EngineSTTDropdown />
<EngineSTTDropdown external={sttExternal} />
</div>
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<LanguageSTTDropdown />
</div>
<div className="h-px bg-black/20 bg-white/20" role="none" />
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<TextToSpeechSwitch />
</div>
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<EngineTTSDropdown />
<EngineTTSDropdown external={ttsExternal} />
</div>
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<VoiceDropdown />
@ -199,15 +210,15 @@ function Speech() {
<Tabs.Content value={'advanced'}>
<div className="flex flex-col gap-3 text-sm text-black dark:text-gray-50">
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<ConversationModeSwitch />
</div>
<div className="h-px bg-black/20 bg-white/20" role="none" />
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<SpeechToTextSwitch />
</div>
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<EngineSTTDropdown />
<EngineSTTDropdown external={sttExternal} />
</div>
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<LanguageSTTDropdown />
@ -231,7 +242,7 @@ function Speech() {
<AutomaticPlaybackSwitch />
</div>
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<EngineTTSDropdown />
<EngineTTSDropdown external={ttsExternal} />
</div>
<div className="border-b last-of-type:border-b-0 dark:border-gray-700">
<VoiceDropdown />

View file

@ -1,15 +1,23 @@
import React from 'react';
import { useRecoilState } from 'recoil';
import { Dropdown } from '~/components/ui';
import { useLocalize } from '~/hooks';
import store from '~/store';
export default function EngineTTSDropdown() {
interface EngineTTSDropdownProps {
external: boolean;
}
const EngineTTSDropdown: React.FC<EngineTTSDropdownProps> = ({ external }) => {
const localize = useLocalize();
const [engineTTS, setEngineTTS] = useRecoilState<string>(store.engineTTS);
const endpointOptions = [
{ value: 'browser', display: localize('com_nav_browser') },
{ value: 'external', display: localize('com_nav_external') },
];
const endpointOptions = external
? [
{ value: 'browser', display: localize('com_nav_browser') },
{ value: 'external', display: localize('com_nav_external') },
]
: [{ value: 'browser', display: localize('com_nav_browser') }];
const handleSelect = (value: string) => {
setEngineTTS(value);
@ -28,4 +36,6 @@ export default function EngineTTSDropdown() {
/>
</div>
);
}
};
export default EngineTTSDropdown;