Add persistent all-time download counter, session vs total stats

- Track totalDownloadedAllTime in settings (persists across restarts)
- Track sessionDownloadedBytes for current app session
- Status bar shows both: Session + Gesamt
- Statistics section shows Heruntergeladen (Session) + (Gesamt)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sucukdeluxe 2026-03-02 19:00:17 +01:00
parent 4ea3a75dc0
commit 3c510fc265
6 changed files with 18 additions and 3 deletions

View File

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

@ -76,6 +76,7 @@ export function defaultSettings(): AppSettings {
collapseNewPackages: true, collapseNewPackages: true,
autoSkipExtracted: false, autoSkipExtracted: false,
confirmDeleteSelection: true, confirmDeleteSelection: true,
totalDownloadedAllTime: 0,
bandwidthSchedules: [] bandwidthSchedules: []
}; };
} }

View File

@ -728,6 +728,8 @@ export class DownloadManager extends EventEmitter {
private speedBytesLastWindow = 0; private speedBytesLastWindow = 0;
private sessionDownloadedBytes = 0;
private statsCache: DownloadStats | null = null; private statsCache: DownloadStats | null = null;
private statsCacheAt = 0; private statsCacheAt = 0;
@ -911,6 +913,7 @@ export class DownloadManager extends EventEmitter {
const stats = { const stats = {
totalDownloaded, totalDownloaded,
totalDownloadedAllTime: this.settings.totalDownloadedAllTime,
totalFiles, totalFiles,
totalPackages: this.session.packageOrder.length, totalPackages: this.session.packageOrder.length,
sessionStartedAt: this.session.runStartedAt sessionStartedAt: this.session.runStartedAt
@ -4264,6 +4267,8 @@ export class DownloadManager extends EventEmitter {
written += buffer.length; written += buffer.length;
windowBytes += buffer.length; windowBytes += buffer.length;
this.session.totalDownloadedBytes += buffer.length; this.session.totalDownloadedBytes += buffer.length;
this.sessionDownloadedBytes += buffer.length;
this.settings.totalDownloadedAllTime += buffer.length;
this.itemContributedBytes.set(active.itemId, (this.itemContributedBytes.get(active.itemId) || 0) + buffer.length); this.itemContributedBytes.set(active.itemId, (this.itemContributedBytes.get(active.itemId) || 0) + buffer.length);
this.recordSpeed(buffer.length, item.packageId); this.recordSpeed(buffer.length, item.packageId);
throughputWindowBytes += buffer.length; throughputWindowBytes += buffer.length;

View File

@ -109,6 +109,7 @@ export function normalizeSettings(settings: AppSettings): AppSettings {
collapseNewPackages: settings.collapseNewPackages !== undefined ? Boolean(settings.collapseNewPackages) : defaults.collapseNewPackages, collapseNewPackages: settings.collapseNewPackages !== undefined ? Boolean(settings.collapseNewPackages) : defaults.collapseNewPackages,
autoSkipExtracted: settings.autoSkipExtracted !== undefined ? Boolean(settings.autoSkipExtracted) : defaults.autoSkipExtracted, autoSkipExtracted: settings.autoSkipExtracted !== undefined ? Boolean(settings.autoSkipExtracted) : defaults.autoSkipExtracted,
confirmDeleteSelection: settings.confirmDeleteSelection !== undefined ? Boolean(settings.confirmDeleteSelection) : defaults.confirmDeleteSelection, confirmDeleteSelection: settings.confirmDeleteSelection !== undefined ? Boolean(settings.confirmDeleteSelection) : defaults.confirmDeleteSelection,
totalDownloadedAllTime: typeof settings.totalDownloadedAllTime === "number" && settings.totalDownloadedAllTime >= 0 ? settings.totalDownloadedAllTime : defaults.totalDownloadedAllTime,
theme: VALID_THEMES.has(settings.theme) ? settings.theme : defaults.theme, theme: VALID_THEMES.has(settings.theme) ? settings.theme : defaults.theme,
bandwidthSchedules: normalizeBandwidthSchedules(settings.bandwidthSchedules) bandwidthSchedules: normalizeBandwidthSchedules(settings.bandwidthSchedules)
}; };

View File

@ -51,6 +51,7 @@ interface LinkPopupState {
const emptyStats = (): DownloadStats => ({ const emptyStats = (): DownloadStats => ({
totalDownloaded: 0, totalDownloaded: 0,
totalDownloadedAllTime: 0,
totalFiles: 0, totalFiles: 0,
totalPackages: 0, totalPackages: 0,
sessionStartedAt: 0 sessionStartedAt: 0
@ -2124,9 +2125,13 @@ export function App(): ReactElement {
<span className="stat-value">{snapshot.speedText.replace("Geschwindigkeit: ", "")}</span> <span className="stat-value">{snapshot.speedText.replace("Geschwindigkeit: ", "")}</span>
</div> </div>
<div className="stat-item"> <div className="stat-item">
<span className="stat-label">Gesamt heruntergeladen</span> <span className="stat-label">Heruntergeladen (Session)</span>
<span className="stat-value">{humanSize(snapshot.stats.totalDownloaded)}</span> <span className="stat-value">{humanSize(snapshot.stats.totalDownloaded)}</span>
</div> </div>
<div className="stat-item">
<span className="stat-label">Heruntergeladen (Gesamt)</span>
<span className="stat-value">{humanSize(snapshot.stats.totalDownloadedAllTime)}</span>
</div>
<div className="stat-item"> <div className="stat-item">
<span className="stat-label">Fertige Dateien</span> <span className="stat-label">Fertige Dateien</span>
<span className="stat-value">{snapshot.stats.totalFiles}</span> <span className="stat-value">{snapshot.stats.totalFiles}</span>
@ -2476,7 +2481,8 @@ export function App(): ReactElement {
<footer className="status-bar"> <footer className="status-bar">
<span>Pakete: {snapshot.stats.totalPackages}</span> <span>Pakete: {snapshot.stats.totalPackages}</span>
<span>Links: {Object.keys(snapshot.session.items).length}</span> <span>Links: {Object.keys(snapshot.session.items).length}</span>
<span>Gesamt geladen: {humanSize(snapshot.stats.totalDownloaded)}</span> <span>Session: {humanSize(snapshot.stats.totalDownloaded)}</span>
<span>Gesamt: {humanSize(snapshot.stats.totalDownloadedAllTime)}</span>
<span>Hoster: {configuredProviders.length}</span> <span>Hoster: {configuredProviders.length}</span>
<span>{snapshot.speedText}</span> <span>{snapshot.speedText}</span>
<span>{snapshot.etaText}</span> <span>{snapshot.etaText}</span>

View File

@ -28,6 +28,7 @@ export interface BandwidthScheduleEntry {
export interface DownloadStats { export interface DownloadStats {
totalDownloaded: number; totalDownloaded: number;
totalDownloadedAllTime: number;
totalFiles: number; totalFiles: number;
totalPackages: number; totalPackages: number;
sessionStartedAt: number; sessionStartedAt: number;
@ -76,6 +77,7 @@ export interface AppSettings {
collapseNewPackages: boolean; collapseNewPackages: boolean;
autoSkipExtracted: boolean; autoSkipExtracted: boolean;
confirmDeleteSelection: boolean; confirmDeleteSelection: boolean;
totalDownloadedAllTime: number;
bandwidthSchedules: BandwidthScheduleEntry[]; bandwidthSchedules: BandwidthScheduleEntry[];
} }