Fix L7/M13/M37: badge colors, secret masking, dev-jargon hints

L7: Canceled status chip now uses 'subtle' color (neutral) instead of 'warning'
    (amber) -- distinguishing it from paused which remains amber.
M13: Proxy URL and YouTube PO-token inputs now use type="password" to mask
     credentials, matching updateToken. Proxy URLs can carry user:pass; PO tokens
     are opaque secrets.
M37: Rewrite two dev-facing hints -- youtubePlayerClient now says 'how AeroFetch
     identifies itself to YouTube' instead of citing yt-dlp internals; filename
     template says 'Controls how saved files are named' instead of 'yt-dlp output
     template'. Remaining hints (cookie browser, aria2c, etc.) were already clean.

typecheck + 242 tests + eslint + prettier green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 14:01:25 -04:00
parent 94c5723246
commit 63a327a31c
3 changed files with 8 additions and 6 deletions
+3 -3
View File
@@ -258,7 +258,7 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
`style={{ color: … }}` error spans + its local `errorRowText` class. The remaining red references live in `style={{ color: … }}` error spans + its local `errorRowText` class. The remaining red references live in
per-component `makeStyles` classes (DownloadBar/LibraryView/QueueItem/TerminalView), not inline; migrate per-component `makeStyles` classes (DownloadBar/LibraryView/QueueItem/TerminalView), not inline; migrate
those to the shared hook incrementally.* those to the shared hook incrementally.*
- [ ] **M13 — Inconsistent secret-field masking.** `updateToken` uses `type="password"`; `proxy` - [x] **M13 — Inconsistent secret-field masking.** `updateToken` uses `type="password"`; `proxy`
(may carry `user:pass@`) and `youtubePoToken` (a token) are plain-text Inputs. (may carry `user:pass@`) and `youtubePoToken` (a token) are plain-text Inputs.
- [ ] **M14 — Settings search mutates React-owned DOM.** The search toggles each card's - [ ] **M14 — Settings search mutates React-owned DOM.** The search toggles each card's
`el.style.display` directly; fragile (breaks if a card ever gets a conditional `style`) and `el.style.display` directly; fragile (breaks if a card ever gets a conditional `style`) and
@@ -361,7 +361,7 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
pending/error/canceled only, so selecting 5 rows (incl. 2 already-downloaded) shows "Download **3** pending/error/canceled only, so selecting 5 rows (incl. 2 already-downloaded) shows "Download **3**
selected." The checkbox count and the button count silently disagree. **Fix:** only show checkboxes on selected." The checkbox count and the button count silently disagree. **Fix:** only show checkboxes on
actionable rows, or count all selected. actionable rows, or count all selected.
- [ ] **M37 — End-user hints leak developer/internal references.** Settings hints surface dev-facing - [x] **M37 — End-user hints leak developer/internal references.** Settings hints surface dev-facing
detail: "Requires aria2c.exe in resources/bin (see the README there)", "paste a read-only **Gitea** detail: "Requires aria2c.exe in resources/bin (see the README there)", "paste a read-only **Gitea**
token", "sent via `--extractor-args`", "breaking downloads with **403** errors", "open a locked cookie token", "sent via `--extractor-args`", "breaking downloads with **403** errors", "open a locked cookie
database", and roadmap status ("automatic minting is **planned**"). These read as code comments, not database", and roadmap status ("automatic minting is **planned**"). These read as code comments, not
@@ -388,7 +388,7 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
where a class exists elsewhere. where a class exists elsewhere.
- [ ] **L6 — Control height mismatch.** `Select` is a fixed 32px sitting beside `size="large"` - [ ] **L6 — Control height mismatch.** `Select` is a fixed 32px sitting beside `size="large"`
(~40px) Input/Buttons in DownloadBar. (~40px) Input/Buttons in DownloadBar.
- [ ] **L7 — `canceled` and `paused` share the 'warning' badge color** (QueueItem) — visually - [x] **L7 — `canceled` and `paused` share the 'warning' badge color** (QueueItem) — visually
ambiguous. ambiguous.
- [ ] **L8 — Index/compound list keys.** TerminalView keys log lines by array index; Settings - [ ] **L8 — Index/compound list keys.** TerminalView keys log lines by array index; Settings
Diagnostics keys by `id + occurredAt` while every other list keys by `id` alone. Diagnostics keys by `id + occurredAt` while every other list keys by `id` alone.
+4 -2
View File
@@ -677,6 +677,7 @@ export function SettingsView(): React.JSX.Element {
hint="HTTP/HTTPS/SOCKS proxy URL, e.g. socks5://127.0.0.1:1080. Leave blank to use the system default." hint="HTTP/HTTPS/SOCKS proxy URL, e.g. socks5://127.0.0.1:1080. Leave blank to use the system default."
> >
<Input <Input
type="password"
value={proxy} value={proxy}
placeholder="socks5://127.0.0.1:1080" placeholder="socks5://127.0.0.1:1080"
onChange={(_, d) => update({ proxy: d.value })} onChange={(_, d) => update({ proxy: d.value })}
@@ -707,7 +708,7 @@ export function SettingsView(): React.JSX.Element {
<Field <Field
label="YouTube client (advanced)" label="YouTube client (advanced)"
hint="Override the YouTube extraction client when downloads start failing the bot check. Try web_safari, tv, or mweb. Leave blank for yt-dlp's default." hint="Override how AeroFetch identifies itself to YouTube when downloads start failing. Try web_safari, tv, or mweb. Leave blank for the automatic default."
> >
<Input <Input
value={youtubePlayerClient} value={youtubePlayerClient}
@@ -725,6 +726,7 @@ export function SettingsView(): React.JSX.Element {
> >
<div className={styles.folderRow}> <div className={styles.folderRow}>
<Input <Input
type="password"
style={{ flexGrow: 1 }} style={{ flexGrow: 1 }}
value={youtubePoToken} value={youtubePoToken}
placeholder="(none)" placeholder="(none)"
@@ -878,7 +880,7 @@ export function SettingsView(): React.JSX.Element {
</div> </div>
<Field <Field
label="Filename template" label="Filename template"
hint="yt-dlp output template. Tokens like %(title)s and %(ext)s are filled in per video." hint="Controls how saved files are named. Use %(title)s for the video title, %(ext)s for the extension, and similar tokens."
> >
<Input <Input
value={filenameTemplate} value={filenameTemplate}
@@ -21,7 +21,7 @@ const STATUS_CHIP: Record<ChipStatus, { label: string; color: ChipColor }> = {
saved: { label: 'Saved', color: 'subtle' }, saved: { label: 'Saved', color: 'subtle' },
completed: { label: 'Completed', color: 'success' }, completed: { label: 'Completed', color: 'success' },
error: { label: 'Failed', color: 'danger' }, error: { label: 'Failed', color: 'danger' },
canceled: { label: 'Canceled', color: 'warning' } canceled: { label: 'Canceled', color: 'subtle' }
} }
/** Shared status chip used by the download queue and the library item list. */ /** Shared status chip used by the download queue and the library item list. */