From 234ac6e00c4e9e337e4c88829deee665d1a5303c Mon Sep 17 00:00:00 2001
From: xXJSONDeruloXx <danielhimebauch@gmail.com>
Date: Mon, 18 Aug 2025 12:08:21 -0400
Subject: lock profile selection if game is running

---
 src/components/ProfileManagement.tsx | 47 +++++++++++++++++++++++++++++-------
 1 file changed, 38 insertions(+), 9 deletions(-)

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

diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx
index 67f0645..46c507c 100644
--- a/src/components/ProfileManagement.tsx
+++ b/src/components/ProfileManagement.tsx
@@ -11,7 +11,9 @@ import {
   ButtonItem,
   ModalRoot,
   TextField,
-  Focusable
+  Focusable,
+  AppOverview,
+  Router
 } from "@decky/ui";
 import { 
   getProfiles, 
@@ -24,11 +26,6 @@ import {
 } from "../api/lsfgApi";
 import { showSuccessToast, showErrorToast } from "../utils/toastUtils";
 
-interface ProfileManagementProps {
-  currentProfile?: string;
-  onProfileChange?: (profileName: string) => void;
-}
-
 interface TextInputModalProps {
   title: string;
   description: string;
@@ -110,6 +107,7 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
   const [profiles, setProfiles] = useState<string[]>([]);
   const [selectedProfile, setSelectedProfile] = useState<string>(currentProfile || "decky-lsfg-vk");
   const [isLoading, setIsLoading] = useState(false);
+  const [mainRunningApp, setMainRunningApp] = useState<AppOverview | undefined>(undefined);
 
   // Load profiles on component mount
   useEffect(() => {
@@ -123,6 +121,22 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
     }
   }, [currentProfile]);
 
+  // Poll for running app every 2 seconds
+  useEffect(() => {
+    const checkRunningApp = () => {
+      setMainRunningApp(Router.MainRunningApp);
+    };
+
+    // Check immediately
+    checkRunningApp();
+
+    // Set up polling interval
+    const interval = setInterval(checkRunningApp, 2000);
+
+    // Cleanup interval on unmount
+    return () => clearInterval(interval);
+  }, []);
+
   const loadProfiles = async () => {
     try {
       const result: ProfilesResult = await getProfiles();
@@ -301,6 +315,21 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
 
   return (
     <PanelSection title="Select Profile">
+      {/* Display currently running game info */}
+      {mainRunningApp && (
+        <PanelSectionRow>
+          <div style={{ 
+            padding: "8px 12px", 
+            backgroundColor: "rgba(0, 255, 0, 0.1)", 
+            borderRadius: "4px",
+            border: "1px solid rgba(0, 255, 0, 0.3)",
+            fontSize: "13px"
+          }}>
+            <strong>{mainRunningApp.display_name}</strong> running. Close game to change profile.
+          </div>
+        </PanelSectionRow>
+      )}
+      
       <PanelSectionRow>
         <Field
           label=""
@@ -311,7 +340,7 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
             rgOptions={profileOptions}
             selectedOption={selectedProfile}
             onChange={handleDropdownChange}
-            disabled={isLoading}
+            disabled={isLoading || !!mainRunningApp}
           />
         </Field>
       </PanelSectionRow>
@@ -320,7 +349,7 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
         <ButtonItem
           layout="below"
           onClick={handleRenameProfile}
-          disabled={isLoading || selectedProfile === "decky-lsfg-vk"}
+          disabled={isLoading || selectedProfile === "decky-lsfg-vk" || !!mainRunningApp}
         >
           Rename
         </ButtonItem>
@@ -330,7 +359,7 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
         <ButtonItem
           layout="below"
           onClick={handleDeleteProfile}
-          disabled={isLoading || selectedProfile === "decky-lsfg-vk"}
+          disabled={isLoading || selectedProfile === "decky-lsfg-vk" || !!mainRunningApp}
         >
           Delete
         </ButtonItem>
-- 
cgit v1.2.3


From c6092d861cc3fb4d333dd47ec135474b030fb9b4 Mon Sep 17 00:00:00 2001
From: xXJSONDeruloXx <danielhimebauch@gmail.com>
Date: Mon, 18 Aug 2025 12:33:26 -0400
Subject: make all sections collapsible

---
 src/components/ProfileManagement.tsx | 166 +++++++++++++++++++++++++----------
 1 file changed, 119 insertions(+), 47 deletions(-)

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

diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx
index 46c507c..4a75484 100644
--- a/src/components/ProfileManagement.tsx
+++ b/src/components/ProfileManagement.tsx
@@ -1,6 +1,5 @@
 import { useState, useEffect } from "react";
 import {
-  PanelSection,
   PanelSectionRow,
   Dropdown,
   DropdownOption,
@@ -15,6 +14,7 @@ import {
   AppOverview,
   Router
 } from "@decky/ui";
+import { RiArrowDownSFill, RiArrowUpSFill } from "react-icons/ri";
 import { 
   getProfiles, 
   createProfile, 
@@ -26,6 +26,8 @@ import {
 } from "../api/lsfgApi";
 import { showSuccessToast, showErrorToast } from "../utils/toastUtils";
 
+const PROFILES_COLLAPSED_KEY = 'lsfg-profiles-collapsed';
+
 interface TextInputModalProps {
   title: string;
   description: string;
@@ -108,6 +110,25 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
   const [selectedProfile, setSelectedProfile] = useState<string>(currentProfile || "decky-lsfg-vk");
   const [isLoading, setIsLoading] = useState(false);
   const [mainRunningApp, setMainRunningApp] = useState<AppOverview | undefined>(undefined);
+  
+  // Initialize with localStorage value, fallback to false (expanded) if not found
+  const [profilesCollapsed, setProfilesCollapsed] = useState(() => {
+    try {
+      const saved = localStorage.getItem(PROFILES_COLLAPSED_KEY);
+      return saved !== null ? JSON.parse(saved) : false;
+    } catch {
+      return false;
+    }
+  });
+
+  // Persist profiles collapse state to localStorage
+  useEffect(() => {
+    try {
+      localStorage.setItem(PROFILES_COLLAPSED_KEY, JSON.stringify(profilesCollapsed));
+    } catch (error) {
+      console.warn('Failed to save profiles collapse state:', error);
+    }
+  }, [profilesCollapsed]);
 
   // Load profiles on component mount
   useEffect(() => {
@@ -314,56 +335,107 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
   ];
 
   return (
-    <PanelSection title="Select Profile">
-      {/* Display currently running game info */}
-      {mainRunningApp && (
-        <PanelSectionRow>
-          <div style={{ 
-            padding: "8px 12px", 
-            backgroundColor: "rgba(0, 255, 0, 0.1)", 
-            borderRadius: "4px",
-            border: "1px solid rgba(0, 255, 0, 0.3)",
-            fontSize: "13px"
-          }}>
-            <strong>{mainRunningApp.display_name}</strong> running. Close game to change profile.
-          </div>
-        </PanelSectionRow>
-      )}
-      
-      <PanelSectionRow>
-        <Field
-          label=""
-          childrenLayout="below"
-          childrenContainerWidth="max"
-        >
-          <Dropdown
-            rgOptions={profileOptions}
-            selectedOption={selectedProfile}
-            onChange={handleDropdownChange}
-            disabled={isLoading || !!mainRunningApp}
-          />
-        </Field>
-      </PanelSectionRow>
-      
+    <>
+      <style>
+        {`
+        .LSFG_ProfilesCollapseButton_Container > div > div > div > button {
+          height: 10px !important;
+        }
+        .LSFG_ProfilesCollapseButton_Container > div > div > div > div > button {
+          height: 10px !important;
+        }
+        `}
+      </style>
+
       <PanelSectionRow>
-        <ButtonItem
-          layout="below"
-          onClick={handleRenameProfile}
-          disabled={isLoading || selectedProfile === "decky-lsfg-vk" || !!mainRunningApp}
+        <div
+          style={{
+            fontSize: "14px",
+            fontWeight: "bold",
+            marginTop: "16px",
+            marginBottom: "8px",
+            borderBottom: "1px solid rgba(255, 255, 255, 0.2)",
+            paddingBottom: "4px",
+            color: "white"
+          }}
         >
-          Rename
-        </ButtonItem>
+          Select Profile
+        </div>
       </PanelSectionRow>
-      
+
       <PanelSectionRow>
-        <ButtonItem
-          layout="below"
-          onClick={handleDeleteProfile}
-          disabled={isLoading || selectedProfile === "decky-lsfg-vk" || !!mainRunningApp}
-        >
-          Delete
-        </ButtonItem>
+        <div className="LSFG_ProfilesCollapseButton_Container">
+          <ButtonItem
+            layout="below"
+            bottomSeparator={profilesCollapsed ? "standard" : "none"}
+            onClick={() => setProfilesCollapsed(!profilesCollapsed)}
+          >
+            {profilesCollapsed ? (
+              <RiArrowDownSFill
+                style={{ transform: "translate(0, -13px)", fontSize: "1.5em" }}
+              />
+            ) : (
+              <RiArrowUpSFill
+                style={{ transform: "translate(0, -12px)", fontSize: "1.5em" }}
+              />
+            )}
+          </ButtonItem>
+        </div>
       </PanelSectionRow>
-    </PanelSection>
+
+      {!profilesCollapsed && (
+        <>
+          {/* Display currently running game info */}
+          {mainRunningApp && (
+            <PanelSectionRow>
+              <div style={{ 
+                padding: "8px 12px", 
+                backgroundColor: "rgba(0, 255, 0, 0.1)", 
+                borderRadius: "4px",
+                border: "1px solid rgba(0, 255, 0, 0.3)",
+                fontSize: "13px"
+              }}>
+                <strong>{mainRunningApp.display_name}</strong> running. Close game to change profile.
+              </div>
+            </PanelSectionRow>
+          )}
+          
+          <PanelSectionRow>
+            <Field
+              label=""
+              childrenLayout="below"
+              childrenContainerWidth="max"
+            >
+              <Dropdown
+                rgOptions={profileOptions}
+                selectedOption={selectedProfile}
+                onChange={handleDropdownChange}
+                disabled={isLoading || !!mainRunningApp}
+              />
+            </Field>
+          </PanelSectionRow>
+          
+          <PanelSectionRow>
+            <ButtonItem
+              layout="below"
+              onClick={handleRenameProfile}
+              disabled={isLoading || selectedProfile === "decky-lsfg-vk" || !!mainRunningApp}
+            >
+              Rename
+            </ButtonItem>
+          </PanelSectionRow>
+          
+          <PanelSectionRow>
+            <ButtonItem
+              layout="below"
+              onClick={handleDeleteProfile}
+              disabled={isLoading || selectedProfile === "decky-lsfg-vk" || !!mainRunningApp}
+            >
+              Delete
+            </ButtonItem>
+          </PanelSectionRow>
+        </>
+      )}
+    </>
   );
 }
-- 
cgit v1.2.3


From 119d3d7cb21fb96f220ec25f478d4b3621ae402f Mon Sep 17 00:00:00 2001
From: xXJSONDeruloXx <danielhimebauch@gmail.com>
Date: Mon, 18 Aug 2025 12:36:35 -0400
Subject: profile at top and readout in header

---
 src/components/ProfileManagement.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx
index 4a75484..7c8966b 100644
--- a/src/components/ProfileManagement.tsx
+++ b/src/components/ProfileManagement.tsx
@@ -359,7 +359,7 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
             color: "white"
           }}
         >
-          Select Profile
+          Profile: {selectedProfile === "decky-lsfg-vk" ? "Default" : selectedProfile}
         </div>
       </PanelSectionRow>
 
-- 
cgit v1.2.3


From 687d017c02d5a7dc37fde941c583ff74d8dd6363 Mon Sep 17 00:00:00 2001
From: xXJSONDeruloXx <danielhimebauch@gmail.com>
Date: Mon, 18 Aug 2025 12:50:42 -0400
Subject: visibility for profile lock indicator, ver bump

---
 src/components/ProfileManagement.tsx | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

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

diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx
index 7c8966b..6e2a8f8 100644
--- a/src/components/ProfileManagement.tsx
+++ b/src/components/ProfileManagement.tsx
@@ -347,6 +347,21 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
         `}
       </style>
 
+      {/* Display currently running game info - always visible */}
+      {mainRunningApp && (
+        <PanelSectionRow>
+          <div style={{ 
+            padding: "8px 12px", 
+            backgroundColor: "rgba(0, 255, 0, 0.1)", 
+            borderRadius: "4px",
+            border: "1px solid rgba(0, 255, 0, 0.3)",
+            fontSize: "13px"
+          }}>
+            <strong>{mainRunningApp.display_name}</strong> running. Close game to change profile.
+          </div>
+        </PanelSectionRow>
+      )}
+
       <PanelSectionRow>
         <div
           style={{
@@ -385,21 +400,6 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa
 
       {!profilesCollapsed && (
         <>
-          {/* Display currently running game info */}
-          {mainRunningApp && (
-            <PanelSectionRow>
-              <div style={{ 
-                padding: "8px 12px", 
-                backgroundColor: "rgba(0, 255, 0, 0.1)", 
-                borderRadius: "4px",
-                border: "1px solid rgba(0, 255, 0, 0.3)",
-                fontSize: "13px"
-              }}>
-                <strong>{mainRunningApp.display_name}</strong> running. Close game to change profile.
-              </div>
-            </PanelSectionRow>
-          )}
-          
           <PanelSectionRow>
             <Field
               label=""
-- 
cgit v1.2.3

