Ai_Assistant/client/overlay/subtitles.js

59 lines
1.5 KiB
JavaScript
Raw Normal View History

2026-05-24 13:31:30 +02:00
// subtitles.js
let _hideTimeout = null;
let _revealTimeouts = [];
let _enabled = true;
export function setSubtitlesEnabled(enabled) {
_enabled = enabled;
if (!enabled) {
const container = document.getElementById('subtitle-container');
if (container) container.classList.remove('visible');
}
}
export function getSubtitlesEnabled() {
return _enabled;
}
export function showSubtitleStreaming(text, totalDurationSeconds, mode = "word") {
if (!_enabled) return;
const container = document.getElementById('subtitle-container');
// Clear any pending timeouts from the previous chunk
if (_hideTimeout !== null) {
clearTimeout(_hideTimeout);
_hideTimeout = null;
}
for (const id of _revealTimeouts) clearTimeout(id);
_revealTimeouts = [];
container.innerHTML = '';
container.classList.add('visible');
let segments = mode === "letter" ? [...text] : text.split(' ');
let totalSteps = segments.length;
let delay = (totalDurationSeconds * 1000 * 0.7) / totalSteps;
segments.forEach((segment, i) => {
const span = document.createElement('span');
span.style.opacity = '0';
span.style.transition = 'opacity 0.3s ease';
span.textContent = mode === "word" ? segment + ' ' : segment;
container.appendChild(span);
const tid = setTimeout(() => {
span.style.opacity = '1';
}, i * delay);
_revealTimeouts.push(tid);
});
// Hide after total duration
_hideTimeout = setTimeout(() => {
container.classList.remove('visible');
_hideTimeout = null;
}, totalDurationSeconds * 1000 + 900);
}