Browse Source

Downloads view now uses a copy of the original queue. Fixes #351 and some crashes while scrolling and removing a download from the queue

len 8 years ago
parent
commit
ce7118084a

+ 18 - 6
app/src/main/java/eu/kanade/tachiyomi/data/download/model/DownloadQueue.kt

@@ -6,29 +6,41 @@ import rx.Observable
 import rx.subjects.PublishSubject
 import java.util.concurrent.CopyOnWriteArrayList
 
-class DownloadQueue : CopyOnWriteArrayList<Download>() {
+class DownloadQueue(private val queue: MutableList<Download> = CopyOnWriteArrayList<Download>())
+: List<Download> by queue {
 
     private val statusSubject = PublishSubject.create<Download>()
 
-    override fun add(download: Download): Boolean {
+    private val removeSubject = PublishSubject.create<Download>()
+
+    fun add(download: Download): Boolean {
         download.setStatusSubject(statusSubject)
         download.status = Download.QUEUE
-        return super.add(download)
+        return queue.add(download)
     }
 
     fun del(download: Download) {
-        super.remove(download)
+        val removed = queue.remove(download)
         download.setStatusSubject(null)
+        if (removed) {
+            removeSubject.onNext(download)
+        }
     }
 
     fun del(chapter: Chapter) {
         find { it.chapter.id == chapter.id }?.let { del(it) }
     }
 
-    fun getActiveDownloads() =
+    fun clear() {
+        queue.forEach { del(it) }
+    }
+
+    fun getActiveDownloads(): Observable<Download> =
         Observable.from(this).filter { download -> download.status == Download.DOWNLOADING }
 
-    fun getStatusObservable() = statusSubject.onBackpressureBuffer()
+    fun getStatusObservable(): Observable<Download> = statusSubject.onBackpressureBuffer()
+
+    fun getRemovedObservable(): Observable<Download> = removeSubject.onBackpressureBuffer()
 
     fun getProgressObservable(): Observable<Download> {
         return statusSubject.onBackpressureBuffer()

+ 7 - 8
app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaDataFetcher.kt

@@ -1,5 +1,6 @@
 package eu.kanade.tachiyomi.data.glide
 
+import android.support.v4.util.AtomicFile
 import com.bumptech.glide.Priority
 import com.bumptech.glide.load.data.DataFetcher
 import eu.kanade.tachiyomi.data.database.models.Manga
@@ -27,16 +28,14 @@ class MangaDataFetcher(private val networkFetcher: DataFetcher<InputStream>,
     override fun loadData(priority: Priority): InputStream? {
         if (manga.favorite) {
             if (!file.exists()) {
-                file.parentFile.mkdirs()
-                networkFetcher.loadData(priority)?.let {
+                networkFetcher.loadData(priority)?.let { input ->
+                    val atomicFile = AtomicFile(file)
+                    val output = atomicFile.startWrite()
                     try {
-                        it.use { input ->
-                            file.outputStream().use { output ->
-                                input.copyTo(output)
-                            }
-                        }
+                        input.use { it.copyTo(output) }
+                        atomicFile.finishWrite(output)
                     } catch (e: Exception) {
-                        file.delete()
+                        atomicFile.failWrite(output)
                         throw e
                     }
                 }

+ 4 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadFragment.kt

@@ -236,6 +236,10 @@ class DownloadFragment : BaseRxFragment<DownloadPresenter>() {
         adapter.setItems(downloads)
     }
 
+    fun onDownloadRemoved(position: Int) {
+        adapter.notifyItemRemoved(position)
+    }
+
     /**
      * Called when the progress of a download changes.
      *

+ 22 - 15
app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt

@@ -6,21 +6,16 @@ import eu.kanade.tachiyomi.data.download.model.Download
 import eu.kanade.tachiyomi.data.download.model.DownloadQueue
 import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
 import rx.Observable
+import rx.android.schedulers.AndroidSchedulers
 import timber.log.Timber
 import uy.kohesive.injekt.injectLazy
+import java.util.*
 
 /**
  * Presenter of [DownloadFragment].
  */
 class DownloadPresenter : BasePresenter<DownloadFragment>() {
 
-    companion object {
-        /**
-         * Id of the restartable that returns the download queue.
-         */
-        const val GET_DOWNLOAD_QUEUE = 1
-    }
-
     /**
      * Download manager.
      */
@@ -34,15 +29,28 @@ class DownloadPresenter : BasePresenter<DownloadFragment>() {
 
     override fun onCreate(savedState: Bundle?) {
         super.onCreate(savedState)
+        
+        Observable.just(ArrayList(downloadQueue))
+                .doOnNext { syncQueue(it) }
+                .subscribeLatestCache({ view, downloads ->
+                    view.onNextDownloads(downloads)
+                }, { view, error ->
+                    Timber.e(error, error.message)
+                })
+    }
 
-        restartableLatestCache(GET_DOWNLOAD_QUEUE,
-                { Observable.just(downloadQueue) },
-                { view, downloads -> view.onNextDownloads(downloads) },
-                { view, error -> Timber.e(error.message) })
+    private fun syncQueue(queue: MutableList<Download>) {
+        add(downloadQueue.getRemovedObservable()
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe { download ->
+                    val position = queue.indexOf(download)
+                    if (position != -1) {
+                        queue.removeAt(position)
 
-        if (savedState == null) {
-            start(GET_DOWNLOAD_QUEUE)
-        }
+                        @Suppress("DEPRECATION")
+                        view?.onDownloadRemoved(position)
+                    }
+                })
     }
 
     fun getStatusObservable(): Observable<Download> {
@@ -60,7 +68,6 @@ class DownloadPresenter : BasePresenter<DownloadFragment>() {
      */
     fun clearQueue() {
         downloadManager.clearQueue()
-        start(GET_DOWNLOAD_QUEUE)
     }
 
 }

+ 0 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.kt

@@ -47,7 +47,6 @@ class LibraryHolder(private val view: View,
                 .load(manga)
                 .diskCacheStrategy(DiskCacheStrategy.RESULT)
                 .centerCrop()
-                .placeholder(android.R.color.transparent)
                 .into(view.thumbnail)
     }