import { ButtonItem, ConfirmModal, DialogButton, Focusable, PanelSection, PanelSectionRow, ToggleField, gamepadDialogClasses, showModal } from "@decky/ui"; import { useCallback, useEffect, useRef, useState } from "react"; import { FaArrowLeft } from "react-icons/fa"; import { ConfigurationData } from "../config/configSchema"; import { GameTarget } from "../hooks/useGameConfiguration"; import { GameConfigurationControls } from "./GameConfigurationControls"; import { GameConfigurationSelector } from "./GameConfigurationSelector"; import { ProfileDetails } from "./ProfileDetails"; interface ConfigurationTabProps { config: ConfigurationData; targets: GameTarget[]; runningGame: GameTarget | null; showDebugTab: boolean; onShowDebugTabChange: (value: boolean) => void; onSelect: (appid: string) => void; onConfigChange: (fieldName: keyof ConfigurationData, value: boolean | number | string | string[]) => Promise; onEnable: (appid: string) => Promise; onEnableAll: () => Promise; onRepair: (appid: string) => Promise; onReset: () => Promise; onResetAll: () => Promise; } export function ConfigurationTab({ config, targets, runningGame, showDebugTab, onShowDebugTabChange, onSelect, onConfigChange, onEnable, onEnableAll, onRepair, onReset, onResetAll, }: ConfigurationTabProps) { const [detailAppId, setDetailAppId] = useState(null); const [focusFpsMultiplier, setFocusFpsMultiplier] = useState(false); const [focusDetailAction, setFocusDetailAction] = useState<"enable" | "fps" | null>(null); const [focusConfiguredToggle, setFocusConfiguredToggle] = useState(false); const enableRef = useRef(null); const closeDetails = useCallback(() => { setFocusFpsMultiplier(false); setFocusDetailAction(null); setDetailAppId(null); }, []); const clearFpsFocusRequest = useCallback(() => setFocusFpsMultiplier(false), []); const clearConfiguredToggleFocusRequest = useCallback(() => setFocusConfiguredToggle(false), []); useEffect(() => { if (!focusDetailAction) return; if (focusDetailAction === "fps") { setFocusFpsMultiplier(true); setFocusDetailAction(null); return; } const frame = requestAnimationFrame(() => { enableRef.current?.querySelector('[role="button"]')?.focus(); setFocusDetailAction(null); }); return () => cancelAnimationFrame(frame); }, [focusDetailAction]); const selectedTarget = detailAppId ? targets.find((target) => target.appid === detailAppId) : null; if (detailAppId === null) { return ( <> { setFocusConfiguredToggle(false); setFocusDetailAction(targets.find((target) => target.appid === appid)?.configured ? "fps" : "enable"); onSelect(appid); setDetailAppId(appid); }} onEnableAll={onEnableAll} onResetAll={onResetAll} focusConfiguredToggle={focusConfiguredToggle} onConfiguredToggleFocused={clearConfiguredToggleFocusRequest} /> ); } const profileLabel = selectedTarget?.name || "Game profile"; const profileTransport = selectedTarget ? selectedTarget.directFlatpak ? "Non-Steam · Direct Flatpak" : selectedTarget.nonSteam ? "Non-Steam" : "Steam" : "Game"; const profileDescription = selectedTarget ? `${profileTransport} · App ID ${selectedTarget.appid} · ${selectedTarget.configured ? "LSFG-VK Enabled" : "LSFG-VK not enabled"}` : "Game is no longer available"; const enableProfile = async (appid: string, quitRunningGame = false) => { if (!(await onEnable(appid))) return; if (quitRunningGame) SteamClient.Apps.TerminateApp(appid, false); setFocusFpsMultiplier(true); }; const handleProfileAction = async () => { if (selectedTarget?.configured) { await onReset(); setFocusConfiguredToggle(true); closeDetails(); } else if (detailAppId) { const isRunningUnconfigured = runningGame?.appid === detailAppId && runningGame.nonSteam === false && selectedTarget?.nonSteam === false && !runningGame.configured; if (isRunningUnconfigured) { showModal( void enableProfile(detailAppId, true)} onCancel={() => void enableProfile(detailAppId)} />, ); } else { await enableProfile(detailAppId); } } }; return (
{profileLabel}
{!selectedTarget?.configured && selectedTarget && ( Enable for next launch )} {selectedTarget?.configured && ( onRepair(selectedTarget.appid) : undefined} /> )} {selectedTarget?.configured && ( Remove profile )}
); }