mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2025-12-22 17:04:23 +01:00
Switch to new navigation.
This commit is contained in:
@@ -71,6 +71,7 @@ dependencies {
|
||||
|
||||
implementation libs.nordic.ble.common
|
||||
implementation libs.nordic.ui.scanner
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.bundles.koin
|
||||
implementation libs.bundles.hilt
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package no.nordicsemi.android.nrftoolbox
|
||||
|
||||
import no.nordicsemi.android.bps.repository.BPS_SERVICE_UUID
|
||||
import no.nordicsemi.android.bps.view.BPSScreen
|
||||
import no.nordicsemi.android.cgms.repository.CGMS_SERVICE_UUID
|
||||
import no.nordicsemi.android.cgms.view.CGMScreen
|
||||
import no.nordicsemi.android.csc.repository.CSC_SERVICE_UUID
|
||||
import no.nordicsemi.android.csc.view.CSCScreen
|
||||
import no.nordicsemi.android.gls.repository.GLS_SERVICE_UUID
|
||||
import no.nordicsemi.android.gls.view.GLSScreen
|
||||
import no.nordicsemi.android.hrs.service.HRS_SERVICE_UUID
|
||||
import no.nordicsemi.android.hrs.view.HRSScreen
|
||||
import no.nordicsemi.android.hts.repository.HTS_SERVICE_UUID
|
||||
import no.nordicsemi.android.hts.view.HTSScreen
|
||||
import no.nordicsemi.android.navigation.ComposeDestination
|
||||
import no.nordicsemi.android.navigation.ComposeDestinations
|
||||
import no.nordicsemi.android.prx.service.PRX_SERVICE_UUID
|
||||
import no.nordicsemi.android.prx.view.PRXScreen
|
||||
import no.nordicsemi.android.rscs.service.RSCS_SERVICE_UUID
|
||||
import no.nordicsemi.android.rscs.view.RSCSScreen
|
||||
import no.nordicsemi.android.uart.repository.UART_SERVICE_UUID
|
||||
import no.nordicsemi.android.uart.view.UARTScreen
|
||||
import no.nordicsemi.ui.scanner.navigation.view.FindDeviceScreen
|
||||
import java.util.*
|
||||
|
||||
val HomeDestinations = ComposeDestinations(HomeDestination.values().map { it.destination })
|
||||
val ProfileDestinations = ComposeDestinations(ProfileDestination.values().map { it.destination })
|
||||
|
||||
enum class HomeDestination(val destination: ComposeDestination) {
|
||||
HOME(ComposeDestination("home-destination") { HomeScreen() }),
|
||||
SCANNER(ComposeDestination("scanner-destination") { FindDeviceScreen() });
|
||||
}
|
||||
|
||||
enum class ProfileDestination(val destination: ComposeDestination, val uuid: UUID) {
|
||||
CSC(ComposeDestination("csc-destination") { CSCScreen() }, CSC_SERVICE_UUID),
|
||||
HRS(ComposeDestination("hrs-destination") { HRSScreen() }, HRS_SERVICE_UUID),
|
||||
HTS(ComposeDestination("hts-destination") { HTSScreen() }, HTS_SERVICE_UUID),
|
||||
GLS(ComposeDestination("gls-destination") { GLSScreen() }, GLS_SERVICE_UUID),
|
||||
BPS(ComposeDestination("bps-destination") { BPSScreen() }, BPS_SERVICE_UUID),
|
||||
PRX(ComposeDestination("prx-destination") { PRXScreen() }, PRX_SERVICE_UUID),
|
||||
RSCS(ComposeDestination("rscs-destination") { RSCSScreen() }, RSCS_SERVICE_UUID),
|
||||
CGMS(ComposeDestination("cgms-destination") { CGMScreen() }, CGMS_SERVICE_UUID),
|
||||
UART(ComposeDestination("uart-destination") { UARTScreen() }, UART_SERVICE_UUID);
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package no.nordicsemi.android.nrftoolbox
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.ParcelUuid
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import no.nordicsemi.android.bps.view.BPSScreen
|
||||
import no.nordicsemi.android.cgms.view.CGMScreen
|
||||
import no.nordicsemi.android.csc.view.CSCScreen
|
||||
import no.nordicsemi.android.gls.view.GLSScreen
|
||||
import no.nordicsemi.android.hrs.view.HRSScreen
|
||||
import no.nordicsemi.android.hts.view.HTSScreen
|
||||
import no.nordicsemi.android.prx.view.PRXScreen
|
||||
import no.nordicsemi.android.rscs.view.RSCSScreen
|
||||
import no.nordicsemi.android.uart.view.UARTScreen
|
||||
import no.nordicsemi.ui.scanner.navigation.view.FindDeviceScreen
|
||||
import no.nordicsemi.ui.scanner.ui.exhaustive
|
||||
|
||||
@Composable
|
||||
internal fun HomeScreen() {
|
||||
val navController = rememberNavController()
|
||||
val viewModel: HomeViewModel = hiltViewModel()
|
||||
|
||||
val activity = LocalContext.current as Activity
|
||||
BackHandler {
|
||||
if (navController.currentDestination?.navigatorName != NavigationId.HOME.id) {
|
||||
navController.popBackStack()
|
||||
} else {
|
||||
activity.finish()
|
||||
}
|
||||
}
|
||||
|
||||
val destination = viewModel.destination.collectAsState()
|
||||
|
||||
val navigateUp = { viewModel.navigateUp() }
|
||||
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = NavigationId.HOME.id
|
||||
) {
|
||||
composable(NavigationId.HOME.id) {
|
||||
HomeView(viewModel)
|
||||
}
|
||||
composable(NavigationId.SCANNER.id) {
|
||||
val profile = viewModel.profile!!
|
||||
FindDeviceScreen(ParcelUuid(profile.uuid)) {
|
||||
viewModel.onScannerFlowResult(it)
|
||||
}
|
||||
}
|
||||
composable(NavigationId.CSC.id) {
|
||||
CSCScreen(navigateUp)
|
||||
}
|
||||
composable(NavigationId.HRS.id) {
|
||||
HRSScreen(navigateUp)
|
||||
}
|
||||
composable(NavigationId.HTS.id) {
|
||||
HTSScreen(navigateUp)
|
||||
}
|
||||
composable(NavigationId.GLS.id) {
|
||||
GLSScreen(navigateUp)
|
||||
}
|
||||
composable(NavigationId.BPS.id) {
|
||||
BPSScreen(navigateUp)
|
||||
}
|
||||
composable(NavigationId.PRX.id) {
|
||||
PRXScreen(navigateUp)
|
||||
}
|
||||
composable(NavigationId.RSCS.id) {
|
||||
RSCSScreen(navigateUp)
|
||||
}
|
||||
composable(NavigationId.CGMS.id) {
|
||||
CGMScreen(navigateUp)
|
||||
}
|
||||
composable(NavigationId.UART.id) {
|
||||
UARTScreen(navigateUp)
|
||||
}
|
||||
}
|
||||
|
||||
val context = LocalContext.current as Activity
|
||||
LaunchedEffect(destination.value) {
|
||||
when (val destination = destination.value) {
|
||||
FinishDestination -> context.finish()
|
||||
HomeDestination -> navController.navigateUp()
|
||||
is ProfileDestination -> {
|
||||
navController.navigateUp()
|
||||
navController.navigate(destination.id.id)
|
||||
}
|
||||
is ScannerDestination -> navController.navigate(destination.id.id)
|
||||
}.exhaustive
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import no.nordicsemi.android.theme.view.CloseIconAppBar
|
||||
|
||||
@Composable
|
||||
fun HomeView(viewModel: HomeViewModel) {
|
||||
fun HomeScreen() {
|
||||
val viewModel: HomeViewModel = hiltViewModel()
|
||||
|
||||
Column {
|
||||
val context = LocalContext.current
|
||||
CloseIconAppBar(stringResource(id = R.string.app_name)) {
|
||||
@@ -43,12 +46,12 @@ fun HomeView(viewModel: HomeViewModel) {
|
||||
DoubleSection(
|
||||
leftView = {
|
||||
FeatureButton(R.drawable.ic_csc, R.string.csc_module, R.string.csc_module_full) {
|
||||
viewModel.openProfile(Profile.CSC)
|
||||
viewModel.openProfile(ProfileDestination.CSC)
|
||||
}
|
||||
},
|
||||
rightView = {
|
||||
FeatureButton(R.drawable.ic_hrs, R.string.hrs_module, R.string.hrs_module_full) {
|
||||
viewModel.openProfile(Profile.HRS)
|
||||
viewModel.openProfile(ProfileDestination.HRS)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -58,12 +61,12 @@ fun HomeView(viewModel: HomeViewModel) {
|
||||
DoubleSection(
|
||||
leftView = {
|
||||
FeatureButton(R.drawable.ic_gls, R.string.gls_module, R.string.gls_module_full) {
|
||||
viewModel.openProfile(Profile.GLS)
|
||||
viewModel.openProfile(ProfileDestination.GLS)
|
||||
}
|
||||
},
|
||||
rightView = {
|
||||
FeatureButton(R.drawable.ic_hts, R.string.hts_module, R.string.hts_module_full) {
|
||||
viewModel.openProfile(Profile.HTS)
|
||||
viewModel.openProfile(ProfileDestination.HTS)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -73,12 +76,12 @@ fun HomeView(viewModel: HomeViewModel) {
|
||||
DoubleSection(
|
||||
leftView = {
|
||||
FeatureButton(R.drawable.ic_bps, R.string.bps_module, R.string.bps_module_full) {
|
||||
viewModel.openProfile(Profile.BPS)
|
||||
viewModel.openProfile(ProfileDestination.BPS)
|
||||
}
|
||||
},
|
||||
rightView = {
|
||||
FeatureButton(R.drawable.ic_rscs, R.string.rscs_module, R.string.rscs_module_full) {
|
||||
viewModel.openProfile(Profile.RSCS)
|
||||
viewModel.openProfile(ProfileDestination.RSCS)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -88,12 +91,12 @@ fun HomeView(viewModel: HomeViewModel) {
|
||||
DoubleSection(
|
||||
leftView = {
|
||||
FeatureButton(R.drawable.ic_prx, R.string.prx_module, R.string.prx_module_full) {
|
||||
viewModel.openProfile(Profile.PRX)
|
||||
viewModel.openProfile(ProfileDestination.PRX)
|
||||
}
|
||||
},
|
||||
rightView = {
|
||||
FeatureButton(R.drawable.ic_cgm, R.string.cgm_module, R.string.cgm_module_full) {
|
||||
viewModel.openProfile(Profile.CGMS)
|
||||
viewModel.openProfile(ProfileDestination.CGMS)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -101,7 +104,7 @@ fun HomeView(viewModel: HomeViewModel) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
FeatureButton(R.drawable.ic_uart, R.string.uart_module, R.string.uart_module_full) {
|
||||
viewModel.openProfile(Profile.UART)
|
||||
viewModel.openProfile(ProfileDestination.UART)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
@@ -2,50 +2,22 @@ package no.nordicsemi.android.nrftoolbox
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import no.nordicsemi.android.navigation.ForwardDestination
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.navigation.UUIDArgument
|
||||
import no.nordicsemi.android.service.SelectedBluetoothDeviceHolder
|
||||
import no.nordicsemi.ui.scanner.navigation.view.FindDeviceCloseResult
|
||||
import no.nordicsemi.ui.scanner.navigation.view.FindDeviceFlowStatus
|
||||
import no.nordicsemi.ui.scanner.navigation.view.FindDeviceSuccessResult
|
||||
import no.nordicsemi.ui.scanner.ui.exhaustive
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class HomeViewModel @Inject constructor(
|
||||
private val deviceHolder: SelectedBluetoothDeviceHolder
|
||||
private val deviceHolder: SelectedBluetoothDeviceHolder,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
private val _destination = MutableStateFlow<NavDestination>(HomeDestination)
|
||||
val destination = _destination.asStateFlow()
|
||||
|
||||
var profile: Profile? = null //to pass argument between nav destinations
|
||||
|
||||
fun onScannerFlowResult(status: FindDeviceFlowStatus) {
|
||||
when (status) {
|
||||
FindDeviceCloseResult -> navigateUp()
|
||||
is FindDeviceSuccessResult -> onDeviceSelected(status)
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
fun openProfile(profile: Profile) {
|
||||
this.profile = profile
|
||||
_destination.value = ScannerDestination(profile)
|
||||
}
|
||||
|
||||
fun navigateUp() {
|
||||
val currentDestination = _destination.value
|
||||
_destination.value = when (currentDestination) {
|
||||
FinishDestination -> FinishDestination
|
||||
HomeDestination -> FinishDestination
|
||||
is ProfileDestination -> HomeDestination
|
||||
is ScannerDestination -> HomeDestination
|
||||
}
|
||||
}
|
||||
|
||||
private fun onDeviceSelected(result: FindDeviceSuccessResult) {
|
||||
val profile = requireNotNull(profile)
|
||||
deviceHolder.attachDevice(result.device)
|
||||
_destination.value = ProfileDestination(profile.toNavigationId(), profile.isPairingRequired)
|
||||
fun openProfile(destination: ProfileDestination) {
|
||||
navigationManager.navigateTo(
|
||||
ForwardDestination(destination.destination.id),
|
||||
UUIDArgument(destination.uuid)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import androidx.compose.ui.Modifier
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import no.nordicsemi.android.material.you.NordicActivity
|
||||
import no.nordicsemi.android.material.you.NordicTheme
|
||||
import no.nordicsemi.android.navigation.NavigationView
|
||||
import no.nordicsemi.ui.scanner.ScannerDestinations
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : NordicActivity() {
|
||||
@@ -22,7 +24,9 @@ class MainActivity : NordicActivity() {
|
||||
color = MaterialTheme.colorScheme.surface,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
HomeScreen()
|
||||
NavigationView(
|
||||
HomeDestinations + ProfileDestinations + ScannerDestinations
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package no.nordicsemi.android.nrftoolbox
|
||||
|
||||
sealed class NavDestination
|
||||
|
||||
object FinishDestination : NavDestination()
|
||||
|
||||
sealed class ForwardDestination : NavDestination() {
|
||||
abstract val id: NavigationId
|
||||
}
|
||||
|
||||
object HomeDestination : ForwardDestination() {
|
||||
override val id: NavigationId = NavigationId.HOME
|
||||
}
|
||||
|
||||
data class ScannerDestination(val profile: Profile) : ForwardDestination() {
|
||||
override val id: NavigationId = NavigationId.SCANNER
|
||||
}
|
||||
|
||||
data class ProfileDestination(
|
||||
override val id: NavigationId,
|
||||
val isPairingRequired: Boolean
|
||||
) : ForwardDestination()
|
||||
@@ -1,55 +0,0 @@
|
||||
package no.nordicsemi.android.nrftoolbox
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import no.nordicsemi.android.bps.repository.BPS_SERVICE_UUID
|
||||
import no.nordicsemi.android.cgms.repository.CGMS_SERVICE_UUID
|
||||
import no.nordicsemi.android.csc.repository.CYCLING_SPEED_AND_CADENCE_SERVICE_UUID
|
||||
import no.nordicsemi.android.gls.repository.GLS_SERVICE_UUID
|
||||
import no.nordicsemi.android.hrs.service.HR_SERVICE_UUID
|
||||
import no.nordicsemi.android.hts.repository.HT_SERVICE_UUID
|
||||
import no.nordicsemi.android.prx.service.PRX_SERVICE_UUID
|
||||
import no.nordicsemi.android.rscs.service.RSCS_SERVICE_UUID
|
||||
import no.nordicsemi.android.uart.repository.UART_SERVICE_UUID
|
||||
import java.util.*
|
||||
|
||||
enum class NavigationId(val id: String) {
|
||||
HOME("home-screen"),
|
||||
SCANNER("scanner-screen"),
|
||||
CSC("csc-screen"),
|
||||
HRS("hrs-screen"),
|
||||
HTS("hts-screen"),
|
||||
GLS("gls-screen"),
|
||||
BPS("bps-screen"),
|
||||
PRX("prx-screen"),
|
||||
RSCS("rscs-screen"),
|
||||
CGMS("cgms-screen"),
|
||||
UART("uart-screen");
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
enum class Profile(val uuid: UUID, val isPairingRequired: Boolean) : Parcelable {
|
||||
CSC(CYCLING_SPEED_AND_CADENCE_SERVICE_UUID, false),
|
||||
HRS(HR_SERVICE_UUID, false),
|
||||
HTS(HT_SERVICE_UUID, false),
|
||||
GLS(GLS_SERVICE_UUID, true),
|
||||
BPS(BPS_SERVICE_UUID, false),
|
||||
PRX(PRX_SERVICE_UUID, true),
|
||||
RSCS(RSCS_SERVICE_UUID, false),
|
||||
CGMS(CGMS_SERVICE_UUID, false),
|
||||
UART(UART_SERVICE_UUID, false);
|
||||
}
|
||||
|
||||
fun Profile.toNavigationId(): NavigationId {
|
||||
return when (this) {
|
||||
Profile.CSC -> NavigationId.CSC
|
||||
Profile.HRS -> NavigationId.HRS
|
||||
Profile.HTS -> NavigationId.HTS
|
||||
Profile.GLS -> NavigationId.GLS
|
||||
Profile.BPS -> NavigationId.BPS
|
||||
Profile.PRX -> NavigationId.PRX
|
||||
Profile.RSCS -> NavigationId.RSCS
|
||||
Profile.CGMS -> NavigationId.CGMS
|
||||
Profile.UART -> NavigationId.UART
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ dependencies {
|
||||
implementation project(":lib_utils")
|
||||
|
||||
implementation libs.nordic.ble.common
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.nordic.log
|
||||
implementation libs.nordic.ui.scanner
|
||||
|
||||
@@ -13,19 +13,15 @@ import no.nordicsemi.android.theme.view.DeviceConnectingView
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
fun BPSScreen(finishAction: () -> Unit) {
|
||||
fun BPSScreen() {
|
||||
val viewModel: BPSViewModel = hiltViewModel()
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
LaunchedEffect(state.isActive) {
|
||||
if (state.isActive) {
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.connectDevice()
|
||||
} else {
|
||||
finishAction()
|
||||
}
|
||||
}
|
||||
|
||||
BPSView(state.viewState) { viewModel.onEvent(it) }
|
||||
BPSView(state) { viewModel.onEvent(it) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -2,11 +2,6 @@ package no.nordicsemi.android.bps.view
|
||||
|
||||
import no.nordicsemi.android.bps.data.BPSData
|
||||
|
||||
internal data class BPSState(
|
||||
val viewState: BPSViewState,
|
||||
val isActive: Boolean = true
|
||||
)
|
||||
|
||||
internal sealed class BPSViewState
|
||||
|
||||
internal object LoadingState : BPSViewState()
|
||||
|
||||
@@ -6,14 +6,16 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import no.nordicsemi.android.bps.data.BPSRepository
|
||||
import no.nordicsemi.android.bps.repository.BPSManager
|
||||
import no.nordicsemi.android.bps.view.BPSScreenViewEvent
|
||||
import no.nordicsemi.android.bps.view.BPSState
|
||||
import no.nordicsemi.android.bps.view.DisconnectEvent
|
||||
import no.nordicsemi.android.bps.view.DisplayDataState
|
||||
import no.nordicsemi.android.bps.view.LoadingState
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.service.BleManagerStatus
|
||||
import no.nordicsemi.android.service.ConnectionObserverAdapter
|
||||
import no.nordicsemi.android.service.SelectedBluetoothDeviceHolder
|
||||
@@ -24,16 +26,17 @@ import javax.inject.Inject
|
||||
internal class BPSViewModel @Inject constructor(
|
||||
private val bpsManager: BPSManager,
|
||||
private val deviceHolder: SelectedBluetoothDeviceHolder,
|
||||
private val repository: BPSRepository
|
||||
private val repository: BPSRepository,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
val state = repository.data.combine(repository.status) { data, status ->
|
||||
when (status) {
|
||||
BleManagerStatus.CONNECTING -> BPSState(LoadingState)
|
||||
BleManagerStatus.OK -> BPSState(DisplayDataState(data))
|
||||
BleManagerStatus.DISCONNECTED -> BPSState(DisplayDataState(data), false)
|
||||
BleManagerStatus.CONNECTING -> LoadingState
|
||||
BleManagerStatus.OK,
|
||||
BleManagerStatus.DISCONNECTED -> DisplayDataState(data)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, BPSState(LoadingState))
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState)
|
||||
|
||||
init {
|
||||
bpsManager.setConnectionObserver(object : ConnectionObserverAdapter() {
|
||||
@@ -52,6 +55,12 @@ internal class BPSViewModel @Inject constructor(
|
||||
repository.setNewStatus(BleManagerStatus.DISCONNECTED)
|
||||
}
|
||||
})
|
||||
|
||||
repository.status.onEach {
|
||||
if (it == BleManagerStatus.DISCONNECTED) {
|
||||
navigationManager.navigateUp()
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
fun onEvent(event: BPSScreenViewEvent) {
|
||||
|
||||
@@ -10,6 +10,7 @@ dependencies {
|
||||
|
||||
implementation libs.nordic.log
|
||||
implementation libs.nordic.theme
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.bundles.compose
|
||||
implementation libs.androidx.core
|
||||
|
||||
@@ -16,21 +16,17 @@ import no.nordicsemi.android.theme.view.DeviceConnectingView
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
fun CGMScreen(finishAction: () -> Unit) {
|
||||
fun CGMScreen() {
|
||||
val viewModel: CGMScreenViewModel = hiltViewModel()
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
val context = LocalContext.current
|
||||
LaunchedEffect(state.isActive) {
|
||||
if (state.isActive) {
|
||||
LaunchedEffect(Unit) {
|
||||
val intent = Intent(context, CGMService::class.java)
|
||||
context.startService(intent)
|
||||
} else if (!state.isActive) {
|
||||
finishAction()
|
||||
}
|
||||
}
|
||||
|
||||
CGMView(state.viewState) {
|
||||
CGMView(state) {
|
||||
viewModel.onEvent(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,6 @@ package no.nordicsemi.android.cgms.view
|
||||
|
||||
import no.nordicsemi.android.cgms.data.CGMData
|
||||
|
||||
internal data class CGMState(
|
||||
val viewState: CGMViewState,
|
||||
val isActive: Boolean = true
|
||||
)
|
||||
|
||||
internal sealed class CGMViewState
|
||||
|
||||
internal object LoadingState : CGMViewState()
|
||||
|
||||
@@ -5,31 +5,42 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import no.nordicsemi.android.cgms.data.CGMRepository
|
||||
import no.nordicsemi.android.cgms.data.CGMServiceCommand
|
||||
import no.nordicsemi.android.cgms.view.CGMState
|
||||
import no.nordicsemi.android.cgms.view.CGMViewEvent
|
||||
import no.nordicsemi.android.cgms.view.DisconnectEvent
|
||||
import no.nordicsemi.android.cgms.view.DisplayDataState
|
||||
import no.nordicsemi.android.cgms.view.LoadingState
|
||||
import no.nordicsemi.android.cgms.view.OnWorkingModeSelected
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.service.BleManagerStatus
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
internal class CGMScreenViewModel @Inject constructor(
|
||||
private val repository: CGMRepository
|
||||
private val repository: CGMRepository,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
val state = repository.data.combine(repository.status) { data, status ->
|
||||
when (status) {
|
||||
BleManagerStatus.CONNECTING -> CGMState(LoadingState)
|
||||
BleManagerStatus.OK -> CGMState(DisplayDataState(data))
|
||||
BleManagerStatus.DISCONNECTED -> CGMState(DisplayDataState(data), false)
|
||||
BleManagerStatus.CONNECTING -> LoadingState
|
||||
BleManagerStatus.OK,
|
||||
BleManagerStatus.DISCONNECTED -> DisplayDataState(data)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState)
|
||||
|
||||
init {
|
||||
repository.status.onEach {
|
||||
if (it == BleManagerStatus.DISCONNECTED) {
|
||||
navigationManager.navigateUp()
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, CGMState(LoadingState))
|
||||
|
||||
fun onEvent(event: CGMViewEvent) {
|
||||
when (event) {
|
||||
|
||||
@@ -10,6 +10,7 @@ dependencies {
|
||||
|
||||
implementation libs.nordic.log
|
||||
implementation libs.nordic.theme
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.bundles.compose
|
||||
implementation libs.androidx.core
|
||||
|
||||
@@ -35,7 +35,7 @@ import no.nordicsemi.android.service.BatteryManager
|
||||
import java.util.*
|
||||
|
||||
/** Cycling Speed and Cadence service UUID. */
|
||||
val CYCLING_SPEED_AND_CADENCE_SERVICE_UUID: UUID = UUID.fromString("00001816-0000-1000-8000-00805f9b34fb")
|
||||
val CSC_SERVICE_UUID: UUID = UUID.fromString("00001816-0000-1000-8000-00805f9b34fb")
|
||||
|
||||
/** Cycling Speed and Cadence Measurement characteristic UUID. */
|
||||
private val CSC_MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00002A5B-0000-1000-8000-00805f9b34fb")
|
||||
@@ -101,7 +101,7 @@ internal class CSCManager(context: Context, private val repository: CSCRepositor
|
||||
}
|
||||
|
||||
public override fun isRequiredServiceSupported(gatt: BluetoothGatt): Boolean {
|
||||
val service = gatt.getService(CYCLING_SPEED_AND_CADENCE_SERVICE_UUID)
|
||||
val service = gatt.getService(CSC_SERVICE_UUID)
|
||||
if (service != null) {
|
||||
cscMeasurementCharacteristic = service.getCharacteristic(
|
||||
CSC_MEASUREMENT_CHARACTERISTIC_UUID
|
||||
|
||||
@@ -16,21 +16,17 @@ import no.nordicsemi.android.theme.view.DeviceConnectingView
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
fun CSCScreen(finishAction: () -> Unit) {
|
||||
fun CSCScreen() {
|
||||
val viewModel: CSCViewModel = hiltViewModel()
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
val context = LocalContext.current
|
||||
LaunchedEffect(state.isActive) {
|
||||
if (state.isActive) {
|
||||
LaunchedEffect(Unit) {
|
||||
val intent = Intent(context, CSCService::class.java)
|
||||
context.startService(intent)
|
||||
} else {
|
||||
finishAction()
|
||||
}
|
||||
}
|
||||
|
||||
CSCView(state.viewState) { viewModel.onEvent(it) }
|
||||
CSCView(state) { viewModel.onEvent(it) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -2,11 +2,6 @@ package no.nordicsemi.android.csc.view
|
||||
|
||||
import no.nordicsemi.android.csc.data.CSCData
|
||||
|
||||
internal data class CSCState(
|
||||
val viewState: CSCViewState,
|
||||
val isActive: Boolean = true
|
||||
)
|
||||
|
||||
internal sealed class CSCViewState
|
||||
|
||||
internal object LoadingState : CSCViewState()
|
||||
|
||||
@@ -5,33 +5,44 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import no.nordicsemi.android.csc.data.CSCRepository
|
||||
import no.nordicsemi.android.csc.data.DisconnectCommand
|
||||
import no.nordicsemi.android.csc.data.SetWheelSizeCommand
|
||||
import no.nordicsemi.android.csc.view.CSCState
|
||||
import no.nordicsemi.android.csc.view.CSCViewEvent
|
||||
import no.nordicsemi.android.csc.view.DisplayDataState
|
||||
import no.nordicsemi.android.csc.view.LoadingState
|
||||
import no.nordicsemi.android.csc.view.OnDisconnectButtonClick
|
||||
import no.nordicsemi.android.csc.view.OnSelectedSpeedUnitSelected
|
||||
import no.nordicsemi.android.csc.view.OnWheelSizeSelected
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.service.BleManagerStatus
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
internal class CSCViewModel @Inject constructor(
|
||||
private val repository: CSCRepository
|
||||
private val repository: CSCRepository,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
val state = repository.data.combine(repository.status) { data, status ->
|
||||
when (status) {
|
||||
BleManagerStatus.CONNECTING -> CSCState(LoadingState)
|
||||
BleManagerStatus.OK -> CSCState(DisplayDataState(data))
|
||||
BleManagerStatus.DISCONNECTED -> CSCState(DisplayDataState(data), false)
|
||||
BleManagerStatus.CONNECTING -> LoadingState
|
||||
BleManagerStatus.OK,
|
||||
BleManagerStatus.DISCONNECTED -> DisplayDataState(data)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState)
|
||||
|
||||
init {
|
||||
repository.status.onEach {
|
||||
if (it == BleManagerStatus.DISCONNECTED) {
|
||||
navigationManager.navigateUp()
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, CSCState(LoadingState))
|
||||
|
||||
fun onEvent(event: CSCViewEvent) {
|
||||
when (event) {
|
||||
|
||||
@@ -10,6 +10,7 @@ dependencies {
|
||||
|
||||
implementation libs.nordic.ble.common
|
||||
implementation libs.nordic.theme
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.nordic.log
|
||||
implementation libs.nordic.dfu
|
||||
|
||||
@@ -11,6 +11,7 @@ dependencies {
|
||||
implementation libs.nordic.ble.common
|
||||
implementation libs.nordic.theme
|
||||
implementation libs.nordic.ui.scanner
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.nordic.log
|
||||
|
||||
|
||||
@@ -2,11 +2,6 @@ package no.nordicsemi.android.gls.view
|
||||
|
||||
import no.nordicsemi.android.gls.data.GLSData
|
||||
|
||||
internal data class GLSState(
|
||||
val viewState: GLSViewState,
|
||||
val isActive: Boolean = true
|
||||
)
|
||||
|
||||
internal sealed class GLSViewState
|
||||
|
||||
internal object LoadingState : GLSViewState()
|
||||
|
||||
@@ -16,21 +16,17 @@ import no.nordicsemi.android.theme.view.DeviceConnectingView
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
fun GLSScreen(finishAction: () -> Unit) {
|
||||
fun GLSScreen() {
|
||||
val viewModel: GLSViewModel = hiltViewModel()
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
Log.d("AAATESTAAA", "$viewModel") //TODO fix screen rotation
|
||||
|
||||
LaunchedEffect(state.isActive) {
|
||||
if (state.isActive) {
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.connectDevice()
|
||||
} else {
|
||||
finishAction()
|
||||
}
|
||||
}
|
||||
|
||||
GLSView(state.viewState) {
|
||||
GLSView(state) {
|
||||
viewModel.onEvent(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,15 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import no.nordicsemi.android.gls.data.GLSRepository
|
||||
import no.nordicsemi.android.gls.data.WorkingMode
|
||||
import no.nordicsemi.android.gls.repository.GLSManager
|
||||
import no.nordicsemi.android.gls.view.DisplayDataState
|
||||
import no.nordicsemi.android.gls.view.GLSState
|
||||
import no.nordicsemi.android.gls.view.LoadingState
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.service.BleManagerStatus
|
||||
import no.nordicsemi.android.service.ConnectionObserverAdapter
|
||||
import no.nordicsemi.android.service.SelectedBluetoothDeviceHolder
|
||||
@@ -23,16 +25,17 @@ import javax.inject.Inject
|
||||
internal class GLSViewModel @Inject constructor(
|
||||
private val glsManager: GLSManager,
|
||||
private val deviceHolder: SelectedBluetoothDeviceHolder,
|
||||
private val repository: GLSRepository
|
||||
private val repository: GLSRepository,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
val state = repository.data.combine(repository.status) { data, status ->
|
||||
when (status) {
|
||||
BleManagerStatus.CONNECTING -> GLSState(LoadingState)
|
||||
BleManagerStatus.OK -> GLSState(DisplayDataState(data))
|
||||
BleManagerStatus.DISCONNECTED -> GLSState(DisplayDataState(data), false)
|
||||
BleManagerStatus.CONNECTING -> LoadingState
|
||||
BleManagerStatus.OK,
|
||||
BleManagerStatus.DISCONNECTED -> DisplayDataState(data)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, GLSState(LoadingState))
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState)
|
||||
|
||||
init {
|
||||
glsManager.setConnectionObserver(object : ConnectionObserverAdapter() {
|
||||
@@ -51,6 +54,12 @@ internal class GLSViewModel @Inject constructor(
|
||||
repository.setNewStatus(BleManagerStatus.DISCONNECTED)
|
||||
}
|
||||
})
|
||||
|
||||
repository.status.onEach {
|
||||
if (it == BleManagerStatus.DISCONNECTED) {
|
||||
navigationManager.navigateUp()
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
fun onEvent(event: GLSScreenViewEvent) {
|
||||
|
||||
@@ -9,6 +9,7 @@ dependencies {
|
||||
implementation libs.chart
|
||||
|
||||
implementation libs.nordic.ble.common
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.nordic.log
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import no.nordicsemi.android.hrs.data.HRSRepository
|
||||
import no.nordicsemi.android.service.BatteryManager
|
||||
import java.util.*
|
||||
|
||||
val HR_SERVICE_UUID: UUID = UUID.fromString("0000180D-0000-1000-8000-00805f9b34fb")
|
||||
val HRS_SERVICE_UUID: UUID = UUID.fromString("0000180D-0000-1000-8000-00805f9b34fb")
|
||||
private val BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID = UUID.fromString("00002A38-0000-1000-8000-00805f9b34fb")
|
||||
private val HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00002A37-0000-1000-8000-00805f9b34fb")
|
||||
|
||||
@@ -100,7 +100,7 @@ internal class HRSManager(context: Context, private val dataHolder: HRSRepositor
|
||||
}
|
||||
|
||||
override fun isRequiredServiceSupported(gatt: BluetoothGatt): Boolean {
|
||||
val service = gatt.getService(HR_SERVICE_UUID)
|
||||
val service = gatt.getService(HRS_SERVICE_UUID)
|
||||
if (service != null) {
|
||||
heartRateCharacteristic = service.getCharacteristic(
|
||||
HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID
|
||||
@@ -111,7 +111,7 @@ internal class HRSManager(context: Context, private val dataHolder: HRSRepositor
|
||||
|
||||
override fun isOptionalServiceSupported(gatt: BluetoothGatt): Boolean {
|
||||
super.isOptionalServiceSupported(gatt)
|
||||
val service = gatt.getService(HR_SERVICE_UUID)
|
||||
val service = gatt.getService(HRS_SERVICE_UUID)
|
||||
if (service != null) {
|
||||
bodySensorLocationCharacteristic = service.getCharacteristic(
|
||||
BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID
|
||||
|
||||
@@ -16,21 +16,17 @@ import no.nordicsemi.android.theme.view.DeviceConnectingView
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
fun HRSScreen(finishAction: () -> Unit) {
|
||||
fun HRSScreen() {
|
||||
val viewModel: HRSViewModel = hiltViewModel()
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
val context = LocalContext.current
|
||||
LaunchedEffect(state.isActive) {
|
||||
if (state.isActive) {
|
||||
LaunchedEffect(Unit) {
|
||||
val intent = Intent(context, HRSService::class.java)
|
||||
context.startService(intent)
|
||||
} else {
|
||||
finishAction()
|
||||
}
|
||||
}
|
||||
|
||||
HRSView(state.viewState) { viewModel.onEvent(it) }
|
||||
HRSView(state) { viewModel.onEvent(it) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package no.nordicsemi.android.hrs.view
|
||||
|
||||
sealed class HRSScreenViewEvent
|
||||
internal sealed class HRSScreenViewEvent
|
||||
|
||||
object DisconnectEvent : HRSScreenViewEvent()
|
||||
internal object DisconnectEvent : HRSScreenViewEvent()
|
||||
|
||||
internal object NavigateUpEvent : HRSScreenViewEvent()
|
||||
|
||||
@@ -2,11 +2,6 @@ package no.nordicsemi.android.hrs.view
|
||||
|
||||
import no.nordicsemi.android.hrs.data.HRSData
|
||||
|
||||
internal data class HRSState(
|
||||
val viewState: HRSViewState,
|
||||
val isActive: Boolean = true
|
||||
)
|
||||
|
||||
internal sealed class HRSViewState
|
||||
|
||||
internal object LoadingState : HRSViewState()
|
||||
|
||||
@@ -5,33 +5,47 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import no.nordicsemi.android.hrs.data.HRSRepository
|
||||
import no.nordicsemi.android.hrs.view.DisconnectEvent
|
||||
import no.nordicsemi.android.hrs.view.DisplayDataState
|
||||
import no.nordicsemi.android.hrs.view.HRSScreenViewEvent
|
||||
import no.nordicsemi.android.hrs.view.HRSState
|
||||
import no.nordicsemi.android.hrs.view.LoadingState
|
||||
import no.nordicsemi.android.hrs.view.NavigateUpEvent
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.service.BleManagerStatus
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
internal class HRSViewModel @Inject constructor(
|
||||
private val repository: HRSRepository
|
||||
private val repository: HRSRepository,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
val state = repository.data.combine(repository.status) { data, status ->
|
||||
when (status) {
|
||||
BleManagerStatus.CONNECTING -> HRSState(LoadingState)
|
||||
BleManagerStatus.OK -> HRSState(DisplayDataState(data))
|
||||
BleManagerStatus.DISCONNECTED -> HRSState(DisplayDataState(data), false)
|
||||
BleManagerStatus.CONNECTING -> LoadingState
|
||||
BleManagerStatus.OK,
|
||||
BleManagerStatus.DISCONNECTED -> DisplayDataState(data)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState)
|
||||
|
||||
init {
|
||||
repository.status.onEach {
|
||||
if (it == BleManagerStatus.DISCONNECTED) {
|
||||
navigationManager.navigateUp()
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, HRSState(LoadingState))
|
||||
|
||||
fun onEvent(event: HRSScreenViewEvent) {
|
||||
(event as? DisconnectEvent)?.let {
|
||||
onDisconnectButtonClick()
|
||||
}
|
||||
when (event) {
|
||||
DisconnectEvent -> onDisconnectButtonClick()
|
||||
NavigateUpEvent -> navigationManager.navigateUp()
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
private fun onDisconnectButtonClick() {
|
||||
|
||||
@@ -10,6 +10,7 @@ dependencies {
|
||||
|
||||
implementation libs.nordic.log
|
||||
implementation libs.nordic.theme
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.bundles.compose
|
||||
implementation libs.androidx.core
|
||||
|
||||
@@ -32,7 +32,7 @@ import no.nordicsemi.android.hts.data.HTSRepository
|
||||
import no.nordicsemi.android.service.BatteryManager
|
||||
import java.util.*
|
||||
|
||||
val HT_SERVICE_UUID: UUID = UUID.fromString("00001809-0000-1000-8000-00805f9b34fb")
|
||||
val HTS_SERVICE_UUID: UUID = UUID.fromString("00001809-0000-1000-8000-00805f9b34fb")
|
||||
private val HT_MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00002A1C-0000-1000-8000-00805f9b34fb")
|
||||
|
||||
/**
|
||||
@@ -81,7 +81,7 @@ internal class HTSManager internal constructor(
|
||||
}
|
||||
|
||||
override fun isRequiredServiceSupported(gatt: BluetoothGatt): Boolean {
|
||||
val service = gatt.getService(HT_SERVICE_UUID)
|
||||
val service = gatt.getService(HTS_SERVICE_UUID)
|
||||
if (service != null) {
|
||||
htCharacteristic = service.getCharacteristic(HT_MEASUREMENT_CHARACTERISTIC_UUID)
|
||||
}
|
||||
|
||||
@@ -16,21 +16,17 @@ import no.nordicsemi.android.theme.view.DeviceConnectingView
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
fun HTSScreen(finishAction: () -> Unit) {
|
||||
fun HTSScreen() {
|
||||
val viewModel: HTSViewModel = hiltViewModel()
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
val context = LocalContext.current
|
||||
LaunchedEffect(state.isActive) {
|
||||
if (state.isActive) {
|
||||
LaunchedEffect(Unit) {
|
||||
val intent = Intent(context, HTSService::class.java)
|
||||
context.startService(intent)
|
||||
} else {
|
||||
finishAction()
|
||||
}
|
||||
}
|
||||
|
||||
HTSView(state.viewState) { viewModel.onEvent(it) }
|
||||
HTSView(state) { viewModel.onEvent(it) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -2,11 +2,6 @@ package no.nordicsemi.android.hts.view
|
||||
|
||||
import no.nordicsemi.android.hts.data.HTSData
|
||||
|
||||
internal data class HTSState(
|
||||
val viewState: HTSViewState,
|
||||
val isActive: Boolean = true
|
||||
)
|
||||
|
||||
internal sealed class HTSViewState
|
||||
|
||||
internal object LoadingState : HTSViewState()
|
||||
|
||||
@@ -5,30 +5,41 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import no.nordicsemi.android.hts.data.HTSRepository
|
||||
import no.nordicsemi.android.hts.view.DisconnectEvent
|
||||
import no.nordicsemi.android.hts.view.DisplayDataState
|
||||
import no.nordicsemi.android.hts.view.HTSScreenViewEvent
|
||||
import no.nordicsemi.android.hts.view.HTSState
|
||||
import no.nordicsemi.android.hts.view.LoadingState
|
||||
import no.nordicsemi.android.hts.view.OnTemperatureUnitSelected
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.service.BleManagerStatus
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
internal class HTSViewModel @Inject constructor(
|
||||
private val repository: HTSRepository
|
||||
private val repository: HTSRepository,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
val state = repository.data.combine(repository.status) { data, status ->
|
||||
when (status) {
|
||||
BleManagerStatus.CONNECTING -> HTSState(LoadingState)
|
||||
BleManagerStatus.OK -> HTSState(DisplayDataState(data))
|
||||
BleManagerStatus.DISCONNECTED -> HTSState(DisplayDataState(data), false)
|
||||
BleManagerStatus.CONNECTING -> LoadingState
|
||||
BleManagerStatus.OK,
|
||||
BleManagerStatus.DISCONNECTED -> DisplayDataState(data)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState)
|
||||
|
||||
init {
|
||||
repository.status.onEach {
|
||||
if (it == BleManagerStatus.DISCONNECTED) {
|
||||
navigationManager.navigateUp()
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, HTSState(LoadingState))
|
||||
|
||||
fun onEvent(event: HTSScreenViewEvent) {
|
||||
when (event) {
|
||||
|
||||
@@ -9,6 +9,7 @@ dependencies {
|
||||
implementation libs.nordic.ble.common
|
||||
|
||||
implementation libs.nordic.log
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.bundles.compose
|
||||
implementation libs.androidx.core
|
||||
|
||||
@@ -17,21 +17,17 @@ import no.nordicsemi.android.theme.view.DeviceConnectingView
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
fun PRXScreen(finishAction: () -> Unit) {
|
||||
fun PRXScreen() {
|
||||
val viewModel: PRXViewModel = hiltViewModel()
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
val context = LocalContext.current
|
||||
LaunchedEffect(state.isActive) {
|
||||
if (state.isActive) {
|
||||
LaunchedEffect(Unit) {
|
||||
val intent = Intent(context, PRXService::class.java)
|
||||
context.startService(intent)
|
||||
} else {
|
||||
finishAction()
|
||||
}
|
||||
}
|
||||
|
||||
PRXView(state.viewState) { viewModel.onEvent(it) }
|
||||
PRXView(state) { viewModel.onEvent(it) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -2,11 +2,6 @@ package no.nordicsemi.android.prx.view
|
||||
|
||||
import no.nordicsemi.android.prx.data.PRXData
|
||||
|
||||
internal data class PRXState(
|
||||
val viewState: PRXViewState,
|
||||
val isActive: Boolean = true
|
||||
)
|
||||
|
||||
internal sealed class PRXViewState
|
||||
|
||||
internal object LoadingState : PRXViewState()
|
||||
|
||||
@@ -5,7 +5,10 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.prx.data.DisableAlarm
|
||||
import no.nordicsemi.android.prx.data.Disconnect
|
||||
import no.nordicsemi.android.prx.data.EnableAlarm
|
||||
@@ -14,7 +17,6 @@ import no.nordicsemi.android.prx.view.DisconnectEvent
|
||||
import no.nordicsemi.android.prx.view.DisplayDataState
|
||||
import no.nordicsemi.android.prx.view.LoadingState
|
||||
import no.nordicsemi.android.prx.view.PRXScreenViewEvent
|
||||
import no.nordicsemi.android.prx.view.PRXState
|
||||
import no.nordicsemi.android.prx.view.TurnOffAlert
|
||||
import no.nordicsemi.android.prx.view.TurnOnAlert
|
||||
import no.nordicsemi.android.service.BleManagerStatus
|
||||
@@ -23,16 +25,25 @@ import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
internal class PRXViewModel @Inject constructor(
|
||||
private val repository: PRXRepository
|
||||
private val repository: PRXRepository,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
val state = repository.data.combine(repository.status) { data, status ->
|
||||
when (status) {
|
||||
BleManagerStatus.CONNECTING -> PRXState(LoadingState)
|
||||
BleManagerStatus.OK -> PRXState(DisplayDataState(data))
|
||||
BleManagerStatus.DISCONNECTED -> PRXState(DisplayDataState(data), false)
|
||||
BleManagerStatus.CONNECTING -> LoadingState
|
||||
BleManagerStatus.OK,
|
||||
BleManagerStatus.DISCONNECTED -> DisplayDataState(data)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState)
|
||||
|
||||
init {
|
||||
repository.status.onEach {
|
||||
if (it == BleManagerStatus.DISCONNECTED) {
|
||||
navigationManager.navigateUp()
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, PRXState(LoadingState))
|
||||
|
||||
fun onEvent(event: PRXScreenViewEvent) {
|
||||
when (event) {
|
||||
|
||||
@@ -9,6 +9,7 @@ dependencies {
|
||||
implementation libs.nordic.ble.common
|
||||
|
||||
implementation libs.nordic.log
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.bundles.compose
|
||||
implementation libs.androidx.core
|
||||
|
||||
@@ -16,21 +16,17 @@ import no.nordicsemi.android.theme.view.DeviceConnectingView
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
fun RSCSScreen(finishAction: () -> Unit) {
|
||||
fun RSCSScreen() {
|
||||
val viewModel: RSCSViewModel = hiltViewModel()
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
val context = LocalContext.current
|
||||
LaunchedEffect(state.isActive) {
|
||||
if (state.isActive) {
|
||||
LaunchedEffect(Unit) {
|
||||
val intent = Intent(context, RSCSService::class.java)
|
||||
context.startService(intent)
|
||||
} else {
|
||||
finishAction()
|
||||
}
|
||||
}
|
||||
|
||||
RSCSView(state.viewState) { viewModel.onEvent(it) }
|
||||
RSCSView(state) { viewModel.onEvent(it) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -2,11 +2,6 @@ package no.nordicsemi.android.rscs.view
|
||||
|
||||
import no.nordicsemi.android.rscs.data.RSCSData
|
||||
|
||||
internal data class RSCSState(
|
||||
val viewState: RSCSViewState,
|
||||
val isActive: Boolean = true
|
||||
)
|
||||
|
||||
internal sealed class RSCSViewState
|
||||
|
||||
internal object LoadingState : RSCSViewState()
|
||||
|
||||
@@ -5,12 +5,14 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.rscs.data.RSCSRepository
|
||||
import no.nordicsemi.android.rscs.view.DisconnectEvent
|
||||
import no.nordicsemi.android.rscs.view.DisplayDataState
|
||||
import no.nordicsemi.android.rscs.view.LoadingState
|
||||
import no.nordicsemi.android.rscs.view.RSCSState
|
||||
import no.nordicsemi.android.rscs.view.RSCScreenViewEvent
|
||||
import no.nordicsemi.android.service.BleManagerStatus
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
@@ -18,16 +20,25 @@ import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
internal class RSCSViewModel @Inject constructor(
|
||||
private val repository: RSCSRepository
|
||||
private val repository: RSCSRepository,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
val state = repository.data.combine(repository.status) { data, status ->
|
||||
when (status) {
|
||||
BleManagerStatus.CONNECTING -> RSCSState(LoadingState)
|
||||
BleManagerStatus.OK -> RSCSState(DisplayDataState(data))
|
||||
BleManagerStatus.DISCONNECTED -> RSCSState(DisplayDataState(data), false)
|
||||
BleManagerStatus.CONNECTING -> LoadingState
|
||||
BleManagerStatus.OK,
|
||||
BleManagerStatus.DISCONNECTED -> DisplayDataState(data)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState)
|
||||
|
||||
init {
|
||||
repository.status.onEach {
|
||||
if (it == BleManagerStatus.DISCONNECTED) {
|
||||
navigationManager.navigateUp()
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, RSCSState(LoadingState))
|
||||
|
||||
fun onEvent(event: RSCScreenViewEvent) {
|
||||
when (event) {
|
||||
|
||||
@@ -10,6 +10,7 @@ dependencies {
|
||||
|
||||
implementation libs.nordic.log
|
||||
implementation libs.nordic.theme
|
||||
implementation libs.nordic.navigation
|
||||
|
||||
implementation libs.bundles.compose
|
||||
implementation libs.androidx.core
|
||||
|
||||
@@ -16,21 +16,17 @@ import no.nordicsemi.android.uart.viewmodel.UARTViewModel
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
fun UARTScreen(finishAction: () -> Unit) {
|
||||
fun UARTScreen() {
|
||||
val viewModel: UARTViewModel = hiltViewModel()
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
val context = LocalContext.current
|
||||
LaunchedEffect(state.isActive) {
|
||||
if (state.isActive) {
|
||||
LaunchedEffect(Unit) {
|
||||
val intent = Intent(context, UARTService::class.java)
|
||||
context.startService(intent)
|
||||
} else if (!state.isActive) {
|
||||
finishAction()
|
||||
}
|
||||
}
|
||||
|
||||
UARTView(state.viewState) { viewModel.onEvent(it) }
|
||||
UARTView(state) { viewModel.onEvent(it) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -2,11 +2,6 @@ package no.nordicsemi.android.uart.view
|
||||
|
||||
import no.nordicsemi.android.uart.data.UARTData
|
||||
|
||||
internal data class UARTState(
|
||||
val viewState: UARTViewState,
|
||||
val isActive: Boolean = true
|
||||
)
|
||||
|
||||
internal sealed class UARTViewState
|
||||
|
||||
internal object LoadingState : UARTViewState()
|
||||
|
||||
@@ -5,7 +5,10 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import no.nordicsemi.android.navigation.NavigationManager
|
||||
import no.nordicsemi.android.service.BleManagerStatus
|
||||
import no.nordicsemi.android.uart.data.DisconnectCommand
|
||||
import no.nordicsemi.android.uart.data.SendTextCommand
|
||||
@@ -16,23 +19,31 @@ import no.nordicsemi.android.uart.view.OnCreateMacro
|
||||
import no.nordicsemi.android.uart.view.OnDeleteMacro
|
||||
import no.nordicsemi.android.uart.view.OnDisconnectButtonClick
|
||||
import no.nordicsemi.android.uart.view.OnRunMacro
|
||||
import no.nordicsemi.android.uart.view.UARTState
|
||||
import no.nordicsemi.android.uart.view.UARTViewEvent
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
internal class UARTViewModel @Inject constructor(
|
||||
private val repository: UARTRepository
|
||||
private val repository: UARTRepository,
|
||||
private val navigationManager: NavigationManager
|
||||
) : ViewModel() {
|
||||
|
||||
val state = repository.data.combine(repository.status) { data, status ->
|
||||
when (status) {
|
||||
BleManagerStatus.CONNECTING -> UARTState(LoadingState)
|
||||
BleManagerStatus.OK -> UARTState(DisplayDataState(data))
|
||||
BleManagerStatus.DISCONNECTED -> UARTState(DisplayDataState(data), false)
|
||||
BleManagerStatus.CONNECTING -> LoadingState
|
||||
BleManagerStatus.OK,
|
||||
BleManagerStatus.DISCONNECTED -> DisplayDataState(data)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, LoadingState)
|
||||
|
||||
init {
|
||||
repository.status.onEach {
|
||||
if (it == BleManagerStatus.DISCONNECTED) {
|
||||
navigationManager.navigateUp()
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
}.stateIn(viewModelScope, SharingStarted.Lazily, UARTState(LoadingState))
|
||||
|
||||
fun onEvent(event: UARTViewEvent) {
|
||||
when (event) {
|
||||
|
||||
@@ -11,6 +11,7 @@ dependencyResolutionManagement {
|
||||
|
||||
versionCatalogs {
|
||||
libs {
|
||||
alias('nordic-navigation').to('no.nordicsemi.android.common:navigation:1.0.0')
|
||||
alias('nordic-theme').to('no.nordicsemi.android.common:theme:1.0.0')
|
||||
alias('nordic-ble-common').to('no.nordicsemi.android:ble-common:2.3.1')
|
||||
alias('nordic-log').to('no.nordicsemi.android:log:2.3.0')
|
||||
@@ -76,11 +77,13 @@ include ':app'
|
||||
include ':profile_bps'
|
||||
include ':profile_cgms'
|
||||
include ':profile_csc'
|
||||
include ':profile_dfu'
|
||||
include ':profile_gls'
|
||||
include ':profile_hrs'
|
||||
include ':profile_hts'
|
||||
include ':profile_prx'
|
||||
include ':profile_rscs'
|
||||
include ':profile_uart'
|
||||
|
||||
include ':lib_service'
|
||||
include ':lib_theme'
|
||||
@@ -89,13 +92,3 @@ include ':lib_utils'
|
||||
if (file('../Android-Common-Libraries').exists()) {
|
||||
includeBuild('../Android-Common-Libraries')
|
||||
}
|
||||
|
||||
//if (file('../Android-BLE-Library').exists()) {
|
||||
// includeBuild('../Android-BLE-Library')
|
||||
//}
|
||||
//
|
||||
//if (file('../Android-Scanner-Compat-Library').exists()) {
|
||||
// includeBuild('../Android-Scanner-Compat-Library')
|
||||
//}
|
||||
include ':profile_uart'
|
||||
include ':profile_dfu'
|
||||
|
||||
Reference in New Issue
Block a user