浏览代码

Implement click events for chapter download icons

arkon 4 年之前
父节点
当前提交
63398fe491

+ 19 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt

@@ -34,6 +34,7 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
 import eu.kanade.tachiyomi.data.database.models.Category
 import eu.kanade.tachiyomi.data.database.models.Chapter
 import eu.kanade.tachiyomi.data.database.models.Manga
+import eu.kanade.tachiyomi.data.download.DownloadService
 import eu.kanade.tachiyomi.data.download.model.Download
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.databinding.MangaControllerBinding
@@ -59,6 +60,7 @@ import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersSettingsSheet
 import eu.kanade.tachiyomi.ui.manga.chapter.DeleteChaptersDialog
 import eu.kanade.tachiyomi.ui.manga.chapter.DownloadCustomChaptersDialog
 import eu.kanade.tachiyomi.ui.manga.chapter.MangaChaptersHeaderAdapter
+import eu.kanade.tachiyomi.ui.manga.chapter.base.BaseChaptersAdapter
 import eu.kanade.tachiyomi.ui.manga.info.MangaInfoHeaderAdapter
 import eu.kanade.tachiyomi.ui.manga.track.TrackController
 import eu.kanade.tachiyomi.ui.reader.ReaderActivity
@@ -90,6 +92,7 @@ class MangaController :
     ActionMode.Callback,
     FlexibleAdapter.OnItemClickListener,
     FlexibleAdapter.OnItemLongClickListener,
+    BaseChaptersAdapter.OnChapterClickListener,
     ChangeMangaCoverDialog.Listener,
     ChangeMangaCategoriesDialog.Listener,
     DownloadCustomChaptersDialog.Listener,
@@ -866,6 +869,22 @@ class MangaController :
         super.onDetach(view)
     }
 
+    override fun downloadChapter(position: Int) {
+        val item = chaptersAdapter?.getItem(position) ?: return
+        if (item.status == Download.State.ERROR) {
+            DownloadService.start(activity!!)
+        } else {
+            downloadChapters(listOf(item))
+        }
+        chaptersAdapter?.updateItem(item)
+    }
+
+    override fun deleteChapter(position: Int) {
+        val item = chaptersAdapter?.getItem(position) ?: return
+        deleteChapters(listOf(item))
+        chaptersAdapter?.updateItem(item)
+    }
+
     // SELECTION MODE ACTIONS
 
     private fun selectAll() {

+ 0 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDownloadView.kt

@@ -56,6 +56,4 @@ class ChapterDownloadView @JvmOverloads constructor(context: Context, attrs: Att
 
         binding.errorIcon.isVisible = state == Download.State.ERROR
     }
-
-    // TODO: onClick actions
 }

+ 6 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt

@@ -5,20 +5,24 @@ import android.text.SpannableStringBuilder
 import android.text.style.ForegroundColorSpan
 import android.view.View
 import androidx.core.view.isVisible
-import eu.davidea.viewholders.FlexibleViewHolder
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.databinding.ChaptersItemBinding
 import eu.kanade.tachiyomi.source.LocalSource
+import eu.kanade.tachiyomi.ui.manga.chapter.base.BaseChapterHolder
 import java.util.Date
 
 class ChapterHolder(
     view: View,
     private val adapter: ChaptersAdapter
-) : FlexibleViewHolder(view, adapter) {
+) : BaseChapterHolder(view, adapter) {
 
     private val binding = ChaptersItemBinding.bind(view)
 
+    init {
+        binding.download.setOnClickListener { onDownloadClick(it) }
+    }
+
     fun bind(item: ChapterItem, manga: Manga) {
         val chapter = item.chapter
 

+ 5 - 38
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt

@@ -3,37 +3,16 @@ 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.AbstractHeaderItem
 import eu.davidea.flexibleadapter.items.IFlexible
+import eu.davidea.viewholders.FlexibleViewHolder
 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.chapter.base.BaseChapterItem
 
-class ChapterItem(val chapter: Chapter, val manga: Manga) :
-    AbstractFlexibleItem<ChapterHolder>(),
-    Chapter by chapter {
-
-    private var _status: Download.State = Download.State.NOT_DOWNLOADED
-
-    var status: Download.State
-        get() = download?.status ?: _status
-        set(value) {
-            _status = value
-        }
-
-    val progress: Int
-        get() {
-            val pages = download?.pages ?: return 0
-            return pages.map(Page::progress).average().toInt()
-        }
-
-    @Transient
-    var download: Download? = null
-
-    val isDownloaded: Boolean
-        get() = status == Download.State.DOWNLOADED
+class ChapterItem(chapter: Chapter, val manga: Manga) :
+    BaseChapterItem<ChapterHolder, AbstractHeaderItem<FlexibleViewHolder>>(chapter) {
 
     override fun getLayoutRes(): Int {
         return R.layout.chapters_item
@@ -51,16 +30,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()
-    }
 }

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.kt

@@ -1,10 +1,10 @@
 package eu.kanade.tachiyomi.ui.manga.chapter
 
 import android.content.Context
-import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.ui.manga.MangaController
+import eu.kanade.tachiyomi.ui.manga.chapter.base.BaseChaptersAdapter
 import eu.kanade.tachiyomi.util.system.getResourceColor
 import uy.kohesive.injekt.injectLazy
 import java.text.DateFormat
@@ -14,7 +14,7 @@ import java.text.DecimalFormatSymbols
 class ChaptersAdapter(
     controller: MangaController,
     context: Context
-) : FlexibleAdapter<ChapterItem>(null, controller, true) {
+) : BaseChaptersAdapter<ChapterItem>(controller) {
 
     private val preferences: PreferencesHelper by injectLazy()
 

+ 38 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/base/BaseChapterHolder.kt

@@ -0,0 +1,38 @@
+package eu.kanade.tachiyomi.ui.manga.chapter.base
+
+import android.view.View
+import eu.davidea.viewholders.FlexibleViewHolder
+import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.data.download.model.Download
+import eu.kanade.tachiyomi.util.view.popupMenu
+
+open class BaseChapterHolder(
+    view: View,
+    private val adapter: BaseChaptersAdapter<*>
+) : FlexibleViewHolder(view, adapter) {
+
+    fun onDownloadClick(view: View) {
+        val item = adapter.getItem(bindingAdapterPosition) as? BaseChapterItem<*, *> ?: return
+        when (item.status) {
+            Download.State.NOT_DOWNLOADED, Download.State.ERROR -> {
+                adapter.clickListener.downloadChapter(bindingAdapterPosition)
+            }
+            else -> {
+                view.popupMenu(
+                    R.menu.chapter_download,
+                    initMenu = {
+                        // Download.State.DOWNLOADED
+                        findItem(R.id.delete_download).isVisible = item.status == Download.State.DOWNLOADED
+
+                        // Download.State.DOWNLOADING, Download.State.QUEUE
+                        findItem(R.id.cancel_download).isVisible = item.status != Download.State.DOWNLOADED
+                    },
+                    onMenuItemClick = {
+                        adapter.clickListener.deleteChapter(bindingAdapterPosition)
+                        true
+                    }
+                )
+            }
+        }
+    }
+}

+ 47 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/base/BaseChapterItem.kt

@@ -0,0 +1,47 @@
+package eu.kanade.tachiyomi.ui.manga.chapter.base
+
+import eu.davidea.flexibleadapter.items.AbstractHeaderItem
+import eu.davidea.flexibleadapter.items.AbstractSectionableItem
+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<T : BaseChapterHolder, H : AbstractHeaderItem<*>>(
+    val chapter: Chapter,
+    header: H? = null
+) :
+    AbstractSectionableItem<T, H?>(header),
+    Chapter by chapter {
+
+    private var _status: Download.State = Download.State.NOT_DOWNLOADED
+
+    var status: Download.State
+        get() = download?.status ?: _status
+        set(value) {
+            _status = value
+        }
+
+    val progress: Int
+        get() {
+            val pages = download?.pages ?: return 0
+            return pages.map(Page::progress).average().toInt()
+        }
+
+    @Transient
+    var download: Download? = null
+
+    val isDownloaded: Boolean
+        get() = status == Download.State.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()
+    }
+}

+ 22 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/base/BaseChaptersAdapter.kt

@@ -0,0 +1,22 @@
+package eu.kanade.tachiyomi.ui.manga.chapter.base
+
+import eu.davidea.flexibleadapter.FlexibleAdapter
+import eu.davidea.flexibleadapter.items.IFlexible
+
+abstract class BaseChaptersAdapter<T : IFlexible<*>>(
+    controller: OnChapterClickListener
+) : FlexibleAdapter<T>(null, controller, true) {
+
+    /**
+     * Listener for browse item clicks.
+     */
+    val clickListener: OnChapterClickListener = controller
+
+    /**
+     * Listener which should be called when user clicks the download icons.
+     */
+    interface OnChapterClickListener {
+        fun downloadChapter(position: Int)
+        fun deleteChapter(position: Int)
+    }
+}

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesAdapter.kt

@@ -1,15 +1,15 @@
 package eu.kanade.tachiyomi.ui.recent.updates
 
 import android.content.Context
-import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.davidea.flexibleadapter.items.IFlexible
 import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.ui.manga.chapter.base.BaseChaptersAdapter
 import eu.kanade.tachiyomi.util.system.getResourceColor
 
 class UpdatesAdapter(
     val controller: UpdatesController,
     context: Context
-) : FlexibleAdapter<IFlexible<*>>(null, controller, true) {
+) : BaseChaptersAdapter<IFlexible<*>>(controller) {
 
     var readColor = context.getResourceColor(R.attr.colorOnSurface, 0.38f)
     var unreadColor = context.getResourceColor(R.attr.colorOnSurface)

+ 19 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt

@@ -13,6 +13,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.davidea.flexibleadapter.SelectableAdapter
 import eu.davidea.flexibleadapter.items.IFlexible
 import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.data.download.DownloadService
 import eu.kanade.tachiyomi.data.download.model.Download
 import eu.kanade.tachiyomi.data.library.LibraryUpdateService
 import eu.kanade.tachiyomi.data.notification.Notifications
@@ -23,6 +24,7 @@ import eu.kanade.tachiyomi.ui.base.controller.RootController
 import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
 import eu.kanade.tachiyomi.ui.main.MainActivity
 import eu.kanade.tachiyomi.ui.manga.MangaController
+import eu.kanade.tachiyomi.ui.manga.chapter.base.BaseChaptersAdapter
 import eu.kanade.tachiyomi.ui.reader.ReaderActivity
 import eu.kanade.tachiyomi.util.system.notificationManager
 import eu.kanade.tachiyomi.util.system.toast
@@ -45,6 +47,7 @@ class UpdatesController :
     FlexibleAdapter.OnItemClickListener,
     FlexibleAdapter.OnItemLongClickListener,
     FlexibleAdapter.OnUpdateListener,
+    BaseChaptersAdapter.OnChapterClickListener,
     ConfirmDeleteChaptersDialog.Listener,
     UpdatesAdapter.OnCoverClickListener {
 
@@ -291,6 +294,22 @@ class UpdatesController :
         Timber.e(error)
     }
 
+    override fun downloadChapter(position: Int) {
+        val item = adapter?.getItem(position) as? UpdatesItem ?: return
+        if (item.status == Download.State.ERROR) {
+            DownloadService.start(activity!!)
+        } else {
+            downloadChapters(listOf(item))
+        }
+        adapter?.updateItem(item)
+    }
+
+    override fun deleteChapter(position: Int) {
+        val item = adapter?.getItem(position) as? UpdatesItem ?: return
+        deleteChapters(listOf(item))
+        adapter?.updateItem(item)
+    }
+
     /**
      * Called when ActionMode created.
      * @param mode the ActionMode object

+ 4 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesHolder.kt

@@ -6,12 +6,12 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
 import com.bumptech.glide.load.resource.bitmap.CenterCrop
 import com.bumptech.glide.load.resource.bitmap.RoundedCorners
 import com.bumptech.glide.request.RequestOptions
-import eu.davidea.viewholders.FlexibleViewHolder
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.glide.GlideApp
 import eu.kanade.tachiyomi.data.glide.toMangaThumbnail
 import eu.kanade.tachiyomi.databinding.UpdatesItemBinding
 import eu.kanade.tachiyomi.source.LocalSource
+import eu.kanade.tachiyomi.ui.manga.chapter.base.BaseChapterHolder
 
 /**
  * Holder that contains chapter item
@@ -23,7 +23,7 @@ import eu.kanade.tachiyomi.source.LocalSource
  * @constructor creates a new recent chapter holder.
  */
 class UpdatesHolder(private val view: View, private val adapter: UpdatesAdapter) :
-    FlexibleViewHolder(view, adapter) {
+    BaseChapterHolder(view, adapter) {
 
     private val binding = UpdatesItemBinding.bind(view)
 
@@ -31,6 +31,8 @@ class UpdatesHolder(private val view: View, private val adapter: UpdatesAdapter)
         binding.mangaCover.setOnClickListener {
             adapter.coverClickListener.onCoverClick(bindingAdapterPosition)
         }
+
+        binding.download.setOnClickListener { onDownloadClick(it) }
     }
 
     fun bind(item: UpdatesItem) {

+ 3 - 37
app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesItem.kt

@@ -3,37 +3,15 @@ package eu.kanade.tachiyomi.ui.recent.updates
 import android.view.View
 import androidx.recyclerview.widget.RecyclerView
 import eu.davidea.flexibleadapter.FlexibleAdapter
-import eu.davidea.flexibleadapter.items.AbstractSectionableItem
 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.chapter.base.BaseChapterItem
 import eu.kanade.tachiyomi.ui.recent.DateSectionItem
 
-class UpdatesItem(val chapter: Chapter, val manga: Manga, header: DateSectionItem) :
-    AbstractSectionableItem<UpdatesHolder, DateSectionItem>(header) {
-
-    private var _status: Download.State = Download.State.NOT_DOWNLOADED
-
-    var status: Download.State
-        get() = download?.status ?: _status
-        set(value) {
-            _status = value
-        }
-
-    val progress: Int
-        get() {
-            val pages = download?.pages ?: return 0
-            return pages.map(Page::progress).average().toInt()
-        }
-
-    @Transient
-    var download: Download? = null
-
-    val isDownloaded: Boolean
-        get() = status == Download.State.DOWNLOADED
+class UpdatesItem(chapter: Chapter, val manga: Manga, header: DateSectionItem) :
+    BaseChapterItem<UpdatesHolder, DateSectionItem>(chapter, header) {
 
     override fun getLayoutRes(): Int {
         return R.layout.updates_item
@@ -51,16 +29,4 @@ class UpdatesItem(val chapter: Chapter, val manga: Manga, header: DateSectionIte
     ) {
         holder.bind(this)
     }
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other is UpdatesItem) {
-            return chapter.id!! == other.chapter.id!!
-        }
-        return false
-    }
-
-    override fun hashCode(): Int {
-        return chapter.id!!.hashCode()
-    }
 }

+ 1 - 3
app/src/main/res/layout/chapter_download_view.xml

@@ -4,9 +4,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="28dp"
     android:layout_height="28dp"
-    android:background="?selectableItemBackgroundBorderless"
-    android:clickable="true"
-    android:focusable="true">
+    android:background="?selectableItemBackgroundBorderless">
 
     <ImageView
         android:id="@+id/download_icon_border"

+ 12 - 0
app/src/main/res/menu/chapter_download.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/delete_download"
+        android:title="@string/action_delete" />
+
+    <item
+        android:id="@+id/cancel_download"
+        android:title="@string/action_cancel" />
+
+</menu>