mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-21 01:53:57 +00:00
feat: enhance game scanning notifications and UI updates
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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} />;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user