| 
					
				 | 
			
			
				@@ -17,31 +17,30 @@ 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.lang.withUIContext 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 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.catch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import kotlinx.coroutines.flow.collectLatest 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import kotlinx.coroutines.flow.map 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import logcat.LogPriority 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import rx.Observable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import rx.android.schedulers.AndroidSchedulers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import rx.schedulers.Schedulers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import uy.kohesive.injekt.injectLazy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import uy.kohesive.injekt.Injekt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import uy.kohesive.injekt.api.get 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.text.DateFormat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.Calendar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.Date 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.TreeMap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-class UpdatesPresenter : BasePresenter<UpdatesController>() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    val preferences: PreferencesHelper 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 setReadStatus: SetReadStatus by injectLazy() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class UpdatesPresenter( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private val preferences: PreferencesHelper = Injekt.get(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private val downloadManager: DownloadManager = Injekt.get(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private val sourceManager: SourceManager = Injekt.get(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private val handler: DatabaseHandler = Injekt.get(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private val updateChapter: UpdateChapter = Injekt.get(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private val setReadStatus: SetReadStatus = Injekt.get(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+) : BasePresenter<UpdatesController>() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private val relativeTime: Int = preferences.relativeTime().get() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private val dateFormat: DateFormat = preferences.dateFormat() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -52,77 +51,70 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     override fun onCreate(savedState: Bundle?) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         super.onCreate(savedState) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        getUpdatesObservable() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        downloadManager.queue.getStatusObservable() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .observeOn(Schedulers.io()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .onBackpressureBuffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .observeOn(AndroidSchedulers.mainThread()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .subscribeLatestCache( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { view, it -> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    onDownloadStatusChange(it) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    view.onChapterDownloadUpdate(it) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { _, error -> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    logcat(LogPriority.ERROR, error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        presenterScope.launchIO { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            subscribeToUpdates() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            downloadManager.queue.getStatusAsFlow() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .catch { error -> logcat(LogPriority.ERROR, error) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .collectLatest { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    withUIContext { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        onDownloadStatusChange(it) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        view?.onChapterDownloadUpdate(it) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        downloadManager.queue.getProgressObservable() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .observeOn(Schedulers.io()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .onBackpressureBuffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .observeOn(AndroidSchedulers.mainThread()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .subscribeLatestCache(UpdatesController::onChapterDownloadUpdate) { _, error -> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                logcat(LogPriority.ERROR, error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            downloadManager.queue.getProgressAsFlow() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .catch { error -> logcat(LogPriority.ERROR, error) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .collectLatest { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    withUIContext { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        view?.onChapterDownloadUpdate(it) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * Get observable containing recent chapters and date 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return observable containing recent chapters and date 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private fun getUpdatesObservable() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private suspend fun subscribeToUpdates() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // Set date limit for recent chapters 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        presenterScope.launchIO { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            val cal = Calendar.getInstance().apply { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                time = Date() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                add(Calendar.MONTH, -3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        val cal = Calendar.getInstance().apply { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            time = Date() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            add(Calendar.MONTH, -3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            handler 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .subscribeToList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    mangasQueries.getRecentlyUpdated(after = cal.timeInMillis, mangaChapterMapper) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handler 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .subscribeToList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mangasQueries.getRecentlyUpdated(after = cal.timeInMillis, mangaChapterMapper) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .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) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .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) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                setDownloadedChapters(list) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    _updates.value = list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _updates.value = list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // Set unread chapter count for bottom bar badge 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    preferences.unreadUpdatesCount().set(list.count { !it.chapter.read }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // Set unread chapter count for bottom bar badge 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                preferences.unreadUpdatesCount().set(list.count { !it.chapter.read }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /** 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -184,16 +176,14 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * @param chapters list of chapters 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fun deleteChapters(chapters: List<UpdatesItem>) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Observable.just(chapters) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .doOnNext { deleteChaptersInternal(it) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .subscribeOn(Schedulers.io()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .observeOn(AndroidSchedulers.mainThread()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .subscribeFirst( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { view, _ -> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    view.onChaptersDeleted() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                UpdatesController::onChaptersDeletedError, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        launchIO { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                deleteChaptersInternal(chapters) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                withUIContext { view?.onChaptersDeleted() } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } catch (e: Throwable) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                withUIContext { view?.onChaptersDeletedError(e) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /** 
			 |