Show number of unique library items (closes #6522)
- Filters do affect this - Won't be shown if tabs aren't visible and there's more than 1 category (so it'd always show the per-category count), but a separate stats page should show that info instead
This commit is contained in:
parent
32190b6cac
commit
8a3a7418d0
1 changed files with 25 additions and 48 deletions
|
@ -97,19 +97,16 @@ class LibraryPresenter(
|
||||||
private val trackManager: TrackManager = Injekt.get(),
|
private val trackManager: TrackManager = Injekt.get(),
|
||||||
) : BasePresenter<LibraryController>(), LibraryState by state {
|
) : BasePresenter<LibraryController>(), LibraryState by state {
|
||||||
|
|
||||||
var loadedManga by mutableStateOf(emptyMap<Long, List<LibraryItem>>())
|
private var loadedManga by mutableStateOf(emptyMap<Long, List<LibraryItem>>())
|
||||||
private set
|
|
||||||
|
|
||||||
val isLibraryEmpty by derivedStateOf { loadedManga.isEmpty() }
|
val isLibraryEmpty by derivedStateOf { loadedManga.isEmpty() }
|
||||||
|
|
||||||
val tabVisibility by preferences.categoryTabs().asState()
|
val tabVisibility by preferences.categoryTabs().asState()
|
||||||
|
|
||||||
val mangaCountVisibility by preferences.categoryNumberOfItems().asState()
|
val mangaCountVisibility by preferences.categoryNumberOfItems().asState()
|
||||||
|
|
||||||
var activeCategory: Int by preferences.lastUsedCategory().asState()
|
var activeCategory: Int by preferences.lastUsedCategory().asState()
|
||||||
|
|
||||||
val isDownloadOnly: Boolean by preferences.downloadedOnly().asState()
|
val isDownloadOnly: Boolean by preferences.downloadedOnly().asState()
|
||||||
|
|
||||||
val isIncognitoMode: Boolean by preferences.incognitoMode().asState()
|
val isIncognitoMode: Boolean by preferences.incognitoMode().asState()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -147,7 +144,7 @@ class LibraryPresenter(
|
||||||
*/
|
*/
|
||||||
if (librarySubscription == null || librarySubscription!!.isCancelled) {
|
if (librarySubscription == null || librarySubscription!!.isCancelled) {
|
||||||
librarySubscription = presenterScope.launchIO {
|
librarySubscription = presenterScope.launchIO {
|
||||||
getLibraryObservable()
|
getLibraryFlow().asObservable()
|
||||||
.combineLatest(badgeTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
|
.combineLatest(badgeTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
|
||||||
lib.apply { setBadges(mangaMap) }
|
lib.apply { setBadges(mangaMap) }
|
||||||
}
|
}
|
||||||
|
@ -402,8 +399,16 @@ class LibraryPresenter(
|
||||||
*
|
*
|
||||||
* @return an observable of the categories and its manga.
|
* @return an observable of the categories and its manga.
|
||||||
*/
|
*/
|
||||||
private fun getLibraryObservable(): Observable<Library> {
|
private fun getLibraryFlow(): Flow<Library> {
|
||||||
return combine(getCategoriesFlow(), getLibraryMangasFlow()) { dbCategories, libraryManga ->
|
val categoriesFlow = getCategories.subscribe()
|
||||||
|
val libraryMangasFlow = getLibraryManga.subscribe()
|
||||||
|
.map { list ->
|
||||||
|
list.map { libraryManga ->
|
||||||
|
// Display mode based on user preference: take it from global library setting or category
|
||||||
|
LibraryItem(libraryManga)
|
||||||
|
}.groupBy { it.manga.category.toLong() }
|
||||||
|
}
|
||||||
|
return combine(categoriesFlow, libraryMangasFlow) { dbCategories, libraryManga ->
|
||||||
val categories = if (libraryManga.isNotEmpty() && libraryManga.containsKey(0).not()) {
|
val categories = if (libraryManga.isNotEmpty() && libraryManga.containsKey(0).not()) {
|
||||||
dbCategories.filterNot { it.isSystemCategory }
|
dbCategories.filterNot { it.isSystemCategory }
|
||||||
} else {
|
} else {
|
||||||
|
@ -412,32 +417,7 @@ class LibraryPresenter(
|
||||||
|
|
||||||
state.categories = categories
|
state.categories = categories
|
||||||
Library(categories, libraryManga)
|
Library(categories, libraryManga)
|
||||||
}.asObservable()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the categories from the database.
|
|
||||||
*
|
|
||||||
* @return an observable of the categories.
|
|
||||||
*/
|
|
||||||
private fun getCategoriesFlow(): Flow<List<Category>> {
|
|
||||||
return getCategories.subscribe()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the manga grouped by categories.
|
|
||||||
*
|
|
||||||
* @return an observable containing a map with the category id as key and a list of manga as the
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
private fun getLibraryMangasFlow(): Flow<LibraryMap> {
|
|
||||||
return getLibraryManga.subscribe()
|
|
||||||
.map { list ->
|
|
||||||
list.map { libraryManga ->
|
|
||||||
// Display mode based on user preference: take it from global library setting or category
|
|
||||||
LibraryItem(libraryManga)
|
|
||||||
}.groupBy { it.manga.category.toLong() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -531,8 +511,8 @@ class LibraryPresenter(
|
||||||
* @param mangas the list of manga.
|
* @param mangas the list of manga.
|
||||||
*/
|
*/
|
||||||
fun downloadUnreadChapters(mangas: List<Manga>) {
|
fun downloadUnreadChapters(mangas: List<Manga>) {
|
||||||
mangas.forEach { manga ->
|
launchIO {
|
||||||
launchIO {
|
mangas.forEach { manga ->
|
||||||
val chapters = getChapterByMangaId.await(manga.id)
|
val chapters = getChapterByMangaId.await(manga.id)
|
||||||
.filter { !it.read }
|
.filter { !it.read }
|
||||||
.map { it.toDbChapter() }
|
.map { it.toDbChapter() }
|
||||||
|
@ -548,8 +528,8 @@ class LibraryPresenter(
|
||||||
* @param mangas the list of manga.
|
* @param mangas the list of manga.
|
||||||
*/
|
*/
|
||||||
fun markReadStatus(mangas: List<Manga>, read: Boolean) {
|
fun markReadStatus(mangas: List<Manga>, read: Boolean) {
|
||||||
mangas.forEach { manga ->
|
launchIO {
|
||||||
launchIO {
|
mangas.forEach { manga ->
|
||||||
setReadStatus.await(
|
setReadStatus.await(
|
||||||
manga = manga,
|
manga = manga,
|
||||||
read = read,
|
read = read,
|
||||||
|
@ -635,14 +615,15 @@ class LibraryPresenter(
|
||||||
|
|
||||||
return produceState(initialValue = default, category, loadedManga, mangaCountVisibility, tabVisibility) {
|
return produceState(initialValue = default, category, loadedManga, mangaCountVisibility, tabVisibility) {
|
||||||
val title = if (tabVisibility.not()) categoryName else defaultTitle
|
val title = if (tabVisibility.not()) categoryName else defaultTitle
|
||||||
|
val count = when {
|
||||||
|
category == null || mangaCountVisibility.not() -> null
|
||||||
|
tabVisibility.not() -> loadedManga[category.id]?.size
|
||||||
|
else -> loadedManga.values.flatten().distinct().size
|
||||||
|
}
|
||||||
|
|
||||||
value = when {
|
value = when (category) {
|
||||||
category == null -> default
|
null -> default
|
||||||
(tabVisibility.not() && mangaCountVisibility.not()) -> LibraryToolbarTitle(title)
|
else -> LibraryToolbarTitle(title, count)
|
||||||
tabVisibility.not() && mangaCountVisibility -> LibraryToolbarTitle(title, loadedManga[category.id]?.size)
|
|
||||||
(tabVisibility && categories.size > 1) && mangaCountVisibility -> LibraryToolbarTitle(title)
|
|
||||||
tabVisibility && mangaCountVisibility -> LibraryToolbarTitle(title, loadedManga[category.id]?.size)
|
|
||||||
else -> default
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -674,10 +655,6 @@ class LibraryPresenter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasSelection(): Boolean {
|
|
||||||
return selection.isNotEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clearSelection() {
|
fun clearSelection() {
|
||||||
state.selection = emptyList()
|
state.selection = emptyList()
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue