Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change gender to voice for cloud tts settings #20057

Merged
merged 2 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions src/data/cloud/tts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { caseInsensitiveStringCompare } from "../../common/string/compare";
import { LocalizeFunc } from "../../common/translations/localize";
import { HomeAssistant } from "../../types";

export interface CloudTTSInfo {
Expand Down Expand Up @@ -27,27 +26,21 @@ export const getCloudTtsLanguages = (info?: CloudTTSInfo) => {
return languages;
};

export const getCloudTtsSupportedGenders = (
export const getCloudTtsSupportedVoices = (
language: string,
info: CloudTTSInfo | undefined,
localize: LocalizeFunc
info: CloudTTSInfo | undefined
) => {
const genders: Array<[string, string]> = [];
const voices: Array<string> = [];

if (!info) {
return genders;
return voices;
}

for (const [curLang, gender] of info.languages) {
for (const [curLang, voice] of info.languages) {
if (curLang === language) {
genders.push([
gender,
gender === "male" || gender === "female"
? localize(`ui.components.media-browser.tts.gender_${gender}`)
: gender,
]);
voices.push(voice);
}
}

return genders.sort((a, b) => caseInsensitiveStringCompare(a[1], b[1]));
return voices.sort((a, b) => caseInsensitiveStringCompare(a, b));
};
54 changes: 28 additions & 26 deletions src/panels/config/cloud/account/cloud-tts-pref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
CloudTTSInfo,
getCloudTTSInfo,
getCloudTtsLanguages,
getCloudTtsSupportedGenders,
getCloudTtsSupportedVoices,
} from "../../../../data/cloud/tts";
import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box";
import type { HomeAssistant } from "../../../../types";
Expand All @@ -37,11 +37,7 @@ export class CloudTTSPref extends LitElement {

const languages = this.getLanguages(this.ttsInfo);
const defaultVoice = this.cloudStatus.prefs.tts_default_voice;
const genders = this.getSupportedGenders(
defaultVoice[0],
this.ttsInfo,
this.hass.localize
);
const voices = this.getSupportedVoices(defaultVoice[0], this.ttsInfo);

return html`
<ha-card
Expand All @@ -68,15 +64,15 @@ export class CloudTTSPref extends LitElement {

<ha-select
.label=${this.hass.localize(
"ui.panel.config.cloud.account.tts.default_gender"
"ui.panel.config.cloud.account.tts.default_voice"
)}
.disabled=${this.savingPreferences}
.value=${defaultVoice[1]}
@selected=${this._handleGenderChange}
@selected=${this._handleVoiceChange}
>
${genders.map(
([key, label]) =>
html`<mwc-list-item .value=${key}>${label}</mwc-list-item>`
${voices.map(
(voice) =>
html`<mwc-list-item .value=${voice}>${voice}</mwc-list-item>`
)}
</ha-select>
</div>
Expand All @@ -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) {
super.willUpdate(changedProps);
if (!this.hasUpdated) {
Expand All @@ -104,7 +110,7 @@ export class CloudTTSPref extends LitElement {

private getLanguages = memoizeOne(getCloudTtsLanguages);

private getSupportedGenders = memoizeOne(getCloudTtsSupportedGenders);
private getSupportedVoices = memoizeOne(getCloudTtsSupportedVoices);

private _openTryDialog() {
showTryTtsDialog(this, {
Expand All @@ -119,19 +125,15 @@ export class CloudTTSPref extends LitElement {
this.savingPreferences = true;
const language = ev.detail.value;

const curGender = this.cloudStatus!.prefs.tts_default_voice[1];
const genders = this.getSupportedGenders(
language,
this.ttsInfo,
this.hass.localize
);
const newGender = genders.find((item) => item[0] === curGender)
? curGender
: genders[0][0];
const curVoice = this.cloudStatus!.prefs.tts_default_voice[1];
const voices = this.getSupportedVoices(language, this.ttsInfo);
const newVoice = voices.find((item) => item === curVoice)
? curVoice
: voices[0];

try {
await updateCloudPref(this.hass, {
tts_default_voice: [language, newGender],
tts_default_voice: [language, newVoice],
});
fireEvent(this, "ha-refresh-cloud-status");
} catch (err: any) {
Expand All @@ -145,25 +147,25 @@ export class CloudTTSPref extends LitElement {
}
}

async _handleGenderChange(ev) {
async _handleVoiceChange(ev) {
if (ev.target.value === this.cloudStatus!.prefs.tts_default_voice[1]) {
return;
}
this.savingPreferences = true;
const language = this.cloudStatus!.prefs.tts_default_voice[0];
const gender = ev.target.value;
const voice = ev.target.value;

try {
await updateCloudPref(this.hass, {
tts_default_voice: [language, gender],
tts_default_voice: [language, voice],
});
fireEvent(this, "ha-refresh-cloud-status");
} catch (err: any) {
this.savingPreferences = false;
// eslint-disable-next-line no-console
console.error(err);
showAlertDialog(this, {
text: `Unable to save default gender. ${err}`,
text: `Unable to save default voice. ${err}`,
warning: true,
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/panels/config/cloud/account/dialog-cloud-tts-try.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,15 @@ export class DialogTryTts extends LitElement {
this._loadingExample = true;

const language = this._params!.defaultVoice[0];
const gender = this._params!.defaultVoice[1];
const voice = this._params!.defaultVoice[1];

let url;
try {
const result = await convertTextToSpeech(this.hass, {
platform: "cloud",
message,
language,
options: { gender },
options: { voice },
});
url = result.path;
} catch (err: any) {
Expand Down
2 changes: 1 addition & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3512,7 +3512,7 @@
"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.",
"default_language": "Default language to use",
"default_gender": "Default gender to use",
"default_voice": "Default voice to use",
"try": "Try",
"dialog": {
"header": "Try text-to-speech",
Expand Down
Loading