WIP: tutorial screen

This commit is contained in:
Sylwester Zieliński
2022-05-04 14:13:14 +02:00
parent 718ef0f44a
commit 742d854b8b
19 changed files with 132 additions and 30 deletions

View File

@@ -15,6 +15,7 @@ sealed class BleManagerResult <T> {
}
}
class IdleResult<T> : BleManagerResult<T>()
class ConnectingResult<T> : BleManagerResult<T>()
data class SuccessResult<T>(val data: T) : BleManagerResult<T>()

View File

@@ -11,12 +11,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.bps.R
import no.nordicsemi.android.bps.viewmodel.BPSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.DeviceDisconnectedView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.ui.scanner.ui.Reason
@Composable
@@ -37,6 +36,7 @@ fun BPSScreen() {
when (state) {
NoDeviceState -> NoDeviceView()
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)

View File

@@ -11,12 +11,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.cgms.R
import no.nordicsemi.android.cgms.viewmodel.CGMScreenViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.DeviceDisconnectedView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.ui.scanner.ui.Reason
@Composable
@@ -35,6 +34,7 @@ fun CGMScreen() {
when (state) {
NoDeviceState -> NoDeviceView()
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)

View File

@@ -11,12 +11,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.csc.R
import no.nordicsemi.android.csc.viewmodel.CSCViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.DeviceDisconnectedView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.ui.scanner.ui.Reason
@Composable
@@ -35,6 +34,7 @@ fun CSCScreen() {
when (state.cscManagerState) {
NoDeviceState -> NoDeviceView()
is WorkingState -> when (state.cscManagerState.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(OnDisconnectButtonClick) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)

View File

@@ -11,12 +11,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.gls.R
import no.nordicsemi.android.gls.main.viewmodel.GLSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.DeviceDisconnectedView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.ui.scanner.ui.Reason
@Composable
@@ -37,6 +36,7 @@ fun GLSScreen() {
when (state) {
NoDeviceState -> NoDeviceView()
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)

View File

@@ -34,6 +34,7 @@ fun HRSScreen() {
when (state) {
NoDeviceState -> NoDeviceView()
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)

View File

@@ -11,12 +11,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.hts.R
import no.nordicsemi.android.hts.viewmodel.HTSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.DeviceDisconnectedView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.ui.scanner.ui.Reason
@Composable
@@ -35,6 +34,7 @@ fun HTSScreen() {
when (state.htsManagerState) {
NoDeviceState -> NoDeviceView()
is WorkingState -> when (state.htsManagerState.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)

View File

@@ -12,12 +12,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.prx.R
import no.nordicsemi.android.prx.viewmodel.PRXViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.DeviceDisconnectedView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.ui.scanner.ui.Reason
@Composable
@@ -36,6 +35,7 @@ fun PRXScreen() {
when (state) {
NoDeviceState -> NoDeviceView()
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceOutOfRangeView { viewModel.onEvent(DisconnectEvent) }

View File

@@ -11,12 +11,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.rscs.R
import no.nordicsemi.android.rscs.viewmodel.RSCSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.DeviceDisconnectedView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.ui.scanner.ui.Reason
@Composable
@@ -35,6 +34,7 @@ fun RSCSScreen() {
when (state) {
NoDeviceState -> NoDeviceView()
is WorkingState -> when (state.result) {
is IdleResult,
is ConnectingResult -> DeviceConnectingView { viewModel.onEvent(DisconnectEvent) }
is DisconnectedResult -> DeviceDisconnectedView(Reason.USER, navigateUp)
is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp)

View File

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

View File

@@ -10,7 +10,7 @@ import no.nordicsemi.android.ble.ktx.suspend
import no.nordicsemi.android.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.service.BleManagerResult
import no.nordicsemi.android.service.ConnectingResult
import no.nordicsemi.android.service.IdleResult
import no.nordicsemi.android.service.ServiceManager
import no.nordicsemi.android.uart.data.*
import javax.inject.Inject
@@ -22,14 +22,21 @@ class UARTRepository @Inject internal constructor(
private val context: Context,
private val serviceManager: ServiceManager,
private val configurationDataSource: ConfigurationDataSource,
private val toolboxLoggerFactory: ToolboxLoggerFactory
private val toolboxLoggerFactory: ToolboxLoggerFactory,
private val sp: UARTSharedPrefs
) {
private var manager: UARTManager? = null
private var logger: ToolboxLogger? = null
private val _data = MutableStateFlow<BleManagerResult<UARTData>>(ConnectingResult())
private val _data = MutableStateFlow<BleManagerResult<UARTData>>(IdleResult())
internal val data = _data.asStateFlow()
var showTutorial: Boolean
get() = sp.showTutorial
set(value) {
sp.showTutorial = value
}
val isRunning = data.map { it.isRunning() }
val hasBeenDisconnected = data.map { it.hasBeenDisconnected() }

View File

@@ -0,0 +1,20 @@
package no.nordicsemi.android.uart.repository
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
private const val FILE_NAME = "uart-sp"
private const val SHOW_TUTORIAL_FIELD = "show-tutorial"
class UARTSharedPrefs @Inject constructor(
@ApplicationContext
private val context: Context
) {
private val sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
var showTutorial: Boolean
get() = sp.getBoolean(SHOW_TUTORIAL_FIELD, true)
set(value) = sp.edit().putBoolean(SHOW_TUTORIAL_FIELD, value).apply()
}

View File

@@ -0,0 +1,9 @@
package no.nordicsemi.android.uart.view
import androidx.compose.runtime.Composable
@Composable
fun SettingsScreen() {
}

View File

@@ -0,0 +1,36 @@
package no.nordicsemi.android.uart.view
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import no.nordicsemi.android.material.you.Tutorial
import no.nordicsemi.android.uart.R
import no.nordicsemi.android.uart.viewmodel.UARTViewModel
@Composable
internal fun TutorialScreen(viewModel: UARTViewModel) {
val page1: @Composable () -> Unit = {
Image(
painter = painterResource(id = R.drawable.tutorial_1),
contentDescription = "",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
}
val page2: @Composable () -> Unit = {
Image(
painter = painterResource(id = R.drawable.tutorial_2),
contentDescription = "",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
}
Tutorial(listOf(page1, page2)) {
viewModel.onTutorialClose()
}
}

View File

@@ -9,14 +9,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.uart.R
import no.nordicsemi.android.uart.viewmodel.UARTViewModel
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.DeviceDisconnectedView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.ui.scanner.ui.Reason
@Composable
@@ -39,13 +38,24 @@ fun UARTScreen() {
when (state.uartManagerState) {
NoDeviceState -> NoDeviceView()
is WorkingState -> when (state.uartManagerState.result) {
is IdleResult,
is ConnectingResult -> Scroll { DeviceConnectingView { viewModel.onEvent(DisconnectEvent) } }
is DisconnectedResult -> Scroll { DeviceDisconnectedView(Reason.USER, navigateUp) }
is LinkLossResult -> Scroll { DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp) }
is MissingServiceResult -> Scroll { DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp) }
is UnknownErrorResult -> Scroll { DeviceDisconnectedView(Reason.UNKNOWN, navigateUp) }
is SuccessResult -> UARTContentView(state.uartManagerState.result.data, state) { viewModel.onEvent(it) }
is SuccessResult -> {
// val i1 = PagerViewEntity(
// listOf(
// PagerViewItem("aaa") { Text("aa") },
// PagerViewItem("bbb") { Text("bb") }
// )
// )
// PagerView(i1)
UARTContentView(state.uartManagerState.result.data, state) { viewModel.onEvent(it) }
}
}
TutorialState -> TutorialScreen(viewModel)
}.exhaustive
}
}

View File

@@ -29,3 +29,5 @@ internal sealed class HTSManagerState
internal data class WorkingState(val result: BleManagerResult<UARTData>) : HTSManagerState()
internal object NoDeviceState : HTSManagerState()
internal object TutorialState : HTSManagerState()

View File

@@ -7,6 +7,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import no.nordicsemi.android.navigation.*
import no.nordicsemi.android.service.IdleResult
import no.nordicsemi.android.uart.data.UARTConfiguration
import no.nordicsemi.android.uart.data.UARTMacro
import no.nordicsemi.android.uart.data.UARTPersistentDataSource
@@ -30,12 +31,17 @@ internal class UARTViewModel @Inject constructor(
init {
viewModelScope.launch {
if (repository.isRunning.firstOrNull() == false) {
if (repository.showTutorial) {
_state.value = _state.value.copy(uartManagerState = TutorialState)
} else if (repository.isRunning.firstOrNull() == false) {
requestBluetoothDevice()
}
}
repository.data.onEach {
if (it is IdleResult) {
return@onEach
}
_state.value = _state.value.copy(uartManagerState = WorkingState(it))
}.launchIn(viewModelScope)
@@ -87,6 +93,16 @@ internal class UARTViewModel @Inject constructor(
}.exhaustive
}
fun onTutorialClose() {
repository.showTutorial = false
_state.value = _state.value.copy(uartManagerState = NoDeviceState)
viewModelScope.launch {
if (repository.isRunning.firstOrNull() == false) {
requestBluetoothDevice()
}
}
}
private fun onMacroInputSwitch() {
_state.value = _state.value.copy(isInputVisible = !state.value.isInputVisible)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB