fix(anime): guard playback races and harden install/extract tests

- Tag subtitle cache writes with a generation counter so overlapping playEpisode calls can't clobber the shared cache dir, and don't fail playback when track setup errors
- Ignore stale episode clicks in the detail panel via a LatestRequest guard on playback
- Extract a resetGrid helper in animeui to dedupe grid-clearing logic
- Assert reader cancellation and extracted-file writes actually happen in installer/subsync tests
This commit is contained in:
2026-08-02 02:04:24 -07:00
parent fbfdea7c64
commit 10ad19f934
5 changed files with 57 additions and 29 deletions
+10 -10
View File
@@ -202,10 +202,16 @@ function createCard(entry: AnimeBrowserEntry, showSource: boolean): HTMLButtonEl
return card;
}
function renderEntries(entries: AnimeBrowserEntry[], emptyMessage: string): void {
// Which source a cover came from only matters when they are mixed together.
/** Drops every card and the empty-state message so a fresh page can build up. */
function resetGrid(): void {
seenEntries.clear();
grid.replaceChildren();
gridEmpty.classList.add('hidden');
}
function renderEntries(entries: AnimeBrowserEntry[], emptyMessage: string): void {
// Which source a cover came from only matters when they are mixed together.
resetGrid();
appendEntries(entries);
const empty = grid.childElementCount === 0;
@@ -255,11 +261,7 @@ api.onSearchUpdate((update) => {
const request = soleBrowseRequest(inFlightBrowses);
activeStreamRequestId = request?.id ?? 0;
const append = request?.append === true;
if (!append) {
seenEntries.clear();
grid.replaceChildren();
gridEmpty.classList.add('hidden');
}
if (!append) resetGrid();
return;
}
if (activeStreamRequestId !== browseState.requestId) return;
@@ -317,9 +319,7 @@ async function runSearch(query: string): Promise<void> {
// A new search means new results; leave the detail page for them.
if (detailPanel.isOpen()) detailPanel.close();
setStatus(query ? `Searching for “${query}”…` : 'Loading popular…');
seenEntries.clear();
grid.replaceChildren();
gridEmpty.classList.add('hidden');
resetGrid();
await runBrowse(started.request);
}