From ad2b182777bfd0a5ceef6e654df75ff13eb8b503 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sun, 6 Sep 2026 15:08:45 -0400 Subject: refactor: offload configuration to lsfg-vk --- src/components/ProfileManagement.tsx | 477 ----------------------------------- 1 file changed, 477 deletions(-) delete mode 100644 src/components/ProfileManagement.tsx (limited to 'src/components/ProfileManagement.tsx') diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx deleted file mode 100644 index 626d54c..0000000 --- a/src/components/ProfileManagement.tsx +++ /dev/null @@ -1,477 +0,0 @@ -import { useState, useEffect } from "react"; -import { - PanelSectionRow, - Dropdown, - DropdownOption, - showModal, - ConfirmModal, - Field, - DialogButton, - ButtonItem, - ModalRoot, - TextField, - Focusable, - AppOverview, - Router -} from "@decky/ui"; -import { RiArrowDownSFill, RiArrowUpSFill, RiEditLine, RiDeleteBinLine } from "react-icons/ri"; -import { - getProfiles, - createProfile, - deleteProfile, - renameProfile, - setCurrentProfile, - ProfilesResult, - ProfileResult -} from "../api/lsfgApi"; -import { showSuccessToast, showErrorToast } from "../utils/toastUtils"; -import t from '../i18n/i18n'; - -const PROFILES_COLLAPSED_KEY = 'lsfg-profiles-collapsed'; - -interface TextInputModalProps { - title: string; - description: string; - defaultValue?: string; - okText?: string; - cancelText?: string; - onOK: (value: string) => void; - closeModal?: () => void; -} - -function TextInputModal({ - title, - description, - defaultValue = "", - okText = "OK", - cancelText = "Cancel", - onOK, - closeModal -}: TextInputModalProps) { - const [value, setValue] = useState(defaultValue); - - const handleOK = () => { - if (value.trim()) { - onOK(value); - closeModal?.(); - } - }; - - return ( - -
-

{title}

-

{description}

- -
- - setValue(e?.target?.value || "")} - style={{ width: "100%" }} - /> - -
- - - - {cancelText} - - - {okText} - - -
-
- ); -} - -interface ProfileManagementProps { - currentProfile?: string; - onProfileChange?: (profileName: string) => void; -} - -export function ProfileManagement({ currentProfile, onProfileChange }: ProfileManagementProps) { - const [profiles, setProfiles] = useState([]); - const [selectedProfile, setSelectedProfile] = useState(currentProfile || "decky-lsfg-vk"); - const [isLoading, setIsLoading] = useState(false); - const [mainRunningApp, setMainRunningApp] = useState(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(() => { - loadProfiles(); - }, []); - - // Update selected profile when prop changes - useEffect(() => { - if (currentProfile) { - setSelectedProfile(currentProfile); - } - }, [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(); - if (result.success && result.profiles) { - setProfiles(result.profiles); - if (result.current_profile) { - setSelectedProfile(result.current_profile); - } - } else { - console.error("Failed to load profiles:", result.error); - showErrorToast("Failed to load profiles", result.error || "Unknown error"); - } - } catch (error) { - console.error("Error loading profiles:", error); - showErrorToast("Error loading profiles", String(error)); - } - }; - - const handleProfileChange = async (profileName: string) => { - setIsLoading(true); - try { - const result: ProfileResult = await setCurrentProfile(profileName); - if (result.success) { - setSelectedProfile(profileName); - showSuccessToast("Profile switched", `Switched to profile: ${profileName}`); - onProfileChange?.(profileName); - } else { - console.error("Failed to switch profile:", result.error); - showErrorToast("Failed to switch profile", result.error || "Unknown error"); - } - } catch (error) { - console.error("Error switching profile:", error); - showErrorToast("Error switching profile", String(error)); - } finally { - setIsLoading(false); - } - }; - - const handleCreateProfile = () => { - showModal( - { - if (name.trim()) { - createNewProfile(name.trim()); - } - }} - /> - ); - }; - - const createNewProfile = async (profileName: string) => { - setIsLoading(true); - try { - const result: ProfileResult = await createProfile(profileName, selectedProfile); - if (result.success) { - // Use the normalized name returned from backend (spaces converted to dashes) - const actualProfileName = result.profile_name || profileName; - showSuccessToast("Profile created", `Created profile: ${actualProfileName}`); - await loadProfiles(); - // Automatically switch to the newly created profile using the normalized name - await handleProfileChange(actualProfileName); - } else { - console.error("Failed to create profile:", result.error); - showErrorToast("Failed to create profile", result.error || "Unknown error"); - } - } catch (error) { - console.error("Error creating profile:", error); - showErrorToast("Error creating profile", String(error)); - } finally { - setIsLoading(false); - } - }; - - const handleDeleteProfile = () => { - if (selectedProfile === "decky-lsfg-vk") { - showErrorToast(t('PROFILE_CANNOT_DELETE_TITLE', 'Cannot delete default profile'), t('PROFILE_CANNOT_DELETE_MSG', 'The default profile cannot be deleted')); - return; - } - - showModal( - deleteSelectedProfile()} - /> - ); - }; - - const deleteSelectedProfile = async () => { - setIsLoading(true); - try { - const result: ProfileResult = await deleteProfile(selectedProfile); - if (result.success) { - showSuccessToast("Profile deleted", `Deleted profile: ${selectedProfile}`); - await loadProfiles(); - // If we deleted the current profile, it should have switched to default - setSelectedProfile("decky-lsfg-vk"); - onProfileChange?.("decky-lsfg-vk"); - } else { - console.error("Failed to delete profile:", result.error); - showErrorToast("Failed to delete profile", result.error || "Unknown error"); - } - } catch (error) { - console.error("Error deleting profile:", error); - showErrorToast("Error deleting profile", String(error)); - } finally { - setIsLoading(false); - } - }; - - const handleDropdownChange = (option: DropdownOption) => { - if (option.data === "__NEW_PROFILE__") { - handleCreateProfile(); - } else { - handleProfileChange(option.data); - } - }; - - const handleRenameProfile = () => { - if (selectedProfile === "decky-lsfg-vk") { - showErrorToast(t('PROFILE_CANNOT_RENAME_TITLE', 'Cannot rename default profile'), t('PROFILE_CANNOT_RENAME_MSG', 'The default profile cannot be renamed')); - return; - } - - showModal( - { - if (newName.trim() && newName.trim() !== selectedProfile) { - renameSelectedProfile(newName.trim()); - } - }} - /> - ); - }; - - const renameSelectedProfile = async (newName: string) => { - setIsLoading(true); - try { - const result: ProfileResult = await renameProfile(selectedProfile, newName); - if (result.success) { - // Use the normalized name returned from backend (spaces converted to dashes) - const actualNewName = result.profile_name || newName; - showSuccessToast("Profile renamed", `Renamed profile to: ${actualNewName}`); - await loadProfiles(); - setSelectedProfile(actualNewName); - onProfileChange?.(actualNewName); - } else { - console.error("Failed to rename profile:", result.error); - showErrorToast("Failed to rename profile", result.error || "Unknown error"); - } - } catch (error) { - console.error("Error renaming profile:", error); - showErrorToast("Error renaming profile", String(error)); - } finally { - setIsLoading(false); - } - }; - - const profileOptions: DropdownOption[] = [ - ...profiles.map((profile: string) => ({ - data: profile, - label: profile === "decky-lsfg-vk" ? t('PROFILE_DEFAULT', 'Default') : profile - })), - { - data: "__NEW_PROFILE__", - label: t('PROFILE_NEW', 'New Profile') - } - ]; - - return ( - <> - - - {/* Display currently running game info - always visible */} - {mainRunningApp && ( - -
- {mainRunningApp.display_name} running. {t('PROFILE_CLOSE_GAME', 'Close game to change profile.')} -
-
- )} - - -
- {t('PROFILE_SECTION_TITLE', 'Profile:')} {selectedProfile === "decky-lsfg-vk" ? t('PROFILE_DEFAULT', 'Default') : selectedProfile} -
-
- - -
- setProfilesCollapsed(!profilesCollapsed)} - > - {profilesCollapsed ? ( - - ) : ( - - )} - -
-
- - {!profilesCollapsed && ( - <> - - - - - - - - - - - - - - - - - - - )} - - ); -} -- cgit v1.2.3