mirror of
https://github.com/Ashinch/ReadYou.git
synced 2025-02-07 15:48:50 +01:00
feat(ui): click on top bar to scroll back to top
This commit is contained in:
parent
fe22c445f0
commit
05b249b708
@ -17,17 +17,19 @@ import me.ash.reader.ui.theme.palette.onDark
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun RYScaffold(
|
||||
modifier: Modifier = Modifier,
|
||||
containerColor: Color = MaterialTheme.colorScheme.surface,
|
||||
topBarTonalElevation: Dp = 0.dp,
|
||||
containerTonalElevation: Dp = 0.dp,
|
||||
navigationIcon: (@Composable () -> Unit)? = null,
|
||||
actions: (@Composable RowScope.() -> Unit)? = null,
|
||||
topBar: (@Composable () -> Unit)? = null,
|
||||
bottomBar: (@Composable () -> Unit)? = null,
|
||||
floatingActionButton: (@Composable () -> Unit)? = null,
|
||||
content: @Composable () -> Unit = {},
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
modifier = modifier
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceColorAtElevation(
|
||||
topBarTonalElevation,
|
||||
@ -39,7 +41,7 @@ fun RYScaffold(
|
||||
color = containerColor
|
||||
) onDark MaterialTheme.colorScheme.surface,
|
||||
topBar = {
|
||||
if (navigationIcon != null || actions != null) {
|
||||
if (topBar != null) topBar() else if (navigationIcon != null || actions != null) {
|
||||
TopAppBar(
|
||||
title = {},
|
||||
navigationIcon = { navigationIcon?.invoke() },
|
||||
|
@ -2,6 +2,7 @@ package me.ash.reader.ui.page.home.feeds
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@ -31,6 +32,8 @@ import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
|
||||
import androidx.compose.runtime.Composable
|
||||
@ -76,6 +79,7 @@ import me.ash.reader.ui.ext.currentAccountId
|
||||
import me.ash.reader.ui.ext.findActivity
|
||||
import me.ash.reader.ui.ext.getCurrentVersion
|
||||
import me.ash.reader.ui.ext.getDefaultGroupId
|
||||
import me.ash.reader.ui.ext.surfaceColorAtElevation
|
||||
import me.ash.reader.ui.page.common.RouteName
|
||||
import me.ash.reader.ui.page.home.FilterState
|
||||
import me.ash.reader.ui.page.home.HomeViewModel
|
||||
@ -207,29 +211,50 @@ fun FeedsPage(
|
||||
RYScaffold(
|
||||
topBarTonalElevation = topBarTonalElevation.value.dp,
|
||||
containerTonalElevation = groupListTonalElevation.value.dp,
|
||||
navigationIcon = {
|
||||
FeedbackIconButton(
|
||||
modifier = Modifier.size(20.dp),
|
||||
imageVector = Icons.Outlined.Settings,
|
||||
contentDescription = stringResource(R.string.settings),
|
||||
tint = MaterialTheme.colorScheme.onSurface,
|
||||
showBadge = newVersion.whetherNeedUpdate(currentVersion, skipVersion),
|
||||
) {
|
||||
navController.navigate(RouteName.SETTINGS) {
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
if (subscribeViewModel.rssService.get().addSubscription) {
|
||||
FeedbackIconButton(
|
||||
imageVector = Icons.Rounded.Add,
|
||||
contentDescription = stringResource(R.string.subscribe),
|
||||
tint = MaterialTheme.colorScheme.onSurface,
|
||||
) {
|
||||
subscribeViewModel.showDrawer()
|
||||
}
|
||||
}
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
modifier = Modifier.clickable(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
if (listState.firstVisibleItemIndex != 0) {
|
||||
listState.animateScrollToItem(0)
|
||||
}
|
||||
}
|
||||
},
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
),
|
||||
title = {},
|
||||
navigationIcon = {
|
||||
FeedbackIconButton(
|
||||
modifier = Modifier.size(20.dp),
|
||||
imageVector = Icons.Outlined.Settings,
|
||||
contentDescription = stringResource(R.string.settings),
|
||||
tint = MaterialTheme.colorScheme.onSurface,
|
||||
showBadge = newVersion.whetherNeedUpdate(currentVersion, skipVersion),
|
||||
) {
|
||||
navController.navigate(RouteName.SETTINGS) {
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
if (subscribeViewModel.rssService.get().addSubscription) {
|
||||
FeedbackIconButton(
|
||||
imageVector = Icons.Rounded.Add,
|
||||
contentDescription = stringResource(R.string.subscribe),
|
||||
tint = MaterialTheme.colorScheme.onSurface,
|
||||
) {
|
||||
subscribeViewModel.showDrawer()
|
||||
}
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
|
||||
topBarTonalElevation.value.dp
|
||||
),
|
||||
)
|
||||
)
|
||||
},
|
||||
content = {
|
||||
PullToRefreshBox(
|
||||
|
@ -1,6 +1,8 @@
|
||||
package me.ash.reader.ui.page.home.flow
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@ -15,7 +17,10 @@ import androidx.compose.material.icons.automirrored.rounded.ArrowBack
|
||||
import androidx.compose.material.icons.rounded.DoneAll
|
||||
import androidx.compose.material.icons.rounded.Search
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.LargeTopAppBar
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
|
||||
import androidx.compose.runtime.Composable
|
||||
@ -61,6 +66,7 @@ import me.ash.reader.ui.component.base.FeedbackIconButton
|
||||
import me.ash.reader.ui.component.base.RYExtensibleVisibility
|
||||
import me.ash.reader.ui.component.base.RYScaffold
|
||||
import me.ash.reader.ui.ext.collectAsStateValue
|
||||
import me.ash.reader.ui.ext.surfaceColorAtElevation
|
||||
import me.ash.reader.ui.page.common.RouteName
|
||||
import me.ash.reader.ui.page.home.HomeViewModel
|
||||
|
||||
@ -228,64 +234,78 @@ fun FlowPage(
|
||||
RYScaffold(
|
||||
topBarTonalElevation = topBarTonalElevation.value.dp,
|
||||
containerTonalElevation = articleListTonalElevation.value.dp,
|
||||
navigationIcon = {
|
||||
FeedbackIconButton(
|
||||
imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
|
||||
contentDescription = stringResource(R.string.back),
|
||||
tint = MaterialTheme.colorScheme.onSurface
|
||||
) {
|
||||
onSearch = false
|
||||
if (navController.previousBackStackEntry == null) {
|
||||
navController.navigate(RouteName.FEEDS) {
|
||||
launchSingleTop = true
|
||||
}
|
||||
} else {
|
||||
navController.popBackStack()
|
||||
}
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
RYExtensibleVisibility(visible = !filterUiState.filter.isStarred()) {
|
||||
FeedbackIconButton(
|
||||
imageVector = Icons.Rounded.DoneAll,
|
||||
contentDescription = stringResource(R.string.mark_all_as_read),
|
||||
tint = if (markAsRead) {
|
||||
MaterialTheme.colorScheme.primary
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
) {
|
||||
scope.launch {
|
||||
// java.lang.NullPointerException: Attempt to invoke virtual method
|
||||
// 'boolean androidx.compose.ui.node.LayoutNode.getNeedsOnPositionedDispatch$ui_release()'
|
||||
// on a null object reference
|
||||
if (flowUiState.listState.firstVisibleItemIndex != 0) {
|
||||
flowUiState.listState.scrollToItem(0)
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
modifier = Modifier.clickable(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
if (listState.firstVisibleItemIndex != 0) {
|
||||
listState.animateScrollToItem(0)
|
||||
}
|
||||
}
|
||||
markAsRead = !markAsRead
|
||||
},
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
),
|
||||
title = {},
|
||||
navigationIcon = {
|
||||
FeedbackIconButton(
|
||||
imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
|
||||
contentDescription = stringResource(R.string.back),
|
||||
tint = MaterialTheme.colorScheme.onSurface
|
||||
) {
|
||||
onSearch = false
|
||||
if (navController.previousBackStackEntry == null) {
|
||||
navController.navigate(RouteName.FEEDS) {
|
||||
launchSingleTop = true
|
||||
}
|
||||
} else {
|
||||
navController.popBackStack()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FeedbackIconButton(
|
||||
imageVector = Icons.Rounded.Search,
|
||||
contentDescription = stringResource(R.string.search),
|
||||
tint = if (onSearch) {
|
||||
MaterialTheme.colorScheme.primary
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
) {
|
||||
scope.launch {
|
||||
// java.lang.NullPointerException: Attempt to invoke virtual method
|
||||
// 'boolean androidx.compose.ui.node.LayoutNode.getNeedsOnPositionedDispatch$ui_release()'
|
||||
// on a null object reference
|
||||
if (flowUiState.listState.firstVisibleItemIndex != 0) {
|
||||
flowUiState.listState.scrollToItem(0)
|
||||
actions = {
|
||||
RYExtensibleVisibility(visible = !filterUiState.filter.isStarred()) {
|
||||
FeedbackIconButton(
|
||||
imageVector = Icons.Rounded.DoneAll,
|
||||
contentDescription = stringResource(R.string.mark_all_as_read),
|
||||
tint = if (markAsRead) {
|
||||
MaterialTheme.colorScheme.primary
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
) {
|
||||
scope.launch {
|
||||
if (flowUiState.listState.firstVisibleItemIndex != 0) {
|
||||
flowUiState.listState.animateScrollToItem(0)
|
||||
}
|
||||
markAsRead = !markAsRead
|
||||
onSearch = false
|
||||
}
|
||||
}
|
||||
}
|
||||
onSearch = !onSearch
|
||||
}
|
||||
}
|
||||
FeedbackIconButton(
|
||||
imageVector = Icons.Rounded.Search,
|
||||
contentDescription = stringResource(R.string.search),
|
||||
tint = if (onSearch) {
|
||||
MaterialTheme.colorScheme.primary
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
) {
|
||||
scope.launch {
|
||||
if (flowUiState.listState.firstVisibleItemIndex != 0) {
|
||||
flowUiState.listState.animateScrollToItem(0)
|
||||
}
|
||||
onSearch = !onSearch
|
||||
}
|
||||
}
|
||||
}, colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
|
||||
topBarTonalElevation.value.dp
|
||||
),
|
||||
)
|
||||
)
|
||||
},
|
||||
content = {
|
||||
PullToRefreshBox(
|
||||
@ -394,9 +414,6 @@ fun FlowPage(
|
||||
filterBarTonalElevation = filterBarTonalElevation.value.dp,
|
||||
) {
|
||||
scope.launch {
|
||||
// java.lang.NullPointerException: Attempt to invoke virtual method
|
||||
// 'boolean androidx.compose.ui.node.LayoutNode.getNeedsOnPositionedDispatch$ui_release()'
|
||||
// on a null object reference
|
||||
if (flowUiState.listState.firstVisibleItemIndex != 0) {
|
||||
flowUiState.listState.animateScrollToItem(0)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user