From afceac15c89f274d571dcb61da18c6273a550f65 Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Thu, 4 Aug 2022 04:41:15 +0700 Subject: [PATCH] Add scroll overlay to LibraryToolbar (#7669) Works when category tab is not shown --- .../kanade/presentation/components/AppBar.kt | 2 +- .../presentation/library/LibraryScreen.kt | 19 +++++- .../library/components/LibraryToolbar.kt | 64 +++++++++++-------- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/components/AppBar.kt b/app/src/main/java/eu/kanade/presentation/components/AppBar.kt index 05206f476c..723758b3a2 100644 --- a/app/src/main/java/eu/kanade/presentation/components/AppBar.kt +++ b/app/src/main/java/eu/kanade/presentation/components/AppBar.kt @@ -89,7 +89,7 @@ fun AppBar( // Menu actions: @Composable RowScope.() -> Unit = {}, // Action mode - isActionMode: Boolean, + isActionMode: Boolean = false, onCancelActionMode: () -> Unit = {}, // Banners downloadedOnlyMode: Boolean = false, diff --git a/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt b/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt index 841ecd4fb4..451468eda6 100644 --- a/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt @@ -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 = { diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryToolbar.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryToolbar.kt index f959c28dc8..9b38426566 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryToolbar.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryToolbar.kt @@ -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, ) }