Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,12 @@ package no.nordicsemi.android.common.test

import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import dagger.hilt.android.AndroidEntryPoint
import no.nordicsemi.android.common.navigation.*
import no.nordicsemi.android.common.permission.RequireBluetooth
import no.nordicsemi.android.common.test.view.mainDestinations
import no.nordicsemi.android.common.navigation.NavigationView
import no.nordicsemi.android.common.test.main.MainDestinations
import no.nordicsemi.android.common.test.scanner.ScannerDestinations
import no.nordicsemi.android.common.theme.NordicActivity
import no.nordicsemi.android.common.theme.NordicTheme
import no.nordicsemi.android.common.theme.view.NordicAppBar

@AndroidEntryPoint
class MainActivity : NordicActivity() {
Expand All @@ -54,40 +48,8 @@ class MainActivity : NordicActivity() {

setContent {
NordicTheme {
NavigationView(mainDestinations + otherDestinations)
NavigationView(MainDestinations + ScannerDestinations)
}
}
}
}
// --------------------------------------------------------------------------------


// ---------------------------------------------------------------------------------------------
val Details = DestinationId("details")

val otherDestinations = ComposeDestinations(listOf(
ComposeDestination(Details) { navigationManager ->
DetailsScreen(navigationManager)
},
))

data class DetailsParams(val index: Int) : NavigationArgument {
override val destinationId = Details
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DetailsScreen(
navigationManager: NavigationManager,
) {
Column {
NordicAppBar(
text = "Kaczka",
onNavigationButtonClick = { navigationManager.navigateUp() },
)
RequireBluetooth {
val index = navigationManager.getArgumentForId(Details).collectAsState(initial = DetailsParams(-1)).value as DetailsParams
Text(text = "Details ${index.index}")
}
}
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
package no.nordicsemi.android.common.test.view
package no.nordicsemi.android.common.test.main

import android.widget.Toast
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.common.logger.view.LoggerAppBarIcon
import androidx.compose.material3.ExperimentalMaterial3Api
import no.nordicsemi.android.common.navigation.ComposeDestination
import no.nordicsemi.android.common.navigation.ComposeDestinations
import no.nordicsemi.android.common.navigation.DestinationId
import no.nordicsemi.android.common.navigation.NavigationManager
import no.nordicsemi.android.common.navigation.*
import no.nordicsemi.android.common.test.R
import no.nordicsemi.android.common.test.view.page.*
import no.nordicsemi.android.common.test.main.page.*
import no.nordicsemi.android.common.theme.view.NordicAppBar
import no.nordicsemi.android.common.theme.view.PagerView
import no.nordicsemi.android.common.theme.view.PagerViewEntity

val Main = DestinationId("main")
/** This is the destination identifier. */
val Main = createDestination("main")

/**
* List of destinations defined in the module.
*
* Optionally, this can define a local Router for routing navigation within the module.
*/
private val MainDestination = defineDestination(Main) {
MainScreen()
}

val mainDestinations = ComposeDestinations(listOf(
ComposeDestination(Main) { navigationManager ->
MainScreen(navigationManager)
},
))
val MainDestinations = MainDestination.asDestinations()

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(
navigationManager: NavigationManager,
) {
private fun MainScreen() {
Column {
NordicAppBar(
text = stringResource(id = R.string.title_main),
Expand All @@ -46,10 +47,10 @@ fun MainScreen(
)
val pages = PagerViewEntity(listOf(
BasicsPage,
Fonts,
Wizard,
Connection,
Warning,
FontsPage,
WizardPage,
ConnectionPage,
WarningPage,
))
PagerView(
viewEntity = pages,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,96 @@
package no.nordicsemi.android.common.test.view.page
package no.nordicsemi.android.common.test.main.page

import android.annotation.SuppressLint
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import no.nordicsemi.android.common.navigation.Navigator
import no.nordicsemi.android.common.test.R
import no.nordicsemi.android.common.test.scanner.Scanner
import no.nordicsemi.android.common.theme.NordicTheme
import no.nordicsemi.android.common.theme.view.PagerViewItem
import no.nordicsemi.android.common.theme.view.RssiIcon
import no.nordicsemi.android.common.ui.scanner.main.DeviceListItem
import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice
import javax.inject.Inject

val BasicsPage = PagerViewItem("Basics") {
BasicViews(
onOpenScanner = {}
val vm = hiltViewModel<BasicPageViewModel>()
val device by vm.device.collectAsState()

BasicViewsScreen(
device = device?.let { DeviceInfo(it) },
onOpenScanner = { vm.openScanner() }
)
}

private const val DEVICE_KEY = "device"

@HiltViewModel
class BasicPageViewModel @Inject constructor(
private val navigator: Navigator,
private val savedStateHandle: SavedStateHandle,
) : ViewModel() {
// Initialize the selected device from the saved state handle.
var device = savedStateHandle.getStateFlow<DiscoveredBluetoothDevice?>(DEVICE_KEY, null)
private set

init {
navigator.resultFrom(Scanner)
// Filter out results of cancelled navigation.
.filter { it != null }
// Save the result in SavedStateHandle.
.onEach { savedStateHandle[DEVICE_KEY] = it }
// And finally, launch the flow in the ViewModelScope.
.launchIn(viewModelScope)
}

fun openScanner() {
navigator.navigateTo(Scanner)
// As the "navigateForResult" coroutine uses navigation,
// it will use Dispatchers.Main context internally.
// Here we can use any dispatcher.
// viewModelScope.launch(Dispatchers.IO) {
// // Navigate and wait for the result.
// navigator.navigateForResult<DiscoveredBluetoothDevice>()
// // If the result was returned, update the device.
// // If user cancelled, the result will be null and we ignore it.
// ?.let { device.value = it }
// }
}
}

@SuppressLint("MissingPermission")
data class DeviceInfo(
private val device: DiscoveredBluetoothDevice?
) {
val name = device?.name ?: "Unknown"
val address = device?.address ?: "Unknown"
val rssi = device?.rssi ?: 0
}

@Composable
private fun BasicViews(
private fun BasicViewsScreen(
device: DeviceInfo?,
onOpenScanner: () -> Unit,
) {
Column(
Expand All @@ -46,26 +106,36 @@ private fun BasicViews(
Text(text = stringResource(id = R.string.action_scanner))
}

Device()
device?.let {
Device(
deviceName = it.name,
deviceAddress = it.address,
rssi = it.rssi,
)
}

BasicViews()
BasicViewsScreen()

Cards()
}
}

@Composable
private fun Device() {
private fun Device(
deviceName: String,
deviceAddress: String,
rssi: Int,
) {
Box(modifier = Modifier
.clip(RoundedCornerShape(10.dp))
.clickable { }
.padding(8.dp)
) {
DeviceListItem(
name = "Nordic Blinky",
address = "AA:BB:CC:DD:EE:FF",
name = deviceName,
address = deviceAddress,
) {
RssiIcon(rssi = -40)
RssiIcon(rssi = rssi)
}
}
}
Expand Down Expand Up @@ -134,7 +204,7 @@ private fun OtherWidgets() {
}

@Composable
private fun BasicViews() {
private fun BasicViewsScreen() {
Column {
Buttons()

Expand Down Expand Up @@ -185,7 +255,8 @@ private fun Cards() {
@Composable
private fun ContentPreview() {
NordicTheme {
BasicViews(
BasicViewsScreen(
device = null,
onOpenScanner = {}
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package no.nordicsemi.android.common.test.view.page
package no.nordicsemi.android.common.test.main.page

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
Expand All @@ -19,12 +19,12 @@ import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.common.ui.scanner.view.NoDeviceView
import no.nordicsemi.android.common.ui.scanner.view.Reason

val Connection = PagerViewItem("Connection") {
Connection()
val ConnectionPage = PagerViewItem("Connection") {
ConnectionScreen()
}

@Composable
private fun Connection() {
private fun ConnectionScreen() {
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
Expand Down Expand Up @@ -74,5 +74,5 @@ private fun Connection() {
@Preview
@Composable
private fun ConnectionPreview() {
Connection()
ConnectionScreen()
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package no.nordicsemi.android.common.test.view.page
package no.nordicsemi.android.common.test.main.page

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
Expand All @@ -12,12 +12,12 @@ import no.nordicsemi.android.common.test.R
import no.nordicsemi.android.common.theme.NordicTheme
import no.nordicsemi.android.common.theme.view.PagerViewItem

val Fonts = PagerViewItem("Fonts") {
Fonts()
val FontsPage = PagerViewItem("Fonts") {
FontsScreen()
}

@Composable
private fun Fonts() {
private fun FontsScreen() {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Expand Down Expand Up @@ -77,6 +77,6 @@ private fun Fonts() {
@Composable
private fun FontsPreview() {
NordicTheme {
Fonts()
FontsScreen()
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package no.nordicsemi.android.common.test.view.page
package no.nordicsemi.android.common.test.main.page

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
Expand All @@ -19,12 +19,12 @@ import no.nordicsemi.android.common.theme.NordicTheme
import no.nordicsemi.android.common.theme.view.PagerViewItem
import no.nordicsemi.android.common.theme.view.WarningView

val Warning = PagerViewItem("Warning") {
Warning()
val WarningPage = PagerViewItem("Warning") {
WarningScreen()
}

@Composable
private fun Warning() {
private fun WarningScreen() {
WarningView(
imageVector = Icons.Default.Paragliding,
title = stringResource(id = R.string.warning_title),
Expand Down Expand Up @@ -57,6 +57,6 @@ private fun Warning() {
@Composable
private fun WarningPreview() {
NordicTheme {
Warning()
WarningScreen()
}
}
Loading