Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ export function useBigPictureDownloadsPageData() {
pauseOrResumeAction = "resume";
} else if (isExtracting) {
statusLabel = "Extracting";
} else if (lastPacket?.isReconnecting) {
statusLabel = "Reconnecting…";
} else if (lastPacket?.isCheckingFiles) {
statusLabel = "Checking files";
} else if (lastPacket?.isDownloadingMetadata) {
Expand Down Expand Up @@ -579,6 +581,7 @@ export function useBigPictureDownloadsPageData() {

const shouldZeroSpeed =
activeGame.download.extracting ||
lastPacket?.isReconnecting ||
lastPacket?.isCheckingFiles ||
lastPacket?.isDownloadingMetadata ||
lastPacket?.gameId !== activeGame.id;
Expand All @@ -603,6 +606,7 @@ export function useBigPictureDownloadsPageData() {
activeGame,
lastPacket?.downloadSpeed,
lastPacket?.gameId,
lastPacket?.isReconnecting,
lastPacket?.isCheckingFiles,
lastPacket?.isDownloadingMetadata,
lastPacket?.numPeers,
Expand Down
2 changes: 2 additions & 0 deletions src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"scan_games_detection_warning": "Detection relies on a community-maintained list of known games and may be outdated, so some games might not be found."
},
"bottom_panel": {
"reconnecting": "Reconnecting {{title}}…",
"no_downloads_in_progress": "No downloads in progress",
"downloading_metadata": "Downloading {{title}} metadata…",
"downloading": "Downloading {{title}}… ({{percentage}} complete) - Completion {{eta}} - {{speed}}",
Expand Down Expand Up @@ -681,6 +682,7 @@
"loading": "Loading…"
},
"downloads": {
"reconnecting": "Reconnecting…",
"resume": "Resume",
"pause": "Pause",
"eta": "Completion {{eta}}",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
"scan_games_scan_again": "Escanear nuevamente"
},
"bottom_panel": {
"reconnecting": "Reconectando {{title}}…",
"no_downloads_in_progress": "Sin descargas en progreso",
"downloading_metadata": "Descargando metadatos de {{title}}…",
"downloading": "Descargando {{title}}… ({{percentage}} completado) - Finalizando {{eta}} - {{speed}}",
Expand Down Expand Up @@ -640,6 +641,7 @@
"loading": "Cargando…"
},
"downloads": {
"reconnecting": "Reconectando…",
"resume": "Resumir",
"pause": "Pausar",
"eta": "Tiempo de finalizción {{eta}}",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/pt-BR/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
"scan_games_scan_again": "Escanear Novamente"
},
"bottom_panel": {
"reconnecting": "Reconectando {{title}}…",
"no_downloads_in_progress": "Sem downloads em andamento",
"downloading_metadata": "Baixando metadados de {{title}}…",
"downloading": "Baixando {{title}}… ({{percentage}} concluído) - Conclusão {{eta}} - {{speed}}",
Expand Down Expand Up @@ -590,6 +591,7 @@
"loading": "Carregando…"
},
"downloads": {
"reconnecting": "Reconectando…",
"resume": "Retomar",
"pause": "Pausar",
"eta": "Conclusão {{eta}}",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/pt-PT/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
"scan_games_scan_again": "Escanear Novamente"
},
"bottom_panel": {
"reconnecting": "A reconectar {{title}}…",
"no_downloads_in_progress": "Sem transferências em andamento",
"downloading_metadata": "A transferir metadados de {{title}}…",
"downloading": "A transferir {{title}}… ({{percentage}} concluído) - Conclusão {{eta}} - {{speed}}",
Expand Down Expand Up @@ -507,6 +508,7 @@
"loading": "A carregar…"
},
"downloads": {
"reconnecting": "A reconectar…",
"resume": "Continuar",
"pause": "Colocar em pausa",
"eta": "Conclusão {{eta}}",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/ru/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"scan_games_detection_warning": "Обнаружение основано на поддерживаемом сообществом списке известных игр и может быть устаревшим, поэтому некоторые игры могут быть не найдены."
},
"bottom_panel": {
"reconnecting": "Переподключение к {{title}}…",
"no_downloads_in_progress": "Нет активных загрузок",
"downloading_metadata": "Загрузка метаданных {{title}}…",
"downloading": "Загрузка {{title}}… ({{percentage}} завершено) - Окончание {{eta}} - {{speed}}",
Expand Down Expand Up @@ -682,6 +683,7 @@
"loading": "Загрузка…"
},
"downloads": {
"reconnecting": "Переподключение…",
"resume": "Возобновить",
"pause": "Приостановить",
"eta": "Окончание {{eta}}",
Expand Down
1 change: 1 addition & 0 deletions src/main/events/connectivity/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "./update-network-status";
11 changes: 11 additions & 0 deletions src/main/events/connectivity/update-network-status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { registerEvent } from "../register-event";
import { DownloadOrchestrator } from "@main/services";

const updateNetworkStatus = (
_event: Electron.IpcMainInvokeEvent,
payload: { online: boolean; switched?: boolean }
) => {
DownloadOrchestrator.onNetworkStatusChanged(payload);
};

registerEvent("updateNetworkStatus", updateNetworkStatus);
1 change: 1 addition & 0 deletions src/main/events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "./autoupdater";
import "./big-picture";
import "./catalogue";
import "./cloud-save";
import "./connectivity";
import "./download-sources";
import "./friends";
import "./hardware";
Expand Down
10 changes: 9 additions & 1 deletion src/main/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { app, BrowserWindow, net, protocol } from "electron";
import { app, BrowserWindow, net, powerMonitor, protocol } from "electron";
import updater from "electron-updater";
import i18n from "i18next";
import path from "node:path";
Expand All @@ -10,6 +10,7 @@ import {
WindowManager,
Lock,
PowerSaveBlockerManager,
DownloadOrchestrator,
} from "@main/services";
import resources from "@locales";
import { PythonRPC } from "./services/python-rpc";
Expand Down Expand Up @@ -171,6 +172,13 @@ app.whenReady().then(async () => {
WindowManager.createNotificationWindow();
WindowManager.createSystemTray(language || "en");

powerMonitor.on("resume", () => {
DownloadOrchestrator.onNetworkStatusChanged({
online: true,
switched: true,
});
});

if (deepLinkArg) {
handleDeepLinkPath(deepLinkArg);
}
Expand Down
80 changes: 80 additions & 0 deletions src/main/services/download-orchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,87 @@ function withInsertedId(ids: string[], id: string, targetIndex?: number) {
return nextIds;
}

const NO_INTERNET_GRACE_MS = 15000;
const RECONNECT_DEBOUNCE_MS = 2000;

export class DownloadOrchestrator {
private static isOnline = true;
private static reconnectGraceTimer: NodeJS.Timeout | null = null;
private static lastReconnectAt = 0;

static onNetworkStatusChanged(payload: {
online: boolean;
switched?: boolean;
}) {
const { online } = payload;

if (!DownloadManager.isJsDownloadActive) {
this.isOnline = online;
this.clearReconnectGrace();
return;
}

if (!online) {
if (this.isOnline) {
logger.log(
"[DownloadOrchestrator] Connection lost during download; waiting for it to come back"
);
}
this.isOnline = false;
DownloadManager.notifyReconnecting(true);

if (!this.reconnectGraceTimer) {
this.reconnectGraceTimer = setTimeout(() => {
this.reconnectGraceTimer = null;
if (this.isOnline) return;

if (!DownloadManager.isActiveDownloadReconnecting()) {
this.isOnline = true;
return;
}

void this.stopActiveDownloadForNoNetwork();
}, NO_INTERNET_GRACE_MS);
}
return;
}

this.isOnline = true;
this.clearReconnectGrace();

const now = Date.now();
if (now - this.lastReconnectAt < RECONNECT_DEBOUNCE_MS) return;
this.lastReconnectAt = now;

logger.log(
"[DownloadOrchestrator] Connection available; resuming the active download"
);
DownloadManager.reconnectActiveDownload();
}

private static clearReconnectGrace() {
if (this.reconnectGraceTimer) {
clearTimeout(this.reconnectGraceTimer);
this.reconnectGraceTimer = null;
}
}

private static async stopActiveDownloadForNoNetwork() {
const downloadId = DownloadManager.getActiveDownloadId();
if (!downloadId) return;

const download = await downloadsSublevel.get(downloadId).catch(() => null);
if (!download) return;

logger.log(
"[DownloadOrchestrator] No connection after the grace window; pausing the download"
);
await this.pauseDownload(download, {
reason: "paused",
startNextQueued: false,
});
}

private static async getAllDownloads() {
return downloadsSublevel.values().all();
}
Expand Down
Loading
Loading