diff options
| author | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2026-05-19 14:26:39 -0400 |
|---|---|---|
| committer | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2026-05-19 14:26:39 -0400 |
| commit | 19e5aefa2f41ebd4389bf27136adacf3e75d3502 (patch) | |
| tree | c7f2228aa45fd4325a68de6fe6f32864f383791c /src/components/OptiScalerControls.tsx | |
| parent | 9e12c11b6189972ea04de454dad5c8554efe657a (diff) | |
| download | Decky-Framegen-feat/asset-manifest-fsr4-variants.tar.gz Decky-Framegen-feat/asset-manifest-fsr4-variants.zip | |
feat: add fsr4 runtime manifestsfeat/asset-manifest-fsr4-variants
Diffstat (limited to 'src/components/OptiScalerControls.tsx')
| -rw-r--r-- | src/components/OptiScalerControls.tsx | 106 |
1 files changed, 97 insertions, 9 deletions
diff --git a/src/components/OptiScalerControls.tsx b/src/components/OptiScalerControls.tsx index f88e8f9..2167fcd 100644 --- a/src/components/OptiScalerControls.tsx +++ b/src/components/OptiScalerControls.tsx @@ -1,9 +1,9 @@ import { useState, useEffect } from "react"; -import { DropdownItem, PanelSection, PanelSectionRow } from "@decky/ui"; -import { runInstallFGMod, runUninstallFGMod } from "../api"; +import { DropdownItem, Field, PanelSection, PanelSectionRow, ToggleField } from "@decky/ui"; +import { runInstallFGMod, runUninstallFGMod, setDefaultFsr4Variant } from "../api"; import { OperationResult } from "./ResultDisplay"; import { createAutoCleanupTimer } from "../utils"; -import { TIMEOUTS, PROXY_DLL_OPTIONS, DEFAULT_PROXY_DLL } from "../utils/constants"; +import { TIMEOUTS, PROXY_DLL_OPTIONS, DEFAULT_PROXY_DLL, FSR4_VARIANT_OPTIONS, DEFAULT_FSR4_VARIANT } from "../utils/constants"; import { InstallationStatus } from "./InstallationStatus"; import { OptiScalerHeader } from "./OptiScalerHeader"; import { ClipboardCommands } from "./ClipboardCommands"; @@ -13,18 +13,31 @@ import { UninstallButton } from "./UninstallButton"; import { ManualPatchControls } from "./CustomPathOverride"; import { SteamGamePatcher } from "./SteamGamePatcher"; +interface FgmodInfo { + exists: boolean; + version?: string | null; + selected_fsr4_variant?: string | null; + selected_fsr4_variant_label?: string | null; + install_manifest_present?: boolean; +} + interface OptiScalerControlsProps { pathExists: boolean | null; setPathExists: (exists: boolean | null) => void; + fgmodInfo?: FgmodInfo | null; } -export function OptiScalerControls({ pathExists, setPathExists }: OptiScalerControlsProps) { +export function OptiScalerControls({ pathExists, setPathExists, fgmodInfo }: OptiScalerControlsProps) { const [installing, setInstalling] = useState(false); const [uninstalling, setUninstalling] = useState(false); const [installResult, setInstallResult] = useState<OperationResult | null>(null); const [uninstallResult, setUninstallResult] = useState<OperationResult | null>(null); - const [manualModeEnabled, setManualModeEnabled] = useState(false); + const [advancedModeEnabled, setAdvancedModeEnabled] = useState(false); + const [manualClipboardModeEnabled, setManualClipboardModeEnabled] = useState(false); const [dllName, setDllName] = useState<string>(DEFAULT_PROXY_DLL); + const [fsr4Variant, setFsr4Variant] = useState<string>(DEFAULT_FSR4_VARIANT); + const [fsr4VariantTouched, setFsr4VariantTouched] = useState(false); + const [switchingVariant, setSwitchingVariant] = useState(false); useEffect(() => { if (installResult) { return createAutoCleanupTimer(() => setInstallResult(null), TIMEOUTS.resultDisplay); @@ -39,10 +52,17 @@ export function OptiScalerControls({ pathExists, setPathExists }: OptiScalerCont return () => {}; // Ensure a cleanup function is always returned }, [uninstallResult]); + useEffect(() => { + const installedVariant = fgmodInfo?.selected_fsr4_variant; + if (!fsr4VariantTouched && installedVariant && FSR4_VARIANT_OPTIONS.some((option) => option.value === installedVariant)) { + setFsr4Variant(installedVariant); + } + }, [fgmodInfo?.selected_fsr4_variant, fsr4VariantTouched]); + const handleInstallClick = async () => { try { setInstalling(true); - const result = await runInstallFGMod(); + const result = await runInstallFGMod(fsr4Variant); setInstallResult(result); if (result.status === "success") { setPathExists(true); @@ -69,6 +89,31 @@ export function OptiScalerControls({ pathExists, setPathExists }: OptiScalerCont } }; + const handleFsr4VariantChange = async (nextVariant: string) => { + const previousVariant = fsr4Variant; + setFsr4Variant(nextVariant); + setFsr4VariantTouched(true); + + if (pathExists !== true) return; + + try { + setSwitchingVariant(true); + const result = await setDefaultFsr4Variant(nextVariant); + if (result.status !== "success") { + throw new Error(result.message || result.output || "Failed to switch default FSR4 runtime."); + } + setFsr4Variant(result.selected_default_variant || nextVariant); + setFsr4VariantTouched(false); + } catch (error) { + console.error(error); + setFsr4Variant(previousVariant); + } finally { + setSwitchingVariant(false); + } + }; + + const installedVariantLabel = fgmodInfo?.selected_fsr4_variant_label || FSR4_VARIANT_OPTIONS.find((option) => option.value === fsr4Variant)?.label; + return ( <PanelSection> <InstallationStatus @@ -79,6 +124,28 @@ export function OptiScalerControls({ pathExists, setPathExists }: OptiScalerCont <OptiScalerHeader pathExists={pathExists} /> + <PanelSectionRow> + <DropdownItem + label="Default FSR4 runtime" + description={FSR4_VARIANT_OPTIONS.find((option) => option.value === fsr4Variant)?.hint} + menuLabel="Default FSR4 runtime" + selectedOption={fsr4Variant} + rgOptions={FSR4_VARIANT_OPTIONS.map((option) => ({ data: option.value, label: option.label }))} + disabled={installing || uninstalling || switchingVariant} + onChange={(option) => { + void handleFsr4VariantChange(String(option.data)); + }} + /> + </PanelSectionRow> + + {pathExists === true && fgmodInfo?.version && installedVariantLabel && ( + <PanelSectionRow> + <Field label="Installed bundle" description={`OptiScaler ${fgmodInfo.version}`}> + {installedVariantLabel} + </Field> + </PanelSectionRow> + )} + {pathExists === true && ( <PanelSectionRow> <DropdownItem @@ -93,18 +160,39 @@ export function OptiScalerControls({ pathExists, setPathExists }: OptiScalerCont )} {pathExists === true && ( - <SteamGamePatcher dllName={dllName} /> + <SteamGamePatcher dllName={dllName} fsr4Variant={fsr4Variant} /> )} <ClipboardCommands pathExists={pathExists} dllName={dllName} /> + {pathExists === true && ( + <PanelSectionRow> + <ToggleField + label="Manual Mode" + description="Show wrapper command clipboard buttons for patching and unpatching through ~/fgmod scripts." + checked={manualClipboardModeEnabled} + onChange={setManualClipboardModeEnabled} + /> + </PanelSectionRow> + )} + + {pathExists === true && manualClipboardModeEnabled ? ( + <ClipboardCommands + pathExists={pathExists} + dllName={dllName} + manualModeEnabled + showLaunchOptions={false} + /> + ) : null} + <ManualPatchControls isAvailable={pathExists === true} - onManualModeChange={setManualModeEnabled} + onManualModeChange={setAdvancedModeEnabled} dllName={dllName} + fsr4Variant={fsr4Variant} /> - {!manualModeEnabled && ( + {!advancedModeEnabled && ( <InstructionCard pathExists={pathExists} /> )} <OptiScalerWiki pathExists={pathExists} /> |
