Downloads view now uses a copy of the original queue. Fixes #351 and some crashes while scrolling and removing a download from the queue
Cette révision appartient à :
Parent
06786322ca
révision
ce7118084a
5 fichiers modifiés avec 51 ajouts et 30 suppressions
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ class LibraryHolder(private val view: View,
|
|||
.load(manga)
|
||||
.diskCacheStrategy(DiskCacheStrategy.RESULT)
|
||||
.centerCrop()
|
||||
.placeholder(android.R.color.transparent)
|
||||
.into(view.thumbnail)
|
||||
}
|
||||
|
||||
|
|
Référencer dans un nouveau ticket