From ca0d5f0ec1f4ba21f4bf51f0f773d2b6bad45c93 Mon Sep 17 00:00:00 2001
From: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
Date: Thu, 17 Jul 2025 08:49:12 -0400
Subject: reorganize for readability and DRY (#115)

* reorganize for readability and DRY

* rm backup files

* ver bump
---
 src/index.tsx | 303 +---------------------------------------------------------
 1 file changed, 3 insertions(+), 300 deletions(-)
 mode change 100755 => 100644 src/index.tsx

(limited to 'src/index.tsx')

diff --git a/src/index.tsx b/src/index.tsx
old mode 100755
new mode 100644
index 64dabdb..12150d2
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,304 +1,7 @@
-import { useState, useEffect } from "react";
-import {
-  PanelSection,
-  PanelSectionRow,
-  ButtonItem,
-  DropdownItem,
-  ConfirmModal,
-  showModal
-} from "@decky/ui";
-import { definePlugin, callable } from "@decky/api";
+import { definePlugin } from "@decky/api";
 import { RiAiGenerate } from "react-icons/ri";
-
-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");
-
-const listInstalledGames = callable<
-  [],
-  { status: string; games: { appid: string; name: string }[] }
->("list_installed_games");
-
-const logError = callable<[string], void>("log_error");
-
-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<boolean | null>(null);
-
-  useEffect(() => {
-    const checkPath = async () => {
-      try {
-        const result = await checkFGModPath();
-        setPathExists(result.exists);
-      } catch (e) {
-        logError('useEffect -> checkPath' + String(e));
-        console.error(e);
-      }
-    };
-    checkPath(); // Initial check
-    const intervalId = setInterval(checkPath, 3000); // Check every 3 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 () => {};
-  }, [uninstallResult]);
-
-  const handleInstallClick = async () => {
-    try {
-      setInstalling(true);
-      const result = await runInstallFGMod();
-      setInstalling(false);
-      setInstallResult(result);
-    } catch (e) {
-      logError('handleInstallClick: ' + String(e));
-      console.error(e)
-    }
-  };
-
-  const handleUninstallClick = async () => {
-    try {
-      setUninstalling(true);
-      const result = await runUninstallFGMod();
-      setUninstalling(false);
-      setUninstallResult(result);
-    } catch (e) {
-      logError('handleUninstallClick' + String(e));
-      console.error(e)
-    }
-  };
-
-  return (
-    <PanelSection>
-      {pathExists !== null ? (
-        <PanelSectionRow>
-          <div style={{ color: pathExists ? "green" : "red" }}>
-            {pathExists ? "OptiScaler Mod Is Installed" : "OptiScaler Mod Not Installed"}
-          </div>
-        </PanelSectionRow>
-      ) : null}
-      {pathExists === false ? (
-        <PanelSectionRow>
-          <ButtonItem layout="below" onClick={handleInstallClick} disabled={installing}>
-            {installing ? "Installing..." : "Install OptiScaler FG Mod"}
-          </ButtonItem>
-        </PanelSectionRow>
-      ) : null}
-      {pathExists === true ? (
-        <PanelSectionRow>
-          <ButtonItem layout="below" onClick={handleUninstallClick} disabled={uninstalling}>
-            {uninstalling ? "Uninstalling..." : "Uninstall OptiScaler FG Mod"}
-          </ButtonItem>
-        </PanelSectionRow>
-      ) : null}
-      {installResult ? (
-        <PanelSectionRow>
-          <div>
-            <strong>Status:</strong>{" "}
-            {installResult.status === "success" ? "Success" : "Error"}
-            <br />
-            {installResult.output ? (
-              <>
-                <strong>Output:</strong>
-                <pre style={{ whiteSpace: "pre-wrap" }}>{installResult.output}</pre>
-              </>
-            ) : null}
-            {installResult.message ? (
-              <>
-                <strong>Error:</strong> {installResult.message}
-              </>
-            ) : null}
-          </div>
-        </PanelSectionRow>
-      ) : null}
-      {uninstallResult ? (
-        <PanelSectionRow>
-          <div>
-            <strong>Status:</strong>{" "}
-            {uninstallResult.status === "success" ? "Success" : "Error"}
-            <br />
-            {uninstallResult.output ? (
-              <>
-                <strong>Output:</strong>
-                <pre style={{ whiteSpace: "pre-wrap" }}>{uninstallResult.output}</pre>
-              </>
-            ) : null}
-            {uninstallResult.message ? (
-              <>
-                <strong>Error:</strong> {uninstallResult.message}
-              </>
-            ) : null}
-          </div>
-        </PanelSectionRow>
-      ) : null}
-      <PanelSectionRow>
-        <div>
-          Install the OptiScaler-based mod above, then select and patch a game below to enable DLSS replacement with FSR Frame Generation. Map a button to "insert" key to bring up the OptiScaler menu in-game.
-        </div>
-      </PanelSectionRow>
-    </PanelSection>
-  );
-}
-
-function InstalledGamesSection() {
-  const [games, setGames] = useState<{ appid: number; name: string }[]>([]);
-  const [selectedGame, setSelectedGame] = useState<{ appid: number; name: string } | null>(null);
-  const [result, setResult] = useState<string>('');
-
-  useEffect(() => {
-    const fetchGames = async () => {
-      try {
-        const response = await listInstalledGames();
-        if (response.status === "success") {
-          const sortedGames = [...response.games]
-            .map(game => ({
-              ...game,
-              appid: parseInt(game.appid, 10),
-            }))
-            .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
-          setGames(sortedGames);
-        } else {
-          logError('fetchGames: ' + JSON.stringify(response));
-          console.error('fetchGames: ' + JSON.stringify(response));
-        }
-      } catch (error) {
-        logError("Error fetching games:" + String(error));
-        console.error("Error fetching games:", String(error));
-      }
-    };
-    fetchGames();
-  }, []);
-
-  const handlePatchClick = async () => {
-    if (!selectedGame) return;
-
-    // Show confirmation modal
-    showModal(
-      <ConfirmModal 
-        strTitle={`Patch ${selectedGame.name}?`}
-        strDescription={
-          "WARNING: Decky Framegen does not unpatch games when uninstalled. Be sure to unpatch the game or verify the integrity of your game files if you choose to uninstall the plugin or the game has issues."
-        }
-        strOKButtonText="Yeah man, I wanna do it"
-        strCancelButtonText="Cancel"
-        onOK={async () => {
-          try {
-            await SteamClient.Apps.SetAppLaunchOptions(selectedGame.appid, '~/fgmod/fgmod %COMMAND%');
-            setResult(`Launch options set for ${selectedGame.name}. You can now select DLSS in the game's menu, and access OptiScaler with Insert key.`);
-          } catch (error) {
-            logError('handlePatchClick: ' + String(error));
-            setResult(error instanceof Error ? `Error setting launch options: ${error.message}` : 'Error setting launch options');
-          }
-        }}
-      />
-    );
-  };
-
-  const handleUnpatchClick = async () => {
-    if (!selectedGame) return;
-
-    try {
-      await SteamClient.Apps.SetAppLaunchOptions(selectedGame.appid, '~/fgmod/fgmod-uninstaller.sh %COMMAND%');
-      setResult(`OptiScaler will uninstall on next launch of ${selectedGame.name}.`);
-    } catch (error) {
-      logError('handleUnpatchClick: ' + String(error));
-      setResult(error instanceof Error ? `Error clearing launch options: ${error.message}` : 'Error clearing launch options');
-    }
-  };
-
-  return (
-    <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>
-
-      {result ? (
-        <PanelSectionRow>
-          <div style={{ 
-            padding: '12px',
-            marginTop: '16px',
-            backgroundColor: 'var(--decky-selected-ui-bg)',
-            borderRadius: '4px'
-          }}>
-            {result}
-          </div>
-        </PanelSectionRow>
-      ) : null}
-      
-      {selectedGame ? (
-        <>
-          <PanelSectionRow>
-            <ButtonItem
-              layout="below"
-              onClick={handlePatchClick}
-            >
-              Patch
-            </ButtonItem>
-          </PanelSectionRow>
-          <PanelSectionRow>
-            <ButtonItem
-              layout="below"
-              onClick={handleUnpatchClick}
-            >
-              Unpatch
-            </ButtonItem>
-          </PanelSectionRow>
-        </>
-      ) : null}
-    </PanelSection>
-  );
-}
+import { FGModInstallerSection } from "./components/FGModInstallerSection";
+import { InstalledGamesSection } from "./components/InstalledGamesSection";
 
 export default definePlugin(() => ({
   name: "Framegen Plugin",
-- 
cgit v1.2.3

