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

This commit is contained in:
len 2016-07-01 18:30:46 +02:00
parent 06786322ca
commit ce7118084a
5 changed files with 51 additions and 30 deletions

View File

@ -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()

View File

@ -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
}
}

View File

@ -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.
*

View File

@ -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.
*/
@ -35,14 +30,27 @@ class DownloadPresenter : BasePresenter<DownloadFragment>() {
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
restartableLatestCache(GET_DOWNLOAD_QUEUE,
{ Observable.just(downloadQueue) },
{ view, downloads -> view.onNextDownloads(downloads) },
{ view, error -> Timber.e(error.message) })
if (savedState == null) {
start(GET_DOWNLOAD_QUEUE)
Observable.just(ArrayList(downloadQueue))
.doOnNext { syncQueue(it) }
.subscribeLatestCache({ view, downloads ->
view.onNextDownloads(downloads)
}, { view, error ->
Timber.e(error, 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)
@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)
}
}

View File

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