From aa6013b7caeadfdc3183743046294f86516b724e Mon Sep 17 00:00:00 2001 From: Jobobby04 Date: Fri, 7 May 2021 14:27:07 -0400 Subject: [PATCH] Convert the Chapter sheet into a dialog --- app/build.gradle.kts | 4 +- .../kanade/tachiyomi/source/model/Filter.kt | 9 +- .../tachiyomi/ui/reader/ReaderActivity.kt | 21 +-- .../tachiyomi/ui/reader/ReaderPresenter.kt | 5 - .../ui/reader/chapter/ReaderChapterAdapter.kt | 21 +++ .../ui/reader/chapter/ReaderChapterDialog.kt | 78 ++++++++++ .../ui/reader/chapter/ReaderChapterItem.kt | 94 +++++++----- .../ui/reader/chapter/ReaderChapterSheet.kt | 142 ------------------ .../main/res/layout/reader_chapter_item.xml | 2 +- .../main/res/layout/reader_chapters_sheet.xml | 49 +----- 10 files changed, 168 insertions(+), 257 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterAdapter.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterDialog.kt delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterSheet.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2a6b8c3fe..2b1812186 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -306,12 +306,10 @@ dependencies { testImplementation("com.ms-square:debugoverlay-no-op:$debugOverlayVersion") // RatingBar (SY) - implementation ("me.zhanghai.android.materialratingbar:library:1.4.0") + implementation("me.zhanghai.android.materialratingbar:library:1.4.0") // JsonReader for similar manga implementation("com.squareup.moshi:moshi:1.12.0") - - implementation("com.mikepenz:fastadapter:5.4.1") // SY <-- } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt b/app/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt index e91e4ebb5..75e704a9b 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt @@ -26,7 +26,14 @@ sealed class Filter(val name: String, var state: T) { } // SY --> - abstract class AutoComplete(name: String, val hint: String, val values: List, val skipAutoFillTags: List = emptyList(), val excludePrefix: String? = null, state: List) : Filter>(name, state) + abstract class AutoComplete( + name: String, + val hint: String, + val values: List, + val skipAutoFillTags: List = emptyList(), + val excludePrefix: String? = null, + state: List + ) : Filter>(name, state) // SY <-- override fun equals(other: Any?): Boolean { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 3835c454b..0a4f50764 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -48,7 +48,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Error import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Success -import eu.kanade.tachiyomi.ui.reader.chapter.ReaderChapterSheet +import eu.kanade.tachiyomi.ui.reader.chapter.ReaderChapterDialog import eu.kanade.tachiyomi.ui.reader.loader.HttpPageLoader import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter import eu.kanade.tachiyomi.ui.reader.model.ReaderPage @@ -144,8 +144,6 @@ class ReaderActivity : BaseRxActivity() private val autoScrollFlow = MutableSharedFlow() private var autoScrollJob: Job? = null private val sourceManager: SourceManager by injectLazy() - - private lateinit var chapterBottomSheet: ReaderChapterSheet // SY <-- /** @@ -245,9 +243,6 @@ class ReaderActivity : BaseRxActivity() super.onDestroy() viewer?.destroy() viewer = null - // SY --> - chapterBottomSheet.adapter = null - // SY <-- config = null menuToggleToast?.cancel() readingModeToast?.cancel() @@ -545,7 +540,7 @@ class ReaderActivity : BaseRxActivity() setTooltip(R.string.chapters) setOnClickListener { - chapterBottomSheet.show() + ReaderChapterDialog(this@ReaderActivity) } } @@ -706,8 +701,6 @@ class ReaderActivity : BaseRxActivity() } .launchIn(lifecycleScope) - chapterBottomSheet = ReaderChapterSheet(this) - updateBottomButtons() // <-- EH @@ -880,10 +873,6 @@ class ReaderActivity : BaseRxActivity() ) startActivity(intent) } - - fun refreshSheetChapters() { - chapterBottomSheet.refreshList() - } // SY <-- /** @@ -1067,12 +1056,6 @@ class ReaderActivity : BaseRxActivity() val newChapter = presenter.onPageSelected(page) val pages = page.chapter.pages ?: return - // SY --> - if (chapterBottomSheet.selectedChapterId != page.chapter.chapter.id) { - chapterBottomSheet.refreshList() - } - // SY <-- - // Set bottom page number binding.pageNumber.text = "${page.number}/${pages.size}" // binding.pageText.text = "${page.number}/${pages.size}" diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index 2b9b394bf..edc15e5cc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -477,11 +477,6 @@ class ReaderPresenter( Timber.d("Setting ${selectedChapter.chapter.url} as active") onChapterChanged(currentChapters.currChapter) loadNewChapter(selectedChapter) - // SY --> - Observable.just(selectedChapter).subscribeFirst({ view, _ -> - view.refreshSheetChapters() - }) - // SY <-- } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterAdapter.kt new file mode 100644 index 000000000..8bd081026 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterAdapter.kt @@ -0,0 +1,21 @@ +package eu.kanade.tachiyomi.ui.reader.chapter + +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.kanade.tachiyomi.data.database.models.Chapter + +class ReaderChapterAdapter( + dialog: OnBookmarkClickListener +) : FlexibleAdapter(null, dialog, true) { + + /** + * Listener for browse item clicks. + */ + val clickListener: OnBookmarkClickListener = dialog + + /** + * Listener which should be called when user clicks the download icons. + */ + interface OnBookmarkClickListener { + fun bookmarkChapter(chapter: Chapter) + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterDialog.kt new file mode 100644 index 000000000..c4776198f --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterDialog.kt @@ -0,0 +1,78 @@ +package eu.kanade.tachiyomi.ui.reader.chapter + +import androidx.recyclerview.widget.LinearLayoutManager +import com.afollestad.materialdialogs.MaterialDialog +import com.afollestad.materialdialogs.callbacks.onDismiss +import com.afollestad.materialdialogs.customview.customView +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.databinding.ReaderChaptersSheetBinding +import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import eu.kanade.tachiyomi.ui.reader.ReaderPresenter +import eu.kanade.tachiyomi.util.lang.launchUI +import eu.kanade.tachiyomi.util.system.dpToPx + +class ReaderChapterDialog(private val activity: ReaderActivity) : ReaderChapterAdapter.OnBookmarkClickListener { + private val binding = ReaderChaptersSheetBinding.inflate(activity.layoutInflater, null, false) + + var presenter: ReaderPresenter = activity.presenter + var adapter: FlexibleAdapter? = null + var dialog: MaterialDialog + + init { + dialog = MaterialDialog(activity) + .title(R.string.chapters) + .customView(view = binding.root) + .show { + adapter = ReaderChapterAdapter(this@ReaderChapterDialog) + binding.chapterRecycler.adapter = adapter + + adapter?.mItemClickListener = FlexibleAdapter.OnItemClickListener { _, position -> + val item = adapter?.getItem(position) + if (item != null && item.id != presenter.getCurrentChapter()?.chapter?.id) { + dismiss() + presenter.loadNewChapterFromSheet(item) + } + true + } + + binding.chapterRecycler.layoutManager = LinearLayoutManager(context) + onDismiss { + destroy() + } + refreshList() + } + } + + private fun refreshList() { + launchUI { + val chapters = with(presenter.getChapters(activity)) { + when (activity.presenter.manga?.sorting) { + Manga.CHAPTER_SORTING_SOURCE -> sortedBy { it.source_order } + Manga.CHAPTER_SORTING_NUMBER -> sortedByDescending { it.chapter_number } + Manga.CHAPTER_SORTING_UPLOAD_DATE -> sortedBy { it.date_upload } + else -> sortedBy { it.source_order } + } + } + + adapter?.clear() + adapter?.updateDataSet(chapters) + + (binding.chapterRecycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset( + adapter?.getGlobalPositionOf(chapters.find { it.isCurrent }) ?: 0, + (binding.chapterRecycler.height / 2).dpToPx + ) + } + } + + fun destroy() { + adapter = null + } + + override fun bookmarkChapter(chapter: Chapter) { + presenter.toggleBookmark(chapter) + refreshList() + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterItem.kt index 725ea530d..15f384acd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterItem.kt @@ -4,50 +4,68 @@ import android.content.Context import android.graphics.Typeface import android.text.SpannableStringBuilder import android.view.View -import android.widget.FrameLayout -import android.widget.ImageView -import android.widget.TextView -import com.mikepenz.fastadapter.FastAdapter -import com.mikepenz.fastadapter.items.AbstractItem +import androidx.recyclerview.widget.RecyclerView +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +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.databinding.ReaderChapterItemBinding import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.view.setVectorCompat import java.text.DateFormat import java.text.DecimalFormat import java.util.Date -class ReaderChapterItem(val chapter: Chapter, val manga: Manga, val isCurrent: Boolean, context: Context, val dateFormat: DateFormat, val decimalFormat: DecimalFormat) : - AbstractItem(), +class ReaderChapterItem(chapter: Chapter, val manga: Manga, val isCurrent: Boolean, context: Context, val dateFormat: DateFormat, val decimalFormat: DecimalFormat) : + AbstractFlexibleItem(), Chapter by chapter { val readColor = context.getResourceColor(R.attr.colorOnSurface, 0.38f) val unreadColor = context.getResourceColor(R.attr.colorOnSurface) val bookmarkedColor = context.getResourceColor(R.attr.colorAccent) - /** defines the type defining this item. must be unique. preferably an id */ - override val type: Int = R.id.reader_chapter_layout - - /** defines the layout which will be used for this item in the list */ - override val layoutRes: Int = R.layout.reader_chapter_item - - override var identifier: Long = chapter.id!! - - override fun getViewHolder(v: View): ViewHolder { - return ViewHolder(v) + override fun getLayoutRes(): Int { + return R.layout.reader_chapter_item } - class ViewHolder(view: View) : FastAdapter.ViewHolder(view) { - private var chapterTitle: TextView = view.findViewById(R.id.chapter_title) - private var chapterSubtitle: TextView = view.findViewById(R.id.chapter_scanlator) - var bookmarkButton: FrameLayout = view.findViewById(R.id.bookmark_layout) - private var bookmarkImage: ImageView = view.findViewById(R.id.bookmark_image) + override fun createViewHolder(view: View, adapter: FlexibleAdapter>): ViewHolder { + return ViewHolder(view, adapter as ReaderChapterAdapter) + } - override fun bindView(item: ReaderChapterItem, payloads: List) { + override fun bindViewHolder( + adapter: FlexibleAdapter>, + holder: ViewHolder, + position: Int, + payloads: List? + ) { + holder.bind(this) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ReaderChapterItem + + if (id != other.id) return false + + return true + } + + override fun hashCode(): Int { + return id.hashCode() + } + + inner class ViewHolder(view: View, private val adapter: ReaderChapterAdapter) : FlexibleViewHolder(view, adapter) { + val binding = ReaderChapterItemBinding.bind(itemView) + + fun bind(item: ReaderChapterItem) { val manga = item.manga - chapterTitle.text = when (manga.displayMode) { + binding.chapterTitle.text = when (manga.displayMode) { Manga.CHAPTER_DISPLAY_NUMBER -> { val number = item.decimalFormat.format(item.chapter_number.toDouble()) itemView.context.getString(R.string.display_mode_chapter, number) @@ -61,8 +79,8 @@ class ReaderChapterItem(val chapter: Chapter, val manga: Manga, val isCurrent: B item.bookmark -> item.bookmarkedColor else -> item.unreadColor } - chapterTitle.setTextColor(chapterColor) - chapterSubtitle.setTextColor(chapterColor) + binding.chapterTitle.setTextColor(chapterColor) + binding.chapterScanlator.setTextColor(chapterColor) // bookmarkImage.isVisible = item.bookmark @@ -76,29 +94,27 @@ class ReaderChapterItem(val chapter: Chapter, val manga: Manga, val isCurrent: B } if (descriptions.isNotEmpty()) { - chapterSubtitle.text = descriptions.joinTo(SpannableStringBuilder(), " • ") + binding.chapterScanlator.text = descriptions.joinTo(SpannableStringBuilder(), " • ") } else { - chapterSubtitle.text = "" + binding.chapterScanlator.text = "" } if (item.bookmark) { - bookmarkImage.setVectorCompat(R.drawable.ic_bookmark_24dp, R.attr.colorAccent) + binding.bookmarkImage.setVectorCompat(R.drawable.ic_bookmark_24dp, R.attr.colorAccent) } else { - bookmarkImage.setVectorCompat(R.drawable.ic_bookmark_border_24dp, R.attr.colorOnSurface) + binding.bookmarkImage.setVectorCompat(R.drawable.ic_bookmark_border_24dp, R.attr.colorOnSurface) } if (item.isCurrent) { - chapterTitle.setTypeface(null, Typeface.BOLD_ITALIC) - chapterSubtitle.setTypeface(null, Typeface.BOLD_ITALIC) + binding.chapterTitle.setTypeface(null, Typeface.BOLD_ITALIC) + binding.chapterScanlator.setTypeface(null, Typeface.BOLD_ITALIC) } else { - chapterTitle.setTypeface(null, Typeface.NORMAL) - chapterSubtitle.setTypeface(null, Typeface.NORMAL) + binding.chapterTitle.setTypeface(null, Typeface.NORMAL) + binding.chapterScanlator.setTypeface(null, Typeface.NORMAL) + } + binding.bookmarkLayout.setOnClickListener { + adapter.clickListener.bookmarkChapter(item) } - } - - override fun unbindView(item: ReaderChapterItem) { - chapterTitle.text = null - chapterSubtitle.text = null } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterSheet.kt deleted file mode 100644 index 490c00fd8..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterSheet.kt +++ /dev/null @@ -1,142 +0,0 @@ -package eu.kanade.tachiyomi.ui.reader.chapter - -import android.annotation.SuppressLint -import android.view.View -import android.view.ViewGroup -import android.widget.SeekBar -import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.mikepenz.fastadapter.FastAdapter -import com.mikepenz.fastadapter.adapters.ItemAdapter -import com.mikepenz.fastadapter.listeners.ClickEventHook -import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.databinding.ReaderChaptersSheetBinding -import eu.kanade.tachiyomi.ui.reader.ReaderActivity -import eu.kanade.tachiyomi.ui.reader.ReaderPresenter -import eu.kanade.tachiyomi.util.lang.launchUI -import eu.kanade.tachiyomi.util.system.dpToPx -import eu.kanade.tachiyomi.widget.SimpleSeekBarListener -import eu.kanade.tachiyomi.widget.sheet.BaseBottomSheetDialog -import exh.util.isExpanded -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import reactivecircus.flowbinding.android.view.clicks - -/** - * Color filter sheet to toggle custom filter and brightness overlay. - */ -class ReaderChapterSheet(private val activity: ReaderActivity) : BaseBottomSheetDialog(activity) { - private var sheetBehavior: BottomSheetBehavior<*>? = null - - private val binding = ReaderChaptersSheetBinding.inflate(activity.layoutInflater, null, false) - private var initialized = false - - var presenter: ReaderPresenter - var adapter: FastAdapter? = null - private val itemAdapter = ItemAdapter() - var shouldCollapse = true - var selectedChapterId = -1L - - init { - setContentView(binding.root) - - sheetBehavior = BottomSheetBehavior.from(binding.root.parent as ViewGroup) - - presenter = activity.presenter - adapter = FastAdapter.with(itemAdapter) - binding.chapterRecycler.adapter = adapter - adapter?.onClickListener = { _, _, item, _ -> - if (!sheetBehavior.isExpanded()) { - false - } else { - if (item.chapter.id != presenter.getCurrentChapter()?.chapter?.id) { - shouldCollapse = false - presenter.loadNewChapterFromSheet(item.chapter) - } - true - } - } - adapter?.addEventHook( - object : ClickEventHook() { - override fun onBind(viewHolder: RecyclerView.ViewHolder): View? { - return if (viewHolder is ReaderChapterItem.ViewHolder) { - viewHolder.bookmarkButton - } else { - null - } - } - - override fun onClick( - v: View, - position: Int, - fastAdapter: FastAdapter, - item: ReaderChapterItem - ) { - presenter.toggleBookmark(item.chapter) - refreshList() - } - } - ) - - binding.chapterRecycler.layoutManager = LinearLayoutManager(context) - // refreshList() - binding.webviewButton.clicks() - .onEach { activity.openMangaInBrowser() } - .launchIn(activity.lifecycleScope) - - binding.pageSeekbar.setOnSeekBarChangeListener( - object : SimpleSeekBarListener() { - - @SuppressLint("SetTextI18n") - override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { - if (activity.viewer != null && fromUser) { - binding.pageText.text = "${value + 1}/${binding.pageSeekbar.max + 1}" - binding.pageSeekbar.progress = value - activity.moveToPageIndex(value) - } - } - } - ) - } - - override fun onStart() { - super.onStart() - sheetBehavior?.skipCollapsed = true - sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED - } - - override fun show() { - if (!initialized) { - refreshList() - initialized = true - } - binding.pageText.text = activity.binding.pageNumber.text - binding.pageSeekbar.max = activity.binding.pageSeekbar.max - binding.pageSeekbar.progress = activity.binding.pageSeekbar.progress - super.show() - } - - fun refreshList() { - launchUI { - val chapters = with(presenter.getChapters(context)) { - when (activity.presenter.manga?.sorting) { - Manga.CHAPTER_SORTING_SOURCE -> sortedBy { it.source_order } - Manga.CHAPTER_SORTING_NUMBER -> sortedByDescending { it.chapter_number } - Manga.CHAPTER_SORTING_UPLOAD_DATE -> sortedBy { it.date_upload } - else -> sortedBy { it.source_order } - } - } - - selectedChapterId = chapters.find { it.isCurrent }?.chapter?.id ?: -1L - itemAdapter.clear() - itemAdapter.add(chapters) - - (binding.chapterRecycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset( - adapter?.getPosition(presenter.getCurrentChapter()?.chapter?.id ?: 0L) ?: 0, - (binding.chapterRecycler.height / 2).dpToPx - ) - } - } -} diff --git a/app/src/main/res/layout/reader_chapter_item.xml b/app/src/main/res/layout/reader_chapter_item.xml index 0f80c24d8..5a66f2ef6 100644 --- a/app/src/main/res/layout/reader_chapter_item.xml +++ b/app/src/main/res/layout/reader_chapter_item.xml @@ -58,6 +58,6 @@ android:layout_height="30dp" android:layout_gravity="center" android:src="@drawable/ic_bookmark_border_24dp" - android:tint="?attr/colorOnSurface" /> + app:tint="?attr/colorOnSurface" /> \ No newline at end of file diff --git a/app/src/main/res/layout/reader_chapters_sheet.xml b/app/src/main/res/layout/reader_chapters_sheet.xml index 90537a7af..7ab5d25af 100644 --- a/app/src/main/res/layout/reader_chapters_sheet.xml +++ b/app/src/main/res/layout/reader_chapters_sheet.xml @@ -1,59 +1,14 @@ - - - - - - - - -