Add download queue features from J2K fork
This commit is contained in:
@@ -5,6 +5,7 @@ import com.hippo.unifile.UniFile
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
@@ -19,7 +20,7 @@ import uy.kohesive.injekt.injectLazy
|
||||
*
|
||||
* @param context the application context.
|
||||
*/
|
||||
class DownloadManager(context: Context) {
|
||||
class DownloadManager(private val context: Context) {
|
||||
|
||||
/**
|
||||
* The sources manager.
|
||||
@@ -92,6 +93,29 @@ class DownloadManager(context: Context) {
|
||||
downloader.clearQueue(isNotification)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorders the download queue.
|
||||
*
|
||||
* @param downloads value to set the download queue to
|
||||
*/
|
||||
fun reorderQueue(downloads: List<Download>) {
|
||||
val wasRunning = downloader.isRunning
|
||||
|
||||
if (downloads.isEmpty()) {
|
||||
DownloadService.stop(context)
|
||||
downloader.queue.clear()
|
||||
return
|
||||
}
|
||||
|
||||
downloader.pause()
|
||||
downloader.queue.clear()
|
||||
downloader.queue.addAll(downloads)
|
||||
|
||||
if (wasRunning) {
|
||||
downloader.start()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the downloader to enqueue the given list of chapters.
|
||||
*
|
||||
@@ -157,6 +181,15 @@ class DownloadManager(context: Context) {
|
||||
return cache.getDownloadCount(manga)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls delete chapter, which deletes a temp download.
|
||||
*
|
||||
* @param download the download to cancel.
|
||||
*/
|
||||
fun deletePendingDownload(download: Download) {
|
||||
deleteChapters(listOf(download.chapter), download.manga, download.source)
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the directories of a list of downloaded chapters.
|
||||
*
|
||||
|
||||
@@ -83,7 +83,8 @@ class Downloader(
|
||||
* Whether the downloader is running.
|
||||
*/
|
||||
@Volatile
|
||||
private var isRunning: Boolean = false
|
||||
var isRunning: Boolean = false
|
||||
private set
|
||||
|
||||
init {
|
||||
launchNow {
|
||||
|
||||
@@ -24,17 +24,30 @@ class Download(val source: HttpSource, val manga: Manga, val chapter: Chapter) {
|
||||
set(status) {
|
||||
field = status
|
||||
statusSubject?.onNext(this)
|
||||
statusCallback?.invoke(this)
|
||||
}
|
||||
|
||||
@Transient
|
||||
private var statusSubject: PublishSubject<Download>? = null
|
||||
|
||||
@Transient
|
||||
private var statusCallback: ((Download) -> Unit)? = null
|
||||
|
||||
val progress: Int
|
||||
get() {
|
||||
val pages = pages ?: return 0
|
||||
return pages.map(Page::progress).average().toInt()
|
||||
}
|
||||
|
||||
fun setStatusSubject(subject: PublishSubject<Download>?) {
|
||||
statusSubject = subject
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun setStatusCallback(f: ((Download) -> Unit)?) {
|
||||
statusCallback = f
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val NOT_DOWNLOADED = 0
|
||||
const val QUEUE = 1
|
||||
const val DOWNLOADING = 2
|
||||
|
||||
@@ -12,16 +12,18 @@ import rx.subjects.PublishSubject
|
||||
class DownloadQueue(
|
||||
private val store: DownloadStore,
|
||||
private val queue: MutableList<Download> = CopyOnWriteArrayList<Download>()
|
||||
) :
|
||||
List<Download> by queue {
|
||||
) : List<Download> by queue {
|
||||
|
||||
private val statusSubject = PublishSubject.create<Download>()
|
||||
|
||||
private val updatedRelay = PublishRelay.create<Unit>()
|
||||
|
||||
private val downloadListeners = mutableListOf<DownloadListener>()
|
||||
|
||||
fun addAll(downloads: List<Download>) {
|
||||
downloads.forEach { download ->
|
||||
download.setStatusSubject(statusSubject)
|
||||
download.setStatusCallback(::setPagesFor)
|
||||
download.status = Download.QUEUE
|
||||
}
|
||||
queue.addAll(downloads)
|
||||
@@ -33,6 +35,11 @@ class DownloadQueue(
|
||||
val removed = queue.remove(download)
|
||||
store.remove(download)
|
||||
download.setStatusSubject(null)
|
||||
download.setStatusCallback(null)
|
||||
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE) {
|
||||
download.status = Download.NOT_DOWNLOADED
|
||||
}
|
||||
callListeners(download)
|
||||
if (removed) {
|
||||
updatedRelay.call(Unit)
|
||||
}
|
||||
@@ -55,6 +62,11 @@ class DownloadQueue(
|
||||
fun clear() {
|
||||
queue.forEach { download ->
|
||||
download.setStatusSubject(null)
|
||||
download.setStatusCallback(null)
|
||||
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE) {
|
||||
download.status = Download.NOT_DOWNLOADED
|
||||
}
|
||||
callListeners(download)
|
||||
}
|
||||
queue.clear()
|
||||
store.clear()
|
||||
@@ -70,6 +82,24 @@ class DownloadQueue(
|
||||
.startWith(Unit)
|
||||
.map { this }
|
||||
|
||||
private fun setPagesFor(download: Download) {
|
||||
if (download.status == Download.DOWNLOADING) {
|
||||
download.pages?.forEach { page ->
|
||||
page.setStatusCallback {
|
||||
callListeners(download)
|
||||
}
|
||||
}
|
||||
} else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
|
||||
setPagesSubject(download.pages, null)
|
||||
}
|
||||
|
||||
callListeners(download)
|
||||
}
|
||||
|
||||
private fun callListeners(download: Download) {
|
||||
downloadListeners.forEach { it.updateDownload(download) }
|
||||
}
|
||||
|
||||
fun getProgressObservable(): Observable<Download> {
|
||||
return statusSubject.onBackpressureBuffer()
|
||||
.startWith(getActiveDownloads())
|
||||
@@ -77,12 +107,14 @@ class DownloadQueue(
|
||||
if (download.status == Download.DOWNLOADING) {
|
||||
val pageStatusSubject = PublishSubject.create<Int>()
|
||||
setPagesSubject(download.pages, pageStatusSubject)
|
||||
callListeners(download)
|
||||
return@flatMap pageStatusSubject
|
||||
.onBackpressureBuffer()
|
||||
.filter { it == Page.READY }
|
||||
.map { download }
|
||||
} else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
|
||||
setPagesSubject(download.pages, null)
|
||||
callListeners(download)
|
||||
}
|
||||
Observable.just(download)
|
||||
}
|
||||
@@ -96,4 +128,16 @@ class DownloadQueue(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addListener(listener: DownloadListener) {
|
||||
downloadListeners.add(listener)
|
||||
}
|
||||
|
||||
fun removeListener(listener: DownloadListener) {
|
||||
downloadListeners.remove(listener)
|
||||
}
|
||||
|
||||
interface DownloadListener {
|
||||
fun updateDownload(download: Download)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user