Implement click events for chapter download icons

This commit is contained in:
arkon 2020-12-31 18:14:51 -05:00
parent bf32bf28da
commit 63398fe491
14 changed files with 180 additions and 88 deletions

View file

@ -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() {

View file

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

View file

@ -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

View file

@ -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()
}
}

View file

@ -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()

View file

@ -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
}
)
}
}
}
}

View file

@ -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()
}
}

View file

@ -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)
}
}

View file

@ -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)

View file

@ -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

View file

@ -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) {

View file

@ -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()
}
}

View file

@ -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"

View file

@ -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>