diff --git a/android/backend/config/src/main/java/io/clawdroid/backend/config/ConfigSectionDetailScreen.kt b/android/backend/config/src/main/java/io/clawdroid/backend/config/ConfigSectionDetailScreen.kt index fae63f958..727008695 100644 --- a/android/backend/config/src/main/java/io/clawdroid/backend/config/ConfigSectionDetailScreen.kt +++ b/android/backend/config/src/main/java/io/clawdroid/backend/config/ConfigSectionDetailScreen.kt @@ -201,7 +201,7 @@ private fun ConfigField( "float" -> NumberField(field, onValueChanged, KeyboardType.Decimal) "[]string" -> StringArrayField(field, onValueChanged) "directory" -> DirectoryField(field, onValueChanged, snackbarHostState) - "map", "[]any" -> ReadOnlyField(field) + "map", "[]any" -> JsonField(field, onValueChanged) else -> StringField(field, onValueChanged) } } @@ -296,13 +296,26 @@ private fun StringArrayField(field: FieldState, onValueChanged: (String) -> Unit } @Composable -private fun ReadOnlyField(field: FieldState) { +private fun JsonField(field: FieldState, onValueChanged: (String) -> Unit) { + val jsonError = remember(field.value) { + if (field.value.isBlank()) null + else try { + kotlinx.serialization.json.Json.parseToJsonElement(field.value); null + } catch (e: Exception) { + e.message + } + } + OutlinedTextField( - value = field.value.ifEmpty { "(complex value)" }, - onValueChange = {}, + value = field.value, + onValueChange = onValueChanged, label = { Text(field.label, color = TextSecondary) }, - readOnly = true, - enabled = false, + singleLine = false, + minLines = 3, + isError = jsonError != null, + supportingText = if (jsonError != null) { + { Text(jsonError, color = MaterialTheme.colorScheme.error) } + } else null, colors = configFieldColors(), modifier = Modifier.fillMaxWidth(), ) diff --git a/android/backend/config/src/main/java/io/clawdroid/backend/config/ConfigViewModel.kt b/android/backend/config/src/main/java/io/clawdroid/backend/config/ConfigViewModel.kt index fdae7f138..c5c13786c 100644 --- a/android/backend/config/src/main/java/io/clawdroid/backend/config/ConfigViewModel.kt +++ b/android/backend/config/src/main/java/io/clawdroid/backend/config/ConfigViewModel.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonNull @@ -29,6 +30,7 @@ class ConfigViewModel(private val apiClient: ConfigApiClient) : ViewModel() { private var configValues: JsonObject? = null private var saveJob: Job? = null private var pendingSectionKey: String? = null + private val prettyJson = Json { prettyPrint = true } init { loadData() @@ -193,6 +195,7 @@ class ConfigViewModel(private val apiClient: ConfigApiClient) : ViewModel() { element.map { it.jsonPrimitive.contentOrNull ?: "" }.joinToString(", ") } else "" } + "map", "[]any" -> prettyJson.encodeToString(JsonElement.serializer(), element) else -> (element as? JsonPrimitive)?.contentOrNull ?: element.toString() } } @@ -232,6 +235,7 @@ class ConfigViewModel(private val apiClient: ConfigApiClient) : ViewModel() { .filter { it.isNotEmpty() } .map { JsonPrimitive(it) } ) + "map", "[]any" -> prettyJson.parseToJsonElement(field.value) else -> JsonPrimitive(field.value) } }