Compare commits

...

2 Commits

Author SHA1 Message Date
Administrator
59dbd4b41c release: v3.3.96 2026-06-21 16:48:21 +02:00
Administrator
54dbba223d fix(diag): log the full eventloop-delay payload + harden tray icon load
The v3.3.94 measurement computed the main-process event-loop delay, CPU%, per-hoster connection distribution and transient error counts, but logged only '[INFO ] perf': logInfo(ctx, msg) treats a string first arg as the whole message and discards the second, so the payload was thrown away (confirmed in the user's upload-debug.log). Pass the line as a single argument so the real numbers reach the log.

Also: assets/ was missing from the electron-builder files list, so app_icon.ico was never packaged into the asar — new Tray() threw an unhandled rejection on every startup and left no tray icon. Package the icons and wrap createTray in try/catch with a nativeImage fallback so a missing/invalid icon can never crash tray creation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 16:47:48 +02:00
2 changed files with 34 additions and 16 deletions

44
main.js
View File

@ -1,6 +1,6 @@
process.env.UV_THREADPOOL_SIZE = process.env.UV_THREADPOOL_SIZE || '64';
const { monitorEventLoopDelay } = require('perf_hooks');
const { app, BrowserWindow, ipcMain, dialog, clipboard, nativeTheme, Tray, Menu } = require('electron');
const { app, BrowserWindow, ipcMain, dialog, clipboard, nativeTheme, Tray, Menu, nativeImage } = require('electron');
nativeTheme.themeSource = 'dark';
const path = require('path');
const fs = require('fs');
@ -225,7 +225,7 @@ function _maybeLogEventLoopDelay(activeJobs) {
upStr = ` active-by-hoster={${byHoster}} transient-errs=${d.transientErrors || 0} pending=${d.pending || 0}`;
}
} catch {}
logInfo('perf', `eventloop-delay active=${activeJobs} mean=${mean}ms p99=${p99}ms max=${max}ms stddev=${stddev}ms threadpool=${process.env.UV_THREADPOOL_SIZE}${cpuStr}${resStr}${upStr}`);
logInfo(`eventloop-delay active=${activeJobs} mean=${mean}ms p99=${p99}ms max=${max}ms stddev=${stddev}ms threadpool=${process.env.UV_THREADPOOL_SIZE}${cpuStr}${resStr}${upStr}`);
_eventLoopDelay.reset();
} catch {}
}
@ -1220,20 +1220,36 @@ function createWindow() {
}
function createTray() {
const iconPath = path.join(__dirname, 'assets', 'app_icon.ico');
tray = new Tray(iconPath);
tray.setToolTip('Multi-Hoster-Upload');
try {
const candidates = [
path.join(process.resourcesPath || __dirname, 'assets', 'app_icon.ico'),
path.join(__dirname, 'assets', 'app_icon.ico'),
path.join(__dirname, 'assets', 'icon.png')
];
let icon = null;
for (const p of candidates) {
try {
const img = nativeImage.createFromPath(p);
if (img && !img.isEmpty()) { icon = img; break; }
} catch {}
}
tray = new Tray(icon || nativeImage.createEmpty());
tray.setToolTip('Multi-Hoster-Upload');
const contextMenu = Menu.buildFromTemplate([
{ label: 'Öffnen', click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); } } },
{ type: 'separator' },
{ label: 'Beenden', click: () => { app.quit(); } }
]);
tray.setContextMenu(contextMenu);
const contextMenu = Menu.buildFromTemplate([
{ label: 'Öffnen', click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); } } },
{ type: 'separator' },
{ label: 'Beenden', click: () => { app.quit(); } }
]);
tray.setContextMenu(contextMenu);
tray.on('click', () => {
if (mainWindow) { mainWindow.show(); mainWindow.focus(); }
});
tray.on('click', () => {
if (mainWindow) { mainWindow.show(); mainWindow.focus(); }
});
} catch (err) {
tray = null;
debugLog(`createTray failed (non-fatal): ${err && err.message ? err.message : err}`);
}
}
function updateTrayTooltip(text) {

View File

@ -1,6 +1,6 @@
{
"name": "multi-hoster-uploader",
"version": "3.3.95",
"version": "3.3.96",
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
"main": "main.js",
"scripts": {
@ -33,7 +33,9 @@
"main.js",
"preload.js",
"lib/**/*",
"renderer/**/*"
"renderer/**/*",
"assets/app_icon.ico",
"assets/app_icon.png"
],
"win": {
"target": [