From e85a568e6eaf14f9da851647867f8d693ce04e37 Mon Sep 17 00:00:00 2001
From: Chubby Granny Chaser
Date: Mon, 3 Feb 2025 13:50:34 +0000
Subject: [PATCH 1/7] fix: fixing seeding on level
---
src/main/events/torrenting/pause-game-seed.ts | 1 +
src/main/events/torrenting/resume-game-seed.ts | 1 +
src/renderer/src/pages/downloads/download-group.tsx | 10 +++++-----
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/main/events/torrenting/pause-game-seed.ts b/src/main/events/torrenting/pause-game-seed.ts
index b19da5256..fb628ee1e 100644
--- a/src/main/events/torrenting/pause-game-seed.ts
+++ b/src/main/events/torrenting/pause-game-seed.ts
@@ -15,6 +15,7 @@ const pauseGameSeed = async (
await downloadsSublevel.put(downloadKey, {
...download,
+ status: "complete",
shouldSeed: false,
});
diff --git a/src/main/events/torrenting/resume-game-seed.ts b/src/main/events/torrenting/resume-game-seed.ts
index 63bab9523..322e3c5df 100644
--- a/src/main/events/torrenting/resume-game-seed.ts
+++ b/src/main/events/torrenting/resume-game-seed.ts
@@ -14,6 +14,7 @@ const resumeGameSeed = async (
await downloadsSublevel.put(levelKeys.game(shop, objectId), {
...download,
+ status: "seeding",
shouldSeed: true,
});
diff --git a/src/renderer/src/pages/downloads/download-group.tsx b/src/renderer/src/pages/downloads/download-group.tsx
index 8c61672c2..5bfe2948c 100644
--- a/src/renderer/src/pages/downloads/download-group.tsx
+++ b/src/renderer/src/pages/downloads/download-group.tsx
@@ -173,7 +173,7 @@ export function DownloadGroup({
const deleting = isGameDeleting(game.id);
- if (download?.progress === 1) {
+ if (game.download?.progress === 1) {
return [
{
label: t("install"),
@@ -188,8 +188,8 @@ export function DownloadGroup({
disabled: deleting,
icon: ,
show:
- download.status === "seeding" &&
- download.downloader === Downloader.Torrent,
+ game.download?.status === "seeding" &&
+ game.download?.downloader === Downloader.Torrent,
onClick: () => {
pauseSeeding(game.shop, game.objectId);
},
@@ -199,8 +199,8 @@ export function DownloadGroup({
disabled: deleting,
icon: ,
show:
- download.status !== "seeding" &&
- download.downloader === Downloader.Torrent,
+ game.download?.status !== "seeding" &&
+ game.download?.downloader === Downloader.Torrent,
onClick: () => {
resumeSeeding(game.shop, game.objectId);
},
From 1b0606027295e59463ab5ae656d044698ab9338c Mon Sep 17 00:00:00 2001
From: Chubby Granny Chaser
Date: Mon, 3 Feb 2025 13:54:03 +0000
Subject: [PATCH 2/7] fix: fixing seeding on level
---
src/renderer/src/pages/downloads/download-group.tsx | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/renderer/src/pages/downloads/download-group.tsx b/src/renderer/src/pages/downloads/download-group.tsx
index 5bfe2948c..be640bb3d 100644
--- a/src/renderer/src/pages/downloads/download-group.tsx
+++ b/src/renderer/src/pages/downloads/download-group.tsx
@@ -280,11 +280,7 @@ export function DownloadGroup({
- {
- DOWNLOADER_NAME[
- game?.download?.downloader as Downloader
- ]
- }
+ {DOWNLOADER_NAME[game.download?.downloader as Downloader]}
From 0e88300747c1b08a741983f690220754294070a6 Mon Sep 17 00:00:00 2001
From: Hachi-R
Date: Mon, 3 Feb 2025 12:55:40 -0300
Subject: [PATCH 3/7] fix: improve download and seeding logic in main process
---
.../events/torrenting/resume-game-seed.ts | 5 +++--
src/main/main.ts | 20 +++++++++----------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/src/main/events/torrenting/resume-game-seed.ts b/src/main/events/torrenting/resume-game-seed.ts
index 322e3c5df..ae0984508 100644
--- a/src/main/events/torrenting/resume-game-seed.ts
+++ b/src/main/events/torrenting/resume-game-seed.ts
@@ -8,11 +8,12 @@ const resumeGameSeed = async (
shop: GameShop,
objectId: string
) => {
- const download = await downloadsSublevel.get(levelKeys.game(shop, objectId));
+ const downloadKey = levelKeys.game(shop, objectId);
+ const download = await downloadsSublevel.get(downloadKey);
if (!download) return;
- await downloadsSublevel.put(levelKeys.game(shop, objectId), {
+ await downloadsSublevel.put(downloadKey, {
...download,
status: "seeding",
shouldSeed: true,
diff --git a/src/main/main.ts b/src/main/main.ts
index 4824a1a57..68d4684b8 100644
--- a/src/main/main.ts
+++ b/src/main/main.ts
@@ -57,23 +57,21 @@ export const loadState = async () => {
.values()
.all()
.then((games) => {
- return sortBy(
- games.filter((game) => game.queued),
- "timestamp",
- "DESC"
- );
+ return sortBy(games, "timestamp", "DESC");
});
- const [nextItemOnQueue] = downloads;
+ const [nextItemOnQueue] = downloads.filter((game) => game.queued);
const downloadsToSeed = downloads.filter(
- (download) =>
- download.shouldSeed &&
- download.downloader === Downloader.Torrent &&
- download.progress === 1 &&
- download.uri !== null
+ (game) =>
+ game.shouldSeed &&
+ game.downloader === Downloader.Torrent &&
+ game.progress === 1 &&
+ game.uri !== null
);
+ console.log("downloadsToSeed", downloadsToSeed);
+
await DownloadManager.startRPC(nextItemOnQueue, downloadsToSeed);
startMainLoop();
From 90cb35db40d91ec784fb7c33ab25f918aa1941d2 Mon Sep 17 00:00:00 2001
From: Hachi-R
Date: Mon, 3 Feb 2025 16:50:02 -0300
Subject: [PATCH 4/7] fix: improve aria2x download path detection
---
scripts/postinstall.cjs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/scripts/postinstall.cjs b/scripts/postinstall.cjs
index 70768a7d3..fc3f69ddb 100644
--- a/scripts/postinstall.cjs
+++ b/scripts/postinstall.cjs
@@ -107,7 +107,10 @@ const copyAria2Macos = async () => {
};
const copyAria2 = () => {
- if (fs.existsSync("aria2")) {
+ const aria2Path =
+ process.platform === "win32" ? "aria2/aria2c.exe" : "aria2/aria2c";
+
+ if (fs.existsSync(aria2Path)) {
console.log("Aria2 already exists, skipping download...");
return;
}
From 52771d5a00d04c3d93c4c41255fc66cfb26735c2 Mon Sep 17 00:00:00 2001
From: Chubby Granny Chaser
Date: Mon, 3 Feb 2025 20:07:12 +0000
Subject: [PATCH 5/7] feat: adding articles for seeding and peers
---
python_rpc/main.py | 2 ++
.../events/torrenting/cancel-game-download.ts | 9 +++++-
.../services/download/download-manager.ts | 6 ++--
src/renderer/src/hooks/use-download.ts | 2 +-
.../src/pages/downloads/download-group.scss | 8 +++++
.../src/pages/downloads/download-group.tsx | 18 +++++++++--
.../src/pages/downloads/downloads.tsx | 32 +++++++++----------
.../modals/download-settings-modal.tsx | 6 ++--
8 files changed, 58 insertions(+), 25 deletions(-)
diff --git a/python_rpc/main.py b/python_rpc/main.py
index 2deb20297..94c34e174 100644
--- a/python_rpc/main.py
+++ b/python_rpc/main.py
@@ -159,6 +159,8 @@ def action():
downloader = downloads.get(game_id)
if downloader:
downloader.pause_download()
+
+ if downloading_game_id == game_id:
downloading_game_id = -1
elif action == 'cancel':
downloader = downloads.get(game_id)
diff --git a/src/main/events/torrenting/cancel-game-download.ts b/src/main/events/torrenting/cancel-game-download.ts
index 5d80337ff..860d33bb8 100644
--- a/src/main/events/torrenting/cancel-game-download.ts
+++ b/src/main/events/torrenting/cancel-game-download.ts
@@ -13,7 +13,14 @@ const cancelGameDownload = async (
await DownloadManager.cancelDownload(downloadKey);
- await downloadsSublevel.del(downloadKey);
+ const download = await downloadsSublevel.get(downloadKey);
+
+ if (!download) return;
+
+ await downloadsSublevel.put(downloadKey, {
+ ...download,
+ status: "removed",
+ });
};
registerEvent("cancelGameDownload", cancelGameDownload);
diff --git a/src/main/services/download/download-manager.ts b/src/main/services/download/download-manager.ts
index 247d5c750..789a30100 100644
--- a/src/main/services/download/download-manager.ts
+++ b/src/main/services/download/download-manager.ts
@@ -219,8 +219,10 @@ export class DownloadManager {
} as PauseDownloadPayload)
.catch(() => {});
- WindowManager.mainWindow?.setProgressBar(-1);
- this.downloadingGameId = null;
+ if (downloadKey === this.downloadingGameId) {
+ WindowManager.mainWindow?.setProgressBar(-1);
+ this.downloadingGameId = null;
+ }
}
static async resumeDownload(download: Download) {
diff --git a/src/renderer/src/hooks/use-download.ts b/src/renderer/src/hooks/use-download.ts
index 49a033c9a..6d9e04d38 100644
--- a/src/renderer/src/hooks/use-download.ts
+++ b/src/renderer/src/hooks/use-download.ts
@@ -39,7 +39,7 @@ export function useDownload() {
const pauseDownload = async (shop: GameShop, objectId: string) => {
await window.electron.pauseGameDownload(shop, objectId);
await updateLibrary();
- dispatch(clearDownload());
+ if (lastPacket?.gameId === `${shop}:${objectId}`) dispatch(clearDownload());
};
const resumeDownload = async (shop: GameShop, objectId: string) => {
diff --git a/src/renderer/src/pages/downloads/download-group.scss b/src/renderer/src/pages/downloads/download-group.scss
index 2c5e9701b..4a67e8578 100644
--- a/src/renderer/src/pages/downloads/download-group.scss
+++ b/src/renderer/src/pages/downloads/download-group.scss
@@ -5,6 +5,14 @@
flex-direction: column;
gap: calc(globals.$spacing-unit * 2);
+ &__details-with-article {
+ display: flex;
+ align-items: center;
+ gap: calc(globals.$spacing-unit / 2);
+ align-self: flex-start;
+ cursor: pointer;
+ }
+
&__header {
display: flex;
align-items: center;
diff --git a/src/renderer/src/pages/downloads/download-group.tsx b/src/renderer/src/pages/downloads/download-group.tsx
index 664164710..6d5816831 100644
--- a/src/renderer/src/pages/downloads/download-group.tsx
+++ b/src/renderer/src/pages/downloads/download-group.tsx
@@ -24,6 +24,7 @@ import {
DownloadIcon,
LinkIcon,
PlayIcon,
+ QuestionIcon,
ThreeBarsIcon,
TrashIcon,
UnlinkIcon,
@@ -122,8 +123,12 @@ export function DownloadGroup({
{download.downloader === Downloader.Torrent && (
-
+
{lastPacket?.numPeers} peers / {lastPacket?.numSeeds} seeds
+
)}
>
@@ -136,7 +141,14 @@ export function DownloadGroup({
return download.status === "seeding" &&
download.downloader === Downloader.Torrent ? (
<>
- {t("seeding")}
+
+ {t("seeding")}
+
+
+
{uploadSpeed && {uploadSpeed}/s
}
>
) : (
@@ -217,7 +229,7 @@ export function DownloadGroup({
];
}
- if (isGameDownloading || download?.status === "active") {
+ if (isGameDownloading) {
return [
{
label: t("pause"),
diff --git a/src/renderer/src/pages/downloads/downloads.tsx b/src/renderer/src/pages/downloads/downloads.tsx
index eb38c6f5a..8b0e5576b 100644
--- a/src/renderer/src/pages/downloads/downloads.tsx
+++ b/src/renderer/src/pages/downloads/downloads.tsx
@@ -8,7 +8,7 @@ import "./downloads.scss";
import { DeleteGameModal } from "./delete-game-modal";
import { DownloadGroup } from "./download-group";
import type { GameShop, LibraryGame, SeedingStatus } from "@types";
-import { orderBy, sortBy } from "lodash-es";
+import { orderBy } from "lodash-es";
import { ArrowDownIcon } from "@primer/octicons-react";
export default function Downloads() {
@@ -58,24 +58,24 @@ export default function Downloads() {
complete: [],
};
- const result = sortBy(library, (game) => game.download?.timestamp).reduce(
- (prev, next) => {
- /* Game has been manually added to the library or has been canceled */
- if (!next.download?.status || next.download?.status === "removed")
- return prev;
+ const result = orderBy(
+ library,
+ (game) => game.download?.timestamp,
+ "desc"
+ ).reduce((prev, next) => {
+ /* Game has been manually added to the library */
+ if (!next.download) return prev;
- /* Is downloading */
- if (lastPacket?.gameId === next.id)
- return { ...prev, downloading: [...prev.downloading, next] };
+ /* Is downloading */
+ if (lastPacket?.gameId === next.id)
+ return { ...prev, downloading: [...prev.downloading, next] };
- /* Is either queued or paused */
- if (next.download.queued || next.download?.status === "paused")
- return { ...prev, queued: [...prev.queued, next] };
+ /* Is either queued or paused */
+ if (next.download.queued || next.download?.status === "paused")
+ return { ...prev, queued: [...prev.queued, next] };
- return { ...prev, complete: [...prev.complete, next] };
- },
- initialValue
- );
+ return { ...prev, complete: [...prev.complete, next] };
+ }, initialValue);
const queued = orderBy(result.queued, (game) => game.download?.timestamp, [
"desc",
diff --git a/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx b/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx
index 214af1d15..0892d0cf7 100644
--- a/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx
+++ b/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx
@@ -163,8 +163,10 @@ export function DownloadSettingsModal({
selectedDownloader === downloader ? "primary" : "outline"
}
disabled={
- downloader === Downloader.RealDebrid &&
- !userPreferences?.realDebridApiToken
+ (downloader === Downloader.RealDebrid &&
+ !userPreferences?.realDebridApiToken) ||
+ (downloader === Downloader.TorBox &&
+ !userPreferences?.torBoxApiToken)
}
onClick={() => setSelectedDownloader(downloader)}
>
From f4c1d2e7b73c47ec7748c92b99b55c4fd2a3b5ee Mon Sep 17 00:00:00 2001
From: Hachi-R
Date: Mon, 3 Feb 2025 17:15:17 -0300
Subject: [PATCH 6/7] style: fix sidebar layout
---
src/renderer/src/components/sidebar/sidebar.scss | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/renderer/src/components/sidebar/sidebar.scss b/src/renderer/src/components/sidebar/sidebar.scss
index 0640b3c58..b626835f9 100644
--- a/src/renderer/src/components/sidebar/sidebar.scss
+++ b/src/renderer/src/components/sidebar/sidebar.scss
@@ -23,6 +23,7 @@
&__content {
display: flex;
flex-direction: column;
+ flex: 1;
padding: calc(globals.$spacing-unit * 2);
gap: calc(globals.$spacing-unit * 2);
width: 100%;
@@ -54,6 +55,7 @@
display: flex;
color: globals.$muted-color;
border-radius: 4px;
+
&:hover {
background-color: rgba(255, 255, 255, 0.15);
}
@@ -104,13 +106,14 @@
&__container {
display: flex;
flex-direction: column;
+ flex: 1;
overflow: hidden;
}
&__section {
- gap: calc(globals.$spacing-unit * 2);
display: flex;
flex-direction: column;
+ gap: calc(globals.$spacing-unit * 2);
padding-bottom: globals.$spacing-unit;
}
From 2ed18996df00d7d07a4d7030b17b8bb49219d502 Mon Sep 17 00:00:00 2001
From: Zamitto <167933696+zamitto@users.noreply.github.com>
Date: Mon, 3 Feb 2025 17:41:34 -0300
Subject: [PATCH 7/7] fix: not saving unlocked achievements correctly
---
.../events/library/add-game-to-library.ts | 6 ++--
.../events/user/get-unlocked-achievements.ts | 6 ++--
.../achievements/merge-achievements.ts | 30 +++++++++----------
.../update-local-unlocked-achivements.ts | 2 +-
.../library-sync/merge-with-remote-games.ts | 4 +--
5 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/src/main/events/library/add-game-to-library.ts b/src/main/events/library/add-game-to-library.ts
index 629933482..c59f6ac82 100644
--- a/src/main/events/library/add-game-to-library.ts
+++ b/src/main/events/library/add-game-to-library.ts
@@ -5,7 +5,7 @@ import type { Game, GameShop } from "@types";
import { steamGamesWorker } from "@main/workers";
import { createGame } from "@main/services/library-sync";
import { steamUrlBuilder } from "@shared";
-import { updateLocalUnlockedAchivements } from "@main/services/achievements/update-local-unlocked-achivements";
+import { updateLocalUnlockedAchievements } from "@main/services/achievements/update-local-unlocked-achivements";
import { downloadsSublevel, gamesSublevel, levelKeys } from "@main/level";
const addGameToLibrary = async (
@@ -46,9 +46,9 @@ const addGameToLibrary = async (
await gamesSublevel.put(levelKeys.game(shop, objectId), game);
- updateLocalUnlockedAchivements(game);
+ await createGame(game).catch(() => {});
- createGame(game).catch(() => {});
+ updateLocalUnlockedAchievements(game);
}
};
diff --git a/src/main/events/user/get-unlocked-achievements.ts b/src/main/events/user/get-unlocked-achievements.ts
index 6deecbadf..21aad7a04 100644
--- a/src/main/events/user/get-unlocked-achievements.ts
+++ b/src/main/events/user/get-unlocked-achievements.ts
@@ -32,7 +32,7 @@ export const getUnlockedAchievements = async (
return achievementsData
.map((achievementData) => {
- const unlockedAchiementData = unlockedAchievements.find(
+ const unlockedAchievementData = unlockedAchievements.find(
(localAchievement) => {
return (
localAchievement.name.toUpperCase() ==
@@ -45,11 +45,11 @@ export const getUnlockedAchievements = async (
? achievementData.icon
: achievementData.icongray;
- if (unlockedAchiementData) {
+ if (unlockedAchievementData) {
return {
...achievementData,
unlocked: true,
- unlockTime: unlockedAchiementData.unlockTime,
+ unlockTime: unlockedAchievementData.unlockTime,
};
}
diff --git a/src/main/services/achievements/merge-achievements.ts b/src/main/services/achievements/merge-achievements.ts
index 7e6ebf0a0..e173af273 100644
--- a/src/main/services/achievements/merge-achievements.ts
+++ b/src/main/services/achievements/merge-achievements.ts
@@ -23,23 +23,21 @@ const saveAchievementsOnLocal = async (
return gameAchievementsSublevel
.get(levelKey)
.then(async (gameAchievement) => {
- if (gameAchievement) {
- await gameAchievementsSublevel.put(levelKey, {
- ...gameAchievement,
- unlockedAchievements: unlockedAchievements,
- });
+ await gameAchievementsSublevel.put(levelKey, {
+ achievements: gameAchievement?.achievements ?? [],
+ unlockedAchievements: unlockedAchievements,
+ });
- if (!sendUpdateEvent) return;
+ if (!sendUpdateEvent) return;
- return getUnlockedAchievements(objectId, shop, true)
- .then((achievements) => {
- WindowManager.mainWindow?.webContents.send(
- `on-update-achievements-${objectId}-${shop}`,
- achievements
- );
- })
- .catch(() => {});
- }
+ return getUnlockedAchievements(objectId, shop, true)
+ .then((achievements) => {
+ WindowManager.mainWindow?.webContents.send(
+ `on-update-achievements-${objectId}-${shop}`,
+ achievements
+ );
+ })
+ .catch(() => {});
});
};
@@ -133,7 +131,7 @@ export const mergeAchievements = async (
);
})
.catch((err) => {
- if (err! instanceof SubscriptionRequiredError) {
+ if (err instanceof SubscriptionRequiredError) {
achievementsLogger.log(
"Achievements not synchronized on API due to lack of subscription",
game.objectId,
diff --git a/src/main/services/achievements/update-local-unlocked-achivements.ts b/src/main/services/achievements/update-local-unlocked-achivements.ts
index 8832a475d..44f2693ab 100644
--- a/src/main/services/achievements/update-local-unlocked-achivements.ts
+++ b/src/main/services/achievements/update-local-unlocked-achivements.ts
@@ -6,7 +6,7 @@ import { parseAchievementFile } from "./parse-achievement-file";
import { mergeAchievements } from "./merge-achievements";
import type { Game, UnlockedAchievement } from "@types";
-export const updateLocalUnlockedAchivements = async (game: Game) => {
+export const updateLocalUnlockedAchievements = async (game: Game) => {
const gameAchievementFiles = findAchievementFiles(game);
const achievementFileInsideDirectory =
diff --git a/src/main/services/library-sync/merge-with-remote-games.ts b/src/main/services/library-sync/merge-with-remote-games.ts
index c3f57c535..f98fb0d35 100644
--- a/src/main/services/library-sync/merge-with-remote-games.ts
+++ b/src/main/services/library-sync/merge-with-remote-games.ts
@@ -24,7 +24,7 @@ export const mergeWithRemoteGames = async () => {
? game.playTimeInMilliseconds
: localGame.playTimeInMilliseconds;
- gamesSublevel.put(levelKeys.game(game.shop, game.objectId), {
+ await gamesSublevel.put(levelKeys.game(game.shop, game.objectId), {
...localGame,
remoteId: game.id,
lastTimePlayed: updatedLastTimePlayed,
@@ -39,7 +39,7 @@ export const mergeWithRemoteGames = async () => {
? steamUrlBuilder.icon(game.objectId, steamGame.clientIcon)
: null;
- gamesSublevel.put(levelKeys.game(game.shop, game.objectId), {
+ await gamesSublevel.put(levelKeys.game(game.shop, game.objectId), {
objectId: game.objectId,
title: steamGame?.name,
remoteId: game.id,