import { useState, useEffect } from "react"; import { PanelSection, PanelSectionRow, ButtonItem, DropdownItem, ConfirmModal, showModal } from "@decky/ui"; import { listInstalledGames, logError } from "../api"; import { safeAsyncOperation } from "../utils"; import { STYLES } from "../utils/constants"; import { GameInfo } from "../types/index"; export function InstalledGamesSection() { const [games, setGames] = useState([]); const [selectedGame, setSelectedGame] = useState(null); const [result, setResult] = useState(''); useEffect(() => { const fetchGames = async () => { const response = await safeAsyncOperation( async () => await listInstalledGames(), 'fetchGames' ); if (response?.status === "success") { const sortedGames = [...response.games] .map(game => ({ ...game, appid: parseInt(game.appid, 10), })) .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())); setGames(sortedGames); } else if (response) { logError('fetchGames: ' + JSON.stringify(response)); console.error('fetchGames: ' + JSON.stringify(response)); } }; fetchGames(); }, []); const handlePatchClick = async () => { if (!selectedGame) return; // Show confirmation modal showModal( { try { await SteamClient.Apps.SetAppLaunchOptions(selectedGame.appid, '~/fgmod/fgmod %COMMAND%'); setResult(`✓ Frame generation enabled for ${selectedGame.name}. Launch the game, enable DLSS in graphics settings, then press Insert to access OptiScaler options.`); } catch (error) { logError('handlePatchClick: ' + String(error)); setResult(error instanceof Error ? `Error: ${error.message}` : 'Error enabling frame generation'); } }} /> ); }; const handleUnpatchClick = async () => { if (!selectedGame) return; try { await SteamClient.Apps.SetAppLaunchOptions(selectedGame.appid, '~/fgmod/fgmod-uninstaller.sh %COMMAND%'); setResult(`✓ Frame generation will be disabled on next launch of ${selectedGame.name}.`); } catch (error) { logError('handleUnpatchClick: ' + String(error)); setResult(error instanceof Error ? `Error: ${error.message}` : 'Error disabling frame generation'); } }; return ( ({ data: game.appid, label: game.name }))} selectedOption={selectedGame?.appid} onChange={(option) => { const game = games.find(g => g.appid === option.data); setSelectedGame(game || null); setResult(''); }} strDefaultLabel="Choose a game" menuLabel="Installed Games" /> {result ? (
{result.includes('Error') ? '❌' : '✅'} {result}
) : null} {selectedGame ? ( <> Enable Frame Generation Disable Frame Generation ) : null}
); }