From f6b1ef96b7b7446189d8bf5f0292fcc88639ad4a Mon Sep 17 00:00:00 2001 From: Administrator Date: Sun, 19 Apr 2026 23:30:14 +0200 Subject: [PATCH] feat(log): auto-persist fallback path into settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the configured log path isn't writable and we fall back to Desktop/userData, the working fallback now gets saved into globalSettings.logFilePath automatically. Benefits: - Next session writes directly to the known-working path, no fallback ladder, no recurring toast warning. - The Settings input reflects the actual path in use, so users don't stay confused about where their uploads are being logged. - Live update via IPC — if the Settings view is currently open, the input value updates without needing a view switch. Daily-log mode is handled: we strip the -YYYY-MM-DD suffix before persisting so tomorrow's auto-rotation doesn't double-date the filename. --- main.js | 32 ++++++++++++++++++++++++++++++++ preload.js | 3 +++ renderer/app.js | 13 ++++++++++--- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/main.js b/main.js index 10656af..993f187 100644 --- a/main.js +++ b/main.js @@ -290,6 +290,10 @@ function _flushUploadLog() { debugLog(`uploadLog append failed: ${err.message}`); } else if (target.isFallback && !_uploadLogFallbackWarned) { _uploadLogFallbackWarned = true; + // Auto-persist the working fallback into the user's config so the + // next session writes here directly (no more fallback ladder) and + // the Settings input reflects reality. + _persistFallbackLogPath(target.path); if (mainWindow && !mainWindow.isDestroyed()) { mainWindow.webContents.send('upload-log-fallback', { fallbackPath: target.path }); } @@ -298,6 +302,34 @@ function _flushUploadLog() { }); } +function _persistFallbackLogPath(workingPath) { + try { + const cfg = configStore.load(); + const gs = cfg.globalSettings || {}; + // If daily-log is on, workingPath has a date suffix (fileuploader-YYYY-MM-DD.log). + // Strip that before saving so the base path rolls forward to tomorrow's + // file correctly — otherwise the next day's getLogFilePath would append + // another date onto the already-dated base. + let toSave = workingPath; + if (gs.sessionLog) { + const dir = path.dirname(workingPath); + const base = path.basename(workingPath); + const stripped = base.replace(/-\d{4}-\d{2}-\d{2}(\.[^.]+)$/, '$1'); + toSave = path.join(dir, stripped); + } + if (gs.logFilePath === toSave) return; + gs.logFilePath = toSave; + cfg.globalSettings = gs; + configStore.save({ globalSettings: gs }).catch(() => {}); + _invalidateUploadLogTargetCache(); + if (mainWindow && !mainWindow.isDestroyed()) { + mainWindow.webContents.send('log-path-auto-updated', { logFilePath: toSave }); + } + } catch (err) { + debugLog(`persist fallback logpath failed: ${err.message}`); + } +} + function appendUploadLog(hoster, link, fileName) { const now = new Date(); const pad = (n) => String(n).padStart(2, '0'); diff --git a/preload.js b/preload.js index 3ec208f..2ce3d3f 100644 --- a/preload.js +++ b/preload.js @@ -108,6 +108,9 @@ contextBridge.exposeInMainWorld('api', { ipcRenderer.on('account-rotation-log', (_event, data) => callback(data)); }, openLogFolder: () => ipcRenderer.invoke('open-log-folder'), + onLogPathAutoUpdated: (callback) => { + ipcRenderer.on('log-path-auto-updated', (_event, data) => callback(data)); + }, // Remote Control remoteGetSettings: () => ipcRenderer.invoke('remote:get-settings'), remoteSaveSettings: (settings) => ipcRenderer.invoke('remote:save-settings', settings), diff --git a/renderer/app.js b/renderer/app.js index 625cce2..83da3a7 100644 --- a/renderer/app.js +++ b/renderer/app.js @@ -118,12 +118,19 @@ async function init() { }); window.api.onShutdownCountdown(handleShutdownCountdown); window.api.onUploadLogFallback((data) => { - // Non-blocking toast instead of alert() — alert() in Electron halts the - // entire renderer main thread (including the upload table) until the user - // clicks OK. During a big batch that freezes everything. const path = data && data.fallbackPath ? data.fallbackPath : '(Fallback)'; showCopyToast(`Log-Pfad nicht beschreibbar — schreibe nach: ${path}`, 8000); }); + window.api.onLogPathAutoUpdated((data) => { + if (!data || !data.logFilePath) return; + // Keep the in-memory config and the visible Settings input in sync so + // the user sees the path that's actually being written to, and the + // next save from the UI doesn't revert it. + if (config && config.globalSettings) config.globalSettings.logFilePath = data.logFilePath; + const input = document.getElementById('logFilePathInput'); + if (input) input.value = data.logFilePath; + showCopyToast(`Log-Pfad automatisch auf funktionierenden Ordner gesetzt`, 5000); + }); window.api.onAccountRotationLog((entry) => { // Surface only the user-visible rotation events as toasts; full detail // goes to account-rotation.log. Keep it quiet otherwise.