From 112cdd54e3b946fddb0d2389c7770cf90bad67ec Mon Sep 17 00:00:00 2001 From: len Date: Sat, 11 Mar 2017 21:20:46 +0100 Subject: [PATCH] Update chapters adapter --- .../{ChaptersHolder.kt => ChapterHolder.kt} | 244 +++++++++--------- .../tachiyomi/ui/manga/chapter/ChapterItem.kt | 50 ++++ .../ui/manga/chapter/ChapterModel.kt | 19 -- .../ui/manga/chapter/ChaptersAdapter.kt | 43 +-- .../ui/manga/chapter/ChaptersFragment.kt | 84 +++--- .../ui/manga/chapter/ChaptersPresenter.kt | 34 +-- .../res/layout/fragment_manga_chapters.xml | 14 +- 7 files changed, 252 insertions(+), 236 deletions(-) rename app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/{ChaptersHolder.kt => ChapterHolder.kt} (75%) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterModel.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt similarity index 75% rename from app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.kt rename to app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt index a5f7e09c4..1b42ea2cf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterHolder.kt @@ -1,128 +1,116 @@ -package eu.kanade.tachiyomi.ui.manga.chapter - -import android.view.View -import android.widget.PopupMenu -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.ui.base.adapter.FlexibleViewHolder -import eu.kanade.tachiyomi.util.getResourceColor -import kotlinx.android.synthetic.main.item_chapter.view.* -import java.text.DateFormat -import java.text.DecimalFormat -import java.text.DecimalFormatSymbols -import java.util.* - -class ChaptersHolder( - private val view: View, - private val adapter: ChaptersAdapter, - listener: FlexibleViewHolder.OnListItemClickListener) -: FlexibleViewHolder(view, adapter, listener) { - - private val readColor = view.context.getResourceColor(android.R.attr.textColorHint) - private val unreadColor = view.context.getResourceColor(android.R.attr.textColorPrimary) - private val bookmarkedColor = view.context.getResourceColor(R.attr.colorAccent) - private val decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols().apply { decimalSeparator = '.' }) - private val df = DateFormat.getDateInstance(DateFormat.SHORT) - - private var item: ChapterModel? = null - - init { - // We need to post a Runnable to show the popup to make sure that the PopupMenu is - // correctly positioned. The reason being that the view may change position before the - // PopupMenu is shown. - view.chapter_menu.setOnClickListener { it.post { showPopupMenu(it) } } - } - - fun onSetValues(chapter: ChapterModel, manga: Manga?) = with(view) { - item = chapter - - chapter_title.text = when (manga?.displayMode) { - Manga.DISPLAY_NUMBER -> { - val formattedNumber = decimalFormat.format(chapter.chapter_number.toDouble()) - context.getString(R.string.display_mode_chapter, formattedNumber) - } - else -> chapter.name - } - - // Set correct text color - chapter_title.setTextColor(if (chapter.read) readColor else unreadColor) - if (chapter.bookmark) chapter_title.setTextColor(bookmarkedColor) - - if (chapter.date_upload > 0) { - chapter_date.text = df.format(Date(chapter.date_upload)) - chapter_date.setTextColor(if (chapter.read) readColor else unreadColor) - } else { - chapter_date.text = "" - } - - chapter_pages.text = if (!chapter.read && chapter.last_page_read > 0) { - context.getString(R.string.chapter_progress, chapter.last_page_read + 1) - } else { - "" - } - - notifyStatus(chapter.status) - } - - fun notifyStatus(status: Int) = with(view.download_text) { - when (status) { - Download.QUEUE -> setText(R.string.chapter_queued) - Download.DOWNLOADING -> setText(R.string.chapter_downloading) - Download.DOWNLOADED -> setText(R.string.chapter_downloaded) - Download.ERROR -> setText(R.string.chapter_error) - else -> text = "" - } - } - - private fun showPopupMenu(view: View) = item?.let { chapter -> - // Create a PopupMenu, giving it the clicked view for an anchor - val popup = PopupMenu(view.context, view) - - // Inflate our menu resource into the PopupMenu's Menu - popup.menuInflater.inflate(R.menu.chapter_single, popup.menu) - - // Hide download and show delete if the chapter is downloaded - if (chapter.isDownloaded) { - popup.menu.findItem(R.id.action_download).isVisible = false - popup.menu.findItem(R.id.action_delete).isVisible = true - } - - // Hide bookmark if bookmark - popup.menu.findItem(R.id.action_bookmark).isVisible = !chapter.bookmark - popup.menu.findItem(R.id.action_remove_bookmark).isVisible = chapter.bookmark - - // Hide mark as unread when the chapter is unread - if (!chapter.read && chapter.last_page_read == 0) { - popup.menu.findItem(R.id.action_mark_as_unread).isVisible = false - } - - // Hide mark as read when the chapter is read - if (chapter.read) { - popup.menu.findItem(R.id.action_mark_as_read).isVisible = false - } - - // Set a listener so we are notified if a menu item is clicked - popup.setOnMenuItemClickListener { menuItem -> - val chapterList = listOf(chapter) - - with(adapter.fragment) { - when (menuItem.itemId) { - R.id.action_download -> downloadChapters(chapterList) - R.id.action_bookmark -> bookmarkChapters(chapterList, true) - R.id.action_remove_bookmark -> bookmarkChapters(chapterList, false) - R.id.action_delete -> deleteChapters(chapterList) - R.id.action_mark_as_read -> markAsRead(chapterList) - R.id.action_mark_as_unread -> markAsUnread(chapterList) - R.id.action_mark_previous_as_read -> markPreviousAsRead(chapter) - } - } - - true - } - - // Finally show the PopupMenu - popup.show() - } - -} +package eu.kanade.tachiyomi.ui.manga.chapter + +import android.view.View +import android.widget.PopupMenu +import eu.davidea.viewholders.FlexibleViewHolder +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.util.getResourceColor +import kotlinx.android.synthetic.main.item_chapter.view.* +import java.text.DateFormat +import java.text.DecimalFormat +import java.text.DecimalFormatSymbols +import java.util.* + +class ChapterHolder( + private val view: View, + private val adapter: ChaptersAdapter) +: FlexibleViewHolder(view, adapter) { + + private val readColor = view.context.getResourceColor(android.R.attr.textColorHint) + private val unreadColor = view.context.getResourceColor(android.R.attr.textColorPrimary) + private val bookmarkedColor = view.context.getResourceColor(R.attr.colorAccent) + private val decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols().apply { decimalSeparator = '.' }) + private val df = DateFormat.getDateInstance(DateFormat.SHORT) + + init { + // We need to post a Runnable to show the popup to make sure that the PopupMenu is + // correctly positioned. The reason being that the view may change position before the + // PopupMenu is shown. + view.chapter_menu.setOnClickListener { it.post { showPopupMenu(it) } } + } + + fun bind(item: ChapterItem, manga: Manga) = with(view) { + val chapter = item.chapter + + chapter_title.text = when (manga.displayMode) { + Manga.DISPLAY_NUMBER -> { + val formattedNumber = decimalFormat.format(chapter.chapter_number.toDouble()) + context.getString(R.string.display_mode_chapter, formattedNumber) + } + else -> chapter.name + } + + // Set correct text color + chapter_title.setTextColor(if (chapter.read) readColor else unreadColor) + if (chapter.bookmark) chapter_title.setTextColor(bookmarkedColor) + + if (chapter.date_upload > 0) { + chapter_date.text = df.format(Date(chapter.date_upload)) + chapter_date.setTextColor(if (chapter.read) readColor else unreadColor) + } else { + chapter_date.text = "" + } + + chapter_pages.text = if (!chapter.read && chapter.last_page_read > 0) { + context.getString(R.string.chapter_progress, chapter.last_page_read + 1) + } else { + "" + } + + notifyStatus(item.status) + } + + fun notifyStatus(status: Int) = with(view.download_text) { + when (status) { + Download.QUEUE -> setText(R.string.chapter_queued) + Download.DOWNLOADING -> setText(R.string.chapter_downloading) + Download.DOWNLOADED -> setText(R.string.chapter_downloaded) + Download.ERROR -> setText(R.string.chapter_error) + else -> text = "" + } + } + + private fun showPopupMenu(view: View) { + val item = adapter.getItem(adapterPosition) ?: return + + // Create a PopupMenu, giving it the clicked view for an anchor + val popup = PopupMenu(view.context, view) + + // Inflate our menu resource into the PopupMenu's Menu + popup.menuInflater.inflate(R.menu.chapter_single, popup.menu) + + val chapter = item.chapter + + // Hide download and show delete if the chapter is downloaded + if (item.isDownloaded) { + popup.menu.findItem(R.id.action_download).isVisible = false + popup.menu.findItem(R.id.action_delete).isVisible = true + } + + // Hide bookmark if bookmark + popup.menu.findItem(R.id.action_bookmark).isVisible = !chapter.bookmark + popup.menu.findItem(R.id.action_remove_bookmark).isVisible = chapter.bookmark + + // Hide mark as unread when the chapter is unread + if (!chapter.read && chapter.last_page_read == 0) { + popup.menu.findItem(R.id.action_mark_as_unread).isVisible = false + } + + // Hide mark as read when the chapter is read + if (chapter.read) { + popup.menu.findItem(R.id.action_mark_as_read).isVisible = false + } + + // Set a listener so we are notified if a menu item is clicked + popup.setOnMenuItemClickListener { menuItem -> + adapter.menuItemListener(adapterPosition, menuItem) + true + } + + // Finally show the PopupMenu + popup.show() + } + +} 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 new file mode 100644 index 000000000..70f4a5dc1 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt @@ -0,0 +1,50 @@ +package eu.kanade.tachiyomi.ui.manga.chapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +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 + +class ChapterItem(val chapter: Chapter, val manga: Manga) : AbstractFlexibleItem(), + Chapter by chapter { + + private var _status: Int = 0 + + 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.item_chapter + } + + override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): ChapterHolder { + return ChapterHolder(inflater.inflate(layoutRes, parent, false), adapter as ChaptersAdapter) + } + + override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: ChapterHolder, position: Int, payloads: List?) { + 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() + } + +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterModel.kt deleted file mode 100644 index 7f878c7b3..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package eu.kanade.tachiyomi.ui.manga.chapter - -import eu.kanade.tachiyomi.data.database.models.Chapter -import eu.kanade.tachiyomi.data.download.model.Download - -class ChapterModel(c: Chapter) : Chapter by c { - - private var _status: Int = 0 - - var status: Int - get() = download?.status ?: _status - set(value) { _status = value } - - @Transient var download: Download? = null - - val isDownloaded: Boolean - get() = status == Download.DOWNLOADED - -} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.kt index 55b1f3f9c..7f9cc21f1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.kt @@ -1,42 +1,19 @@ package eu.kanade.tachiyomi.ui.manga.chapter -import android.view.ViewGroup -import eu.davidea.flexibleadapter4.FlexibleAdapter -import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.util.inflate +import android.view.MenuItem +import eu.davidea.flexibleadapter.FlexibleAdapter -class ChaptersAdapter(val fragment: ChaptersFragment) : FlexibleAdapter() { +class ChaptersAdapter(val fragment: ChaptersFragment) : FlexibleAdapter(null, fragment, true) { - init { - setHasStableIds(true) + var items: List = emptyList() + + val menuItemListener: (Int, MenuItem) -> Unit = { position, item -> + fragment.onItemMenuClick(position, item) } - var items: List - get() = mItems - set(value) { - mItems = value - notifyDataSetChanged() - } - - override fun updateDataSet(param: String) { - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChaptersHolder { - val v = parent.inflate(R.layout.item_chapter) - return ChaptersHolder(v, this, fragment) - } - - override fun onBindViewHolder(holder: ChaptersHolder, position: Int) { - val chapter = getItem(position) - val manga = fragment.presenter.manga - holder.onSetValues(chapter, manga) - - //When user scrolls this bind the correct selection status - holder.itemView.isActivated = isSelected(position) - } - - override fun getItemId(position: Int): Long { - return mItems[position].id!! + override fun updateDataSet(items: List) { + this.items = items + super.updateDataSet(items.toList()) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt index 359706dee..2627e165c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt @@ -12,12 +12,11 @@ import android.support.v7.widget.DividerItemDecoration import android.support.v7.widget.LinearLayoutManager import android.view.* import com.afollestad.materialdialogs.MaterialDialog -import eu.davidea.flexibleadapter4.FlexibleAdapter +import eu.davidea.flexibleadapter.FlexibleAdapter 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.ui.base.adapter.FlexibleViewHolder import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment import eu.kanade.tachiyomi.ui.manga.MangaActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity @@ -30,7 +29,10 @@ import nucleus.factory.RequiresPresenter import timber.log.Timber @RequiresPresenter(ChaptersPresenter::class) -class ChaptersFragment : BaseRxFragment(), ActionMode.Callback, FlexibleViewHolder.OnListItemClickListener { +class ChaptersFragment : BaseRxFragment(), + ActionMode.Callback, + FlexibleAdapter.OnItemClickListener, + FlexibleAdapter.OnItemLongClickListener { companion object { /** @@ -71,38 +73,31 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac recycler.layoutManager = LinearLayoutManager(activity) recycler.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL)) recycler.setHasFixedSize(true) +// TODO enable in a future commit +// adapter.setFastScroller(fast_scroller, context.getResourceColor(R.attr.colorAccent)) +// adapter.toggleFastScroller() swipe_refresh.setOnRefreshListener { fetchChapters() } fab.setOnClickListener { - val chapter = presenter.getNextUnreadChapter() - if (chapter != null) { + val item = presenter.getNextUnreadChapter() + if (item != null) { // Create animation listener val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) { - openChapter(chapter, true) + openChapter(item.chapter, true) } } // Get coordinates and start animation val coordinates = fab.getCoordinates() if (!reveal_view.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) { - openChapter(chapter) + openChapter(item.chapter) } } else { context.toast(R.string.no_next_chapter) } } - - } - - override fun onPause() { - // Stop recycler's scrolling when onPause is called. If the activity is finishing - // the presenter will be destroyed, and it could cause NPE - // https://github.com/inorichi/tachiyomi/issues/159 - recycler.stopScroll() - - super.onPause() } override fun onResume() { @@ -173,19 +168,20 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac return true } + @Suppress("UNUSED_PARAMETER") fun onNextManga(manga: Manga) { // Set initial values activity.supportInvalidateOptionsMenu() } - fun onNextChapters(chapters: List) { + fun onNextChapters(chapters: List) { // If the list is empty, fetch chapters from source if the conditions are met // We use presenter chapters instead because they are always unfiltered if (presenter.chapters.isEmpty()) initialFetchChapters() destroyActionModeIfNeeded() - adapter.items = chapters + adapter.updateDataSet(chapters) } private fun initialFetchChapters() { @@ -230,7 +226,7 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac .title(R.string.action_display_mode) .items(modes.map { getString(it) }) .itemsIds(ids) - .itemsCallbackSingleChoice(selectedIndex) { dialog, itemView, which, text -> + .itemsCallbackSingleChoice(selectedIndex) { _, itemView, _, _ -> // Save the new display mode presenter.setDisplayMode(itemView.id) // Refresh ui @@ -250,7 +246,7 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac .title(R.string.sorting_mode) .items(modes.map { getString(it) }) .itemsIds(ids) - .itemsCallbackSingleChoice(selectedIndex) { dialog, itemView, which, text -> + .itemsCallbackSingleChoice(selectedIndex) { _, itemView, _, _ -> // Save the new sorting mode presenter.setSorting(itemView.id) true @@ -267,7 +263,7 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac .title(R.string.manga_download) .negativeText(android.R.string.cancel) .items(modes.map { getString(it) }) - .itemsCallback { dialog, view, i, charSequence -> + .itemsCallback { _, _, i, _ -> fun getUnreadChaptersSorted() = presenter.chapters .filter { !it.read && it.status == Download.NOT_DOWNLOADED } @@ -299,8 +295,8 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac getHolder(download.chapter)?.notifyStatus(download.status) } - private fun getHolder(chapter: Chapter): ChaptersHolder? { - return recycler.findViewHolderForItemId(chapter.id!!) as? ChaptersHolder + private fun getHolder(chapter: Chapter): ChapterHolder? { + return recycler.findViewHolderForItemId(chapter.id!!) as? ChapterHolder } override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { @@ -324,7 +320,7 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac .content(R.string.confirm_delete_chapters) .positiveText(android.R.string.yes) .negativeText(android.R.string.no) - .onPositive { dialog, action -> deleteChapters(getSelectedChapters()) } + .onPositive { _, _ -> deleteChapters(getSelectedChapters()) } .show() } else -> return false @@ -338,8 +334,8 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac actionMode = null } - fun getSelectedChapters(): List { - return adapter.selectedItems.map { adapter.getItem(it) } + fun getSelectedChapters(): List { + return adapter.selectedPositions.map { adapter.getItem(it) } } fun destroyActionModeIfNeeded() { @@ -351,18 +347,18 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac setContextTitle(adapter.selectedItemCount) } - fun markAsRead(chapters: List) { + fun markAsRead(chapters: List) { presenter.markChaptersRead(chapters, true) if (presenter.preferences.removeAfterMarkedAsRead()) { deleteChapters(chapters) } } - fun markAsUnread(chapters: List) { + fun markAsUnread(chapters: List) { presenter.markChaptersRead(chapters, false) } - fun markPreviousAsRead(chapter: ChapterModel) { + fun markPreviousAsRead(chapter: ChapterItem) { val chapters = if (presenter.sortDescending()) adapter.items.reversed() else adapter.items val chapterPos = chapters.indexOf(chapter) if (chapterPos != -1) { @@ -370,7 +366,7 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac } } - fun downloadChapters(chapters: List) { + fun downloadChapters(chapters: List) { destroyActionModeIfNeeded() presenter.downloadChapters(chapters) if (!presenter.manga.favorite){ @@ -382,12 +378,12 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac } } - fun bookmarkChapters(chapters: List, bookmarked: Boolean) { + fun bookmarkChapters(chapters: List, bookmarked: Boolean) { destroyActionModeIfNeeded() presenter.bookmarkChapters(chapters, bookmarked) } - fun deleteChapters(chapters: List) { + fun deleteChapters(chapters: List) { destroyActionModeIfNeeded() DeletingChaptersDialog().show(childFragmentManager, DeletingChaptersDialog.TAG) presenter.deleteChapters(chapters) @@ -408,26 +404,40 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac ?.dismissAllowingStateLoss() } - override fun onListItemClick(position: Int): Boolean { + override fun onItemClick(position: Int): Boolean { val item = adapter.getItem(position) ?: return false if (actionMode != null && adapter.mode == FlexibleAdapter.MODE_MULTI) { toggleSelection(position) return true } else { - openChapter(item) + openChapter(item.chapter) return false } } - override fun onListItemLongClick(position: Int) { + override fun onItemLongClick(position: Int) { if (actionMode == null) actionMode = (activity as AppCompatActivity).startSupportActionMode(this) toggleSelection(position) } + fun onItemMenuClick(position: Int, item: MenuItem) { + val chapter = adapter.getItem(position)?.let { listOf(it) } ?: return + + when (item.itemId) { + R.id.action_download -> downloadChapters(chapter) + R.id.action_bookmark -> bookmarkChapters(chapter, true) + R.id.action_remove_bookmark -> bookmarkChapters(chapter, false) + R.id.action_delete -> deleteChapters(chapter) + R.id.action_mark_as_read -> markAsRead(chapter) + R.id.action_mark_as_unread -> markAsUnread(chapter) + R.id.action_mark_previous_as_read -> markPreviousAsRead(chapter[0]) + } + } + private fun toggleSelection(position: Int) { - adapter.toggleSelection(position, false) + adapter.toggleSelection(position) val count = adapter.selectedItemCount if (count == 0) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt index 79c328fe9..be294a97e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt @@ -65,14 +65,14 @@ class ChaptersPresenter : BasePresenter() { /** * List of chapters of the manga. It's always unfiltered and unsorted. */ - var chapters: List = emptyList() + var chapters: List = emptyList() private set /** * Subject of list of chapters to allow updating the view without going to DB. */ - val chaptersRelay: PublishRelay> - by lazy { PublishRelay.create>() } + val chaptersRelay: PublishRelay> + by lazy { PublishRelay.create>() } /** * Whether the chapter list has been requested to the source. @@ -103,7 +103,7 @@ class ChaptersPresenter : BasePresenter() { chaptersRelay.flatMap { applyChapterFilters(it) } .observeOn(AndroidSchedulers.mainThread()) .subscribeLatestCache(ChaptersFragment::onNextChapters, - { view, error -> Timber.e(error) }) + { _, error -> Timber.e(error) }) // Add the subscription that retrieves the chapters from the database, keeps subscribed to // changes, and sends the list of chapters to the relay. @@ -135,15 +135,15 @@ class ChaptersPresenter : BasePresenter() { .filter { download -> download.manga.id == manga.id } .doOnNext { onDownloadStatusChange(it) } .subscribeLatestCache(ChaptersFragment::onChapterStatusChange, - { view, error -> Timber.e(error) }) + { _, error -> Timber.e(error) }) } /** * Converts a chapter from the database to an extended model, allowing to store new fields. */ - private fun Chapter.toModel(): ChapterModel { + private fun Chapter.toModel(): ChapterItem { // Create the model object. - val model = ChapterModel(this) + val model = ChapterItem(this, manga) // Find an active download for this chapter. val download = downloadManager.queue.find { it.chapter.id == id } @@ -160,7 +160,7 @@ class ChaptersPresenter : BasePresenter() { * * @param chapters the list of chapter from the database. */ - private fun setDownloadedChapters(chapters: List) { + private fun setDownloadedChapters(chapters: List) { val files = downloadManager.findMangaDir(source, manga)?.listFiles() ?: return val cached = mutableMapOf() files.mapNotNull { it.name } @@ -181,7 +181,7 @@ class ChaptersPresenter : BasePresenter() { .subscribeOn(Schedulers.io()) .map { syncChaptersWithSource(db, it, manga, source) } .observeOn(AndroidSchedulers.mainThread()) - .subscribeFirst({ view, chapters -> + .subscribeFirst({ view, _ -> view.onFetchChaptersDone() }, ChaptersFragment::onFetchChaptersError) } @@ -198,7 +198,7 @@ class ChaptersPresenter : BasePresenter() { * @param chapters the list of chapters from the database * @return an observable of the list of chapters filtered and sorted. */ - private fun applyChapterFilters(chapters: List): Observable> { + private fun applyChapterFilters(chapters: List): Observable> { var observable = Observable.from(chapters).subscribeOn(Schedulers.io()) if (onlyUnread()) { observable = observable.filter { !it.read } @@ -248,7 +248,7 @@ class ChaptersPresenter : BasePresenter() { /** * Returns the next unread chapter or null if everything is read. */ - fun getNextUnreadChapter(): ChapterModel? { + fun getNextUnreadChapter(): ChapterItem? { return chapters.sortedByDescending { it.source_order }.find { !it.read } } @@ -257,7 +257,7 @@ class ChaptersPresenter : BasePresenter() { * @param selectedChapters the list of selected chapters. * @param read whether to mark chapters as read or unread. */ - fun markChaptersRead(selectedChapters: List, read: Boolean) { + fun markChaptersRead(selectedChapters: List, read: Boolean) { Observable.from(selectedChapters) .doOnNext { chapter -> chapter.read = read @@ -275,7 +275,7 @@ class ChaptersPresenter : BasePresenter() { * Downloads the given list of chapters with the manager. * @param chapters the list of chapters to download. */ - fun downloadChapters(chapters: List) { + fun downloadChapters(chapters: List) { DownloadService.start(context) downloadManager.downloadChapters(manga, chapters) } @@ -284,7 +284,7 @@ class ChaptersPresenter : BasePresenter() { * Bookmarks the given list of chapters. * @param selectedChapters the list of chapters to bookmark. */ - fun bookmarkChapters(selectedChapters: List, bookmarked: Boolean) { + fun bookmarkChapters(selectedChapters: List, bookmarked: Boolean) { Observable.from(selectedChapters) .doOnNext { chapter -> chapter.bookmark = bookmarked @@ -299,14 +299,14 @@ class ChaptersPresenter : BasePresenter() { * Deletes the given list of chapter. * @param chapters the list of chapters to delete. */ - fun deleteChapters(chapters: List) { + fun deleteChapters(chapters: List) { Observable.from(chapters) .doOnNext { deleteChapter(it) } .toList() .doOnNext { if (onlyDownloaded()) refreshChapters() } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribeFirst({ view, result -> + .subscribeFirst({ view, _ -> view.onChaptersDeleted() }, ChaptersFragment::onChaptersDeletedError) } @@ -315,7 +315,7 @@ class ChaptersPresenter : BasePresenter() { * Deletes a chapter from disk. This method is called in a background thread. * @param chapter the chapter to delete. */ - private fun deleteChapter(chapter: ChapterModel) { + private fun deleteChapter(chapter: ChapterItem) { downloadManager.queue.remove(chapter) downloadManager.deleteChapter(source, manga, chapter) chapter.status = Download.NOT_DOWNLOADED diff --git a/app/src/main/res/layout/fragment_manga_chapters.xml b/app/src/main/res/layout/fragment_manga_chapters.xml index d3a25fdff..11412d180 100644 --- a/app/src/main/res/layout/fragment_manga_chapters.xml +++ b/app/src/main/res/layout/fragment_manga_chapters.xml @@ -13,8 +13,7 @@ android:layout_height="match_parent" android:background="?attr/colorAccent" android:elevation="5dp" - android:visibility="invisible" - /> + android:visibility="invisible"/> + +