diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt index 39af1476..d161d98a 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt @@ -17,11 +17,15 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowUpward import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material3.Card import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBar @@ -31,6 +35,7 @@ import androidx.compose.material3.SheetValue import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -39,6 +44,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ClipboardManager +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.text.toLowerCase @@ -126,6 +132,36 @@ fun sendResult( activity?.finish() } +@Composable +fun GoToTop(goToTop: () -> Unit) { + FloatingActionButton( + onClick = goToTop + ) { + Icon( + Icons.Default.ArrowUpward, + contentDescription = stringResource(R.string.go_to_top) + ) + } +} + +@Composable +fun LazyListState.isScrollingUp(): Boolean { + var previousIndex by remember(this) { mutableStateOf(firstVisibleItemIndex) } + var previousScrollOffset by remember(this) { mutableStateOf(firstVisibleItemScrollOffset) } + return remember(this) { + derivedStateOf { + if (previousIndex != firstVisibleItemIndex) { + previousIndex > firstVisibleItemIndex + } else { + previousScrollOffset >= firstVisibleItemScrollOffset + }.also { + previousIndex = firstVisibleItemIndex + previousScrollOffset = firstVisibleItemScrollOffset + } + } + }.value +} + @OptIn(ExperimentalMaterial3Api::class) @Composable fun MainScreen( @@ -145,8 +181,18 @@ fun MainScreen( skipPartiallyExpanded = true ) val scope = rememberCoroutineScope() + val listState = rememberLazyListState() Scaffold( + floatingActionButton = { + if (navBackStackEntry?.destination?.route?.contains("History") == true) { + GoToTop { + scope.launch { + listState.scrollToItem(0) + } + } + } + }, topBar = { if (shouldShowBottomSheet) { AccountsBottomSheet( @@ -268,7 +314,8 @@ fun MainScreen( Modifier .fillMaxSize() .padding(padding) - .padding(16.dp) + .padding(16.dp), + state = listState ) { items(history.size) { Card( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ca00751b..3e004ac4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -79,4 +79,5 @@ Data copied to the clipboard Message already encrypted Relay + go to top \ No newline at end of file