Initial commit: AeroFetch — yt-dlp/YouTube downloader for Windows
Electron + React (Fluent UI) desktop frontend for yt-dlp: - Download queue with live progress, concurrency cap, cancel/retry - Format/quality picker via yt-dlp probe; audio extraction to MP3 - Settings + history persistence (electron-store / JSON) - Clipboard link auto-detect; persisted light/dark theme - NSIS + portable packaging (binaries bundled at build time, not in git) UI: "Studio" sidebar layout with a toffee-brown theme (light + neutral dark). Dropdowns use a native <select> and tooltips a CSS-only Hint, to avoid a dev-machine GPU overlay flicker/blank issue. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { app } from 'electron'
|
||||
import { join } from 'path'
|
||||
import { accessSync, mkdirSync, constants } from 'fs'
|
||||
|
||||
/**
|
||||
* When running as the portable build, keep all per-user data (settings, history,
|
||||
* caches — everything under `userData`) in an `AeroFetch-data` folder right next to
|
||||
* the portable .exe. That makes the app fully self-contained on a USB stick and
|
||||
* leaves nothing behind on a shared/library PC.
|
||||
*
|
||||
* Detection: electron-builder's `portable` target sets PORTABLE_EXECUTABLE_DIR at
|
||||
* runtime to the folder the user launched the exe from. The installed (NSIS) build
|
||||
* and dev don't set it, so they correctly use the default %APPDATA%\AeroFetch —
|
||||
* which is per-user and never requires admin either.
|
||||
*
|
||||
* If the portable folder is read-only (locked-down machine, read-only media), we
|
||||
* silently fall back to %APPDATA%. Either way the app needs no admin privileges.
|
||||
*
|
||||
* Must be called at startup, before the app is ready and before anything reads a
|
||||
* user path (electron-store, history DB, etc.).
|
||||
*/
|
||||
export function setupPortableData(): void {
|
||||
const portableExeDir = process.env.PORTABLE_EXECUTABLE_DIR
|
||||
if (!portableExeDir) return
|
||||
|
||||
const portableDataDir = join(portableExeDir, 'AeroFetch-data')
|
||||
try {
|
||||
mkdirSync(portableDataDir, { recursive: true })
|
||||
accessSync(portableDataDir, constants.W_OK)
|
||||
app.setPath('userData', portableDataDir)
|
||||
} catch {
|
||||
// Read-only media — keep the default %APPDATA% userData (per-user, no admin).
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user