Apply fixes to UART profile

This commit is contained in:
Sylwester Zieliński
2022-02-17 11:00:33 +01:00
parent faef3720ad
commit 7b1b91e5da
8 changed files with 144 additions and 57 deletions

View File

@@ -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
}

View File

@@ -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()

View File

@@ -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")
}
}

View File

@@ -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()
}

View File

@@ -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) })
}
}
}

View File

@@ -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)
}
}

View File

@@ -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),

View File

@@ -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>