diff --git a/app/src/main/java/sh/sar/isodroid/ui/components/CreateImgDialog.kt b/app/src/main/java/sh/sar/isodroid/ui/components/CreateImgDialog.kt index 835d741..0864315 100644 --- a/app/src/main/java/sh/sar/isodroid/ui/components/CreateImgDialog.kt +++ b/app/src/main/java/sh/sar/isodroid/ui/components/CreateImgDialog.kt @@ -76,9 +76,10 @@ fun CreateImgDialog( val fullFileName = if (fileName.isNotBlank()) "$fileName.img" else "" val fileExists = fullFileName.isNotEmpty() && existingFiles.contains(fullFileName) + val hasInvalidChars = fileName.any { !it.isLetterOrDigit() && it !in "-_. ()[]+," } val isValidInput = fileName.isNotBlank() && - !fileName.contains("/") && + !hasInvalidChars && sizeValue.toLongOrNull()?.let { it > 0 } == true && !fileExists @@ -135,11 +136,11 @@ fun CreateImgDialog( // File name input OutlinedTextField( value = fileName, - onValueChange = { fileName = it.replace("/", "") }, + onValueChange = { fileName = it }, label = { Text("File Name") }, suffix = { Text(".img") }, singleLine = true, - isError = fileExists, + isError = fileExists || hasInvalidChars, modifier = Modifier.fillMaxWidth() ) @@ -153,6 +154,16 @@ fun CreateImgDialog( ) } + // Show error if invalid characters + if (hasInvalidChars) { + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = "Invalid file name", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.error + ) + } + Spacer(modifier = Modifier.height(16.dp)) // Size input diff --git a/app/src/main/java/sh/sar/isodroid/ui/components/FileContextMenu.kt b/app/src/main/java/sh/sar/isodroid/ui/components/FileContextMenu.kt index 065ab9f..88a1152 100644 --- a/app/src/main/java/sh/sar/isodroid/ui/components/FileContextMenu.kt +++ b/app/src/main/java/sh/sar/isodroid/ui/components/FileContextMenu.kt @@ -170,7 +170,8 @@ private fun RenameDialog( val nameWithoutExtension = currentName.removeSuffix(extension) var newName by remember { mutableStateOf(nameWithoutExtension) } - val isValid = newName.isNotBlank() && !newName.contains("/") + val hasInvalidChars = newName.any { !it.isLetterOrDigit() && it !in "-_. ()[]+," } + val isValid = newName.isNotBlank() && !hasInvalidChars AlertDialog( onDismissRequest = onDismiss, @@ -179,12 +180,22 @@ private fun RenameDialog( Column { OutlinedTextField( value = newName, - onValueChange = { newName = it.replace("/", "") }, + onValueChange = { newName = it }, label = { Text("File Name") }, suffix = { Text(extension) }, singleLine = true, + isError = hasInvalidChars, modifier = Modifier.fillMaxWidth() ) + + if (hasInvalidChars) { + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = "Invalid file name", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.error + ) + } } }, confirmButton = { diff --git a/app/src/main/java/sh/sar/isodroid/ui/screens/SettingsScreen.kt b/app/src/main/java/sh/sar/isodroid/ui/screens/SettingsScreen.kt index 8207a00..3557910 100644 --- a/app/src/main/java/sh/sar/isodroid/ui/screens/SettingsScreen.kt +++ b/app/src/main/java/sh/sar/isodroid/ui/screens/SettingsScreen.kt @@ -489,6 +489,7 @@ private fun DirectoryBrowserDialog( scope.launch { val trimmedName = name.trim() if (trimmedName.isEmpty()) return@launch + val newPath = "$currentPath/$trimmedName" RootManager.executeCommand("mkdir -p \"$newPath\"") // Create marker file to indicate this folder was created by the app @@ -716,6 +717,9 @@ private fun DirectoryBrowserDialog( // Create folder dialog if (showCreateFolderDialog) { + val hasInvalidChars = newFolderName.any { !it.isLetterOrDigit() && it !in "-_. ()[]+," } + val isValidInput = newFolderName.isNotBlank() && !hasInvalidChars + AlertDialog( onDismissRequest = { showCreateFolderDialog = false @@ -723,24 +727,36 @@ private fun DirectoryBrowserDialog( }, title = { Text("Create Directory") }, text = { - OutlinedTextField( - value = newFolderName, - onValueChange = { newFolderName = it }, - label = { Text("Directory name") }, - singleLine = true, - modifier = Modifier.fillMaxWidth() - ) + Column { + OutlinedTextField( + value = newFolderName, + onValueChange = { newFolderName = it }, + label = { Text("Directory name") }, + singleLine = true, + isError = hasInvalidChars, + modifier = Modifier.fillMaxWidth() + ) + + if (hasInvalidChars) { + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = "Invalid directory name", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.error + ) + } + } }, confirmButton = { TextButton( onClick = { - if (newFolderName.isNotBlank()) { + if (isValidInput) { createFolder(newFolderName) showCreateFolderDialog = false newFolderName = "" } }, - enabled = newFolderName.isNotBlank() + enabled = isValidInput ) { Text("Create") }