import { useState, useEffect } from "react"; import { PanelSection, PanelSectionRow, ButtonItem, Router, } from "@decky/ui"; import { definePlugin, callable } from "@decky/api"; import { FaShip } from "react-icons/fa"; const runInstallFGMod = callable< [], { status: string; message?: string; output?: string } >("run_install_fgmod"); const runUninstallFGMod = callable< [], { status: string; message?: string; output?: string } >("run_uninstall_fgmod"); const checkFGModPath = callable< [], { exists: boolean } >("check_fgmod_path"); function FGModInstallerSection() { const [installing, setInstalling] = useState(false); const [uninstalling, setUninstalling] = useState(false); const [installResult, setInstallResult] = useState<{ status: string; output?: string; message?: string; } | null>(null); const [uninstallResult, setUninstallResult] = useState<{ status: string; output?: string; message?: string; } | null>(null); const [pathExists, setPathExists] = useState(null); useEffect(() => { const checkPath = async () => { const result = await checkFGModPath(); setPathExists(result.exists); }; checkPath(); // Initial check const intervalId = setInterval(checkPath, 5000); // Check every 5 seconds return () => clearInterval(intervalId); // Cleanup interval on component unmount }, []); useEffect(() => { if (installResult) { const timer = setTimeout(() => { setInstallResult(null); }, 5000); return () => clearTimeout(timer); } return () => {}; // Ensure a cleanup function is always returned }, [installResult]); useEffect(() => { if (uninstallResult) { const timer = setTimeout(() => { setUninstallResult(null); }, 5000); return () => clearTimeout(timer); } return () => {}; // Ensure a cleanup function is always returned }, [uninstallResult]); const handleInstallClick = async () => { setInstalling(true); const result = await runInstallFGMod(); setInstalling(false); setInstallResult(result); }; const handleUninstallClick = async () => { setUninstalling(true); const result = await runUninstallFGMod(); setUninstalling(false); setUninstallResult(result); }; return ( {installing ? "Installing..." : "Install FG Mod"} {uninstalling ? "Uninstalling..." : "Uninstall FG Mod"} {installResult && (
Status:{" "} {installResult.status === "success" ? "Success" : "Error"}
{installResult.output && ( <> Output:
{installResult.output}
)} {installResult.message && ( <> Error: {installResult.message} )}
)} {uninstallResult && (
Status:{" "} {uninstallResult.status === "success" ? "Success" : "Error"}
{uninstallResult.output && ( <> Output:
{uninstallResult.output}
)} {uninstallResult.message && ( <> Error: {uninstallResult.message} )}
)} {pathExists !== null && (
{pathExists ? "Patch Is Installed" : "Patch Not Installed"}
)}
Once the patch is installed, you can apply the mod by adding the following to the game's launch options:
/home/deck/fgmod/fgmod %COMMAND%
); } function MainRunningApp() { const mainRunningApp = Router.MainRunningApp; return (
{mainRunningApp ? ( Main Running App: {mainRunningApp.display_name} ) : ( No app is currently running. )}
); } export default definePlugin(() => ({ name: "Framegen Plugin", titleView:
Framegen Plugin
, content: ( <> ), icon: , onDismount() { console.log("Framegen Plugin unmounted"); }, })); function MainContent() { return ( <> ); }