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 <noreply@anthropic.com>
This commit is contained in:
+3
-3
@@ -422,7 +422,7 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
|||||||
version/update/export/import — two patterns in one file.
|
version/update/export/import — two patterns in one file.
|
||||||
- [ ] **L22 — DownloadOptionsForm shows both audio + video controls** regardless of the chosen
|
- [ ] **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.).
|
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).
|
report includes all).
|
||||||
- [ ] **L24 — `window.open(htmlUrl, '_blank')`** in SettingsView is the only `window.open` in the
|
- [ ] **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`.
|
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)').
|
`titleFromUrl` placeholder before metadata resolves ('YouTube video (id)').
|
||||||
- [x] **L77 — ffmpeg/ffprobe versions have no re-check affordance** (load once; "not found" sticks
|
- [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.
|
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.
|
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).
|
just sponsors until the user expands categories (expectation gap).
|
||||||
|
|
||||||
*Round 4 (2026-06-29) — doc/code drift, build artifacts, edge cases:*
|
*Round 4 (2026-06-29) — doc/code drift, build artifacts, edge cases:*
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export function DownloadsView(): React.JSX.Element {
|
|||||||
{items.length === 0 ? (
|
{items.length === 0 ? (
|
||||||
<div className={styles.empty}>
|
<div className={styles.empty}>
|
||||||
<ArrowDownloadRegular fontSize={40} />
|
<ArrowDownloadRegular fontSize={40} />
|
||||||
<Body1>Nothing queued yet. Paste a URL above to get started.</Body1>
|
<Body1>Nothing queued yet. Paste a URL above, then click Download.</Body1>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<VirtualList
|
<VirtualList
|
||||||
|
|||||||
@@ -1008,6 +1008,11 @@ export function SettingsView(): React.JSX.Element {
|
|||||||
<Caption1 className={errText.errorPre}>{e.error}</Caption1>
|
<Caption1 className={errText.errorPre}>{e.error}</Caption1>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
{errorEntries.length > 20 && (
|
||||||
|
<Caption1 className={styles.hint}>
|
||||||
|
Showing 20 of {errorEntries.length} errors.
|
||||||
|
</Caption1>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
+1
-1
@@ -217,7 +217,7 @@ export const DEFAULT_DOWNLOAD_OPTIONS: DownloadOptions = {
|
|||||||
autoSubtitles: false,
|
autoSubtitles: false,
|
||||||
sponsorBlock: false,
|
sponsorBlock: false,
|
||||||
sponsorBlockMode: 'remove',
|
sponsorBlockMode: 'remove',
|
||||||
sponsorBlockCategories: ['sponsor'],
|
sponsorBlockCategories: ['sponsor', 'selfpromo', 'interaction'],
|
||||||
embedChapters: false,
|
embedChapters: false,
|
||||||
splitChapters: false,
|
splitChapters: false,
|
||||||
embedMetadata: true,
|
embedMetadata: true,
|
||||||
|
|||||||
@@ -220,13 +220,19 @@ describe('embedSubtitles', () => {
|
|||||||
|
|
||||||
describe('sponsorBlock', () => {
|
describe('sponsorBlock', () => {
|
||||||
it('remove → --sponsorblock-remove <cats> --force-keyframes-at-cuts', () => {
|
it('remove → --sponsorblock-remove <cats> --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(hasSeq(argv, '--sponsorblock-remove', 'sponsor', '--force-keyframes-at-cuts')).toBe(true)
|
||||||
expect(argv).not.toContain('--sponsorblock-mark')
|
expect(argv).not.toContain('--sponsorblock-mark')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('mark → --sponsorblock-mark <cats>, no keyframe forcing', () => {
|
it('mark → --sponsorblock-mark <cats>, 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(hasSeq(argv, '--sponsorblock-mark', 'sponsor')).toBe(true)
|
||||||
expect(argv).not.toContain('--sponsorblock-remove')
|
expect(argv).not.toContain('--sponsorblock-remove')
|
||||||
expect(argv).not.toContain('--force-keyframes-at-cuts')
|
expect(argv).not.toContain('--force-keyframes-at-cuts')
|
||||||
|
|||||||
Reference in New Issue
Block a user