MangaController overhaul (#7244)

This commit is contained in:
Ivan Iskandar
2022-06-25 22:03:48 +07:00
committed by GitHub
parent cf7ca5bd28
commit 33a778873a
57 changed files with 3701 additions and 2955 deletions

View File

@@ -83,7 +83,7 @@ class SearchController(
binding.progress.isVisible = isReplacingManga
if (!isReplacingManga) {
router.popController(this)
if (newManga != null) {
if (newManga?.id != null) {
val newMangaController = RouterTransaction.with(MangaController(newManga.id!!))
if (router.backstack.lastOrNull()?.controller is MangaController) {
// Replace old MangaController

View File

@@ -1,40 +0,0 @@
package eu.kanade.tachiyomi.ui.library
import android.app.Dialog
import android.os.Bundle
import com.bluelinelabs.conductor.Controller
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.ui.base.controller.DialogController
class ChangeMangaCoverDialog<T>(bundle: Bundle? = null) :
DialogController(bundle) where T : Controller, T : ChangeMangaCoverDialog.Listener {
private lateinit var manga: Manga
constructor(target: T, manga: Manga) : this() {
targetController = target
this.manga = manga
}
@Suppress("DEPRECATION")
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(activity!!)
.setTitle(R.string.action_edit_cover)
.setPositiveButton(R.string.action_edit) { _, _ ->
(targetController as? Listener)?.openMangaCoverPicker(manga)
}
.setNegativeButton(android.R.string.cancel, null)
.setNeutralButton(R.string.action_delete) { _, _ ->
(targetController as? Listener)?.deleteMangaCover(manga)
}
.create()
}
interface Listener {
fun deleteMangaCover(manga: Manga)
fun openMangaCoverPicker(manga: Manga)
}
}

View File

@@ -420,7 +420,7 @@ class MainActivity : BaseActivity() {
SHORTCUT_MANGA -> {
val extras = intent.extras ?: return false
val fgController = router.backstack.lastOrNull()?.controller as? MangaController
if (fgController?.manga?.id != extras.getLong(MangaController.MANGA_EXTRA)) {
if (fgController?.mangaId != extras.getLong(MangaController.MANGA_EXTRA)) {
router.popToRoot()
setSelectedNavItem(R.id.nav_library)
router.pushController(RouterTransaction.with(MangaController(extras)))
@@ -601,6 +601,9 @@ class MainActivity : BaseActivity() {
}
val isFullComposeController = internalTo is FullComposeController<*>
binding.appbar.isVisible = !isFullComposeController
binding.controllerContainer.enableScrollingBehavior(!isFullComposeController)
if (!isTablet()) {
// Save lift state
if (isPush) {
@@ -623,17 +626,6 @@ class MainActivity : BaseActivity() {
}
binding.root.isLiftAppBarOnScroll = internalTo !is NoAppBarElevationController
binding.appbar.isVisible = !isFullComposeController
binding.controllerContainer.enableScrollingBehavior(!isFullComposeController)
// TODO: Remove when MangaController is full compose
if (!isFullComposeController) {
binding.appbar.isTransparentWhenNotLifted = internalTo is MangaController
binding.controllerContainer.overlapHeader = internalTo is MangaController
}
} else {
binding.appbar.isVisible = !isFullComposeController
}
}

View File

@@ -1,127 +0,0 @@
package eu.kanade.tachiyomi.ui.manga.chapter
import android.text.SpannableStringBuilder
import android.view.View
import androidx.core.text.buildSpannedString
import androidx.core.text.color
import androidx.core.view.isVisible
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.ChaptersItemBinding
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.ui.manga.chapter.base.BaseChapterHolder
import eu.kanade.tachiyomi.util.lang.toRelativeString
import java.util.Date
class ChapterHolder(
view: View,
private val adapter: ChaptersAdapter,
) : BaseChapterHolder(view, adapter) {
private val binding = ChaptersItemBinding.bind(view)
init {
binding.download.listener = downloadActionListener
}
fun bind(item: ChapterItem, manga: Manga) {
val chapter = item.chapter
binding.chapterTitle.text = when (manga.displayMode) {
Manga.CHAPTER_DISPLAY_NUMBER -> {
val number = adapter.decimalFormat.format(chapter.chapter_number.toDouble())
itemView.context.getString(R.string.display_mode_chapter, number)
}
else -> chapter.name
// TODO: show cleaned name consistently around the app
// else -> cleanChapterName(chapter, manga)
}
// Set correct text color
val chapterTitleColor = when {
chapter.read -> adapter.readColor
chapter.bookmark -> adapter.bookmarkedColor
else -> adapter.unreadColor
}
binding.chapterTitle.setTextColor(chapterTitleColor)
val chapterDescriptionColor = when {
chapter.read -> adapter.readColor
chapter.bookmark -> adapter.bookmarkedColor
else -> adapter.unreadColorSecondary
}
binding.chapterDescription.setTextColor(chapterDescriptionColor)
binding.bookmarkIcon.isVisible = chapter.bookmark
val descriptions = mutableListOf<CharSequence>()
if (chapter.date_upload > 0) {
descriptions.add(Date(chapter.date_upload).toRelativeString(itemView.context, adapter.relativeTime, adapter.dateFormat))
}
if (!chapter.read && chapter.last_page_read > 0) {
val lastPageRead = buildSpannedString {
color(adapter.readColor) {
append(itemView.context.getString(R.string.chapter_progress, chapter.last_page_read + 1))
}
}
descriptions.add(lastPageRead)
}
if (!chapter.scanlator.isNullOrBlank()) {
descriptions.add(chapter.scanlator!!)
}
if (descriptions.isNotEmpty()) {
binding.chapterDescription.text = descriptions.joinTo(SpannableStringBuilder(), "")
} else {
binding.chapterDescription.text = ""
}
binding.download.isVisible = item.manga.source != LocalSource.ID
binding.download.setState(item.status, item.progress)
}
private fun cleanChapterName(chapter: Chapter, manga: Manga): String {
return chapter.name
.trim()
.removePrefix(manga.title)
.trim(*CHAPTER_TRIM_CHARS)
}
}
private val CHAPTER_TRIM_CHARS = arrayOf(
// Whitespace
' ',
'\u0009',
'\u000A',
'\u000B',
'\u000C',
'\u000D',
'\u0020',
'\u0085',
'\u00A0',
'\u1680',
'\u2000',
'\u2001',
'\u2002',
'\u2003',
'\u2004',
'\u2005',
'\u2006',
'\u2007',
'\u2008',
'\u2009',
'\u200A',
'\u2028',
'\u2029',
'\u202F',
'\u205F',
'\u3000',
// Separators
'-',
'_',
',',
':',
).toCharArray()

View File

@@ -1,33 +0,0 @@
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.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.ui.manga.chapter.base.BaseChapterItem
class ChapterItem(chapter: Chapter, val manga: Manga) :
BaseChapterItem<ChapterHolder, AbstractHeaderItem<FlexibleViewHolder>>(chapter) {
override fun getLayoutRes(): Int {
return R.layout.chapters_item
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): ChapterHolder {
return ChapterHolder(view, adapter as ChaptersAdapter)
}
override fun bindViewHolder(
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
holder: ChapterHolder,
position: Int,
payloads: List<Any?>?,
) {
holder.bind(this, manga)
}
}

View File

@@ -1,46 +0,0 @@
package eu.kanade.tachiyomi.ui.manga.chapter
import android.content.Context
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
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
class ChaptersAdapter(
controller: MangaController,
context: Context,
) : BaseChaptersAdapter<ChapterItem>(controller) {
private val preferences: PreferencesHelper by injectLazy()
var items: List<ChapterItem> = emptyList()
val readColor = context.getResourceColor(R.attr.colorOnSurface, 0.38f)
val unreadColor = context.getResourceColor(R.attr.colorOnSurface)
val unreadColorSecondary = context.getResourceColor(android.R.attr.textColorSecondary)
val bookmarkedColor = context.getResourceColor(R.attr.colorAccent)
val decimalFormat = DecimalFormat(
"#.###",
DecimalFormatSymbols()
.apply { decimalSeparator = '.' },
)
val relativeTime: Int = preferences.relativeTime().get()
val dateFormat: DateFormat = preferences.dateFormat()
override fun updateDataSet(items: List<ChapterItem>?) {
this.items = items ?: emptyList()
super.updateDataSet(items)
}
fun indexOf(item: ChapterItem): Int {
return items.indexOf(item)
}
}

View File

@@ -7,10 +7,11 @@ import android.view.View
import androidx.core.view.isVisible
import com.bluelinelabs.conductor.Router
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.manga.model.toTriStateGroupState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.ui.manga.MangaPresenter
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
import eu.kanade.tachiyomi.util.view.popupMenu
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
@@ -18,6 +19,9 @@ import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.launch
class ChaptersSettingsSheet(
private val router: Router,
@@ -28,7 +32,7 @@ class ChaptersSettingsSheet(
private var manga: Manga? = null
val filters = Filter(context)
private val filters = Filter(context)
private val sort = Sort(context)
private val display = Display(context)
@@ -42,8 +46,14 @@ class ChaptersSettingsSheet(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
scope = MainScope()
// TODO: Listen to changes
updateManga()
scope.launch {
presenter.state
.filterIsInstance<MangaScreenState.Success>()
.collectLatest {
manga = it.manga
getTabViews().forEach { settings -> (settings as Settings).updateView() }
}
}
}
override fun onDetachedFromWindow() {
@@ -63,17 +73,13 @@ class ChaptersSettingsSheet(
R.string.action_display,
)
private fun updateManga() {
manga = presenter.manga.toDomainManga()
}
private fun showPopupMenu(view: View) {
view.popupMenu(
menuRes = R.menu.default_chapter_filter,
onMenuItemClick = {
when (itemId) {
R.id.set_as_default -> {
SetChapterSettingsDialog(presenter.manga).showDialog(router)
SetChapterSettingsDialog(presenter.manga!!.toDbManga()).showDialog(router)
}
}
},
@@ -144,10 +150,6 @@ class ChaptersSettingsSheet(
bookmarked -> presenter.setBookmarkedFilter(newState)
else -> {}
}
// TODO: Remove
updateManga()
updateView()
}
}
}
@@ -202,16 +204,11 @@ class ChaptersSettingsSheet(
override fun onItemClicked(item: Item) {
when (item) {
source -> presenter.setSorting(Manga.CHAPTER_SORTING_SOURCE.toInt())
chapterNum -> presenter.setSorting(Manga.CHAPTER_SORTING_NUMBER.toInt())
uploadDate -> presenter.setSorting(Manga.CHAPTER_SORTING_UPLOAD_DATE.toInt())
source -> presenter.setSorting(Manga.CHAPTER_SORTING_SOURCE)
chapterNum -> presenter.setSorting(Manga.CHAPTER_SORTING_NUMBER)
uploadDate -> presenter.setSorting(Manga.CHAPTER_SORTING_UPLOAD_DATE)
else -> throw Exception("Unknown sorting")
}
// TODO: Remove
presenter.reverseSortOrder()
updateManga()
updateView()
}
}
}
@@ -257,14 +254,10 @@ class ChaptersSettingsSheet(
if (item.checked) return
when (item) {
displayTitle -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NAME.toInt())
displayChapterNum -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NUMBER.toInt())
displayTitle -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NAME)
displayChapterNum -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NUMBER)
else -> throw NotImplementedError("Unknown display mode")
}
// TODO: Remove
updateManga()
updateView()
}
}
}

View File

@@ -1,30 +0,0 @@
package eu.kanade.tachiyomi.ui.manga.chapter
import android.app.Dialog
import android.os.Bundle
import com.bluelinelabs.conductor.Controller
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.base.controller.DialogController
class DeleteChaptersDialog<T>(bundle: Bundle? = null) : DialogController(bundle)
where T : Controller, T : DeleteChaptersDialog.Listener {
constructor(target: T) : this() {
targetController = target
}
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(activity!!)
.setMessage(R.string.confirm_delete_chapters)
.setPositiveButton(android.R.string.ok) { _, _ ->
(targetController as? Listener)?.deleteChapters()
}
.setNegativeButton(android.R.string.cancel, null)
.create()
}
interface Listener {
fun deleteChapters()
}
}

View File

@@ -1,69 +0,0 @@
package eu.kanade.tachiyomi.ui.manga.chapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.MangaChaptersHeaderBinding
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.system.getResourceColor
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.android.view.clicks
class MangaChaptersHeaderAdapter(
private val controller: MangaController,
) :
RecyclerView.Adapter<MangaChaptersHeaderAdapter.HeaderViewHolder>() {
private var numChapters: Int? = null
private var hasActiveFilters: Boolean = false
private lateinit var binding: MangaChaptersHeaderBinding
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HeaderViewHolder {
binding = MangaChaptersHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return HeaderViewHolder(binding.root)
}
override fun getItemCount(): Int = 1
override fun getItemId(position: Int): Long = hashCode().toLong()
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
holder.bind()
}
fun setNumChapters(numChapters: Int) {
this.numChapters = numChapters
notifyItemChanged(0, this)
}
fun setHasActiveFilters(hasActiveFilters: Boolean) {
this.hasActiveFilters = hasActiveFilters
notifyItemChanged(0, this)
}
inner class HeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
fun bind() {
binding.chaptersLabel.text = if (numChapters == null) {
view.context.getString(R.string.chapters)
} else {
view.context.resources.getQuantityString(R.plurals.manga_num_chapters, numChapters!!, numChapters)
}
val filterColor = if (hasActiveFilters) {
view.context.getResourceColor(R.attr.colorFilterActive)
} else {
view.context.getResourceColor(R.attr.colorOnBackground)
}
binding.btnChaptersFilter.drawable.setTint(filterColor)
merge(view.clicks(), binding.btnChaptersFilter.clicks())
.onEach { controller.showSettingsSheet() }
.launchIn(controller.viewScope)
}
}
}

View File

@@ -1,276 +0,0 @@
package eu.kanade.tachiyomi.ui.manga.info
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.databinding.MangaInfoHeaderBinding
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.getNameForMangaInfo
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.controller.getMainAppBarHeight
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.view.loadAutoPause
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.android.view.clicks
import reactivecircus.flowbinding.android.view.longClicks
import uy.kohesive.injekt.injectLazy
class MangaInfoHeaderAdapter(
private val controller: MangaController,
private val fromSource: Boolean,
private val isTablet: Boolean,
) :
RecyclerView.Adapter<MangaInfoHeaderAdapter.HeaderViewHolder>() {
private val trackManager: TrackManager by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
private val sourceManager: SourceManager by injectLazy()
private var manga: Manga = controller.presenter.manga
private var source: Source = controller.presenter.source
private var trackCount: Int = 0
private lateinit var binding: MangaInfoHeaderBinding
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HeaderViewHolder {
binding = MangaInfoHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
updateCoverPosition()
// Expand manga info if navigated from source listing or explicitly set to
// (e.g. on tablets)
binding.mangaSummarySection.expanded = fromSource || isTablet
return HeaderViewHolder(binding.root)
}
override fun getItemCount(): Int = 1
override fun getItemId(position: Int): Long = hashCode().toLong()
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
holder.bind()
}
/**
* Update the view with manga information.
*
* @param manga manga object containing information about manga.
* @param source the source of the manga.
*/
fun update(manga: Manga, source: Source) {
this.manga = manga
this.source = source
update()
}
fun update() {
notifyItemChanged(0, this)
}
fun setTrackingCount(trackCount: Int) {
this.trackCount = trackCount
update()
}
private fun updateCoverPosition() {
if (isTablet) return
val appBarHeight = controller.getMainAppBarHeight()
binding.mangaCover.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin += appBarHeight
}
}
inner class HeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
fun bind() {
// For rounded corners
binding.mangaCover.clipToOutline = true
binding.btnFavorite.clicks()
.onEach { controller.onFavoriteClick() }
.launchIn(controller.viewScope)
if (controller.presenter.manga.favorite) {
binding.btnFavorite.longClicks()
.onEach { controller.onCategoriesClick() }
.launchIn(controller.viewScope)
}
with(binding.btnTracking) {
if (trackManager.hasLoggedServices()) {
isVisible = true
if (trackCount > 0) {
setIconResource(R.drawable.ic_done_24dp)
text = view.context.resources.getQuantityString(
R.plurals.num_trackers,
trackCount,
trackCount,
)
isActivated = true
} else {
setIconResource(R.drawable.ic_sync_24dp)
text = view.context.getString(R.string.manga_tracking_tab)
isActivated = false
}
clicks()
.onEach { controller.onTrackingClick() }
.launchIn(controller.viewScope)
} else {
isVisible = false
}
}
if (controller.presenter.source is HttpSource) {
binding.btnWebview.isVisible = true
binding.btnWebview.clicks()
.onEach { controller.openMangaInWebView() }
.launchIn(controller.viewScope)
}
binding.mangaFullTitle.longClicks()
.onEach {
controller.activity?.copyToClipboard(
view.context.getString(R.string.title),
binding.mangaFullTitle.text.toString(),
)
}
.launchIn(controller.viewScope)
binding.mangaFullTitle.clicks()
.onEach {
controller.performGlobalSearch(binding.mangaFullTitle.text.toString())
}
.launchIn(controller.viewScope)
binding.mangaAuthor.longClicks()
.onEach {
controller.activity?.copyToClipboard(
binding.mangaAuthor.text.toString(),
binding.mangaAuthor.text.toString(),
)
}
.launchIn(controller.viewScope)
binding.mangaAuthor.clicks()
.onEach {
controller.performGlobalSearch(binding.mangaAuthor.text.toString())
}
.launchIn(controller.viewScope)
binding.mangaArtist.longClicks()
.onEach {
controller.activity?.copyToClipboard(
binding.mangaArtist.text.toString(),
binding.mangaArtist.text.toString(),
)
}
.launchIn(controller.viewScope)
binding.mangaArtist.clicks()
.onEach {
controller.performGlobalSearch(binding.mangaArtist.text.toString())
}
.launchIn(controller.viewScope)
binding.mangaCover.clicks()
.onEach {
controller.showFullCoverDialog()
}
.launchIn(controller.viewScope)
setMangaInfo()
}
/**
* Update the view with manga information.
*
* @param manga manga object containing information about manga.
* @param source the source of the manga.
*/
private fun setMangaInfo() {
// Update full title TextView.
binding.mangaFullTitle.text = manga.title.ifBlank { view.context.getString(R.string.unknown) }
// Update author TextView.
binding.mangaAuthor.text = if (manga.author.isNullOrBlank()) {
view.context.getString(R.string.unknown_author)
} else {
manga.author
}
// Update artist TextView.
val hasArtist = !manga.artist.isNullOrBlank() && manga.artist != manga.author
binding.mangaArtist.isVisible = hasArtist
if (hasArtist) {
binding.mangaArtist.text = manga.artist
}
// If manga source is known update source TextView.
binding.mangaMissingSourceIcon.isVisible = source is SourceManager.StubSource
with(binding.mangaSource) {
text = source.getNameForMangaInfo()
setOnClickListener {
controller.performSearch(sourceManager.getOrStub(source.id).name)
}
}
// Update manga status.
val (statusDrawable, statusString) = when (manga.status) {
SManga.ONGOING -> R.drawable.ic_status_ongoing_24dp to R.string.ongoing
SManga.COMPLETED -> R.drawable.ic_status_completed_24dp to R.string.completed
SManga.LICENSED -> R.drawable.ic_status_licensed_24dp to R.string.licensed
SManga.PUBLISHING_FINISHED -> R.drawable.ic_done_24dp to R.string.publishing_finished
SManga.CANCELLED -> R.drawable.ic_close_24dp to R.string.cancelled
SManga.ON_HIATUS -> R.drawable.ic_pause_24dp to R.string.on_hiatus
else -> R.drawable.ic_status_unknown_24dp to R.string.unknown
}
binding.mangaStatusIcon.setImageResource(statusDrawable)
binding.mangaStatus.setText(statusString)
// Set the favorite drawable to the correct one.
setFavoriteButtonState(manga.favorite)
// Set cover if changed.
binding.backdrop.loadAutoPause(manga)
binding.mangaCover.loadAutoPause(manga)
// Manga info section
binding.mangaSummarySection.setTags(manga.getGenres(), controller::performGenreSearch)
binding.mangaSummarySection.description = manga.description
binding.mangaSummarySection.isVisible = !manga.description.isNullOrBlank() || !manga.genre.isNullOrBlank()
}
/**
* Update favorite button with correct drawable and text.
*
* @param isFavorite determines if manga is favorite or not.
*/
private fun setFavoriteButtonState(isFavorite: Boolean) {
// Set the Favorite drawable to the correct one.
// Border drawable if false, filled drawable if true.
val (iconResource, stringResource) = when (isFavorite) {
true -> R.drawable.ic_favorite_24dp to R.string.in_library
false -> R.drawable.ic_favorite_border_24dp to R.string.add_to_library
}
binding.btnFavorite.apply {
setIconResource(iconResource)
text = context.getString(stringResource)
isActivated = isFavorite
}
}
}
}

View File

@@ -80,7 +80,7 @@ class TrackSearchDialog : DialogController {
// Do an initial search based on the manga's title
if (savedViewState == null) {
currentlySearched = trackController.presenter.manga.title
currentlySearched = trackController.presenter.manga!!.title
binding!!.titleInput.editText?.append(currentlySearched)
}
search(currentlySearched)

View File

@@ -10,6 +10,7 @@ import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.DateValidatorPointBackward
import com.google.android.material.datepicker.DateValidatorPointForward
import com.google.android.material.datepicker.MaterialDatePicker
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.databinding.TrackControllerBinding
@@ -25,7 +26,7 @@ import eu.kanade.tachiyomi.widget.sheet.BaseBottomSheetDialog
class TrackSheet(
val controller: MangaController,
val fragmentManager: FragmentManager,
private val fragmentManager: FragmentManager,
) : BaseBottomSheetDialog(controller.activity!!),
TrackAdapter.OnClickListener,
SetTrackStatusDialog.Listener,
@@ -74,8 +75,8 @@ class TrackSheet(
override fun onSetClick(position: Int) {
val item = adapter.getItem(position) ?: return
val manga = controller.presenter.manga
val source = controller.presenter.source
val manga = controller.presenter.manga?.toDbManga() ?: return
val source = controller.presenter.source ?: return
if (item.service is EnhancedTrackService) {
if (item.track != null) {

View File

@@ -34,7 +34,7 @@ class HistoryController : ComposeController<HistoryPresenter>(), RootController
nestedScrollInterop = nestedScrollInterop,
presenter = presenter,
onClickCover = { history ->
router.pushController(MangaController(history))
router.pushController(MangaController(history.id))
},
onClickResume = { history ->
presenter.getNextChapterForManga(history.mangaId, history.chapterId)