Minor cleanup/fixes

- Add FAB collapsing in clear database screen (fixes #7935)
- Don't allow multiline category names to be entered
- Consolidate Downloaded Only / Incognito Mode banner components
- Fix see-through migrate screen sticky header
This commit is contained in:
arkon 2022-09-18 16:08:50 -04:00
parent b668364afb
commit 83871fc013
17 changed files with 68 additions and 71 deletions

View file

@ -40,10 +40,9 @@ import eu.kanade.presentation.browse.components.BrowseSourceComfortableGrid
import eu.kanade.presentation.browse.components.BrowseSourceCompactGrid import eu.kanade.presentation.browse.components.BrowseSourceCompactGrid
import eu.kanade.presentation.browse.components.BrowseSourceList import eu.kanade.presentation.browse.components.BrowseSourceList
import eu.kanade.presentation.browse.components.BrowseSourceToolbar import eu.kanade.presentation.browse.components.BrowseSourceToolbar
import eu.kanade.presentation.components.DownloadedOnlyModeBanner import eu.kanade.presentation.components.AppStateBanners
import eu.kanade.presentation.components.EmptyScreen import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.ExtendedFloatingActionButton import eu.kanade.presentation.components.ExtendedFloatingActionButton
import eu.kanade.presentation.components.IncognitoModeBanner
import eu.kanade.presentation.components.LoadingScreen import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.Scaffold import eu.kanade.presentation.components.Scaffold
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -90,12 +89,8 @@ fun BrowseSourceScreen(
onSearch = { presenter.search() }, onSearch = { presenter.search() },
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )
if (downloadedOnlyMode) {
DownloadedOnlyModeBanner() AppStateBanners(downloadedOnlyMode, incognitoMode)
}
if (incognitoMode) {
IncognitoModeBanner()
}
} }
}, },
floatingActionButton = { floatingActionButton = {
@ -140,7 +135,7 @@ fun BrowseSourceScreen(
) )
}, },
label = { label = {
Text(text = stringResource(id = R.string.popular)) Text(text = stringResource(R.string.popular))
}, },
) )
if (presenter.source?.supportsLatest == true) { if (presenter.source?.supportsLatest == true) {
@ -159,7 +154,7 @@ fun BrowseSourceScreen(
) )
}, },
label = { label = {
Text(text = stringResource(id = R.string.latest)) Text(text = stringResource(R.string.latest))
}, },
) )
} }
@ -176,7 +171,7 @@ fun BrowseSourceScreen(
) )
}, },
label = { label = {
Text(text = stringResource(id = R.string.action_filter)) Text(text = stringResource(R.string.action_filter))
}, },
) )
} }
@ -195,7 +190,7 @@ fun BrowseSourceFloatingActionButton(
AnimatedVisibility(visible = isVisible) { AnimatedVisibility(visible = isVisible) {
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
modifier = modifier, modifier = modifier,
text = { Text(text = stringResource(id = R.string.action_filter)) }, text = { Text(text = stringResource(R.string.action_filter)) },
icon = { Icon(Icons.Outlined.FilterList, contentDescription = "") }, icon = { Icon(Icons.Outlined.FilterList, contentDescription = "") },
onClick = onFabClick, onClick = onFabClick,
) )

View file

@ -1,5 +1,6 @@
package eu.kanade.presentation.browse package eu.kanade.presentation.browse
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@ -84,7 +85,7 @@ fun MigrateSourceList(
stickyHeader(key = "header") { stickyHeader(key = "header") {
Row( Row(
modifier = Modifier modifier = Modifier
.animateItemPlacement() .background(MaterialTheme.colorScheme.background)
.padding(start = horizontalPadding), .padding(start = horizontalPadding),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
@ -109,14 +110,9 @@ fun MigrateSourceList(
} }
} }
item(key = "title") {
}
items( items(
items = list, items = list,
key = { (source, _) -> key = { (source, _) -> source.id },
source.id
},
) { (source, count) -> ) { (source, count) ->
MigrateSourceItem( MigrateSourceItem(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemPlacement(),

View file

@ -102,7 +102,7 @@ fun BrowseSourceComfortableGridItem(
}, },
badgesStart = { badgesStart = {
if (manga.favorite) { if (manga.favorite) {
Badge(text = stringResource(id = R.string.in_library)) Badge(text = stringResource(R.string.in_library))
} }
}, },
) )

View file

@ -113,7 +113,7 @@ fun BrowseSourceCompactGridItem(
}, },
badgesStart = { badgesStart = {
if (manga.favorite) { if (manga.favorite) {
Badge(text = stringResource(id = R.string.in_library)) Badge(text = stringResource(R.string.in_library))
} }
}, },
content = { content = {

View file

@ -18,7 +18,7 @@ fun RemoveMangaDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -28,11 +28,11 @@ fun RemoveMangaDialog(
onConfirm() onConfirm()
}, },
) { ) {
Text(text = stringResource(id = R.string.action_remove)) Text(text = stringResource(R.string.action_remove))
} }
}, },
title = { title = {
Text(text = stringResource(id = R.string.are_you_sure)) Text(text = stringResource(R.string.are_you_sure))
}, },
text = { text = {
Text(text = stringResource(R.string.remove_manga)) Text(text = stringResource(R.string.remove_manga))

View file

@ -91,7 +91,7 @@ fun BrowseSourceListItem(
onLongClick = onLongClick, onLongClick = onLongClick,
badges = { badges = {
if (manga.favorite) { if (manga.favorite) {
Badge(text = stringResource(id = R.string.in_library)) Badge(text = stringResource(R.string.in_library))
} }
}, },
content = { content = {

View file

@ -85,24 +85,24 @@ fun BrowseSourceRegularToolbar(
AppBarActions( AppBarActions(
actions = listOf( actions = listOf(
AppBar.Action( AppBar.Action(
title = stringResource(id = R.string.action_search), title = stringResource(R.string.action_search),
icon = Icons.Outlined.Search, icon = Icons.Outlined.Search,
onClick = onSearchClick, onClick = onSearchClick,
), ),
AppBar.Action( AppBar.Action(
title = stringResource(id = R.string.action_display_mode), title = stringResource(R.string.action_display_mode),
icon = Icons.Filled.ViewModule, icon = Icons.Filled.ViewModule,
onClick = { selectingDisplayMode = true }, onClick = { selectingDisplayMode = true },
), ),
if (isLocalSource) { if (isLocalSource) {
AppBar.Action( AppBar.Action(
title = stringResource(id = R.string.label_help), title = stringResource(R.string.label_help),
icon = Icons.Outlined.Help, icon = Icons.Outlined.Help,
onClick = onHelpClick, onClick = onHelpClick,
) )
} else { } else {
AppBar.Action( AppBar.Action(
title = stringResource(id = R.string.action_web_view), title = stringResource(R.string.action_web_view),
icon = Icons.Outlined.Public, icon = Icons.Outlined.Public,
onClick = onWebViewClick, onClick = onWebViewClick,
) )
@ -114,7 +114,7 @@ fun BrowseSourceRegularToolbar(
onDismissRequest = { selectingDisplayMode = false }, onDismissRequest = { selectingDisplayMode = false },
) { ) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_display_comfortable_grid)) }, text = { Text(text = stringResource(R.string.action_display_comfortable_grid)) },
onClick = { onDisplayModeChange(LibraryDisplayMode.ComfortableGrid) }, onClick = { onDisplayModeChange(LibraryDisplayMode.ComfortableGrid) },
trailingIcon = { trailingIcon = {
if (displayMode == LibraryDisplayMode.ComfortableGrid) { if (displayMode == LibraryDisplayMode.ComfortableGrid) {
@ -126,7 +126,7 @@ fun BrowseSourceRegularToolbar(
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_display_grid)) }, text = { Text(text = stringResource(R.string.action_display_grid)) },
onClick = { onDisplayModeChange(LibraryDisplayMode.CompactGrid) }, onClick = { onDisplayModeChange(LibraryDisplayMode.CompactGrid) },
trailingIcon = { trailingIcon = {
if (displayMode == LibraryDisplayMode.CompactGrid) { if (displayMode == LibraryDisplayMode.CompactGrid) {
@ -138,7 +138,7 @@ fun BrowseSourceRegularToolbar(
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_display_list)) }, text = { Text(text = stringResource(R.string.action_display_list)) },
onClick = { onDisplayModeChange(LibraryDisplayMode.List) }, onClick = { onDisplayModeChange(LibraryDisplayMode.List) },
trailingIcon = { trailingIcon = {
if (displayMode == LibraryDisplayMode.List) { if (displayMode == LibraryDisplayMode.List) {

View file

@ -51,6 +51,7 @@ fun CategoryCreateDialog(
label = { label = {
Text(text = stringResource(R.string.name)) Text(text = stringResource(R.string.name))
}, },
singleLine = true,
) )
}, },
) )
@ -98,6 +99,7 @@ fun CategoryRenameDialog(
label = { label = {
Text(text = stringResource(R.string.name)) Text(text = stringResource(R.string.name))
}, },
singleLine = true,
) )
}, },
) )

View file

@ -144,12 +144,7 @@ fun AppBar(
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )
if (downloadedOnlyMode) { AppStateBanners(downloadedOnlyMode, incognitoMode)
DownloadedOnlyModeBanner()
}
if (incognitoMode) {
IncognitoModeBanner()
}
} }
} }

View file

@ -1,6 +1,7 @@
package eu.kanade.presentation.components package eu.kanade.presentation.components
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -13,7 +14,20 @@ import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@Composable @Composable
fun DownloadedOnlyModeBanner() { fun ColumnScope.AppStateBanners(
downloadedOnlyMode: Boolean,
incognitoMode: Boolean,
) {
if (downloadedOnlyMode) {
DownloadedOnlyModeBanner()
}
if (incognitoMode) {
IncognitoModeBanner()
}
}
@Composable
private fun DownloadedOnlyModeBanner() {
Text( Text(
text = stringResource(R.string.label_downloaded_only), text = stringResource(R.string.label_downloaded_only),
modifier = Modifier modifier = Modifier
@ -27,7 +41,7 @@ fun DownloadedOnlyModeBanner() {
} }
@Composable @Composable
fun IncognitoModeBanner() { private fun IncognitoModeBanner() {
Text( Text(
text = stringResource(R.string.pref_incognito_mode), text = stringResource(R.string.pref_incognito_mode),
modifier = Modifier modifier = Modifier

View file

@ -76,12 +76,7 @@ fun TabbedScreen(
} }
} }
if (downloadedOnlyMode) { AppStateBanners(downloadedOnlyMode, incognitoMode)
DownloadedOnlyModeBanner()
}
if (incognitoMode) {
IncognitoModeBanner()
}
HorizontalPager( HorizontalPager(
count = tabs.size, count = tabs.size,

View file

@ -13,8 +13,7 @@ import androidx.compose.ui.unit.dp
import com.google.accompanist.pager.PagerState import com.google.accompanist.pager.PagerState
import eu.kanade.domain.category.model.Category import eu.kanade.domain.category.model.Category
import eu.kanade.presentation.category.visualName import eu.kanade.presentation.category.visualName
import eu.kanade.presentation.components.DownloadedOnlyModeBanner import eu.kanade.presentation.components.AppStateBanners
import eu.kanade.presentation.components.IncognitoModeBanner
import eu.kanade.presentation.components.TabIndicator import eu.kanade.presentation.components.TabIndicator
import eu.kanade.presentation.components.TabText import eu.kanade.presentation.components.TabText
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -51,11 +50,7 @@ fun LibraryTabs(
) )
} }
} }
if (isDownloadOnly) {
DownloadedOnlyModeBanner() AppStateBanners(isDownloadOnly, isIncognitoMode)
}
if (isIncognitoMode) {
IncognitoModeBanner()
}
} }
} }

View file

@ -28,9 +28,8 @@ import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.DownloadedOnlyModeBanner import eu.kanade.presentation.components.AppStateBanners
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.components.IncognitoModeBanner
import eu.kanade.presentation.manga.DownloadAction import eu.kanade.presentation.manga.DownloadAction
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -198,11 +197,6 @@ fun MangaAppBar(
), ),
) )
if (downloadedOnlyMode) { AppStateBanners(downloadedOnlyMode, incognitoMode)
DownloadedOnlyModeBanner()
}
if (incognitoMode) {
IncognitoModeBanner()
}
} }
} }

View file

@ -1,5 +1,6 @@
package eu.kanade.presentation.more.settings.database package eu.kanade.presentation.more.settings.database
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import eu.kanade.presentation.components.Scaffold import eu.kanade.presentation.components.Scaffold
@ -7,7 +8,6 @@ import eu.kanade.presentation.more.settings.database.components.ClearDatabaseCon
import eu.kanade.presentation.more.settings.database.components.ClearDatabaseDeleteDialog import eu.kanade.presentation.more.settings.database.components.ClearDatabaseDeleteDialog
import eu.kanade.presentation.more.settings.database.components.ClearDatabaseFloatingActionButton import eu.kanade.presentation.more.settings.database.components.ClearDatabaseFloatingActionButton
import eu.kanade.presentation.more.settings.database.components.ClearDatabaseToolbar import eu.kanade.presentation.more.settings.database.components.ClearDatabaseToolbar
import eu.kanade.presentation.util.plus
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.setting.database.ClearDatabasePresenter import eu.kanade.tachiyomi.ui.setting.database.ClearDatabasePresenter
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
@ -18,6 +18,7 @@ fun ClearDatabaseScreen(
navigateUp: () -> Unit, navigateUp: () -> Unit,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val lazyListState = rememberLazyListState()
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
ClearDatabaseToolbar( ClearDatabaseToolbar(
@ -31,6 +32,7 @@ fun ClearDatabaseScreen(
floatingActionButton = { floatingActionButton = {
ClearDatabaseFloatingActionButton( ClearDatabaseFloatingActionButton(
isVisible = presenter.selection.isNotEmpty(), isVisible = presenter.selection.isNotEmpty(),
lazyListState = lazyListState,
onClickDelete = { onClickDelete = {
presenter.dialog = ClearDatabasePresenter.Dialog.Delete(presenter.selection) presenter.dialog = ClearDatabasePresenter.Dialog.Delete(presenter.selection)
}, },
@ -40,6 +42,7 @@ fun ClearDatabaseScreen(
ClearDatabaseContent( ClearDatabaseContent(
state = presenter, state = presenter,
contentPadding = paddingValues, contentPadding = paddingValues,
lazyListState = lazyListState,
onClickSelection = { source -> onClickSelection = { source ->
presenter.toggleSelection(source) presenter.toggleSelection(source)
}, },

View file

@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -19,12 +20,14 @@ import eu.kanade.tachiyomi.R
fun ClearDatabaseContent( fun ClearDatabaseContent(
state: ClearDatabaseState, state: ClearDatabaseState,
contentPadding: PaddingValues, contentPadding: PaddingValues,
lazyListState: LazyListState,
onClickSelection: (Source) -> Unit, onClickSelection: (Source) -> Unit,
) { ) {
Crossfade(targetState = state.isEmpty.not()) { _state -> Crossfade(targetState = state.isEmpty.not()) { _state ->
when (_state) { when (_state) {
true -> FastScrollLazyColumn( true -> FastScrollLazyColumn(
contentPadding = contentPadding + WindowInsets.navigationBars.asPaddingValues(), contentPadding = contentPadding + WindowInsets.navigationBars.asPaddingValues(),
state = lazyListState,
) { ) {
items(state.items) { sourceWithCount -> items(state.items) { sourceWithCount ->
ClearDatabaseItem( ClearDatabaseItem(

View file

@ -4,6 +4,7 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -12,11 +13,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.ExtendedFloatingActionButton import eu.kanade.presentation.components.ExtendedFloatingActionButton
import eu.kanade.presentation.util.isScrolledToEnd
import eu.kanade.presentation.util.isScrollingUp
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@Composable @Composable
fun ClearDatabaseFloatingActionButton( fun ClearDatabaseFloatingActionButton(
isVisible: Boolean, isVisible: Boolean,
lazyListState: LazyListState,
onClickDelete: () -> Unit, onClickDelete: () -> Unit,
) { ) {
AnimatedVisibility( AnimatedVisibility(
@ -33,6 +37,7 @@ fun ClearDatabaseFloatingActionButton(
Icon(Icons.Outlined.Delete, contentDescription = "") Icon(Icons.Outlined.Delete, contentDescription = "")
}, },
onClick = onClickDelete, onClick = onClickDelete,
expanded = lazyListState.isScrollingUp() || lazyListState.isScrolledToEnd(),
) )
} }
} }

View file

@ -174,20 +174,20 @@ class DownloadController :
onDismissRequest = { onExpanded(false) }, onDismissRequest = { onExpanded(false) },
) { ) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_reorganize_by)) }, text = { Text(text = stringResource(R.string.action_reorganize_by)) },
children = { children = {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_order_by_upload_date)) }, text = { Text(text = stringResource(R.string.action_order_by_upload_date)) },
children = { children = {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_newest)) }, text = { Text(text = stringResource(R.string.action_newest)) },
onClick = { onClick = {
reorderQueue({ it.download.chapter.date_upload }, true) reorderQueue({ it.download.chapter.date_upload }, true)
onExpanded(false) onExpanded(false)
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_oldest)) }, text = { Text(text = stringResource(R.string.action_oldest)) },
onClick = { onClick = {
reorderQueue({ it.download.chapter.date_upload }, false) reorderQueue({ it.download.chapter.date_upload }, false)
onExpanded(false) onExpanded(false)
@ -196,17 +196,17 @@ class DownloadController :
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_order_by_chapter_number)) }, text = { Text(text = stringResource(R.string.action_order_by_chapter_number)) },
children = { children = {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_asc)) }, text = { Text(text = stringResource(R.string.action_asc)) },
onClick = { onClick = {
reorderQueue({ it.download.chapter.chapter_number }, false) reorderQueue({ it.download.chapter.chapter_number }, false)
onExpanded(false) onExpanded(false)
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_desc)) }, text = { Text(text = stringResource(R.string.action_desc)) },
onClick = { onClick = {
reorderQueue({ it.download.chapter.chapter_number }, true) reorderQueue({ it.download.chapter.chapter_number }, true)
onExpanded(false) onExpanded(false)
@ -217,7 +217,7 @@ class DownloadController :
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(id = R.string.action_cancel_all)) }, text = { Text(text = stringResource(R.string.action_cancel_all)) },
onClick = { onClick = {
presenter.clearQueue(context) presenter.clearQueue(context)
onExpanded(false) onExpanded(false)