Library's first load is now async + private scope in library presenter

This commit is contained in:
Jay 2020-04-11 14:26:01 -04:00
parent 3cd74ce05e
commit ed3e819829
4 changed files with 38 additions and 40 deletions

View File

@ -60,6 +60,7 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForRootController
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.scrollViewWith
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
import eu.kanade.tachiyomi.util.view.setStyle
@ -326,11 +327,11 @@ class LibraryController(
recycler.updatePaddingRelative(bottom = height)
presenter.onRestore()
if (presenter.libraryItems.isNotEmpty())
onNextLibraryUpdate(presenter.libraryItems, true)
else {
if (presenter.libraryItems.isNotEmpty()) {
onNextLibraryUpdate(presenter.libraryItems, true)
} else {
recycler_layout.alpha = 0f
presenter.getLibraryBlocking()
presenter.getLibrary()
}
}
@ -452,6 +453,7 @@ class LibraryController(
if (recycler_layout.alpha == 0f) recycler_layout.animate().alpha(1f).setDuration(500)
.start()
} else if (justStarted && freshStart) {
progress.gone()
scrollToHeader(activeCategory)
fast_scroller.translationX = 0f
view?.post {

View File

@ -18,14 +18,15 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet
import eu.kanade.tachiyomi.util.lang.removeArticles
import eu.kanade.tachiyomi.util.system.executeOnIO
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_EXCLUDE
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_IGNORE
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_INCLUDE
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_REALLY_EXCLUDE
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import uy.kohesive.injekt.Injekt
@ -46,6 +47,8 @@ class LibraryPresenter(
private val downloadManager: DownloadManager = Injekt.get()
) {
private var scope = CoroutineScope(Job() + Dispatchers.Default)
private val context = preferences.context
private val loggedServices by lazy { Injekt.get<TrackManager>().services.filter { it.isLogged } }
@ -62,12 +65,9 @@ class LibraryPresenter(
/**
* List of all manga to update the
*/
// private var rawMangaMap: LibraryMap? = null
var libraryItems: List<LibraryItem> = emptyList()
private var allLibraryItems: List<LibraryItem> = emptyList()
// private var currentMangaMap: LibraryMap? = null
private var totalChapters: Map<Long, Int>? = null
fun onDestroy() {
@ -94,30 +94,15 @@ class LibraryPresenter(
mangaMap = applySort(mangaMap)
mangaMap
}
val freshStart = libraryItems.isEmpty()
libraryItems = mangaMap
view.onNextLibraryUpdate(libraryItems)
view.onNextLibraryUpdate(libraryItems, freshStart)
withContext(Dispatchers.IO) {
setTotalChapters()
}
}
}
fun getLibraryBlocking() {
val mangaMap = {
val library = getLibraryFromDB()
library.apply { setDownloadCount(library) }
allLibraryItems = library
var mangaMap = library
mangaMap = applyFilters(mangaMap)
mangaMap = applySort(mangaMap)
mangaMap
}()
libraryItems = mangaMap
launchUI {
view.onNextLibraryUpdate(libraryItems)
}
}
/**
* Applies library filters to the given map of manga.
*
@ -530,21 +515,21 @@ class LibraryPresenter(
* @param mangas the list of manga to delete.
*/
fun removeMangaFromLibrary(mangas: List<Manga>) {
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
scope.launch {
// Create a set of the list
val mangaToDelete = mangas.distinctBy { it.id }
mangaToDelete.forEach { it.favorite = false }
db.insertMangas(mangaToDelete).executeAsBlocking()
db.insertMangas(mangaToDelete).executeOnIO()
getLibrary()
}
}
fun confirmDeletion(mangas: List<Manga>) {
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
scope.launch {
val mangaToDelete = mangas.distinctBy { it.id }
mangaToDelete.forEach { manga ->
db.resetMangaInfo(manga).executeAsBlocking()
db.resetMangaInfo(manga).executeOnIO()
coverCache.deleteFromCache(manga.thumbnail_url)
val source = sourceManager.get(manga.source) as? HttpSource
if (source != null)
@ -554,11 +539,11 @@ class LibraryPresenter(
}
fun updateManga(manga: LibraryManga) {
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
val rawMap = allLibraryItems ?: return@launch
val currentMap = libraryItems ?: return@launch
scope.launch {
val rawMap = allLibraryItems
val currentMap = libraryItems
val id = manga.id ?: return@launch
val dbManga = db.getLibraryManga(id).executeAsBlocking() ?: return@launch
val dbManga = db.getLibraryManga(id).executeOnIO() ?: return@launch
arrayOf(rawMap, currentMap).forEach { map ->
map.forEach { item ->
if (item.manga.id == dbManga.id) {
@ -572,10 +557,10 @@ class LibraryPresenter(
}
fun reAddMangas(mangas: List<Manga>) {
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
scope.launch {
val mangaToAdd = mangas.distinctBy { it.id }
mangaToAdd.forEach { it.favorite = true }
db.insertMangas(mangaToAdd).executeAsBlocking()
db.insertMangas(mangaToAdd).executeOnIO()
getLibrary()
mangaToAdd.forEach { db.insertManga(it).executeAsBlocking() }
}
@ -620,12 +605,12 @@ class LibraryPresenter(
}
fun rearrangeCategory(catId: Int?, mangaIds: List<Long>) {
GlobalScope.launch(Dispatchers.IO) {
scope.launch {
val category = categories.find { catId == it.id } ?: return@launch
category.mangaSort = null
category.mangaOrder = mangaIds
if (category.id == 0) preferences.defaultMangaOrder().set(mangaIds.joinToString("/"))
else db.insertCategory(category).executeAsBlocking()
else db.insertCategory(category).executeOnIO()
requestSortUpdate()
}
}
@ -635,7 +620,7 @@ class LibraryPresenter(
catId: Int?,
mangaIds: List<Long>
) {
GlobalScope.launch(Dispatchers.IO) {
scope.launch {
val categoryId = catId ?: return@launch
val category = categories.find { catId == it.id } ?: return@launch
@ -646,7 +631,7 @@ class LibraryPresenter(
val categories =
if (catId == 0) emptyList()
else
db.getCategoriesForManga(manga).executeAsBlocking()
db.getCategoriesForManga(manga).executeOnIO()
.filter { it.id != oldCatId } + listOf(category)
for (cat in categories) {

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.util.system
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetObject
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutCollectionOfObjects
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutObject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@ -17,3 +18,7 @@ suspend fun <T> PreparedGetObject<T>.executeOnIO(): T? {
suspend fun <T> PreparedPutObject<T>.executeOnIO() {
withContext(Dispatchers.IO) { executeAsBlocking() }
}
suspend fun <T> PreparedPutCollectionOfObjects<T>.executeOnIO() {
withContext(Dispatchers.IO) { executeAsBlocking() }
}

View File

@ -6,6 +6,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progress"
android:layout_gravity="center"
android:layout_width="75dp"
android:layout_height="75dp"/>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"