From b79eb3f1d3484aa36545010ef27e29d45d189da3 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 4 Apr 2020 14:01:46 -0400 Subject: [PATCH] Remove old download controller --- .../ui/download/DownloadController.kt | 307 ------------------ .../ui/download/DownloadPresenter.kt | 71 ---- .../kanade/tachiyomi/ui/main/MainActivity.kt | 10 +- .../tachiyomi/ui/recents/RecentsController.kt | 4 + 4 files changed, 10 insertions(+), 382 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt deleted file mode 100644 index 6fb021dfe4..0000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt +++ /dev/null @@ -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(), - DownloadAdapter.DownloadItemListener { - - /** - * Adapter containing the active downloads. - */ - private var adapter: DownloadAdapter? = null - - /** - * Map of subscriptions for active downloads. - */ - private val progressSubscriptions by lazy { HashMap() } - - /** - * 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) { - 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) { - } -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt deleted file mode 100644 index ccf810b88c..0000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt +++ /dev/null @@ -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() { - - /** - * 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 { - return downloadQueue.getStatusObservable() - .startWith(downloadQueue.getActiveDownloads()) - } - - fun getDownloadProgressObservable(): Observable { - return downloadQueue.getProgressObservable() - .onBackpressureBuffer() - } - - /** - * Pauses the download queue. - */ - fun pauseDownloads() { - downloadManager.pauseDownloads() - } - - /** - * Clears the download queue. - */ - fun clearQueue() { - downloadManager.clearQueue() - } - - fun reorder(downloads: List) { - downloadManager.reorderQueue(downloads) - } - - fun cancelDownload(download: Download) { - downloadManager.deletePendingDownloads(download) - } -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 3275d425fe..f8d0c5fcf3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -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.catalogue.CatalogueController 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.manga.MangaDetailsController import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController @@ -399,9 +398,12 @@ open class MainActivity : BaseActivity(), DownloadServiceListener { router.pushController(MangaDetailsController(extras).withFadeTransaction()) } SHORTCUT_DOWNLOADS -> { - if (router.backstack.none { it.controller() is DownloadController }) { - if (router.backstack.isEmpty()) bottom_nav.selectedItemId = R.id.nav_library - router.pushController(DownloadController().withFadeTransaction()) + bottom_nav.selectedItemId = R.id.nav_catalogues + router.popToRoot() + bottom_nav.post { + val controller = + router.backstack.firstOrNull()?.controller() as? RecentsController + controller?.showDownloads() } } Intent.ACTION_SEARCH, "com.google.android.gms.actions.SEARCH_ACTION" -> { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt index ab0289c12a..0db6accabb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt @@ -353,6 +353,10 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle), } } + fun showDownloads() { + dl_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED + } + fun toggleDownloads() { if (dl_bottom_sheet.sheetBehavior?.isHideable == false) { if (showingDownloads) dl_bottom_sheet.dismiss()