From 2108a523bc39f5229a719039e63566458efe1558 Mon Sep 17 00:00:00 2001 From: Moyasee Date: Mon, 19 Jan 2026 18:01:55 +0200 Subject: [PATCH] refactor: streamline game scanning logic and enhance notification handling --- .../events/library/scan-installed-games.ts | 97 ++++++++----------- .../components/header/scan-games-modal.tsx | 2 +- 2 files changed, 42 insertions(+), 57 deletions(-) diff --git a/src/main/events/library/scan-installed-games.ts b/src/main/events/library/scan-installed-games.ts index 0bdc818c..7e6c290f 100644 --- a/src/main/events/library/scan-installed-games.ts +++ b/src/main/events/library/scan-installed-games.ts @@ -28,6 +28,39 @@ interface ScanResult { total: number; } +async function searchInDirectories( + executableNames: Set +): Promise { + for (const scanDir of SCAN_DIRECTORIES) { + if (!fs.existsSync(scanDir)) continue; + + const foundPath = await findExecutableInFolder(scanDir, executableNames); + if (foundPath) return foundPath; + } + return null; +} + +async function publishScanNotification(foundCount: number): Promise { + const hasFoundGames = foundCount > 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: foundCount } + ), + { url: "/library?openScanModal=true" } + ); +} + const scanInstalledGames = async ( _event: Electron.IpcMainInvokeEvent ): Promise => { @@ -43,84 +76,36 @@ const scanInstalledGames = async ( ); const foundGames: FoundGame[] = []; + const gamesToScan = games.filter((g) => !g.game.executablePath); - for (const { key, game } of games) { - if (game.executablePath) { - continue; - } - + for (const { key, game } of gamesToScan) { const executableNames = GameExecutables.getExecutablesForGame( game.objectId ); - if (!executableNames || executableNames.length === 0) { - continue; - } + if (!executableNames || executableNames.length === 0) continue; const normalizedNames = new Set( executableNames.map((name) => name.toLowerCase()) ); - let foundPath: string | null = null; - - for (const scanDir of SCAN_DIRECTORIES) { - if (!fs.existsSync(scanDir)) { - continue; - } - - foundPath = await findExecutableInFolder(scanDir, normalizedNames); - - if (foundPath) { - break; - } - } + const foundPath = await searchInDirectories(normalizedNames); if (foundPath) { - await gamesSublevel.put(key, { - ...game, - executablePath: foundPath, - }); + await gamesSublevel.put(key, { ...game, executablePath: foundPath }); logger.info( `[ScanInstalledGames] Found executable for ${game.objectId}: ${foundPath}` ); - foundGames.push({ - title: game.title, - executablePath: foundPath, - }); + foundGames.push({ title: game.title, executablePath: foundPath }); } } WindowManager.mainWindow?.webContents.send("on-library-batch-complete"); + await publishScanNotification(foundGames.length); - 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, - }; + return { foundGames, total: gamesToScan.length }; }; async function findExecutableInFolder( diff --git a/src/renderer/src/components/header/scan-games-modal.tsx b/src/renderer/src/components/header/scan-games-modal.tsx index fa771182..9e9b1de1 100644 --- a/src/renderer/src/components/header/scan-games-modal.tsx +++ b/src/renderer/src/components/header/scan-games-modal.tsx @@ -31,7 +31,7 @@ export function ScanGamesModal({ scanResult, onStartScan, onClearResult, -}: ScanGamesModalProps) { +}: Readonly) { const { t } = useTranslation("header"); const handleClose = () => {