Route downloads into Documents\Video / Documents\Audio and simplify the home page
- Create Documents\Video and Documents\Audio on startup (ensureMediaDirs), and route each download into them by kind when no explicit output folder is set. An empty outputDir now means "sort by type"; a chosen folder still overrides for both kinds. - Settings/Onboarding "Download folder" gains a placeholder + hint describing the blank = route-by-type behaviour. - Trim the home download bar to the essentials: URL box, Search and Paste buttons, format/quality, and the Download button. Removed the private-mode toggle, per-download Options panel, custom-command panel, command preview, and the saving-to-folder line. - Bump version to 0.3.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+30
-5
@@ -1,5 +1,6 @@
|
||||
import { app } from 'electron'
|
||||
import { join } from 'path'
|
||||
import { mkdirSync } from 'fs'
|
||||
import Store from 'electron-store'
|
||||
import { isSafeFilenameTemplate, isSafeOutputDir } from './validation'
|
||||
import {
|
||||
@@ -16,7 +17,7 @@ import {
|
||||
} from '@shared/ipc'
|
||||
|
||||
const DEFAULTS: Settings = {
|
||||
outputDir: '', // resolved to the OS Downloads folder on first read
|
||||
outputDir: '', // blank = route by kind into Documents\Video / Documents\Audio (see getDefaultMediaDir)
|
||||
defaultKind: 'video',
|
||||
defaultVideoQuality: 'Best available',
|
||||
defaultAudioQuality: 'Best (MP3)',
|
||||
@@ -45,6 +46,31 @@ export function getDownloadArchivePath(): string {
|
||||
return join(app.getPath('userData'), 'download-archive.txt')
|
||||
}
|
||||
|
||||
/**
|
||||
* The default per-kind download destination: video → Documents\Video,
|
||||
* audio → Documents\Audio. Used when the user hasn't set an explicit output
|
||||
* folder (Settings → Download folder), so downloads are sorted by type.
|
||||
*/
|
||||
export function getDefaultMediaDir(kind: 'video' | 'audio'): string {
|
||||
return join(app.getPath('documents'), kind === 'audio' ? 'Audio' : 'Video')
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Documents\Video and Documents\Audio folders up front (called once
|
||||
* at startup) so they exist the moment the app opens, not just after the first
|
||||
* download. Best-effort: yt-dlp also creates the output dir at download time, so
|
||||
* a failure here (read-only Documents, redirected folder) is non-fatal.
|
||||
*/
|
||||
export function ensureMediaDirs(): void {
|
||||
for (const kind of ['video', 'audio'] as const) {
|
||||
try {
|
||||
mkdirSync(getDefaultMediaDir(kind), { recursive: true })
|
||||
} catch {
|
||||
/* non-fatal — the download path will be created on demand instead */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Coerce an untrusted partial into a valid DownloadOptions, falling back to the
|
||||
// defaults for any missing/invalid field. Used both to migrate older settings
|
||||
// files (which predate downloadOptions) and to validate renderer writes.
|
||||
@@ -100,10 +126,9 @@ export function getSettings(): Settings {
|
||||
// `set`, so only write when something actually changed — otherwise this churns
|
||||
// the settings file on every read. (audit P1)
|
||||
const cur = s.store
|
||||
if (!cur.outputDir) {
|
||||
// Fill in the real Downloads path the first time, and persist it once.
|
||||
s.set('outputDir', app.getPath('downloads'))
|
||||
}
|
||||
// outputDir is intentionally left blank by default — an empty value routes each
|
||||
// download into Documents\Video / Documents\Audio by kind (see buildCommand).
|
||||
// Only an explicit user choice (Settings → Download folder) overrides that.
|
||||
// Migrate settings files that predate downloadOptions (or hold a partial one),
|
||||
// but only persist when sanitizing actually altered the stored value.
|
||||
const sanitized = sanitizeOptions(cur.downloadOptions)
|
||||
|
||||
Reference in New Issue
Block a user