style: apply spotless formatting

This commit is contained in:
James Rich
2026-03-26 22:17:16 -05:00
parent 48ac9a9019
commit 763a8f8b07
8 changed files with 37 additions and 68 deletions

View File

@@ -173,7 +173,8 @@ class MainActivity : ComponentActivity() {
},
org.meshtastic.core.ui.util.LocalTracerouteMapScreenProvider provides
{ destNum, requestId, logUuid, onNavigateUp ->
val metricsViewModel = koinViewModel<org.meshtastic.feature.node.metrics.MetricsViewModel> {
val metricsViewModel =
koinViewModel<org.meshtastic.feature.node.metrics.MetricsViewModel> {
org.koin.core.parameter.parametersOf(destNum)
}
metricsViewModel.setNodeId(destNum)

View File

@@ -61,7 +61,7 @@ fun MainScreen() {
MeshtasticNavigationSuite(
multiBackstack = multiBackstack,
uiViewModel = viewModel,
modifier = Modifier.fillMaxSize()
modifier = Modifier.fillMaxSize(),
) {
val provider =
entryProvider<NavKey> {

View File

@@ -26,9 +26,7 @@ import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.rememberNavBackStack
/**
* Manages independent backstacks for multiple tabs.
*/
/** Manages independent backstacks for multiple tabs. */
class MultiBackstack(val startTab: NavKey) {
var backStacks: Map<NavKey, NavBackStack<NavKey>> = emptyMap()
@@ -38,9 +36,7 @@ class MultiBackstack(val startTab: NavKey) {
val activeBackStack: NavBackStack<NavKey>
get() = backStacks[currentTabRoute] ?: error("Stack for $currentTabRoute not found")
/**
* Switches to a new top-level tab route.
*/
/** Switches to a new top-level tab route. */
fun navigateTopLevel(route: NavKey) {
val rootKey = TopLevelDestination.fromNavKey(route)?.route ?: route
@@ -53,25 +49,21 @@ class MultiBackstack(val startTab: NavKey) {
}
}
/**
* Handles back navigation according to the "exit through home" pattern.
*/
/** Handles back navigation according to the "exit through home" pattern. */
fun goBack() {
val currentStack = activeBackStack
if (currentStack.size > 1) {
currentStack.removeLastOrNull()
return
}
// If we're at the root of a non-start tab, switch back to the start tab
if (currentTabRoute != startTab) {
currentTabRoute = startTab
}
}
/**
* Sets the active tab and replaces its stack with the provided route path.
*/
/** Sets the active tab and replaces its stack with the provided route path. */
fun handleDeepLink(navKeys: List<NavKey>) {
val rootKey = navKeys.firstOrNull() ?: return
val topLevel = TopLevelDestination.fromNavKey(rootKey)?.route ?: rootKey
@@ -81,21 +73,17 @@ class MultiBackstack(val startTab: NavKey) {
}
}
/**
* Remembers a [MultiBackstack] for managing independent tab navigation histories with Navigation 3.
*/
/** Remembers a [MultiBackstack] for managing independent tab navigation histories with Navigation 3. */
@Composable
fun rememberMultiBackstack(initialTab: NavKey = TopLevelDestination.Connections.route): MultiBackstack {
val stacks = mutableMapOf<NavKey, NavBackStack<NavKey>>()
TopLevelDestination.entries.forEach { dest ->
key(dest.route) {
stacks[dest.route] = rememberNavBackStack(MeshtasticNavSavedStateConfig, dest.route)
}
key(dest.route) { stacks[dest.route] = rememberNavBackStack(MeshtasticNavSavedStateConfig, dest.route) }
}
val multiBackstack = remember { MultiBackstack(initialTab) }
multiBackstack.backStacks = stacks
return multiBackstack
}

View File

@@ -37,16 +37,14 @@ fun MeshtasticAppShell(
content: @Composable () -> Unit,
) {
LaunchedEffect(uiViewModel) {
uiViewModel.navigationDeepLink.collect { navKeys ->
multiBackstack.handleDeepLink(navKeys)
}
uiViewModel.navigationDeepLink.collect { navKeys -> multiBackstack.handleDeepLink(navKeys) }
}
MeshtasticCommonAppSetup(
uiViewModel = uiViewModel,
onNavigateToTracerouteMap = { destNum, requestId, logUuid ->
multiBackstack.activeBackStack.add(
NodeDetailRoutes.TracerouteMap(destNum = destNum, requestId = requestId, logUuid = logUuid)
NodeDetailRoutes.TracerouteMap(destNum = destNum, requestId = requestId, logUuid = logUuid),
)
},
)

View File

@@ -42,9 +42,7 @@ import androidx.navigation3.scene.SinglePaneSceneStrategy
import androidx.navigation3.ui.NavDisplay
import org.meshtastic.core.navigation.MultiBackstack
/**
* Duration in milliseconds for the shared crossfade transition between navigation scenes.
*/
/** Duration in milliseconds for the shared crossfade transition between navigation scenes. */
private const val TRANSITION_DURATION_MS = 350
/**
@@ -64,13 +62,11 @@ fun MeshtasticNavDisplay(
backStack = backStack,
onBack = { multiBackstack.goBack() },
entryProvider = entryProvider,
modifier = modifier
modifier = modifier,
)
}
/**
* Shared [NavDisplay] wrapper for a single backstack.
*/
/** Shared [NavDisplay] wrapper for a single backstack. */
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun MeshtasticNavDisplay(
@@ -114,20 +110,21 @@ fun MeshtasticNavDisplay(
val saveableDecorator = rememberSaveableStateHolderNavEntryDecorator<NavKey>()
val vmStoreDecorator = rememberViewModelStoreNavEntryDecorator<NavKey>()
val activeDecorators = remember(backStack, saveableDecorator, vmStoreDecorator) {
listOf(saveableDecorator, vmStoreDecorator)
}
val activeDecorators =
remember(backStack, saveableDecorator, vmStoreDecorator) { listOf(saveableDecorator, vmStoreDecorator) }
NavDisplay(
backStack = backStack,
entryProvider = entryProvider,
entryDecorators = activeDecorators,
onBack = onBack ?: {
if (backStack.size > 1) {
backStack.removeLastOrNull()
}
},
onBack =
onBack
?: {
if (backStack.size > 1) {
backStack.removeLastOrNull()
}
},
sceneStrategies =
listOf(
DialogSceneStrategy(),
@@ -141,9 +138,7 @@ fun MeshtasticNavDisplay(
)
}
/**
* Shared crossfade [ContentTransform] used for both forward and pop navigation.
*/
/** Shared crossfade [ContentTransform] used for both forward and pop navigation. */
private fun meshtasticTransitionSpec(): AnimatedContentTransitionScope<Scene<NavKey>>.() -> ContentTransform = {
ContentTransform(
fadeIn(animationSpec = tween(TRANSITION_DURATION_MS)),

View File

@@ -46,7 +46,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation3.runtime.NavKey
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.ConnectionState
import org.meshtastic.core.model.DeviceType
@@ -65,8 +64,8 @@ import org.meshtastic.core.ui.viewmodel.UIViewModel
/**
* Shared adaptive navigation shell using [NavigationSuiteScaffold].
*
* This implementation uses the [MultiBackstack] state holder to manage independent histories for each tab,
* aligning with Navigation 3 best practices for state preservation during tab switching.
* This implementation uses the [MultiBackstack] state holder to manage independent histories for each tab, aligning
* with Navigation 3 best practices for state preservation during tab switching.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -81,7 +80,7 @@ fun MeshtasticNavigationSuite(
val selectedDevice by uiViewModel.currentDeviceAddressFlow.collectAsStateWithLifecycle()
val adaptiveInfo = currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true)
val currentTabRoute = multiBackstack.currentTabRoute
val topLevelDestination = TopLevelDestination.fromNavKey(currentTabRoute)
@@ -96,9 +95,7 @@ fun MeshtasticNavigationSuite(
val isSelected = destination == topLevelDestination
item(
selected = isSelected,
onClick = {
handleNavigation(destination, topLevelDestination, multiBackstack, uiViewModel)
},
onClick = { handleNavigation(destination, topLevelDestination, multiBackstack, uiViewModel) },
icon = {
NavigationIconContent(
destination = destination,

View File

@@ -36,19 +36,16 @@ import androidx.compose.ui.graphics.toComposeImageBitmap
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.isMetaPressed
import androidx.compose.ui.input.key.isShiftPressed
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.type
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Notification
import androidx.compose.ui.window.Tray
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberTrayState
import androidx.compose.ui.window.rememberWindowState
import androidx.navigation3.runtime.NavKey
import co.touchlab.kermit.Logger
import coil3.ImageLoader
import coil3.compose.setSingletonImageLoaderFactory
@@ -76,9 +73,7 @@ import org.meshtastic.desktop.ui.DesktopMainScreen
import java.awt.Desktop
import java.util.Locale
/**
* Meshtastic Desktop — the first non-Android target for the shared KMP module graph.
*/
/** Meshtastic Desktop — the first non-Android target for the shared KMP module graph. */
private val LocalAppLocale = staticCompositionLocalOf { "" }
private const val MEMORY_CACHE_MAX_BYTES = 64L * 1024L * 1024L // 64 MiB
@@ -160,9 +155,7 @@ fun main(args: Array<String>) = application(exitProcessOnExit = false) {
val windowState = rememberWindowState()
LaunchedEffect(Unit) {
notificationManager.notifications.collect { notification ->
trayState.sendNotification(notification)
}
notificationManager.notifications.collect { notification -> trayState.sendNotification(notification) }
}
LaunchedEffect(Unit) {

View File

@@ -33,12 +33,9 @@ import org.meshtastic.desktop.navigation.desktopNavGraph
/** Desktop main screen — uses shared navigation components. */
@Composable
fun DesktopMainScreen(
uiViewModel: UIViewModel,
multiBackstack: MultiBackstack,
) {
fun DesktopMainScreen(uiViewModel: UIViewModel, multiBackstack: MultiBackstack) {
val backStack = multiBackstack.activeBackStack
Surface(modifier = Modifier.fillMaxSize()) {
MeshtasticAppShell(
multiBackstack = multiBackstack,
@@ -54,7 +51,7 @@ fun DesktopMainScreen(
MeshtasticNavDisplay(
multiBackstack = multiBackstack,
entryProvider = provider,
modifier = Modifier.fillMaxSize()
modifier = Modifier.fillMaxSize(),
)
}
}