Add first working example of CGM service in new approach

This commit is contained in:
Sylwester Zieliński
2022-02-11 11:02:06 +01:00
parent d12409cffd
commit 8d21c591ee
20 changed files with 267 additions and 118 deletions

View File

@@ -8,6 +8,7 @@ import no.nordicsemi.android.hrs.view.HRSScreen
import no.nordicsemi.android.hts.view.HTSScreen
import no.nordicsemi.android.navigation.ComposeDestination
import no.nordicsemi.android.navigation.ComposeDestinations
import no.nordicsemi.android.nrftoolbox.view.HomeScreen
import no.nordicsemi.android.prx.view.PRXScreen
import no.nordicsemi.android.rscs.view.RSCSScreen
import no.nordicsemi.android.uart.view.UARTScreen

View File

@@ -1,16 +0,0 @@
package no.nordicsemi.android.nrftoolbox
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import no.nordicsemi.android.navigation.NavigationManager
import javax.inject.Inject
@HiltViewModel
class HomeViewModel @Inject constructor(
private val navigationManager: NavigationManager
) : ViewModel() {
fun openProfile(destination: ProfileDestination) {
navigationManager.navigateTo(destination.destination.id)
}
}

View File

@@ -1,4 +1,4 @@
package no.nordicsemi.android.nrftoolbox
package no.nordicsemi.android.nrftoolbox.view
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
@@ -6,19 +6,25 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.nrftoolbox.R
import no.nordicsemi.android.theme.view.ScreenSection
@Composable
@@ -26,6 +32,7 @@ fun FeatureButton(
@DrawableRes iconId: Int,
@StringRes nameCode: Int,
@StringRes name: Int,
isRunning: Boolean? = null,
onClick: () -> Unit
) {
ScreenSection(onClick = onClick) {
@@ -57,15 +64,32 @@ fun FeatureButton(
Spacer(modifier = Modifier.size(16.dp))
Text(
text = stringResource(id = nameCode),
style = MaterialTheme.typography.headlineSmall,
textAlign = TextAlign.Center
)
// Text(
// text = stringResource(id = nameCode),
// style = MaterialTheme.typography.headlineSmall,
// textAlign = TextAlign.Center
// )
isRunning?.let {
Icon(
painter = painterResource(id = R.drawable.ic_running_indicator),
contentDescription = stringResource(id = R.string.running_profile_icon),
tint = getRunningIndicatorColor(it)
)
}
}
}
}
@Composable
private fun getRunningIndicatorColor(isRunning: Boolean): Color {
return if (isRunning) {
colorResource(id = R.color.nordicGrass)
} else {
MaterialTheme.colorScheme.outline
}
}
@Preview
@Composable
private fun FeatureButtonPreview() {

View File

@@ -1,4 +1,4 @@
package no.nordicsemi.android.nrftoolbox
package no.nordicsemi.android.nrftoolbox.view
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
@@ -6,17 +6,23 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.nrftoolbox.BuildConfig
import no.nordicsemi.android.nrftoolbox.ProfileDestination
import no.nordicsemi.android.nrftoolbox.R
import no.nordicsemi.android.nrftoolbox.viewmodel.HomeViewModel
import no.nordicsemi.android.theme.view.TitleAppBar
@Composable
fun HomeScreen() {
val viewModel: HomeViewModel = hiltViewModel()
val state = viewModel.state.collectAsState().value
Column {
TitleAppBar(stringResource(id = R.string.app_name))
@@ -34,21 +40,15 @@ fun HomeScreen() {
Spacer(modifier = Modifier.height(16.dp))
Text(
text = stringResource(id = R.string.bluetooth_services),
text = stringResource(id = R.string.viewmodel_profiles),
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.fillMaxWidth(),
)
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_csc, R.string.csc_module, R.string.csc_module_full) {
viewModel.openProfile(ProfileDestination.CSC)
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_hrs, R.string.hrs_module, R.string.hrs_module_full) {
viewModel.openProfile(ProfileDestination.HRS)
FeatureButton(R.drawable.ic_bps, R.string.bps_module, R.string.bps_module_full) {
viewModel.openProfile(ProfileDestination.BPS)
}
Spacer(modifier = Modifier.height(16.dp))
@@ -59,31 +59,45 @@ fun HomeScreen() {
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_hts, R.string.hts_module, R.string.hts_module_full) {
Text(
text = stringResource(id = R.string.service_profiles),
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.fillMaxWidth(),
)
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_csc, R.string.csc_module, R.string.csc_module_full, state.isCSCModuleRunning) {
viewModel.openProfile(ProfileDestination.CSC)
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_hrs, R.string.hrs_module, R.string.hrs_module_full, state.isHRSModuleRunning) {
viewModel.openProfile(ProfileDestination.HRS)
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_hts, R.string.hts_module, R.string.hts_module_full, state.isHTSModuleRunning) {
viewModel.openProfile(ProfileDestination.HTS)
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_bps, R.string.bps_module, R.string.bps_module_full) {
viewModel.openProfile(ProfileDestination.BPS)
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_rscs, R.string.rscs_module, R.string.rscs_module_full) {
FeatureButton(R.drawable.ic_rscs, R.string.rscs_module, R.string.rscs_module_full, state.isRSCSModuleRunning) {
viewModel.openProfile(ProfileDestination.RSCS)
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_prx, R.string.prx_module, R.string.prx_module_full) {
FeatureButton(R.drawable.ic_prx, R.string.prx_module, R.string.prx_module_full, state.isPRXModuleRunning) {
viewModel.openProfile(ProfileDestination.PRX)
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(R.drawable.ic_cgm, R.string.cgm_module, R.string.cgm_module_full) {
FeatureButton(R.drawable.ic_cgm, R.string.cgm_module, R.string.cgm_module_full, state.isCGMModuleRunning) {
viewModel.openProfile(ProfileDestination.CGMS)
}

View File

@@ -0,0 +1,10 @@
package no.nordicsemi.android.nrftoolbox.view
data class HomeViewState(
val isCSCModuleRunning: Boolean = false,
val isHRSModuleRunning: Boolean = false,
val isHTSModuleRunning: Boolean = false,
val isRSCSModuleRunning: Boolean = false,
val isPRXModuleRunning: Boolean = false,
val isCGMModuleRunning: Boolean = false
)

View File

@@ -0,0 +1,34 @@
package no.nordicsemi.android.nrftoolbox.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import no.nordicsemi.android.cgms.data.CGMRepository
import no.nordicsemi.android.navigation.NavigationManager
import no.nordicsemi.android.nrftoolbox.ProfileDestination
import no.nordicsemi.android.nrftoolbox.view.HomeViewState
import javax.inject.Inject
@HiltViewModel
class HomeViewModel @Inject constructor(
private val navigationManager: NavigationManager,
private val cgmRepository: CGMRepository
) : ViewModel() {
private val _state = MutableStateFlow(HomeViewState())
val state = _state.asStateFlow()
init {
cgmRepository.isRunning.onEach {
_state.value = _state.value.copy(isCGMModuleRunning = it)
}.launchIn(viewModelScope)
}
fun openProfile(destination: ProfileDestination) {
navigationManager.navigateTo(destination.destination.id)
}
}