Fix M17: statusByUrl picks highest-priority status for duplicate URLs
LibraryView mapped url -> status by last-write, so when a URL had multiple
queue entries ("Download anyway"), the row reflected whichever item was
iterated last. Added a STATUS_PRIORITY ranking (completed > downloading >
queued > saved > paused > error > canceled) and keep the highest-priority
status per URL, so a row shows the most meaningful state of that video.
typecheck + 242 tests + eslint green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -272,7 +272,7 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
|||||||
fallback is dependency-free (no Fluent/theme provider — the crash may have come from that tree), logs via
|
fallback is dependency-free (no Fluent/theme provider — the crash may have come from that tree), logs via
|
||||||
`componentDidCatch`, shows the error message, and offers a Reload button (`window.location.reload()`;
|
`componentDidCatch`, shows the error message, and offers a Reload button (`window.location.reload()`;
|
||||||
persisted data lives in main, so nothing is lost).*
|
persisted data lives in main, so nothing is lost).*
|
||||||
- [ ] **M17 — `statusByUrl` collapses duplicate URLs.** LibraryView maps URL→status into one
|
- [x] **M17 — `statusByUrl` collapses duplicate URLs.** LibraryView maps URL→status into one
|
||||||
`Map`; with "Download anyway" duplicates, a row can reflect the wrong item's state.
|
`Map`; with "Download anyway" duplicates, a row can reflect the wrong item's state.
|
||||||
- [ ] **M18 — Audio "quality" presets hard-code MP3.** `QUALITY_OPTIONS.audio` labels ("Best
|
- [ ] **M18 — Audio "quality" presets hard-code MP3.** `QUALITY_OPTIONS.audio` labels ("Best
|
||||||
(MP3)", "320 kbps") are shown even when `downloadOptions.audioFormat` is opus/flac/wav, so the
|
(MP3)", "320 kbps") are shown even when `downloadOptions.audioFormat` is opus/flac/wav, so the
|
||||||
|
|||||||
@@ -59,6 +59,19 @@ type LibRow =
|
|||||||
/** Above this many flattened rows, the item list switches to a virtualized panel. */
|
/** Above this many flattened rows, the item list switches to a virtualized panel. */
|
||||||
const VIRTUALIZE_AT = 100
|
const VIRTUALIZE_AT = 100
|
||||||
|
|
||||||
|
// When a URL appears more than once in the queue ("Download anyway" duplicates),
|
||||||
|
// the library row should reflect the most meaningful state: a finished copy wins,
|
||||||
|
// then anything in flight, then terminal failures (M17).
|
||||||
|
const STATUS_PRIORITY: Record<DownloadStatus, number> = {
|
||||||
|
completed: 6,
|
||||||
|
downloading: 5,
|
||||||
|
queued: 4,
|
||||||
|
saved: 3,
|
||||||
|
paused: 2,
|
||||||
|
error: 1,
|
||||||
|
canceled: 0
|
||||||
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
root: { display: 'flex', flexDirection: 'column', gap: '18px' },
|
root: { display: 'flex', flexDirection: 'column', gap: '18px' },
|
||||||
sub: { color: tokens.colorNeutralForeground3 },
|
sub: { color: tokens.colorNeutralForeground3 },
|
||||||
@@ -308,7 +321,13 @@ export function LibraryView(): React.JSX.Element {
|
|||||||
// Live per-URL queue status so a video row reflects its real download state.
|
// Live per-URL queue status so a video row reflects its real download state.
|
||||||
const statusByUrl = useMemo(() => {
|
const statusByUrl = useMemo(() => {
|
||||||
const m = new Map<string, DownloadStatus>()
|
const m = new Map<string, DownloadStatus>()
|
||||||
for (const d of downloadItems) m.set(d.url, d.status)
|
for (const d of downloadItems) {
|
||||||
|
const prev = m.get(d.url)
|
||||||
|
// Keep the highest-priority status when a URL has duplicate queue entries.
|
||||||
|
if (prev === undefined || STATUS_PRIORITY[d.status] > STATUS_PRIORITY[prev]) {
|
||||||
|
m.set(d.url, d.status)
|
||||||
|
}
|
||||||
|
}
|
||||||
return m
|
return m
|
||||||
}, [downloadItems])
|
}, [downloadItems])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user