feat: Add bottom-nav scroll-to-top handling for nodes and conversations (#3674)

This commit is contained in:
Mac DeCourcy 2025-11-12 14:22:21 -08:00 committed by GitHub
parent 00276bc5d4
commit bc8ff26167
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 176 additions and 13 deletions

View file

@ -44,10 +44,12 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.animateFloatingActionButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -56,6 +58,8 @@ import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DeviceVersion
@ -70,7 +74,9 @@ import org.meshtastic.core.strings.remove_favorite
import org.meshtastic.core.strings.remove_ignored
import org.meshtastic.core.ui.component.AddContactFAB
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.ScrollToTopEvent
import org.meshtastic.core.ui.component.rememberTimeTickWithLifecycle
import org.meshtastic.core.ui.component.smartScrollToTop
import org.meshtastic.core.ui.component.supportsQrCodeSharing
import org.meshtastic.core.ui.theme.StatusColors.StatusRed
import org.meshtastic.feature.node.component.NodeActionDialogs
@ -81,7 +87,11 @@ import org.meshtastic.proto.AdminProtos
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable
fun NodeListScreen(viewModel: NodeListViewModel = hiltViewModel(), navigateToNodeDetails: (Int) -> Unit) {
fun NodeListScreen(
navigateToNodeDetails: (Int) -> Unit,
viewModel: NodeListViewModel = hiltViewModel(),
scrollToTopEvents: Flow<ScrollToTopEvent>? = null,
) {
val state by viewModel.nodesUiState.collectAsStateWithLifecycle()
val nodes by viewModel.nodeList.collectAsStateWithLifecycle()
@ -92,6 +102,15 @@ fun NodeListScreen(viewModel: NodeListViewModel = hiltViewModel(), navigateToNod
val ignoredNodeCount = unfilteredNodes.count { it.isIgnored }
val listState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
LaunchedEffect(scrollToTopEvents) {
scrollToTopEvents?.collectLatest { event ->
if (event is ScrollToTopEvent.NodesTabPressed) {
listState.smartScrollToTop(coroutineScope)
}
}
}
val currentTimeMillis = rememberTimeTickWithLifecycle()
val connectionState by viewModel.connectionState.collectAsStateWithLifecycle()