Fix L46/L71/L74: unify yt-dlp missing message, editable dir inputs, swatch a11y

L46: Introduced YTDLP_MISSING_MSG constant in binaries.ts. All four callers
     (download, indexer, probe, ytdlp) now emit the same user-facing string:
     "yt-dlp.exe is missing. Open Settings -> Software update to re-download it."
     This removes newline-embedded messages and four divergent phrasings.

L71: Removed readOnly from videoDir/audioDir folder inputs in SettingsView.
     Added onChange handler so users can paste or type a path directly without
     being forced to use the Browse button. The path still flows through
     applySettings() in main, which validates it.

L74: Accent color swatches were triple-labeled (aria-pressed + aria-label +
     title). Replaced with a single aria-label that embeds "(selected)" state,
     plus title for the hover tooltip. Removed the incorrect aria-pressed
     (these are selection buttons, not toggles).

typecheck + 242 tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 14:27:02 -04:00
parent b035a88873
commit 3ae4a5357c
7 changed files with 20 additions and 16 deletions
+4
View File
@@ -80,6 +80,10 @@ export function getFfprobePath(): string {
return join(getBinDir(), 'ffprobe.exe')
}
/** User-facing error shown whenever yt-dlp.exe is not found at startup. */
export const YTDLP_MISSING_MSG =
'yt-dlp.exe is missing. Open Settings → Software update to re-download it.'
/** Optional bundled external downloader; absent unless dropped into resources/bin. */
export function getAria2cPath(): string {
return join(getBinDir(), 'aria2c.exe')
+3 -2
View File
@@ -10,7 +10,8 @@ import {
getFfmpegPath,
getFfprobePath,
getSystem32Path,
getAppIconImage
getAppIconImage,
YTDLP_MISSING_MSG
} from './binaries'
import { getSettings, getDownloadArchivePath, getDefaultMediaDir } from './settings'
import { ensureManagedYtdlp } from './ytdlp'
@@ -225,7 +226,7 @@ export function startDownload(wc: WebContents, opts: StartDownloadOptions): Star
if (!existsSync(ytdlp)) {
return {
ok: false,
error: `yt-dlp.exe is missing and couldn't be restored from the bundle.\nReinstall AeroFetch, or drop yt-dlp.exe into resources/bin/ (see the README there).`
error: YTDLP_MISSING_MSG
}
}
// ffmpeg is used by nearly every download (merge, audio extract, thumbnail/
+2 -2
View File
@@ -11,7 +11,7 @@
import { execFile } from 'child_process'
import { existsSync } from 'fs'
import { getYtdlpPath } from './binaries'
import { getYtdlpPath, YTDLP_MISSING_MSG } from './binaries'
import { cleanError } from './log'
import { assertHttpUrl } from './url'
import {
@@ -90,7 +90,7 @@ export async function indexSource(
return { ok: false, error: (e as Error).message }
}
if (!existsSync(getYtdlpPath())) {
return { ok: false, error: 'yt-dlp.exe not found. Drop it into resources/bin/.' }
return { ok: false, error: YTDLP_MISSING_MSG }
}
const cls = classifySource(url)
+2 -2
View File
@@ -1,6 +1,6 @@
import { execFile } from 'child_process'
import { existsSync } from 'fs'
import { getYtdlpPath } from './binaries'
import { getYtdlpPath, YTDLP_MISSING_MSG } from './binaries'
import { fmtBytes } from './lib/formatters'
import { cleanError } from './log'
import { assertHttpUrl } from './url'
@@ -115,7 +115,7 @@ export function probeMedia(url: string): Promise<ProbeResult> {
if (!existsSync(ytdlp)) {
return Promise.resolve({
ok: false,
error: `yt-dlp.exe not found at ${ytdlp}\nDrop it into resources/bin/ (see the README there).`
error: YTDLP_MISSING_MSG
})
}
let target: string
+3 -3
View File
@@ -1,7 +1,7 @@
import { execFile } from 'child_process'
import { existsSync, mkdirSync, copyFileSync } from 'fs'
import { dirname } from 'path'
import { getYtdlpPath, getBundledYtdlpPath } from './binaries'
import { getYtdlpPath, getBundledYtdlpPath, YTDLP_MISSING_MSG } from './binaries'
import { getSettings, setSettings } from './settings'
import { shouldAutoCheckYtdlp } from './ytdlpPolicy'
import {
@@ -39,7 +39,7 @@ export function getYtdlpVersion(): Promise<YtdlpVersionResult> {
if (!existsSync(ytdlpPath)) {
return Promise.resolve({
ok: false,
error: `yt-dlp.exe not found at ${ytdlpPath}\nDownload it into resources/bin/ (see the README there).`
error: YTDLP_MISSING_MSG
})
}
@@ -85,7 +85,7 @@ export function updateYtdlp(channel: YtdlpUpdateChannel): Promise<YtdlpUpdateRes
if (!existsSync(ytdlpPath)) {
return Promise.resolve({
ok: false,
error: `yt-dlp.exe not found at ${ytdlpPath}\nDownload it into resources/bin/ (see the README there).`
error: YTDLP_MISSING_MSG
})
}