From 4104e28053fc03b3875958c7bf56ec6fbc5aab84 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 16 Aug 2025 12:05:10 -0400 Subject: initial prof selector and creator ui --- src/api/lsfgApi.ts | 26 +++ src/components/Content.tsx | 26 ++- src/components/ProfileManagement.tsx | 307 +++++++++++++++++++++++++++++++++++ src/components/index.ts | 1 + src/hooks/useProfileManagement.ts | 194 ++++++++++++++++++++++ 5 files changed, 553 insertions(+), 1 deletion(-) create mode 100644 src/components/ProfileManagement.tsx create mode 100644 src/hooks/useProfileManagement.ts (limited to 'src') diff --git a/src/api/lsfgApi.ts b/src/api/lsfgApi.ts index 8d14da6..6c535af 100644 --- a/src/api/lsfgApi.ts +++ b/src/api/lsfgApi.ts @@ -55,6 +55,8 @@ export interface ConfigSchemaResult { field_names: string[]; field_types: Record; defaults: ConfigurationData; + profiles?: string[]; + current_profile?: string; } export interface UpdateCheckResult { @@ -87,6 +89,22 @@ export interface FileContentResult { error?: string; } +// Profile management interfaces +export interface ProfilesResult { + success: boolean; + profiles?: string[]; + current_profile?: string; + message?: string; + error?: string; +} + +export interface ProfileResult { + success: boolean; + profile_name?: string; + message?: string; + error?: string; +} + // API functions export const installLsfgVk = callable<[], InstallationResult>("install_lsfg_vk"); export const uninstallLsfgVk = callable<[], InstallationResult>("uninstall_lsfg_vk"); @@ -113,3 +131,11 @@ export const updateLsfgConfigFromObject = async (config: ConfigurationData): Pro // Self-updater API functions export const checkForPluginUpdate = callable<[], UpdateCheckResult>("check_for_plugin_update"); export const downloadPluginUpdate = callable<[string], UpdateDownloadResult>("download_plugin_update"); + +// Profile management API functions +export const getProfiles = callable<[], ProfilesResult>("get_profiles"); +export const createProfile = callable<[string, string?], ProfileResult>("create_profile"); +export const deleteProfile = callable<[string], ProfileResult>("delete_profile"); +export const renameProfile = callable<[string, string], ProfileResult>("rename_profile"); +export const setCurrentProfile = callable<[string], ProfileResult>("set_current_profile"); +export const updateProfileConfig = callable<[string, ConfigurationData], ConfigUpdateResult>("update_profile_config"); diff --git a/src/components/Content.tsx b/src/components/Content.tsx index a075574..c7c757b 100644 --- a/src/components/Content.tsx +++ b/src/components/Content.tsx @@ -1,10 +1,12 @@ import { useEffect } from "react"; import { PanelSection, showModal, ButtonItem, PanelSectionRow } from "@decky/ui"; import { useInstallationStatus, useDllDetection, useLsfgConfig } from "../hooks/useLsfgHooks"; +import { useProfileManagement } from "../hooks/useProfileManagement"; import { useInstallationActions } from "../hooks/useInstallationActions"; import { StatusDisplay } from "./StatusDisplay"; import { InstallationButton } from "./InstallationButton"; import { ConfigurationSection } from "./ConfigurationSection"; +import { ProfileManagement } from "./ProfileManagement"; import { UsageInstructions } from "./UsageInstructions"; import { WikiButton } from "./WikiButton"; import { ClipboardButton } from "./ClipboardButton"; @@ -29,6 +31,11 @@ export function Content() { updateField } = useLsfgConfig(); + const { + currentProfile, + updateProfileConfig + } = useProfileManagement(); + const { isInstalling, isUninstalling, handleInstall, handleUninstall } = useInstallationActions(); // Reload config when installation status changes @@ -40,7 +47,16 @@ export function Content() { // Generic configuration change handler const handleConfigChange = async (fieldName: keyof ConfigurationData, value: boolean | number | string) => { - await updateField(fieldName, value); + // If we have a current profile, update that profile specifically + if (currentProfile) { + const newConfig = { ...config, [fieldName]: value }; + await updateProfileConfig(currentProfile, newConfig); + // Also update local config state + await updateField(fieldName, value); + } else { + // Fallback to the original method + await updateField(fieldName, value); + } }; const onInstall = () => { @@ -74,6 +90,14 @@ export function Content() { + {/* Profile Management - only show if installed */} + {isInstalled && ( + loadLsfgConfig()} + /> + )} + {/* Configuration Section - only show if installed */} {isInstalled && ( void; +} + +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 = () => { + onOK(value); + closeModal?.(); + }; + + return ( + +
+

{title}

+

{description}

+ + + setValue(e?.target?.value || "")} + /> + + +
+ + {okText} + + + {cancelText} + +
+
+
+ ); +} + +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); + + // Load profiles on component mount + useEffect(() => { + loadProfiles(); + }, []); + + // Update selected profile when prop changes + useEffect(() => { + if (currentProfile) { + setSelectedProfile(currentProfile); + } + }, [currentProfile]); + + 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) { + showSuccessToast("Profile created", `Created profile: ${profileName}`); + await loadProfiles(); + } 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("Cannot delete default profile", "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 handleRenameProfile = () => { + if (selectedProfile === "decky-lsfg-vk") { + showErrorToast("Cannot rename default profile", "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) { + showSuccessToast("Profile renamed", `Renamed profile to: ${newName}`); + await loadProfiles(); + setSelectedProfile(newName); + onProfileChange?.(newName); + } 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 => ({ + data: profile, + label: profile === "decky-lsfg-vk" ? `${profile} (default)` : profile + })); + + return ( + + + + handleProfileChange(option.data)} + disabled={isLoading} + /> + + + + + + + New Profile + + + + Rename + + + + Delete + + + + + ); +} diff --git a/src/components/index.ts b/src/components/index.ts index 305911d..bf60423 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -8,3 +8,4 @@ export { WikiButton } from "./WikiButton"; export { SmartClipboardButton } from "./SmartClipboardButton"; export { PluginUpdateChecker } from "./PluginUpdateChecker"; export { NerdStuffModal } from "./NerdStuffModal"; +export { ProfileManagement } from "./ProfileManagement"; diff --git a/src/hooks/useProfileManagement.ts b/src/hooks/useProfileManagement.ts new file mode 100644 index 0000000..bb6cd6f --- /dev/null +++ b/src/hooks/useProfileManagement.ts @@ -0,0 +1,194 @@ +import { useState, useEffect, useCallback } from "react"; +import { + getProfiles, + createProfile, + deleteProfile, + renameProfile, + setCurrentProfile, + updateProfileConfig, + type ProfilesResult, + type ProfileResult, + type ConfigUpdateResult +} from "../api/lsfgApi"; +import { ConfigurationData } from "../config/configSchema"; +import { showSuccessToast, showErrorToast } from "../utils/toastUtils"; + +export function useProfileManagement() { + const [profiles, setProfiles] = useState([]); + const [currentProfile, setCurrentProfileState] = useState("decky-lsfg-vk"); + const [isLoading, setIsLoading] = useState(false); + + // Load profiles on hook initialization + const loadProfiles = useCallback(async () => { + try { + const result: ProfilesResult = await getProfiles(); + if (result.success && result.profiles) { + setProfiles(result.profiles); + if (result.current_profile) { + setCurrentProfileState(result.current_profile); + } + return result; + } else { + console.error("Failed to load profiles:", result.error); + showErrorToast("Failed to load profiles", result.error || "Unknown error"); + return result; + } + } catch (error) { + console.error("Error loading profiles:", error); + showErrorToast("Error loading profiles", String(error)); + return { success: false, error: String(error) }; + } + }, []); + + // Create a new profile + const handleCreateProfile = useCallback(async (profileName: string, sourceProfile?: string) => { + setIsLoading(true); + try { + const result: ProfileResult = await createProfile(profileName, sourceProfile || currentProfile); + if (result.success) { + showSuccessToast("Profile created", `Created profile: ${profileName}`); + await loadProfiles(); + return result; + } else { + console.error("Failed to create profile:", result.error); + showErrorToast("Failed to create profile", result.error || "Unknown error"); + return result; + } + } catch (error) { + console.error("Error creating profile:", error); + showErrorToast("Error creating profile", String(error)); + return { success: false, error: String(error) }; + } finally { + setIsLoading(false); + } + }, [currentProfile, loadProfiles]); + + // Delete a profile + const handleDeleteProfile = useCallback(async (profileName: string) => { + if (profileName === "decky-lsfg-vk") { + showErrorToast("Cannot delete default profile", "The default profile cannot be deleted"); + return { success: false, error: "Cannot delete default profile" }; + } + + setIsLoading(true); + try { + const result: ProfileResult = await deleteProfile(profileName); + if (result.success) { + showSuccessToast("Profile deleted", `Deleted profile: ${profileName}`); + await loadProfiles(); + // If we deleted the current profile, it should have switched to default + if (currentProfile === profileName) { + setCurrentProfileState("decky-lsfg-vk"); + } + return result; + } else { + console.error("Failed to delete profile:", result.error); + showErrorToast("Failed to delete profile", result.error || "Unknown error"); + return result; + } + } catch (error) { + console.error("Error deleting profile:", error); + showErrorToast("Error deleting profile", String(error)); + return { success: false, error: String(error) }; + } finally { + setIsLoading(false); + } + }, [currentProfile, loadProfiles]); + + // Rename a profile + const handleRenameProfile = useCallback(async (oldName: string, newName: string) => { + if (oldName === "decky-lsfg-vk") { + showErrorToast("Cannot rename default profile", "The default profile cannot be renamed"); + return { success: false, error: "Cannot rename default profile" }; + } + + setIsLoading(true); + try { + const result: ProfileResult = await renameProfile(oldName, newName); + if (result.success) { + showSuccessToast("Profile renamed", `Renamed profile to: ${newName}`); + await loadProfiles(); + // Update current profile if it was renamed + if (currentProfile === oldName) { + setCurrentProfileState(newName); + } + return result; + } else { + console.error("Failed to rename profile:", result.error); + showErrorToast("Failed to rename profile", result.error || "Unknown error"); + return result; + } + } catch (error) { + console.error("Error renaming profile:", error); + showErrorToast("Error renaming profile", String(error)); + return { success: false, error: String(error) }; + } finally { + setIsLoading(false); + } + }, [currentProfile, loadProfiles]); + + // Set the current active profile + const handleSetCurrentProfile = useCallback(async (profileName: string) => { + setIsLoading(true); + try { + const result: ProfileResult = await setCurrentProfile(profileName); + if (result.success) { + setCurrentProfileState(profileName); + showSuccessToast("Profile switched", `Switched to profile: ${profileName}`); + return result; + } else { + console.error("Failed to switch profile:", result.error); + showErrorToast("Failed to switch profile", result.error || "Unknown error"); + return result; + } + } catch (error) { + console.error("Error switching profile:", error); + showErrorToast("Error switching profile", String(error)); + return { success: false, error: String(error) }; + } finally { + setIsLoading(false); + } + }, []); + + // Update configuration for a specific profile + const handleUpdateProfileConfig = useCallback(async (profileName: string, config: ConfigurationData) => { + setIsLoading(true); + try { + const result: ConfigUpdateResult = await updateProfileConfig(profileName, config); + if (result.success) { + // Only show success toast if this is the current profile + if (profileName === currentProfile) { + showSuccessToast("Configuration updated", `Updated configuration for profile: ${profileName}`); + } + return result; + } else { + console.error("Failed to update profile config:", result.error); + showErrorToast("Failed to update profile config", result.error || "Unknown error"); + return result; + } + } catch (error) { + console.error("Error updating profile config:", error); + showErrorToast("Error updating profile config", String(error)); + return { success: false, error: String(error) }; + } finally { + setIsLoading(false); + } + }, [currentProfile]); + + // Initialize profiles on mount + useEffect(() => { + loadProfiles(); + }, [loadProfiles]); + + return { + profiles, + currentProfile, + isLoading, + loadProfiles, + createProfile: handleCreateProfile, + deleteProfile: handleDeleteProfile, + renameProfile: handleRenameProfile, + setCurrentProfile: handleSetCurrentProfile, + updateProfileConfig: handleUpdateProfileConfig + }; +} -- cgit v1.2.3 From 5c3cd5d0dc620a64b13475c7daa5638ddcb061bb Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 16 Aug 2025 12:17:21 -0400 Subject: fix unique prof creation in conf --- src/components/Content.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/components/Content.tsx b/src/components/Content.tsx index c7c757b..d823257 100644 --- a/src/components/Content.tsx +++ b/src/components/Content.tsx @@ -50,11 +50,13 @@ export function Content() { // If we have a current profile, update that profile specifically if (currentProfile) { const newConfig = { ...config, [fieldName]: value }; - await updateProfileConfig(currentProfile, newConfig); - // Also update local config state - await updateField(fieldName, value); + const result = await updateProfileConfig(currentProfile, newConfig); + if (result.success) { + // Reload config to reflect the changes from the backend + await loadLsfgConfig(); + } } else { - // Fallback to the original method + // Fallback to the original method for backward compatibility await updateField(fieldName, value); } }; -- cgit v1.2.3 From 149ecf2d8bf5eaacb2e71d7006d3b38f15b91104 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 16 Aug 2025 12:27:11 -0400 Subject: fix: stuck ui states on newly created profile in conf items --- src/components/Content.tsx | 8 ++++++-- src/components/ProfileManagement.tsx | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/components/Content.tsx b/src/components/Content.tsx index d823257..7815951 100644 --- a/src/components/Content.tsx +++ b/src/components/Content.tsx @@ -33,7 +33,8 @@ export function Content() { const { currentProfile, - updateProfileConfig + updateProfileConfig, + loadProfiles } = useProfileManagement(); const { isInstalling, isUninstalling, handleInstall, handleUninstall } = useInstallationActions(); @@ -96,7 +97,10 @@ export function Content() { {isInstalled && ( loadLsfgConfig()} + onProfileChange={async () => { + await loadProfiles(); + await loadLsfgConfig(); + }} /> )} diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx index a499836..83b5fa4 100644 --- a/src/components/ProfileManagement.tsx +++ b/src/components/ProfileManagement.tsx @@ -163,6 +163,8 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa if (result.success) { showSuccessToast("Profile created", `Created profile: ${profileName}`); await loadProfiles(); + // Automatically switch to the newly created profile + await handleProfileChange(profileName); } else { console.error("Failed to create profile:", result.error); showErrorToast("Failed to create profile", result.error || "Unknown error"); -- cgit v1.2.3 From 4c6939b1938f044a7511f617406e35de463c1b35 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 16 Aug 2025 12:39:32 -0400 Subject: fix styling of prof buttons --- src/components/ProfileManagement.tsx | 68 +++++++++++++++++++----------------- src/hooks/useProfileManagement.ts | 4 --- 2 files changed, 36 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx index 83b5fa4..d5e5521 100644 --- a/src/components/ProfileManagement.tsx +++ b/src/components/ProfileManagement.tsx @@ -8,7 +8,7 @@ import { ConfirmModal, Field, DialogButton, - Focusable, + ButtonItem, ModalRoot, TextField } from "@decky/ui"; @@ -268,41 +268,45 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa - handleProfileChange(option.data)} - disabled={isLoading} - /> +
+ handleProfileChange(option.data)} + disabled={isLoading} + /> +
- - - New Profile - - - - Rename - - - - Delete - - + + New Profile + + + + + + Rename + + + + + + Delete +
); diff --git a/src/hooks/useProfileManagement.ts b/src/hooks/useProfileManagement.ts index bb6cd6f..4b10f0e 100644 --- a/src/hooks/useProfileManagement.ts +++ b/src/hooks/useProfileManagement.ts @@ -156,10 +156,6 @@ export function useProfileManagement() { try { const result: ConfigUpdateResult = await updateProfileConfig(profileName, config); if (result.success) { - // Only show success toast if this is the current profile - if (profileName === currentProfile) { - showSuccessToast("Configuration updated", `Updated configuration for profile: ${profileName}`); - } return result; } else { console.error("Failed to update profile config:", result.error); -- cgit v1.2.3 From ef9ef1b2bbd9fa34375578b4091a8729d25c94ab Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 16 Aug 2025 15:11:56 -0400 Subject: rm unneeded line in dd for profiles --- src/components/ProfileManagement.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx index d5e5521..79d3aa1 100644 --- a/src/components/ProfileManagement.tsx +++ b/src/components/ProfileManagement.tsx @@ -265,10 +265,9 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa })); return ( - + - -
+
- -- cgit v1.2.3 From 79cd9296e9aaf2453030b014712e95312f201514 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 16 Aug 2025 15:29:04 -0400 Subject: fix width of DD after rm of label --- src/components/ProfileManagement.tsx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx index 79d3aa1..709a28c 100644 --- a/src/components/ProfileManagement.tsx +++ b/src/components/ProfileManagement.tsx @@ -267,14 +267,18 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa return ( -
- handleProfileChange(option.data)} - disabled={isLoading} - /> -
+ + handleProfileChange(option.data)} + disabled={isLoading} + /> +
-- cgit v1.2.3 From ca74a157ca5cc22c9b4292c895af35be96b54588 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 16 Aug 2025 15:35:49 -0400 Subject: move new profile into dropdown --- src/components/ProfileManagement.tsx | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx index 709a28c..ef68844 100644 --- a/src/components/ProfileManagement.tsx +++ b/src/components/ProfileManagement.tsx @@ -216,6 +216,14 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa } }; + const handleDropdownChange = (option: DropdownOption) => { + if (option.data === "__NEW_PROFILE__") { + handleCreateProfile(); + } else { + handleProfileChange(option.data); + } + }; + const handleRenameProfile = () => { if (selectedProfile === "decky-lsfg-vk") { showErrorToast("Cannot rename default profile", "The default profile cannot be renamed"); @@ -259,10 +267,16 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa } }; - const profileOptions: DropdownOption[] = profiles.map(profile => ({ - data: profile, - label: profile === "decky-lsfg-vk" ? `${profile} (default)` : profile - })); + const profileOptions: DropdownOption[] = [ + ...profiles.map((profile: string) => ({ + data: profile, + label: profile === "decky-lsfg-vk" ? "Default" : profile + })), + { + data: "__NEW_PROFILE__", + label: "New Profile" + } + ]; return ( @@ -275,21 +289,11 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa handleProfileChange(option.data)} + onChange={handleDropdownChange} disabled={isLoading} /> - - - - New Profile - - Date: Sat, 16 Aug 2025 15:42:29 -0400 Subject: fix width of new profile text field --- src/components/ProfileManagement.tsx | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx index ef68844..543609f 100644 --- a/src/components/ProfileManagement.tsx +++ b/src/components/ProfileManagement.tsx @@ -56,24 +56,31 @@ function TextInputModal({ return ( -
+

{title}

-

{description}

+

{description}

- - setValue(e?.target?.value || "")} - /> - +
+ + setValue(e?.target?.value || "")} + style={{ width: "100%" }} + /> + +
-
- - {okText} - +
{cancelText} + + {okText} +
-- cgit v1.2.3 From aaf9351b6f91b35d6e33b9d52d51cae6061c93bd Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 16 Aug 2025 15:45:32 -0400 Subject: hide fp16 toggle --- src/components/ConfigurationSection.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/components/ConfigurationSection.tsx b/src/components/ConfigurationSection.tsx index 31ce278..466a982 100644 --- a/src/components/ConfigurationSection.tsx +++ b/src/components/ConfigurationSection.tsx @@ -113,14 +113,14 @@ export function ConfigurationSection({ /> - + {/* onConfigChange(NO_FP16, value)} /> - + */} Date: Sat, 16 Aug 2025 16:09:11 -0400 Subject: fix focusable elements for new profile creation modal --- src/components/ProfileManagement.tsx | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx index 543609f..67f0645 100644 --- a/src/components/ProfileManagement.tsx +++ b/src/components/ProfileManagement.tsx @@ -10,7 +10,8 @@ import { DialogButton, ButtonItem, ModalRoot, - TextField + TextField, + Focusable } from "@decky/ui"; import { getProfiles, @@ -50,8 +51,10 @@ function TextInputModal({ const [value, setValue] = useState(defaultValue); const handleOK = () => { - onOK(value); - closeModal?.(); + if (value.trim()) { + onOK(value); + closeModal?.(); + } }; return ( @@ -74,14 +77,25 @@ function TextInputModal({
-
+ {cancelText} - + {okText} -
+
); -- cgit v1.2.3 From 1baac4d3bb0a036e4cc19319ca881ca39ce09250 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 16 Aug 2025 19:33:47 -0400 Subject: add conf preservation logic, edge case handling if we add params down the line --- src/components/ConfigurationSection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/components/ConfigurationSection.tsx b/src/components/ConfigurationSection.tsx index 466a982..92d1867 100644 --- a/src/components/ConfigurationSection.tsx +++ b/src/components/ConfigurationSection.tsx @@ -4,7 +4,7 @@ import { RiArrowDownSFill, RiArrowUpSFill } from "react-icons/ri"; import { ConfigurationData } from "../config/configSchema"; import { FpsMultiplierControl } from "./FpsMultiplierControl"; import { - NO_FP16, FLOW_SCALE, PERFORMANCE_MODE, HDR_MODE, + FLOW_SCALE, PERFORMANCE_MODE, HDR_MODE, EXPERIMENTAL_PRESENT_MODE, DXVK_FRAME_RATE, DISABLE_STEAMDECK_MODE, MANGOHUD_WORKAROUND, DISABLE_VKBASALT, FORCE_ENABLE_VKBASALT, ENABLE_WSI } from "../config/generatedConfigSchema"; -- cgit v1.2.3