fix(renderer): L138/L145 clipboard privacy+dedup, M14 state-driven settings search
- L138: gate the clipboard check on the settings `loaded` flag (not just clipboardWatch), so it never reads using the pre-load fallback; the effect re-runs when loaded flips true so a pre-launch copied link is still offered. - L145: lastSeen is module-level, so a dismissed clipboard link stays suppressed across the hook's remount on a Downloads<->Library tab switch. - M14: SettingsView renders each card in a React-owned wrapper and drives its visibility from a `hidden` state array — the search no longer writes display:none onto a card's own DOM node. Matching still reads textContent (full label coverage, no per-card keyword upkeep). typecheck + 268 tests + eslint + prettier green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+16
-4
@@ -363,9 +363,14 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
those to the shared hook incrementally.*
|
||||
- [x] **M13 — Inconsistent secret-field masking.** `updateToken` uses `type="password"`; `proxy`
|
||||
(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
|
||||
- [x] **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
|
||||
matches on `textContent` incl. hidden text. Prefer state-driven filtering.
|
||||
matches on `textContent` incl. hidden text. Prefer state-driven filtering. *Fixed: each card renders
|
||||
inside a React-owned wrapper whose visibility is driven by a `hidden` state array in
|
||||
[SettingsView.tsx](src/renderer/src/components/SettingsView.tsx) — the filter no longer writes
|
||||
`display` onto a card's own node, so a card setting its own inline style can't break it. Matching still
|
||||
reads the wrapper's `textContent` (so search covers every visible label without hand-maintained
|
||||
per-card keywords); the minor "matches hidden descendant text" point is unchanged and left as-is.*
|
||||
- [x] **M15 — Nested interactive controls in `role="button"` (a11y).** LibraryView's group header
|
||||
is a `role="button"` div containing `<Button>`s (All / Download) — invalid ARIA / keyboard
|
||||
semantics. Make the header a real element with sibling buttons.
|
||||
@@ -789,9 +794,13 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
instead of an indeterminate state. *Fixed: `parseProgress` now sets `sizeUnknown: !totalBytes` on
|
||||
`DownloadProgress`; the store threads it onto the item and `QueueItem` renders an indeterminate bar +
|
||||
"Downloading…" (instead of a frozen 0%) when it's set, reusing the existing SR7 indeterminate path.*
|
||||
- [ ] **L138 — Clipboard read on every window focus.** [useClipboardLink.ts](src/renderer/src/useClipboardLink.ts)
|
||||
- [x] **L138 — Clipboard read on every window focus.** [useClipboardLink.ts](src/renderer/src/useClipboardLink.ts)
|
||||
reads the full clipboard on each `focus` (and once on mount, possibly before `clipboardWatch` has
|
||||
loaded — FALLBACK is `true`). Reading all clipboard text whenever focused may surprise privacy-conscious users.
|
||||
*Fixed: the check now gates on the settings store's `loaded` flag as well as `clipboardWatch`, so the
|
||||
clipboard is never read using the pre-load fallback (the mount-before-settings-load window); the effect
|
||||
re-runs when `loaded` flips true, so a link copied before launch is still offered once the real setting
|
||||
is known. (Per-focus reads were already gated on `clipboardWatch`; the privacy default itself is SR4.)*
|
||||
- [ ] **L139 — Auto-update vs concurrent spawn race.** `runStartupYtdlpAutoUpdate` can overwrite
|
||||
`yt-dlp.exe` on launch while a deep-link/queued download spawns the same binary — a Windows
|
||||
file-in-use/corrupt-spawn window.
|
||||
@@ -816,8 +825,11 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
(mitigated today by the embedded fallback tray icon).
|
||||
- [ ] **L144 — Duplicate guard checks the queue only, not history.** Re-adding a URL downloaded earlier
|
||||
(already cleared from the queue) gives no "already downloaded" hint (roadmap notes this as a possible extension).
|
||||
- [ ] **L145 — `useClipboardLink` re-offers a dismissed link after a tab switch.** `lastSeen` is
|
||||
- [x] **L145 — `useClipboardLink` re-offers a dismissed link after a tab switch.** `lastSeen` is
|
||||
per-hook-instance; switching Downloads↔Library remounts it, so a previously-dismissed clipboard link is offered again.
|
||||
*Fixed: `lastSeen` is now a module-level variable (not a per-instance `useRef`), so a dismissed/accepted
|
||||
clipboard link stays suppressed across hook remounts. Only one field is mounted at a time (tab switch), so
|
||||
there's no cross-field contention.*
|
||||
- [x] **L146 — `parseTrimSections` accepts malformed multi-colon times.** The `\d+(?::\d{1,2})*` pattern
|
||||
passes tokens like `1:2:3:4-5:6:7:8`, which then reach yt-dlp's `--download-sections` and fail there
|
||||
rather than being rejected up front.
|
||||
|
||||
Reference in New Issue
Block a user