feat: add TTS voice picker to voice mode bottom sheet
This commit is contained in:
@@ -19,6 +19,8 @@ export class VoiceSession {
|
||||
this.voiceMode = false;
|
||||
this.transcript = "";
|
||||
this.talkMode = "auto";
|
||||
this.voices = [];
|
||||
this.voiceIdx = -1;
|
||||
this.term = null;
|
||||
this.ws = null;
|
||||
this._lastLine = 0;
|
||||
@@ -32,6 +34,22 @@ export class VoiceSession {
|
||||
get lang() { return LANGS[this.langIdx]; }
|
||||
get langLabel() { return LANG_LABELS[this.langIdx]; }
|
||||
get modeLabel() { return MODE_LABELS[this.talkMode]; }
|
||||
get voiceName() { return this.voices[this.voiceIdx]?.name || "Default"; }
|
||||
|
||||
loadVoices() {
|
||||
const all = speechSynthesis.getVoices();
|
||||
const prefix = this.lang.split("-")[0];
|
||||
this.voices = all.filter(v => v.lang.startsWith(prefix));
|
||||
// Try to keep current selection
|
||||
if (this.voiceIdx >= this.voices.length) this.voiceIdx = 0;
|
||||
if (!this.voices.length) this.voiceIdx = -1;
|
||||
this._notify();
|
||||
}
|
||||
|
||||
setVoice(idx) {
|
||||
this.voiceIdx = idx;
|
||||
this._notify();
|
||||
}
|
||||
|
||||
attach(term, ws) {
|
||||
this.term = term;
|
||||
@@ -50,6 +68,8 @@ export class VoiceSession {
|
||||
speechSynthesis.speak(new SpeechSynthesisUtterance(""));
|
||||
this._ttsUnlocked = true;
|
||||
}
|
||||
this.loadVoices();
|
||||
speechSynthesis.onvoiceschanged = () => this.loadVoices();
|
||||
if (this.term) {
|
||||
this._lastLine = this.term.buffer.active.baseY + this.term.buffer.active.cursorY;
|
||||
}
|
||||
@@ -193,9 +213,7 @@ export class VoiceSession {
|
||||
speechSynthesis.cancel();
|
||||
const u = new SpeechSynthesisUtterance(text);
|
||||
u.lang = this.lang;
|
||||
const voices = speechSynthesis.getVoices();
|
||||
const v = voices.find(v => v.lang.startsWith(this.lang.split("-")[0]));
|
||||
if (v) u.voice = v;
|
||||
if (this.voices[this.voiceIdx]) u.voice = this.voices[this.voiceIdx];
|
||||
u.onstart = () => { this.speaking = true; this._notify(); };
|
||||
u.onend = () => { this.speaking = false; this._notify(); };
|
||||
u.onerror = () => { this.speaking = false; this._notify(); };
|
||||
@@ -215,6 +233,7 @@ export class VoiceSession {
|
||||
|
||||
cycleLang() {
|
||||
this.langIdx = (this.langIdx + 1) % LANGS.length;
|
||||
this.loadVoices();
|
||||
if (this.listening) {
|
||||
const wasContinuous = this._recog?.continuous;
|
||||
this._stopSTT();
|
||||
|
||||
Reference in New Issue
Block a user