Start migration away from global top app bar (#3132)

This commit is contained in:
Phil Oliver 2025-09-17 18:38:22 -04:00 committed by GitHub
parent e4bfce0989
commit fed3ebbd36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 685 additions and 466 deletions

View file

@ -92,6 +92,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
@ -138,6 +139,7 @@ import com.geeksville.mesh.navigation.NodeDetailRoutes
import com.geeksville.mesh.navigation.Route
import com.geeksville.mesh.navigation.SettingsRoutes
import com.geeksville.mesh.service.ServiceAction
import com.geeksville.mesh.ui.common.components.MainAppBar
import com.geeksville.mesh.ui.common.components.TitledCard
import com.geeksville.mesh.ui.common.preview.NodePreviewParameterProvider
import com.geeksville.mesh.ui.common.theme.AppTheme
@ -176,12 +178,13 @@ private data class DrawableMetricInfo(
val rotateIcon: Float = 0f,
)
@Suppress("LongMethod")
@Composable
fun NodeDetailScreen(
modifier: Modifier = Modifier,
viewModel: MetricsViewModel = hiltViewModel(),
uiViewModel: UIViewModel = hiltViewModel(),
navigateToMessages: (String) -> Unit,
navigateToMessages: (String) -> Unit = {},
onNavigate: (Route) -> Unit = {},
onNavigateUp: () -> Unit = {},
) {
@ -189,6 +192,7 @@ fun NodeDetailScreen(
val environmentState by viewModel.environmentState.collectAsStateWithLifecycle()
val lastTracerouteTime by uiViewModel.lastTraceRouteTime.collectAsStateWithLifecycle()
val ourNode by uiViewModel.ourNodeInfo.collectAsStateWithLifecycle()
val isConnected by uiViewModel.isConnectedStateFlow.collectAsStateWithLifecycle(false)
val availableLogs by
remember(state, environmentState) {
@ -210,29 +214,49 @@ fun NodeDetailScreen(
}
val node = state.node
if (node != null) {
NodeDetailContent(
node = node,
ourNode = ourNode,
metricsState = state,
lastTracerouteTime = lastTracerouteTime,
availableLogs = availableLogs,
uiViewModel = uiViewModel,
onAction = { action ->
handleNodeAction(
action = action,
uiViewModel = uiViewModel,
node = node,
navigateToMessages = navigateToMessages,
onNavigateUp = onNavigateUp,
onNavigate = onNavigate,
viewModel = viewModel,
)
},
modifier = modifier,
)
} else {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { CircularProgressIndicator() }
@Suppress("ModifierNotUsedAtRoot")
Scaffold(
topBar = {
MainAppBar(
title = node?.user?.longName ?: "",
ourNode = ourNode,
isConnected = isConnected,
showNodeChip = false,
canNavigateUp = true,
onNavigateUp = onNavigateUp,
actions = {},
onAction = {},
)
},
) { paddingValues ->
if (node != null) {
@Suppress("ViewModelForwarding")
NodeDetailContent(
node = node,
ourNode = ourNode,
metricsState = state,
lastTracerouteTime = lastTracerouteTime,
availableLogs = availableLogs,
uiViewModel = uiViewModel,
onAction = { action ->
handleNodeAction(
action = action,
uiViewModel = uiViewModel,
node = node,
navigateToMessages = navigateToMessages,
onNavigateUp = onNavigateUp,
onNavigate = onNavigate,
viewModel = viewModel,
)
},
modifier = modifier.padding(paddingValues),
)
} else {
Box(modifier = Modifier.fillMaxSize().padding(paddingValues), contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
}
}
}

View file

@ -42,14 +42,17 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.DataPacket
import com.geeksville.mesh.R
import com.geeksville.mesh.model.DeviceVersion
import com.geeksville.mesh.model.Node
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.ui.common.components.MainAppBar
import com.geeksville.mesh.ui.common.components.rememberTimeTickWithLifecycle
import com.geeksville.mesh.ui.node.components.NodeFilterTextField
import com.geeksville.mesh.ui.node.components.NodeItem
@ -70,6 +73,8 @@ fun NodeScreen(
val nodes by model.nodeList.collectAsStateWithLifecycle()
val ourNode by model.ourNodeInfo.collectAsStateWithLifecycle()
val onlineNodeCount by model.onlineNodeCount.collectAsStateWithLifecycle(0)
val totalNodeCount by model.totalNodeCount.collectAsStateWithLifecycle(0)
val unfilteredNodes by model.unfilteredNodeList.collectAsStateWithLifecycle()
val ignoredNodeCount = unfilteredNodes.count { it.isIgnored }
@ -85,6 +90,19 @@ fun NodeScreen(
val isScrollInProgress by remember { derivedStateOf { listState.isScrollInProgress } }
Scaffold(
topBar = {
MainAppBar(
title = stringResource(R.string.nodes),
subtitle = stringResource(R.string.node_count_template, onlineNodeCount, totalNodeCount),
ourNode = ourNode,
isConnected = connectionState.isConnected(),
showNodeChip = false,
canNavigateUp = false,
onNavigateUp = {},
actions = {},
onAction = {},
)
},
floatingActionButton = {
val firmwareVersion = DeviceVersion(ourNode?.metadata?.firmwareVersion ?: "0.0.0")
val shareCapable = firmwareVersion.supportsQrCodeSharing()