mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Fix app freezes when queueing many chapters with SAF. Closes #817
This commit is contained in:
		| @@ -91,7 +91,6 @@ class Downloader(private val context: Context, private val provider: DownloadPro | ||||
|  | ||||
|     init { | ||||
|         Observable.fromCallable { store.restore() } | ||||
|                 .map { downloads -> downloads.filter { isDownloadAllowed(it) } } | ||||
|                 .subscribeOn(Schedulers.io()) | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 .subscribe({ downloads -> queue.addAll(downloads) | ||||
| @@ -213,8 +212,7 @@ class Downloader(private val context: Context, private val provider: DownloadPro | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Creates a download object for every chapter and adds them to the downloads queue. This method | ||||
|      * must be called in the main thread. | ||||
|      * Creates a download object for every chapter and adds them to the downloads queue. | ||||
|      * | ||||
|      * @param manga the manga of the chapters to download. | ||||
|      * @param chapters the list of chapters to download. | ||||
| @@ -222,52 +220,48 @@ class Downloader(private val context: Context, private val provider: DownloadPro | ||||
|     fun queueChapters(manga: Manga, chapters: List<Chapter>) { | ||||
|         val source = sourceManager.get(manga.source) as? HttpSource ?: return | ||||
|  | ||||
|         val chaptersToQueue = chapters | ||||
|                 // Avoid downloading chapters with the same name. | ||||
|                 .distinctBy { it.name } | ||||
|                 // Add chapters to queue from the start. | ||||
|                 .sortedByDescending { it.source_order } | ||||
|                 // Create a downloader for each one. | ||||
|                 .map { Download(source, manga, it) } | ||||
|                 // Filter out those already queued or downloaded. | ||||
|                 .filter { isDownloadAllowed(it) } | ||||
|         Observable | ||||
|                 // Background, long running checks | ||||
|                 .fromCallable { | ||||
|                     val mangaDir = provider.findMangaDir(source, manga) | ||||
|  | ||||
|         // Return if there's nothing to queue. | ||||
|         if (chaptersToQueue.isEmpty()) | ||||
|             return | ||||
|                     chapters | ||||
|                             // Avoid downloading chapters with the same name. | ||||
|                             .distinctBy { it.name } | ||||
|                             // Filter out those already downloaded. | ||||
|                             .filter { mangaDir?.findFile(provider.getChapterDirName(it)) == null } | ||||
|                             // Add chapters to queue from the start. | ||||
|                             .sortedByDescending { it.source_order } | ||||
|                 } | ||||
|                 .subscribeOn(Schedulers.io()) | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 // Main thread, quick checks | ||||
|                 .map { chaptersToQueue -> | ||||
|                     chaptersToQueue | ||||
|                             // Filter out those already enqueued. | ||||
|                             .filter { chapter -> queue.none { it.chapter.id == chapter.id } } | ||||
|                             // Create a download for each one. | ||||
|                             .map { Download(source, manga, it) } | ||||
|                 } | ||||
|                 .subscribe { chaptersToQueue -> | ||||
|                     if (chaptersToQueue.isNotEmpty()) { | ||||
|                         queue.addAll(chaptersToQueue) | ||||
|  | ||||
|         queue.addAll(chaptersToQueue) | ||||
|                         // Initialize queue size. | ||||
|                         notifier.initialQueueSize = queue.size | ||||
|  | ||||
|         // Initialize queue size. | ||||
|         notifier.initialQueueSize = queue.size | ||||
|                         // Initial multi-thread | ||||
|                         notifier.multipleDownloadThreads = preferences.downloadThreads().getOrDefault() > 1 | ||||
|  | ||||
|         // Initial multi-thread | ||||
|         notifier.multipleDownloadThreads = preferences.downloadThreads().getOrDefault() > 1 | ||||
|  | ||||
|         if (isRunning) { | ||||
|             // Send the list of downloads to the downloader. | ||||
|             downloadsRelay.call(chaptersToQueue) | ||||
|         } else { | ||||
|             // Show initial notification. | ||||
|             notifier.onProgressChange(queue) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns true if the given download can be queued and downloaded. | ||||
|      * | ||||
|      * @param download the download to be checked. | ||||
|      */ | ||||
|     private fun isDownloadAllowed(download: Download): Boolean { | ||||
|         // If the chapter is already queued, don't add it again | ||||
|         if (queue.any { it.chapter.id == download.chapter.id }) | ||||
|             return false | ||||
|  | ||||
|         val dir = provider.findChapterDir(download.source, download.manga, download.chapter) | ||||
|         if (dir != null && dir.exists()) | ||||
|             return false | ||||
|  | ||||
|         return true | ||||
|                         if (isRunning) { | ||||
|                             // Send the list of downloads to the downloader. | ||||
|                             downloadsRelay.call(chaptersToQueue) | ||||
|                         } else { | ||||
|                             // Show initial notification. | ||||
|                             notifier.onProgressChange(queue) | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
		Reference in New Issue
	
	Block a user