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:
Bram Kragten 2024-03-20 10:56:32 +01:00 committed by GitHub
parent 7e1fa0cf38
commit c30b9cdfcf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 43 deletions

View File

@ -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));
}; };

View File

@ -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,
}); });
} }

View File

@ -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) {

View File

@ -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",