From 0d658d4b05a19822bd6037868e5f8910330d9c7c Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 28 Mar 2020 15:07:21 -0400 Subject: [PATCH] Refactoring ChapterItem to make the download button more reusable --- .../kanade/tachiyomi/ui/main/MainActivity.kt | 6 +-- .../tachiyomi/ui/manga/MangaDetailsAdapter.kt | 16 +----- .../ui/manga/chapter/BaseChapterAdapter.kt | 16 ++++++ .../ui/manga/chapter/BaseChapterHolder.kt | 52 +++++++++++++++++++ .../ui/manga/chapter/BaseChapterItem.kt | 40 ++++++++++++++ .../ui/manga/chapter/ChapterHolder.kt | 41 +-------------- .../tachiyomi/ui/manga/chapter/ChapterItem.kt | 36 +------------ .../ui/recents/RecentMangaAdapter.kt | 7 ++- .../tachiyomi/ui/recents/RecentMangaHolder.kt | 45 ++-------------- .../tachiyomi/ui/recents/RecentMangaItem.kt | 35 ++----------- .../tachiyomi/ui/recents/RecentsController.kt | 2 +- 11 files changed, 128 insertions(+), 168 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterAdapter.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterHolder.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterItem.kt 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 179a1e9fd6..dee56fc63b 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 @@ -61,6 +61,9 @@ import eu.kanade.tachiyomi.util.system.launchUI import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets import eu.kanade.tachiyomi.util.view.updateLayoutParams import eu.kanade.tachiyomi.util.view.updatePadding +import java.util.Date +import java.util.concurrent.TimeUnit +import kotlin.math.abs import kotlinx.android.synthetic.main.main_activity.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -68,9 +71,6 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import timber.log.Timber import uy.kohesive.injekt.injectLazy -import java.util.Date -import java.util.concurrent.TimeUnit -import kotlin.math.abs open class MainActivity : BaseActivity(), DownloadServiceListener { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsAdapter.kt index 3e73e437a4..5aa8717dfc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsAdapter.kt @@ -2,14 +2,12 @@ package eu.kanade.tachiyomi.ui.manga import android.content.Context import android.view.View -import androidx.fragment.app.FragmentActivity import androidx.recyclerview.widget.ItemTouchHelper -import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterAdapter import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem -import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate import eu.kanade.tachiyomi.util.system.getResourceColor import java.text.DecimalFormat import java.text.DecimalFormatSymbols @@ -18,7 +16,7 @@ import uy.kohesive.injekt.injectLazy class MangaDetailsAdapter( val controller: MangaDetailsController, context: Context -) : FlexibleAdapter>(null, controller, true) { +) : BaseChapterAdapter>(controller) { val preferences: PreferencesHelper by injectLazy() @@ -44,11 +42,6 @@ class MangaDetailsAdapter( return items.indexOf(item) } - fun unlock() { - val activity = controller.activity as? FragmentActivity ?: return - SecureActivityDelegate.promptLockIfNeeded(activity) - } - fun performFilter() { val s = getFilter(String::class.java) if (s.isNullOrBlank()) { @@ -84,9 +77,4 @@ class MangaDetailsAdapter( fun zoomImageFromThumb(thumbView: View) fun showTrackingSheet() } - - interface DownloadInterface { - fun downloadChapter(position: Int) - fun startDownloadNow(position: Int) - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterAdapter.kt new file mode 100644 index 0000000000..7de4583a37 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterAdapter.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.ui.manga.chapter + +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.IFlexible + +open class BaseChapterAdapter>( + obj: DownloadInterface +) : FlexibleAdapter(null, obj, true) { + + val baseDelegate = obj + + interface DownloadInterface { + fun downloadChapter(position: Int) + fun startDownloadNow(position: Int) + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterHolder.kt new file mode 100644 index 0000000000..2fbba92d88 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterHolder.kt @@ -0,0 +1,52 @@ +package eu.kanade.tachiyomi.ui.manga.chapter + +import android.view.View +import androidx.appcompat.widget.PopupMenu +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.download.model.Download +import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder +import kotlinx.android.synthetic.main.download_button.* + +open class BaseChapterHolder( + view: View, + private val adapter: BaseChapterAdapter<*> +) : BaseFlexibleViewHolder(view, adapter) { + + init { + download_button.setOnClickListener { downloadOrRemoveMenu() } + } + + private fun downloadOrRemoveMenu() { + val chapter = adapter.getItem(adapterPosition) as? BaseChapterItem ?: return + if (chapter.status == Download.NOT_DOWNLOADED || chapter.status == Download.ERROR) { + adapter.baseDelegate.downloadChapter(adapterPosition) + } else { + download_button.post { + // Create a PopupMenu, giving it the clicked view for an anchor + val popup = PopupMenu(download_button.context, download_button) + + // Inflate our menu resource into the PopupMenu's Menu + popup.menuInflater.inflate(R.menu.chapter_download, popup.menu) + + popup.menu.findItem(R.id.action_start).isVisible = chapter.status == Download.QUEUE + + // Hide download and show delete if the chapter is downloaded + if (chapter.status != Download.DOWNLOADED) popup.menu.findItem(R.id.action_delete).title = download_button.context.getString( + R.string.action_cancel + ) + + // Set a listener so we are notified if a menu item is clicked + popup.setOnMenuItemClickListener { item -> + when (item.itemId) { + R.id.action_delete -> adapter.baseDelegate.downloadChapter(adapterPosition) + R.id.action_start -> adapter.baseDelegate.startDownloadNow(adapterPosition) + } + true + } + + // Finally show the PopupMenu + popup.show() + } + } + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterItem.kt new file mode 100644 index 0000000000..ffa4300cee --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/BaseChapterItem.kt @@ -0,0 +1,40 @@ +package eu.kanade.tachiyomi.ui.manga.chapter + +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import eu.kanade.tachiyomi.data.database.models.Chapter +import eu.kanade.tachiyomi.data.download.model.Download +import eu.kanade.tachiyomi.source.model.Page + +abstract class BaseChapterItem(val chapter: Chapter) : + AbstractFlexibleItem(), + Chapter by chapter { + + private var _status: Int = 0 + + val progress: Int + get() { + val pages = download?.pages ?: return 0 + return pages.map(Page::progress).average().toInt() + } + + var status: Int + get() = download?.status ?: _status + set(value) { _status = value } + + @Transient var download: Download? = null + + val isDownloaded: Boolean + get() = status == Download.DOWNLOADED + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other is BaseChapterItem<*>) { + return chapter.id!! == other.chapter.id!! + } + return false + } + + override fun hashCode(): Int { + return chapter.id!!.hashCode() + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt index 1d37793820..3a841f50ae 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt @@ -2,13 +2,11 @@ package eu.kanade.tachiyomi.ui.manga.chapter import android.text.format.DateUtils import android.view.View -import androidx.appcompat.widget.PopupMenu import androidx.core.content.ContextCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.source.LocalSource -import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder import eu.kanade.tachiyomi.ui.manga.MangaDetailsAdapter import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.visibleIf @@ -17,53 +15,18 @@ import kotlinx.android.synthetic.main.chapters_item.* import kotlinx.android.synthetic.main.download_button.* class ChapterHolder( - private val view: View, + view: View, private val adapter: MangaDetailsAdapter -) : BaseFlexibleViewHolder(view, adapter) { +) : BaseChapterHolder(view, adapter) { private var localSource = false init { - download_button.setOnClickListener { downloadOrRemoveMenu() } download_button.setOnLongClickListener { adapter.delegate.startDownloadRange(adapterPosition) true } } - private fun downloadOrRemoveMenu() { - val chapter = adapter.getItem(adapterPosition) as? ChapterItem ?: return - if (chapter.status == Download.NOT_DOWNLOADED || chapter.status == Download.ERROR) { - adapter.delegate.downloadChapter(adapterPosition) - } else { - download_button.post { - // Create a PopupMenu, giving it the clicked view for an anchor - val popup = PopupMenu(download_button.context, download_button) - - // Inflate our menu resource into the PopupMenu's Menu - popup.menuInflater.inflate(R.menu.chapter_download, popup.menu) - - popup.menu.findItem(R.id.action_start).isVisible = chapter.status == Download.QUEUE - - // Hide download and show delete if the chapter is downloaded - if (chapter.status != Download.DOWNLOADED) popup.menu.findItem(R.id.action_delete).title = download_button.context.getString( - R.string.action_cancel - ) - - // Set a listener so we are notified if a menu item is clicked - popup.setOnMenuItemClickListener { item -> - when (item.itemId) { - R.id.action_delete -> adapter.delegate.downloadChapter(adapterPosition) - R.id.action_start -> adapter.delegate.startDownloadNow(adapterPosition) - } - true - } - - // Finally show the PopupMenu - popup.show() - } - } - } - fun bind(item: ChapterItem, manga: Manga) { val chapter = item.chapter val isLocked = item.isLocked diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt index d12426e151..9d0c77f409 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt @@ -3,37 +3,17 @@ package eu.kanade.tachiyomi.ui.manga.chapter import android.view.View import androidx.recyclerview.widget.RecyclerView import eu.davidea.flexibleadapter.FlexibleAdapter -import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R 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.source.model.Page import eu.kanade.tachiyomi.ui.manga.MangaDetailsAdapter -class ChapterItem(val chapter: Chapter, val manga: Manga) : - AbstractFlexibleItem(), - Chapter by chapter { +class ChapterItem(chapter: Chapter, val manga: Manga) : + BaseChapterItem(chapter) { - private var _status: Int = 0 - - val progress: Int - get() { - val pages = download?.pages ?: return 0 - return pages.map(Page::progress).average().toInt() - } var isLocked = false - var status: Int - get() = download?.status ?: _status - set(value) { _status = value } - - @Transient var download: Download? = null - - val isDownloaded: Boolean - get() = status == Download.DOWNLOADED - override fun getLayoutRes(): Int { return R.layout.chapters_item } @@ -58,16 +38,4 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) : ) { holder.bind(this, manga) } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other is ChapterItem) { - return chapter.id!! == other.chapter.id!! - } - return false - } - - override fun hashCode(): Int { - return chapter.id!!.hashCode() - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaAdapter.kt index 721c93ade1..4f97481751 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaAdapter.kt @@ -2,20 +2,19 @@ package eu.kanade.tachiyomi.ui.recents import android.widget.ImageView import androidx.recyclerview.widget.ItemTouchHelper -import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.ui.manga.MangaDetailsAdapter +import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterAdapter import java.text.DecimalFormat import java.text.DecimalFormatSymbols class RecentMangaAdapter(val delegate: RecentsInterface) : - FlexibleAdapter>(null, delegate, true) { + BaseChapterAdapter>(delegate) { val decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols() .apply { decimalSeparator = '.' }) - interface RecentsInterface : RecentMangaInterface, MangaDetailsAdapter.DownloadInterface + interface RecentsInterface : RecentMangaInterface, DownloadInterface interface RecentMangaInterface { fun onCoverClick(position: Int) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt index 3154cef56c..02266f6546 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaHolder.kt @@ -2,11 +2,10 @@ package eu.kanade.tachiyomi.ui.recents import android.text.format.DateUtils import android.view.View -import androidx.appcompat.widget.PopupMenu import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.source.LocalSource -import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder +import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterHolder import eu.kanade.tachiyomi.util.view.visibleIf import java.util.Date import kotlinx.android.synthetic.main.download_button.* @@ -15,45 +14,10 @@ import kotlinx.android.synthetic.main.recent_manga_item.* class RecentMangaHolder( view: View, val adapter: RecentMangaAdapter -) : BaseFlexibleViewHolder(view, adapter) { +) : BaseChapterHolder(view, adapter) { init { cover_thumbnail.setOnClickListener { adapter.delegate.onCoverClick(adapterPosition) } - download_button.setOnClickListener { downloadOrRemoveMenu() } - } - - private fun downloadOrRemoveMenu() { - val chapter = adapter.getItem(adapterPosition) as? RecentMangaItem ?: return - if (chapter.status == Download.NOT_DOWNLOADED || chapter.status == Download.ERROR) { - adapter.delegate.downloadChapter(adapterPosition) - } else { - download_button.post { - // Create a PopupMenu, giving it the clicked view for an anchor - val popup = PopupMenu(download_button.context, download_button) - - // Inflate our menu resource into the PopupMenu's Menu - popup.menuInflater.inflate(R.menu.chapter_download, popup.menu) - - popup.menu.findItem(R.id.action_start).isVisible = chapter.status == Download.QUEUE - - // Hide download and show delete if the chapter is downloaded - if (chapter.status != Download.DOWNLOADED) popup.menu.findItem(R.id.action_delete).title = download_button.context.getString( - R.string.action_cancel - ) - - // Set a listener so we are notified if a menu item is clicked - popup.setOnMenuItemClickListener { item -> - when (item.itemId) { - R.id.action_delete -> adapter.delegate.downloadChapter(adapterPosition) - R.id.action_start -> adapter.delegate.startDownloadNow(adapterPosition) - } - true - } - - // Finally show the PopupMenu - popup.show() - } - } } fun bind(item: RecentMangaItem) { @@ -102,9 +66,8 @@ class RecentMangaHolder( ) } - fun notifyStatus(status: Int, progress: Int) = with(download_button) { - setDownloadStatus(status, progress) - } + fun notifyStatus(status: Int, progress: Int) = + download_button.setDownloadStatus(status, progress) override fun getFrontView(): View { return front_view diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaItem.kt index a98085bd01..cfde9766d8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentMangaItem.kt @@ -3,31 +3,14 @@ package eu.kanade.tachiyomi.ui.recents import android.view.View import androidx.recyclerview.widget.RecyclerView import eu.davidea.flexibleadapter.FlexibleAdapter -import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory -import eu.kanade.tachiyomi.data.download.model.Download -import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterItem -class RecentMangaItem(val mch: MangaChapterHistory, val chapter: Chapter) : - AbstractFlexibleItem - () { - - private var _status: Int = 0 - - val progress: Int - get() { - val pages = download?.pages ?: return 0 - return pages.map(Page::progress).average().toInt() - } - - var status: Int - get() = download?.status ?: _status - set(value) { _status = value } - - @Transient var download: Download? = null +class RecentMangaItem(val mch: MangaChapterHistory, chapter: Chapter) : + BaseChapterItem(chapter) { override fun getLayoutRes(): Int { return R.layout.recent_manga_item @@ -46,18 +29,6 @@ class RecentMangaItem(val mch: MangaChapterHistory, val chapter: Chapter) : position: Int, payloads: MutableList? ) { - holder.bind(this) } - - override fun equals(other: Any?): Boolean { - if (other is RecentMangaItem) { - return chapter.id == other.chapter.id - } - return false - } - - override fun hashCode(): Int { - return chapter.id!!.hashCode() - } } 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 9ea98efca9..d1f56f362d 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 @@ -134,7 +134,7 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle), } } - fun refreshItem(chapterId: Long) { + private fun refreshItem(chapterId: Long) { for (i in 0 until adapter.itemCount) { val holder = recycler.findViewHolderForAdapterPosition(i) as? RecentsHolder ?: continue holder.refreshChapter(chapterId)