From 753a293cd70fcf59abebeb6e167dcae12f80e1ca Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Thu, 26 Sep 2024 21:51:15 -0300 Subject: [PATCH] feat: remove notification spam --- src/locales/en/translation.json | 3 +- .../events/library/add-game-to-library.ts | 6 ++-- .../game-achievements-observer.ts | 2 +- .../achievements/get-game-achievement-data.ts | 21 +++++++++++ .../achievements/merge-achievements.ts | 23 ++++++------ ...s => update-local-unlocked-achivements.ts} | 36 ++++++++----------- .../library-sync/upload-games-batch.ts | 4 +-- src/main/services/notifications.ts | 34 +++++++++++++----- 8 files changed, 80 insertions(+), 49 deletions(-) create mode 100644 src/main/services/achievements/get-game-achievement-data.ts rename src/main/services/achievements/{save-all-local-steam-achivements.ts => update-local-unlocked-achivements.ts} (71%) diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index c8700663..fbfe4835 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -227,7 +227,8 @@ "repack_count_other": "{{count}} repacks added", "new_update_available": "Version {{version}} available", "restart_to_install_update": "Restart Hydra to install the update", - "game_achievement_unlocked": "{{game}} achievement unlocked" + "notification_achievement_unlocked_title": "Achievement unlocked for {{game}}", + "notification_achievement_unlocked_body": "{{achievement}} and other {{count}} were unlocked" }, "system_tray": { "open": "Open Hydra", diff --git a/src/main/events/library/add-game-to-library.ts b/src/main/events/library/add-game-to-library.ts index 8e9d0886..20c9a6e9 100644 --- a/src/main/events/library/add-game-to-library.ts +++ b/src/main/events/library/add-game-to-library.ts @@ -8,7 +8,7 @@ import { getFileBase64 } from "@main/helpers"; import { steamGamesWorker } from "@main/workers"; import { createGame } from "@main/services/library-sync"; import { steamUrlBuilder } from "@shared"; -import { saveAllLocalSteamAchivements } from "@main/services/achievements/save-all-local-steam-achivements"; +import { updateLocalUnlockedAchivements } from "@main/services/achievements/update-local-unlocked-achivements"; const addGameToLibrary = async ( _event: Electron.IpcMainInvokeEvent, @@ -53,9 +53,7 @@ const addGameToLibrary = async ( }); } - // TODO: search for achievements only from this game - console.log("Searching for achievements", title); - saveAllLocalSteamAchivements(); + updateLocalUnlockedAchivements(true, objectID); const game = await gameRepository.findOne({ where: { objectID } }); diff --git a/src/main/services/achievements/game-achievements-observer.ts b/src/main/services/achievements/game-achievements-observer.ts index 16cafa48..f6453a6d 100644 --- a/src/main/services/achievements/game-achievements-observer.ts +++ b/src/main/services/achievements/game-achievements-observer.ts @@ -25,7 +25,7 @@ const processAchievementFile = async (game: Game, file: AchievementFile) => { console.log(unlockedAchievements); if (unlockedAchievements.length) { - mergeAchievements(game.objectID, game.shop, unlockedAchievements); + mergeAchievements(game.objectID, game.shop, unlockedAchievements, true); } } }; diff --git a/src/main/services/achievements/get-game-achievement-data.ts b/src/main/services/achievements/get-game-achievement-data.ts new file mode 100644 index 00000000..907a32b7 --- /dev/null +++ b/src/main/services/achievements/get-game-achievement-data.ts @@ -0,0 +1,21 @@ +import { userPreferencesRepository } from "@main/repository"; +import { HydraApi } from "../hydra-api"; + +export const getGameAchievementData = async ( + objectId: string, + shop: string +) => { + const userPreferences = await userPreferencesRepository.findOne({ + where: { id: 1 }, + }); + + return HydraApi.get( + "/games/achievements", + { + shop, + objectId, + language: userPreferences?.language || "en", + }, + { needsAuth: false } + ); +}; diff --git a/src/main/services/achievements/merge-achievements.ts b/src/main/services/achievements/merge-achievements.ts index fc1e95a4..969ed9a4 100644 --- a/src/main/services/achievements/merge-achievements.ts +++ b/src/main/services/achievements/merge-achievements.ts @@ -22,12 +22,15 @@ const saveAchievementsOnLocal = async ( export const mergeAchievements = async ( objectId: string, shop: string, - achievements: UnlockedAchievement[] + achievements: UnlockedAchievement[], + publishNotification: boolean ) => { const game = await gameRepository.findOne({ where: { objectID: objectId, shop: shop as GameShop }, }); + if (!game) return; + const localGameAchievement = await gameAchievementRepository.findOne({ where: { objectId, @@ -53,20 +56,20 @@ export const mergeAchievements = async ( ); } - for (const achievement of newAchievements.slice(0, 3)) { - const completeAchievement = JSON.parse( + if (newAchievements.length > 0 && publishNotification) { + const achievement = newAchievements.pop()!; + const achievementInfo = JSON.parse( localGameAchievement?.achievements || "[]" ).find((steamAchievement) => { return achievement.name === steamAchievement.name; }); - if (completeAchievement) { - publishNewAchievementNotification( - game?.title || " ", - completeAchievement.displayName, - completeAchievement.icon - ); - } + publishNewAchievementNotification( + game.title ?? "", + achievementInfo.displayName, + achievementInfo.icon, + newAchievements.length + ); } const mergedLocalAchievements = unlockedAchievements.concat(newAchievements); diff --git a/src/main/services/achievements/save-all-local-steam-achivements.ts b/src/main/services/achievements/update-local-unlocked-achivements.ts similarity index 71% rename from src/main/services/achievements/save-all-local-steam-achivements.ts rename to src/main/services/achievements/update-local-unlocked-achivements.ts index 154c3f79..eb80773e 100644 --- a/src/main/services/achievements/save-all-local-steam-achivements.ts +++ b/src/main/services/achievements/update-local-unlocked-achivements.ts @@ -1,21 +1,16 @@ -import { - gameAchievementRepository, - gameRepository, - userPreferencesRepository, -} from "@main/repository"; +import { gameAchievementRepository, gameRepository } from "@main/repository"; import { findSteamGameAchievementFiles } from "./find-steam-game-achivement-files"; import { parseAchievementFile } from "./parse-achievement-file"; -import { HydraApi } from "@main/services"; import { checkUnlockedAchievements } from "./check-unlocked-achievements"; import { mergeAchievements } from "./merge-achievements"; import type { UnlockedAchievement } from "@types"; +import { getGameAchievementData } from "./get-game-achievement-data"; -export const saveAllLocalSteamAchivements = async () => { - const userPreferences = await userPreferencesRepository.findOne({ - where: { id: 1 }, - }); - - const gameAchievementFiles = findSteamGameAchievementFiles(); +export const updateLocalUnlockedAchivements = async ( + publishNotification: boolean, + objectId?: string +) => { + const gameAchievementFiles = findSteamGameAchievementFiles(objectId); for (const objectId of gameAchievementFiles.keys()) { const [game, localAchievements] = await Promise.all([ @@ -36,15 +31,7 @@ export const saveAllLocalSteamAchivements = async () => { ); if (!localAchievements || !localAchievements.achievements) { - await HydraApi.get( - "/games/achievements", - { - shop: "steam", - objectId, - language: userPreferences?.language || "en", - }, - { needsAuth: false } - ) + await getGameAchievementData(objectId, "steam") .then((achievements) => { return gameAchievementRepository.upsert( { @@ -75,6 +62,11 @@ export const saveAllLocalSteamAchivements = async () => { } } - mergeAchievements(objectId, "steam", unlockedAchievements); + mergeAchievements( + objectId, + "steam", + unlockedAchievements, + publishNotification + ); } }; diff --git a/src/main/services/library-sync/upload-games-batch.ts b/src/main/services/library-sync/upload-games-batch.ts index 3d06f118..f46b0f14 100644 --- a/src/main/services/library-sync/upload-games-batch.ts +++ b/src/main/services/library-sync/upload-games-batch.ts @@ -4,7 +4,7 @@ import { IsNull } from "typeorm"; import { HydraApi } from "../hydra-api"; import { mergeWithRemoteGames } from "./merge-with-remote-games"; import { WindowManager } from "../window-manager"; -import { saveAllLocalSteamAchivements } from "../achievements/save-all-local-steam-achivements"; +import { updateLocalUnlockedAchivements } from "../achievements/update-local-unlocked-achivements"; export const uploadGamesBatch = async () => { const games = await gameRepository.find({ @@ -29,7 +29,7 @@ export const uploadGamesBatch = async () => { await mergeWithRemoteGames(); - await saveAllLocalSteamAchivements(); + await updateLocalUnlockedAchivements(false); if (WindowManager.mainWindow) WindowManager.mainWindow.webContents.send("on-library-batch-complete"); diff --git a/src/main/services/notifications.ts b/src/main/services/notifications.ts index c3e524d8..9df932c6 100644 --- a/src/main/services/notifications.ts +++ b/src/main/services/notifications.ts @@ -99,7 +99,8 @@ const downloadImage = async (url: string, iconPath: string) => { export const publishNewAchievementNotification = async ( game: string, name: string, - iconUrl: string + iconUrl: string, + count: number ) => { const iconPath = path.join( app.getPath("temp"), @@ -108,14 +109,29 @@ export const publishNewAchievementNotification = async ( await downloadImage(iconUrl, iconPath).catch(() => {}); - new Notification({ - title: t("game_achievement_unlocked", { - ns: "notifications", - game, - }), - body: name, - icon: iconPath, - }).show(); + if (count > 1) { + new Notification({ + title: t("notification_achievement_unlocked_title", { + ns: "notifications", + game: game, + }), + body: t("notification_achievement_unlocked_body", { + ns: "notifications", + achievement: name, + count, + }), + icon: iconPath, + }).show(); + } else { + new Notification({ + title: t("notification_achievement_unlocked_title", { + ns: "notifications", + game: game, + }), + body: name, + icon: iconPath, + }).show(); + } }; export const publishNewFriendRequestNotification = async () => {};