From 6c1b16cc4ecd1dc6c28882374419653538dca8f9 Mon Sep 17 00:00:00 2001
From: xXJSONDeruloXx <danielhimebauch@gmail.com>
Date: Mon, 20 Oct 2025 13:53:36 -0400
Subject: feat: collapsible config section above workarounds

---
 src/components/ConfigurationSection.tsx | 154 ++++++++++++++++++++++----------
 1 file changed, 107 insertions(+), 47 deletions(-)

(limited to 'src/components/ConfigurationSection.tsx')

diff --git a/src/components/ConfigurationSection.tsx b/src/components/ConfigurationSection.tsx
index b098b32..632c3a0 100644
--- a/src/components/ConfigurationSection.tsx
+++ b/src/components/ConfigurationSection.tsx
@@ -14,13 +14,23 @@ interface ConfigurationSectionProps {
   onConfigChange: (fieldName: keyof ConfigurationData, value: boolean | number | string) => Promise<void>;
 }
 
-const WORKAROUNDS_COLLAPSED_KEY = 'lsfg-workarounds-collapsed';
+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);
@@ -31,11 +41,19 @@ export function ConfigurationSection({
   });
 
   // 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);
+      console.warn("Failed to save workarounds collapse state:", error);
     }
   }, [workaroundsCollapsed]);
 
@@ -43,6 +61,8 @@ export function ConfigurationSection({
     <>
       <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;
         }
@@ -52,59 +72,99 @@ export function ConfigurationSection({
         `}
       </style>
 
-      {/* FPS Multiplier */}
-      <FpsMultiplierControl config={config} onConfigChange={onConfigChange} />
-
+      {/* Config Section */}
       <PanelSectionRow>
-        <SliderField
-          label={`Flow Scale (${Math.round(config.flow_scale * 100)}%)`}
-          description="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)}
-        />
+        <div
+          style={{
+            fontSize: "14px",
+            fontWeight: "bold",
+            marginTop: "16px",
+            marginBottom: "8px",
+            borderBottom: "1px solid rgba(255, 255, 255, 0.2)",
+            paddingBottom: "4px",
+            color: "white"
+          }}
+        >
+          Config
+        </div>
       </PanelSectionRow>
 
       <PanelSectionRow>
-        <SliderField
-          label={`Base FPS Cap${config.dxvk_frame_rate > 0 ? ` (${config.dxvk_frame_rate} FPS)` : ' (Off)'}`}
-          description="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)}
-        />
+        <div className="LSFG_ConfigCollapseButton_Container">
+          <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>
 
-      <PanelSectionRow>
-        <ToggleField
-          label={`Present Mode (${(config.experimental_present_mode || "fifo") === "fifo" ? "FIFO - VSync" : "Mailbox"})`}
-          description="Toggle between FIFO - VSync (default) and Mailbox presentation modes for better performance or compatibility"
-          checked={(config.experimental_present_mode || "fifo") === "fifo"}
-          onChange={(value) => onConfigChange(EXPERIMENTAL_PRESENT_MODE, value ? "fifo" : "mailbox")}
-        />
-      </PanelSectionRow>
+      {!configCollapsed && (
+        <>
+          <FpsMultiplierControl config={config} onConfigChange={onConfigChange} />
 
-      <PanelSectionRow>
-        <ToggleField
-          label="Performance Mode"
-          description="Uses a lighter model for FG (Recommended for most games)"
-          checked={config.performance_mode}
-          onChange={(value) => onConfigChange(PERFORMANCE_MODE, value)}
-        />
-      </PanelSectionRow>
+          <PanelSectionRow>
+            <SliderField
+              label={`Flow Scale (${Math.round(config.flow_scale * 100)}%)`}
+              description="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="HDR Mode"
-          description="Enables HDR mode (only for games that support HDR)"
-          checked={config.hdr_mode}
-          onChange={(value) => onConfigChange(HDR_MODE, value)}
-        />
-      </PanelSectionRow>
+          <PanelSectionRow>
+            <SliderField
+              label={`Base FPS Cap${config.dxvk_frame_rate > 0 ? ` (${config.dxvk_frame_rate} FPS)` : " (Off)"}`}
+              description="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={`Present Mode (${(config.experimental_present_mode || "fifo") === "fifo" ? "FIFO - VSync" : "Mailbox"})`}
+              description="Toggle between FIFO - VSync (default) and Mailbox presentation modes for better performance or compatibility"
+              checked={(config.experimental_present_mode || "fifo") === "fifo"}
+              onChange={(value) => onConfigChange(EXPERIMENTAL_PRESENT_MODE, value ? "fifo" : "mailbox")}
+            />
+          </PanelSectionRow>
+
+          <PanelSectionRow>
+            <ToggleField
+              label="Performance Mode"
+              description="Uses a lighter model for FG (Recommended for most games)"
+              checked={config.performance_mode}
+              onChange={(value) => onConfigChange(PERFORMANCE_MODE, value)}
+            />
+          </PanelSectionRow>
+
+          <PanelSectionRow>
+            <ToggleField
+              label="HDR Mode"
+              description="Enables HDR mode (only for games that support HDR)"
+              checked={config.hdr_mode}
+              onChange={(value) => onConfigChange(HDR_MODE, value)}
+            />
+          </PanelSectionRow>
+        </>
+      )}
 
       {/* Workarounds Section */}
       <PanelSectionRow>
-- 
cgit v1.2.3


From f2a2f4a126c5b60a2f8115c850883ccb8d736825 Mon Sep 17 00:00:00 2001
From: xXJSONDeruloXx <danielhimebauch@gmail.com>
Date: Mon, 20 Oct 2025 14:20:32 -0400
Subject: chore: move fps mul to top

---
 src/components/ConfigurationSection.tsx | 3 ---
 1 file changed, 3 deletions(-)

(limited to 'src/components/ConfigurationSection.tsx')

diff --git a/src/components/ConfigurationSection.tsx b/src/components/ConfigurationSection.tsx
index 632c3a0..eeacf05 100644
--- a/src/components/ConfigurationSection.tsx
+++ b/src/components/ConfigurationSection.tsx
@@ -2,7 +2,6 @@ import { PanelSectionRow, ToggleField, SliderField, ButtonItem } from "@decky/ui
 import { useState, useEffect } from "react";
 import { RiArrowDownSFill, RiArrowUpSFill } from "react-icons/ri";
 import { ConfigurationData } from "../config/configSchema";
-import { FpsMultiplierControl } from "./FpsMultiplierControl";
 import {
   FLOW_SCALE, PERFORMANCE_MODE, HDR_MODE,
   EXPERIMENTAL_PRESENT_MODE, DXVK_FRAME_RATE, DISABLE_STEAMDECK_MODE,
@@ -111,8 +110,6 @@ export function ConfigurationSection({
 
       {!configCollapsed && (
         <>
-          <FpsMultiplierControl config={config} onConfigChange={onConfigChange} />
-
           <PanelSectionRow>
             <SliderField
               label={`Flow Scale (${Math.round(config.flow_scale * 100)}%)`}
-- 
cgit v1.2.3


From 8dcfea10e22d783a8adc6b1564e10bd32777a665 Mon Sep 17 00:00:00 2001
From: xXJSONDeruloXx <danielhimebauch@gmail.com>
Date: Mon, 20 Oct 2025 14:26:05 -0400
Subject: chore: compact spacing for collapsibles

---
 src/components/ConfigurationSection.tsx | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

(limited to 'src/components/ConfigurationSection.tsx')

diff --git a/src/components/ConfigurationSection.tsx b/src/components/ConfigurationSection.tsx
index eeacf05..0734297 100644
--- a/src/components/ConfigurationSection.tsx
+++ b/src/components/ConfigurationSection.tsx
@@ -77,10 +77,10 @@ export function ConfigurationSection({
           style={{
             fontSize: "14px",
             fontWeight: "bold",
-            marginTop: "16px",
-            marginBottom: "8px",
+            marginTop: "8px",
+            marginBottom: "6px",
             borderBottom: "1px solid rgba(255, 255, 255, 0.2)",
-            paddingBottom: "4px",
+            paddingBottom: "3px",
             color: "white"
           }}
         >
@@ -89,7 +89,10 @@ export function ConfigurationSection({
       </PanelSectionRow>
 
       <PanelSectionRow>
-        <div className="LSFG_ConfigCollapseButton_Container">
+        <div
+          className="LSFG_ConfigCollapseButton_Container"
+          style={{ marginTop: "-2px", marginBottom: "4px" }}
+        >
           <ButtonItem
             layout="below"
             bottomSeparator={configCollapsed ? "standard" : "none"}
@@ -169,10 +172,10 @@ export function ConfigurationSection({
           style={{
             fontSize: "14px",
             fontWeight: "bold",
-            marginTop: "16px",
-            marginBottom: "8px",
+            marginTop: "8px",
+            marginBottom: "6px",
             borderBottom: "1px solid rgba(255, 255, 255, 0.2)",
-            paddingBottom: "4px",
+            paddingBottom: "3px",
             color: "white"
           }}
         >
@@ -181,7 +184,10 @@ export function ConfigurationSection({
       </PanelSectionRow>
 
       <PanelSectionRow>
-        <div className="LSFG_WorkaroundsCollapseButton_Container">
+        <div
+          className="LSFG_WorkaroundsCollapseButton_Container"
+          style={{ marginTop: "-2px", marginBottom: "4px" }}
+        >
           <ButtonItem
             layout="below"
             bottomSeparator={workaroundsCollapsed ? "standard" : "none"}
-- 
cgit v1.2.3

