fix(library): a listing poll can no longer put back an older resume point

A poll already out when the player closed answered with the point the server held before the
closing beacon, over the row's patch; Continue then opened there and wrote it back. The close now
cancels the listings' fetches before patching and reads them again once the beacon has landed.
This commit is contained in:
2026-10-07 23:16:25 +02:00
parent 0a35f2a3b1
commit 891dc628f3
4 changed files with 59 additions and 12 deletions
+12 -4
View File
@@ -69,16 +69,24 @@ export default function LibraryPlayer({
});
useMediaKeys(media);
// The library row's bar follows the point at once — both listings this job may sit in — rather
// than after the next refetch, which may land before the closing beacon does.
// than after the next refetch. On the way out a listing poll may already be out, having read the
// server before the closing point lands: it is cancelled, or its answer replaced the row's point
// with the older one, Continue opened there, and its first checkpoint wrote it back over the right
// one. Once the point is on the server, the listings are read again.
const lists = [qk.downloads(), qk.downloadsShared()];
const keepPoint = (position: number, duration: number, leaving: boolean) => {
const at = keptPosition(position, duration);
for (const key of [qk.downloads(), qk.downloadsShared()]) {
for (const key of lists) {
if (leaving) void qc.cancelQueries({ queryKey: key, exact: true });
qc.setQueryData<DownloadJob[]>(key, (jobs) =>
jobs?.map((j) => (j.id === job.id ? { ...j, position_seconds: at } : j)),
);
}
if (leaving) api.saveDownloadProgressBeacon(job.id, position, duration);
else void api.saveDownloadProgress(job.id, position, duration).catch(() => {});
if (leaving) {
api.saveDownloadProgressBeacon(job.id, position, duration, () => {
for (const key of lists) void qc.invalidateQueries({ queryKey: key, exact: true });
});
} else void api.saveDownloadProgress(job.id, position, duration).catch(() => {});
};
useResume(media, String(job.id), fromStart ? 0 : (job.position_seconds ?? 0), keepPoint);