diff options
Diffstat (limited to 'src/components/Content.tsx')
| -rw-r--r-- | src/components/Content.tsx | 181 |
1 files changed, 117 insertions, 64 deletions
diff --git a/src/components/Content.tsx b/src/components/Content.tsx index 1d7d2d1..ce3c018 100644 --- a/src/components/Content.tsx +++ b/src/components/Content.tsx @@ -1,81 +1,118 @@ import { Tabs } from "@decky/ui"; import { useEffect, useRef, useState } from "react"; -import { FaFileAlt, FaGamepad, FaLayerGroup, FaList, FaTools } from "react-icons/fa"; +import { FaCube, FaFileAlt, FaGamepad, FaList, FaTools } from "react-icons/fa"; import { ConfigurationData } from "../config/configSchema"; -import { tabStyles } from "../styles"; +import { useFlatpakConfiguration } from "../hooks/useFlatpakConfiguration"; import { useGameConfiguration } from "../hooks/useGameConfiguration"; -import { useInstallationActions } from "../hooks/useInstallationActions"; -import { useInstallationStatus } from "../hooks/useLsfgHooks"; +import { useInstallation } from "../hooks/useLsfgHooks"; +import { tabStyles } from "../styles"; import { ConfigFileTab } from "./ConfigFileTab"; import { ConfigurationTab } from "./ConfigurationTab"; -import { FlatpaksTab } from "./FlatpaksTab"; +import { FlatpakNowPlayingTab } from "./FlatpakNowPlayingTab"; +import { FlatpakTab } from "./FlatpakTab"; import { NowPlayingTab } from "./NowPlayingTab"; import { SetupTab } from "./SetupTab"; const tabIcons = { nowPlaying: <FaGamepad size={18} />, - configuration: <FaList size={18} />, - flatpak: <FaLayerGroup size={18} />, + games: <FaList size={18} />, + flatpak: <FaCube size={18} />, configFile: <FaFileAlt size={18} />, setup: <FaTools size={18} />, }; +const DEBUG_TAB_VISIBILITY_KEY = "lsfg-debug-tab-visible-v1"; + +function usePersistentBoolean(key: string, defaultValue: boolean) { + const [value, setValue] = useState(() => { + try { + const stored = localStorage.getItem(key); + return stored === null ? defaultValue : stored === "true"; + } catch { + return defaultValue; + } + }); + + useEffect(() => { + try { + localStorage.setItem(key, String(value)); + } catch {} + }, [key, value]); + + return [value, setValue] as const; +} + export function Content() { const { - isInstalled, - installationStatus, - setIsInstalled, - setInstallationStatus, - losslessScalingInstalled, - losslessScalingStatus, - steamBranchStatus, - checkInstallation, - } = useInstallationStatus(); - const { config, + runningConfig, targets, runningGame, setSelectedAppId, save, + saveFor, enable, enableAll, + repair, resetSelected, resetAll, reload, } = useGameConfiguration(); - const { isInstalling, isUninstalling, handleInstall, handleUninstall } = useInstallationActions(); - const [tab, setTab] = useState("Setup"); + const { + isInstalled, + installationStatus, + losslessScalingInstalled, + losslessScalingStatus, + steamBranchStatus, + isInstalling, + isUninstalling, + install, + uninstall, + } = useInstallation(reload); const setupComplete = isInstalled && losslessScalingInstalled && steamBranchStatus?.success === true && steamBranchStatus.installed && !steamBranchStatus.needs_switch; - const previousRunningState = useRef<{ appid: string; configured: boolean } | null>(null); + const flatpak = useFlatpakConfiguration(setupComplete); + const [tab, setTab] = useState("Setup"); + const [showDebugTab, setShowDebugTab] = usePersistentBoolean(DEBUG_TAB_VISIBILITY_KEY, true); + const previousRunningWorkload = useRef<string | null>(null); + const runningFlatpak = flatpak.runningApp; + const hasNowPlaying = Boolean(runningGame?.configured || runningFlatpak); + const runningWorkload = runningGame?.configured + ? `steam:${runningGame.appid}` + : runningFlatpak ? `flatpak:${runningFlatpak.app_id}` : null; useEffect(() => { if (!setupComplete) { setTab("Setup"); return; } - setTab((current) => current === "Setup" ? (runningGame?.configured ? "NowPlaying" : "Configuration") : current); - }, [runningGame?.configured, setupComplete]); + setTab((current) => current === "Setup" ? (hasNowPlaying ? "NowPlaying" : "Games") : current); + }, [hasNowPlaying, setupComplete]); useEffect(() => { if (!setupComplete) return; - const current = runningGame ? { appid: runningGame.appid, configured: runningGame.configured } : null; - const previous = previousRunningState.current; - previousRunningState.current = current; - if (current?.appid && (current.appid !== previous?.appid || current.configured !== previous?.configured)) { - setTab(current.configured ? "NowPlaying" : "Configuration"); - } else if (!current && previous) { - setTab((currentTab) => currentTab === "NowPlaying" ? "Configuration" : currentTab); + const previous = previousRunningWorkload.current; + previousRunningWorkload.current = runningWorkload; + if (runningWorkload && runningWorkload !== previous) setTab("NowPlaying"); + else if (!runningWorkload && previous) { + setTab((current) => current === "NowPlaying" ? "Games" : current); + } + }, [runningWorkload, setupComplete]); + + useEffect(() => { + if (isInstalled) { + void reload(); + void flatpak.reload(); } - }, [runningGame?.appid, runningGame?.configured, setupComplete]); + }, [isInstalled, reload, flatpak.reload]); useEffect(() => { - if (isInstalled) void reload(); - }, [isInstalled, reload]); + if (!showDebugTab && tab === "ConfigFile") setTab("Games"); + }, [showDebugTab, tab]); const handleConfigChange = async ( fieldName: keyof ConfigurationData, @@ -85,15 +122,7 @@ export function Content() { await save({ ...config, [fieldName]: value }, cleanupLaunchOptions); }; - const onInstall = () => { - void handleInstall(setIsInstalled, setInstallationStatus, reload, checkInstallation); - }; - - const onUninstall = () => { - void handleUninstall(setIsInstalled, setInstallationStatus, checkInstallation); - }; - - const setupContent = ( + const setup = ( <SetupTab isInstalled={isInstalled} installationStatus={installationStatus} @@ -102,48 +131,72 @@ export function Content() { steamBranchStatus={steamBranchStatus} isInstalling={isInstalling} isUninstalling={isUninstalling} - onInstall={onInstall} - onUninstall={onUninstall} + onInstall={() => void install()} + onUninstall={() => void uninstall()} /> ); + const nowPlaying = runningGame?.configured ? ( + <NowPlayingTab + game={runningGame} + config={runningConfig} + onConfigChange={async (field, value) => { + await saveFor(runningGame.appid, { ...runningConfig, [field]: value }, true); + }} + /> + ) : runningFlatpak ? ( + <FlatpakNowPlayingTab + app={runningFlatpak} + busy={flatpak.busyAppId === runningFlatpak.app_id} + onConfigChange={flatpak.updateConfig} + onWorkaroundChange={flatpak.updateWorkarounds} + /> + ) : null; + const tabs = setupComplete ? [ - ...(runningGame?.configured ? [{ - id: "NowPlaying", - title: tabIcons.nowPlaying, - content: ( - <NowPlayingTab - game={runningGame} - config={config} - onConfigChange={(fieldName, value) => handleConfigChange(fieldName, value)} - /> - ), - }] : []), + ...(nowPlaying ? [{ id: "NowPlaying", title: tabIcons.nowPlaying, content: nowPlaying }] : []), { - id: "Configuration", - title: tabIcons.configuration, + id: "Games", + title: tabIcons.games, content: ( <ConfigurationTab config={config} targets={targets} runningGame={runningGame} + showDebugTab={showDebugTab} + onShowDebugTabChange={setShowDebugTab} onSelect={setSelectedAppId} - onConfigChange={(fieldName, value) => handleConfigChange(fieldName, value, true)} + onConfigChange={(field, value) => handleConfigChange(field, value, true)} onEnable={enable} onEnableAll={enableAll} + onRepair={repair} onReset={resetSelected} onResetAll={resetAll} /> ), }, - { id: "Flatpak", title: tabIcons.flatpak, content: <FlatpaksTab /> }, - { id: "ConfigFile", title: tabIcons.configFile, content: <ConfigFileTab /> }, // comment out for prod - { id: "Setup", title: tabIcons.setup, content: setupContent }, + { + id: "Flatpak", + title: tabIcons.flatpak, + content: ( + <FlatpakTab + apps={flatpak.apps} + runningApp={runningFlatpak} + loading={flatpak.loading} + busyAppId={flatpak.busyAppId} + onRefresh={flatpak.reload} + onEnable={flatpak.enableApp} + onRemove={flatpak.removeApp} + onConfigChange={flatpak.updateConfig} + onWorkaroundChange={flatpak.updateWorkarounds} + /> + ), + }, + ...(showDebugTab ? [{ id: "ConfigFile", title: tabIcons.configFile, content: <ConfigFileTab /> }] : []), + { id: "Setup", title: tabIcons.setup, content: setup }, ] - : [ - { id: "Setup", title: tabIcons.setup, content: setupContent }, - ]; + : [{ id: "Setup", title: tabIcons.setup, content: setup }]; return ( <div @@ -151,7 +204,7 @@ export function Content() { style={{ height: "95%", width: "300px", position: "fixed", marginTop: "-12px", overflow: "hidden" }} > <style>{tabStyles}</style> - <Tabs activeTab={tab} onShowTab={setTab} tabs={tabs} /> + <Tabs activeTab={!showDebugTab && tab === "ConfigFile" ? "Games" : tab} onShowTab={setTab} tabs={tabs} /> </div> ); } |
