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:
parent
ed5e013874
commit
01c6e46a71
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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 } }
|
||||||
}
|
}
|
||||||
|
@ -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)) },
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user