import { ButtonItem, Field, Focusable, PanelSection, PanelSectionRow } from "@decky/ui"; import { useCallback, useEffect, useRef, useState } from "react"; import { ConfigurationData } from "../config/configSchema"; import { GameTarget } from "../hooks/useGameConfiguration"; import { GameConfigurationControls } from "./GameConfigurationControls"; import { GameConfigurationSelector } from "./GameConfigurationSelector"; interface ConfigurationTabProps { config: ConfigurationData; targets: GameTarget[]; runningGame: GameTarget | null; onSelect: (appid: string) => void; onConfigChange: (fieldName: keyof ConfigurationData, value: boolean | number | string | string[]) => Promise; onEnable: (appid: string) => Promise; onReset: () => Promise; onResetAll: () => Promise; } export function ConfigurationTab({ config, targets, runningGame, onSelect, onConfigChange, onEnable, onReset, onResetAll, }: ConfigurationTabProps) { const [detailAppId, setDetailAppId] = useState(null); const [focusFpsMultiplier, setFocusFpsMultiplier] = useState(false); const [focusBackToGames, setFocusBackToGames] = useState(false); const backToGamesRef = useRef(null); const promptedRunningAppId = useRef(null); const closeDetails = useCallback(() => { setFocusFpsMultiplier(false); setFocusBackToGames(false); setDetailAppId(null); }, []); const clearFpsFocusRequest = useCallback(() => setFocusFpsMultiplier(false), []); useEffect(() => { if (!focusBackToGames) return; const frame = requestAnimationFrame(() => { backToGamesRef.current?.querySelector('[role="button"]')?.focus(); setFocusBackToGames(false); }); return () => cancelAnimationFrame(frame); }, [focusBackToGames]); useEffect(() => { if (!runningGame || runningGame.configured) { promptedRunningAppId.current = null; return; } if (promptedRunningAppId.current !== runningGame.appid && detailAppId === null) { promptedRunningAppId.current = runningGame.appid; setDetailAppId(runningGame.appid); } }, [detailAppId, runningGame?.appid, runningGame?.configured]); const selectedTarget = detailAppId ? targets.find((target) => target.appid === detailAppId) : null; if (detailAppId === null) { return ( { setFocusBackToGames(true); onSelect(appid); setDetailAppId(appid); }} onResetAll={onResetAll} /> ); } const profileLabel = selectedTarget?.name || "Game profile"; const profileDescription = selectedTarget ? `${selectedTarget.nonSteam ? "Non-Steam" : "Steam"} · App ID ${selectedTarget.appid} · ${selectedTarget.configured ? "Configured" : "Not configured"}` : "Game is no longer available"; return ( Back to games {selectedTarget?.configured && ( )} { if (selectedTarget?.configured) { promptedRunningAppId.current = detailAppId; await onReset(); closeDetails(); } else if (detailAppId) { if (await onEnable(detailAppId)) setFocusFpsMultiplier(true); } }} > {selectedTarget?.configured ? "Remove profile" : "Enable for next launch"} ); }