From 1c6bc49ed025610d75228ca6f487360a99d9ab1b Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Mon, 26 May 2025 10:06:19 -0300 Subject: [PATCH 1/4] feat: sync game data when opening game page --- src/main/events/index.ts | 1 + .../events/library/sync-game-by-object-id.ts | 26 +++++++++++++++++++ src/preload/index.ts | 2 ++ .../game-details/game-details.context.tsx | 8 +++--- src/renderer/src/declaration.d.ts | 1 + src/types/index.ts | 17 ++++++++++++ 6 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/main/events/library/sync-game-by-object-id.ts diff --git a/src/main/events/index.ts b/src/main/events/index.ts index d0f900d9..ed77cadb 100644 --- a/src/main/events/index.ts +++ b/src/main/events/index.ts @@ -20,6 +20,7 @@ import "./library/create-game-shortcut"; import "./library/close-game"; import "./library/delete-game-folder"; import "./library/get-game-by-object-id"; +import "./library/sync-game-by-object-id"; import "./library/get-library"; import "./library/extract-game-download"; import "./library/open-game"; diff --git a/src/main/events/library/sync-game-by-object-id.ts b/src/main/events/library/sync-game-by-object-id.ts new file mode 100644 index 00000000..6aa1c77b --- /dev/null +++ b/src/main/events/library/sync-game-by-object-id.ts @@ -0,0 +1,26 @@ +import { registerEvent } from "../register-event"; +import { gamesSublevel, levelKeys } from "@main/level"; +import { HydraApi } from "@main/services"; +import type { GameShop, UserGameDetails } from "@types"; + +const syncGameByObjectId = async ( + _event: Electron.IpcMainInvokeEvent, + shop: GameShop, + objectId: string +) => { + return HydraApi.get( + `/profile/games/${shop}/${objectId}` + ).then(async (res) => { + const gameKey = levelKeys.game(shop, objectId); + const game = await gamesSublevel.get(gameKey); + + gamesSublevel.put(gameKey, { + ...(game ?? { remoteId: null }), + ...res, + }); + + return res; + }); +}; + +registerEvent("syncGameByObjectId", syncGameByObjectId); diff --git a/src/preload/index.ts b/src/preload/index.ts index 42f8d538..e660b7b9 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -187,6 +187,8 @@ contextBridge.exposeInMainWorld("electron", { ipcRenderer.invoke("deleteGameFolder", shop, objectId), getGameByObjectId: (shop: GameShop, objectId: string) => ipcRenderer.invoke("getGameByObjectId", shop, objectId), + syncGameByObjectId: (shop: GameShop, objectId: string) => + ipcRenderer.invoke("syncGameByObjectId", shop, objectId), resetGameAchievements: (shop: GameShop, objectId: string) => ipcRenderer.invoke("resetGameAchievements", shop, objectId), extractGameDownload: (shop: GameShop, objectId: string) => diff --git a/src/renderer/src/context/game-details/game-details.context.tsx b/src/renderer/src/context/game-details/game-details.context.tsx index 21d11b33..e58ed673 100644 --- a/src/renderer/src/context/game-details/game-details.context.tsx +++ b/src/renderer/src/context/game-details/game-details.context.tsx @@ -108,7 +108,7 @@ export function GameDetailsContextProvider({ return window.electron .getGameByObjectId(shop, objectId) .then((result) => setGame(result)); - }, [setGame, shop, objectId]); + }, [shop, objectId]); const isGameDownloading = lastPacket?.gameId === game?.id && game?.download?.status === "active"; @@ -183,11 +183,13 @@ export function GameDetailsContextProvider({ .catch(() => {}); } - updateGame(); + window.electron.syncGameByObjectId(shop, objectId).then(() => { + if (abortController.signal.aborted) return; + updateGame(); + }); }, [ updateGame, dispatch, - gameTitle, objectId, shop, i18n.language, diff --git a/src/renderer/src/declaration.d.ts b/src/renderer/src/declaration.d.ts index 05d0cad0..509b34f3 100644 --- a/src/renderer/src/declaration.d.ts +++ b/src/renderer/src/declaration.d.ts @@ -155,6 +155,7 @@ declare global { shop: GameShop, objectId: string ) => Promise; + syncGameByObjectId: (shop: GameShop, objectId: string) => Promise; onGamesRunning: ( cb: ( gamesRunning: Pick[] diff --git a/src/types/index.ts b/src/types/index.ts index 19b3deab..2cb3618f 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -343,6 +343,23 @@ export type LibraryGame = Game & download: Download | null; }; +export type UserGameDetails = ShopAssets & { + userId: string; + playTimeInMilliseconds: number; + unlockedAchievementCount: number; + achievementsPointsEarnedSum: number; + lastTimePlayed: Date | null; + isDeleted: boolean; + isFavorite: boolean; + friendsWhoPlayed: { + id: string; + displayName: string; + profileImageUrl: string | null; + lastTimePlayed: Date | null; + playTimeInSeconds: number; + }[]; +}; + export * from "./game.types"; export * from "./steam.types"; export * from "./download.types"; From d2b3508b5b55c8dbf1067e33f4ec26f4a85f33bb Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Mon, 26 May 2025 11:47:36 -0300 Subject: [PATCH 2/4] fix: refactor and fix types --- src/main/events/library/sync-game-by-object-id.ts | 8 ++++++-- src/types/index.ts | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/events/library/sync-game-by-object-id.ts b/src/main/events/library/sync-game-by-object-id.ts index 6aa1c77b..0630ceb9 100644 --- a/src/main/events/library/sync-game-by-object-id.ts +++ b/src/main/events/library/sync-game-by-object-id.ts @@ -14,9 +14,13 @@ const syncGameByObjectId = async ( const gameKey = levelKeys.game(shop, objectId); const game = await gamesSublevel.get(gameKey); + const { id, playTimeInSeconds, ...rest } = res; + gamesSublevel.put(gameKey, { - ...(game ?? { remoteId: null }), - ...res, + ...game, + ...rest, + remoteId: id, + playTimeInMilliseconds: playTimeInSeconds * 1000, }); return res; diff --git a/src/types/index.ts b/src/types/index.ts index 2cb3618f..0a1cb713 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -344,8 +344,8 @@ export type LibraryGame = Game & }; export type UserGameDetails = ShopAssets & { - userId: string; - playTimeInMilliseconds: number; + id: string; + playTimeInSeconds: number; unlockedAchievementCount: number; achievementsPointsEarnedSum: number; lastTimePlayed: Date | null; From 0225e31947a2ccd8f0d6412965e3883aa422e6a5 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Mon, 26 May 2025 11:50:08 -0300 Subject: [PATCH 3/4] feat: add await to update level game --- src/main/events/library/sync-game-by-object-id.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/events/library/sync-game-by-object-id.ts b/src/main/events/library/sync-game-by-object-id.ts index 0630ceb9..02071696 100644 --- a/src/main/events/library/sync-game-by-object-id.ts +++ b/src/main/events/library/sync-game-by-object-id.ts @@ -11,12 +11,12 @@ const syncGameByObjectId = async ( return HydraApi.get( `/profile/games/${shop}/${objectId}` ).then(async (res) => { + const { id, playTimeInSeconds, ...rest } = res; + const gameKey = levelKeys.game(shop, objectId); const game = await gamesSublevel.get(gameKey); - const { id, playTimeInSeconds, ...rest } = res; - - gamesSublevel.put(gameKey, { + await gamesSublevel.put(gameKey, { ...game, ...rest, remoteId: id, From 358c15163a615b1975f81a4925672922c9298fea Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Mon, 26 May 2025 11:57:54 -0300 Subject: [PATCH 4/4] fix: remove unneeded call to current game --- src/main/events/library/sync-game-by-object-id.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/events/library/sync-game-by-object-id.ts b/src/main/events/library/sync-game-by-object-id.ts index 02071696..6235a09c 100644 --- a/src/main/events/library/sync-game-by-object-id.ts +++ b/src/main/events/library/sync-game-by-object-id.ts @@ -14,10 +14,8 @@ const syncGameByObjectId = async ( const { id, playTimeInSeconds, ...rest } = res; const gameKey = levelKeys.game(shop, objectId); - const game = await gamesSublevel.get(gameKey); await gamesSublevel.put(gameKey, { - ...game, ...rest, remoteId: id, playTimeInMilliseconds: playTimeInSeconds * 1000,