mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2026-02-04 14:24:26 +01:00
Add database migrtion to UART to support configuration from previous version
This commit is contained in:
@@ -4,7 +4,7 @@ apply plugin: 'com.google.protobuf'
|
||||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = 'com.google.protobuf:protoc:3.14.0'
|
||||
artifact = 'com.google.protobuf:protoc:3.14.0:osx-x86_64'
|
||||
}
|
||||
|
||||
// Generates the java Protobuf-lite code for the Protobufs in this project. See
|
||||
@@ -27,6 +27,10 @@ dependencies {
|
||||
implementation project(":lib_theme")
|
||||
implementation project(":lib_utils")
|
||||
|
||||
implementation libs.room.runtime
|
||||
implementation libs.room.ktx
|
||||
kapt libs.room.compiler
|
||||
|
||||
implementation libs.nordic.ble.common
|
||||
implementation libs.nordic.ble.ktx
|
||||
|
||||
@@ -45,4 +49,9 @@ dependencies {
|
||||
implementation libs.compose.activity
|
||||
|
||||
testImplementation libs.bundles.test
|
||||
|
||||
implementation('org.simpleframework:simple-xml:2.7.1') {
|
||||
exclude group: 'stax', module: 'stax-api'
|
||||
exclude group: 'xpp3', module: 'xpp3'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package no.nordicsemi.android.uart
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import no.nordicsemi.android.uart.db.ConfigurationsDao
|
||||
import no.nordicsemi.android.uart.db.ConfigurationsDatabase
|
||||
import no.nordicsemi.android.uart.db.MIGRATION_1_2
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class HiltModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
internal fun provideDB(@ApplicationContext context: Context): ConfigurationsDatabase {
|
||||
return Room.databaseBuilder(
|
||||
context,
|
||||
ConfigurationsDatabase::class.java, "toolbox_uart.db"
|
||||
).addMigrations(MIGRATION_1_2).build()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
internal fun provideDao(db: ConfigurationsDatabase): ConfigurationsDao {
|
||||
return db.dao()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package no.nordicsemi.android.uart.data
|
||||
|
||||
enum class MacroEol(val eolIndex: Int) {
|
||||
LF(0),
|
||||
CR(1),
|
||||
CR_LF(2);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package no.nordicsemi.android.uart.data
|
||||
|
||||
enum class MacroIcon(val index: Int) {
|
||||
LEFT(0),
|
||||
UP(1),
|
||||
RIGHT(2),
|
||||
DOWN(3),
|
||||
SETTINGS(4),
|
||||
REW(5),
|
||||
PLAY(6),
|
||||
PAUSE(7),
|
||||
STOP(8),
|
||||
FWD(9),
|
||||
INFO(10),
|
||||
NUMBER_1(11),
|
||||
NUMBER_2(12),
|
||||
NUMBER_3(13),
|
||||
NUMBER_4(14),
|
||||
NUMBER_5(15),
|
||||
NUMBER_6(16),
|
||||
NUMBER_7(17),
|
||||
NUMBER_8(18),
|
||||
NUMBER_9(19);
|
||||
|
||||
companion object {
|
||||
fun create(index: Int): MacroIcon {
|
||||
return values().firstOrNull { it.index == index }
|
||||
?: throw IllegalArgumentException("Cannot create MacroIcon for index: $index")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package no.nordicsemi.android.uart.data
|
||||
|
||||
data class UARTConfiguration(
|
||||
val name: String,
|
||||
val macros: List<UARTMacro>
|
||||
)
|
||||
@@ -1,7 +1,3 @@
|
||||
package no.nordicsemi.android.uart.data
|
||||
|
||||
data class UARTMacro(val command: String, val newLineChar: NewLineChar)
|
||||
|
||||
enum class NewLineChar {
|
||||
LF, CR_LF, CR
|
||||
}
|
||||
data class UARTMacro(val icon: MacroIcon, val command: String, val newLineChar: MacroEol)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package no.nordicsemi.android.uart.data
|
||||
|
||||
fun String.parseWithNewLineChar(newLineChar: NewLineChar): String {
|
||||
fun String.parseWithNewLineChar(newLineChar: MacroEol): String {
|
||||
return when (newLineChar) {
|
||||
NewLineChar.LF -> this
|
||||
NewLineChar.CR_LF -> this.replace("\n", "\r\n")
|
||||
NewLineChar.CR -> this.replace("\n", "\r")
|
||||
MacroEol.LF -> this
|
||||
MacroEol.CR_LF -> this.replace("\n", "\r\n")
|
||||
MacroEol.CR -> this.replace("\n", "\r")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +1,51 @@
|
||||
package no.nordicsemi.android.uart.data
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.dataStore
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import no.nordicsemi.android.Macro
|
||||
import no.nordicsemi.android.MacroSettings
|
||||
import no.nordicsemi.android.uart.db.*
|
||||
import org.simpleframework.xml.Serializer
|
||||
import org.simpleframework.xml.core.Persister
|
||||
import org.simpleframework.xml.strategy.Strategy
|
||||
import org.simpleframework.xml.strategy.VisitorStrategy
|
||||
import org.simpleframework.xml.stream.Format
|
||||
import org.simpleframework.xml.stream.HyphenStyle
|
||||
import java.io.StringWriter
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
private const val MACRO_FILE = "macro.proto"
|
||||
|
||||
@Singleton
|
||||
internal class UARTPersistentDataSource @Inject constructor(
|
||||
@ApplicationContext
|
||||
private val context: Context
|
||||
private val configurationsDao: ConfigurationsDao,
|
||||
) {
|
||||
private val Context.dataStore: DataStore<MacroSettings> by dataStore(fileName = MACRO_FILE, MacroSerializer)
|
||||
|
||||
val macros = context.dataStore.data.map {
|
||||
it.macrosList.map {
|
||||
UARTMacro(it.name, it.newLineType.toNewLineChar())
|
||||
fun getConfigurations(): Flow<List<UARTConfiguration>> = configurationsDao.load().map {
|
||||
it.map {
|
||||
val xml: String = it.xml
|
||||
val format = Format(HyphenStyle())
|
||||
val serializer: Serializer = Persister(format)
|
||||
val configuration = serializer.read(XmlConfiguration::class.java, xml)
|
||||
|
||||
UARTConfiguration(configuration.name ?: "Unknown", createMacro(configuration.commands))
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun saveMacros(uartMacros: List<UARTMacro>) {
|
||||
context.dataStore.updateData { settings ->
|
||||
val macros = uartMacros.map { it.toMacro() }
|
||||
settings.toBuilder()
|
||||
.clearMacros()
|
||||
.addAllMacros(macros)
|
||||
.build()
|
||||
private fun createMacro(macros: Array<XmlCommand?>): List<UARTMacro> {
|
||||
return macros.filterNotNull().mapNotNull {
|
||||
val icon = MacroIcon.create(it.iconIndex)
|
||||
it.command?.let { c -> UARTMacro(icon, c, it.eol) }
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun addNewMacro(uartMacro: UARTMacro) {
|
||||
context.dataStore.updateData { settings ->
|
||||
settings.toBuilder()
|
||||
.addMacros(uartMacro.toMacro())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
suspend fun saveConfiguration(configuration: UARTConfiguration) {
|
||||
val format = Format(HyphenStyle())
|
||||
val strategy: Strategy = VisitorStrategy(CommentVisitor())
|
||||
val serializer: Serializer = Persister(strategy, format)
|
||||
val writer = StringWriter()
|
||||
serializer.write(configuration, writer)
|
||||
val xml = writer.toString()
|
||||
|
||||
suspend fun deleteMacro(uartMacro: UARTMacro) {
|
||||
context.dataStore.updateData { settings ->
|
||||
val i = settings.macrosList.map { it.name }.indexOf(uartMacro.command)
|
||||
settings.toBuilder()
|
||||
.removeMacros(i)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
private fun UARTMacro.toMacro(): Macro {
|
||||
return Macro.newBuilder()
|
||||
.setName(command)
|
||||
.setNewLineType(newLineChar.toMacroNewLineType())
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun NewLineChar.toMacroNewLineType(): Macro.NewLineType {
|
||||
return when (this) {
|
||||
NewLineChar.LF -> Macro.NewLineType.LF
|
||||
NewLineChar.CR_LF -> Macro.NewLineType.LF_CR
|
||||
NewLineChar.CR -> Macro.NewLineType.CR
|
||||
}
|
||||
}
|
||||
|
||||
private fun Macro.NewLineType.toNewLineChar(): NewLineChar {
|
||||
return when (this) {
|
||||
Macro.NewLineType.LF -> NewLineChar.LF
|
||||
Macro.NewLineType.LF_CR -> NewLineChar.CR_LF
|
||||
Macro.NewLineType.CR -> NewLineChar.CR
|
||||
Macro.NewLineType.UNRECOGNIZED -> throw IllegalArgumentException("Unrecognized NewLineChar.")
|
||||
}
|
||||
configurationsDao.insert(Configuration(0, configuration.name, xml, 0))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package no.nordicsemi.android.uart.db
|
||||
|
||||
import no.nordicsemi.android.uart.data.MacroIcon
|
||||
import org.simpleframework.xml.strategy.Type
|
||||
import org.simpleframework.xml.strategy.Visitor
|
||||
import org.simpleframework.xml.stream.InputNode
|
||||
import org.simpleframework.xml.stream.NodeMap
|
||||
import org.simpleframework.xml.stream.OutputNode
|
||||
|
||||
/**
|
||||
* The comment visitor will add comments to the XML during saving.
|
||||
*/
|
||||
internal class CommentVisitor : Visitor {
|
||||
override fun read(type: Type, node: NodeMap<InputNode>) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
override fun write(type: Type, node: NodeMap<OutputNode>) {
|
||||
if (type.type == Array<XmlCommand>::class.java) {
|
||||
val element = node.node
|
||||
val builder =
|
||||
StringBuilder("A configuration must have 9 commands, one for each button.\n Possible icons are:")
|
||||
for (icon in MacroIcon.values()) builder.append("\n - ")
|
||||
.append(icon.toString())
|
||||
element.comment = builder.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package no.nordicsemi.android.uart.db
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "configurations")
|
||||
internal data class Configuration(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ColumnInfo(name = "id") val id: Int,
|
||||
@ColumnInfo(name = "name") val name: String,
|
||||
@ColumnInfo(name = "xml") val xml: String,
|
||||
@ColumnInfo(name = "deleted") val deleted: Int
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
package no.nordicsemi.android.uart.db
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
internal interface ConfigurationsDao {
|
||||
|
||||
@Query("SELECT * FROM configurations")
|
||||
fun load(): Flow<List<Configuration>>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(configuration: Configuration)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package no.nordicsemi.android.uart.db
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
|
||||
@Database(entities = [Configuration::class], version = 2)
|
||||
internal abstract class ConfigurationsDatabase : RoomDatabase() {
|
||||
abstract fun dao(): ConfigurationsDao
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package no.nordicsemi.android.uart.db
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val MIGRATION_1_2 = object : Migration(1, 2) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// Empty implementation, because the schema isn't changing.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.uart.db
|
||||
|
||||
import no.nordicsemi.android.uart.data.MacroEol
|
||||
import no.nordicsemi.android.uart.data.MacroIcon
|
||||
import org.simpleframework.xml.Attribute
|
||||
import org.simpleframework.xml.Root
|
||||
import org.simpleframework.xml.Text
|
||||
|
||||
@Root
|
||||
internal class XmlCommand {
|
||||
|
||||
/**
|
||||
* Returns the command that will be sent to UART device.
|
||||
* @return the command
|
||||
*/
|
||||
/**
|
||||
* Sets the command.
|
||||
* @param command the command that will be sent to UART device
|
||||
*/
|
||||
@Text(required = false)
|
||||
var command: String? = null
|
||||
/**
|
||||
* Returns whether the icon is active.
|
||||
* @return true if it's active
|
||||
*/
|
||||
/**
|
||||
* Sets whether the command is active.
|
||||
* @param active true to make it active
|
||||
*/
|
||||
@Attribute(required = false)
|
||||
var isActive = false
|
||||
|
||||
/**
|
||||
* Returns the new line type.
|
||||
* @return end of line terminator
|
||||
*/
|
||||
@Attribute(required = false)
|
||||
var eol = MacroEol.LF
|
||||
private set
|
||||
|
||||
@Attribute(required = false)
|
||||
private var icon = MacroIcon.LEFT
|
||||
|
||||
/**
|
||||
* Sets the new line type.
|
||||
* @param eol end of line terminator
|
||||
*/
|
||||
fun setEol(eol: Int) {
|
||||
this.eol = MacroEol.values()[eol]
|
||||
}
|
||||
/**
|
||||
* Returns the icon index.
|
||||
* @return the icon index
|
||||
*/
|
||||
/**
|
||||
* Sets the icon index.
|
||||
* @param index index of the icon.
|
||||
*/
|
||||
var iconIndex: Int
|
||||
get() = icon.index
|
||||
set(index) {
|
||||
icon = MacroIcon.values()[index]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.uart.db
|
||||
|
||||
import org.simpleframework.xml.Attribute
|
||||
import org.simpleframework.xml.ElementArray
|
||||
import org.simpleframework.xml.Root
|
||||
import org.simpleframework.xml.core.PersistenceException
|
||||
import org.simpleframework.xml.core.Validate
|
||||
|
||||
@Root
|
||||
internal class XmlConfiguration {
|
||||
|
||||
@Attribute(required = false, empty = "Unnamed")
|
||||
var name: String? = null
|
||||
|
||||
@ElementArray
|
||||
val commands: Array<XmlCommand?> = arrayOfNulls(COMMANDS_COUNT)
|
||||
|
||||
@Validate
|
||||
@Throws(PersistenceException::class)
|
||||
private fun validate() {
|
||||
if (commands.size != COMMANDS_COUNT) throw PersistenceException("There must be always $COMMANDS_COUNT commands in a configuration.")
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val COMMANDS_COUNT = 9
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,20 @@ 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.RadioButtonGroup
|
||||
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.MacroEol
|
||||
import no.nordicsemi.android.uart.data.MacroIcon
|
||||
import no.nordicsemi.android.uart.data.UARTMacro
|
||||
import no.nordicsemi.android.utils.EMPTY
|
||||
|
||||
@Composable
|
||||
internal fun UARTAddMacroDialog(onDismiss: () -> Unit, onEvent: (UARTViewEvent) -> Unit) {
|
||||
val command = remember { mutableStateOf(String.EMPTY) }
|
||||
val newLineChar = remember { mutableStateOf(NewLineChar.LF) }
|
||||
val newLineChar = remember { mutableStateOf(MacroEol.LF) }
|
||||
val isError = remember { mutableStateOf(false) }
|
||||
|
||||
Dialog(onDismissRequest = { onDismiss() }) {
|
||||
@@ -84,7 +85,7 @@ internal fun UARTAddMacroDialog(onDismiss: () -> Unit, onEvent: (UARTViewEvent)
|
||||
TextButton(onClick = {
|
||||
if (isCommandValid(command.value)) {
|
||||
onDismiss()
|
||||
onEvent(OnCreateMacro(UARTMacro(command.value, newLineChar.value)))
|
||||
onEvent(OnCreateMacro(UARTMacro(MacroIcon.DOWN, command.value, newLineChar.value)))
|
||||
} else {
|
||||
isError.value = true
|
||||
}
|
||||
@@ -100,8 +101,8 @@ internal fun UARTAddMacroDialog(onDismiss: () -> Unit, onEvent: (UARTViewEvent)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NewLineCharSection(checkedItem: NewLineChar, onItemClick: (NewLineChar) -> Unit) {
|
||||
val items = NewLineChar.values().map {
|
||||
private fun NewLineCharSection(checkedItem: MacroEol, onItemClick: (MacroEol) -> Unit) {
|
||||
val items = MacroEol.values().map {
|
||||
RadioButtonItem(it.toDisplayString(), it == checkedItem)
|
||||
}
|
||||
val viewEntity = RadioGroupViewEntity(items)
|
||||
@@ -112,9 +113,9 @@ private fun NewLineCharSection(checkedItem: NewLineChar, onItemClick: (NewLineCh
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
|
||||
HorizontalLabelRadioButtonGroup(viewEntity) {
|
||||
RadioButtonGroup(viewEntity) {
|
||||
val i = items.indexOf(it)
|
||||
onItemClick(NewLineChar.values()[i])
|
||||
onItemClick(MacroEol.values()[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@ 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
|
||||
import no.nordicsemi.android.uart.data.MacroEol
|
||||
|
||||
@Composable
|
||||
fun NewLineChar.toDisplayString(): String {
|
||||
fun MacroEol.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)
|
||||
MacroEol.LF -> stringResource(id = R.string.uart_macro_dialog_lf)
|
||||
MacroEol.CR_LF -> stringResource(id = R.string.uart_macro_dialog_cr_lf)
|
||||
MacroEol.CR -> stringResource(id = R.string.uart_macro_dialog_cr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ fun UARTScreen() {
|
||||
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)
|
||||
is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp)
|
||||
is UnknownErrorResult -> DeviceDisconnectedView(Reason.UNKNOWN, navigateUp)
|
||||
is SuccessResult -> UARTContentView(state.uartManagerState.result.data, state.macros) { viewModel.onEvent(it) }
|
||||
is SuccessResult -> UARTContentView(state.uartManagerState.result.data, state.configuration) { viewModel.onEvent(it) }
|
||||
}
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package no.nordicsemi.android.uart.view
|
||||
|
||||
import no.nordicsemi.android.service.BleManagerResult
|
||||
import no.nordicsemi.android.uart.data.UARTConfiguration
|
||||
import no.nordicsemi.android.uart.data.UARTData
|
||||
import no.nordicsemi.android.uart.data.UARTMacro
|
||||
|
||||
internal data class UARTViewState(
|
||||
val macros: List<UARTMacro> = emptyList(),
|
||||
val configuration: List<UARTConfiguration> = emptyList(),
|
||||
val uartManagerState: HTSManagerState = NoDeviceState
|
||||
)
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ internal class UARTViewModel @Inject constructor(
|
||||
_state.value = _state.value.copy(uartManagerState = WorkingState(it))
|
||||
}.launchIn(viewModelScope)
|
||||
|
||||
dataSource.macros.onEach {
|
||||
_state.value = _state.value.copy(macros = it)
|
||||
dataSource.getConfigurations().onEach {
|
||||
_state.value = _state.value.copy(configuration = it)
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,11 @@ dependencyResolutionManagement {
|
||||
alias('google-permissions').to('com.google.accompanist:accompanist-permissions:0.20.0')
|
||||
alias('chart').to('com.github.PhilJay:MPAndroidChart:v3.1.0')
|
||||
|
||||
version('room', '2.4.1')
|
||||
alias('room-runtime').to('androidx.room', 'room-runtime').versionRef('room')
|
||||
alias('room-ktx').to('androidx.room', 'room-ktx').versionRef('room')
|
||||
alias('room-compiler').to('androidx.room', 'room-compiler').versionRef('room')
|
||||
|
||||
//-- Test ------------------------------------------------------------------------------
|
||||
alias('test-junit').to('junit:junit:4.13.2')
|
||||
alias('android-test-junit').to('androidx.test.ext:junit:1.1.3')
|
||||
|
||||
Reference in New Issue
Block a user