From 52909258caa4865666ad8fb5d4be1da432603302 Mon Sep 17 00:00:00 2001 From: Sucukdeluxe Date: Wed, 4 Mar 2026 15:03:29 +0100 Subject: [PATCH] Release v1.6.11 Co-Authored-By: Claude Opus 4.6 --- package.json | 2 +- src/main/app-controller.ts | 8 ++++++++ src/main/constants.ts | 3 ++- src/main/download-manager.ts | 30 ++++++++++++++++++++++++++---- src/main/main.ts | 2 +- src/renderer/App.tsx | 4 +++- src/shared/types.ts | 1 + tests/app-order.test.ts | 2 +- 8 files changed, 43 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 02b7b91..3c92f88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "real-debrid-downloader", - "version": "1.6.10", + "version": "1.6.11", "description": "Real-Debrid Downloader Desktop (Electron + React + TypeScript)", "main": "build/main/main/main.js", "author": "Sucukdeluxe", diff --git a/src/main/app-controller.ts b/src/main/app-controller.ts index 0e5a160..4f52864 100644 --- a/src/main/app-controller.ts +++ b/src/main/app-controller.ts @@ -112,6 +112,9 @@ export class AppController { this.autoResumePending = false; void this.manager.start().catch((err) => logger.warn(`Auto-Resume Start Fehler: ${String(err)}`)); logger.info("Auto-Resume beim Start aktiviert"); + } else { + // Trigger pending extractions without starting the session + this.manager.triggerIdleExtractions(); } } } @@ -158,6 +161,11 @@ export class AppController { } public async installUpdate(onProgress?: (progress: UpdateInstallProgress) => void): Promise { + // Stop active downloads/extractions before installing to avoid data corruption + if (this.manager.isSessionRunning()) { + this.manager.stop(); + } + const cacheAgeMs = Date.now() - this.lastUpdateCheckAt; const cached = this.lastUpdateCheck && !this.lastUpdateCheck.error && cacheAgeMs <= 10 * 60 * 1000 ? this.lastUpdateCheck diff --git a/src/main/constants.ts b/src/main/constants.ts index a4b5a95..069e043 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -86,6 +86,7 @@ export function defaultSettings(): AppSettings { totalDownloadedAllTime: 0, bandwidthSchedules: [], columnOrder: ["name", "size", "progress", "hoster", "account", "prio", "status", "speed"], - extractCpuPriority: "high" + extractCpuPriority: "high", + autoExtractWhenStopped: true }; } diff --git a/src/main/download-manager.ts b/src/main/download-manager.ts index 670d062..ccf9bce 100644 --- a/src/main/download-manager.ts +++ b/src/main/download-manager.ts @@ -898,6 +898,21 @@ export class DownloadManager extends EventEmitter { return this.summary; } + public isSessionRunning(): boolean { + return this.session.running; + } + + /** Trigger pending extractions without starting the session (for autoExtractWhenStopped). */ + public triggerIdleExtractions(): void { + if (this.session.running || !this.settings.autoExtract || !this.settings.autoExtractWhenStopped) { + return; + } + this.recoverPostProcessingOnStartup(); + this.triggerPendingExtractions(); + this.persistSoon(); + this.emitState(); + } + public getSnapshot(): UiSnapshot { const now = nowMs(); this.pruneSpeedEvents(now); @@ -2924,6 +2939,7 @@ export class DownloadManager extends EventEmitter { } public stop(): void { + const keepExtraction = this.settings.autoExtractWhenStopped; this.session.running = false; this.session.paused = false; this.session.reconnectUntil = 0; @@ -2935,10 +2951,12 @@ export class DownloadManager extends EventEmitter { this.speedBytesLastWindow = 0; this.speedBytesPerPackage.clear(); this.speedEventsHead = 0; - this.abortPostProcessing("stop"); - for (const waiter of this.packagePostProcessWaiters) { waiter.resolve(); } - this.packagePostProcessWaiters = []; - this.packagePostProcessActive = 0; + if (!keepExtraction) { + this.abortPostProcessing("stop"); + for (const waiter of this.packagePostProcessWaiters) { waiter.resolve(); } + this.packagePostProcessWaiters = []; + this.packagePostProcessActive = 0; + } for (const active of this.activeTasks.values()) { active.abortReason = "stop"; active.abortController.abort("stop"); @@ -2953,6 +2971,10 @@ export class DownloadManager extends EventEmitter { } } for (const pkg of Object.values(this.session.packages)) { + if (keepExtraction && (pkg.status === "extracting" || pkg.status === "integrity_check")) { + // Keep extraction-related statuses when autoExtractWhenStopped + continue; + } if (pkg.status === "downloading" || pkg.status === "validating" || pkg.status === "extracting" || pkg.status === "integrity_check" || pkg.status === "paused" || pkg.status === "reconnect_wait") { diff --git a/src/main/main.ts b/src/main/main.ts index 9441e1e..d123375 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -238,7 +238,7 @@ function registerIpcHandlers(): void { if (result.started) { setTimeout(() => { app.quit(); - }, 800); + }, 2500); } return result; }); diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index f7d60fb..16803ca 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -74,7 +74,8 @@ const emptySnapshot = (): UiSnapshot => ({ updateRepo: "", autoUpdateCheck: true, clipboardWatch: false, minimizeToTray: false, theme: "dark", collapseNewPackages: true, autoSkipExtracted: false, confirmDeleteSelection: true, bandwidthSchedules: [], totalDownloadedAllTime: 0, - columnOrder: ["name", "size", "progress", "hoster", "account", "prio", "status", "speed"] + columnOrder: ["name", "size", "progress", "hoster", "account", "prio", "status", "speed"], + autoExtractWhenStopped: true }, session: { version: 2, packageOrder: [], packages: {}, items: {}, runStartedAt: 0, @@ -2668,6 +2669,7 @@ export function App(): ReactElement { +
setNum("maxParallelExtract", Math.max(1, Math.min(8, Number(e.target.value) || 2)))} />