Release v1.5.90

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sucukdeluxe 2026-03-04 03:04:49 +01:00
parent 92101e249a
commit 254612a49b
4 changed files with 19 additions and 7 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "real-debrid-downloader", "name": "real-debrid-downloader",
"version": "1.5.89", "version": "1.5.90",
"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",

View File

@ -2544,10 +2544,10 @@ export class DownloadManager extends EventEmitter {
public async startPackages(packageIds: string[]): Promise<void> { public async startPackages(packageIds: string[]): Promise<void> {
const targetSet = new Set(packageIds); const targetSet = new Set(packageIds);
// Enable specified packages if disabled // Enable specified packages if disabled (only non-cancelled)
for (const pkgId of targetSet) { for (const pkgId of targetSet) {
const pkg = this.session.packages[pkgId]; const pkg = this.session.packages[pkgId];
if (pkg && !pkg.enabled) { if (pkg && !pkg.cancelled && !pkg.enabled) {
pkg.enabled = true; pkg.enabled = true;
} }
} }
@ -2613,6 +2613,10 @@ export class DownloadManager extends EventEmitter {
this.speedEventsHead = 0; this.speedEventsHead = 0;
this.lastGlobalProgressBytes = 0; this.lastGlobalProgressBytes = 0;
this.lastGlobalProgressAt = nowMs(); this.lastGlobalProgressAt = nowMs();
this.lastReconnectMarkAt = 0;
this.consecutiveReconnects = 0;
this.globalSpeedLimitQueue = Promise.resolve();
this.globalSpeedLimitNextAt = 0;
this.summary = null; this.summary = null;
this.nonResumableActive = 0; this.nonResumableActive = 0;
this.persistSoon(); this.persistSoon();
@ -2637,10 +2641,10 @@ export class DownloadManager extends EventEmitter {
if (item) affectedPackageIds.add(item.packageId); if (item) affectedPackageIds.add(item.packageId);
} }
// Enable affected packages if disabled // Enable affected packages if disabled (only non-cancelled)
for (const pkgId of affectedPackageIds) { for (const pkgId of affectedPackageIds) {
const pkg = this.session.packages[pkgId]; const pkg = this.session.packages[pkgId];
if (pkg && !pkg.enabled) { if (pkg && !pkg.cancelled && !pkg.enabled) {
pkg.enabled = true; pkg.enabled = true;
} }
} }
@ -2666,6 +2670,8 @@ export class DownloadManager extends EventEmitter {
for (const itemId of targetSet) { for (const itemId of targetSet) {
const item = this.session.items[itemId]; const item = this.session.items[itemId];
if (!item) continue; if (!item) continue;
const pkg = this.session.packages[item.packageId];
if (!pkg || pkg.cancelled || !pkg.enabled) continue;
if (item.status === "queued" || item.status === "reconnect_wait") { if (item.status === "queued" || item.status === "reconnect_wait") {
this.runItemIds.add(item.id); this.runItemIds.add(item.id);
this.runPackageIds.add(item.packageId); this.runPackageIds.add(item.packageId);
@ -2708,6 +2714,10 @@ export class DownloadManager extends EventEmitter {
this.speedEventsHead = 0; this.speedEventsHead = 0;
this.lastGlobalProgressBytes = 0; this.lastGlobalProgressBytes = 0;
this.lastGlobalProgressAt = nowMs(); this.lastGlobalProgressAt = nowMs();
this.lastReconnectMarkAt = 0;
this.consecutiveReconnects = 0;
this.globalSpeedLimitQueue = Promise.resolve();
this.globalSpeedLimitNextAt = 0;
this.summary = null; this.summary = null;
this.nonResumableActive = 0; this.nonResumableActive = 0;
this.persistSoon(); this.persistSoon();

View File

@ -293,7 +293,7 @@ function registerIpcHandlers(): void {
return controller.startPackages(packageIds); return controller.startPackages(packageIds);
}); });
ipcMain.handle(IPC_CHANNELS.START_ITEMS, (_event: IpcMainInvokeEvent, itemIds: string[]) => { ipcMain.handle(IPC_CHANNELS.START_ITEMS, (_event: IpcMainInvokeEvent, itemIds: string[]) => {
if (!Array.isArray(itemIds)) throw new Error("itemIds muss ein Array sein"); validateStringArray(itemIds ?? [], "itemIds");
return controller.startItems(itemIds); return controller.startItems(itemIds);
}); });
ipcMain.handle(IPC_CHANNELS.STOP, () => controller.stop()); ipcMain.handle(IPC_CHANNELS.STOP, () => controller.stop());

View File

@ -2830,10 +2830,12 @@ export function App(): ReactElement {
{contextMenu && (() => { {contextMenu && (() => {
const multi = selectedIds.size > 1; const multi = selectedIds.size > 1;
const hasPackages = [...selectedIds].some((id) => snapshot.session.packages[id]); const hasPackages = [...selectedIds].some((id) => snapshot.session.packages[id]);
const startableStatuses = new Set(["queued", "cancelled", "reconnect_wait"]);
const hasStartableItems = [...selectedIds].some((id) => { const it = snapshot.session.items[id]; return it && startableStatuses.has(it.status); });
const hasItems = [...selectedIds].some((id) => snapshot.session.items[id]); const hasItems = [...selectedIds].some((id) => snapshot.session.items[id]);
return ( return (
<div ref={ctxMenuRef} className="ctx-menu" style={{ left: contextMenu.x, top: contextMenu.y }} onClick={(e) => e.stopPropagation()}> <div ref={ctxMenuRef} className="ctx-menu" style={{ left: contextMenu.x, top: contextMenu.y }} onClick={(e) => e.stopPropagation()}>
{(hasPackages || hasItems) && ( {(hasPackages || hasStartableItems) && (
<button className="ctx-menu-item" onClick={() => { <button className="ctx-menu-item" onClick={() => {
const pkgIds = [...selectedIds].filter((id) => snapshot.session.packages[id]); const pkgIds = [...selectedIds].filter((id) => snapshot.session.packages[id]);
const itemIds = [...selectedIds].filter((id) => snapshot.session.items[id]); const itemIds = [...selectedIds].filter((id) => snapshot.session.items[id]);