Renderer refactoring

ui_enhancements
aandrew-me 3 weeks ago
parent 944e6c5db4
commit 17c231175c

@ -1,10 +1,10 @@
const cp = require("child_process");
const os = require("os");
const fs = require("fs");
const path = require("path");
const {shell, ipcRenderer, clipboard} = require("electron"); const {shell, ipcRenderer, clipboard} = require("electron");
const {default: YTDlpWrap} = require("yt-dlp-wrap-plus"); const {default: YTDlpWrap} = require("yt-dlp-wrap-plus");
const {constants} = require("fs/promises"); const {constants} = require("fs/promises");
const { homedir, platform } = require("os");
const { join } = require("path");
const { mkdirSync, accessSync, promises, existsSync } = require("fs");
const { execSync, spawn } = require("child_process");
const i18n = new (require("../translations/i18n"))(); const i18n = new (require("../translations/i18n"))();
@ -156,15 +156,14 @@ class YtDownloaderApp {
* Sets up the application's hidden directory and the default download directory. * Sets up the application's hidden directory and the default download directory.
*/ */
_setupDirectories() { _setupDirectories() {
const homedir = os.homedir(); const userHomeDir = homedir();
const hiddenDir = path.join(homedir, ".ytDownloader"); const hiddenDir = join(userHomeDir, ".ytDownloader");
fs.mkdirSync(hiddenDir, {recursive: true}); mkdirSync(hiddenDir, {recursive: true});
let defaultDownloadDir = path.join(homedir, "Downloads"); let defaultDownloadDir = join(userHomeDir, "Downloads");
if (os.platform() === "linux") { if (platform() === "linux") {
try { try {
const xdgDownloadDir = cp const xdgDownloadDir = execSync("xdg-user-dir DOWNLOAD")
.execSync("xdg-user-dir DOWNLOAD")
.toString() .toString()
.trim(); .trim();
if (xdgDownloadDir) { if (xdgDownloadDir) {
@ -180,7 +179,7 @@ class YtDownloaderApp {
); );
if (savedPath) { if (savedPath) {
try { try {
fs.accessSync(savedPath, constants.W_OK); accessSync(savedPath, constants.W_OK);
this.state.downloadDir = savedPath; this.state.downloadDir = savedPath;
} catch { } catch {
console.warn( console.warn(
@ -197,7 +196,7 @@ class YtDownloaderApp {
} }
$(CONSTANTS.DOM_IDS.PATH_DISPLAY).textContent = this.state.downloadDir; $(CONSTANTS.DOM_IDS.PATH_DISPLAY).textContent = this.state.downloadDir;
fs.mkdirSync(this.state.downloadDir, {recursive: true}); mkdirSync(this.state.downloadDir, {recursive: true});
} }
/** /**
@ -238,14 +237,14 @@ class YtDownloaderApp {
* @returns {Promise<string>} A promise that resolves with the path to yt-dlp. * @returns {Promise<string>} A promise that resolves with the path to yt-dlp.
*/ */
async _findOrDownloadYtDlp() { async _findOrDownloadYtDlp() {
const hiddenDir = path.join(os.homedir(), ".ytDownloader"); const hiddenDir = join(homedir(), ".ytDownloader");
const defaultYtDlpName = const defaultYtDlpName =
os.platform() === "win32" ? "ytdlp.exe" : "ytdlp"; platform() === "win32" ? "ytdlp.exe" : "ytdlp";
const defaultYtDlpPath = path.join(hiddenDir, defaultYtDlpName); const defaultYtDlpPath = join(hiddenDir, defaultYtDlpName);
// Priority 1: Environment Variable // Priority 1: Environment Variable
if (process.env.YTDOWNLOADER_YTDLP_PATH) { if (process.env.YTDOWNLOADER_YTDLP_PATH) {
if (fs.existsSync(process.env.YTDOWNLOADER_YTDLP_PATH)) { if (existsSync(process.env.YTDOWNLOADER_YTDLP_PATH)) {
return process.env.YTDOWNLOADER_YTDLP_PATH; return process.env.YTDOWNLOADER_YTDLP_PATH;
} }
throw new Error( throw new Error(
@ -254,17 +253,17 @@ class YtDownloaderApp {
} }
// Priority 2: System-installed versions (macOS, BSD) // Priority 2: System-installed versions (macOS, BSD)
if (os.platform() === "darwin") { if (platform() === "darwin") {
const possiblePaths = [ const possiblePaths = [
"/opt/homebrew/bin/yt-dlp", "/opt/homebrew/bin/yt-dlp",
"/usr/local/bin/yt-dlp", "/usr/local/bin/yt-dlp",
]; ];
const foundPath = possiblePaths.find((p) => fs.existsSync(p)); const foundPath = possiblePaths.find((p) => existsSync(p));
if (foundPath) return foundPath; if (foundPath) return foundPath;
$(CONSTANTS.DOM_IDS.POPUP_BOX_MAC).style.display = "block"; $(CONSTANTS.DOM_IDS.POPUP_BOX_MAC).style.display = "block";
} else if (os.platform() === "freebsd") { } else if (platform() === "freebsd") {
try { try {
return cp.execSync("which yt-dlp").toString().trim(); return execSync("which yt-dlp").toString().trim();
} catch { } catch {
throw new Error( throw new Error(
"No yt-dlp found in PATH on FreeBSD. Please install it." "No yt-dlp found in PATH on FreeBSD. Please install it."
@ -276,8 +275,8 @@ class YtDownloaderApp {
const storedPath = localStorage.getItem( const storedPath = localStorage.getItem(
CONSTANTS.LOCAL_STORAGE_KEYS.YT_DLP_PATH CONSTANTS.LOCAL_STORAGE_KEYS.YT_DLP_PATH
); );
if (storedPath && fs.existsSync(storedPath)) { if (storedPath && existsSync(storedPath)) {
cp.spawn(`"${storedPath}"`, ["-U"], {shell: true}) spawn(`"${storedPath}"`, ["-U"], {shell: true})
.on("error", (err) => .on("error", (err) =>
console.error( console.error(
"Failed to run background yt-dlp update:", "Failed to run background yt-dlp update:",
@ -292,7 +291,7 @@ class YtDownloaderApp {
// Priority 4: Default location or download // Priority 4: Default location or download
try { try {
await fs.promises.access(defaultYtDlpPath); await promises.access(defaultYtDlpPath);
return defaultYtDlpPath; return defaultYtDlpPath;
} catch { } catch {
console.log("yt-dlp not found, downloading..."); console.log("yt-dlp not found, downloading...");
@ -328,7 +327,7 @@ class YtDownloaderApp {
async _findFfmpeg() { async _findFfmpeg() {
// Priority 1: Environment Variable // Priority 1: Environment Variable
if (process.env.YTDOWNLOADER_FFMPEG_PATH) { if (process.env.YTDOWNLOADER_FFMPEG_PATH) {
if (fs.existsSync(process.env.YTDOWNLOADER_FFMPEG_PATH)) { if (existsSync(process.env.YTDOWNLOADER_FFMPEG_PATH)) {
return process.env.YTDOWNLOADER_FFMPEG_PATH; return process.env.YTDOWNLOADER_FFMPEG_PATH;
} }
throw new Error( throw new Error(
@ -337,9 +336,9 @@ class YtDownloaderApp {
} }
// Priority 2: System-installed (FreeBSD) // Priority 2: System-installed (FreeBSD)
if (os.platform() === "freebsd") { if (platform() === "freebsd") {
try { try {
return cp.execSync("which ffmpeg").toString().trim(); return execSync("which ffmpeg").toString().trim();
} catch { } catch {
throw new Error( throw new Error(
"No ffmpeg found in PATH on FreeBSD. App may not work correctly." "No ffmpeg found in PATH on FreeBSD. App may not work correctly."
@ -348,9 +347,9 @@ class YtDownloaderApp {
} }
// Priority 3: Bundled ffmpeg // Priority 3: Bundled ffmpeg
return os.platform() === "win32" return platform() === "win32"
? path.join(__dirname, "..", "ffmpeg.exe") ? join(__dirname, "..", "ffmpeg.exe")
: path.join(__dirname, "..", "ffmpeg"); : join(__dirname, "..", "ffmpeg");
} }
/** /**
@ -460,14 +459,14 @@ class YtDownloaderApp {
Object.entries(menuMapping).forEach(([id, page]) => { Object.entries(menuMapping).forEach(([id, page]) => {
$(id)?.addEventListener("click", () => { $(id)?.addEventListener("click", () => {
this._closeMenu(); this._closeMenu();
ipcRenderer.send("load-page", path.join(__dirname, page)); ipcRenderer.send("load-page", join(__dirname, page));
}); });
}); });
Object.entries(windowMapping).forEach(([id, page]) => { Object.entries(windowMapping).forEach(([id, page]) => {
$(id)?.addEventListener("click", () => { $(id)?.addEventListener("click", () => {
this._closeMenu(); this._closeMenu();
ipcRenderer.send("load-win", path.join(__dirname, page)); ipcRenderer.send("load-win", join(__dirname, page));
}); });
}); });
@ -760,7 +759,7 @@ class YtDownloaderApp {
// Sanitize filename // Sanitize filename
const invalidChars = const invalidChars =
os.platform() === "win32" ? /[<>:"/\\|?*[\]`#]/g : /["/`#]/g; platform() === "win32" ? /[<>:"/\\|?*[\]`#]/g : /["/`#]/g;
let finalFilename = title let finalFilename = title
.replace(invalidChars, "") .replace(invalidChars, "")
.trim() .trim()
@ -770,12 +769,12 @@ class YtDownloaderApp {
} }
if (rangeCmd) { if (rangeCmd) {
let rangeTxt = rangeCmd.replace("*", ""); let rangeTxt = rangeCmd.replace("*", "");
if (os.platform() === "win32") if (platform() === "win32")
rangeTxt = rangeTxt.replace(/:/g, "_"); rangeTxt = rangeTxt.replace(/:/g, "_");
finalFilename += ` [${rangeTxt}]`; finalFilename += ` [${rangeTxt}]`;
} }
const outputPath = `"${path.join( const outputPath = `"${join(
this.state.downloadDir, this.state.downloadDir,
`${finalFilename}.${ext}` `${finalFilename}.${ext}`
)}"`; )}"`;
@ -1138,7 +1137,7 @@ class YtDownloaderApp {
if (!progressEl) return; if (!progressEl) return;
const fullFilename = `${filename}.${ext}`; const fullFilename = `${filename}.${ext}`;
const fullPath = path.join(this.state.downloadDir, fullFilename); const fullPath = join(this.state.downloadDir, fullFilename);
progressEl.innerHTML = ""; // Clear progress bar progressEl.innerHTML = ""; // Clear progress bar
const link = document.createElement("b"); const link = document.createElement("b");
@ -1159,7 +1158,7 @@ class YtDownloaderApp {
}; };
// Add to download history // Add to download history
fs.promises.stat(fullPath) promises.stat(fullPath)
.then(stat => { .then(stat => {
const fileSize = stat.size || 0; const fileSize = stat.size || 0;
ipcRenderer.invoke("add-to-history", { ipcRenderer.invoke("add-to-history", {

Loading…
Cancel
Save