Update web/templates/entry_view.html
This commit is contained in:
parent
8fa265fae4
commit
4d012289d1
@ -279,20 +279,33 @@
|
|||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- ===== TTS with play/stop toggle (ONLY this block changed) ===== -->
|
||||||
<script>
|
<script>
|
||||||
(function(){
|
(function(){
|
||||||
const ttsBtn = document.getElementById('ttsBtn');
|
const ttsBtn = document.getElementById('ttsBtn');
|
||||||
if (!ttsBtn) return;
|
if (!ttsBtn) return;
|
||||||
|
|
||||||
// Provided by the view for staff, or empty for non-staff
|
const TTS_URL = "{{ tts_url|default:'' }}"; // staff-only when present
|
||||||
const TTS_URL = "{{ tts_url|default:'' }}";
|
let ttsAudio = null; // holds current playback (Audio or shim)
|
||||||
|
|
||||||
|
function stopPlayback(){
|
||||||
|
try {
|
||||||
|
if (window.speechSynthesis) speechSynthesis.cancel();
|
||||||
|
} catch(e){}
|
||||||
|
try {
|
||||||
|
if (ttsAudio && typeof ttsAudio.pause === 'function') {
|
||||||
|
ttsAudio.pause();
|
||||||
|
ttsAudio.currentTime = 0;
|
||||||
|
}
|
||||||
|
if (ttsAudio && typeof ttsAudio.stop === 'function') {
|
||||||
|
ttsAudio.stop();
|
||||||
|
}
|
||||||
|
} catch(e){}
|
||||||
|
ttsAudio = null;
|
||||||
|
}
|
||||||
|
|
||||||
async function playOpenAITTS() {
|
async function playOpenAITTS() {
|
||||||
// fetch audio bytes from your Django endpoint
|
const r = await fetch(TTS_URL, { credentials: 'same-origin', cache: 'no-store' });
|
||||||
const r = await fetch(TTS_URL, {
|
|
||||||
credentials: 'same-origin',
|
|
||||||
cache: 'no-store'
|
|
||||||
});
|
|
||||||
if (!r.ok) {
|
if (!r.ok) {
|
||||||
const msg = await r.text().catch(()=> String(r.status));
|
const msg = await r.text().catch(()=> String(r.status));
|
||||||
throw new Error(`HTTP ${r.status}: ${msg.slice(0,200)}`);
|
throw new Error(`HTTP ${r.status}: ${msg.slice(0,200)}`);
|
||||||
@ -307,13 +320,10 @@
|
|||||||
|
|
||||||
const audio = new Audio(url);
|
const audio = new Audio(url);
|
||||||
audio.preload = 'auto';
|
audio.preload = 'auto';
|
||||||
audio.autoplay = true;
|
audio.setAttribute('playsinline','');
|
||||||
audio.setAttribute('playsinline',''); // iOS/Safari
|
audio.onended = () => { URL.revokeObjectURL(url); ttsAudio = null; };
|
||||||
try {
|
await audio.play();
|
||||||
await audio.play();
|
ttsAudio = audio;
|
||||||
} finally {
|
|
||||||
audio.onended = () => URL.revokeObjectURL(url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildCombinedText(){
|
function buildCombinedText(){
|
||||||
@ -328,19 +338,31 @@
|
|||||||
if (!('speechSynthesis' in window) || !('SpeechSynthesisUtterance' in window)) {
|
if (!('speechSynthesis' in window) || !('SpeechSynthesisUtterance' in window)) {
|
||||||
throw new Error('Browser TTS not supported.');
|
throw new Error('Browser TTS not supported.');
|
||||||
}
|
}
|
||||||
window.speechSynthesis.cancel();
|
speechSynthesis.cancel();
|
||||||
const u = new SpeechSynthesisUtterance(text);
|
const u = new SpeechSynthesisUtterance(text);
|
||||||
u.rate = 1.0; u.pitch = 1.0; u.volume = 1.0;
|
u.rate = 1.0; u.pitch = 1.0; u.volume = 1.0;
|
||||||
|
u.onend = () => { ttsAudio = null; };
|
||||||
speechSynthesis.speak(u);
|
speechSynthesis.speak(u);
|
||||||
|
|
||||||
|
// Create a tiny shim so our toggle can "stop" it
|
||||||
|
ttsAudio = {
|
||||||
|
pause: () => speechSynthesis.cancel(),
|
||||||
|
currentTime: 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ttsBtn.addEventListener('click', async () => {
|
ttsBtn.addEventListener('click', async () => {
|
||||||
try {
|
try {
|
||||||
|
// Toggle: if already playing, stop instead
|
||||||
|
if (ttsAudio) {
|
||||||
|
stopPlayback();
|
||||||
|
showToast("Playback stopped");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ttsBtn.disabled = true;
|
ttsBtn.disabled = true;
|
||||||
|
|
||||||
// Staff users get the OpenAI endpoint; others fall back
|
if (TTS_URL) {
|
||||||
const usingOpenAI = Boolean(TTS_URL);
|
|
||||||
if (usingOpenAI) {
|
|
||||||
await playOpenAITTS();
|
await playOpenAITTS();
|
||||||
showToast("Using OpenAI TTS");
|
showToast("Using OpenAI TTS");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user