diff --git a/package.json b/package.json index 45c545a..b6ba21e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "real-debrid-downloader", - "version": "1.6.0", + "version": "1.6.1", "description": "Real-Debrid Downloader Desktop (Electron + React + TypeScript)", "main": "build/main/main/main.js", "author": "Sucukdeluxe", diff --git a/src/main/download-manager.ts b/src/main/download-manager.ts index 5e8e3e0..fb9facf 100644 --- a/src/main/download-manager.ts +++ b/src/main/download-manager.ts @@ -1462,6 +1462,7 @@ export class DownloadManager extends EventEmitter { this.runOutcomes.delete(itemId); this.itemContributedBytes.delete(itemId); this.retryAfterByItem.delete(itemId); + this.retryStateByItem.delete(itemId); if (this.session.running) { this.runItemIds.add(itemId); } @@ -1555,7 +1556,6 @@ export class DownloadManager extends EventEmitter { } private async checkRapidgatorLinks(itemIds: string[]): Promise { - const checked = new Map>>(); const itemsToCheck: Array<{ itemId: string; url: string }> = []; for (const itemId of itemIds) { @@ -2470,6 +2470,7 @@ export class DownloadManager extends EventEmitter { item.targetPath = ""; item.provider = null; item.fullStatus = "Wartet"; + item.onlineStatus = undefined; item.updatedAt = nowMs(); } @@ -2534,6 +2535,7 @@ export class DownloadManager extends EventEmitter { item.targetPath = ""; item.provider = null; item.fullStatus = "Wartet"; + item.onlineStatus = undefined; item.updatedAt = nowMs(); } @@ -2924,6 +2926,8 @@ export class DownloadManager extends EventEmitter { this.speedBytesPerPackage.clear(); this.speedEventsHead = 0; this.abortPostProcessing("stop"); + for (const waiter of this.packagePostProcessWaiters) { waiter.resolve(); } + this.packagePostProcessWaiters = []; for (const active of this.activeTasks.values()) { active.abortReason = "stop"; active.abortController.abort("stop"); @@ -3576,7 +3580,7 @@ export class DownloadManager extends EventEmitter { continue; } - if (this.settings.autoExtract && failed === 0 && success > 0) { + if (this.settings.autoExtract && failed === 0 && cancelled === 0 && success > 0) { const needsExtraction = items.some((item) => item.status === "completed" && !isExtractedLabel(item.fullStatus)); if (needsExtraction) { pkg.status = "queued"; @@ -6048,7 +6052,11 @@ export class DownloadManager extends EventEmitter { return; } // Immediately clean up extracted items if "Sofort" policy is active - this.applyPackageDoneCleanup(packageId); + if (this.settings.completedCleanupPolicy === "immediate") { + for (const itemId of [...pkg.itemIds]) { + this.applyCompletedCleanupPolicy(packageId, itemId); + } + } if (!this.session.packages[packageId]) { return; // Package was fully cleaned up } @@ -6426,7 +6434,7 @@ export class DownloadManager extends EventEmitter { return; } } - this.removePackageFromSession(packageId, [...pkg.itemIds]); + this.removePackageFromSession(packageId, [...pkg.itemIds], "completed"); } } } diff --git a/src/main/storage.ts b/src/main/storage.ts index e47499c..f12354e 100644 --- a/src/main/storage.ts +++ b/src/main/storage.ts @@ -453,7 +453,7 @@ export function saveSettings(paths: StoragePaths, settings: AppSettings): void { } let asyncSettingsSaveRunning = false; -let asyncSettingsSaveQueued: { paths: StoragePaths; payload: string } | null = null; +let asyncSettingsSaveQueued: { paths: StoragePaths; settings: AppSettings } | null = null; async function writeSettingsPayload(paths: StoragePaths, payload: string): Promise { await fs.promises.mkdir(paths.baseDir, { recursive: true }); @@ -476,7 +476,7 @@ export async function saveSettingsAsync(paths: StoragePaths, settings: AppSettin const persisted = sanitizeCredentialPersistence(normalizeSettings(settings)); const payload = JSON.stringify(persisted, null, 2); if (asyncSettingsSaveRunning) { - asyncSettingsSaveQueued = { paths, payload }; + asyncSettingsSaveQueued = { paths, settings }; return; } asyncSettingsSaveRunning = true; @@ -489,7 +489,7 @@ export async function saveSettingsAsync(paths: StoragePaths, settings: AppSettin if (asyncSettingsSaveQueued) { const queued = asyncSettingsSaveQueued; asyncSettingsSaveQueued = null; - void writeSettingsPayload(queued.paths, queued.payload).catch((err) => logger.error(`Async Settings-Save (queued) fehlgeschlagen: ${String(err)}`)); + void saveSettingsAsync(queued.paths, queued.settings); } } } diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index bddf48c..ffda36b 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -2706,7 +2706,13 @@ export function App(): ReactElement { {deleteConfirm && (() => { const itemCount = [...deleteConfirm.ids].filter((id) => snapshot.session.items[id]).length; const pkgCount = [...deleteConfirm.ids].filter((id) => snapshot.session.packages[id]).length; - const totalRemaining = Object.keys(snapshot.session.items).length + Object.keys(snapshot.session.packages).length - itemCount - pkgCount; + const removedItemIds = new Set(); + for (const id of deleteConfirm.ids) { + if (snapshot.session.items[id]) removedItemIds.add(id); + const pkg = snapshot.session.packages[id]; + if (pkg) { for (const iid of pkg.itemIds) removedItemIds.add(iid); } + } + const totalRemaining = Object.keys(snapshot.session.items).length - removedItemIds.size; const parts: string[] = []; if (pkgCount > 0) parts.push(`${pkgCount} Paket(e)`); if (itemCount > 0) parts.push(`${itemCount} Link(s)`); @@ -2991,7 +2997,8 @@ export function App(): ReactElement {