Add scroll overlay to LibraryToolbar (#7669)

Works when category tab is not shown
This commit is contained in:
Ivan Iskandar 2022-08-04 04:41:15 +07:00 committed by GitHub
parent 3d4e56948d
commit afceac15c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 29 deletions

View File

@ -89,7 +89,7 @@ fun AppBar(
// Menu
actions: @Composable RowScope.() -> Unit = {},
// Action mode
isActionMode: Boolean,
isActionMode: Boolean = false,
onCancelActionMode: () -> Unit = {},
// Banners
downloadedOnlyMode: Boolean = false,

View File

@ -1,10 +1,17 @@
package eu.kanade.presentation.library
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import eu.kanade.domain.category.model.Category
import eu.kanade.presentation.components.LibraryBottomActionMenu
import eu.kanade.presentation.components.LoadingScreen
@ -30,21 +37,29 @@ fun LibraryScreen(
onClickFilter: () -> Unit,
onClickRefresh: (Category?) -> Unit,
) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val insets = WindowInsets.navigationBars.only(WindowInsetsSides.Horizontal)
Crossfade(targetState = presenter.isLoading) { state ->
when (state) {
true -> LoadingScreen()
false -> Scaffold(
modifier = Modifier.safeDrawingPadding(),
modifier = Modifier
.windowInsetsPadding(insets)
.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
val title by presenter.getToolbarTitle()
val tabVisible = presenter.tabVisibility && presenter.categories.size > 1
LibraryToolbar(
state = presenter,
title = title,
incognitoMode = !tabVisible && presenter.isIncognitoMode,
downloadedOnlyMode = !tabVisible && presenter.isDownloadOnly,
onClickUnselectAll = onClickUnselectAll,
onClickSelectAll = onClickSelectAll,
onClickInvertSelection = onClickInvertSelection,
onClickFilter = onClickFilter,
onClickRefresh = { onClickRefresh(null) },
scrollBehavior = scrollBehavior.takeIf { !tabVisible }, // For scroll overlay when no tab
)
},
bottomBar = {

View File

@ -5,8 +5,6 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.FilterList
import androidx.compose.material.icons.outlined.FlipToBack
import androidx.compose.material.icons.outlined.Refresh
@ -16,9 +14,9 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@ -28,10 +26,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.sp
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.Pill
import eu.kanade.presentation.library.LibraryState
import eu.kanade.presentation.theme.active
@ -41,29 +39,40 @@ import kotlinx.coroutines.delay
fun LibraryToolbar(
state: LibraryState,
title: LibraryToolbarTitle,
incognitoMode: Boolean,
downloadedOnlyMode: Boolean,
onClickUnselectAll: () -> Unit,
onClickSelectAll: () -> Unit,
onClickInvertSelection: () -> Unit,
onClickFilter: () -> Unit,
onClickRefresh: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior?,
) = when {
state.selectionMode -> LibrarySelectionToolbar(
state = state,
incognitoMode = incognitoMode,
downloadedOnlyMode = downloadedOnlyMode,
onClickUnselectAll = onClickUnselectAll,
onClickSelectAll = onClickSelectAll,
onClickInvertSelection = onClickInvertSelection,
)
state.searchQuery != null -> LibrarySearchToolbar(
searchQuery = state.searchQuery!!,
incognitoMode = incognitoMode,
downloadedOnlyMode = downloadedOnlyMode,
onChangeSearchQuery = { state.searchQuery = it },
onClickCloseSearch = { state.searchQuery = null },
scrollBehavior = scrollBehavior,
)
else -> LibraryRegularToolbar(
title = title,
hasFilters = state.hasActiveFilters,
incognitoMode = incognitoMode,
downloadedOnlyMode = downloadedOnlyMode,
onClickSearch = { state.searchQuery = "" },
onClickFilter = onClickFilter,
onClickRefresh = onClickRefresh,
scrollBehavior = scrollBehavior,
)
}
@ -71,14 +80,17 @@ fun LibraryToolbar(
fun LibraryRegularToolbar(
title: LibraryToolbarTitle,
hasFilters: Boolean,
incognitoMode: Boolean,
downloadedOnlyMode: Boolean,
onClickSearch: () -> Unit,
onClickFilter: () -> Unit,
onClickRefresh: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior?,
) {
val pillAlpha = if (isSystemInDarkTheme()) 0.12f else 0.08f
val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else LocalContentColor.current
SmallTopAppBar(
title = {
AppBar(
titleContent = {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = title.text,
@ -106,30 +118,28 @@ fun LibraryRegularToolbar(
Icon(Icons.Outlined.Refresh, contentDescription = "search")
}
},
incognitoMode = incognitoMode,
downloadedOnlyMode = downloadedOnlyMode,
scrollBehavior = scrollBehavior,
)
}
@Composable
fun LibrarySelectionToolbar(
state: LibraryState,
incognitoMode: Boolean,
downloadedOnlyMode: Boolean,
onClickUnselectAll: () -> Unit,
onClickSelectAll: () -> Unit,
onClickInvertSelection: () -> Unit,
) {
val backgroundColor by TopAppBarDefaults.smallTopAppBarColors().containerColor(1f)
SmallTopAppBar(
AppBar(
modifier = Modifier
.drawBehind {
drawRect(backgroundColor.copy(alpha = 1f))
},
navigationIcon = {
IconButton(onClick = onClickUnselectAll) {
Icon(Icons.Outlined.Close, contentDescription = "close")
}
},
title = {
Text(text = "${state.selection.size}")
},
titleContent = { Text(text = "${state.selection.size}") },
actions = {
IconButton(onClick = onClickSelectAll) {
Icon(Icons.Outlined.SelectAll, contentDescription = "search")
@ -138,27 +148,26 @@ fun LibrarySelectionToolbar(
Icon(Icons.Outlined.FlipToBack, contentDescription = "invert")
}
},
colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = Color.Transparent,
scrolledContainerColor = Color.Transparent,
),
isActionMode = true,
onCancelActionMode = onClickUnselectAll,
incognitoMode = incognitoMode,
downloadedOnlyMode = downloadedOnlyMode,
)
}
@Composable
fun LibrarySearchToolbar(
searchQuery: String,
incognitoMode: Boolean,
downloadedOnlyMode: Boolean,
onChangeSearchQuery: (String) -> Unit,
onClickCloseSearch: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior?,
) {
val focusRequester = remember { FocusRequester.Default }
SmallTopAppBar(
navigationIcon = {
IconButton(onClick = onClickCloseSearch) {
Icon(Icons.Outlined.ArrowBack, contentDescription = "back")
}
},
title = {
AppBar(
navigateUp = onClickCloseSearch,
titleContent = {
BasicTextField(
value = searchQuery,
onValueChange = onChangeSearchQuery,
@ -175,6 +184,9 @@ fun LibrarySearchToolbar(
focusRequester.requestFocus()
}
},
incognitoMode = incognitoMode,
downloadedOnlyMode = downloadedOnlyMode,
scrollBehavior = scrollBehavior,
)
}