From 7e0b7f652a9c50afa14399ec69171c2f1e10028b Mon Sep 17 00:00:00 2001 From: 10k11 <339974264+10k11@users.noreply.github.com> Date: Sun, 8 Nov 2026 15:57:38 +0530 Subject: [PATCH] desktop: open the window even when offline; fetch yt-dlp in the background The first launch awaited the yt-dlp download and quit on failure, so the app never showed a window without internet (for example in the AppImage catalog test, which runs with --net=none). Co-Authored-By: Claude Sonnet 5.5 --- desktop/README.md | 2 +- desktop/ytdlp.mjs | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/desktop/README.md b/desktop/README.md index 649c490..95fd823 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -2,7 +2,7 @@ An Electron wrapper that runs the regular Flux server on `127.0.0.1` and shows it in a window. No Node, Docker or setup needed for users. The server code is unchanged; the app only sets environment variables (`FLUX_LOCAL_MODE=1`, data in the OS app-data folder). -- The **media engine** is downloaded (checksum-verified) on first launch into the app-data folder and self-updates on later launches. +- The **media engine** is downloaded (checksum-verified) in the background on first launch into the app-data folder and self-updates on later launches. The app opens even when offline; downloads start working once the engine has arrived. - **FFmpeg / FFprobe** are bundled through `ffmpeg-static` and `ffprobe-static`. - **Local mode** (`FLUX_LOCAL_MODE=1`) treats the person running the app as signed in, so full-length downloads work without Google sign-in. It is ignored unless the server listens on `127.0.0.1`. diff --git a/desktop/ytdlp.mjs b/desktop/ytdlp.mjs index d755aa3..2422efa 100644 --- a/desktop/ytdlp.mjs +++ b/desktop/ytdlp.mjs @@ -1,6 +1,6 @@ // Keeps a standalone yt-dlp in the app's data folder: downloaded and verified on // first launch, then self-updated in the background (sites change often). -import { mkdir, writeFile, chmod, access } from "node:fs/promises"; +import { mkdir, writeFile, chmod, access, rename } from "node:fs/promises"; import { createHash } from "node:crypto"; import { spawn } from "node:child_process"; import path from "node:path"; @@ -59,11 +59,17 @@ async function download(target) { createHash("sha256").update(bytes).digest("hex") !== expected.toLowerCase() ) throw new Error("Checksum verification failed for yt-dlp."); - await writeFile(target, bytes); - if (process.platform !== "win32") await chmod(target, 0o755); + // Write to a temp name first so an interrupted download is never mistaken for a working binary. + const tmp = `${target}.part`; + await writeFile(tmp, bytes); + if (process.platform !== "win32") await chmod(tmp, 0o755); + await rename(tmp, target); } -/** Returns the path to yt-dlp, downloading it on first run. Updates run in the background. */ +/** + * Returns the path to yt-dlp right away. On first run the download happens in the background, + * so the app still opens when offline; downloads work once yt-dlp has arrived. + */ export async function ensureYtDlp(binDir) { await mkdir(binDir, { recursive: true }); const target = path.join( @@ -75,7 +81,9 @@ export async function ensureYtDlp(binDir) { () => false, ); if (!exists) { - await download(target); + download(target).catch((error) => + console.error(`Could not fetch yt-dlp yet: ${error.message}`), + ); return target; } // Best effort: the standalone binary can update itself in place.