mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-24 18:01:50 +01:00
Remove old download controller
This commit is contained in:
parent
d0def563c8
commit
b79eb3f1d3
@ -1,307 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.ui.download
|
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.Menu
|
|
||||||
import android.view.MenuInflater
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadService
|
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
|
||||||
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
|
||||||
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
|
|
||||||
import kotlinx.android.synthetic.main.download_controller.*
|
|
||||||
import rx.Observable
|
|
||||||
import rx.Subscription
|
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
|
||||||
import java.util.HashMap
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controller that shows the currently active downloads.
|
|
||||||
* Uses R.layout.fragment_download_queue.
|
|
||||||
*/
|
|
||||||
class DownloadController : NucleusController<DownloadPresenter>(),
|
|
||||||
DownloadAdapter.DownloadItemListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter containing the active downloads.
|
|
||||||
*/
|
|
||||||
private var adapter: DownloadAdapter? = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map of subscriptions for active downloads.
|
|
||||||
*/
|
|
||||||
private val progressSubscriptions by lazy { HashMap<Download, Subscription>() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the download queue is running or not.
|
|
||||||
*/
|
|
||||||
private var isRunning: Boolean = false
|
|
||||||
|
|
||||||
init {
|
|
||||||
setHasOptionsMenu(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
|
||||||
return inflater.inflate(R.layout.download_controller, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createPresenter(): DownloadPresenter {
|
|
||||||
return DownloadPresenter()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTitle(): String? {
|
|
||||||
return resources?.getString(R.string.label_download_queue)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View) {
|
|
||||||
super.onViewCreated(view)
|
|
||||||
view.applyWindowInsetsForController()
|
|
||||||
|
|
||||||
// Check if download queue is empty and update information accordingly.
|
|
||||||
setInformationView()
|
|
||||||
|
|
||||||
// Initialize adapter.
|
|
||||||
adapter = DownloadAdapter(this@DownloadController)
|
|
||||||
recycler.adapter = adapter
|
|
||||||
adapter?.isHandleDragEnabled = true
|
|
||||||
|
|
||||||
// Set the layout manager for the recycler and fixed size.
|
|
||||||
recycler.layoutManager = LinearLayoutManager(view.context)
|
|
||||||
recycler.setHasFixedSize(true)
|
|
||||||
recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
|
|
||||||
|
|
||||||
// Suscribe to changes
|
|
||||||
DownloadService.runningRelay
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribeUntilDestroy { onQueueStatusChange(it) }
|
|
||||||
|
|
||||||
presenter.getDownloadStatusObservable()
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribeUntilDestroy { onStatusChange(it) }
|
|
||||||
|
|
||||||
presenter.getDownloadProgressObservable()
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribeUntilDestroy { onUpdateDownloadedPages(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
|
||||||
for (subscription in progressSubscriptions.values) {
|
|
||||||
subscription.unsubscribe()
|
|
||||||
}
|
|
||||||
progressSubscriptions.clear()
|
|
||||||
adapter = null
|
|
||||||
super.onDestroyView(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
|
||||||
inflater.inflate(R.menu.download_queue, menu)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
|
||||||
// Set start button visibility.
|
|
||||||
menu.findItem(R.id.start_queue).isVisible = !isRunning && !presenter.downloadQueue.isEmpty()
|
|
||||||
|
|
||||||
// Set pause button visibility.
|
|
||||||
menu.findItem(R.id.pause_queue).isVisible = isRunning
|
|
||||||
|
|
||||||
// Set clear button visibility.
|
|
||||||
menu.findItem(R.id.clear_queue).isVisible = !presenter.downloadQueue.isEmpty()
|
|
||||||
|
|
||||||
// Set reorder button visibility.
|
|
||||||
menu.findItem(R.id.reorder).isVisible = !presenter.downloadQueue.isEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
val context = applicationContext ?: return false
|
|
||||||
when (item.itemId) {
|
|
||||||
R.id.start_queue -> DownloadService.start(context)
|
|
||||||
R.id.pause_queue -> {
|
|
||||||
DownloadService.stop(context)
|
|
||||||
presenter.pauseDownloads()
|
|
||||||
}
|
|
||||||
R.id.clear_queue -> {
|
|
||||||
DownloadService.stop(context)
|
|
||||||
presenter.clearQueue()
|
|
||||||
}
|
|
||||||
R.id.newest, R.id.oldest -> {
|
|
||||||
val adapter = adapter ?: return false
|
|
||||||
val items = adapter.currentItems.sortedBy { it.download.chapter.date_upload }
|
|
||||||
.toMutableList()
|
|
||||||
if (item.itemId == R.id.newest)
|
|
||||||
items.reverse()
|
|
||||||
adapter.updateDataSet(items)
|
|
||||||
val downloads = items.mapNotNull { it.download }
|
|
||||||
presenter.reorder(downloads)
|
|
||||||
}
|
|
||||||
else -> return super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the status of a download changes.
|
|
||||||
*
|
|
||||||
* @param download the download whose status has changed.
|
|
||||||
*/
|
|
||||||
private fun onStatusChange(download: Download) {
|
|
||||||
when (download.status) {
|
|
||||||
Download.DOWNLOADING -> {
|
|
||||||
observeProgress(download)
|
|
||||||
// Initial update of the downloaded pages
|
|
||||||
onUpdateDownloadedPages(download)
|
|
||||||
}
|
|
||||||
Download.DOWNLOADED -> {
|
|
||||||
unsubscribeProgress(download)
|
|
||||||
onUpdateProgress(download)
|
|
||||||
onUpdateDownloadedPages(download)
|
|
||||||
}
|
|
||||||
Download.ERROR -> unsubscribeProgress(download)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Observe the progress of a download and notify the view.
|
|
||||||
*
|
|
||||||
* @param download the download to observe its progress.
|
|
||||||
*/
|
|
||||||
private fun observeProgress(download: Download) {
|
|
||||||
val subscription = Observable.interval(50, TimeUnit.MILLISECONDS)
|
|
||||||
// Get the sum of percentages for all the pages.
|
|
||||||
.flatMap {
|
|
||||||
Observable.from(download.pages)
|
|
||||||
.map(Page::progress)
|
|
||||||
.reduce { x, y -> x + y }
|
|
||||||
}
|
|
||||||
// Keep only the latest emission to avoid backpressure.
|
|
||||||
.onBackpressureLatest()
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe { progress ->
|
|
||||||
// Update the view only if the progress has changed.
|
|
||||||
if (download.totalProgress != progress) {
|
|
||||||
download.totalProgress = progress
|
|
||||||
onUpdateProgress(download)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoid leaking subscriptions
|
|
||||||
progressSubscriptions.remove(download)?.unsubscribe()
|
|
||||||
|
|
||||||
progressSubscriptions[download] = subscription
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribes the given download from the progress subscriptions.
|
|
||||||
*
|
|
||||||
* @param download the download to unsubscribe.
|
|
||||||
*/
|
|
||||||
private fun unsubscribeProgress(download: Download) {
|
|
||||||
progressSubscriptions.remove(download)?.unsubscribe()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the queue's status has changed. Updates the visibility of the buttons.
|
|
||||||
*
|
|
||||||
* @param running whether the queue is now running or not.
|
|
||||||
*/
|
|
||||||
private fun onQueueStatusChange(running: Boolean) {
|
|
||||||
isRunning = running
|
|
||||||
activity?.invalidateOptionsMenu()
|
|
||||||
|
|
||||||
// Check if download queue is empty and update information accordingly.
|
|
||||||
setInformationView()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called from the presenter to assign the downloads for the adapter.
|
|
||||||
*
|
|
||||||
* @param downloads the downloads from the queue.
|
|
||||||
*/
|
|
||||||
fun onNextDownloads(downloads: List<DownloadItem>) {
|
|
||||||
activity?.invalidateOptionsMenu()
|
|
||||||
setInformationView()
|
|
||||||
adapter?.updateDataSet(downloads)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the progress of a download changes.
|
|
||||||
*
|
|
||||||
* @param download the download whose progress has changed.
|
|
||||||
*/
|
|
||||||
fun onUpdateProgress(download: Download) {
|
|
||||||
getHolder(download)?.notifyProgress()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a page of a download is downloaded.
|
|
||||||
*
|
|
||||||
* @param download the download whose page has been downloaded.
|
|
||||||
*/
|
|
||||||
fun onUpdateDownloadedPages(download: Download) {
|
|
||||||
getHolder(download)?.notifyDownloadedPages()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the holder for the given download.
|
|
||||||
*
|
|
||||||
* @param download the download to find.
|
|
||||||
* @return the holder of the download or null if it's not bound.
|
|
||||||
*/
|
|
||||||
private fun getHolder(download: Download): DownloadHolder? {
|
|
||||||
return recycler?.findViewHolderForItemId(download.chapter.id!!) as? DownloadHolder
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set information view when queue is empty
|
|
||||||
*/
|
|
||||||
private fun setInformationView() {
|
|
||||||
if (presenter.downloadQueue.isEmpty()) {
|
|
||||||
empty_view?.show(R.drawable.ic_file_download_black_128dp,
|
|
||||||
R.string.information_no_downloads)
|
|
||||||
} else {
|
|
||||||
empty_view?.hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when an item is released from a drag.
|
|
||||||
*
|
|
||||||
* @param position The position of the released item.
|
|
||||||
*/
|
|
||||||
override fun onItemReleased(position: Int) {
|
|
||||||
val adapter = adapter ?: return
|
|
||||||
val downloads = (0 until adapter.itemCount).mapNotNull { adapter.getItem(it)?.download }
|
|
||||||
presenter.reorder(downloads)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the menu item of a download is pressed
|
|
||||||
*
|
|
||||||
* @param position The position of the item
|
|
||||||
* @param menuItem The menu Item pressed
|
|
||||||
*/
|
|
||||||
override fun onMenuItemClick(position: Int, menuItem: MenuItem) {
|
|
||||||
when (menuItem.itemId) {
|
|
||||||
R.id.move_to_top, R.id.move_to_bottom -> {
|
|
||||||
val items = adapter?.currentItems?.toMutableList() ?: return
|
|
||||||
val item = items[position]
|
|
||||||
items.remove(item)
|
|
||||||
if (menuItem.itemId == R.id.move_to_top)
|
|
||||||
items.add(0, item)
|
|
||||||
else
|
|
||||||
items.add(item)
|
|
||||||
adapter?.updateDataSet(items)
|
|
||||||
val downloads = items.mapNotNull { it.download }
|
|
||||||
presenter.reorder(downloads)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemRemoved(position: Int) {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.ui.download
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
|
||||||
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
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Presenter of [DownloadController].
|
|
||||||
*/
|
|
||||||
class DownloadPresenter : BasePresenter<DownloadController>() {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Download manager.
|
|
||||||
*/
|
|
||||||
val downloadManager: DownloadManager by injectLazy()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Property to get the queue from the download manager.
|
|
||||||
*/
|
|
||||||
val downloadQueue: DownloadQueue
|
|
||||||
get() = downloadManager.queue
|
|
||||||
|
|
||||||
override fun onCreate(savedState: Bundle?) {
|
|
||||||
super.onCreate(savedState)
|
|
||||||
|
|
||||||
downloadQueue.getUpdatedObservable()
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.map { it.map(::DownloadItem) }
|
|
||||||
.subscribeLatestCache(DownloadController::onNextDownloads) { _, error ->
|
|
||||||
Timber.e(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getDownloadStatusObservable(): Observable<Download> {
|
|
||||||
return downloadQueue.getStatusObservable()
|
|
||||||
.startWith(downloadQueue.getActiveDownloads())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getDownloadProgressObservable(): Observable<Download> {
|
|
||||||
return downloadQueue.getProgressObservable()
|
|
||||||
.onBackpressureBuffer()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pauses the download queue.
|
|
||||||
*/
|
|
||||||
fun pauseDownloads() {
|
|
||||||
downloadManager.pauseDownloads()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the download queue.
|
|
||||||
*/
|
|
||||||
fun clearQueue() {
|
|
||||||
downloadManager.clearQueue()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun reorder(downloads: List<Download>) {
|
|
||||||
downloadManager.reorderQueue(downloads)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun cancelDownload(download: Download) {
|
|
||||||
downloadManager.deletePendingDownloads(download)
|
|
||||||
}
|
|
||||||
}
|
|
@ -47,7 +47,6 @@ import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
|||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
|
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
|
||||||
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
|
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
|
||||||
import eu.kanade.tachiyomi.ui.download.DownloadController
|
|
||||||
import eu.kanade.tachiyomi.ui.library.LibraryController
|
import eu.kanade.tachiyomi.ui.library.LibraryController
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||||
import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController
|
import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController
|
||||||
@ -399,9 +398,12 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
router.pushController(MangaDetailsController(extras).withFadeTransaction())
|
router.pushController(MangaDetailsController(extras).withFadeTransaction())
|
||||||
}
|
}
|
||||||
SHORTCUT_DOWNLOADS -> {
|
SHORTCUT_DOWNLOADS -> {
|
||||||
if (router.backstack.none { it.controller() is DownloadController }) {
|
bottom_nav.selectedItemId = R.id.nav_catalogues
|
||||||
if (router.backstack.isEmpty()) bottom_nav.selectedItemId = R.id.nav_library
|
router.popToRoot()
|
||||||
router.pushController(DownloadController().withFadeTransaction())
|
bottom_nav.post {
|
||||||
|
val controller =
|
||||||
|
router.backstack.firstOrNull()?.controller() as? RecentsController
|
||||||
|
controller?.showDownloads()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Intent.ACTION_SEARCH, "com.google.android.gms.actions.SEARCH_ACTION" -> {
|
Intent.ACTION_SEARCH, "com.google.android.gms.actions.SEARCH_ACTION" -> {
|
||||||
|
@ -353,6 +353,10 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showDownloads() {
|
||||||
|
dl_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
|
||||||
|
}
|
||||||
|
|
||||||
fun toggleDownloads() {
|
fun toggleDownloads() {
|
||||||
if (dl_bottom_sheet.sheetBehavior?.isHideable == false) {
|
if (dl_bottom_sheet.sheetBehavior?.isHideable == false) {
|
||||||
if (showingDownloads) dl_bottom_sheet.dismiss()
|
if (showingDownloads) dl_bottom_sheet.dismiss()
|
||||||
|
Loading…
Reference in New Issue
Block a user