Two related Phase-4 changes.
1. main.ts: tBackend(key, params) helper with DE/EN tables for every
user-visible error / status string produced server-side. Previously
every backend message was hardcoded German, so EN-mode users saw
German errors in the queue (last_error), in download progress
status, in clip-download responses, and in the preflight panel.
~30 keys covered: invalidVodUrl, streamlinkMissing, fileTooSmall,
integrity*, downloadCancelled / downloadPaused, attemptFailed,
retryingIn, statusBytesDownloaded, mergeGroupFileMissing,
notAllPartsDownloaded / notAllClipPartsDownloaded, ffmpegMerge/
SplitFailed, diskSpaceShortFor, all preflight* messages, etc.
classifyDownloadError extended to recognize EN equivalents
(streamlink not found, no video stream, folder) so the retry
classification still works correctly when the language is EN.
The hand-rolled translation table in renderer.ts:downloadClip is
gone — backend strings are already locale-correct.
2. styles.css: --border-soft CSS var added to :root and the
theme-light override. Inline styles in index.html for the VOD
filter input / sort select / bulk bar were referencing
--bg-secondary / --text-primary / --border-color (which don't
exist) and falling through to dark hex fallbacks (#222 / #fff /
#444), producing a dark patch in light theme. Now uses
var(--bg-card) / var(--text) / var(--border-soft) which both
themes define.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two complete UX features.
1. Streamer list is now drag-and-drop reorderable. The order is
persisted via the existing config.streamers save path, so it
survives a restart. The dragstart-then-click race that would
normally fire selectStreamer when the drag is released is
suppressed via a 50ms post-dragend window.
2. VOD cards each get a top-left checkbox. Selecting >=1 card opens
a sticky action bar above the grid with "+ Queue" and "Clear"
buttons. Bulk-add iterates the selected URLs and calls addToQueue
for each, with a single per-batch toast summarizing the outcome.
Selection is cleared on streamer switch (per-streamer mental
model) but not persisted across reloads (stale selection across
restarts is more confusing than helpful).
Implementation notes:
- Click-on-checkbox is handled by a single delegated listener on
vodGrid (initVodGridSelectionDelegation), not per-card inline
handlers. The card .selected class is toggled in place to avoid
re-rendering the entire grid on every check.
- Streamer items are rebuilt from createElement so the existing
`event.stopPropagation(); removeStreamer(...)` inline pattern
is replaced with a real listener; defends against unusual
characters in streamer names even though Cycle 4 added the
4-25-char alphanumeric regex.
- styles.css: position: relative on .vod-card for the absolute-
positioned checkbox; .selected ring highlight; .dragging
opacity for streamer drag.
- DE / EN locale strings for the bulk-bar; setText / updateBar
hook into applyLanguageToStaticUI so the bar count updates on
language switch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Queue selector uses min-width instead of fixed width for double-digit numbers
- Drag-start handler validates item is still pending before allowing drag
- ensureUniqueFilename uses in-memory claim set to prevent TOCTOU race
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Queue section now uses flex layout with flex-shrink:0 on action buttons,
so they stay visible regardless of queue list length.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace checkboxes with numbered selectors (1, 2, 3...) that show the
merge order. Click order determines VOD sequence in the merged result.
Chronological auto-sort removed — user controls the order.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>