diff --git a/typescript-version/package-lock.json b/typescript-version/package-lock.json
index 371ac46..21c13ea 100644
--- a/typescript-version/package-lock.json
+++ b/typescript-version/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "twitch-vod-manager",
- "version": "4.1.10",
+ "version": "4.1.11",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "twitch-vod-manager",
- "version": "4.1.10",
+ "version": "4.1.11",
"license": "MIT",
"dependencies": {
"axios": "^1.6.0",
diff --git a/typescript-version/package.json b/typescript-version/package.json
index 62cbdb9..32cb338 100644
--- a/typescript-version/package.json
+++ b/typescript-version/package.json
@@ -1,6 +1,6 @@
{
"name": "twitch-vod-manager",
- "version": "4.1.10",
+ "version": "4.1.11",
"description": "Twitch VOD Manager - Download Twitch VODs easily",
"main": "dist/main.js",
"author": "xRangerDE",
diff --git a/typescript-version/src/index.html b/typescript-version/src/index.html
index 90e7ead..23fdfa5 100644
--- a/typescript-version/src/index.html
+++ b/typescript-version/src/index.html
@@ -457,7 +457,7 @@
Updates
-
Version: v4.1.10
+
Version: v4.1.11
@@ -502,7 +502,7 @@
Nicht verbunden
- v4.1.10
+ v4.1.11
diff --git a/typescript-version/src/main.ts b/typescript-version/src/main.ts
index 13d8e32..7afa57d 100644
--- a/typescript-version/src/main.ts
+++ b/typescript-version/src/main.ts
@@ -8,7 +8,7 @@ import { autoUpdater } from 'electron-updater';
// ==========================================
// CONFIG & CONSTANTS
// ==========================================
-const APP_VERSION = '4.1.10';
+const APP_VERSION = '4.1.11';
const UPDATE_CHECK_URL = 'http://24-music.de/version.json';
// Paths
@@ -30,6 +30,9 @@ const MIN_FREE_DISK_BYTES = 128 * 1024 * 1024;
const TOOL_PATH_REFRESH_TTL_MS = 10 * 1000;
const DEBUG_LOG_FLUSH_INTERVAL_MS = 1000;
const DEBUG_LOG_BUFFER_FLUSH_LINES = 48;
+const DEBUG_LOG_READ_TAIL_BYTES = 512 * 1024;
+const DEBUG_LOG_MAX_BYTES = 8 * 1024 * 1024;
+const DEBUG_LOG_TRIM_TO_BYTES = 4 * 1024 * 1024;
const AUTO_UPDATE_CHECK_INTERVAL_MS = 10 * 60 * 1000;
const AUTO_UPDATE_STARTUP_CHECK_DELAY_MS = 5000;
const AUTO_UPDATE_MIN_CHECK_GAP_MS = 45 * 1000;
@@ -533,11 +536,78 @@ function flushPendingDebugLogLines(): void {
const payload = pendingDebugLogLines.join('');
pendingDebugLogLines = [];
fs.appendFileSync(DEBUG_LOG_FILE, payload);
+ trimDebugLogFileIfNeeded();
} catch {
// ignore debug log errors
}
}
+function trimDebugLogFileIfNeeded(): void {
+ try {
+ if (!fs.existsSync(DEBUG_LOG_FILE)) {
+ return;
+ }
+
+ const stats = fs.statSync(DEBUG_LOG_FILE);
+ if (stats.size <= DEBUG_LOG_MAX_BYTES) {
+ return;
+ }
+
+ const bytesToKeep = Math.min(DEBUG_LOG_TRIM_TO_BYTES, stats.size);
+ const startOffset = Math.max(0, stats.size - bytesToKeep);
+ const buffer = Buffer.allocUnsafe(bytesToKeep);
+
+ let fileHandle: number | null = null;
+ try {
+ fileHandle = fs.openSync(DEBUG_LOG_FILE, 'r');
+ fs.readSync(fileHandle, buffer, 0, bytesToKeep, startOffset);
+ } finally {
+ if (fileHandle !== null) {
+ fs.closeSync(fileHandle);
+ }
+ }
+
+ const firstLineBreak = buffer.indexOf(0x0a);
+ const trimmed = firstLineBreak >= 0 && firstLineBreak + 1 < buffer.length
+ ? buffer.subarray(firstLineBreak + 1)
+ : buffer;
+
+ fs.writeFileSync(DEBUG_LOG_FILE, trimmed);
+ } catch {
+ // ignore debug log errors
+ }
+}
+
+function readDebugLogTailFromDisk(): string {
+ const stats = fs.statSync(DEBUG_LOG_FILE);
+ if (stats.size <= 0) {
+ return '';
+ }
+
+ const bytesToRead = Math.min(stats.size, DEBUG_LOG_READ_TAIL_BYTES);
+ if (bytesToRead === stats.size) {
+ return fs.readFileSync(DEBUG_LOG_FILE, 'utf-8');
+ }
+
+ const buffer = Buffer.allocUnsafe(bytesToRead);
+ let fileHandle: number | null = null;
+ try {
+ fileHandle = fs.openSync(DEBUG_LOG_FILE, 'r');
+ fs.readSync(fileHandle, buffer, 0, bytesToRead, stats.size - bytesToRead);
+ } finally {
+ if (fileHandle !== null) {
+ fs.closeSync(fileHandle);
+ }
+ }
+
+ const firstLineBreak = buffer.indexOf(0x0a);
+ const slice = firstLineBreak >= 0 && firstLineBreak + 1 < buffer.length
+ ? buffer.subarray(firstLineBreak + 1)
+ : buffer;
+
+ return slice.toString('utf-8');
+}
+
function startDebugLogFlushTimer(): void {
if (debugLogFlushTimer) {
return;
@@ -569,7 +639,7 @@ function readDebugLog(lines = 200): string {
return 'Debug-Log ist leer.';
}
- const text = fs.readFileSync(DEBUG_LOG_FILE, 'utf-8');
+ const text = readDebugLogTailFromDisk();
const rows = text.split(/\r?\n/).filter(Boolean);
return rows.slice(-lines).join('\n') || 'Debug-Log ist leer.';
} catch (e) {
diff --git a/typescript-version/src/renderer-settings.ts b/typescript-version/src/renderer-settings.ts
index b4dea2b..cebc059 100644
--- a/typescript-version/src/renderer-settings.ts
+++ b/typescript-version/src/renderer-settings.ts
@@ -1,4 +1,13 @@
let lastRuntimeMetricsOutput = '';
+let lastDebugLogOutput = '';
+
+function canRunSettingsAutoRefresh(): boolean {
+ if (document.hidden) {
+ return false;
+ }
+
+ return document.querySelector('.tab-content.active')?.id === 'settingsTab';
+}
async function connect(): Promise {
const hasCredentials = Boolean((config.client_id ?? '').toString().trim() && (config.client_secret ?? '').toString().trim());
@@ -142,6 +151,10 @@ function toggleRuntimeMetricsAutoRefresh(enabled: boolean): void {
if (enabled) {
runtimeMetricsAutoRefreshTimer = window.setInterval(() => {
+ if (!canRunSettingsAutoRefresh()) {
+ return;
+ }
+
void refreshRuntimeMetrics(false);
}, 2000);
}
@@ -245,8 +258,16 @@ async function runPreflight(autoFix = false): Promise {
async function refreshDebugLog(): Promise {
const text = await window.api.getDebugLog(250);
const panel = byId('debugLogOutput');
- panel.textContent = text;
- panel.scrollTop = panel.scrollHeight;
+ const keepAtBottom = (panel.scrollHeight - panel.scrollTop - panel.clientHeight) < 20;
+
+ if (text !== lastDebugLogOutput) {
+ panel.textContent = text;
+ lastDebugLogOutput = text;
+ }
+
+ if (keepAtBottom) {
+ panel.scrollTop = panel.scrollHeight;
+ }
}
function toggleDebugAutoRefresh(enabled: boolean): void {
@@ -257,8 +278,12 @@ function toggleDebugAutoRefresh(enabled: boolean): void {
if (enabled) {
debugLogAutoRefreshTimer = window.setInterval(() => {
+ if (!canRunSettingsAutoRefresh()) {
+ return;
+ }
+
void refreshDebugLog();
- }, 1500);
+ }, 2000);
}
}