feat(tts): integrate autonomous Piper neural TTS with zero-latency pre-warming for words and context

This commit is contained in:
Antigravity committed 2026-10-07 10:40:02 +03:00
1 parent 915d2784a2
commit a6fb4349e9
12 files changed
+514 -27

No files matched your search

+47 -3
View File
@@ -52,6 +52,7 @@ export function initSrs() {
const fcBackDef = document.getElementById('fc-back-def');
const fcBackContextBox = document.getElementById('fc-back-context-box');
const fcBackContext = document.getElementById('fc-back-context');
const fcBackContextAudioBtn = document.getElementById('fc-back-context-audio-btn');
const fcBackNotesBox = document.getElementById('fc-back-notes-box');
const fcBackNotes = document.getElementById('fc-back-notes');
const fcFlipBtnWrap = document.getElementById('fc-flip-btn-wrap');
@@ -298,8 +299,41 @@ export function initSrs() {
fcBackNotes.textContent = card.notes || '';
fcBackNotesBox.style.display = card.notes ? 'block' : 'none';
fcFrontAudioBtn.style.display = 'none';
fcBackAudioBtn.style.display = 'none';
if (fcFrontAudioBtn) fcFrontAudioBtn.style.display = 'inline-flex';
if (fcBackAudioBtn) fcBackAudioBtn.style.display = 'inline-flex';
if (fcBackContextAudioBtn) {
fcBackContextAudioBtn.style.display = card.context_sentence ? 'inline-flex' : 'none';
}
}
if (fcFrontAudioBtn) {
fcFrontAudioBtn.addEventListener('click', (e) => {
e.stopPropagation();
const card = srsQueue[srsCurrentIndex];
if (!card) return;
const url = card.audio_url || `/api/tts?text=${encodeURIComponent(card.term)}&lang=en`;
playAudio(url);
});
}
if (fcBackAudioBtn) {
fcBackAudioBtn.addEventListener('click', (e) => {
e.stopPropagation();
const card = srsQueue[srsCurrentIndex];
if (!card) return;
const url = card.audio_url || `/api/tts?text=${encodeURIComponent(card.term)}&lang=en`;
playAudio(url);
});
}
if (fcBackContextAudioBtn) {
fcBackContextAudioBtn.addEventListener('click', (e) => {
e.stopPropagation();
const card = srsQueue[srsCurrentIndex];
if (!card || !card.context_sentence) return;
const url = card.context_audio_url || `/api/tts?text=${encodeURIComponent(card.context_sentence)}&lang=en`;
playAudio(url);
});
}
function flipFlashcard() {
@@ -363,7 +397,7 @@ export function initSrs() {
quizContextHint.classList.add('hidden');
}
quizAudioBtn.classList.add('hidden');
if (quizAudioBtn) quizAudioBtn.classList.remove('hidden');
const correctText = card.translation;
const all = getAllCards();
@@ -436,6 +470,16 @@ export function initSrs() {
quizNextBtn.focus();
}
if (quizAudioBtn) {
quizAudioBtn.addEventListener('click', (e) => {
e.stopPropagation();
const card = srsQueue[srsCurrentIndex];
if (!card) return;
const url = card.audio_url || `/api/tts?text=${encodeURIComponent(card.term)}&lang=en`;
playAudio(url);
});
}
quizNextBtn.addEventListener('click', () => {
srsCurrentIndex++;
renderSrsCurrentCard();