From 72ea256906faad643f33cca1fd47a448fbcca4d6 Mon Sep 17 00:00:00 2001 From: len Date: Tue, 23 May 2017 20:03:16 +0200 Subject: [PATCH] Downloads with conductor. Remove flexible adapter 4 dependency and unused classes. --- app/build.gradle | 24 +- app/src/main/AndroidManifest.xml | 3 - .../data/notification/NotificationHandler.kt | 5 +- .../ui/base/adapter/FlexibleViewHolder.kt | 39 -- .../adapter/SmartFragmentStatePagerAdapter.kt | 41 -- .../tachiyomi/ui/download/DownloadAdapter.kt | 26 +- ...nloadActivity.kt => DownloadController.kt} | 498 +++++++++--------- .../ui/download/DownloadPresenter.kt | 6 +- .../kanade/tachiyomi/ui/main/MainActivity.kt | 9 +- .../res/layout/activity_download_manager.xml | 52 +- 10 files changed, 306 insertions(+), 397 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/base/adapter/FlexibleViewHolder.kt delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/base/adapter/SmartFragmentStatePagerAdapter.kt rename app/src/main/java/eu/kanade/tachiyomi/ui/download/{DownloadActivity.kt => DownloadController.kt} (68%) diff --git a/app/build.gradle b/app/build.gradle index 8f98e5a8c..9205d23a3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,17 +100,6 @@ android { dependencies { - compile "com.bluelinelabs:conductor:2.1.3" - compile 'com.github.inorichi:conductor-support-preference:master-SNAPSHOT' - - final rxbindings_version = '1.0.1' - compile "com.jakewharton.rxbinding:rxbinding-kotlin:$rxbindings_version" - compile "com.jakewharton.rxbinding:rxbinding-appcompat-v7-kotlin:$rxbindings_version" - compile "com.jakewharton.rxbinding:rxbinding-support-v4-kotlin:$rxbindings_version" - compile "com.jakewharton.rxbinding:rxbinding-recyclerview-v7-kotlin:$rxbindings_version" - - compile 'com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.0.4' - // Modified dependencies compile 'com.github.inorichi:subsampling-scale-image-view:01e5385' compile 'com.github.inorichi:junrar-android:634c1f5' @@ -201,12 +190,23 @@ dependencies { compile 'com.dmitrymalkovich.android:material-design-dimens:1.4' compile 'com.github.dmytrodanylyk.android-process-button:library:1.0.4' compile 'eu.davidea:flexible-adapter:5.0.0-rc1' - compile 'com.github.inorichi:FlexibleAdapter:93985fe' // v4.2.0 to be removed compile 'com.nononsenseapps:filepicker:2.5.2' compile 'com.github.amulyakhare:TextDrawable:558677e' compile 'com.afollestad.material-dialogs:core:0.9.4.2' compile 'me.zhanghai.android.systemuihelper:library:1.0.0' compile 'de.hdodenhof:circleimageview:2.1.0' + compile 'com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.0.4' + + // Conductor + compile "com.bluelinelabs:conductor:2.1.3" + compile 'com.github.inorichi:conductor-support-preference:9e36460' + + // RxBindings + final rxbindings_version = '1.0.1' + compile "com.jakewharton.rxbinding:rxbinding-kotlin:$rxbindings_version" + compile "com.jakewharton.rxbinding:rxbinding-appcompat-v7-kotlin:$rxbindings_version" + compile "com.jakewharton.rxbinding:rxbinding-support-v4-kotlin:$rxbindings_version" + compile "com.jakewharton.rxbinding:rxbinding-recyclerview-v7-kotlin:$rxbindings_version" // Tests testCompile 'junit:junit:4.12' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 953006fb5..b83ac4306 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -53,9 +53,6 @@ android:scheme="tachiyomi" /> - , - private val itemClickListener: FlexibleViewHolder.OnListItemClickListener) : - RecyclerView.ViewHolder(view), View.OnClickListener, View.OnLongClickListener { - - init { - view.setOnClickListener(this) - view.setOnLongClickListener(this) - } - - override fun onClick(view: View) { - if (itemClickListener.onListItemClick(adapterPosition)) { - toggleActivation() - } - } - - override fun onLongClick(view: View): Boolean { - itemClickListener.onListItemLongClick(adapterPosition) - toggleActivation() - return true - } - - fun toggleActivation() { - itemView.isActivated = adapter.isSelected(adapterPosition) - } - - interface OnListItemClickListener { - fun onListItemClick(position: Int): Boolean - fun onListItemLongClick(position: Int) - } - -} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/adapter/SmartFragmentStatePagerAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/adapter/SmartFragmentStatePagerAdapter.kt deleted file mode 100644 index 2169b603c..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/adapter/SmartFragmentStatePagerAdapter.kt +++ /dev/null @@ -1,41 +0,0 @@ -package eu.kanade.tachiyomi.ui.base.adapter - -import android.support.v4.app.Fragment -import android.support.v4.app.FragmentManager -import android.support.v4.app.FragmentStatePagerAdapter -import android.util.SparseArray -import android.view.ViewGroup -import java.util.* - -abstract class SmartFragmentStatePagerAdapter(fragmentManager: FragmentManager) : - FragmentStatePagerAdapter(fragmentManager) { - // Sparse array to keep track of registered fragments in memory - private val registeredFragments = SparseArray() - - // Register the fragment when the item is instantiated - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val fragment = super.instantiateItem(container, position) as Fragment - registeredFragments.put(position, fragment) - return fragment - } - - // Unregister when the item is inactive - override fun destroyItem(container: ViewGroup?, position: Int, `object`: Any) { - registeredFragments.remove(position) - super.destroyItem(container, position, `object`) - } - - // Returns the fragment for the position (if instantiated) - fun getRegisteredFragment(position: Int): Fragment { - return registeredFragments.get(position) - } - - fun getRegisteredFragments(): List { - val fragments = ArrayList() - for (i in 0..registeredFragments.size() - 1) { - fragments.add(registeredFragments.valueAt(i)) - } - return fragments - } - -} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadAdapter.kt index 5f5e7d361..f7194b764 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadAdapter.kt @@ -1,8 +1,7 @@ package eu.kanade.tachiyomi.ui.download -import android.content.Context +import android.support.v7.widget.RecyclerView import android.view.ViewGroup -import eu.davidea.flexibleadapter4.FlexibleAdapter import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.util.inflate @@ -12,7 +11,9 @@ import eu.kanade.tachiyomi.util.inflate * * @param context the context of the fragment containing this adapter. */ -class DownloadAdapter(private val context: Context) : FlexibleAdapter() { +class DownloadAdapter : RecyclerView.Adapter() { + + private var items = emptyList() init { setHasStableIds(true) @@ -24,10 +25,17 @@ class DownloadAdapter(private val context: Context) : FlexibleAdapter) { - mItems = downloads + items = downloads notifyDataSetChanged() } + /** + * Returns the number of downloads in the adapter + */ + override fun getItemCount(): Int { + return items.size + } + /** * Returns the identifier for a download. * @@ -35,7 +43,7 @@ class DownloadAdapter(private val context: Context) : FlexibleAdapter() { - /** - * Adapter containing the active downloads. - */ - private lateinit var adapter: DownloadAdapter - - /** - * Subscription list to be cleared during [onDestroy]. - */ - private val subscriptions by lazy { CompositeSubscription() } - - /** - * 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 - - override fun onCreate(savedState: Bundle?) { - setAppTheme() - super.onCreate(savedState) - setContentView(R.layout.activity_download_manager) - setupToolbar(toolbar) - setToolbarTitle(R.string.label_download_queue) - - // Check if download queue is empty and update information accordingly. - setInformationView() - - // Initialize adapter. - adapter = DownloadAdapter(this) - recycler.adapter = adapter - - // Set the layout manager for the recycler and fixed size. - recycler.layoutManager = LinearLayoutManager(this) - recycler.setHasFixedSize(true) - - // Suscribe to changes - subscriptions += DownloadService.runningRelay - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { onQueueStatusChange(it) } - - subscriptions += presenter.getDownloadStatusObservable() - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { onStatusChange(it) } - - subscriptions += presenter.getDownloadProgressObservable() - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { onUpdateDownloadedPages(it) } - } - - override fun onDestroy() { - for (subscription in progressSubscriptions.values) { - subscription.unsubscribe() - } - progressSubscriptions.clear() - subscriptions.clear() - super.onDestroy() - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - menuInflater.inflate(R.menu.download_queue, menu) - return true - } - - override fun onPrepareOptionsMenu(menu: Menu): Boolean { - // 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() - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - R.id.start_queue -> DownloadService.start(this) - R.id.pause_queue -> { - DownloadService.stop(this) - presenter.pauseDownloads() - } - R.id.clear_queue -> { - DownloadService.stop(this) - presenter.clearQueue() - } - 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.put(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 - supportInvalidateOptionsMenu() - - // 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) { - supportInvalidateOptionsMenu() - setInformationView() - adapter.setItems(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() { - updateEmptyView(presenter.downloadQueue.isEmpty(), - R.string.information_no_downloads, R.drawable.ic_file_download_black_128dp) - } - - fun updateEmptyView(show: Boolean, textResource: Int, drawable: Int) { -// if (show) empty_view.show(drawable, textResource) else empty_view.hide() - } -} +package eu.kanade.tachiyomi.ui.download + +import android.os.Bundle +import android.support.v7.widget.LinearLayoutManager +import android.view.* +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 kotlinx.android.synthetic.main.activity_download_manager.view.* +import rx.Observable +import rx.Subscription +import rx.android.schedulers.AndroidSchedulers +import java.util.* +import java.util.concurrent.TimeUnit + +/** + * Controller that shows the currently active downloads. + * Uses R.layout.fragment_download_queue. + */ +class DownloadController : NucleusController() { + + /** + * 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.activity_download_manager, 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, savedViewState: Bundle?) { + super.onViewCreated(view, savedViewState) + + // Check if download queue is empty and update information accordingly. + setInformationView() + + // Initialize adapter. + adapter = DownloadAdapter() + with(view) { + recycler.adapter = adapter + + // Set the layout manager for the recycler and fixed size. + recycler.layoutManager = LinearLayoutManager(context) + recycler.setHasFixedSize(true) + } + + // 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) { + super.onDestroyView(view) + for (subscription in progressSubscriptions.values) { + subscription.unsubscribe() + } + progressSubscriptions.clear() + adapter = null + } + + 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() + } + + 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() + } + 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.put(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?.setItems(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? { + val recycler = view?.recycler ?: return null + return recycler.findViewHolderForItemId(download.chapter.id!!) as? DownloadHolder + } + + /** + * Set information view when queue is empty + */ + private fun setInformationView() { + val emptyView = view?.empty_view ?: return + if (presenter.downloadQueue.isEmpty()) { + emptyView.show(R.drawable.ic_file_download_black_128dp, + R.string.information_no_downloads) + } else { + emptyView.hide() + } + } + +} 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 index 2664a70e3..4e5b5e288 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.kt @@ -12,9 +12,9 @@ import uy.kohesive.injekt.injectLazy import java.util.* /** - * Presenter of [DownloadActivity]. + * Presenter of [DownloadController]. */ -class DownloadPresenter : BasePresenter() { +class DownloadPresenter : BasePresenter() { /** * Download manager. @@ -33,7 +33,7 @@ class DownloadPresenter : BasePresenter() { downloadQueue.getUpdatedObservable() .observeOn(AndroidSchedulers.mainThread()) .map { ArrayList(it) } - .subscribeLatestCache(DownloadActivity::onNextDownloads, { view, error -> + .subscribeLatestCache(DownloadController::onNextDownloads, { view, error -> Timber.e(error) }) } 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 5b825f9c4..8f1e435b0 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 @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.ui.main import android.animation.ObjectAnimator -import android.content.Intent import android.graphics.Color import android.os.Bundle import android.support.v4.view.GravityCompat @@ -19,7 +18,7 @@ import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController import eu.kanade.tachiyomi.ui.base.controller.TabbedController import eu.kanade.tachiyomi.ui.catalogue.CatalogueController -import eu.kanade.tachiyomi.ui.download.DownloadActivity +import eu.kanade.tachiyomi.ui.download.DownloadController import eu.kanade.tachiyomi.ui.latest_updates.LatestUpdatesController import eu.kanade.tachiyomi.ui.library.LibraryController import eu.kanade.tachiyomi.ui.manga.MangaController @@ -85,7 +84,9 @@ class MainActivity : BaseActivity() { R.id.nav_drawer_catalogues -> setRoot(CatalogueController(), id) R.id.nav_drawer_latest_updates -> setRoot(LatestUpdatesController(), id) R.id.nav_drawer_downloads -> { - startActivity(Intent(this, DownloadActivity::class.java)) + router.pushController(RouterTransaction.with(DownloadController()) + .pushChangeHandler(FadeChangeHandler()) + .popChangeHandler(FadeChangeHandler())) } R.id.nav_drawer_settings -> router.pushController(RouterTransaction.with(SettingsMainController()) @@ -109,6 +110,7 @@ class MainActivity : BaseActivity() { SHORTCUT_CATALOGUES -> setSelectedDrawerItem(R.id.nav_drawer_catalogues) SHORTCUT_MANGA -> router.setRoot( RouterTransaction.with(MangaController(intent.extras))) + SHORTCUT_DOWNLOADS -> setSelectedDrawerItem(R.id.nav_drawer_downloads) else -> setSelectedDrawerItem(startScreenId) } } @@ -225,6 +227,7 @@ class MainActivity : BaseActivity() { private const val SHORTCUT_RECENTLY_UPDATED = "eu.kanade.tachiyomi.SHOW_RECENTLY_UPDATED" private const val SHORTCUT_RECENTLY_READ = "eu.kanade.tachiyomi.SHOW_RECENTLY_READ" private const val SHORTCUT_CATALOGUES = "eu.kanade.tachiyomi.SHOW_CATALOGUES" + const val SHORTCUT_DOWNLOADS = "eu.kanade.tachiyomi.SHOW_DOWNLOADS" const val SHORTCUT_MANGA = "eu.kanade.tachiyomi.SHOW_MANGA" } diff --git a/app/src/main/res/layout/activity_download_manager.xml b/app/src/main/res/layout/activity_download_manager.xml index c99c4f698..d33cf811d 100644 --- a/app/src/main/res/layout/activity_download_manager.xml +++ b/app/src/main/res/layout/activity_download_manager.xml @@ -1,42 +1,22 @@ - + android:id="@+id/frame_container" + android:layout_width="match_parent" + android:layout_height="match_parent"> - + android:layout_height="wrap_content" + android:id="@+id/recycler" + tools:listitem="@layout/item_download"/> - + - - - - - - - - - - - - - \ No newline at end of file +