From 94c5723246e8f787ce644291f631730cc72ef1de Mon Sep 17 00:00:00 2001 From: debont80 Date: Tue, 30 Jun 2026 13:57:53 -0400 Subject: [PATCH] Fix L23/L78/L79: diagnostics hint, empty-state copy, SponsorBlock defaults L23: Diagnostics error list now shows "Showing 20 of N errors." when there are more than 20 logged errors. L78: DownloadsView empty-state copy updated from "Paste a URL above to get started" to "Paste a URL above, then click Download" -- matches the UI. L79: SponsorBlock default categories expanded from ['sponsor'] to ['sponsor', 'selfpromo', 'interaction'] -- sponsor-only was silently covering almost nothing; the three new defaults are universally unwanted. Existing SB tests updated to pass explicit categories instead of using defaults. typecheck + 242 tests + eslint + prettier green. Co-Authored-By: Claude Opus 4.8 --- CODE-AUDIT.md | 6 +++--- src/renderer/src/components/DownloadsView.tsx | 2 +- src/renderer/src/components/SettingsView.tsx | 5 +++++ src/shared/ipc.ts | 2 +- test/buildArgs.test.ts | 10 ++++++++-- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CODE-AUDIT.md b/CODE-AUDIT.md index c29bacb..51bd387 100644 --- a/CODE-AUDIT.md +++ b/CODE-AUDIT.md @@ -422,7 +422,7 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n version/update/export/import — two patterns in one file. - [ ] **L22 — DownloadOptionsForm shows both audio + video controls** regardless of the chosen kind in the per-download override panel (audio format shown for a video download, etc.). -- [ ] **L23 — Diagnostics shows first 20 errors** with no "showing 20 of N" hint (the copied +- [x] **L23 — Diagnostics shows first 20 errors** with no "showing 20 of N" hint (the copied report includes all). - [ ] **L24 — `window.open(htmlUrl, '_blank')`** in SettingsView is the only `window.open` in the app (relies on the window-open handler); elsewhere external opens go through IPC/`shell`. @@ -522,9 +522,9 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n `titleFromUrl` placeholder before metadata resolves ('YouTube video (id)'). - [x] **L77 — ffmpeg/ffprobe versions have no re-check affordance** (load once; "not found" sticks with no retry) unlike the yt-dlp "Check version" button. -- [ ] **L78 — `DownloadsView` empty-state copy** ("Paste a URL above to get started") doesn't match +- [x] **L78 — `DownloadsView` empty-state copy** ("Paste a URL above to get started") doesn't match the actual two-step Fetch→Download affordance. -- [ ] **L79 — SponsorBlock default categories = `['sponsor']` only** — enabling SB silently covers +- [x] **L79 — SponsorBlock default categories = `['sponsor']` only** — enabling SB silently covers just sponsors until the user expands categories (expectation gap). *Round 4 (2026-06-29) — doc/code drift, build artifacts, edge cases:* diff --git a/src/renderer/src/components/DownloadsView.tsx b/src/renderer/src/components/DownloadsView.tsx index 6126513..24cda71 100644 --- a/src/renderer/src/components/DownloadsView.tsx +++ b/src/renderer/src/components/DownloadsView.tsx @@ -133,7 +133,7 @@ export function DownloadsView(): React.JSX.Element { {items.length === 0 ? (
- Nothing queued yet. Paste a URL above to get started. + Nothing queued yet. Paste a URL above, then click Download.
) : ( {e.error} ))} + {errorEntries.length > 20 && ( + + Showing 20 of {errorEntries.length} errors. + + )} )} diff --git a/src/shared/ipc.ts b/src/shared/ipc.ts index ffd98cc..e09188d 100644 --- a/src/shared/ipc.ts +++ b/src/shared/ipc.ts @@ -217,7 +217,7 @@ export const DEFAULT_DOWNLOAD_OPTIONS: DownloadOptions = { autoSubtitles: false, sponsorBlock: false, sponsorBlockMode: 'remove', - sponsorBlockCategories: ['sponsor'], + sponsorBlockCategories: ['sponsor', 'selfpromo', 'interaction'], embedChapters: false, splitChapters: false, embedMetadata: true, diff --git a/test/buildArgs.test.ts b/test/buildArgs.test.ts index 612eb36..5d00cf5 100644 --- a/test/buildArgs.test.ts +++ b/test/buildArgs.test.ts @@ -220,13 +220,19 @@ describe('embedSubtitles', () => { describe('sponsorBlock', () => { it('remove → --sponsorblock-remove --force-keyframes-at-cuts', () => { - const argv = build(opts(), dlo({ sponsorBlock: true, sponsorBlockMode: 'remove' })) + const argv = build( + opts(), + dlo({ sponsorBlock: true, sponsorBlockMode: 'remove', sponsorBlockCategories: ['sponsor'] }) + ) expect(hasSeq(argv, '--sponsorblock-remove', 'sponsor', '--force-keyframes-at-cuts')).toBe(true) expect(argv).not.toContain('--sponsorblock-mark') }) it('mark → --sponsorblock-mark , no keyframe forcing', () => { - const argv = build(opts(), dlo({ sponsorBlock: true, sponsorBlockMode: 'mark' })) + const argv = build( + opts(), + dlo({ sponsorBlock: true, sponsorBlockMode: 'mark', sponsorBlockCategories: ['sponsor'] }) + ) expect(hasSeq(argv, '--sponsorblock-mark', 'sponsor')).toBe(true) expect(argv).not.toContain('--sponsorblock-remove') expect(argv).not.toContain('--force-keyframes-at-cuts')