diff options
| author | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2025-12-06 23:40:32 -0500 |
|---|---|---|
| committer | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2025-12-06 23:40:32 -0500 |
| commit | a4b6f610ca0d2cf73ccbc40c5d9d5b1cc9c629b9 (patch) | |
| tree | d2bc9dc5838ff2f8d8032c12c6cb7ba927155589 | |
| parent | 56c493184fc3960e3b33aa789fad618962c339ae (diff) | |
| download | decky-lsfg-vk-a4b6f610ca0d2cf73ccbc40c5d9d5b1cc9c629b9.tar.gz decky-lsfg-vk-a4b6f610ca0d2cf73ccbc40c5d9d5b1cc9c629b9.zip | |
fix: normalize spaces in profile names w dashes for conf requirements, display actual in FE
| -rw-r--r-- | py_modules/lsfg_vk/config_schema.py | 49 | ||||
| -rw-r--r-- | py_modules/lsfg_vk/configuration.py | 28 | ||||
| -rw-r--r-- | src/components/ProfileManagement.tsx | 16 | ||||
| -rw-r--r-- | src/hooks/useProfileManagement.ts | 10 |
4 files changed, 80 insertions, 23 deletions
diff --git a/py_modules/lsfg_vk/config_schema.py b/py_modules/lsfg_vk/config_schema.py index 3a96401..4ab2dcb 100644 --- a/py_modules/lsfg_vk/config_schema.py +++ b/py_modules/lsfg_vk/config_schema.py @@ -454,19 +454,54 @@ class ConfigurationManager: return create_config_dict(**kwargs) @staticmethod + def normalize_profile_name(profile_name: str) -> str: + """Normalize profile name by converting spaces to dashes and trimming + + This allows users to enter names with spaces, which are then safely + converted to dashes for storage and shell script compatibility. + + Args: + profile_name: The raw profile name from user input + + Returns: + Normalized profile name with spaces converted to dashes + """ + if not profile_name: + return profile_name + + # Trim whitespace and convert spaces to dashes + normalized = profile_name.strip().replace(' ', '-') + + # Collapse multiple consecutive dashes into one + while '--' in normalized: + normalized = normalized.replace('--', '-') + + # Remove leading/trailing dashes + normalized = normalized.strip('-') + + return normalized + + @staticmethod def validate_profile_name(profile_name: str) -> bool: - """Validate profile name for safety""" + """Validate profile name for safety (after normalization)""" if not profile_name: return False + # Normalize first - this converts spaces to dashes + normalized = ConfigurationManager.normalize_profile_name(profile_name) + + if not normalized: + return False + # Check for invalid characters that could cause issues in shell scripts or TOML - invalid_chars = set(' \t\n\r\'"\\/$|&;()<>{}[]`*?') - if any(char in invalid_chars for char in profile_name): + # Note: spaces are now allowed as input (they get converted to dashes) + invalid_chars = set('\t\n\r\'"\\/$|&;()<>{}[]`*?') + if any(char in invalid_chars for char in normalized): return False # Check for reserved names reserved_names = {'global', 'game', 'current_profile'} - if profile_name.lower() in reserved_names: + if normalized.lower() in reserved_names: return False return True @@ -477,6 +512,9 @@ class ConfigurationManager: if not ConfigurationManager.validate_profile_name(profile_name): raise ValueError(f"Invalid profile name: {profile_name}") + # Normalize the profile name (converts spaces to dashes) + profile_name = ConfigurationManager.normalize_profile_name(profile_name) + if profile_name in profile_data["profiles"]: raise ValueError(f"Profile '{profile_name}' already exists") @@ -533,6 +571,9 @@ class ConfigurationManager: if not ConfigurationManager.validate_profile_name(new_name): raise ValueError(f"Invalid profile name: {new_name}") + # Normalize the new name (converts spaces to dashes) + new_name = ConfigurationManager.normalize_profile_name(new_name) + if old_name not in profile_data["profiles"]: raise ValueError(f"Profile '{old_name}' does not exist") diff --git a/py_modules/lsfg_vk/configuration.py b/py_modules/lsfg_vk/configuration.py index 9f8b028..74a3694 100644 --- a/py_modules/lsfg_vk/configuration.py +++ b/py_modules/lsfg_vk/configuration.py @@ -235,11 +235,11 @@ class ConfigurationService(BaseService): """Create a new profile Args: - profile_name: Name for the new profile + profile_name: Name for the new profile (spaces will be converted to dashes) source_profile: Optional source profile to copy from (default: current profile) Returns: - ProfileResponse with success status + ProfileResponse with success status and the normalized profile name """ try: profile_data = self._get_profile_data() @@ -247,15 +247,19 @@ class ConfigurationService(BaseService): if not source_profile: source_profile = profile_data["current_profile"] + # Get the normalized name that will be used for storage + normalized_name = ConfigurationManager.normalize_profile_name(profile_name) + new_profile_data = ConfigurationManager.create_profile(profile_data, profile_name, source_profile) self._save_profile_data(new_profile_data) - self.log.info(f"Created profile '{profile_name}' from '{source_profile}'") + self.log.info(f"Created profile '{normalized_name}' from '{source_profile}'") + # Return the normalized name so frontend can use the actual stored name return self._success_response(ProfileResponse, - f"Profile '{profile_name}' created successfully", - profile_name=profile_name) + f"Profile '{normalized_name}' created successfully", + profile_name=normalized_name) except ValueError as e: error_msg = f"Invalid profile operation: {str(e)}" @@ -306,14 +310,17 @@ class ConfigurationService(BaseService): Args: old_name: Current profile name - new_name: New profile name + new_name: New profile name (spaces will be converted to dashes) Returns: - ProfileResponse with success status + ProfileResponse with success status and the normalized profile name """ try: profile_data = self._get_profile_data() + # Get the normalized name that will be used for storage + normalized_name = ConfigurationManager.normalize_profile_name(new_name) + new_profile_data = ConfigurationManager.rename_profile(profile_data, old_name, new_name) self._save_profile_data(new_profile_data) @@ -322,11 +329,12 @@ class ConfigurationService(BaseService): if not script_result["success"]: self.log.warning(f"Failed to update launch script: {script_result['error']}") - self.log.info(f"Renamed profile '{old_name}' to '{new_name}'") + self.log.info(f"Renamed profile '{old_name}' to '{normalized_name}'") + # Return the normalized name so frontend can use the actual stored name return self._success_response(ProfileResponse, - f"Profile renamed from '{old_name}' to '{new_name}' successfully", - profile_name=new_name) + f"Profile renamed from '{old_name}' to '{normalized_name}' successfully", + profile_name=normalized_name) except ValueError as e: error_msg = f"Invalid profile operation: {str(e)}" diff --git a/src/components/ProfileManagement.tsx b/src/components/ProfileManagement.tsx index 62160d9..73a40c7 100644 --- a/src/components/ProfileManagement.tsx +++ b/src/components/ProfileManagement.tsx @@ -217,10 +217,12 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa try { const result: ProfileResult = await createProfile(profileName, selectedProfile); if (result.success) { - showSuccessToast("Profile created", `Created profile: ${profileName}`); + // 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 - await handleProfileChange(profileName); + // 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"); @@ -307,10 +309,12 @@ export function ProfileManagement({ currentProfile, onProfileChange }: ProfileMa try { const result: ProfileResult = await renameProfile(selectedProfile, newName); if (result.success) { - showSuccessToast("Profile renamed", `Renamed profile to: ${newName}`); + // 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(newName); - onProfileChange?.(newName); + setSelectedProfile(actualNewName); + onProfileChange?.(actualNewName); } else { console.error("Failed to rename profile:", result.error); showErrorToast("Failed to rename profile", result.error || "Unknown error"); diff --git a/src/hooks/useProfileManagement.ts b/src/hooks/useProfileManagement.ts index 4b10f0e..a5f2a07 100644 --- a/src/hooks/useProfileManagement.ts +++ b/src/hooks/useProfileManagement.ts @@ -46,7 +46,9 @@ export function useProfileManagement() { try { const result: ProfileResult = await createProfile(profileName, sourceProfile || currentProfile); if (result.success) { - showSuccessToast("Profile created", `Created profile: ${profileName}`); + // 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(); return result; } else { @@ -106,11 +108,13 @@ export function useProfileManagement() { try { const result: ProfileResult = await renameProfile(oldName, newName); if (result.success) { - showSuccessToast("Profile renamed", `Renamed profile to: ${newName}`); + // 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(); // Update current profile if it was renamed if (currentProfile === oldName) { - setCurrentProfileState(newName); + setCurrentProfileState(actualNewName); } return result; } else { |
