Add double-click resets to the voice settings
This commit is contained in:
+51
-10
@@ -2044,15 +2044,19 @@ async function saveSpeech(extra = {}) {
|
||||
const speed = Number($("#tts-speed").value);
|
||||
const pitch = Number($("#tts-pitch").value);
|
||||
const expressionEl = $("#tts-expression");
|
||||
// A double-click reset clears the override: it must not be resent as a number.
|
||||
const expression =
|
||||
expressionEl.dataset.dirty === "1" || typeof state.speech.expression === "number"
|
||||
? Number(expressionEl.value)
|
||||
: null;
|
||||
expressionEl.dataset.reset === "1"
|
||||
? null
|
||||
: expressionEl.dataset.dirty === "1" || typeof state.speech.expression === "number"
|
||||
? Number(expressionEl.value)
|
||||
: null;
|
||||
|
||||
try {
|
||||
const prefs = await VK.api.post("/api/preferences", {
|
||||
tts: { provider, language, voice, speed, pitch, expression, ...effectOptions(), ...extra }
|
||||
});
|
||||
delete expressionEl.dataset.reset;
|
||||
state.speech = prefs.tts ?? {
|
||||
provider: null,
|
||||
language: null,
|
||||
@@ -2141,6 +2145,7 @@ function buildProfileSliders() {
|
||||
const slider = el("input", { type: "range", min: String(min), max: String(max), step: "1" });
|
||||
slider.id = `tts-profile-${key}`;
|
||||
slider.dataset.key = key;
|
||||
slider.title = "Double-click to reset to the engine default";
|
||||
const value = el("span", { class: "vk-mono vk-dim", text: "default" });
|
||||
|
||||
root.append(
|
||||
@@ -2167,6 +2172,15 @@ function buildProfileSliders() {
|
||||
}
|
||||
});
|
||||
slider.addEventListener("change", () => void saveSpeech());
|
||||
slider.addEventListener("dblclick", () => {
|
||||
const engineDefault = state.profileDefaults?.[key];
|
||||
if (typeof engineDefault !== "number") return;
|
||||
|
||||
slider.value = engineDefault;
|
||||
slider.dataset.dirty = "";
|
||||
value.textContent = "default";
|
||||
void saveSpeech();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2980,6 +2994,11 @@ function init() {
|
||||
for (const id of ["tts-speed", "tts-pitch"]) {
|
||||
$(`#${id}`).addEventListener("input", syncSpeechSliderLabels);
|
||||
$(`#${id}`).addEventListener("change", () => void saveSpeech());
|
||||
$(`#${id}`).addEventListener("dblclick", () => {
|
||||
$(`#${id}`).value = id === "tts-speed" ? "1" : "0";
|
||||
syncSpeechSliderLabels();
|
||||
void saveSpeech();
|
||||
});
|
||||
}
|
||||
$("#tts-expression").addEventListener("input", () => {
|
||||
const slider = $("#tts-expression");
|
||||
@@ -2996,15 +3015,34 @@ function init() {
|
||||
syncSpeechSliderLabels();
|
||||
});
|
||||
$("#tts-expression").addEventListener("change", () => void saveSpeech());
|
||||
$("#tts-expression").addEventListener("dblclick", () => {
|
||||
const slider = $("#tts-expression");
|
||||
const engineDefault = state.expressionDefault;
|
||||
if (typeof engineDefault !== "number") return;
|
||||
|
||||
slider.value = engineDefault;
|
||||
slider.dataset.dirty = "";
|
||||
slider.dataset.stored = "0";
|
||||
slider.dataset.reset = "1";
|
||||
syncSpeechSliderLabels();
|
||||
void saveSpeech();
|
||||
});
|
||||
buildProfileSliders();
|
||||
for (const id of ["tts-highpass", "tts-echo", "tts-word-gap", "tts-volume"]) {
|
||||
$(`#${id}`).addEventListener("input", () => {
|
||||
$("#tts-highpass-value").textContent = `${$("#tts-highpass").value}Hz`;
|
||||
$("#tts-echo-value").textContent = Number($("#tts-echo").value) > 0 ? $("#tts-echo").value : "off";
|
||||
$("#tts-word-gap-value").textContent = `${$("#tts-word-gap").value}ms`;
|
||||
$("#tts-volume-value").textContent = `${Number($("#tts-volume").value)}%`;
|
||||
});
|
||||
const radioDefaults = { "tts-highpass": 40, "tts-echo": 0, "tts-word-gap": 120, "tts-volume": 100 };
|
||||
const syncRadioLabels = () => {
|
||||
$("#tts-highpass-value").textContent = `${$("#tts-highpass").value}Hz`;
|
||||
$("#tts-echo-value").textContent = Number($("#tts-echo").value) > 0 ? $("#tts-echo").value : "off";
|
||||
$("#tts-word-gap-value").textContent = `${$("#tts-word-gap").value}ms`;
|
||||
$("#tts-volume-value").textContent = `${Number($("#tts-volume").value)}%`;
|
||||
};
|
||||
for (const id of Object.keys(radioDefaults)) {
|
||||
$(`#${id}`).addEventListener("input", syncRadioLabels);
|
||||
$(`#${id}`).addEventListener("change", () => void saveSpeech());
|
||||
$(`#${id}`).addEventListener("dblclick", () => {
|
||||
$(`#${id}`).value = String(radioDefaults[id]);
|
||||
syncRadioLabels();
|
||||
void saveSpeech();
|
||||
});
|
||||
}
|
||||
$("#tts-words").addEventListener("change", () => void saveSpeech());
|
||||
$("#tts-vox-clean").addEventListener("change", () => void saveSpeech());
|
||||
@@ -3246,6 +3284,9 @@ function init() {
|
||||
renderRightFavourites();
|
||||
|
||||
void refreshAll();
|
||||
// The speech status and preferences feed the TTS panel and the settings
|
||||
// overlay, so load them at startup instead of on the first panel open.
|
||||
void refreshAudio();
|
||||
void refreshHealth();
|
||||
syncTtsControls();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user