1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-07-21 18:55:36 +02:00

fix(frontend): exact quality match in applyPlaylistQuality

Replace maxHeight >= newHeight (cap check) with item.qualities.includes(newQ)
(exact match). A video with [2160p, 1080p] does not support 1440p; the
previous logic would mark it as supporting any quality up to 2160p and
submit '1440p' which yt-dlp silently downloads as 1080p — misrepresenting
the selected quality.

With exact match, unsupported qualities correctly fall through to the
conflict path (keep prior selection or null), enforcing the same manual-
choice requirement as any other unsupported quality.

Per-row selects are unaffected: they already render only pi.qualities
(the video's actual available formats), no maxHeight logic involved.
This commit is contained in:
TheGeneralist 2026-07-20 23:00:02 +02:00
parent 5e6a612010
commit fe91455908
Signed by: thegeneralist01
SSH key fingerprint: SHA256:pp9qddbCNmVNoSjevdvQvM5z0DHN7LTa8qBMbcMq/R4
3 changed files with 15 additions and 16 deletions

View file

@ -4,7 +4,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Archivr</title>
<script type="module" crossorigin src="/assets/index-A4sxjUxl.js"></script>
<script type="module" crossorigin src="/assets/index-j2VTq1Xm.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-B0SNwnT5.css">
</head>
<body>

View file

@ -136,18 +136,17 @@ function applyPlaylistQuality(newQ, currentItems) {
return { ...item, quality: null }
})
}
const newHeight = parseInt(newQ)
return currentItems.map(item => {
if (item.qualities.length === 0) {
return item
}
const maxHeight = Math.max(...item.qualities.map(q => parseInt(q)))
if (maxHeight >= newHeight) {
// Exact match only: the video must list this quality in its available formats.
// maxHeight >= newHeight would be a cap (yt-dlp silent fallback), not what
// the user selected; a video with [2160p, 1080p] does NOT support 1440p.
if (item.qualities.includes(newQ)) {
return { ...item, quality: newQ }
} else {
if (item.quality !== null) return item
return { ...item, quality: null }
}
// Quality not available for this item keep prior selection if one exists,
// otherwise null (conflict, blocks archive until user picks manually).
if (item.quality !== null) return item
return { ...item, quality: null }
})
}