diff options
| author | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2025-01-31 22:54:15 -0500 |
|---|---|---|
| committer | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2025-01-31 22:54:15 -0500 |
| commit | 77d4d13a06cddc879d238d5cc89e47608d633921 (patch) | |
| tree | 91fdbaf916ea9f403b0285e47b1315af25893acb | |
| parent | f65cee80a47f093dbdc51fc26ace8d92b99b4f07 (diff) | |
| download | Decky-Framegen-77d4d13a06cddc879d238d5cc89e47608d633921.tar.gz Decky-Framegen-77d4d13a06cddc879d238d5cc89e47608d633921.zip | |
Feat: initial dropdown menu implementation
| -rwxr-xr-x | src/index.tsx | 101 |
1 files changed, 59 insertions, 42 deletions
diff --git a/src/index.tsx b/src/index.tsx index 52c3128..8c48ad5 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -3,7 +3,7 @@ import { PanelSection, PanelSectionRow, ButtonItem, - // Router + DropdownItem } from "@decky/ui"; import { definePlugin, callable } from "@decky/api"; import { RiAiGenerate } from "react-icons/ri"; @@ -164,25 +164,21 @@ function FGModInstallerSection() { function InstalledGamesSection() { const [games, setGames] = useState<{ appid: number; name: string }[]>([]); - const [clickedGame, setClickedGame] = useState<{ appid: number; name: string } | null>(null); + const [selectedGame, setSelectedGame] = useState<{ appid: number; name: string } | null>(null); const [result, setResult] = useState<string>(''); useEffect(() => { const fetchGames = async () => { try { const response = await listInstalledGames(); - console.log("listInstalledGames response:", response); if (response.status === "success") { const sortedGames = [...response.games] .map(game => ({ ...game, - appid: parseInt(game.appid, 10), // Convert string to number + appid: parseInt(game.appid, 10), })) .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())); - console.log("Fetched games successfully:", sortedGames.length); setGames(sortedGames); - } else { - console.error("Failed to fetch games:", response); } } catch (error) { console.error("Error fetching games:", error); @@ -192,64 +188,85 @@ function InstalledGamesSection() { fetchGames(); }, []); - const handlePatchClick = async (game: { appid: number; name: string }) => { - setClickedGame(game); + const handlePatchClick = async () => { + if (!selectedGame) return; + try { - await SteamClient.Apps.SetAppLaunchOptions(game.appid, '~/fgmod/fgmod %COMMAND%'); - setResult(`Launch options set successfully for ${game.name}. You can now select DLSS in the game's menu to use FSR Upscaling and FrameGen equivalents.`); + await SteamClient.Apps.SetAppLaunchOptions(selectedGame.appid, '~/fgmod/fgmod %COMMAND%'); + setResult(`Launch options set successfully for ${selectedGame.name}. You can now select DLSS in the game's menu to use FSR Upscaling and FrameGen equivalents.`); } catch (error) { - if (error instanceof Error) { - setResult(`Error setting launch options: ${error.message}`); - } else { - setResult('Error setting launch options'); - } + setResult(error instanceof Error ? `Error setting launch options: ${error.message}` : 'Error setting launch options'); } }; - const handleUnpatchClick = async (game: { appid: number; name: string }) => { - setClickedGame(game); + const handleUnpatchClick = async () => { + if (!selectedGame) return; + try { - await SteamClient.Apps.SetAppLaunchOptions(game.appid, '~/fgmod/fgmod-uninstaller.sh %COMMAND%'); - setResult(`DLSS mods will uninstall on next launch of ${game.name}. The game is now unpatched.`); + await SteamClient.Apps.SetAppLaunchOptions(selectedGame.appid, '~/fgmod/fgmod-uninstaller.sh %COMMAND%'); + setResult(`DLSS mods will uninstall on next launch of ${selectedGame.name}. The game is now unpatched.`); } catch (error) { - if (error instanceof Error) { - setResult(`Error clearing launch options: ${error.message}`); - } else { - setResult('Error clearing launch options'); - } + setResult(error instanceof Error ? `Error clearing launch options: ${error.message}` : 'Error clearing launch options'); } }; return ( - <PanelSection title="Select a game below to patch or unpatch:"> - {games.map((game) => ( - <PanelSectionRow key={game.appid}> - <div style={{ marginBottom: '16px' }}> - {/* Game Name as Bold Subheader */} - <div style={{ fontWeight: 'bold', marginBottom: '8px' }}>{game.name}</div> - {/* Buttons Stacked Vertically */} - <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}> + <PanelSection title="Select a game to patch:"> + <PanelSectionRow> + <DropdownItem + rgOptions={games.map(game => ({ + 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="Select a game..." + menuLabel="Installed Games" + /> + </PanelSectionRow> + + {selectedGame && ( + <> + <PanelSectionRow> + <div style={{ fontWeight: 'bold', fontSize: '1.1em' }}> + {selectedGame.name} + </div> + </PanelSectionRow> + <PanelSectionRow> + <div style={{ display: 'flex', gap: '16px', marginTop: '12px' }}> <ButtonItem layout="below" - onClick={() => handlePatchClick(game)} + onClick={handlePatchClick} > Patch </ButtonItem> <ButtonItem layout="below" - onClick={() => handleUnpatchClick(game)} + onClick={handleUnpatchClick} > Unpatch </ButtonItem> </div> + </PanelSectionRow> + </> + )} + + {result && ( + <PanelSectionRow> + <div style={{ + padding: '12px', + marginTop: '16px', + backgroundColor: 'var(--decky-selected-ui-bg)', + borderRadius: '4px' + }}> + {result} </div> - {clickedGame?.appid === game.appid && ( - <div style={{ padding: '8px', marginTop: '8px' }}> - {result} - </div> - )} </PanelSectionRow> - ))} + )} </PanelSection> ); } @@ -257,7 +274,7 @@ function InstalledGamesSection() { export default definePlugin(() => ({ name: "Framegen Plugin", titleView: <div>Decky Framegen</div>, - alwaysRender: false, + alwaysRender: true, content: ( <> <FGModInstallerSection /> |
