Add daily traffic limits, auto-sort packages, Debrid-Link multi-key improvements
Daily traffic limits: - Per-provider daily download limit (configurable in GB per provider) - Per Debrid-Link API key daily limit (individual limits per key) - Usage tracking with automatic daily reset at midnight - Provider is skipped when daily limit reached, falls back to next provider - Reset button per provider and per Debrid-Link key in account settings - Hoster routing skips daily-limited providers gracefully Debrid-Link multi-key improvements: - Keys now display with labels (#1, #2...) and masked tokens in account list - Option to show detailed per-key view with individual usage stats - Keys that hit their daily limit are automatically skipped - providerAccountId/providerAccountLabel stored per download item Auto-sort packages by progress: - Active packages automatically sorted to top during downloads - Sorted by completion ratio, then downloaded bytes - Toggle in settings (autoSortPackagesByProgress) UI polish: - Package column headers: flatter, more transparent design - LinkSnappy mode label: "Login" renamed to "Web" - Account list: new toggle for detailed Debrid-Link key display - Account usage stats section with warning styling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
71b3612e82
commit
e212ccc86f
@@ -0,0 +1,82 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { DownloadItem, PackageEntry } from "../src/shared/types";
|
||||
import { sortPackagesForDisplay } from "../src/renderer/package-order";
|
||||
|
||||
function createPackage(id: string, itemIds: string[]): PackageEntry {
|
||||
const now = Date.now();
|
||||
return {
|
||||
id,
|
||||
name: id,
|
||||
outputDir: "",
|
||||
extractDir: "",
|
||||
status: "queued",
|
||||
itemIds,
|
||||
cancelled: false,
|
||||
enabled: true,
|
||||
priority: "normal",
|
||||
createdAt: now,
|
||||
updatedAt: now
|
||||
};
|
||||
}
|
||||
|
||||
function createItem(id: string, packageId: string, status: DownloadItem["status"], downloadedBytes: number): DownloadItem {
|
||||
const now = Date.now();
|
||||
return {
|
||||
id,
|
||||
packageId,
|
||||
url: `https://hoster.example/${id}`,
|
||||
provider: null,
|
||||
status,
|
||||
retries: 0,
|
||||
speedBps: 0,
|
||||
downloadedBytes,
|
||||
totalBytes: downloadedBytes,
|
||||
progressPercent: downloadedBytes > 0 ? 50 : 0,
|
||||
fileName: `${id}.bin`,
|
||||
targetPath: "",
|
||||
resumable: true,
|
||||
attempts: 0,
|
||||
lastError: "",
|
||||
fullStatus: "",
|
||||
createdAt: now,
|
||||
updatedAt: now
|
||||
};
|
||||
}
|
||||
|
||||
describe("sortPackagesForDisplay", () => {
|
||||
it("moves active packages with more progress to the top when auto sort is enabled", () => {
|
||||
const packages = [
|
||||
createPackage("pkg-a", ["a1", "a2"]),
|
||||
createPackage("pkg-b", ["b1", "b2"]),
|
||||
createPackage("pkg-c", ["c1"])
|
||||
];
|
||||
const items: Record<string, DownloadItem> = {
|
||||
a1: createItem("a1", "pkg-a", "downloading", 250),
|
||||
a2: createItem("a2", "pkg-a", "completed", 500),
|
||||
b1: createItem("b1", "pkg-b", "downloading", 800),
|
||||
b2: createItem("b2", "pkg-b", "completed", 900),
|
||||
c1: createItem("c1", "pkg-c", "queued", 0)
|
||||
};
|
||||
|
||||
const sorted = sortPackagesForDisplay(packages, items, true, true);
|
||||
|
||||
expect(sorted.map((pkg) => pkg.id)).toEqual(["pkg-b", "pkg-a", "pkg-c"]);
|
||||
});
|
||||
|
||||
it("keeps package order untouched when auto sort is disabled", () => {
|
||||
const packages = [
|
||||
createPackage("pkg-a", ["a1"]),
|
||||
createPackage("pkg-b", ["b1"]),
|
||||
createPackage("pkg-c", ["c1"])
|
||||
];
|
||||
const items: Record<string, DownloadItem> = {
|
||||
a1: createItem("a1", "pkg-a", "queued", 0),
|
||||
b1: createItem("b1", "pkg-b", "downloading", 500),
|
||||
c1: createItem("c1", "pkg-c", "queued", 0)
|
||||
};
|
||||
|
||||
const sorted = sortPackagesForDisplay(packages, items, true, false);
|
||||
|
||||
expect(sorted.map((pkg) => pkg.id)).toEqual(["pkg-a", "pkg-b", "pkg-c"]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user