From b0cd4567538b9366effa2b369b86c3e1ac873d97 Mon Sep 17 00:00:00 2001 From: Colin Edwards Date: Sat, 6 Apr 2024 20:11:01 -0500 Subject: [PATCH] android: Button to jump to bottom of log view This adds a button that can jump to the bottom of the log view. If the user scrolls up we now disable the auto scroll down and show the down button. When the down button is clicked the auto scroll resumes and the button is removed. --- .../src/main/java/org/musicpd/ui/LogScreen.kt | 61 ++++++++++++++++--- .../main/java/org/musicpd/ui/MainScreen.kt | 2 +- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/android/app/src/main/java/org/musicpd/ui/LogScreen.kt b/android/app/src/main/java/org/musicpd/ui/LogScreen.kt index 8a1c14086..d76668819 100644 --- a/android/app/src/main/java/org/musicpd/ui/LogScreen.kt +++ b/android/app/src/main/java/org/musicpd/ui/LogScreen.kt @@ -1,36 +1,79 @@ package org.musicpd.ui -import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.VerticalAlignBottom +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.State +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @Composable -fun LogView(messages: State>) { - val state = rememberLazyListState() +fun LogView(messages: List) { + val lazyListState = rememberLazyListState() - Column(Modifier.fillMaxSize()) { + var userScrolled = remember { mutableStateOf(false) } + + LaunchedEffect(lazyListState) { + snapshotFlow { lazyListState.isScrollInProgress } + .collect { + if (it) { + userScrolled.value = true + } + } + } + + Box(Modifier.fillMaxSize()) { LazyColumn( Modifier.padding(4.dp), - state + lazyListState ) { - items(messages.value) { message -> + items(messages) { message -> Text(text = message, fontFamily = FontFamily.Monospace) } CoroutineScope(Dispatchers.Main).launch { - state.scrollToItem(messages.value.count(), 0) + lazyListState.scrollToItem(messages.count(), 0) + } + } + + if (lazyListState.canScrollForward) { + FloatingActionButton( + onClick = { + userScrolled.value = false + CoroutineScope(Dispatchers.Main).launch { + lazyListState.scrollToItem(messages.count(), 0) + } + }, + modifier = Modifier.padding(16.dp).align(Alignment.BottomEnd) + ) { + Icon(Icons.Filled.VerticalAlignBottom, "Scroll to bottom icon") } } } -} \ No newline at end of file +} + +@Preview +@Composable +fun LogViewPreview() { + val data = listOf("test", + "test2", + "test3") + LogView(data) +} diff --git a/android/app/src/main/java/org/musicpd/ui/MainScreen.kt b/android/app/src/main/java/org/musicpd/ui/MainScreen.kt index 54be709b1..d7dd975d4 100644 --- a/android/app/src/main/java/org/musicpd/ui/MainScreen.kt +++ b/android/app/src/main/java/org/musicpd/ui/MainScreen.kt @@ -69,7 +69,7 @@ fun MPDApp( StatusScreen(settingsViewModel) } composable(NavigationItem.Logs.route) { - LogView(settingsViewModel.getLogs().collectAsStateWithLifecycle()) + LogView(settingsViewModel.getLogs().collectAsStateWithLifecycle().value) } composable(NavigationItem.Settings.route) { MPDSettings(settingsViewModel)