summaryrefslogtreecommitdiff
path: root/src/components/ConfigurationSection.tsx
diff options
context:
space:
mode:
authorxXJSONDeruloXx <danielhimebauch@gmail.com>2026-09-06 15:08:45 -0400
committerxXJSONDeruloXx <danielhimebauch@gmail.com>2026-09-06 15:09:20 -0400
commitad2b182777bfd0a5ceef6e654df75ff13eb8b503 (patch)
tree7b98bfe322f18e59c74d7b3a0745608390a0a0fd /src/components/ConfigurationSection.tsx
parenta9fd67d05d6819a839a60b581c1dc6eb2792a9be (diff)
downloaddecky-lsfg-vk-ad2b182777bfd0a5ceef6e654df75ff13eb8b503.tar.gz
decky-lsfg-vk-ad2b182777bfd0a5ceef6e654df75ff13eb8b503.zip
refactor: offload configuration to lsfg-vk
Diffstat (limited to 'src/components/ConfigurationSection.tsx')
-rw-r--r--src/components/ConfigurationSection.tsx307
1 files changed, 21 insertions, 286 deletions
diff --git a/src/components/ConfigurationSection.tsx b/src/components/ConfigurationSection.tsx
index e83bd58..c2bba7e 100644
--- a/src/components/ConfigurationSection.tsx
+++ b/src/components/ConfigurationSection.tsx
@@ -1,293 +1,28 @@
-import { PanelSectionRow, ToggleField, SliderField, ButtonItem } from "@decky/ui";
-import { useState, useEffect } from "react";
-import { RiArrowDownSFill, RiArrowUpSFill } from "react-icons/ri";
+import { PanelSectionRow, ToggleField, SliderField } from "@decky/ui";
import { ConfigurationData } from "../config/configSchema";
-import {
- FLOW_SCALE, NO_FP16, PERFORMANCE_MODE,
- EXPERIMENTAL_PRESENT_MODE, DXVK_FRAME_RATE, DISABLE_STEAMDECK_MODE,
- MANGOHUD_WORKAROUND, DISABLE_VKBASALT, FORCE_ENABLE_VKBASALT, ENABLE_WSI, ENABLE_ZINK
-} from "../config/generatedConfigSchema";
-import t from '../i18n/i18n';
+import { FLOW_SCALE, PERFORMANCE_MODE, OVERRIDE_PRESENT_MODE, PRESERVE_SWAPCHAIN_IMAGE_COUNT, NO_FP16 } from "../config/configSchema";
interface ConfigurationSectionProps {
config: ConfigurationData;
- onConfigChange: (fieldName: keyof ConfigurationData, value: boolean | number | string) => Promise<void>;
+ onConfigChange: (fieldName: keyof ConfigurationData, value: boolean | number | string | string[]) => Promise<void>;
}
-const WORKAROUNDS_COLLAPSED_KEY = "lsfg-workarounds-collapsed";
-const CONFIG_COLLAPSED_KEY = "lsfg-config-collapsed";
-
-export function ConfigurationSection({
- config,
- onConfigChange
-}: ConfigurationSectionProps) {
- // Initialize with localStorage value, fallback to true if not found
- const [configCollapsed, setConfigCollapsed] = useState(() => {
- try {
- const saved = localStorage.getItem(CONFIG_COLLAPSED_KEY);
- return saved !== null ? JSON.parse(saved) : false;
- } catch {
- return false;
- }
- });
-
- const [workaroundsCollapsed, setWorkaroundsCollapsed] = useState(() => {
- try {
- const saved = localStorage.getItem(WORKAROUNDS_COLLAPSED_KEY);
- return saved !== null ? JSON.parse(saved) : true;
- } catch {
- return true;
- }
- });
-
- // Persist workarounds collapse state to localStorage
- useEffect(() => {
- try {
- localStorage.setItem(CONFIG_COLLAPSED_KEY, JSON.stringify(configCollapsed));
- } catch (error) {
- console.warn("Failed to save config collapse state:", error);
- }
- }, [configCollapsed]);
-
- useEffect(() => {
- try {
- localStorage.setItem(WORKAROUNDS_COLLAPSED_KEY, JSON.stringify(workaroundsCollapsed));
- } catch (error) {
- console.warn("Failed to save workarounds collapse state:", error);
- }
- }, [workaroundsCollapsed]);
-
- return (
- <>
- <style>
- {`
- .LSFG_ConfigCollapseButton_Container > div > div > div > button,
- .LSFG_ConfigCollapseButton_Container > div > div > div > div > button,
- .LSFG_WorkaroundsCollapseButton_Container > div > div > div > button {
- height: 10px !important;
- }
- .LSFG_WorkaroundsCollapseButton_Container > div > div > div > div > button {
- height: 10px !important;
- }
- `}
- </style>
-
- {/* Config Section */}
- <PanelSectionRow>
- <div
- style={{
- fontSize: "14px",
- fontWeight: "bold",
- marginTop: "8px",
- marginBottom: "6px",
- borderBottom: "1px solid rgba(255, 255, 255, 0.2)",
- paddingBottom: "3px",
- color: "white"
- }}
- >
- {t('CONFIG_SECTION_TITLE', 'Config')}
- </div>
- </PanelSectionRow>
-
- <PanelSectionRow>
- <div
- className="LSFG_ConfigCollapseButton_Container"
- style={{ marginTop: "-2px", marginBottom: "4px" }}
- >
- <ButtonItem
- layout="below"
- bottomSeparator={configCollapsed ? "standard" : "none"}
- onClick={() => setConfigCollapsed(!configCollapsed)}
- >
- {configCollapsed ? (
- <RiArrowDownSFill
- style={{ transform: "translate(0, -13px)", fontSize: "1.5em" }}
- />
- ) : (
- <RiArrowUpSFill
- style={{ transform: "translate(0, -12px)", fontSize: "1.5em" }}
- />
- )}
- </ButtonItem>
- </div>
- </PanelSectionRow>
-
- {!configCollapsed && (
- <>
- <PanelSectionRow>
- <SliderField
- label={`${t('CONFIG_FLOW_SCALE', 'Flow Scale')} (${Math.round(config.flow_scale * 100)}%)`}
- description={t('CONFIG_FLOW_SCALE_DESC', 'Lowers internal motion estimation resolution, improving performance slightly')}
- value={config.flow_scale}
- min={0.25}
- max={1.0}
- step={0.01}
- onChange={(value) => onConfigChange(FLOW_SCALE, value)}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
- label="FP16 Acceleration"
- description="Use FP16 shaders when supported"
- checked={!config.no_fp16}
- onChange={(value) => onConfigChange(NO_FP16, !value)}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <SliderField
- label={`${t('CONFIG_BASE_FPS_CAP', 'Base FPS Cap')}${config.dxvk_frame_rate > 0 ? ` (${config.dxvk_frame_rate} FPS)` : ` (${t('CONFIG_BASE_FPS_CAP_OFF', 'Off')})`}`}
- description={t('CONFIG_BASE_FPS_CAP_DESC', 'Base framerate cap for DirectX games, before frame multiplier. (Requires game restart to apply)')}
- value={config.dxvk_frame_rate}
- min={0}
- max={60}
- step={1}
- onChange={(value) => onConfigChange(DXVK_FRAME_RATE, value)}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
- label={`${t('CONFIG_PRESENT_MODE', 'Present Mode Override')} (${(config.experimental_present_mode || "fifo") === "fifo" ? t('CONFIG_PRESENT_MODE_FIFO', 'FIFO - VSync') : 'App Default'})`}
- description={t('CONFIG_PRESENT_MODE_DESC', 'Force FIFO/VSync for v2 frame pacing, or leave the game present mode unchanged')}
- checked={(config.experimental_present_mode || "fifo") === "fifo"}
- onChange={(value) => onConfigChange(EXPERIMENTAL_PRESENT_MODE, value ? "fifo" : "mailbox")}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
- label={t('CONFIG_PERFORMANCE_MODE', 'Performance Mode')}
- description={t('CONFIG_PERFORMANCE_MODE_DESC', 'Uses a lighter model for FG (Recommended for most games)')}
- checked={config.performance_mode}
- onChange={(value) => onConfigChange(PERFORMANCE_MODE, value)}
- />
- </PanelSectionRow>
-
- </>
- )}
-
- {/* Workarounds Section */}
- <PanelSectionRow>
- <div
- style={{
- fontSize: "14px",
- fontWeight: "bold",
- marginTop: "8px",
- marginBottom: "6px",
- borderBottom: "1px solid rgba(255, 255, 255, 0.2)",
- paddingBottom: "3px",
- color: "white"
- }}
- >
- {t('CONFIG_WORKAROUNDS_TITLE', 'Workarounds')}
- </div>
- </PanelSectionRow>
-
- <PanelSectionRow>
- <div
- className="LSFG_WorkaroundsCollapseButton_Container"
- style={{ marginTop: "-2px", marginBottom: "4px" }}
- >
- <ButtonItem
- layout="below"
- bottomSeparator={workaroundsCollapsed ? "standard" : "none"}
- onClick={() => setWorkaroundsCollapsed(!workaroundsCollapsed)}
- >
- {workaroundsCollapsed ? (
- <RiArrowDownSFill
- style={{ transform: "translate(0, -13px)", fontSize: "1.5em" }}
- />
- ) : (
- <RiArrowUpSFill
- style={{ transform: "translate(0, -12px)", fontSize: "1.5em" }}
- />
- )}
- </ButtonItem>
- </div>
- </PanelSectionRow>
-
- {!workaroundsCollapsed && (
- <>
- <PanelSectionRow>
- <ToggleField
- label={t('CONFIG_ENABLE_WSI', 'Enable WSI')}
- description={t('CONFIG_ENABLE_WSI_DESC', 'Re-Enable Gamescope WSI Layer. Requires game restart to apply.')}
- checked={config.enable_wsi}
- onChange={(value) => onConfigChange(ENABLE_WSI, value)}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
- label={t('CONFIG_ENABLE_WOW64', 'Enable WOW64 for 32-bit games')}
- description={t('CONFIG_ENABLE_WOW64_DESC', 'Enables PROTON_USE_WOW64=1 for 32-bit games (Use with ProtonGE to fix crashing)')}
- checked={config.enable_wow64}
- onChange={(value) => onConfigChange('enable_wow64', value)}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
- label={t('CONFIG_DISABLE_STEAMDECK_MODE', 'Disable Steam Deck Mode')}
- description={t('CONFIG_DISABLE_STEAMDECK_MODE_DESC', 'Disables Steam Deck mode (Unlocks hidden settings in some games)')}
- checked={config.disable_steamdeck_mode}
- onChange={(value) => onConfigChange(DISABLE_STEAMDECK_MODE, value)}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
- label={t('CONFIG_MANGOHUD_WORKAROUND', 'MangoHud Workaround')}
- description={t('CONFIG_MANGOHUD_WORKAROUND_DESC', 'Enables a transparent mangohud overlay, sometimes fixes issues with 2X multiplier in game mode')}
- checked={config.mangohud_workaround}
- onChange={(value) => onConfigChange(MANGOHUD_WORKAROUND, value)}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
- label={t('CONFIG_DISABLE_VKBASALT', 'Disable vkBasalt')}
- description={t('CONFIG_DISABLE_VKBASALT_DESC', 'Disables vkBasalt layer which can conflict with LSFG (Reshade, some Decky plugins)')}
- checked={config.disable_vkbasalt}
- disabled={config.force_enable_vkbasalt}
- onChange={(value) => {
- if (value && config.force_enable_vkbasalt) {
- // Turn off force enable when enabling disable
- onConfigChange(FORCE_ENABLE_VKBASALT, false);
- }
- onConfigChange(DISABLE_VKBASALT, value);
- }}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
- label={t('CONFIG_FORCE_ENABLE_VKBASALT', 'Force Enable vkBasalt')}
- description={t('CONFIG_FORCE_ENABLE_VKBASALT_DESC', 'Force vkBasalt to engage to fix framepacing issues in gamemode')}
- checked={config.force_enable_vkbasalt}
- disabled={config.disable_vkbasalt}
- onChange={(value) => {
- if (value && config.disable_vkbasalt) {
- // Turn off disable when enabling force enable
- onConfigChange(DISABLE_VKBASALT, false);
- }
- onConfigChange(FORCE_ENABLE_VKBASALT, value);
- }}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
- label={t('CONFIG_ENABLE_ZINK', 'Enable Zink for OpenGL Games')}
- description={t('CONFIG_ENABLE_ZINK_DESC', 'Use Vulkan-based OpenGL implementation for OpenGL games (may cause crashes or freezes with some games)')}
- checked={config.enable_zink}
- onChange={(value) => onConfigChange(ENABLE_ZINK, value)}
- />
- </PanelSectionRow>
- </>
- )}
- </>
- );
+export function ConfigurationSection({ config, onConfigChange }: ConfigurationSectionProps) {
+ return <>
+ <PanelSectionRow>
+ <SliderField label={`Flow Scale (${Math.round(config.flow_scale * 100)}%)`} description="Motion estimation resolution scale" value={config.flow_scale} min={0.25} max={1} step={0.01} onChange={(value) => onConfigChange(FLOW_SCALE, value)} />
+ </PanelSectionRow>
+ <PanelSectionRow>
+ <ToggleField label="FP16 Acceleration" description="Use FP16 shaders when supported" checked={!config.no_fp16} onChange={(value) => onConfigChange(NO_FP16, !value)} />
+ </PanelSectionRow>
+ <PanelSectionRow>
+ <ToggleField label="Performance Mode" description="Use the lighter frame generation model" checked={config.performance_mode} onChange={(value) => onConfigChange(PERFORMANCE_MODE, value)} />
+ </PanelSectionRow>
+ <PanelSectionRow>
+ <ToggleField label="Present Mode Override" description="Force FIFO/VSync pacing" checked={config.override_present_mode} onChange={(value) => onConfigChange(OVERRIDE_PRESENT_MODE, value)} />
+ </PanelSectionRow>
+ <PanelSectionRow>
+ <ToggleField label="Preserve Swapchain Image Count" description="Do not change the application's swapchain image count" checked={config.preserve_swapchain_image_count} onChange={(value) => onConfigChange(PRESERVE_SWAPCHAIN_IMAGE_COUNT, value)} />
+ </PanelSectionRow>
+ </>;
}