feat: enhance game scanning notifications and UI updates

This commit is contained in:
Moyasee
2026-01-19 17:57:49 +02:00
parent 049a989e85
commit fbbb2520e0
6 changed files with 56 additions and 8 deletions

View File

@@ -629,7 +629,11 @@
"game_extracted": "{{title}} extracted successfully",
"friend_started_playing_game": "{{displayName}} started playing a game",
"test_achievement_notification_title": "This is a test notification",
"test_achievement_notification_description": "Pretty cool, huh?"
"test_achievement_notification_description": "Pretty cool, huh?",
"scan_games_complete_title": "Scanning for games finished successfully",
"scan_games_complete_description": "Found {{count}} games without executable path set",
"scan_games_no_results_title": "Scanning for games finished",
"scan_games_no_results_description": "No installed games were found"
},
"system_tray": {
"open": "Open Hydra",

View File

@@ -1,8 +1,14 @@
import path from "node:path";
import fs from "node:fs";
import { t } from "i18next";
import { registerEvent } from "../register-event";
import { gamesSublevel } from "@main/level";
import { GameExecutables, logger, WindowManager } from "@main/services";
import {
GameExecutables,
LocalNotificationManager,
logger,
WindowManager,
} from "@main/services";
const SCAN_DIRECTORIES = [
String.raw`C:\Games`,
@@ -88,9 +94,32 @@ const scanInstalledGames = async (
WindowManager.mainWindow?.webContents.send("on-library-batch-complete");
const total = games.filter((g) => !g.game.executablePath).length;
const hasFoundGames = foundGames.length > 0;
await LocalNotificationManager.createNotification(
"SCAN_GAMES_COMPLETE",
t(
hasFoundGames
? "scan_games_complete_title"
: "scan_games_no_results_title",
{ ns: "notifications" }
),
t(
hasFoundGames
? "scan_games_complete_description"
: "scan_games_no_results_description",
{ ns: "notifications", count: foundGames.length }
),
{
url: "/library?openScanModal=true",
}
);
return {
foundGames,
total: games.filter((g) => !g.game.executablePath).length,
total,
};
};

View File

@@ -61,22 +61,25 @@
cursor: pointer;
transition: all ease 0.2s;
padding: globals.$spacing-unit;
display: flex;
align-items: center;
justify-content: center;
&:hover {
color: #dadbe1;
}
&--scanning {
&--scanning svg {
animation: spin 2s linear infinite;
}
}
@keyframes spin {
from {
transform: rotate(-0deg);
transform: rotate(0deg);
}
to {
transform: rotate(-360deg);
transform: rotate(360deg);
}
}

View File

@@ -1,6 +1,6 @@
import { useTranslation } from "react-i18next";
import { useEffect, useId, useMemo, useRef, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { useLocation, useNavigate, useSearchParams } from "react-router-dom";
import {
ArrowLeftIcon,
SearchIcon,
@@ -40,6 +40,7 @@ export function Header() {
const navigate = useNavigate();
const location = useLocation();
const [searchParams, setSearchParams] = useSearchParams();
const { headerTitle, draggingDisabled } = useAppSelector(
(state) => state.window
@@ -268,6 +269,14 @@ export function Header() {
return () => window.removeEventListener("resize", handleResize);
}, [isDropdownVisible]);
useEffect(() => {
if (searchParams.get("openScanModal") === "true") {
setShowScanModal(true);
searchParams.delete("openScanModal");
setSearchParams(searchParams, { replace: true });
}
}, [searchParams, setSearchParams]);
return (
<>
<header

View File

@@ -58,6 +58,8 @@ export function LocalNotificationItem({
return <SyncIcon size={24} />;
case "ACHIEVEMENT_UNLOCKED":
return <TrophyIcon size={24} />;
case "SCAN_GAMES_COMPLETE":
return <SyncIcon size={24} />;
default:
return <DownloadIcon size={24} />;
}

View File

@@ -330,7 +330,8 @@ export type LocalNotificationType =
| "EXTRACTION_COMPLETE"
| "DOWNLOAD_COMPLETE"
| "UPDATE_AVAILABLE"
| "ACHIEVEMENT_UNLOCKED";
| "ACHIEVEMENT_UNLOCKED"
| "SCAN_GAMES_COMPLETE";
export interface Notification {
id: string;