mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2025-12-21 16:34:23 +01:00
Improve GLS screen
This commit is contained in:
@@ -9,6 +9,7 @@ dependencies {
|
|||||||
implementation libs.chart
|
implementation libs.chart
|
||||||
|
|
||||||
implementation libs.nordic.ble.common
|
implementation libs.nordic.ble.common
|
||||||
|
implementation libs.nordic.theme
|
||||||
|
|
||||||
implementation libs.nordic.log
|
implementation libs.nordic.log
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,13 @@ package no.nordicsemi.android.gls.data
|
|||||||
internal data class GLSData(
|
internal data class GLSData(
|
||||||
val records: List<GLSRecord> = emptyList(),
|
val records: List<GLSRecord> = emptyList(),
|
||||||
val batteryLevel: Int = 0,
|
val batteryLevel: Int = 0,
|
||||||
val requestStatus: RequestStatus = RequestStatus.IDLE,
|
val requestStatus: RequestStatus = RequestStatus.IDLE
|
||||||
val selectedMode: WorkingMode = WorkingMode.ALL
|
|
||||||
)
|
)
|
||||||
|
|
||||||
internal enum class WorkingMode(val displayName: String) {
|
internal enum class WorkingMode {
|
||||||
ALL("All"),
|
ALL,
|
||||||
LAST("First"),
|
LAST,
|
||||||
FIRST("Last")
|
FIRST
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum class RequestStatus {
|
internal enum class RequestStatus {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package no.nordicsemi.android.gls.data
|
|||||||
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@@ -9,7 +10,7 @@ import javax.inject.Singleton
|
|||||||
internal class GLSDataHolder @Inject constructor() {
|
internal class GLSDataHolder @Inject constructor() {
|
||||||
|
|
||||||
private val _data = MutableStateFlow(GLSData())
|
private val _data = MutableStateFlow(GLSData())
|
||||||
val data: StateFlow<GLSData> = _data
|
val data: StateFlow<GLSData> = _data.asStateFlow()
|
||||||
|
|
||||||
fun addNewRecord(record: GLSRecord) {
|
fun addNewRecord(record: GLSRecord) {
|
||||||
val newRecords = _data.value.records.toMutableList().apply {
|
val newRecords = _data.value.records.toMutableList().apply {
|
||||||
@@ -35,10 +36,6 @@ internal class GLSDataHolder @Inject constructor() {
|
|||||||
_data.tryEmit(_data.value.copy(records = emptyList()))
|
_data.tryEmit(_data.value.copy(records = emptyList()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setNewWorkingMode(workingMode: WorkingMode) {
|
|
||||||
_data.tryEmit(_data.value.copy(selectedMode = workingMode))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNewBatteryLevel(batteryLevel: Int) {
|
fun setNewBatteryLevel(batteryLevel: Int) {
|
||||||
_data.tryEmit(_data.value.copy(batteryLevel = batteryLevel))
|
_data.tryEmit(_data.value.copy(batteryLevel = batteryLevel))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ internal data class GLSRecord(
|
|||||||
/** Concentration unit. One of the following: [ConcentrationUnit.UNIT_KGPL], [ConcentrationUnit.UNIT_MOLPL] */
|
/** Concentration unit. One of the following: [ConcentrationUnit.UNIT_KGPL], [ConcentrationUnit.UNIT_MOLPL] */
|
||||||
val unit: ConcentrationUnit = ConcentrationUnit.UNIT_KGPL,
|
val unit: ConcentrationUnit = ConcentrationUnit.UNIT_KGPL,
|
||||||
|
|
||||||
/** The type of the record. 0 if not present */
|
val type: RecordType?,
|
||||||
val type: Int = 0,
|
|
||||||
|
|
||||||
/** The sample location. 0 if unknown */
|
/** The sample location. 0 if unknown */
|
||||||
val sampleLocation: Int = 0,
|
val sampleLocation: Int = 0,
|
||||||
@@ -48,6 +47,30 @@ internal data class GLSRecord(
|
|||||||
var context: MeasurementContext? = null
|
var context: MeasurementContext? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
internal enum class RecordType(val id: Int) {
|
||||||
|
CAPILLARY_WHOLE_BLOOD(1),
|
||||||
|
CAPILLARY_PLASMA(2),
|
||||||
|
VENOUS_WHOLE_BLOOD(3),
|
||||||
|
VENOUS_PLASMA(4),
|
||||||
|
ARTERIAL_WHOLE_BLOOD(5),
|
||||||
|
ARTERIAL_PLASMA(6),
|
||||||
|
UNDETERMINED_WHOLE_BLOOD(7),
|
||||||
|
UNDETERMINED_PLASMA(8),
|
||||||
|
INTERSTITIAL_FLUID(9),
|
||||||
|
CONTROL_SOLUTION(10);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun create(value: Int): RecordType {
|
||||||
|
return values().firstOrNull { it.id == value.toInt() }
|
||||||
|
?: throw IllegalArgumentException("Cannot find element for provided value.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createOrNull(value: Int?): RecordType? {
|
||||||
|
return values().firstOrNull { it.id == value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal data class MeasurementContext(
|
internal data class MeasurementContext(
|
||||||
/** Record sequence number */
|
/** Record sequence number */
|
||||||
val sequenceNumber: Int = 0,
|
val sequenceNumber: Int = 0,
|
||||||
|
|||||||
@@ -35,21 +35,14 @@ import no.nordicsemi.android.ble.common.data.RecordAccessControlPointData
|
|||||||
import no.nordicsemi.android.ble.common.profile.RecordAccessControlPointCallback.RACPErrorCode
|
import no.nordicsemi.android.ble.common.profile.RecordAccessControlPointCallback.RACPErrorCode
|
||||||
import no.nordicsemi.android.ble.common.profile.RecordAccessControlPointCallback.RACPOpCode
|
import no.nordicsemi.android.ble.common.profile.RecordAccessControlPointCallback.RACPOpCode
|
||||||
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementCallback.GlucoseStatus
|
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementCallback.GlucoseStatus
|
||||||
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Carbohydrate
|
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.*
|
||||||
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Health
|
|
||||||
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Meal
|
|
||||||
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Medication
|
|
||||||
import no.nordicsemi.android.ble.common.profile.glucose.GlucoseMeasurementContextCallback.Tester
|
|
||||||
import no.nordicsemi.android.ble.data.Data
|
import no.nordicsemi.android.ble.data.Data
|
||||||
|
import no.nordicsemi.android.gls.data.*
|
||||||
import no.nordicsemi.android.gls.data.CarbohydrateId
|
import no.nordicsemi.android.gls.data.CarbohydrateId
|
||||||
import no.nordicsemi.android.gls.data.ConcentrationUnit
|
import no.nordicsemi.android.gls.data.ConcentrationUnit
|
||||||
import no.nordicsemi.android.gls.data.GLSDataHolder
|
|
||||||
import no.nordicsemi.android.gls.data.GLSRecord
|
|
||||||
import no.nordicsemi.android.gls.data.HealthStatus
|
import no.nordicsemi.android.gls.data.HealthStatus
|
||||||
import no.nordicsemi.android.gls.data.MeasurementContext
|
|
||||||
import no.nordicsemi.android.gls.data.MedicationId
|
import no.nordicsemi.android.gls.data.MedicationId
|
||||||
import no.nordicsemi.android.gls.data.MedicationUnit
|
import no.nordicsemi.android.gls.data.MedicationUnit
|
||||||
import no.nordicsemi.android.gls.data.RequestStatus
|
|
||||||
import no.nordicsemi.android.gls.data.TestType
|
import no.nordicsemi.android.gls.data.TestType
|
||||||
import no.nordicsemi.android.gls.data.TypeOfMeal
|
import no.nordicsemi.android.gls.data.TypeOfMeal
|
||||||
import no.nordicsemi.android.log.LogContract
|
import no.nordicsemi.android.log.LogContract
|
||||||
@@ -137,7 +130,7 @@ internal class GLSManager @Inject constructor(
|
|||||||
glucoseConcentration = glucoseConcentration ?: 0f,
|
glucoseConcentration = glucoseConcentration ?: 0f,
|
||||||
unit = unit?.let { ConcentrationUnit.create(it) }
|
unit = unit?.let { ConcentrationUnit.create(it) }
|
||||||
?: ConcentrationUnit.UNIT_KGPL,
|
?: ConcentrationUnit.UNIT_KGPL,
|
||||||
type = type ?: 0,
|
type = RecordType.createOrNull(type),
|
||||||
sampleLocation = sampleLocation ?: 0,
|
sampleLocation = sampleLocation ?: 0,
|
||||||
status = status?.value ?: 0
|
status = status?.value ?: 0
|
||||||
)
|
)
|
||||||
@@ -213,8 +206,6 @@ internal class GLSManager @Inject constructor(
|
|||||||
device: BluetoothDevice,
|
device: BluetoothDevice,
|
||||||
numberOfRecords: Int
|
numberOfRecords: Int
|
||||||
) {
|
) {
|
||||||
//TODO("Probably not needed")
|
|
||||||
// mCallbacks!!.onNumberOfRecordsRequested(device, numberOfRecords)
|
|
||||||
if (numberOfRecords > 0) {
|
if (numberOfRecords > 0) {
|
||||||
if (dataHolder.records().isNotEmpty()) {
|
if (dataHolder.records().isNotEmpty()) {
|
||||||
val sequenceNumber = dataHolder.records().last().sequenceNumber + 1 //TODO check if correct
|
val sequenceNumber = dataHolder.records().last().sequenceNumber + 1 //TODO check if correct
|
||||||
@@ -232,9 +223,8 @@ internal class GLSManager @Inject constructor(
|
|||||||
)
|
)
|
||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
dataHolder.setRequestStatus(RequestStatus.SUCCESS)
|
|
||||||
}
|
}
|
||||||
|
dataHolder.setRequestStatus(RequestStatus.SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRecordAccessOperationError(
|
override fun onRecordAccessOperationError(
|
||||||
|
|||||||
@@ -1,24 +1,28 @@
|
|||||||
package no.nordicsemi.android.gls.view
|
package no.nordicsemi.android.gls.view
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Search
|
import androidx.compose.material.icons.filled.Search
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import no.nordicsemi.android.gls.R
|
import no.nordicsemi.android.gls.R
|
||||||
import no.nordicsemi.android.gls.data.GLSData
|
import no.nordicsemi.android.gls.data.GLSData
|
||||||
import no.nordicsemi.android.gls.data.GLSRecord
|
import no.nordicsemi.android.gls.data.GLSRecord
|
||||||
|
import no.nordicsemi.android.gls.data.RequestStatus
|
||||||
import no.nordicsemi.android.gls.data.WorkingMode
|
import no.nordicsemi.android.gls.data.WorkingMode
|
||||||
import no.nordicsemi.android.gls.viewmodel.DisconnectEvent
|
import no.nordicsemi.android.gls.viewmodel.DisconnectEvent
|
||||||
import no.nordicsemi.android.gls.viewmodel.GLSScreenViewEvent
|
import no.nordicsemi.android.gls.viewmodel.GLSScreenViewEvent
|
||||||
import no.nordicsemi.android.gls.viewmodel.OnWorkingModeSelected
|
import no.nordicsemi.android.gls.viewmodel.OnWorkingModeSelected
|
||||||
|
import no.nordicsemi.android.material.you.CircularProgressIndicator
|
||||||
import no.nordicsemi.android.theme.view.BatteryLevelView
|
import no.nordicsemi.android.theme.view.BatteryLevelView
|
||||||
import no.nordicsemi.android.theme.view.ScreenSection
|
import no.nordicsemi.android.theme.view.ScreenSection
|
||||||
import no.nordicsemi.android.theme.view.SectionTitle
|
import no.nordicsemi.android.theme.view.SectionTitle
|
||||||
@@ -26,7 +30,10 @@ import no.nordicsemi.android.theme.view.SectionTitle
|
|||||||
@Composable
|
@Composable
|
||||||
internal fun GLSContentView(state: GLSData, onEvent: (GLSScreenViewEvent) -> Unit) {
|
internal fun GLSContentView(state: GLSData, onEvent: (GLSScreenViewEvent) -> Unit) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
@@ -48,6 +55,8 @@ internal fun GLSContentView(state: GLSData, onEvent: (GLSScreenViewEvent) -> Uni
|
|||||||
) {
|
) {
|
||||||
Text(text = stringResource(id = R.string.disconnect))
|
Text(text = stringResource(id = R.string.disconnect))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,9 +71,13 @@ private fun SettingsView(state: GLSData, onEvent: (GLSScreenViewEvent) -> Unit)
|
|||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
horizontalArrangement = Arrangement.SpaceEvenly
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
) {
|
) {
|
||||||
|
if (state.requestStatus == RequestStatus.PENDING) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
} else {
|
||||||
WorkingMode.values().forEach {
|
WorkingMode.values().forEach {
|
||||||
Button(onClick = { onEvent(OnWorkingModeSelected(it)) }) {
|
Button(onClick = { onEvent(OnWorkingModeSelected(it)) }) {
|
||||||
Text(it.displayName)
|
Text(it.toDisplayString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,11 +103,45 @@ private fun RecordsViewWithData(state: GLSData) {
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
state.records.forEach {
|
state.records.forEachIndexed { i, it ->
|
||||||
Text(text = String.format("Glucose concentration: %.2d", it.glucoseConcentration))
|
RecordItem(it)
|
||||||
|
|
||||||
|
if (i < state.records.size-1) {
|
||||||
|
Spacer(modifier = Modifier.padding(8.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun RecordItem(record: GLSRecord) {
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f)
|
||||||
|
) {
|
||||||
|
record.time?.let {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.gls_timestamp, it),
|
||||||
|
style = MaterialTheme.typography.labelLarge
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = record.type.toDisplayString(),
|
||||||
|
style = MaterialTheme.typography.bodyMedium
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.padding(16.dp))
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = glucoseConcentrationDisplayValue(record.glucoseConcentration, record.unit),
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RecordsViewWithoutData() {
|
private fun RecordsViewWithoutData() {
|
||||||
@@ -106,22 +153,9 @@ private fun RecordsViewWithoutData() {
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
Text(text = stringResource(id = R.string.gls_no_records_info))
|
Text(
|
||||||
|
text = stringResource(id = R.string.gls_no_records_info),
|
||||||
|
style = MaterialTheme.typography.bodyMedium
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
private fun GLSContentView_NoData_Preview() {
|
|
||||||
GLSContentView(GLSData()) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
private fun GLSContentView_WithData_Preview() {
|
|
||||||
GLSContentView(GLSData(records = listOf(
|
|
||||||
GLSRecord(glucoseConcentration = 10f),
|
|
||||||
GLSRecord(glucoseConcentration = 15f),
|
|
||||||
GLSRecord(glucoseConcentration = 20f),
|
|
||||||
))) { }
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package no.nordicsemi.android.gls.view
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import no.nordicsemi.android.gls.R
|
||||||
|
import no.nordicsemi.android.gls.data.ConcentrationUnit
|
||||||
|
import no.nordicsemi.android.gls.data.RecordType
|
||||||
|
import no.nordicsemi.android.gls.data.WorkingMode
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun RecordType?.toDisplayString(): String {
|
||||||
|
return when (this) {
|
||||||
|
RecordType.CAPILLARY_WHOLE_BLOOD -> stringResource(id = R.string.gls_type_capillary_whole_blood)
|
||||||
|
RecordType.CAPILLARY_PLASMA -> stringResource(id = R.string.gls_type_capillary_plasma)
|
||||||
|
RecordType.VENOUS_WHOLE_BLOOD -> stringResource(id = R.string.gls_type_venous_whole_blood)
|
||||||
|
RecordType.VENOUS_PLASMA -> stringResource(id = R.string.gls_type_venous_plasma)
|
||||||
|
RecordType.ARTERIAL_WHOLE_BLOOD -> stringResource(id = R.string.gls_type_arterial_whole_blood)
|
||||||
|
RecordType.ARTERIAL_PLASMA -> stringResource(id = R.string.gls_type_arterial_plasma)
|
||||||
|
RecordType.UNDETERMINED_WHOLE_BLOOD -> stringResource(id = R.string.gls_type_undetermined_whole_blood)
|
||||||
|
RecordType.UNDETERMINED_PLASMA -> stringResource(id = R.string.gls_type_undetermined_plasma)
|
||||||
|
RecordType.INTERSTITIAL_FLUID -> stringResource(id = R.string.gls_type_interstitial_fluid)
|
||||||
|
RecordType.CONTROL_SOLUTION -> stringResource(id = R.string.gls_type_control_solution)
|
||||||
|
null -> stringResource(id = R.string.gls_type_reserved)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun ConcentrationUnit.toDisplayString(): String {
|
||||||
|
return when (this) {
|
||||||
|
//TODO("Check unit_kgpl --> mgpdl")
|
||||||
|
ConcentrationUnit.UNIT_KGPL -> stringResource(id = R.string.gls_unit_mgpdl)
|
||||||
|
ConcentrationUnit.UNIT_MOLPL -> stringResource(id = R.string.gls_unit_mmolpl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun WorkingMode.toDisplayString(): String {
|
||||||
|
return when (this) {
|
||||||
|
WorkingMode.ALL -> stringResource(id = R.string.gls__working_mode__all)
|
||||||
|
WorkingMode.LAST -> stringResource(id = R.string.gls__working_mode__last)
|
||||||
|
WorkingMode.FIRST -> stringResource(id = R.string.gls__working_mode__first)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun glucoseConcentrationDisplayValue(value: Float, unit: ConcentrationUnit): String {
|
||||||
|
val result = when (unit) {
|
||||||
|
ConcentrationUnit.UNIT_KGPL -> value * 100000.0f
|
||||||
|
ConcentrationUnit.UNIT_MOLPL -> value * 1000.0f
|
||||||
|
}
|
||||||
|
return String.format("%.2f %s", result, unit.toDisplayString())
|
||||||
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
package no.nordicsemi.android.gls.viewmodel
|
package no.nordicsemi.android.gls.viewmodel
|
||||||
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import no.nordicsemi.android.gls.data.GLSDataHolder
|
import no.nordicsemi.android.gls.data.GLSDataHolder
|
||||||
import no.nordicsemi.android.gls.data.WorkingMode
|
import no.nordicsemi.android.gls.data.WorkingMode
|
||||||
import no.nordicsemi.android.gls.repository.GLSManager
|
import no.nordicsemi.android.gls.repository.GLSManager
|
||||||
@@ -20,26 +17,11 @@ internal class GLSViewModel @Inject constructor(
|
|||||||
) : CloseableViewModel() {
|
) : CloseableViewModel() {
|
||||||
|
|
||||||
val state = dataHolder.data
|
val state = dataHolder.data
|
||||||
private var lastSelectedMode = state.value.selectedMode
|
|
||||||
|
|
||||||
init {
|
|
||||||
dataHolder.data.onEach {
|
|
||||||
if (lastSelectedMode == it.selectedMode) {
|
|
||||||
return@onEach
|
|
||||||
}
|
|
||||||
lastSelectedMode = it.selectedMode
|
|
||||||
when (it.selectedMode) {
|
|
||||||
WorkingMode.ALL -> glsManager.requestAllRecords()
|
|
||||||
WorkingMode.LAST -> glsManager.requestLastRecord()
|
|
||||||
WorkingMode.FIRST -> glsManager.requestFirstRecord()
|
|
||||||
}.exhaustive
|
|
||||||
}.launchIn(GlobalScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onEvent(event: GLSScreenViewEvent) {
|
fun onEvent(event: GLSScreenViewEvent) {
|
||||||
when (event) {
|
when (event) {
|
||||||
DisconnectEvent -> disconnect()
|
DisconnectEvent -> disconnect()
|
||||||
is OnWorkingModeSelected -> dataHolder.setNewWorkingMode(event.workingMode)
|
is OnWorkingModeSelected -> requestData(event.workingMode)
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +34,14 @@ internal class GLSViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun requestData(mode: WorkingMode) {
|
||||||
|
when (mode) {
|
||||||
|
WorkingMode.ALL -> glsManager.requestAllRecords()
|
||||||
|
WorkingMode.LAST -> glsManager.requestLastRecord()
|
||||||
|
WorkingMode.FIRST -> glsManager.requestFirstRecord()
|
||||||
|
}.exhaustive
|
||||||
|
}
|
||||||
|
|
||||||
private fun disconnect() {
|
private fun disconnect() {
|
||||||
finish()
|
finish()
|
||||||
deviceHolder.forgetDevice()
|
deviceHolder.forgetDevice()
|
||||||
|
|||||||
@@ -2,4 +2,25 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="gls_title">GLS</string>
|
<string name="gls_title">GLS</string>
|
||||||
<string name="gls_no_records_info">There is no data available. This peripheral downloads data only when requested. Please select what kind of data you want to download by clicking one from the above buttons.</string>
|
<string name="gls_no_records_info">There is no data available. This peripheral downloads data only when requested. Please select what kind of data you want to download by clicking one from the above buttons.</string>
|
||||||
|
|
||||||
|
<string name="gls_timestamp">%1$te %1$tb %1$tY at %1$tT</string>
|
||||||
|
|
||||||
|
<string name="gls_type_reserved">Reserved for future use</string>
|
||||||
|
<string name="gls_type_capillary_whole_blood">Capillary Whole blood</string>
|
||||||
|
<string name="gls_type_capillary_plasma">Capillary Plasma</string>
|
||||||
|
<string name="gls_type_venous_whole_blood">Venous Whole blood</string>
|
||||||
|
<string name="gls_type_venous_plasma">Venous Plasma</string>
|
||||||
|
<string name="gls_type_arterial_whole_blood">Arterial Whole blood</string>
|
||||||
|
<string name="gls_type_arterial_plasma">Arterial Plasma</string>
|
||||||
|
<string name="gls_type_undetermined_whole_blood">Undetermined Whole blood</string>
|
||||||
|
<string name="gls_type_undetermined_plasma">Undetermined Plasma</string>
|
||||||
|
<string name="gls_type_interstitial_fluid">Interstitial Fluid (ISF)</string>
|
||||||
|
<string name="gls_type_control_solution">Control Solution</string>
|
||||||
|
|
||||||
|
<string name="gls_unit_mgpdl">mg/dl</string>
|
||||||
|
<string name="gls_unit_mmolpl">mmol/l</string>
|
||||||
|
|
||||||
|
<string name="gls__working_mode__all">All</string>
|
||||||
|
<string name="gls__working_mode__last">Last</string>
|
||||||
|
<string name="gls__working_mode__first">First</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user