From c7f919fe183f956f963f9fb646141d3c68ecb0ed Mon Sep 17 00:00:00 2001 From: lenafx Date: Wed, 17 Dec 2025 21:32:34 +0100 Subject: [PATCH] fixed an error where app wouldnt launch --- desktop/main.js | 92 ++++++++++++++++++++++++++-- desktop/package-lock.json | 42 ++++++------- desktop/package.json | 15 +++-- desktop/server.js | 11 ++-- desktop/src/api/user/user.service.ts | 2 +- desktop/src/shared/headless.js | 32 +++++++++- 6 files changed, 151 insertions(+), 43 deletions(-) diff --git a/desktop/main.js b/desktop/main.js index 33c0460..12accf0 100644 --- a/desktop/main.js +++ b/desktop/main.js @@ -1,12 +1,64 @@ const { app, BrowserWindow, ipcMain } = require('electron'); const { fork } = require('child_process'); const path = require('path'); +const log = require('electron-log'); + +log.transports.file.level = 'info'; +log.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}'; let win; let backend; +const net = require('net'); + +function waitForServer(port, host = '127.0.0.1', timeout = 10000) { + return new Promise((resolve, reject) => { + const start = Date.now(); + + const check = () => { + const socket = new net.Socket(); + + socket + .once('connect', () => { + socket.destroy(); + resolve(); + }) + .once('error', () => { + socket.destroy(); + if (Date.now() - start > timeout) { + reject(new Error('Backend timeout')); + } else { + setTimeout(check, 200); + } + }) + .connect(port, host); + }; + + check(); + }); +} function startBackend() { - backend = fork(path.join(__dirname, 'server.js')); + backend = fork(path.join(__dirname, 'server.js'), [], { + stdio: ['pipe', 'pipe', 'pipe', 'ipc'], + env: { + ...process.env, + IS_PACKAGED: app.isPackaged ? 'true' : 'false' + } + }); + + log.info('Starting backend process...'); + + backend.stdout.on('data', (data) => { + log.info(`[Backend]: ${data.toString().trim()}`); + }); + + backend.stderr.on('data', (data) => { + log.error(`[Backend ERROR]: ${data.toString().trim()}`); + }); + + backend.on('exit', (code) => { + log.warn(`Backend process exited with code: ${code}`); + }); } function createWindow() { @@ -23,19 +75,47 @@ function createWindow() { }); win.setMenu(null); + win.loadURL('http://localhost:54322'); + + win.on('closed', () => { + win = null; + }); } ipcMain.on("win:minimize", () => win.minimize()); -ipcMain.on("win:maximize", () => win.maximize()); +ipcMain.on("win:maximize", () => { + if (win.isMaximized()) { + win.unmaximize(); + } else { + win.maximize(); + } +}); ipcMain.on("win:close", () => win.close()); -app.whenReady().then(() => { +process.on('uncaughtException', (err) => { + log.error('Critical unhandled error in Main:', err); +}); + +app.whenReady().then(async () => { + log.info('--- Application Started ---'); + console.log("Logs location:", log.transports.file.getFile().path); startBackend(); + await waitForServer(54322); createWindow(); + + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) createWindow(); + }); }); app.on('window-all-closed', () => { - if (backend) backend.kill(); - app.quit(); -}); + log.info('Closing all windows...'); + if (backend) { + backend.kill(); + log.info('Backend process terminated.'); + } + if (process.platform !== 'darwin') { + app.quit(); + } +}); \ No newline at end of file diff --git a/desktop/package-lock.json b/desktop/package-lock.json index 3b0b9a0..eba635d 100644 --- a/desktop/package-lock.json +++ b/desktop/package-lock.json @@ -11,10 +11,11 @@ "dependencies": { "@fastify/static": "^8.3.0", "@ryuziii/discord-rpc": "^1.0.1-rc.1", - "bcrypt": "^6.0.0", + "bcryptjs": "^3.0.3", "bindings": "^1.5.0", "cheerio": "^1.1.2", "dotenv": "^17.2.3", + "electron-log": "^5.4.3", "fastify": "^5.6.2", "jsonwebtoken": "^9.0.3", "node-addon-api": "^8.5.0", @@ -1972,18 +1973,13 @@ ], "license": "MIT" }, - "node_modules/bcrypt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz", - "integrity": "sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^8.3.0", - "node-gyp-build": "^4.8.4" - }, - "engines": { - "node": ">= 18" + "node_modules/bcryptjs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.3.tgz", + "integrity": "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g==", + "license": "BSD-3-Clause", + "bin": { + "bcrypt": "bin/bcrypt" } }, "node_modules/bindings": { @@ -3402,6 +3398,15 @@ "node": ">= 10.0.0" } }, + "node_modules/electron-log": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.4.3.tgz", + "integrity": "sha512-sOUsM3LjZdugatazSQ/XTyNcw8dfvH1SYhXWiJyfYodAAKOZdHs0txPiLDXFzOZbhXgAgshQkshH2ccq0feyLQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/electron-publish": { "version": "26.0.11", "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.0.11.tgz", @@ -5365,17 +5370,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/node-gyp-build": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", - "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", - "license": "MIT", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, "node_modules/node-gyp/node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", diff --git a/desktop/package.json b/desktop/package.json index baadcfb..e2789fd 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -4,10 +4,8 @@ "description": "", "main": "main.js", "scripts": { - "build": "tsc", - "start": "tsc && node server.js", - "electron": "tsc && electron .", - "dist": "npm run build && electron-builder" + "start": "tsc && electron .", + "dist": "tsc && electron-builder" }, "keywords": [], "author": "", @@ -16,10 +14,11 @@ "dependencies": { "@fastify/static": "^8.3.0", "@ryuziii/discord-rpc": "^1.0.1-rc.1", - "bcrypt": "^6.0.0", + "bcryptjs": "^3.0.3", "bindings": "^1.5.0", "cheerio": "^1.1.2", "dotenv": "^17.2.3", + "electron-log": "^5.4.3", "fastify": "^5.6.2", "jsonwebtoken": "^9.0.3", "node-addon-api": "^8.5.0", @@ -50,7 +49,11 @@ "public/assets/*" ], "extraResources": [ - "./.env" + { + "from": "C:\\Users\\user\\AppData\\Local\\ms-playwright\\chromium_headless_shell-1200", + "to": "playwright/chromium" + }, + ".env" ], "win": { "target": "portable", diff --git a/desktop/server.js b/desktop/server.js index d7d8fd5..faa374c 100644 --- a/desktop/server.js +++ b/desktop/server.js @@ -9,13 +9,14 @@ const { initDatabase } = require("./electron/shared/database"); const { loadExtensions } = require("./electron/shared/extensions"); const { init } = require("./electron/api/rpc/rpc.controller"); const dotenv = require("dotenv"); -const envPath = process.resourcesPath - ? path.join(process.resourcesPath, ".env") - : path.join(__dirname, ".env"); -// Attempt to load it and log the result to be sure -dotenv.config({ path: envPath }); +const isPackaged = process.env.IS_PACKAGED === "true"; +const envPath = isPackaged + ? path.join(process.resourcesPath, ".env") + : path.join(__dirname, ".env"); + +dotenv.config({ path: envPath, override: false }); const viewsRoutes = require("./electron/views/views.routes"); const animeRoutes = require("./electron/api/anime/anime.routes"); const booksRoutes = require("./electron/api/books/books.routes"); diff --git a/desktop/src/api/user/user.service.ts b/desktop/src/api/user/user.service.ts index fadb477..07b12e7 100644 --- a/desktop/src/api/user/user.service.ts +++ b/desktop/src/api/user/user.service.ts @@ -1,5 +1,5 @@ import {queryAll, queryOne, run} from '../../shared/database'; -import bcrypt from 'bcrypt'; +import bcrypt from 'bcryptjs'; const USER_DB_NAME = 'userdata'; const SALT_ROUNDS = 10; diff --git a/desktop/src/shared/headless.js b/desktop/src/shared/headless.js index 8dee9d5..77cfb64 100644 --- a/desktop/src/shared/headless.js +++ b/desktop/src/shared/headless.js @@ -1,14 +1,44 @@ -const { chromium } = require("playwright-chromium"); +const path = require("path"); +const fs = require("fs"); +const { chromium } = require("playwright-core"); + let browser; let context; const BLOCK_LIST = [ "google-analytics", "doubleclick", "facebook", "twitter", "adsystem", "analytics", "tracker", "pixel", "quantserve", "newrelic" ]; + +function isPackaged() { + return process.env.IS_PACKAGED === "true"; +} + +function getChromiumPath() { + if (isPackaged()) { + return path.join( + process.resourcesPath, + "playwright", + "chromium", + "chrome-headless-shell-win64", + "chrome-headless-shell.exe" + ); + } + + return chromium.executablePath(); +} + async function initHeadless() { if (browser) return; + + const exePath = getChromiumPath(); + + if (!fs.existsSync(exePath)) { + throw new Error("Chromium not found: " + exePath); + } + browser = await chromium.launch({ headless: true, + executablePath: exePath, args: [ "--no-sandbox", "--disable-setuid-sandbox",