mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2025-12-24 01:44:23 +01:00
Apply fixes to UART profile
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package no.nordicsemi.android.uart.data
|
||||
|
||||
data class UARTMacro(
|
||||
val alias: String,
|
||||
val command: String,
|
||||
)
|
||||
data class UARTMacro(val command: String, val newLineChar: NewLineChar)
|
||||
|
||||
enum class NewLineChar {
|
||||
LF, CR_LF, CR
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ import no.nordicsemi.android.ble.common.callback.battery.BatteryLevelResponse
|
||||
import no.nordicsemi.android.ble.ktx.asFlow
|
||||
import no.nordicsemi.android.ble.ktx.asValidResponseFlow
|
||||
import no.nordicsemi.android.service.ConnectionObserverAdapter
|
||||
import no.nordicsemi.android.uart.data.UARTData
|
||||
import no.nordicsemi.android.utils.EMPTY
|
||||
import no.nordicsemi.android.utils.launchWithCatch
|
||||
import java.util.*
|
||||
@@ -76,7 +75,7 @@ internal class UARTManager(
|
||||
override fun initialize() {
|
||||
setNotificationCallback(txCharacteristic).asFlow().onEach {
|
||||
val text: String = it.getStringValue(0) ?: String.EMPTY
|
||||
data.tryEmit(data.value.copy(text = text))
|
||||
data.value = data.value.copy(text = text)
|
||||
}
|
||||
|
||||
requestMtu(260).enqueue()
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package no.nordicsemi.android.uart.data
|
||||
|
||||
fun NewLineChar.parseString(text: String): String {
|
||||
return when (this) {
|
||||
NewLineChar.LF -> text
|
||||
NewLineChar.CR_LF -> text.replace("\n", "\r\n")
|
||||
NewLineChar.CR -> text.replace("\n", "\r")
|
||||
}
|
||||
}
|
||||
@@ -1,63 +1,124 @@
|
||||
package no.nordicsemi.android.uart.view
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import no.nordicsemi.android.material.you.HorizontalLabelRadioButtonGroup
|
||||
import no.nordicsemi.android.material.you.RadioButtonItem
|
||||
import no.nordicsemi.android.material.you.RadioGroupViewEntity
|
||||
import no.nordicsemi.android.material.you.TextField
|
||||
import no.nordicsemi.android.uart.R
|
||||
import no.nordicsemi.android.uart.data.NewLineChar
|
||||
import no.nordicsemi.android.uart.data.UARTMacro
|
||||
import no.nordicsemi.android.utils.EMPTY
|
||||
|
||||
@Composable
|
||||
internal fun UARTAddMacroDialog(onDismiss: () -> Unit, onEvent: (UARTViewEvent) -> Unit) {
|
||||
val alias = remember { mutableStateOf(String.EMPTY) }
|
||||
val command = remember { mutableStateOf(String.EMPTY) }
|
||||
val newLineChar = remember { mutableStateOf(NewLineChar.LF) }
|
||||
val isError = remember { mutableStateOf(false) }
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
title = {
|
||||
Text(text = stringResource(id = R.string.uart_macro_dialog_title))
|
||||
},
|
||||
text = {
|
||||
Dialog(onDismissRequest = { onDismiss() }) {
|
||||
Surface(
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
shadowElevation = 0.dp,
|
||||
) {
|
||||
Column {
|
||||
TextField(text = alias.value, hint = stringResource(id = R.string.uart_macro_dialog_alias)) {
|
||||
alias.value = it
|
||||
}
|
||||
Text(
|
||||
text = stringResource(id = R.string.uart_macro_dialog_title),
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
|
||||
Column(modifier = Modifier.padding(bottom = 8.dp, start = 16.dp, end = 16.dp)) {
|
||||
|
||||
TextField(text = command.value, hint = stringResource(id = R.string.uart_macro_dialog_command)) {
|
||||
command.value = it
|
||||
NewLineCharSection(newLineChar.value) { newLineChar.value = it }
|
||||
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
|
||||
TextField(
|
||||
text = command.value,
|
||||
hint = stringResource(id = R.string.uart_macro_dialog_command)
|
||||
) {
|
||||
isError.value = false
|
||||
command.value = it
|
||||
}
|
||||
|
||||
if (isError.value) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.uart_macro_error),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.End
|
||||
) {
|
||||
TextButton(onClick = { onDismiss() }) {
|
||||
Text(stringResource(id = R.string.uart_macro_dialog_dismiss))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
|
||||
TextButton(onClick = {
|
||||
if (isCommandValid(command.value)) {
|
||||
onDismiss()
|
||||
onEvent(OnCreateMacro(UARTMacro(command.value, newLineChar.value)))
|
||||
} else {
|
||||
isError.value = true
|
||||
}
|
||||
}) {
|
||||
Text(stringResource(id = R.string.uart_macro_dialog_confirm))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
onDismiss()
|
||||
onEvent(OnCreateMacro(UARTMacro(alias.value, command.value)))
|
||||
}
|
||||
) {
|
||||
Text(stringResource(id = R.string.uart_macro_dialog_confirm))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(
|
||||
onClick = { onDismiss() }
|
||||
) {
|
||||
Text(stringResource(id = R.string.uart_macro_dialog_dismiss))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NewLineCharSection(checkedItem: NewLineChar, onItemClick: (NewLineChar) -> Unit) {
|
||||
val items = NewLineChar.values().map {
|
||||
RadioButtonItem(it.toDisplayString(), it == checkedItem)
|
||||
}
|
||||
val viewEntity = RadioGroupViewEntity(items)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.uart_macro_dialog_eol),
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
|
||||
HorizontalLabelRadioButtonGroup(viewEntity) {
|
||||
val i = items.indexOf(it)
|
||||
onItemClick(NewLineChar.values()[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isCommandValid(command: String): Boolean {
|
||||
return command.isNotBlank()
|
||||
}
|
||||
|
||||
@@ -26,15 +26,13 @@ internal fun UARTContentView(state: UARTData, macros: List<UARTMacro>, onEvent:
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
InputSection(macros, onEvent)
|
||||
OutputSection(state.text)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
if (state.text.isNotEmpty()) {
|
||||
OutputSection(state.text)
|
||||
InputSection(macros, onEvent)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
}
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Button(
|
||||
onClick = { onEvent(DisconnectEvent) }
|
||||
@@ -94,7 +92,7 @@ private fun OutputSection(text: String) {
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Text(text = text)
|
||||
Text(text = text.ifBlank { stringResource(id = R.string.uart_output_placeholder) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package no.nordicsemi.android.uart.view
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import no.nordicsemi.android.uart.R
|
||||
import no.nordicsemi.android.uart.data.NewLineChar
|
||||
|
||||
@Composable
|
||||
fun NewLineChar.toDisplayString(): String {
|
||||
return when (this) {
|
||||
NewLineChar.LF -> stringResource(id = R.string.uart_macro_dialog_lf)
|
||||
NewLineChar.CR_LF -> stringResource(id = R.string.uart_macro_dialog_cr_lf)
|
||||
NewLineChar.CR -> stringResource(id = R.string.uart_macro_dialog_cr)
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,7 @@
|
||||
package no.nordicsemi.android.uart.view
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
@@ -42,11 +37,11 @@ internal fun MacroItem(macro: UARTMacro, onEvent: (UARTViewEvent) -> Unit) {
|
||||
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Column(modifier = Modifier.weight(1f).padding(vertical = 8.dp)) {
|
||||
Text(
|
||||
text = macro.alias,
|
||||
text = stringResource(id = R.string.uart_macro_dialog_selected_eol, macro.newLineChar.toDisplayString()),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.uart_command_field, macro.command),
|
||||
|
||||
@@ -20,4 +20,13 @@
|
||||
<string name="uart_macro_dialog_command">Command</string>
|
||||
<string name="uart_macro_dialog_confirm">Confirm</string>
|
||||
<string name="uart_macro_dialog_dismiss">Dismiss</string>
|
||||
|
||||
<string name="uart_macro_dialog_eol">EOL:</string>
|
||||
<string name="uart_macro_dialog_selected_eol">EOL: %s</string>
|
||||
<string name="uart_macro_dialog_lf">LF</string>
|
||||
<string name="uart_macro_dialog_cr_lf">CR + LF</string>
|
||||
<string name="uart_macro_dialog_cr">CR</string>
|
||||
|
||||
<string name="uart_output_placeholder">The incoming messages will be displayed here.</string>
|
||||
<string name="uart_macro_error">Provided command cannot be empty.</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user