mirror of
https://github.com/jambonz/jambonz-webapp.git
synced 2026-07-24 21:12:26 +00:00
feat: custom Vendor (#215)
* feat: custom Vendor * feat: custom Vendor * fix: application with custom tts/stt vendor * fix custom speech name when editing * fix: all comments * fix: remove custom in the list and show extra (custom) * fix: prettier and application sythesizer selector * fix: addd VITE_DISABLE_CUSTOM_SPEECH --------- Co-authored-by: Quan HL <quanluuhoang8@gmail.com>
This commit is contained in:
@@ -28,6 +28,11 @@ export const API_BASE_URL =
|
||||
/** Serves mock API responses from a local dev API server */
|
||||
export const DEV_BASE_URL = import.meta.env.VITE_DEV_BASE_URL;
|
||||
|
||||
/** Disable custom speech vendor*/
|
||||
export const DISABLE_CUSTOM_SPEECH: boolean = JSON.parse(
|
||||
import.meta.env.VITE_DISABLE_CUSTOM_SPEECH || "false"
|
||||
);
|
||||
|
||||
/** TCP Max Port */
|
||||
export const TCP_MAX_PORT = 65535;
|
||||
|
||||
|
||||
@@ -309,6 +309,9 @@ export interface SpeechCredential {
|
||||
stt_region: null | string;
|
||||
instance_id: null | string;
|
||||
riva_server_uri: null | string;
|
||||
auth_token: null | string;
|
||||
custom_stt_url: null | string;
|
||||
custom_tts_url: null | string;
|
||||
}
|
||||
|
||||
export interface Alert {
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
useSpeechVendors,
|
||||
VENDOR_DEEPGRAM,
|
||||
VENDOR_SONIOX,
|
||||
VENDOR_CUSTOM,
|
||||
} from "src/vendor";
|
||||
import {
|
||||
postApplication,
|
||||
@@ -40,6 +41,7 @@ import type {
|
||||
Voice,
|
||||
VoiceLanguage,
|
||||
Language,
|
||||
VendorOptions,
|
||||
} from "src/vendor/types";
|
||||
|
||||
import type {
|
||||
@@ -48,9 +50,10 @@ import type {
|
||||
Application,
|
||||
WebhookMethod,
|
||||
UseApiDataMap,
|
||||
SpeechCredential,
|
||||
} from "src/api/types";
|
||||
import { MSG_REQUIRED_FIELDS, MSG_WEBHOOK_FIELDS } from "src/constants";
|
||||
import { isUserAccountScope, useRedirect } from "src/utils";
|
||||
import { hasLength, isUserAccountScope, useRedirect } from "src/utils";
|
||||
import { setAccountFilter, setLocation } from "src/store/localStore";
|
||||
|
||||
type ApplicationFormProps = {
|
||||
@@ -83,6 +86,10 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
useState<keyof RecognizerVendors>(VENDOR_GOOGLE);
|
||||
const [recogLang, setRecogLang] = useState(LANG_EN_US);
|
||||
const [message, setMessage] = useState("");
|
||||
const [apiUrl, setApiUrl] = useState("");
|
||||
const [credentials] = useApiData<SpeechCredential[]>(apiUrl);
|
||||
const [softTtsVendor, setSoftTtsVendor] = useState<VendorOptions[]>(vendors);
|
||||
const [softSttVendor, setSoftSttVendor] = useState<VendorOptions[]>(vendors);
|
||||
|
||||
/** This lets us map and render the same UI for each... */
|
||||
const webhooks = [
|
||||
@@ -186,6 +193,40 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (credentials && hasLength(credentials)) {
|
||||
const v = credentials
|
||||
.filter((tv) => tv.vendor.startsWith(VENDOR_CUSTOM) && tv.use_for_tts)
|
||||
.map((tv) =>
|
||||
Object.assign({
|
||||
name:
|
||||
tv.vendor.substring(VENDOR_CUSTOM.length + 1) +
|
||||
` (${VENDOR_CUSTOM})`,
|
||||
value: tv.vendor,
|
||||
})
|
||||
);
|
||||
setSoftTtsVendor(vendors.concat(v));
|
||||
|
||||
const v2 = credentials
|
||||
.filter((tv) => tv.vendor.startsWith(VENDOR_CUSTOM) && tv.use_for_stt)
|
||||
.map((tv) =>
|
||||
Object.assign({
|
||||
name:
|
||||
tv.vendor.substring(VENDOR_CUSTOM.length + 1) +
|
||||
` (${VENDOR_CUSTOM})`,
|
||||
value: tv.vendor,
|
||||
})
|
||||
);
|
||||
setSoftSttVendor(vendors.concat(v2));
|
||||
}
|
||||
}, [credentials]);
|
||||
|
||||
useEffect(() => {
|
||||
if (accountSid) {
|
||||
setApiUrl(`Accounts/${accountSid}/SpeechCredentials`);
|
||||
}
|
||||
}, [accountSid]);
|
||||
|
||||
useEffect(() => {
|
||||
setLocation();
|
||||
if (application && application.data) {
|
||||
@@ -382,15 +423,22 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
id="synthesis_vendor"
|
||||
name="synthesis_vendor"
|
||||
value={synthVendor}
|
||||
options={vendors.filter(
|
||||
options={softTtsVendor.filter(
|
||||
(vendor) =>
|
||||
vendor.value != VENDOR_DEEPGRAM &&
|
||||
vendor.value != VENDOR_SONIOX
|
||||
vendor.value != VENDOR_SONIOX &&
|
||||
vendor.value !== VENDOR_CUSTOM
|
||||
)}
|
||||
onChange={(e) => {
|
||||
const vendor = e.target.value as keyof SynthesisVendors;
|
||||
setSynthVendor(vendor);
|
||||
|
||||
/** When Custom Vendor is used, user you have to input the lange and voice. */
|
||||
if (vendor.toString().startsWith(VENDOR_CUSTOM)) {
|
||||
setSynthVoice("");
|
||||
return;
|
||||
}
|
||||
|
||||
/** When using Google and en-US, ensure "Standard-C" is used as default */
|
||||
if (
|
||||
e.target.value === VENDOR_GOOGLE &&
|
||||
@@ -419,55 +467,88 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
setSynthVoice(newLang!.voices[0].value);
|
||||
}}
|
||||
/>
|
||||
{synthVendor && synthLang && (
|
||||
<>
|
||||
<label htmlFor="synthesis_lang">Language</label>
|
||||
<Selector
|
||||
id="synthesis_lang"
|
||||
name="synthesis_lang"
|
||||
value={synthLang}
|
||||
options={synthesis[synthVendor as keyof SynthesisVendors].map(
|
||||
(lang: VoiceLanguage) => ({
|
||||
{synthVendor &&
|
||||
!synthVendor.toString().startsWith(VENDOR_CUSTOM) &&
|
||||
synthLang && (
|
||||
<>
|
||||
<label htmlFor="synthesis_lang">Language</label>
|
||||
<Selector
|
||||
id="synthesis_lang"
|
||||
name="synthesis_lang"
|
||||
value={synthLang}
|
||||
options={synthesis[
|
||||
synthVendor as keyof SynthesisVendors
|
||||
].map((lang: VoiceLanguage) => ({
|
||||
name: lang.name,
|
||||
value: lang.code,
|
||||
})
|
||||
)}
|
||||
onChange={(e) => {
|
||||
const language = e.target.value;
|
||||
setSynthLang(language);
|
||||
}))}
|
||||
onChange={(e) => {
|
||||
const language = e.target.value;
|
||||
setSynthLang(language);
|
||||
|
||||
/** When using Google and en-US, ensure "Standard-C" is used as default */
|
||||
if (
|
||||
synthVendor === VENDOR_GOOGLE &&
|
||||
language === LANG_EN_US
|
||||
) {
|
||||
setSynthVoice(LANG_EN_US_STANDARD_C);
|
||||
return;
|
||||
/** When using Google and en-US, ensure "Standard-C" is used as default */
|
||||
if (
|
||||
synthVendor === VENDOR_GOOGLE &&
|
||||
language === LANG_EN_US
|
||||
) {
|
||||
setSynthVoice(LANG_EN_US_STANDARD_C);
|
||||
return;
|
||||
}
|
||||
|
||||
const newLang = synthesis[
|
||||
synthVendor as keyof SynthesisVendors
|
||||
].find((lang) => lang.code === language);
|
||||
|
||||
setSynthVoice(newLang!.voices[0].value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="synthesis_voice">Voice</label>
|
||||
<Selector
|
||||
id="synthesis_voice"
|
||||
name="synthesis_voice"
|
||||
value={synthVoice}
|
||||
options={
|
||||
synthesis[synthVendor as keyof SynthesisVendors]
|
||||
.filter(
|
||||
(lang: VoiceLanguage) => lang.code === synthLang
|
||||
)
|
||||
.flatMap((lang: VoiceLanguage) =>
|
||||
lang.voices.map((voice: Voice) => ({
|
||||
name: voice.name,
|
||||
value: voice.value,
|
||||
}))
|
||||
) as Voice[]
|
||||
}
|
||||
|
||||
const newLang = synthesis[
|
||||
synthVendor as keyof SynthesisVendors
|
||||
].find((lang) => lang.code === language);
|
||||
|
||||
setSynthVoice(newLang!.voices[0].value);
|
||||
onChange={(e) => setSynthVoice(e.target.value)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{synthVendor.toString().startsWith(VENDOR_CUSTOM) && (
|
||||
<>
|
||||
<label htmlFor="custom_vendor_synthesis_lang">Language</label>
|
||||
<input
|
||||
id="custom_vendor_synthesis_lang"
|
||||
type="text"
|
||||
name="custom_vendor_synthesis_lang"
|
||||
placeholder="Required"
|
||||
required
|
||||
value={synthLang}
|
||||
onChange={(e) => {
|
||||
setSynthLang(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="synthesis_voice">Voice</label>
|
||||
<Selector
|
||||
id="synthesis_voice"
|
||||
name="synthesis_voice"
|
||||
|
||||
<label htmlFor="custom_vendor_synthesis_voice">Voice</label>
|
||||
<input
|
||||
id="custom_vendor_synthesis_voice"
|
||||
type="text"
|
||||
name="custom_vendor_synthesis_voice"
|
||||
placeholder="Required"
|
||||
required
|
||||
value={synthVoice}
|
||||
options={
|
||||
synthesis[synthVendor as keyof SynthesisVendors]
|
||||
.filter((lang: VoiceLanguage) => lang.code === synthLang)
|
||||
.flatMap((lang: VoiceLanguage) =>
|
||||
lang.voices.map((voice: Voice) => ({
|
||||
name: voice.name,
|
||||
value: voice.value,
|
||||
}))
|
||||
) as Voice[]
|
||||
}
|
||||
onChange={(e) => setSynthVoice(e.target.value)}
|
||||
onChange={(e) => {
|
||||
setSynthVoice(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@@ -480,13 +561,18 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
id="recognizer_vendor"
|
||||
name="recognizer_vendor"
|
||||
value={recogVendor}
|
||||
options={vendors.filter(
|
||||
(vendor) => vendor.value != VENDOR_WELLSAID
|
||||
options={softSttVendor.filter(
|
||||
(vendor) =>
|
||||
vendor.value != VENDOR_WELLSAID &&
|
||||
vendor.value !== VENDOR_CUSTOM
|
||||
)}
|
||||
onChange={(e) => {
|
||||
const vendor = e.target.value as keyof RecognizerVendors;
|
||||
setRecogVendor(vendor);
|
||||
|
||||
/**When vendor is custom, Language is input by user */
|
||||
if (vendor.toString() === VENDOR_CUSTOM) return;
|
||||
|
||||
/** Google and AWS have different language lists */
|
||||
/** If the new language doesn't map then default to "en-US" */
|
||||
const newLang = recognizers[vendor].find(
|
||||
@@ -501,19 +587,37 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{recogVendor && recogLang && (
|
||||
{recogVendor &&
|
||||
!recogVendor.toString().startsWith(VENDOR_CUSTOM) &&
|
||||
recogLang && (
|
||||
<>
|
||||
<label htmlFor="recognizer_lang">Language</label>
|
||||
<Selector
|
||||
id="recognizer_lang"
|
||||
name="recognizer_lang"
|
||||
value={recogLang}
|
||||
options={recognizers[
|
||||
recogVendor as keyof RecognizerVendors
|
||||
].map((lang: Language) => ({
|
||||
name: lang.name,
|
||||
value: lang.code,
|
||||
}))}
|
||||
onChange={(e) => {
|
||||
setRecogLang(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{recogVendor.toString().startsWith(VENDOR_CUSTOM) && (
|
||||
<>
|
||||
<label htmlFor="recognizer_lang">Language</label>
|
||||
<Selector
|
||||
id="recognizer_lang"
|
||||
name="recognizer_lang"
|
||||
<label htmlFor="custom_vendor_recognizer_voice">Language</label>
|
||||
<input
|
||||
id="custom_vendor_recognizer_voice"
|
||||
type="text"
|
||||
name="custom_vendor_recognizer_voice"
|
||||
placeholder="Required"
|
||||
required
|
||||
value={recogLang}
|
||||
options={recognizers[
|
||||
recogVendor as keyof RecognizerVendors
|
||||
].map((lang: Language) => ({
|
||||
name: lang.name,
|
||||
value: lang.code,
|
||||
}))}
|
||||
onChange={(e) => {
|
||||
setRecogLang(e.target.value);
|
||||
}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import { Button, ButtonGroup, MS } from "@jambonz/ui-kit";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Selector,
|
||||
Passwd,
|
||||
AccountSelect,
|
||||
Checkzone,
|
||||
} from "src/components/forms";
|
||||
import { toastError, toastSuccess, useSelectState } from "src/store";
|
||||
import {
|
||||
@@ -28,6 +29,7 @@ import {
|
||||
VENDOR_IBM,
|
||||
VENDOR_NVIDIA,
|
||||
VENDOR_SONIOX,
|
||||
VENDOR_CUSTOM,
|
||||
} from "src/vendor";
|
||||
import { MSG_REQUIRED_FIELDS } from "src/constants";
|
||||
import {
|
||||
@@ -41,6 +43,7 @@ import { CredentialStatus } from "./status";
|
||||
import type { RegionVendors, GoogleServiceKey, Vendor } from "src/vendor/types";
|
||||
import type { Account, SpeechCredential, UseApiDataMap } from "src/api/types";
|
||||
import { setAccountFilter, setLocation } from "src/store/localStore";
|
||||
import { DISABLE_CUSTOM_SPEECH } from "src/api/constants";
|
||||
|
||||
type SpeechServiceFormProps = {
|
||||
credential?: UseApiDataMap<SpeechCredential>;
|
||||
@@ -53,7 +56,9 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
const regions = useRegionVendors();
|
||||
const [accounts] = useServiceProviderData<Account[]>("Accounts");
|
||||
const [accountSid, setAccountSid] = useState("");
|
||||
const [initialTtsCheck, setInitialTtsCheck] = useState(false);
|
||||
const [ttsCheck, setTtsCheck] = useState(false);
|
||||
const [initialSttCheck, setInitialSttCheck] = useState(false);
|
||||
const [sttCheck, setSttCheck] = useState(false);
|
||||
const [vendor, setVendor] = useState<Lowercase<Vendor>>(
|
||||
"" as Lowercase<Vendor>
|
||||
@@ -78,6 +83,12 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
const [customSttEndpoint, setCustomSttEndpoint] = useState("");
|
||||
const [tmpCustomSttEndpoint, setTmpCustomSttEndpoint] = useState("");
|
||||
const [rivaServerUri, setRivaServerUri] = useState("");
|
||||
const [customVendorName, setCustomVendorName] = useState("");
|
||||
const [customVendorAuthToken, setCustomVendorAuthToken] = useState("");
|
||||
const [tmpCustomVendorTtsUrl, setTmpCustomVendorTtsUrl] = useState("");
|
||||
const [customVendorTtsUrl, setCustomVendorTtsUrl] = useState("");
|
||||
const [tmpCustomVendorSttUrl, setTmpCustomVendorSttUrl] = useState("");
|
||||
const [customVendorSttUrl, setCustomVendorSttUrl] = useState("");
|
||||
|
||||
const handleFile = (file: File) => {
|
||||
const handleError = () => {
|
||||
@@ -142,6 +153,14 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
...(vendor === VENDOR_NVIDIA && {
|
||||
riva_server_uri: rivaServerUri || null,
|
||||
}),
|
||||
...(vendor === VENDOR_CUSTOM && {
|
||||
vendor: (vendor + ":" + customVendorName) as Lowercase<Vendor>,
|
||||
use_for_tts: ttsCheck ? 1 : 0,
|
||||
use_for_stt: sttCheck ? 1 : 0,
|
||||
custom_tts_url: customVendorTtsUrl || null,
|
||||
custom_stt_url: customVendorSttUrl || null,
|
||||
auth_token: customVendorAuthToken || null,
|
||||
}),
|
||||
};
|
||||
|
||||
if (credential && credential.data) {
|
||||
@@ -198,7 +217,10 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
setLocation();
|
||||
if (credential && credential.data) {
|
||||
if (credential.data.vendor) {
|
||||
setVendor(credential.data.vendor);
|
||||
const v = credential.data.vendor.startsWith(VENDOR_CUSTOM)
|
||||
? VENDOR_CUSTOM
|
||||
: vendor;
|
||||
setVendor(v);
|
||||
}
|
||||
|
||||
if (credential.data.account_sid) {
|
||||
@@ -207,14 +229,18 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
|
||||
if (credential.data.use_for_stt) {
|
||||
setSttCheck(true);
|
||||
setInitialSttCheck(true);
|
||||
} else {
|
||||
setSttCheck(false);
|
||||
setInitialSttCheck(false);
|
||||
}
|
||||
|
||||
if (credential.data.use_for_tts) {
|
||||
setTtsCheck(true);
|
||||
setInitialTtsCheck(true);
|
||||
} else {
|
||||
setTtsCheck(false);
|
||||
setInitialTtsCheck(false);
|
||||
}
|
||||
|
||||
if (credential.data.service_key) {
|
||||
@@ -279,6 +305,16 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
setCustomSttEndpoint(credential.data.custom_stt_endpoint || "");
|
||||
setTmpCustomTtsEndpoint(credential.data.custom_tts_endpoint || "");
|
||||
setTmpCustomSttEndpoint(credential.data.custom_stt_endpoint || "");
|
||||
setCustomVendorName(
|
||||
credential.data.vendor.startsWith(VENDOR_CUSTOM)
|
||||
? credential.data.vendor.substring(VENDOR_CUSTOM.length + 1)
|
||||
: credential.data.vendor
|
||||
);
|
||||
setCustomVendorAuthToken(credential.data.auth_token || "");
|
||||
setCustomVendorSttUrl(credential.data.custom_stt_url || "");
|
||||
setTmpCustomVendorSttUrl(credential.data.custom_stt_url || "");
|
||||
setCustomVendorTtsUrl(credential.data.custom_tts_url || "");
|
||||
setTmpCustomVendorTtsUrl(credential.data.custom_tts_url || "");
|
||||
}
|
||||
}, [credential]);
|
||||
|
||||
@@ -307,7 +343,11 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
name: "Select a vendor",
|
||||
value: "",
|
||||
},
|
||||
].concat(vendors)}
|
||||
]
|
||||
.concat(vendors)
|
||||
.filter(
|
||||
(v) => !DISABLE_CUSTOM_SPEECH || v.value !== VENDOR_CUSTOM
|
||||
)}
|
||||
onChange={(e) => {
|
||||
setVendor(e.target.value as Lowercase<Vendor>);
|
||||
setRegion("");
|
||||
@@ -317,6 +357,23 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
disabled={credential ? true : false}
|
||||
required
|
||||
/>
|
||||
{vendor === VENDOR_CUSTOM && (
|
||||
<>
|
||||
<label htmlFor="custom_vendor_name">
|
||||
Name<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="custom_vendor_name"
|
||||
required
|
||||
type="text"
|
||||
name="custom_vendor_name"
|
||||
placeholder="Vendor Name"
|
||||
value={customVendorName}
|
||||
onChange={(e) => setCustomVendorName(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<AccountSelect
|
||||
@@ -329,19 +386,21 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
</fieldset>
|
||||
{vendor && (
|
||||
<fieldset>
|
||||
{vendor !== VENDOR_DEEPGRAM && vendor !== VENDOR_SONIOX && (
|
||||
<label htmlFor="use_for_tts" className="chk">
|
||||
<input
|
||||
id="use_for_tts"
|
||||
name="use_for_tts"
|
||||
type="checkbox"
|
||||
onChange={(e) => setTtsCheck(e.target.checked)}
|
||||
defaultChecked={ttsCheck}
|
||||
/>
|
||||
<div>Use for text-to-speech</div>
|
||||
</label>
|
||||
)}
|
||||
{vendor !== VENDOR_WELLSAID && (
|
||||
{vendor !== VENDOR_DEEPGRAM &&
|
||||
vendor !== VENDOR_SONIOX &&
|
||||
vendor != VENDOR_CUSTOM && (
|
||||
<label htmlFor="use_for_tts" className="chk">
|
||||
<input
|
||||
id="use_for_tts"
|
||||
name="use_for_tts"
|
||||
type="checkbox"
|
||||
onChange={(e) => setTtsCheck(e.target.checked)}
|
||||
defaultChecked={ttsCheck}
|
||||
/>
|
||||
<div>Use for text-to-speech</div>
|
||||
</label>
|
||||
)}
|
||||
{vendor !== VENDOR_WELLSAID && vendor !== VENDOR_CUSTOM && (
|
||||
<label htmlFor="use_for_stt" className="chk">
|
||||
<input
|
||||
id="use_for_stt"
|
||||
@@ -353,6 +412,87 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
<div>Use for speech-to-text</div>
|
||||
</label>
|
||||
)}
|
||||
{vendor === VENDOR_CUSTOM && (
|
||||
<Fragment>
|
||||
<Checkzone
|
||||
hidden
|
||||
name="custom_vendor_use_for_tts"
|
||||
label="Use for text-to-speech"
|
||||
initialCheck={initialTtsCheck}
|
||||
handleChecked={(e) => {
|
||||
setTtsCheck(e.target.checked);
|
||||
if (!e.target.checked) {
|
||||
setTmpCustomVendorTtsUrl(customVendorTtsUrl);
|
||||
setCustomVendorTtsUrl("");
|
||||
} else {
|
||||
setCustomVendorTtsUrl(tmpCustomVendorTtsUrl);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<label htmlFor="custom_vendor_use_for_tts">
|
||||
TTS HTTP URL<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="custom_vendor_use_for_tts"
|
||||
type="text"
|
||||
name="custom_vendor_use_for_tts"
|
||||
placeholder="Required"
|
||||
required={ttsCheck}
|
||||
value={customVendorTtsUrl}
|
||||
onChange={(e) => {
|
||||
setCustomVendorTtsUrl(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Checkzone>
|
||||
|
||||
<Checkzone
|
||||
hidden
|
||||
name="custom_vendor_use_for_stt"
|
||||
label="Use for speech-to-text"
|
||||
initialCheck={initialSttCheck}
|
||||
handleChecked={(e) => {
|
||||
setSttCheck(e.target.checked);
|
||||
if (!e.target.checked) {
|
||||
setTmpCustomVendorSttUrl(customVendorSttUrl);
|
||||
setCustomVendorSttUrl("");
|
||||
} else {
|
||||
setCustomVendorSttUrl(tmpCustomVendorSttUrl);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<label htmlFor="custom_vendor_use_for_stt">
|
||||
STT websocket URL<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="custom_vendor_use_for_stt"
|
||||
type="text"
|
||||
name="custom_vendor_use_for_stt"
|
||||
placeholder="Required"
|
||||
required={sttCheck}
|
||||
value={customVendorSttUrl}
|
||||
onChange={(e) => {
|
||||
setCustomVendorSttUrl(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Checkzone>
|
||||
</Fragment>
|
||||
)}
|
||||
</fieldset>
|
||||
)}
|
||||
{vendor === VENDOR_CUSTOM && (
|
||||
<fieldset>
|
||||
<label htmlFor="custom_vendor_auth_token">
|
||||
Authentication Token
|
||||
</label>
|
||||
<input
|
||||
id="custom_vendor_auth_token"
|
||||
type="text"
|
||||
name="custom_vendor_auth_token"
|
||||
placeholder="Authentication Token"
|
||||
value={customVendorAuthToken}
|
||||
onChange={(e) => setCustomVendorAuthToken(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
</fieldset>
|
||||
)}
|
||||
{vendor === VENDOR_GOOGLE && (
|
||||
|
||||
@@ -26,6 +26,7 @@ import type { SpeechCredential, Account } from "src/api/types";
|
||||
import { ScopedAccess } from "src/components/scoped-access";
|
||||
import { Scope } from "src/store/types";
|
||||
import { getAccountFilter, setLocation } from "src/store/localStore";
|
||||
import { VENDOR_CUSTOM } from "src/vendor";
|
||||
|
||||
export const SpeechServices = () => {
|
||||
const user = useSelectState("user");
|
||||
@@ -140,7 +141,14 @@ export const SpeechServices = () => {
|
||||
title="Edit application"
|
||||
className="i"
|
||||
>
|
||||
<strong>Vendor: {credential.vendor}</strong>
|
||||
<strong>
|
||||
Vendor:{" "}
|
||||
{credential.vendor.startsWith(VENDOR_CUSTOM)
|
||||
? credential.vendor.substring(
|
||||
VENDOR_CUSTOM.length + 1
|
||||
)
|
||||
: credential.vendor}
|
||||
</strong>
|
||||
<Icons.ArrowRight />
|
||||
</Link>
|
||||
</ScopedAccess>
|
||||
|
||||
Vendored
+5
@@ -18,6 +18,7 @@ export const VENDOR_DEEPGRAM = "deepgram";
|
||||
export const VENDOR_IBM = "ibm";
|
||||
export const VENDOR_NVIDIA = "nvidia";
|
||||
export const VENDOR_SONIOX = "soniox";
|
||||
export const VENDOR_CUSTOM = "custom";
|
||||
|
||||
export const vendors: VendorOptions[] = [
|
||||
{
|
||||
@@ -56,6 +57,10 @@ export const vendors: VendorOptions[] = [
|
||||
name: "Soniox",
|
||||
value: VENDOR_SONIOX,
|
||||
},
|
||||
{
|
||||
name: "Custom",
|
||||
value: VENDOR_CUSTOM,
|
||||
},
|
||||
];
|
||||
|
||||
export const useRegionVendors = () => {
|
||||
|
||||
Vendored
+2
-1
@@ -7,7 +7,8 @@ export type Vendor =
|
||||
| "Deepgram"
|
||||
| "IBM"
|
||||
| "Nvidia"
|
||||
| "Soniox";
|
||||
| "Soniox"
|
||||
| "Custom";
|
||||
|
||||
export interface VendorOptions {
|
||||
name: Vendor;
|
||||
|
||||
Reference in New Issue
Block a user