Release v1.6.11
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e9b9801ac1
commit
52909258ca
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "real-debrid-downloader",
|
"name": "real-debrid-downloader",
|
||||||
"version": "1.6.10",
|
"version": "1.6.11",
|
||||||
"description": "Real-Debrid Downloader Desktop (Electron + React + TypeScript)",
|
"description": "Real-Debrid Downloader Desktop (Electron + React + TypeScript)",
|
||||||
"main": "build/main/main/main.js",
|
"main": "build/main/main/main.js",
|
||||||
"author": "Sucukdeluxe",
|
"author": "Sucukdeluxe",
|
||||||
|
|||||||
@ -112,6 +112,9 @@ export class AppController {
|
|||||||
this.autoResumePending = false;
|
this.autoResumePending = false;
|
||||||
void this.manager.start().catch((err) => logger.warn(`Auto-Resume Start Fehler: ${String(err)}`));
|
void this.manager.start().catch((err) => logger.warn(`Auto-Resume Start Fehler: ${String(err)}`));
|
||||||
logger.info("Auto-Resume beim Start aktiviert");
|
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<UpdateInstallResult> {
|
public async installUpdate(onProgress?: (progress: UpdateInstallProgress) => void): Promise<UpdateInstallResult> {
|
||||||
|
// Stop active downloads/extractions before installing to avoid data corruption
|
||||||
|
if (this.manager.isSessionRunning()) {
|
||||||
|
this.manager.stop();
|
||||||
|
}
|
||||||
|
|
||||||
const cacheAgeMs = Date.now() - this.lastUpdateCheckAt;
|
const cacheAgeMs = Date.now() - this.lastUpdateCheckAt;
|
||||||
const cached = this.lastUpdateCheck && !this.lastUpdateCheck.error && cacheAgeMs <= 10 * 60 * 1000
|
const cached = this.lastUpdateCheck && !this.lastUpdateCheck.error && cacheAgeMs <= 10 * 60 * 1000
|
||||||
? this.lastUpdateCheck
|
? this.lastUpdateCheck
|
||||||
|
|||||||
@ -86,6 +86,7 @@ export function defaultSettings(): AppSettings {
|
|||||||
totalDownloadedAllTime: 0,
|
totalDownloadedAllTime: 0,
|
||||||
bandwidthSchedules: [],
|
bandwidthSchedules: [],
|
||||||
columnOrder: ["name", "size", "progress", "hoster", "account", "prio", "status", "speed"],
|
columnOrder: ["name", "size", "progress", "hoster", "account", "prio", "status", "speed"],
|
||||||
extractCpuPriority: "high"
|
extractCpuPriority: "high",
|
||||||
|
autoExtractWhenStopped: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -898,6 +898,21 @@ export class DownloadManager extends EventEmitter {
|
|||||||
return this.summary;
|
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 {
|
public getSnapshot(): UiSnapshot {
|
||||||
const now = nowMs();
|
const now = nowMs();
|
||||||
this.pruneSpeedEvents(now);
|
this.pruneSpeedEvents(now);
|
||||||
@ -2924,6 +2939,7 @@ export class DownloadManager extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public stop(): void {
|
public stop(): void {
|
||||||
|
const keepExtraction = this.settings.autoExtractWhenStopped;
|
||||||
this.session.running = false;
|
this.session.running = false;
|
||||||
this.session.paused = false;
|
this.session.paused = false;
|
||||||
this.session.reconnectUntil = 0;
|
this.session.reconnectUntil = 0;
|
||||||
@ -2935,10 +2951,12 @@ export class DownloadManager extends EventEmitter {
|
|||||||
this.speedBytesLastWindow = 0;
|
this.speedBytesLastWindow = 0;
|
||||||
this.speedBytesPerPackage.clear();
|
this.speedBytesPerPackage.clear();
|
||||||
this.speedEventsHead = 0;
|
this.speedEventsHead = 0;
|
||||||
|
if (!keepExtraction) {
|
||||||
this.abortPostProcessing("stop");
|
this.abortPostProcessing("stop");
|
||||||
for (const waiter of this.packagePostProcessWaiters) { waiter.resolve(); }
|
for (const waiter of this.packagePostProcessWaiters) { waiter.resolve(); }
|
||||||
this.packagePostProcessWaiters = [];
|
this.packagePostProcessWaiters = [];
|
||||||
this.packagePostProcessActive = 0;
|
this.packagePostProcessActive = 0;
|
||||||
|
}
|
||||||
for (const active of this.activeTasks.values()) {
|
for (const active of this.activeTasks.values()) {
|
||||||
active.abortReason = "stop";
|
active.abortReason = "stop";
|
||||||
active.abortController.abort("stop");
|
active.abortController.abort("stop");
|
||||||
@ -2953,6 +2971,10 @@ export class DownloadManager extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const pkg of Object.values(this.session.packages)) {
|
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"
|
if (pkg.status === "downloading" || pkg.status === "validating"
|
||||||
|| pkg.status === "extracting" || pkg.status === "integrity_check"
|
|| pkg.status === "extracting" || pkg.status === "integrity_check"
|
||||||
|| pkg.status === "paused" || pkg.status === "reconnect_wait") {
|
|| pkg.status === "paused" || pkg.status === "reconnect_wait") {
|
||||||
|
|||||||
@ -238,7 +238,7 @@ function registerIpcHandlers(): void {
|
|||||||
if (result.started) {
|
if (result.started) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
app.quit();
|
app.quit();
|
||||||
}, 800);
|
}, 2500);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -74,7 +74,8 @@ const emptySnapshot = (): UiSnapshot => ({
|
|||||||
updateRepo: "", autoUpdateCheck: true, clipboardWatch: false, minimizeToTray: false,
|
updateRepo: "", autoUpdateCheck: true, clipboardWatch: false, minimizeToTray: false,
|
||||||
theme: "dark", collapseNewPackages: true, autoSkipExtracted: false, confirmDeleteSelection: true,
|
theme: "dark", collapseNewPackages: true, autoSkipExtracted: false, confirmDeleteSelection: true,
|
||||||
bandwidthSchedules: [], totalDownloadedAllTime: 0,
|
bandwidthSchedules: [], totalDownloadedAllTime: 0,
|
||||||
columnOrder: ["name", "size", "progress", "hoster", "account", "prio", "status", "speed"]
|
columnOrder: ["name", "size", "progress", "hoster", "account", "prio", "status", "speed"],
|
||||||
|
autoExtractWhenStopped: true
|
||||||
},
|
},
|
||||||
session: {
|
session: {
|
||||||
version: 2, packageOrder: [], packages: {}, items: {}, runStartedAt: 0,
|
version: 2, packageOrder: [], packages: {}, items: {}, runStartedAt: 0,
|
||||||
@ -2668,6 +2669,7 @@ export function App(): ReactElement {
|
|||||||
<label className="toggle-line"><input type="checkbox" checked={settingsDraft.autoRename4sf4sj} onChange={(e) => setBool("autoRename4sf4sj", e.target.checked)} /> Auto-Rename (Beta)</label>
|
<label className="toggle-line"><input type="checkbox" checked={settingsDraft.autoRename4sf4sj} onChange={(e) => setBool("autoRename4sf4sj", e.target.checked)} /> Auto-Rename (Beta)</label>
|
||||||
<label className="toggle-line"><input type="checkbox" checked={settingsDraft.createExtractSubfolder} onChange={(e) => setBool("createExtractSubfolder", e.target.checked)} /> Entpackte Dateien in Paket-Unterordner speichern</label>
|
<label className="toggle-line"><input type="checkbox" checked={settingsDraft.createExtractSubfolder} onChange={(e) => setBool("createExtractSubfolder", e.target.checked)} /> Entpackte Dateien in Paket-Unterordner speichern</label>
|
||||||
<label className="toggle-line"><input type="checkbox" checked={settingsDraft.hybridExtract} onChange={(e) => setBool("hybridExtract", e.target.checked)} /> Hybrid-Extract</label>
|
<label className="toggle-line"><input type="checkbox" checked={settingsDraft.hybridExtract} onChange={(e) => setBool("hybridExtract", e.target.checked)} /> Hybrid-Extract</label>
|
||||||
|
<label className="toggle-line"><input type="checkbox" checked={settingsDraft.autoExtractWhenStopped ?? true} onChange={(e) => setBool("autoExtractWhenStopped", e.target.checked)} /> Entpacken auch ohne laufende Session (bei Stopp / Programmstart)</label>
|
||||||
<div><label>Parallele Entpackungen</label><input type="number" min={1} max={8} value={settingsDraft.maxParallelExtract} onChange={(e) => setNum("maxParallelExtract", Math.max(1, Math.min(8, Number(e.target.value) || 2)))} /></div>
|
<div><label>Parallele Entpackungen</label><input type="number" min={1} max={8} value={settingsDraft.maxParallelExtract} onChange={(e) => setNum("maxParallelExtract", Math.max(1, Math.min(8, Number(e.target.value) || 2)))} /></div>
|
||||||
<div><label>Extraktions-Priorität</label><select value={settingsDraft.extractCpuPriority} onChange={(e) => setText("extractCpuPriority", e.target.value)}>
|
<div><label>Extraktions-Priorität</label><select value={settingsDraft.extractCpuPriority} onChange={(e) => setText("extractCpuPriority", e.target.value)}>
|
||||||
<option value="high">Hoch (80% CPU)</option>
|
<option value="high">Hoch (80% CPU)</option>
|
||||||
|
|||||||
@ -84,6 +84,7 @@ export interface AppSettings {
|
|||||||
bandwidthSchedules: BandwidthScheduleEntry[];
|
bandwidthSchedules: BandwidthScheduleEntry[];
|
||||||
columnOrder: string[];
|
columnOrder: string[];
|
||||||
extractCpuPriority: ExtractCpuPriority;
|
extractCpuPriority: ExtractCpuPriority;
|
||||||
|
autoExtractWhenStopped: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DownloadItem {
|
export interface DownloadItem {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { reorderPackageOrderByDrop, sortPackageOrderByName } from "../src/renderer/App";
|
import { reorderPackageOrderByDrop, sortPackageOrderByName } from "../src/renderer/package-order";
|
||||||
|
|
||||||
describe("reorderPackageOrderByDrop", () => {
|
describe("reorderPackageOrderByDrop", () => {
|
||||||
it("moves adjacent package down by one on drop", () => {
|
it("moves adjacent package down by one on drop", () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user