diff options
Diffstat (limited to 'src/components/ConfigurationSection.tsx')
| -rw-r--r-- | src/components/ConfigurationSection.tsx | 307 |
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> + </>; } |
