Show empty screen when a category is empty (#8690)

* Show empty screen when a category is empty

* Review changes

* Review changes #2

Co-authored-by: arkon <arkon@users.noreply.github.com>
This commit is contained in:
zbue 2022-12-08 22:15:10 +08:00 committed by GitHub
parent ed5e013874
commit 01c6e46a71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 60 additions and 11 deletions

View File

@ -58,6 +58,7 @@ import eu.kanade.tachiyomi.util.system.LocaleHelper
fun ExtensionScreen( fun ExtensionScreen(
state: ExtensionsState, state: ExtensionsState,
contentPadding: PaddingValues, contentPadding: PaddingValues,
searchQuery: String? = null,
onLongClickItem: (Extension) -> Unit, onLongClickItem: (Extension) -> Unit,
onClickItemCancel: (Extension) -> Unit, onClickItemCancel: (Extension) -> Unit,
onInstallExtension: (Extension.Available) -> Unit, onInstallExtension: (Extension.Available) -> Unit,
@ -75,10 +76,17 @@ fun ExtensionScreen(
) { ) {
when { when {
state.isLoading -> LoadingScreen(modifier = Modifier.padding(contentPadding)) state.isLoading -> LoadingScreen(modifier = Modifier.padding(contentPadding))
state.isEmpty -> EmptyScreen( state.isEmpty -> {
textResource = R.string.empty_screen, val msg = if (!searchQuery.isNullOrEmpty()) {
modifier = Modifier.padding(contentPadding), R.string.no_results_found
) } else {
R.string.empty_screen
}
EmptyScreen(
textResource = msg,
modifier = Modifier.padding(contentPadding),
)
}
else -> { else -> {
ExtensionContent( ExtensionContent(
state = state, state = state,

View File

@ -58,8 +58,13 @@ fun HistoryScreen(
if (it == null) { if (it == null) {
LoadingScreen(modifier = Modifier.padding(contentPadding)) LoadingScreen(modifier = Modifier.padding(contentPadding))
} else if (it.isEmpty()) { } else if (it.isEmpty()) {
val msg = if (!state.searchQuery.isNullOrEmpty()) {
R.string.no_results_found
} else {
R.string.information_no_recent_manga
}
EmptyScreen( EmptyScreen(
textResource = R.string.information_no_recent_manga, textResource = msg,
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )
} else { } else {

View File

@ -32,6 +32,7 @@ fun LibraryContent(
selection: List<LibraryManga>, selection: List<LibraryManga>,
contentPadding: PaddingValues, contentPadding: PaddingValues,
currentPage: () -> Int, currentPage: () -> Int,
hasActiveFilters: Boolean,
showPageTabs: Boolean, showPageTabs: Boolean,
onChangeCurrentPage: (Int) -> Unit, onChangeCurrentPage: (Int) -> Unit,
onMangaClicked: (Long) -> Unit, onMangaClicked: (Long) -> Unit,
@ -97,6 +98,7 @@ fun LibraryContent(
state = pagerState, state = pagerState,
contentPadding = PaddingValues(bottom = contentPadding.calculateBottomPadding()), contentPadding = PaddingValues(bottom = contentPadding.calculateBottomPadding()),
pageCount = categories.size, pageCount = categories.size,
hasActiveFilters = hasActiveFilters,
selectedManga = selection, selectedManga = selection,
searchQuery = searchQuery, searchQuery = searchQuery,
onGlobalSearchClicked = onGlobalSearchClicked, onGlobalSearchClicked = onGlobalSearchClicked,

View File

@ -3,6 +3,7 @@ package eu.kanade.presentation.library.components
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -13,8 +14,10 @@ import androidx.compose.ui.platform.LocalConfiguration
import eu.kanade.core.prefs.PreferenceMutableState import eu.kanade.core.prefs.PreferenceMutableState
import eu.kanade.domain.library.model.LibraryDisplayMode import eu.kanade.domain.library.model.LibraryDisplayMode
import eu.kanade.domain.library.model.LibraryManga import eu.kanade.domain.library.model.LibraryManga
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.HorizontalPager import eu.kanade.presentation.components.HorizontalPager
import eu.kanade.presentation.components.PagerState import eu.kanade.presentation.components.PagerState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.LibraryItem import eu.kanade.tachiyomi.ui.library.LibraryItem
@Composable @Composable
@ -22,6 +25,7 @@ fun LibraryPager(
state: PagerState, state: PagerState,
contentPadding: PaddingValues, contentPadding: PaddingValues,
pageCount: Int, pageCount: Int,
hasActiveFilters: Boolean,
selectedManga: List<LibraryManga>, selectedManga: List<LibraryManga>,
searchQuery: String?, searchQuery: String?,
onGlobalSearchClicked: () -> Unit, onGlobalSearchClicked: () -> Unit,
@ -43,6 +47,12 @@ fun LibraryPager(
return@HorizontalPager return@HorizontalPager
} }
val library = getLibraryForPage(page) val library = getLibraryForPage(page)
if (library.isEmpty()) {
LibraryPagerEmptyScreen(searchQuery, hasActiveFilters, contentPadding)
return@HorizontalPager
}
val displayMode = getDisplayModeForPage(page) val displayMode = getDisplayModeForPage(page)
val columns by if (displayMode != LibraryDisplayMode.List) { val columns by if (displayMode != LibraryDisplayMode.List) {
val configuration = LocalConfiguration.current val configuration = LocalConfiguration.current
@ -96,3 +106,21 @@ fun LibraryPager(
} }
} }
} }
@Composable
private fun LibraryPagerEmptyScreen(
searchQuery: String?,
hasActiveFilters: Boolean,
contentPadding: PaddingValues,
) {
val msg = when {
!searchQuery.isNullOrEmpty() -> R.string.no_results_found
hasActiveFilters -> R.string.error_no_match
else -> R.string.information_no_manga_category
}
EmptyScreen(
textResource = msg,
modifier = Modifier.padding(contentPadding),
)
}

View File

@ -21,6 +21,7 @@ fun extensionsTab(
): TabContent { ): TabContent {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val state by extensionsScreenModel.state.collectAsState() val state by extensionsScreenModel.state.collectAsState()
val searchQuery by extensionsScreenModel.query.collectAsState()
return TabContent( return TabContent(
titleRes = R.string.label_extensions, titleRes = R.string.label_extensions,
@ -37,6 +38,7 @@ fun extensionsTab(
ExtensionScreen( ExtensionScreen(
state = state, state = state,
contentPadding = contentPadding, contentPadding = contentPadding,
searchQuery = searchQuery,
onLongClickItem = { extension -> onLongClickItem = { extension ->
when (extension) { when (extension) {
is Extension.Available -> extensionsScreenModel.installExtension(extension) is Extension.Available -> extensionsScreenModel.installExtension(extension)

View File

@ -742,17 +742,19 @@ class LibraryScreenModel(
val showMangaContinueButton: Boolean = false, val showMangaContinueButton: Boolean = false,
val dialog: Dialog? = null, val dialog: Dialog? = null,
) { ) {
val selectionMode = selection.isNotEmpty() private val libraryCount by lazy {
val categories = library.keys.toList()
val libraryCount by lazy {
library.values library.values
.flatten() .flatten()
.fastDistinctBy { it.libraryManga.manga.id } .fastDistinctBy { it.libraryManga.manga.id }
.size .size
} }
val isLibraryEmpty by lazy { libraryCount == 0 }
val selectionMode = selection.isNotEmpty()
val categories = library.keys.toList()
fun getLibraryItemsByCategoryId(categoryId: Long): List<LibraryItem>? { fun getLibraryItemsByCategoryId(categoryId: Long): List<LibraryItem>? {
return library.firstNotNullOfOrNull { (k, v) -> v.takeIf { k.id == categoryId } } return library.firstNotNullOfOrNull { (k, v) -> v.takeIf { k.id == categoryId } }
} }

View File

@ -149,7 +149,7 @@ object LibraryTab : Tab {
) { contentPadding -> ) { contentPadding ->
when { when {
state.isLoading -> LoadingScreen(modifier = Modifier.padding(contentPadding)) state.isLoading -> LoadingScreen(modifier = Modifier.padding(contentPadding))
state.searchQuery.isNullOrEmpty() && !state.hasActiveFilters && state.libraryCount == 0 -> { state.searchQuery.isNullOrEmpty() && !state.hasActiveFilters && state.isLibraryEmpty -> {
val handler = LocalUriHandler.current val handler = LocalUriHandler.current
EmptyScreen( EmptyScreen(
textResource = R.string.information_empty_library, textResource = R.string.information_empty_library,
@ -170,6 +170,7 @@ object LibraryTab : Tab {
selection = state.selection, selection = state.selection,
contentPadding = contentPadding, contentPadding = contentPadding,
currentPage = { screenModel.activeCategoryIndex }, currentPage = { screenModel.activeCategoryIndex },
hasActiveFilters = state.hasActiveFilters,
showPageTabs = state.showCategoryTabs || !state.searchQuery.isNullOrEmpty(), showPageTabs = state.showCategoryTabs || !state.searchQuery.isNullOrEmpty(),
onChangeCurrentPage = { screenModel.activeCategoryIndex = it }, onChangeCurrentPage = { screenModel.activeCategoryIndex = it },
onMangaClicked = { navigator.push(MangaScreen(it)) }, onMangaClicked = { navigator.push(MangaScreen(it)) },

View File

@ -870,6 +870,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_manga_category">Category is empty</string>
<string name="information_no_entries_found">No entries found in this category</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>