mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat: settings rework (#4678)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
b2b21e10e2
commit
fdd07f893f
27 changed files with 941 additions and 306 deletions
|
|
@ -19,8 +19,11 @@
|
|||
package com.geeksville.mesh.navigation
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.composable
|
||||
|
|
@ -32,7 +35,11 @@ import org.meshtastic.core.navigation.NodesRoutes
|
|||
import org.meshtastic.core.navigation.Route
|
||||
import org.meshtastic.core.navigation.SettingsRoutes
|
||||
import org.meshtastic.feature.settings.AboutScreen
|
||||
import org.meshtastic.feature.settings.AdministrationScreen
|
||||
import org.meshtastic.feature.settings.DeviceConfigurationScreen
|
||||
import org.meshtastic.feature.settings.ModuleConfigurationScreen
|
||||
import org.meshtastic.feature.settings.SettingsScreen
|
||||
import org.meshtastic.feature.settings.SettingsViewModel
|
||||
import org.meshtastic.feature.settings.debugging.DebugScreen
|
||||
import org.meshtastic.feature.settings.filter.FilterSettingsScreen
|
||||
import org.meshtastic.feature.settings.navigation.ConfigRoute
|
||||
|
|
@ -76,6 +83,7 @@ fun NavGraphBuilder.settingsGraph(navController: NavHostController) {
|
|||
val parentEntry =
|
||||
remember(backStackEntry) { navController.getBackStackEntry(SettingsRoutes.SettingsGraph::class) }
|
||||
SettingsScreen(
|
||||
settingsViewModel = hiltViewModel(parentEntry),
|
||||
viewModel = hiltViewModel(parentEntry),
|
||||
onClickNodeChip = {
|
||||
navController.navigate(NodesRoutes.NodeDetailGraph(it)) {
|
||||
|
|
@ -84,10 +92,39 @@ fun NavGraphBuilder.settingsGraph(navController: NavHostController) {
|
|||
}
|
||||
},
|
||||
) {
|
||||
navController.navigate(it) { popUpTo(SettingsRoutes.Settings()) { inclusive = false } }
|
||||
navController.navigate(it)
|
||||
}
|
||||
}
|
||||
|
||||
composable<SettingsRoutes.DeviceConfiguration> { backStackEntry ->
|
||||
val parentEntry =
|
||||
remember(backStackEntry) { navController.getBackStackEntry(SettingsRoutes.SettingsGraph::class) }
|
||||
DeviceConfigurationScreen(
|
||||
viewModel = hiltViewModel(parentEntry),
|
||||
onBack = navController::popBackStack,
|
||||
onNavigate = { route -> navController.navigate(route) },
|
||||
)
|
||||
}
|
||||
|
||||
composable<SettingsRoutes.ModuleConfiguration> { backStackEntry ->
|
||||
val parentEntry =
|
||||
remember(backStackEntry) { navController.getBackStackEntry(SettingsRoutes.SettingsGraph::class) }
|
||||
val settingsViewModel: SettingsViewModel = hiltViewModel(parentEntry)
|
||||
val excludedModulesUnlocked by settingsViewModel.excludedModulesUnlocked.collectAsStateWithLifecycle()
|
||||
ModuleConfigurationScreen(
|
||||
viewModel = hiltViewModel(parentEntry),
|
||||
excludedModulesUnlocked = excludedModulesUnlocked,
|
||||
onBack = navController::popBackStack,
|
||||
onNavigate = { route -> navController.navigate(route) },
|
||||
)
|
||||
}
|
||||
|
||||
composable<SettingsRoutes.Administration> { backStackEntry ->
|
||||
val parentEntry =
|
||||
remember(backStackEntry) { navController.getBackStackEntry(SettingsRoutes.SettingsGraph::class) }
|
||||
AdministrationScreen(viewModel = hiltViewModel(parentEntry), onBack = navController::popBackStack)
|
||||
}
|
||||
|
||||
composable<SettingsRoutes.CleanNodeDb>(
|
||||
deepLinks =
|
||||
listOf(
|
||||
|
|
@ -104,6 +141,7 @@ fun NavGraphBuilder.settingsGraph(navController: NavHostController) {
|
|||
route = entry.route::class,
|
||||
parentGraphRoute = SettingsRoutes.SettingsGraph::class,
|
||||
) { viewModel ->
|
||||
LaunchedEffect(Unit) { viewModel.setResponseStateLoading(entry) }
|
||||
when (entry) {
|
||||
ConfigRoute.USER -> UserConfigScreen(viewModel, onBack = navController::popBackStack)
|
||||
|
||||
|
|
@ -133,6 +171,7 @@ fun NavGraphBuilder.settingsGraph(navController: NavHostController) {
|
|||
route = entry.route::class,
|
||||
parentGraphRoute = SettingsRoutes.SettingsGraph::class,
|
||||
) { viewModel ->
|
||||
LaunchedEffect(Unit) { viewModel.setResponseStateLoading(entry) }
|
||||
when (entry) {
|
||||
ModuleRoute.MQTT -> MQTTConfigScreen(viewModel, onBack = navController::popBackStack)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -35,7 +36,6 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import no.nordicsemi.android.common.core.simpleSharedFlow
|
||||
import org.meshtastic.core.analytics.platform.PlatformAnalytics
|
||||
import org.meshtastic.core.ble.BleError
|
||||
import org.meshtastic.core.ble.BluetoothRepository
|
||||
|
|
@ -82,10 +82,10 @@ constructor(
|
|||
private val _connectionState = MutableStateFlow<ConnectionState>(ConnectionState.Disconnected)
|
||||
val connectionState: StateFlow<ConnectionState> = _connectionState.asStateFlow()
|
||||
|
||||
private val _receivedData = simpleSharedFlow<ByteArray>()
|
||||
private val _receivedData = MutableSharedFlow<ByteArray>(extraBufferCapacity = 64)
|
||||
val receivedData: SharedFlow<ByteArray> = _receivedData
|
||||
|
||||
private val _connectionError = simpleSharedFlow<BleError>()
|
||||
private val _connectionError = MutableSharedFlow<BleError>(extraBufferCapacity = 64)
|
||||
val connectionError: SharedFlow<BleError> = _connectionError.asSharedFlow()
|
||||
|
||||
// Thread-safe StateFlow for tracking device address changes
|
||||
|
|
@ -371,7 +371,7 @@ constructor(
|
|||
serviceScope.handledLaunch { handleSendToRadio(a) }
|
||||
}
|
||||
|
||||
private val _meshActivity = simpleSharedFlow<MeshActivity>()
|
||||
private val _meshActivity = MutableSharedFlow<MeshActivity>(extraBufferCapacity = 64)
|
||||
val meshActivity: SharedFlow<MeshActivity> = _meshActivity.asSharedFlow()
|
||||
|
||||
private fun emitSendActivity() {
|
||||
|
|
|
|||
|
|
@ -94,6 +94,10 @@ constructor(
|
|||
radioConfigRepository?.channelSetFlow?.onEach { channelSet.value = it }?.launchIn(scope)
|
||||
}
|
||||
|
||||
fun getCachedLocalConfig(): LocalConfig = localConfig.value
|
||||
|
||||
fun getCachedChannelSet(): ChannelSet = channelSet.value
|
||||
|
||||
@VisibleForTesting internal constructor() : this(null, null, null, null)
|
||||
|
||||
fun getCurrentPacketId(): Long = currentPacketId.get()
|
||||
|
|
|
|||
|
|
@ -31,10 +31,8 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.meshtastic.core.common.hasLocationPermission
|
||||
import org.meshtastic.core.common.util.handledLaunch
|
||||
import org.meshtastic.core.common.util.toRemoteExceptions
|
||||
|
|
@ -249,9 +247,7 @@ class MeshService : Service() {
|
|||
|
||||
override fun send(p: DataPacket) = toRemoteExceptions { router.actionHandler.handleSend(p, myNodeNum) }
|
||||
|
||||
override fun getConfig(): ByteArray = toRemoteExceptions {
|
||||
runBlocking { radioConfigRepository.localConfigFlow.first().encode() }
|
||||
}
|
||||
override fun getConfig(): ByteArray = toRemoteExceptions { commandSender.getCachedLocalConfig().encode() }
|
||||
|
||||
override fun setConfig(payload: ByteArray) = toRemoteExceptions {
|
||||
router.actionHandler.handleSetConfig(payload, myNodeNum)
|
||||
|
|
@ -310,7 +306,7 @@ class MeshService : Service() {
|
|||
}
|
||||
|
||||
override fun getChannelSet(): ByteArray = toRemoteExceptions {
|
||||
runBlocking { radioConfigRepository.channelSetFlow.first().encode() }
|
||||
commandSender.getCachedChannelSet().encode()
|
||||
}
|
||||
|
||||
override fun getNodes(): List<NodeInfo> = nodeManager.getNodes()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue