Add voice customization UI to voice button page
Some checks failed
Tests / lint (pull_request) Failing after 15s
Tests / test (pull_request) Has been skipped

This commit is contained in:
2026-03-22 23:21:31 +00:00
parent 6d887a63d9
commit 656fb0ad34

View File

@@ -30,6 +30,27 @@
</div>
</div>
<div class="voice-settings mc-panel" style="margin-top: 1rem; border-top: 1px solid var(--border-color); padding-top: 1rem;">
<h3 style="font-size: 0.9rem; color: var(--text-dim); margin-bottom: 0.5rem;">// VOICE CUSTOMIZATION</h3>
<div class="form-group">
<label for="voice-select">Voice:</label>
<select id="voice-select" class="form-control" onchange="updateVoiceSettings()">
{% for voice in voices %}
<option value="{{ voice.id }}" {% if voice.id == current_voice %}selected{% endif %}>{{ voice.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group" style="margin-top: 0.5rem;">
<label for="rate-slider">Rate: <span id="rate-val">{{ current_rate }}</span></label>
<input type="range" id="rate-slider" min="50" max="300" value="{{ current_rate }}" class="form-control" oninput="updateRateLabel(this.value)" onchange="updateVoiceSettings()">
</div>
<div class="form-group" style="margin-top: 0.5rem;">
<label for="volume-slider">Volume: <span id="volume-val">{{ current_volume }}</span></label>
<input type="range" id="volume-slider" min="0" max="1" step="0.1" value="{{ current_volume }}" class="form-control" oninput="updateVolumeLabel(this.value)" onchange="updateVoiceSettings()">
</div>
<button class="btn btn-sm btn-outline-secondary" style="margin-top: 0.5rem;" onclick="testVoice()">Test Voice</button>
</div>
<div class="voice-tips">
<h3>Try saying:</h3>
<ul>
@@ -87,6 +108,38 @@ function startListening() {
function stopListening() {
if (recognition && isListening) { recognition.stop(); }
}
function updateRateLabel(val) { document.getElementById('rate-val').textContent = val; }
function updateVolumeLabel(val) { document.getElementById('volume-val').textContent = val; }
async function updateVoiceSettings() {
const voice_id = document.getElementById('voice-select').value;
const rate = document.getElementById('rate-slider').value;
const volume = document.getElementById('volume-slider').value;
try {
await fetch('/voice/settings', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'voice_id=' + encodeURIComponent(voice_id) + '&rate=' + rate + '&volume=' + volume
});
} catch (e) {
console.error('Failed to update voice settings:', e);
}
}
async function testVoice() {
const text = "Hello, I am Timmy. How can I help you today?";
try {
await fetch('/voice/tts/speak', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'text=' + encodeURIComponent(text)
});
} catch (e) {
console.error('Failed to test voice:', e);
}
}
function resetButton() {
document.getElementById('voice-status').textContent = 'Tap and hold to speak';
document.getElementById('voice-btn').classList.remove('listening');