|
@@ -1,17 +1,28 @@
|
|
|
package eu.kanade.tachiyomi.ui.recent.updates
|
|
|
|
|
|
import android.os.Bundle
|
|
|
-import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
|
|
-import eu.kanade.tachiyomi.data.database.models.Chapter
|
|
|
-import eu.kanade.tachiyomi.data.database.models.MangaChapter
|
|
|
+import eu.kanade.data.DatabaseHandler
|
|
|
+import eu.kanade.data.manga.mangaChapterMapper
|
|
|
+import eu.kanade.domain.chapter.interactor.UpdateChapter
|
|
|
+import eu.kanade.domain.chapter.model.Chapter
|
|
|
+import eu.kanade.domain.chapter.model.ChapterUpdate
|
|
|
+import eu.kanade.domain.chapter.model.toDbChapter
|
|
|
+import eu.kanade.domain.manga.model.Manga
|
|
|
+import eu.kanade.domain.manga.model.toDbManga
|
|
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
|
|
import eu.kanade.tachiyomi.data.download.model.Download
|
|
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
|
import eu.kanade.tachiyomi.source.SourceManager
|
|
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
|
|
import eu.kanade.tachiyomi.ui.recent.DateSectionItem
|
|
|
+import eu.kanade.tachiyomi.util.lang.launchIO
|
|
|
import eu.kanade.tachiyomi.util.lang.toDateKey
|
|
|
import eu.kanade.tachiyomi.util.system.logcat
|
|
|
+import kotlinx.coroutines.flow.MutableStateFlow
|
|
|
+import kotlinx.coroutines.flow.StateFlow
|
|
|
+import kotlinx.coroutines.flow.asStateFlow
|
|
|
+import kotlinx.coroutines.flow.collectLatest
|
|
|
+import kotlinx.coroutines.flow.map
|
|
|
import logcat.LogPriority
|
|
|
import rx.Observable
|
|
|
import rx.android.schedulers.AndroidSchedulers
|
|
@@ -25,24 +36,22 @@ import java.util.TreeMap
|
|
|
class UpdatesPresenter : BasePresenter<UpdatesController>() {
|
|
|
|
|
|
val preferences: PreferencesHelper by injectLazy()
|
|
|
- private val db: DatabaseHelper by injectLazy()
|
|
|
private val downloadManager: DownloadManager by injectLazy()
|
|
|
private val sourceManager: SourceManager by injectLazy()
|
|
|
|
|
|
+ private val handler: DatabaseHandler by injectLazy()
|
|
|
+ private val updateChapter: UpdateChapter by injectLazy()
|
|
|
+
|
|
|
private val relativeTime: Int = preferences.relativeTime().get()
|
|
|
private val dateFormat: DateFormat = preferences.dateFormat()
|
|
|
|
|
|
- /**
|
|
|
- * List containing chapter and manga information
|
|
|
- */
|
|
|
- private var chapters: List<UpdatesItem> = emptyList()
|
|
|
+ private val _updates: MutableStateFlow<List<UpdatesItem>> = MutableStateFlow(listOf())
|
|
|
+ val updates: StateFlow<List<UpdatesItem>> = _updates.asStateFlow()
|
|
|
|
|
|
override fun onCreate(savedState: Bundle?) {
|
|
|
super.onCreate(savedState)
|
|
|
|
|
|
getUpdatesObservable()
|
|
|
- .observeOn(AndroidSchedulers.mainThread())
|
|
|
- .subscribeLatestCache(UpdatesController::onNextRecentChapters)
|
|
|
|
|
|
downloadManager.queue.getStatusObservable()
|
|
|
.observeOn(Schedulers.io())
|
|
@@ -72,43 +81,47 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
|
|
|
*
|
|
|
* @return observable containing recent chapters and date
|
|
|
*/
|
|
|
- private fun getUpdatesObservable(): Observable<List<UpdatesItem>> {
|
|
|
+ private fun getUpdatesObservable() {
|
|
|
// Set date limit for recent chapters
|
|
|
- val cal = Calendar.getInstance().apply {
|
|
|
- time = Date()
|
|
|
- add(Calendar.MONTH, -3)
|
|
|
- }
|
|
|
+ presenterScope.launchIO {
|
|
|
+ val cal = Calendar.getInstance().apply {
|
|
|
+ time = Date()
|
|
|
+ add(Calendar.MONTH, -3)
|
|
|
+ }
|
|
|
|
|
|
- return db.getRecentChapters(cal.time).asRxObservable()
|
|
|
- // Convert to a list of recent chapters.
|
|
|
- .map { mangaChapters ->
|
|
|
- val map = TreeMap<Date, MutableList<MangaChapter>> { d1, d2 -> d2.compareTo(d1) }
|
|
|
- val byDay = mangaChapters
|
|
|
- .groupByTo(map) { it.chapter.date_fetch.toDateKey() }
|
|
|
- byDay.flatMap { entry ->
|
|
|
- val dateItem = DateSectionItem(entry.key, relativeTime, dateFormat)
|
|
|
- entry.value
|
|
|
- .sortedWith(compareBy({ it.chapter.date_fetch }, { it.chapter.chapter_number })).asReversed()
|
|
|
- .map { UpdatesItem(it.chapter, it.manga, dateItem) }
|
|
|
+ handler
|
|
|
+ .subscribeToList {
|
|
|
+ mangasQueries.getRecentlyUpdated(after = cal.timeInMillis, mangaChapterMapper)
|
|
|
}
|
|
|
- }
|
|
|
- .doOnNext { list ->
|
|
|
- list.forEach { item ->
|
|
|
- // Find an active download for this chapter.
|
|
|
- val download = downloadManager.queue.find { it.chapter.id == item.chapter.id }
|
|
|
-
|
|
|
- // If there's an active download, assign it, otherwise ask the manager if
|
|
|
- // the chapter is downloaded and assign it to the status.
|
|
|
- if (download != null) {
|
|
|
- item.download = download
|
|
|
+ .map { mangaChapter ->
|
|
|
+ val map = TreeMap<Date, MutableList<Pair<Manga, Chapter>>> { d1, d2 -> d2.compareTo(d1) }
|
|
|
+ val byDate = mangaChapter.groupByTo(map) { it.second.dateFetch.toDateKey() }
|
|
|
+ byDate.flatMap { entry ->
|
|
|
+ val dateItem = DateSectionItem(entry.key, relativeTime, dateFormat)
|
|
|
+ entry.value
|
|
|
+ .sortedWith(compareBy({ it.second.dateFetch }, { it.second.chapterNumber })).asReversed()
|
|
|
+ .map { UpdatesItem(it.second, it.first, dateItem) }
|
|
|
}
|
|
|
}
|
|
|
- setDownloadedChapters(list)
|
|
|
- chapters = list
|
|
|
+ .collectLatest { list ->
|
|
|
+ list.forEach { item ->
|
|
|
+ // Find an active download for this chapter.
|
|
|
+ val download = downloadManager.queue.find { it.chapter.id == item.chapter.id }
|
|
|
+
|
|
|
+ // If there's an active download, assign it, otherwise ask the manager if
|
|
|
+ // the chapter is downloaded and assign it to the status.
|
|
|
+ if (download != null) {
|
|
|
+ item.download = download
|
|
|
+ }
|
|
|
+ }
|
|
|
+ setDownloadedChapters(list)
|
|
|
|
|
|
- // Set unread chapter count for bottom bar badge
|
|
|
- preferences.unreadUpdatesCount().set(list.count { !it.read })
|
|
|
- }
|
|
|
+ _updates.value = list
|
|
|
+
|
|
|
+ // Set unread chapter count for bottom bar badge
|
|
|
+ preferences.unreadUpdatesCount().set(list.count { !it.chapter.read })
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -135,6 +148,7 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
|
|
|
private fun onDownloadStatusChange(download: Download) {
|
|
|
// Assign the download to the model object.
|
|
|
if (download.status == Download.State.QUEUE) {
|
|
|
+ val chapters = (view?.adapter?.currentItems ?: emptyList()).filterIsInstance<UpdatesItem>()
|
|
|
val chapter = chapters.find { it.chapter.id == download.chapter.id }
|
|
|
if (chapter != null && chapter.download == null) {
|
|
|
chapter.download = download
|
|
@@ -153,17 +167,16 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
|
|
|
* @param read read status
|
|
|
*/
|
|
|
fun markChapterRead(items: List<UpdatesItem>, read: Boolean) {
|
|
|
- val chapters = items.map { it.chapter }
|
|
|
- chapters.forEach {
|
|
|
- it.read = read
|
|
|
- if (!read) {
|
|
|
- it.last_page_read = 0
|
|
|
+ presenterScope.launchIO {
|
|
|
+ val toUpdate = items.map {
|
|
|
+ ChapterUpdate(
|
|
|
+ read = read,
|
|
|
+ lastPageRead = if (!read) 0 else null,
|
|
|
+ id = it.chapter.id,
|
|
|
+ )
|
|
|
}
|
|
|
+ updateChapter.awaitAll(toUpdate)
|
|
|
}
|
|
|
-
|
|
|
- Observable.fromCallable { db.updateChaptersProgress(chapters).executeAsBlocking() }
|
|
|
- .subscribeOn(Schedulers.io())
|
|
|
- .subscribe()
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -190,14 +203,15 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
|
|
|
* @param bookmarked bookmark status
|
|
|
*/
|
|
|
fun bookmarkChapters(items: List<UpdatesItem>, bookmarked: Boolean) {
|
|
|
- val chapters = items.map { it.chapter }
|
|
|
- chapters.forEach {
|
|
|
- it.bookmark = bookmarked
|
|
|
+ presenterScope.launchIO {
|
|
|
+ val toUpdate = items.map {
|
|
|
+ ChapterUpdate(
|
|
|
+ bookmark = bookmarked,
|
|
|
+ id = it.chapter.id,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ updateChapter.awaitAll(toUpdate)
|
|
|
}
|
|
|
-
|
|
|
- Observable.fromCallable { db.updateChaptersProgress(chapters).executeAsBlocking() }
|
|
|
- .subscribeOn(Schedulers.io())
|
|
|
- .subscribe()
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -205,7 +219,7 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
|
|
|
* @param items list of recent chapters seleted.
|
|
|
*/
|
|
|
fun downloadChapters(items: List<UpdatesItem>) {
|
|
|
- items.forEach { downloadManager.downloadChapters(it.manga, listOf(it.chapter)) }
|
|
|
+ items.forEach { downloadManager.downloadChapters(it.manga.toDbManga(), listOf(it.chapter.toDbChapter())) }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -216,9 +230,9 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
|
|
|
private fun deleteChaptersInternal(chapterItems: List<UpdatesItem>) {
|
|
|
val itemsByManga = chapterItems.groupBy { it.manga.id }
|
|
|
for ((_, items) in itemsByManga) {
|
|
|
- val manga = items.first().manga
|
|
|
+ val manga = items.first().manga.toDbManga()
|
|
|
val source = sourceManager.get(manga.source) ?: continue
|
|
|
- val chapters = items.map { it.chapter }
|
|
|
+ val chapters = items.map { it.chapter.toDbChapter() }
|
|
|
|
|
|
downloadManager.deleteChapters(chapters, manga, source)
|
|
|
items.forEach {
|