diff options
| author | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2025-07-13 00:04:54 -0400 |
|---|---|---|
| committer | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2025-07-13 00:04:54 -0400 |
| commit | 77494457e2a4f5c80c3a2f7acb054b12d918d8ad (patch) | |
| tree | fad4c4dd2ce69a850b56078444427866dedce9fa /src/index.tsx | |
| parent | 6cfcaa6c169cb8c898775eee276ff2497ab8f45c (diff) | |
| download | decky-lsfg-vk-77494457e2a4f5c80c3a2f7acb054b12d918d8ad.tar.gz decky-lsfg-vk-77494457e2a4f5c80c3a2f7acb054b12d918d8ad.zip | |
restructure for maintainability
Diffstat (limited to 'src/index.tsx')
| -rwxr-xr-x | src/index.tsx | 450 |
1 files changed, 6 insertions, 444 deletions
diff --git a/src/index.tsx b/src/index.tsx index 2b895b3..e8ab56f 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,448 +1,10 @@ -import { - ButtonItem, - PanelSection, - PanelSectionRow, - staticClasses, - ToggleField, - SliderField -} from "@decky/ui"; -import { - callable, - definePlugin, - toaster, -} from "@decky/api" -import { useState, useEffect } from "react"; -import { FaDownload, FaTrash } from "react-icons/fa"; +import { staticClasses } from "@decky/ui"; +import { definePlugin } from "@decky/api"; import { GiPlasticDuck } from "react-icons/gi"; - -// Function to install lsfg-vk -const installLsfgVk = callable<[], { success: boolean; error?: string; message?: string }>("install_lsfg_vk"); - -// Function to uninstall lsfg-vk -const uninstallLsfgVk = callable<[], { success: boolean; error?: string; message?: string; removed_files?: string[] }>("uninstall_lsfg_vk"); - -// Function to check if lsfg-vk is installed -const checkLsfgVkInstalled = callable<[], { installed: boolean; lib_exists: boolean; json_exists: boolean; script_exists: boolean; lib_path: string; json_path: string; script_path: string; error?: string }>("check_lsfg_vk_installed"); - -// Function to check if Lossless Scaling DLL is available -const checkLosslessScalingDll = callable<[], { detected: boolean; path?: string; source?: string; message?: string; error?: string }>("check_lossless_scaling_dll"); - -// Function to get lsfg configuration -const getLsfgConfig = callable<[], { success: boolean; config?: { enable_lsfg: boolean; multiplier: number; flow_scale: number; hdr: boolean; perf_mode: boolean; immediate_mode: boolean }; error?: string }>("get_lsfg_config"); - -// Function to update lsfg configuration -const updateLsfgConfig = callable<[boolean, number, number, boolean, boolean, boolean], { success: boolean; message?: string; error?: string }>("update_lsfg_config"); - -function Content() { - const [isInstalled, setIsInstalled] = useState<boolean>(false); - const [isInstalling, setIsInstalling] = useState<boolean>(false); - const [isUninstalling, setIsUninstalling] = useState<boolean>(false); - const [installationStatus, setInstallationStatus] = useState<string>(""); - const [dllDetected, setDllDetected] = useState<boolean>(false); - const [dllDetectionStatus, setDllDetectionStatus] = useState<string>(""); - - // LSFG configuration state - const [enableLsfg, setEnableLsfg] = useState<boolean>(true); - const [multiplier, setMultiplier] = useState<number>(2); - const [flowScale, setFlowScale] = useState<number>(1.0); - const [hdr, setHdr] = useState<boolean>(false); - const [perfMode, setPerfMode] = useState<boolean>(false); - const [immediateMode, setImmediateMode] = useState<boolean>(false); - - // Check installation status on component mount - useEffect(() => { - const checkInstallation = async () => { - try { - const status = await checkLsfgVkInstalled(); - setIsInstalled(status.installed); - if (status.installed) { - setInstallationStatus("lsfg-vk is installed"); - } else { - setInstallationStatus("lsfg-vk is not installed"); - } - } catch (error) { - setInstallationStatus("Error checking installation status"); - } - }; - - const checkDllDetection = async () => { - try { - const result = await checkLosslessScalingDll(); - setDllDetected(result.detected); - if (result.detected) { - setDllDetectionStatus(`Lossless Scaling App detected (${result.source})`); - } else { - setDllDetectionStatus(result.message || "Lossless Scaling App not detected"); - } - } catch (error) { - setDllDetectionStatus("Error checking Lossless Scaling App"); - } - }; - - const loadLsfgConfig = async () => { - try { - const result = await getLsfgConfig(); - if (result.success && result.config) { - setEnableLsfg(result.config.enable_lsfg); - setMultiplier(result.config.multiplier); - setFlowScale(result.config.flow_scale); - setHdr(result.config.hdr); - setPerfMode(result.config.perf_mode); - setImmediateMode(result.config.immediate_mode); - console.log("Loaded lsfg config:", result.config); - } else { - // If script doesn't exist or can't be read, keep default values - console.log("lsfg config not available, using defaults:", result.error); - } - } catch (error) { - console.error("Error loading lsfg config:", error); - } - }; - - checkInstallation(); - checkDllDetection(); - - // Always try to load config, regardless of installation status - // This handles cases where the script exists but plugin shows as not installed - loadLsfgConfig(); - }, []); - - // Add a second useEffect to reload config when isInstalled changes - // This ensures UI reflects script state when plugin detects installation - useEffect(() => { - if (isInstalled) { - const reloadConfig = async () => { - try { - const result = await getLsfgConfig(); - if (result.success && result.config) { - setEnableLsfg(result.config.enable_lsfg); - setMultiplier(result.config.multiplier); - setFlowScale(result.config.flow_scale); - setHdr(result.config.hdr); - setPerfMode(result.config.perf_mode); - setImmediateMode(result.config.immediate_mode); - console.log("Reloaded lsfg config after installation detected:", result.config); - } - } catch (error) { - console.error("Error reloading lsfg config:", error); - } - }; - reloadConfig(); - } - }, [isInstalled]); const handleInstall = async () => { - setIsInstalling(true); - setInstallationStatus("Installing lsfg-vk..."); - - try { - const result = await installLsfgVk(); - if (result.success) { - setIsInstalled(true); - setInstallationStatus("lsfg-vk installed successfully!"); - toaster.toast({ - title: "Installation Complete", - body: "lsfg-vk has been installed successfully" - }); - - // Reload lsfg config after installation - try { - const configResult = await getLsfgConfig(); - if (configResult.success && configResult.config) { - setEnableLsfg(configResult.config.enable_lsfg); - setMultiplier(configResult.config.multiplier); - setFlowScale(configResult.config.flow_scale); - setHdr(configResult.config.hdr); - setPerfMode(configResult.config.perf_mode); - setImmediateMode(configResult.config.immediate_mode); - } - } catch (error) { - console.error("Error reloading config after install:", error); - } - } else { - setInstallationStatus(`Installation failed: ${result.error}`); - toaster.toast({ - title: "Installation Failed", - body: result.error || "Unknown error occurred" - }); - } - } catch (error) { - setInstallationStatus(`Installation failed: ${error}`); - toaster.toast({ - title: "Installation Failed", - body: `Error: ${error}` - }); - } finally { - setIsInstalling(false); - } - }; - - const handleUninstall = async () => { - setIsUninstalling(true); - setInstallationStatus("Uninstalling lsfg-vk..."); - - try { - const result = await uninstallLsfgVk(); - if (result.success) { - setIsInstalled(false); - setInstallationStatus("lsfg-vk uninstalled successfully!"); - toaster.toast({ - title: "Uninstallation Complete", - body: result.message || "lsfg-vk has been uninstalled successfully" - }); - } else { - setInstallationStatus(`Uninstallation failed: ${result.error}`); - toaster.toast({ - title: "Uninstallation Failed", - body: result.error || "Unknown error occurred" - }); - } - } catch (error) { - setInstallationStatus(`Uninstallation failed: ${error}`); - toaster.toast({ - title: "Uninstallation Failed", - body: `Error: ${error}` - }); - } finally { - setIsUninstalling(false); - } - }; - - const updateConfig = async (newEnableLsfg: boolean, newMultiplier: number, newFlowScale: number, newHdr: boolean, newPerfMode: boolean, newImmediateMode: boolean) => { - try { - const result = await updateLsfgConfig(newEnableLsfg, newMultiplier, newFlowScale, newHdr, newPerfMode, newImmediateMode); - if (!result.success) { - toaster.toast({ - title: "Update Failed", - body: result.error || "Failed to update configuration" - }); - } - // Only show error notifications, not success notifications to avoid spam - } catch (error) { - toaster.toast({ - title: "Update Failed", - body: `Error: ${error}` - }); - } - }; - - const handleEnableLsfgChange = async (value: boolean) => { - setEnableLsfg(value); - await updateConfig(value, multiplier, flowScale, hdr, perfMode, immediateMode); - }; - - const handleMultiplierChange = async (value: number) => { - setMultiplier(value); - await updateConfig(enableLsfg, value, flowScale, hdr, perfMode, immediateMode); - }; - - const handleFlowScaleChange = async (value: number) => { - setFlowScale(value); - await updateConfig(enableLsfg, multiplier, value, hdr, perfMode, immediateMode); - }; - - const handleHdrChange = async (value: boolean) => { - setHdr(value); - await updateConfig(enableLsfg, multiplier, flowScale, value, perfMode, immediateMode); - }; - - const handlePerfModeChange = async (value: boolean) => { - setPerfMode(value); - await updateConfig(enableLsfg, multiplier, flowScale, hdr, value, immediateMode); - }; - - const handleImmediateModeChange = async (value: boolean) => { - setImmediateMode(value); - await updateConfig(enableLsfg, multiplier, flowScale, hdr, perfMode, value); - }; - - return ( - <PanelSection> - <PanelSectionRow> - <div style={{ marginBottom: "8px", fontSize: "14px" }}> - <div style={{ - color: dllDetected ? "#4CAF50" : "#F44336", - fontWeight: "bold", - marginBottom: "4px" - }}> - {dllDetectionStatus} - </div> - <div style={{ - color: isInstalled ? "#4CAF50" : "#FF9800" - }}> - Status: {installationStatus} - </div> - </div> - </PanelSectionRow> - - <PanelSectionRow> - <ButtonItem - layout="below" - onClick={isInstalled ? handleUninstall : handleInstall} - disabled={isInstalling || isUninstalling} - > - {isInstalling ? ( - <div style={{ display: "flex", alignItems: "center", gap: "8px" }}> - <div>Installing...</div> - </div> - ) : isUninstalling ? ( - <div style={{ display: "flex", alignItems: "center", gap: "8px" }}> - <div>Uninstalling...</div> - </div> - ) : isInstalled ? ( - <div style={{ display: "flex", alignItems: "center", gap: "8px" }}> - <FaTrash /> - <div>Uninstall lsfg-vk</div> - </div> - ) : ( - <div style={{ display: "flex", alignItems: "center", gap: "8px" }}> - <FaDownload /> - <div>Install lsfg-vk</div> - </div> - )} - </ButtonItem> - </PanelSectionRow> - - {/* Configuration Section - only show if installed */} - {isInstalled && ( - <> - <PanelSectionRow> - <div style={{ - fontSize: "14px", - fontWeight: "bold", - marginTop: "16px", - marginBottom: "8px", - borderBottom: "1px solid rgba(255, 255, 255, 0.2)", - paddingBottom: "4px" - }}> - LSFG Configuration - </div> - </PanelSectionRow> - - <PanelSectionRow> - <ToggleField - label="Enable LSFG" - description="Enables the frame generation layer" - checked={enableLsfg} - onChange={handleEnableLsfgChange} - /> - </PanelSectionRow> - - <PanelSectionRow> - <SliderField - label="FPS Multiplier" - description="Traditional FPS multiplier value (2-4)" - value={multiplier} - min={2} - max={4} - step={1} - notchCount={3} - notchLabels={[ - { notchIndex: 0, label: "2" }, - { notchIndex: 1, label: "3" }, - { notchIndex: 2, label: "4" } - ]} - onChange={handleMultiplierChange} - /> - </PanelSectionRow> - - <PanelSectionRow> - <SliderField - label={`Flow Scale ${Math.round(flowScale * 100)}%`} - description="Lowers the flow scale for performance (0.25-1.0)" - value={flowScale} - min={0.25} - max={1.0} - step={0.01} - onChange={handleFlowScaleChange} - /> - </PanelSectionRow> - - <PanelSectionRow> - <ToggleField - label="HDR Mode" - description="Enable HDR mode (only if using HDR)" - checked={hdr} - onChange={handleHdrChange} - /> - </PanelSectionRow> - - <PanelSectionRow> - <ToggleField - label="Performance Mode" - description="Enable performance mode (can quintuple performance)" - checked={perfMode} - onChange={handlePerfModeChange} - /> - </PanelSectionRow> - - <PanelSectionRow> - <ToggleField - label="Immediate Mode" - description="Disable vsync for reduced input lag" - checked={immediateMode} - onChange={handleImmediateModeChange} - /> - </PanelSectionRow> - </> - )} - - <PanelSectionRow> - <div style={{ - fontSize: "13px", - marginTop: "12px", - padding: "8px", - backgroundColor: "rgba(255, 255, 255, 0.05)", - borderRadius: "4px" - }}> - <div style={{ fontWeight: "bold", marginBottom: "6px" }}> - Usage Instructions: - </div> - <div style={{ marginBottom: "4px" }}> - Option 1: Use the lsfg script (recommended): - </div> - <div style={{ - fontFamily: "monospace", - backgroundColor: "rgba(0, 0, 0, 0.3)", - padding: "4px", - borderRadius: "2px", - fontSize: "12px", - marginBottom: "6px" - }}> - ~/lsfg %COMMAND% - </div> - <div style={{ marginBottom: "4px" }}> - Option 2: Manual environment variables: - </div> - <div style={{ - fontFamily: "monospace", - backgroundColor: "rgba(0, 0, 0, 0.3)", - padding: "4px", - borderRadius: "2px", - fontSize: "12px", - marginBottom: "6px" - }}> - ENABLE_LSFG=1 LSFG_MULTIPLIER={multiplier} %COMMAND% - </div> - <div style={{ fontSize: "11px", opacity: 0.8 }}> - The lsfg script uses your current configuration settings. - <br /> - • ENABLE_LSFG=1 - Enables frame generation - <br /> - • LSFG_MULTIPLIER=2-4 - FPS multiplier (start with 2) - <br /> - • LSFG_FLOW_SCALE=0.25-1.0 - Flow scale (for performance) - <br /> - • LSFG_HDR=1 - HDR mode (only if using HDR) - <br /> - • MESA_VK_WSI_PRESENT_MODE=immediate - Disable vsync - </div> - </div> - </PanelSectionRow> - </PanelSection> - ); -}; +import { Content } from "./components"; export default definePlugin(() => { - console.log("Lossless Scaling plugin initializing") + console.log("Lossless Scaling plugin initializing"); return { // The name shown in various decky menus @@ -455,7 +17,7 @@ export default definePlugin(() => { icon: <GiPlasticDuck />, // The function triggered when your plugin unloads onDismount() { - console.log("Lossless Scaling unloading") - }, + console.log("Lossless Scaling unloading"); + } }; }); |
