mirror of
https://github.com/thegeneralist01/archivr
synced 2026-07-22 03:05:32 +02:00
feat(server,frontend): playlist quality selector + per-video overrides + sync UI
routes.rs:
- CaptureBody gains per_item_quality (HashMap<String,String>, serde(default))
and sync (bool, serde(default)); both validated before use
- per_item_quality values validated against same quality predicate as top-level
quality field ("best"|"audio"|"NNNp") so bad per-video values are rejected
at the API boundary rather than silently falling through to quality_format
- capture_handler threads body.per_item_quality + body.sync into CaptureConfig
(replaces hardcoded empty stubs); rearchive_handler keeps empty defaults
- New POST /api/archives/:id/captures/probe-playlist: calls
probe_playlist_qualities via spawn_blocking; 400 for non-playlist locator,
502 on yt-dlp failure, returns PlaylistProbeResult as JSON
api.js:
- probePlaylist(archiveId, locator): POST probe-playlist endpoint
- submitCapture: forwards per_item_quality (non-empty) and sync:true from
extraExtensions param added to submitBgJob
CaptureDialog.jsx:
- isPlaylistSource(): detects yt:/youtube: playlist/@/channel, ytm:playlist/,
YouTube/YTM HTTP(S) URLs with list= param or channel pathnames
- makeItem(): 6 new playlist state fields
- applyPlaylistQuality(): conflict logic — videos that can reach selected
quality get it set; videos that can't and have no prior selection are left
null (conflict); videos with a prior selection keep it when quality is raised
- hasConflict(): any playlistItems entry with quality===null
- updateLocator(): isPlaylistSource branch with 800ms debounce→probePlaylist;
existing isVideoSource path unchanged
- Archive button disabled when anyConflict or any probe in flight
- Per-video expand list with individual quality selects, conflict badges,
sync toggle (appears after probe completes)
styles.css: playlist expansion, conflict, sync toggle CSS
This commit is contained in:
parent
096c98a678
commit
7499deeab0
8 changed files with 447 additions and 87 deletions
|
|
@ -2866,3 +2866,77 @@ body.has-audio-bar { padding-bottom: 56px; }
|
|||
font-size: 0.85em;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
/* ── Playlist quality expansion ──────────────────────────── */
|
||||
.capture-playlist-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 0.75rem;
|
||||
color: var(--muted);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 2px 6px;
|
||||
}
|
||||
.capture-playlist-toggle:hover { color: var(--text); }
|
||||
|
||||
.capture-conflict-badge {
|
||||
font-size: 0.7rem;
|
||||
color: #c07000;
|
||||
background: #fff3cd;
|
||||
border: 1px solid #e0a000;
|
||||
border-radius: 4px;
|
||||
padding: 1px 6px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.capture-playlist-items {
|
||||
border-top: 1px solid var(--line-soft);
|
||||
padding: 4px 0;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.capture-playlist-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 4px 12px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.capture-playlist-item--conflict {
|
||||
background: #fff8f0;
|
||||
}
|
||||
.capture-playlist-item-title {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: var(--text);
|
||||
}
|
||||
.capture-item-quality {
|
||||
font-size: 0.75rem;
|
||||
padding: 2px 4px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 4px;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
}
|
||||
.capture-playlist-conflict-badge {
|
||||
font-size: 0.7rem;
|
||||
color: #c07000;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.capture-sync-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
font-size: 0.78rem;
|
||||
color: var(--muted);
|
||||
border-top: 1px solid var(--line-soft);
|
||||
cursor: pointer;
|
||||
}
|
||||
.capture-sync-row input[type=checkbox] { cursor: pointer; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue