Add ability to open random manga (#8232)

* Add ability to open random manga

* Use `getMangaForCategory` instead

* Put it in overflow menu instead of using EFAB

* Partial review changes

* Merge remote-tracking branch 'refs/remotes/origin/patch-6' into patch-6

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt

* Merge remote-tracking branch 'refs/remotes/origin/patch-6' into patch-6

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt

* Wording changes
This commit is contained in:
zbue 2022-10-30 22:57:33 +08:00 committed by GitHub
parent fcec1581b7
commit f5451a6881
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 4 deletions

View file

@ -36,6 +36,7 @@ fun LibraryScreen(
onClickInvertSelection: () -> Unit, onClickInvertSelection: () -> Unit,
onClickFilter: () -> Unit, onClickFilter: () -> Unit,
onClickRefresh: (Category?) -> Boolean, onClickRefresh: (Category?) -> Boolean,
onClickOpenRandomManga: () -> Unit,
) { ) {
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
@ -51,6 +52,7 @@ fun LibraryScreen(
onClickInvertSelection = onClickInvertSelection, onClickInvertSelection = onClickInvertSelection,
onClickFilter = onClickFilter, onClickFilter = onClickFilter,
onClickRefresh = { onClickRefresh(null) }, onClickRefresh = { onClickRefresh(null) },
onClickOpenRandomManga = onClickOpenRandomManga,
scrollBehavior = scrollBehavior.takeIf { !tabVisible }, // For scroll overlay when no tab scrollBehavior = scrollBehavior.takeIf { !tabVisible }, // For scroll overlay when no tab
) )
}, },

View file

@ -1,15 +1,17 @@
package eu.kanade.presentation.library.components package eu.kanade.presentation.library.components
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.FilterList import androidx.compose.material.icons.outlined.FilterList
import androidx.compose.material.icons.outlined.FlipToBack import androidx.compose.material.icons.outlined.FlipToBack
import androidx.compose.material.icons.outlined.Refresh import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material.icons.outlined.Search import androidx.compose.material.icons.outlined.Search
import androidx.compose.material.icons.outlined.SelectAll import androidx.compose.material.icons.outlined.SelectAll
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalContentColor
@ -17,6 +19,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
@ -26,6 +32,7 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.components.Pill import eu.kanade.presentation.components.Pill
import eu.kanade.presentation.components.SearchToolbar import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.library.LibraryState import eu.kanade.presentation.library.LibraryState
@ -43,6 +50,7 @@ fun LibraryToolbar(
onClickInvertSelection: () -> Unit, onClickInvertSelection: () -> Unit,
onClickFilter: () -> Unit, onClickFilter: () -> Unit,
onClickRefresh: () -> Unit, onClickRefresh: () -> Unit,
onClickOpenRandomManga: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior?, scrollBehavior: TopAppBarScrollBehavior?,
) = when { ) = when {
state.selectionMode -> LibrarySelectionToolbar( state.selectionMode -> LibrarySelectionToolbar(
@ -85,6 +93,7 @@ fun LibraryToolbar(
onClickSearch = { state.searchQuery = "" }, onClickSearch = { state.searchQuery = "" },
onClickFilter = onClickFilter, onClickFilter = onClickFilter,
onClickRefresh = onClickRefresh, onClickRefresh = onClickRefresh,
onClickOpenRandomManga = onClickOpenRandomManga,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )
} }
@ -98,6 +107,7 @@ fun LibraryRegularToolbar(
onClickSearch: () -> Unit, onClickSearch: () -> Unit,
onClickFilter: () -> Unit, onClickFilter: () -> Unit,
onClickRefresh: () -> Unit, onClickRefresh: () -> Unit,
onClickOpenRandomManga: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior?, scrollBehavior: TopAppBarScrollBehavior?,
) { ) {
val pillAlpha = if (isSystemInDarkTheme()) 0.12f else 0.08f val pillAlpha = if (isSystemInDarkTheme()) 0.12f else 0.08f
@ -127,8 +137,34 @@ fun LibraryRegularToolbar(
IconButton(onClick = onClickFilter) { IconButton(onClick = onClickFilter) {
Icon(Icons.Outlined.FilterList, contentDescription = stringResource(R.string.action_filter), tint = filterTint) Icon(Icons.Outlined.FilterList, contentDescription = stringResource(R.string.action_filter), tint = filterTint)
} }
IconButton(onClick = onClickRefresh) { var moreExpanded by remember { mutableStateOf(false) }
Icon(Icons.Outlined.Refresh, contentDescription = stringResource(R.string.pref_category_library_update)) Box {
IconButton(onClick = { moreExpanded = !moreExpanded }) {
Icon(
imageVector = Icons.Outlined.MoreVert,
contentDescription = stringResource(R.string.abc_action_menu_overflow_description),
)
}
val onDismissRequest = { moreExpanded = false }
DropdownMenu(
expanded = moreExpanded,
onDismissRequest = onDismissRequest,
) {
DropdownMenuItem(
text = { Text(text = stringResource(R.string.pref_category_library_update)) },
onClick = {
onClickRefresh()
onDismissRequest()
},
)
DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_open_random_manga)) },
onClick = {
onClickOpenRandomManga()
onDismissRequest()
},
)
}
} }
}, },
incognitoMode = incognitoMode, incognitoMode = incognitoMode,

View file

@ -43,6 +43,8 @@ class LibraryController(
@Composable @Composable
override fun ComposeContent() { override fun ComposeContent() {
val context = LocalContext.current val context = LocalContext.current
val getMangaForCategory = presenter.getMangaForCategory(page = presenter.activeCategory)
LibraryScreen( LibraryScreen(
presenter = presenter, presenter = presenter,
onMangaClicked = ::openManga, onMangaClicked = ::openManga,
@ -60,6 +62,14 @@ class LibraryController(
context.toast(if (started) R.string.updating_category else R.string.update_already_running) context.toast(if (started) R.string.updating_category else R.string.update_already_running)
started started
}, },
onClickOpenRandomManga = {
val items = getMangaForCategory.map { it.libraryManga.manga.id }
if (getMangaForCategory.isNotEmpty()) {
openManga(items.random())
} else {
context.toast(R.string.information_no_entries_found)
}
},
onClickInvertSelection = { presenter.invertSelection(presenter.activeCategory) }, onClickInvertSelection = { presenter.invertSelection(presenter.activeCategory) },
onClickSelectAll = { presenter.selectAll(presenter.activeCategory) }, onClickSelectAll = { presenter.selectAll(presenter.activeCategory) },
onClickUnselectAll = ::clearSelection, onClickUnselectAll = ::clearSelection,

View file

@ -526,7 +526,7 @@ class LibraryPresenter(
@Composable @Composable
fun getMangaForCategory(page: Int): List<LibraryItem> { fun getMangaForCategory(page: Int): List<LibraryItem> {
val unfiltered = remember(categories, loadedManga) { val unfiltered = remember(categories, loadedManga, page) {
val categoryId = categories.getOrNull(page)?.id ?: -1 val categoryId = categories.getOrNull(page)?.id ?: -1
loadedManga[categoryId] ?: emptyList() loadedManga[categoryId] ?: emptyList()
} }

View file

@ -72,6 +72,7 @@
<string name="action_disable_all">Disable all</string> <string name="action_disable_all">Disable all</string>
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_add">Add</string> <string name="action_add">Add</string>
<string name="action_open_random_manga">Open random entry</string>
<string name="action_add_category">Add category</string> <string name="action_add_category">Add category</string>
<string name="action_edit_categories">Edit categories</string> <string name="action_edit_categories">Edit categories</string>
<string name="action_rename_category">Rename category</string> <string name="action_rename_category">Rename category</string>
@ -842,6 +843,7 @@
<string name="information_no_recent">No recent updates</string> <string name="information_no_recent">No recent updates</string>
<string name="information_no_recent_manga">Nothing read recently</string> <string name="information_no_recent_manga">Nothing read recently</string>
<string name="information_empty_library">Your library is empty</string> <string name="information_empty_library">Your library is empty</string>
<string name="information_no_entries_found">No entries found in this category</string>
<string name="getting_started_guide">Getting started guide</string> <string name="getting_started_guide">Getting started guide</string>
<string name="information_empty_category">You have no categories. Tap the plus button to create one for organizing your library.</string> <string name="information_empty_category">You have no categories. Tap the plus button to create one for organizing your library.</string>
<string name="information_empty_category_dialog">You don\'t have any categories yet.</string> <string name="information_empty_category_dialog">You don\'t have any categories yet.</string>