fix: Abort fetch when cancelling audiobook casting and close UI immediately

This commit is contained in:
mARTin-B78 2026-06-22 17:36:05 +02:00
parent 3cc39b8ace
commit 3908f365e5
2 changed files with 18 additions and 3 deletions

View File

@ -275,7 +275,7 @@
<script src="/static/vendor/wavesurfer-regions.min.js"></script>
<!-- loader.js: fetches sections → loads JS modules → removes skeleton -->
<script src="/static/loader.js?v=1.8.0-2"></script>
<script src="/static/loader.js?v=1.8.0-3"></script>
</body>
</html>

View File

@ -164,7 +164,15 @@ function audiobookCastView(total) {
if (ic) ic.className = 'mdi ' + (min ? 'mdi-window-maximize' : 'mdi-window-minimize');
};
ov.querySelector('#ab-cv-min').addEventListener('click', () => setMin(!ov.classList.contains('minimized')));
ov.querySelector('#ab-cv-x').addEventListener('click', () => { if (_audiobook.running) _audiobook.cancel = true; else ov.remove(); });
ov.querySelector('#ab-cv-x').addEventListener('click', () => {
if (_audiobook.running) {
_audiobook.cancel = true;
if (typeof _audiobook.abort === 'function') _audiobook.abort();
ov.remove();
} else {
ov.remove();
}
});
ov.querySelector('#ab-cv-head').addEventListener('click', e => { if (ov.classList.contains('minimized') && !e.target.closest('button')) setMin(false); });
const fill = ov.querySelector('#ab-cv-fill'), count = ov.querySelector('#ab-cv-count');
const feed = ov.querySelector('#ab-cv-feed'), chars = ov.querySelector('#ab-cv-chars');
@ -230,6 +238,9 @@ async function audiobookCast() {
: [text];
_audiobook.running = true; _audiobook.cancel = false;
const ac = new AbortController();
_audiobook.abort = () => ac.abort();
const view = audiobookCastView(chunks.length);
const llm_url = audiobookLlmUrl(), model = audiobookLlmModel(), language = audiobookLang();
@ -254,11 +265,15 @@ async function audiobookCast() {
try {
const r = await fetch('/api/attribute-dialogue', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
signal: ac.signal,
body: JSON.stringify({ text: chunks[i], known_characters: roster.slice(-40), recent, language, llm_url, model }),
});
if (!r.ok) { const e = await r.json().catch(() => ({})); throw new Error(e.detail || r.statusText); }
data = await r.json();
} catch (_) { data = null; }
} catch (err) {
if (err.name === 'AbortError') break;
data = null;
}
let segs = data && Array.isArray(data.segments) ? data.segments : [];
if (!segs.length) {