Change gender to voice for cloud tts settings (#20057)
* change gender to voice for cloud tts settings * Use voice in cloud tts try dialog --------- Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
This commit is contained in:
parent
7e1fa0cf38
commit
c30b9cdfcf
|
@ -1,5 +1,4 @@
|
||||||
import { caseInsensitiveStringCompare } from "../../common/string/compare";
|
import { caseInsensitiveStringCompare } from "../../common/string/compare";
|
||||||
import { LocalizeFunc } from "../../common/translations/localize";
|
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
export interface CloudTTSInfo {
|
export interface CloudTTSInfo {
|
||||||
|
@ -27,27 +26,21 @@ export const getCloudTtsLanguages = (info?: CloudTTSInfo) => {
|
||||||
return languages;
|
return languages;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getCloudTtsSupportedGenders = (
|
export const getCloudTtsSupportedVoices = (
|
||||||
language: string,
|
language: string,
|
||||||
info: CloudTTSInfo | undefined,
|
info: CloudTTSInfo | undefined
|
||||||
localize: LocalizeFunc
|
|
||||||
) => {
|
) => {
|
||||||
const genders: Array<[string, string]> = [];
|
const voices: Array<string> = [];
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return genders;
|
return voices;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [curLang, gender] of info.languages) {
|
for (const [curLang, voice] of info.languages) {
|
||||||
if (curLang === language) {
|
if (curLang === language) {
|
||||||
genders.push([
|
voices.push(voice);
|
||||||
gender,
|
|
||||||
gender === "male" || gender === "female"
|
|
||||||
? localize(`ui.components.media-browser.tts.gender_${gender}`)
|
|
||||||
: gender,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return genders.sort((a, b) => caseInsensitiveStringCompare(a[1], b[1]));
|
return voices.sort((a, b) => caseInsensitiveStringCompare(a, b));
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {
|
||||||
CloudTTSInfo,
|
CloudTTSInfo,
|
||||||
getCloudTTSInfo,
|
getCloudTTSInfo,
|
||||||
getCloudTtsLanguages,
|
getCloudTtsLanguages,
|
||||||
getCloudTtsSupportedGenders,
|
getCloudTtsSupportedVoices,
|
||||||
} from "../../../../data/cloud/tts";
|
} from "../../../../data/cloud/tts";
|
||||||
import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box";
|
import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
@ -37,11 +37,7 @@ export class CloudTTSPref extends LitElement {
|
||||||
|
|
||||||
const languages = this.getLanguages(this.ttsInfo);
|
const languages = this.getLanguages(this.ttsInfo);
|
||||||
const defaultVoice = this.cloudStatus.prefs.tts_default_voice;
|
const defaultVoice = this.cloudStatus.prefs.tts_default_voice;
|
||||||
const genders = this.getSupportedGenders(
|
const voices = this.getSupportedVoices(defaultVoice[0], this.ttsInfo);
|
||||||
defaultVoice[0],
|
|
||||||
this.ttsInfo,
|
|
||||||
this.hass.localize
|
|
||||||
);
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card
|
<ha-card
|
||||||
|
@ -68,15 +64,15 @@ export class CloudTTSPref extends LitElement {
|
||||||
|
|
||||||
<ha-select
|
<ha-select
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.cloud.account.tts.default_gender"
|
"ui.panel.config.cloud.account.tts.default_voice"
|
||||||
)}
|
)}
|
||||||
.disabled=${this.savingPreferences}
|
.disabled=${this.savingPreferences}
|
||||||
.value=${defaultVoice[1]}
|
.value=${defaultVoice[1]}
|
||||||
@selected=${this._handleGenderChange}
|
@selected=${this._handleVoiceChange}
|
||||||
>
|
>
|
||||||
${genders.map(
|
${voices.map(
|
||||||
([key, label]) =>
|
(voice) =>
|
||||||
html`<mwc-list-item .value=${key}>${label}</mwc-list-item>`
|
html`<mwc-list-item .value=${voice}>${voice}</mwc-list-item>`
|
||||||
)}
|
)}
|
||||||
</ha-select>
|
</ha-select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,6 +86,16 @@ export class CloudTTSPref extends LitElement {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected updated(changedProps) {
|
||||||
|
if (
|
||||||
|
changedProps.has("cloudStatus") &&
|
||||||
|
this.cloudStatus?.prefs.tts_default_voice?.[0] !==
|
||||||
|
changedProps.get("cloudStatus")?.prefs.tts_default_voice?.[0]
|
||||||
|
) {
|
||||||
|
this.renderRoot.querySelector("ha-select")?.layoutOptions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected willUpdate(changedProps) {
|
protected willUpdate(changedProps) {
|
||||||
super.willUpdate(changedProps);
|
super.willUpdate(changedProps);
|
||||||
if (!this.hasUpdated) {
|
if (!this.hasUpdated) {
|
||||||
|
@ -104,7 +110,7 @@ export class CloudTTSPref extends LitElement {
|
||||||
|
|
||||||
private getLanguages = memoizeOne(getCloudTtsLanguages);
|
private getLanguages = memoizeOne(getCloudTtsLanguages);
|
||||||
|
|
||||||
private getSupportedGenders = memoizeOne(getCloudTtsSupportedGenders);
|
private getSupportedVoices = memoizeOne(getCloudTtsSupportedVoices);
|
||||||
|
|
||||||
private _openTryDialog() {
|
private _openTryDialog() {
|
||||||
showTryTtsDialog(this, {
|
showTryTtsDialog(this, {
|
||||||
|
@ -119,19 +125,15 @@ export class CloudTTSPref extends LitElement {
|
||||||
this.savingPreferences = true;
|
this.savingPreferences = true;
|
||||||
const language = ev.detail.value;
|
const language = ev.detail.value;
|
||||||
|
|
||||||
const curGender = this.cloudStatus!.prefs.tts_default_voice[1];
|
const curVoice = this.cloudStatus!.prefs.tts_default_voice[1];
|
||||||
const genders = this.getSupportedGenders(
|
const voices = this.getSupportedVoices(language, this.ttsInfo);
|
||||||
language,
|
const newVoice = voices.find((item) => item === curVoice)
|
||||||
this.ttsInfo,
|
? curVoice
|
||||||
this.hass.localize
|
: voices[0];
|
||||||
);
|
|
||||||
const newGender = genders.find((item) => item[0] === curGender)
|
|
||||||
? curGender
|
|
||||||
: genders[0][0];
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateCloudPref(this.hass, {
|
await updateCloudPref(this.hass, {
|
||||||
tts_default_voice: [language, newGender],
|
tts_default_voice: [language, newVoice],
|
||||||
});
|
});
|
||||||
fireEvent(this, "ha-refresh-cloud-status");
|
fireEvent(this, "ha-refresh-cloud-status");
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
@ -145,17 +147,17 @@ export class CloudTTSPref extends LitElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _handleGenderChange(ev) {
|
async _handleVoiceChange(ev) {
|
||||||
if (ev.target.value === this.cloudStatus!.prefs.tts_default_voice[1]) {
|
if (ev.target.value === this.cloudStatus!.prefs.tts_default_voice[1]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.savingPreferences = true;
|
this.savingPreferences = true;
|
||||||
const language = this.cloudStatus!.prefs.tts_default_voice[0];
|
const language = this.cloudStatus!.prefs.tts_default_voice[0];
|
||||||
const gender = ev.target.value;
|
const voice = ev.target.value;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateCloudPref(this.hass, {
|
await updateCloudPref(this.hass, {
|
||||||
tts_default_voice: [language, gender],
|
tts_default_voice: [language, voice],
|
||||||
});
|
});
|
||||||
fireEvent(this, "ha-refresh-cloud-status");
|
fireEvent(this, "ha-refresh-cloud-status");
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
@ -163,7 +165,7 @@ export class CloudTTSPref extends LitElement {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(err);
|
console.error(err);
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
text: `Unable to save default gender. ${err}`,
|
text: `Unable to save default voice. ${err}`,
|
||||||
warning: true,
|
warning: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ export class DialogTryTts extends LitElement {
|
||||||
this._loadingExample = true;
|
this._loadingExample = true;
|
||||||
|
|
||||||
const language = this._params!.defaultVoice[0];
|
const language = this._params!.defaultVoice[0];
|
||||||
const gender = this._params!.defaultVoice[1];
|
const voice = this._params!.defaultVoice[1];
|
||||||
|
|
||||||
let url;
|
let url;
|
||||||
try {
|
try {
|
||||||
|
@ -192,7 +192,7 @@ export class DialogTryTts extends LitElement {
|
||||||
platform: "cloud",
|
platform: "cloud",
|
||||||
message,
|
message,
|
||||||
language,
|
language,
|
||||||
options: { gender },
|
options: { voice },
|
||||||
});
|
});
|
||||||
url = result.path;
|
url = result.path;
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
|
|
@ -3524,7 +3524,7 @@
|
||||||
"title": "Text-to-speech",
|
"title": "Text-to-speech",
|
||||||
"info": "Bring personality to your home by having it speak to you by using our text-to-speech services. You can use this in automations and scripts by using the {service} service.",
|
"info": "Bring personality to your home by having it speak to you by using our text-to-speech services. You can use this in automations and scripts by using the {service} service.",
|
||||||
"default_language": "Default language to use",
|
"default_language": "Default language to use",
|
||||||
"default_gender": "Default gender to use",
|
"default_voice": "Default voice to use",
|
||||||
"try": "Try",
|
"try": "Try",
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"header": "Try text-to-speech",
|
"header": "Try text-to-speech",
|
||||||
|
|
Loading…
Reference in New Issue