Updates & Fixes

Made manga header in details its own item
Pressing the tab icon in library toggles the filters bottom sheet state, no longer just shows it
Pressing the tab icon in browse toggles the extensions sheet
Better logic in detecting which section of the list library you're in
Fixing:
• download cache with incorrect casing
• "view chapters" from notifcation
• Title bar centering
• Filtering by tracker
This commit is contained in:
Jay 2020-03-14 16:29:12 -07:00
parent 1a9614b5de
commit 93cb8f649e
24 changed files with 212 additions and 171 deletions

View File

@ -24,19 +24,10 @@ interface Chapter : SChapter, Serializable {
val isRecognizedNumber: Boolean
get() = chapter_number >= 0f
val isHeader: Boolean
get() = id == Long.MIN_VALUE
companion object {
fun create(): Chapter = ChapterImpl().apply {
chapter_number = -1f
}
fun createHeader(isExpanded: Boolean): Chapter = ChapterImpl().apply {
id = Long.MIN_VALUE
read = isExpanded
manga_id = null
}
}
}

View File

@ -78,7 +78,9 @@ class DownloadCache(
checkRenew()
val files = mangaFiles[manga.id] ?: return false
return files.any { it in provider.getValidChapterDirNames(chapter) }
return files.any { file -> provider.getValidChapterDirNames(chapter).any {
it.toLowerCase() == file.toLowerCase()
} }
}
/**

View File

@ -395,7 +395,7 @@ class NotificationReceiver : BroadcastReceiver() {
}
/**
* Returns [PendingIntent] that opens the manga info controller.
* Returns [PendingIntent] that opens the manga details controller.
*
* @param context context of application
* @param manga manga of chapter
@ -404,7 +404,7 @@ class NotificationReceiver : BroadcastReceiver() {
PendingIntent {
val newIntent =
Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_MANGA)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
.putExtra(MangaDetailsController.MANGA_EXTRA, manga.id)
.putExtra("notificationId", manga.id.hashCode())
.putExtra("groupId", groupId)
@ -422,7 +422,7 @@ class NotificationReceiver : BroadcastReceiver() {
internal fun openExtensionsPendingActivity(context: Context): PendingIntent {
val newIntent =
Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_EXTENSIONS)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
return PendingIntent.getActivity(
context, 0, newIntent, PendingIntent.FLAG_UPDATE_CURRENT
)

View File

@ -21,8 +21,10 @@ class CenteredToolbar@JvmOverloads constructor(context: Context, attrs: Attribut
else {
toolbar_title.text = context.getString(resId)
post {
toolbar_title.text = context.getString(resId)
requestLayout()
if (navigationIcon !is DrawerArrowDrawable) {
toolbar_title.text = context.getString(resId)
requestLayout()
}
}
super.setTitle(null)
}
@ -31,13 +33,15 @@ class CenteredToolbar@JvmOverloads constructor(context: Context, attrs: Attribut
override fun setTitle(title: CharSequence?) {
if (navigationIcon is DrawerArrowDrawable) {
super.setTitle(title)
toolbar_title.text = null
toolbar_title.text = ""
}
else {
toolbar_title.text = title
post {
toolbar_title.text = title
requestLayout()
if (navigationIcon !is DrawerArrowDrawable) {
toolbar_title.text = title
requestLayout()
}
}
super.setTitle(null)
}

View File

@ -1,18 +1,15 @@
package eu.kanade.tachiyomi.ui.base.controller
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
import com.bluelinelabs.conductor.RestoreViewOnCreateController
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.*
import timber.log.Timber
@ -82,7 +79,8 @@ abstract class BaseController(bundle: Bundle? = null) : RestoreViewOnCreateContr
parentController = parentController.parentController
}
(activity as? AppCompatActivity)?.supportActionBar?.title = getTitle()
if (router.backstack.lastOrNull()?.controller() == this)
(activity as? AppCompatActivity)?.supportActionBar?.title = getTitle()
}
private fun Controller.instance(): String {

View File

@ -164,6 +164,15 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
}
fun toggleExtensions() {
if (ext_bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED) {
ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
}
else {
ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
}
}
override fun handleRootBack(): Boolean {
if (ext_bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED) {
ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED

View File

@ -514,13 +514,7 @@ open class LibraryController(
when (item.itemId) {
R.id.action_search -> expandActionViewFromInteraction = true
R.id.action_library_filter -> {
if (bottom_sheet.sheetBehavior?.isHideable == true &&
bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED)
bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN
else if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED
&& bottom_sheet.sheetBehavior?.skipCollapsed == false)
bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
else bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
toggleFilters()
}
R.id.action_library_display -> {
DisplayBottomSheet(this).show()
@ -531,12 +525,14 @@ open class LibraryController(
return true
}
fun showFiltersBottomSheet() {
if (bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_HIDDEN)
bottom_sheet.sheetBehavior?.state =
if (bottom_sheet.sheetBehavior?.skipCollapsed == false)
BottomSheetBehavior.STATE_COLLAPSED
else BottomSheetBehavior.STATE_EXPANDED
fun toggleFilters() {
if (bottom_sheet.sheetBehavior?.isHideable == true &&
bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED)
bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN
else if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED
&& bottom_sheet.sheetBehavior?.skipCollapsed == false)
bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
else bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
}

View File

@ -246,6 +246,9 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
checkboxImage.setImageDrawable(tintedDrawable)
}
override fun onLongClick(view: View?): Boolean {
super.onLongClick(view)
return false
}
}
}

View File

@ -24,6 +24,7 @@ import com.afollestad.materialdialogs.checkbox.checkBoxPrompt
import com.afollestad.materialdialogs.checkbox.isCheckPromptChecked
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
import com.google.android.material.bottomsheet.BottomSheetBehavior
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter
import eu.davidea.flexibleadapter.items.IFlexible
@ -113,13 +114,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
private var scrollListener = object : RecyclerView.OnScrollListener () {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val position =
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
val order = when (val item = adapter.getItem(position)) {
is LibraryHeaderItem -> item.category.order
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
else -> null
}
val order = getCategoryOrder()
if (order != null && order != activeCategory) {
preferences.lastUsedCategory().set(order)
activeCategory = order
@ -163,13 +158,9 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
if (startPosX == null) {
startPosX = event.rawX
startPosY = event.rawY
val position =
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
val order = when (val item = adapter.getItem(position)) {
is LibraryHeaderItem -> item.category.order
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
else -> null
}
val position = (recycler.layoutManager as LinearLayoutManager)
.findFirstVisibleItemPosition()
val order = getCategoryOrder()
if (order != null) {
ogCategory = order
var newOffsetN = order + 1
@ -255,6 +246,26 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
}
}
private fun getCategoryOrder(): Int? {
val position =
(recycler.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
var order = when (val item = adapter.getItem(position)) {
is LibraryHeaderItem -> item.category.order
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
else -> null
}
if (order == null) {
val fPosition =
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
order = when (val item = adapter.getItem(fPosition)) {
is LibraryHeaderItem -> item.category.order
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
else -> null
}
}
return order
}
private fun resetScrollingValues() {
startPosX = null
startPosY = null
@ -448,13 +459,11 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
headerPosition, (if (headerPosition == 0) 0 else (-28).dpToPx)
+ appbarOffset
)
val isCurrentController = router?.backstack?.lastOrNull()?.controller() ==
this
val headerItem = adapter.getItem(headerPosition) as? LibraryHeaderItem
if (headerItem != null) {
customTitleSpinner.category_title.text = headerItem.category.name
if (isCurrentController) setTitle()
setTitle()
}
recycler.suppressLayout(false)
}
@ -590,6 +599,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
*/
override fun onItemLongClick(position: Int) {
if (recyclerIsScrolling()) return
if (adapter.getItem(position) is LibraryHeaderItem) return
createActionModeIfNeeded()
when {
lastClickPosition == -1 -> setSelection(position)
@ -778,8 +788,10 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
override fun onSwipeTop(x: Float, y: Float) {
val sheetRect = Rect()
activity!!.navigationView.getGlobalVisibleRect(sheetRect)
if (sheetRect.contains(x.toInt(), y.toInt()))
showFiltersBottomSheet()
if (sheetRect.contains(x.toInt(), y.toInt())) {
if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED)
toggleFilters()
}
}
override fun onSwipeLeft(x: Float, y: Float) = goToNextCategory(x)
override fun onSwipeRight(x: Float, y: Float) = goToNextCategory(x)

View File

@ -60,11 +60,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
private val filterItems:MutableList<FilterTagGroup> by lazy {
val list = mutableListOf<FilterTagGroup>()
list.add(downloaded)
list.add(unread)
list.add(downloaded)
list.add(completed)
//if (Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().isNotEmpty())
// list.add(categories)
if (Injekt.get<TrackManager>().hasLoggedServices())
list.add(tracked)
list
@ -261,6 +259,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
if (tracked.isActivated) {
filter_layout.addView(trackers)
filterItems.add(trackers!!)
trackers?.setState(FILTER_TRACKER)
reSortViews()
}
}
}
@ -293,6 +293,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
else if (preferences.filterTracked().getOrDefault() != 1 &&
trackers?.parent != null) {
filter_layout.removeView(trackers)
trackers?.reset()
FILTER_TRACKER = ""
filterItems.remove(trackers!!)
}
val hasFilters = hasActiveFilters()

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.library.filter
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import com.f2prateek.rx.preferences.Preference
@ -76,9 +77,10 @@ class FilterTagGroup@JvmOverloads constructor(context: Context, attrs: Attribute
toggleButton(index, false)
}
fun setState(enabled: Boolean) {
if (enabled)
toggleButton(0, false)
fun setState(text: String) {
val index = buttons.indexOfFirst { it.text == text && it.visibility == View.VISIBLE }
if (index > -1)
toggleButton(index, false)
}
fun reset() {

View File

@ -36,7 +36,6 @@ import com.google.android.material.snackbar.Snackbar
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.Migrations
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.DownloadServiceListener
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
@ -58,6 +57,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController
import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.ui.setting.SettingsController
import eu.kanade.tachiyomi.ui.setting.SettingsMainController
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.launchUI
@ -71,8 +71,6 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.util.Date
import java.util.concurrent.TimeUnit
@ -169,27 +167,27 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
//R.id.nav_settings -> setRoot(SettingsMainController(), id)
}
}
else if (currentRoot.tag()?.toIntOrNull() == id) {
when (id) {
R.id.nav_recents -> {
if (router.backstack.size > 1) router.popToRoot()
else {
else if (currentRoot.tag()?.toIntOrNull() == id) {
if (router.backstackSize == 1) {
when (id) {
R.id.nav_recents -> {
val showRecents = preferences.showRecentUpdates().getOrDefault()
if (!showRecents) setRoot(RecentChaptersController(), id)
else setRoot(RecentlyReadController(), id)
preferences.showRecentUpdates().set(!showRecents)
updateRecentsIcon()
}
}
R.id.nav_library -> {
if (router.backstack.size > 1) router.popToRoot()
else {
val controller = router.getControllerWithTag(id.toString()) as?
LibraryController
controller?.showFiltersBottomSheet()
R.id.nav_library -> {
val controller =
router.getControllerWithTag(id.toString()) as? LibraryController
controller?.toggleFilters()
}
R.id.nav_catalogues -> {
val controller =
router.getControllerWithTag(id.toString()) as? CatalogueController
controller?.toggleExtensions()
}
}
R.id.nav_catalogues -> router.popToRoot()
}
}
true
@ -314,9 +312,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
}
}
toolbar.navigationIcon = if (router.backstackSize > 1) drawerArrow else searchDrawable
(router.backstack.lastOrNull()?.controller() as? BaseController)?.setTitle()
toolbar.setNavigationOnClickListener {
val rootSearchController = router.backstack.lastOrNull()?.controller()
if (rootSearchController is RootSearchInterface) {
@ -344,6 +339,10 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
syncActivityViewWithController(router.backstack.lastOrNull()?.controller())
toolbar.navigationIcon = if (router.backstackSize > 1) drawerArrow else searchDrawable
(router.backstack.lastOrNull()?.controller() as? BaseController)?.setTitle()
(router.backstack.lastOrNull()?.controller() as? SettingsController)?.setTitle()
if (savedInstanceState == null) {
// Show changelog if needed
if (Migrations.upgrade(preferences)) {

View File

@ -1,20 +0,0 @@
package eu.kanade.tachiyomi.ui.manga
import android.view.View
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter
abstract class MangaChapterHolder(
private val view: View,
private val adapter: ChaptersAdapter
) : BaseFlexibleViewHolder(view, adapter) {
/**
* Method called from [ChaptersAdapter.onBindViewHolder]. It updates the data for this
* holder with the given manga.
*
* @param item the manga item to bind.
*/
abstract fun bind(item: ChapterItem, manga: Manga)
}

View File

@ -105,7 +105,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File
open class MangaDetailsController : BaseController,
class MangaDetailsController : BaseController,
FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemLongClickListener,
ActionMode.Callback,
@ -126,6 +126,7 @@ open class MangaDetailsController : BaseController,
if (manga != null) {
source = Injekt.get<SourceManager>().getOrStub(manga.source)
}
presenter = MangaDetailsPresenter(this, manga!!, source!!)
}
constructor(mangaId: Long) : this(
@ -142,15 +143,15 @@ open class MangaDetailsController : BaseController,
private var manga: Manga? = null
private var source: Source? = null
var colorAnimator:ValueAnimator? = null
lateinit var presenter:MangaDetailsPresenter
val presenter:MangaDetailsPresenter
var coverColor:Int? = null
var toolbarIsColored = false
private var snack: Snackbar? = null
val fromCatalogue = args.getBoolean(FROM_CATALOGUE_EXTRA, false)
var coverDrawable:Drawable? = null
var trackingBottomSheet: TrackingBottomSheet? = null
private var trackingBottomSheet: TrackingBottomSheet? = null
private var startingDLChapterPos:Int? = null
var startingDLChapterPos:Int? = null
/**
* Adapter containing a list of chapters.
*/
@ -178,7 +179,6 @@ open class MangaDetailsController : BaseController,
override fun onViewCreated(view: View) {
super.onViewCreated(view)
coverColor = null
if (!::presenter.isInitialized) presenter = MangaDetailsPresenter(this, manga!!, source!!)
// Init RecyclerView and adapter
adapter = ChaptersAdapter(this, view.context)
@ -191,7 +191,7 @@ open class MangaDetailsController : BaseController,
DividerItemDecoration.VERTICAL
)
)
recycler.setHasFixedSize(false)
recycler.setHasFixedSize(true)
adapter?.fastScroller = fast_scroller
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = view.context.obtainStyledAttributes(attrsArray)
@ -208,7 +208,6 @@ open class MangaDetailsController : BaseController,
topMargin = appbarHeight + insets.systemWindowInsetTop
bottomMargin = insets.systemWindowInsetBottom
}
// offset the recycler by the fab's inset + some inset on top
v.updatePaddingRelative(bottom = insets.systemWindowInsetBottom)
}
@ -306,6 +305,11 @@ open class MangaDetailsController : BaseController,
presenter.isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()
presenter.headerItem.isLocked = presenter.isLockedFromSearch
presenter.fetchChapters()
val isCurrentController = router?.backstack?.lastOrNull()?.controller() ==
this
if (isCurrentController) {
setStatusBarAndToolbar()
}
}
fun showError(message: String) {
@ -325,10 +329,7 @@ open class MangaDetailsController : BaseController,
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type)
if (type == ControllerChangeType.PUSH_ENTER || type == ControllerChangeType.POP_ENTER) {
setStatusBar()
(activity as MainActivity).appbar.setBackgroundColor(Color.TRANSPARENT)
(activity as MainActivity).toolbar.setBackgroundColor(activity?.window?.statusBarColor
?: Color.TRANSPARENT)
setStatusBarAndToolbar()
}
else if (type == ControllerChangeType.PUSH_EXIT || type == ControllerChangeType.POP_EXIT) {
if (router.backstack.lastOrNull()?.controller() is DialogController)
@ -351,15 +352,9 @@ open class MangaDetailsController : BaseController,
}
fun updateHeader() {
if (presenter.chapters.isEmpty()) {
adapter?.updateDataSet(listOf(presenter.headerItem))
}
else {
swipe_refresh?.isRefreshing = presenter.isLoading
adapter?.updateDataSet(
listOf(ChapterItem(presenter.headerItem, presenter.manga)) + presenter.chapters
)
}
swipe_refresh?.isRefreshing = presenter.isLoading
adapter?.setChapters(presenter.chapters)
addMangaHeader()
activity?.invalidateOptionsMenu()
}
@ -369,15 +364,15 @@ open class MangaDetailsController : BaseController,
launchUI { swipe_refresh?.isRefreshing = true }
presenter.fetchChaptersFromSource()
}
adapter?.updateDataSet(listOf(presenter.headerItem) + chapters)
adapter?.setChapters(chapters)
addMangaHeader()
activity?.invalidateOptionsMenu()
}
fun refreshAdapter() = adapter?.notifyDataSetChanged()
override fun onItemClick(view: View?, position: Int): Boolean {
val chapter = adapter?.getItem(position)?.chapter ?: return false
if (chapter.isHeader) return false
val chapter = (adapter?.getItem(position) as? ChapterItem)?.chapter ?: return false
if (actionMode != null) {
if (startingDLChapterPos == null) {
adapter?.addSelection(position)
@ -410,7 +405,7 @@ open class MangaDetailsController : BaseController,
override fun onItemLongClick(position: Int) {
val adapter = adapter ?: return
val item = adapter.getItem(position) ?: return
val item = (adapter.getItem(position) as? ChapterItem) ?: return
val itemView = getHolder(item)?.itemView ?: return
val popup = PopupMenu(itemView.context, itemView, Gravity.END)
@ -709,7 +704,7 @@ open class MangaDetailsController : BaseController,
}
override fun startDownloadRange(position: Int) {
createActionModeIfNeeded()
if (actionMode == null) createActionModeIfNeeded()
onItemClick(null, position)
}
@ -743,8 +738,11 @@ open class MangaDetailsController : BaseController,
override fun downloadChapter(position: Int) {
val view = view ?: return
val chapter = adapter?.getItem(position) ?: return
if (chapter.isHeader) return
val chapter = (adapter?.getItem(position) as? ChapterItem) ?: return
if (actionMode != null) {
onItemClick(null, position)
return
}
if (chapter.status != Download.NOT_DOWNLOADED && chapter.status != Download.ERROR) {
presenter.deleteChapters(listOf(chapter))
}
@ -970,19 +968,30 @@ open class MangaDetailsController : BaseController,
override fun onDestroyActionMode(mode: ActionMode?) {
actionMode = null
setStatusBar()
setStatusBarAndToolbar()
startingDLChapterPos = null
adapter?.mode = SelectableAdapter.Mode.IDLE
adapter?.clearSelection()
return
}
private fun setStatusBar() {
/**
* Called to set the last used catalogue at the top of the view.
*/
private fun addMangaHeader() {
adapter?.removeAllScrollableHeaders()
adapter?.addScrollableHeader(presenter.headerItem)
}
private fun setStatusBarAndToolbar() {
activity?.window?.statusBarColor = if (toolbarIsColored) {
val translucentColor = ColorUtils.setAlphaComponent(coverColor ?: Color.TRANSPARENT, 175)
(activity as MainActivity).toolbar.setBackgroundColor(translucentColor)
translucentColor
} else Color.TRANSPARENT
(activity as MainActivity).appbar.setBackgroundColor(Color.TRANSPARENT)
(activity as MainActivity).toolbar.setBackgroundColor(activity?.window?.statusBarColor
?: Color.TRANSPARENT)
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {

View File

@ -69,7 +69,7 @@ class MangaDetailsPresenter(private val controller: MangaDetailsController,
var chapters:List<ChapterItem> = emptyList()
private set
var headerItem = ChapterItem(Chapter.createHeader(controller.fromCatalogue), manga)
var headerItem = MangaHeaderItem(manga, controller.fromCatalogue)
fun onCreate() {
isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()

View File

@ -16,7 +16,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.view.gone
@ -30,7 +30,7 @@ class MangaHeaderHolder(
private val view: View,
private val adapter: ChaptersAdapter,
startExpanded: Boolean
) : MangaChapterHolder(view, adapter) {
) : BaseFlexibleViewHolder(view, adapter) {
init {
start_reading_button.setOnClickListener { adapter.coverListener.readNextChapter() }
@ -84,8 +84,8 @@ class MangaHeaderHolder(
}
@SuppressLint("SetTextI18n")
override fun bind(item: ChapterItem, manga: Manga) {
val presenter = adapter.coverListener?.mangaPresenter() ?: return
fun bind(item: MangaHeaderItem, manga: Manga) {
val presenter = adapter.coverListener.mangaPresenter()
manga_full_title.text = manga.currentTitle()
if (manga.currentGenres().isNullOrBlank().not())

View File

@ -0,0 +1,44 @@
package eu.kanade.tachiyomi.ui.manga
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.IFlexible
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter
class MangaHeaderItem(val manga: Manga, private val startExpanded: Boolean):
AbstractFlexibleItem<MangaHeaderHolder>(){
var isLocked = false
override fun getLayoutRes(): Int {
return R.layout.manga_header_item
}
override fun isSelectable(): Boolean {
return false
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaHeaderHolder {
return MangaHeaderHolder(view, adapter as ChaptersAdapter, startExpanded)
}
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
holder: MangaHeaderHolder,
position: Int,
payloads: MutableList<Any?>?) {
holder.bind(this, manga)
}
override fun equals(other: Any?): Boolean {
return (this === other)
}
override fun hashCode(): Int {
return manga.id!!.hashCode()
}
}

View File

@ -10,11 +10,9 @@ 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.MangaChapterHolder
import eu.kanade.tachiyomi.ui.manga.MangaHeaderHolder
class ChapterItem(val chapter: Chapter, val manga: Manga) :
AbstractFlexibleItem<MangaChapterHolder>(),
AbstractFlexibleItem<ChapterMatHolder>(),
Chapter by chapter {
private var _status: Int = 0
@ -36,22 +34,19 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) :
get() = status == Download.DOWNLOADED
override fun getLayoutRes(): Int {
return if (chapter.isHeader) R.layout.manga_header_item
else R.layout.chapters_mat_item
return R.layout.chapters_mat_item
}
override fun isSelectable(): Boolean {
return !chapter.isHeader
return true
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaChapterHolder {
return if (chapter.isHeader) MangaHeaderHolder(view, adapter as ChaptersAdapter,
startExpanded = chapter.read)
else ChapterMatHolder(view, adapter as ChaptersAdapter)
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): ChapterMatHolder {
return ChapterMatHolder(view, adapter as ChaptersAdapter)
}
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
holder: MangaChapterHolder,
holder: ChapterMatHolder,
position: Int,
payloads: MutableList<Any?>?) {
holder.bind(this, manga)

View File

@ -6,10 +6,10 @@ import androidx.appcompat.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.manga.MangaChapterHolder
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.invisible
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.chapters_mat_item.*
import kotlinx.android.synthetic.main.download_button.*
import java.util.Date
@ -17,8 +17,9 @@ import java.util.Date
class ChapterMatHolder(
private val view: View,
private val adapter: ChaptersAdapter
) : MangaChapterHolder(view, adapter) {
) : BaseFlexibleViewHolder(view, adapter) {
private var localSource = false
init {
download_button.setOnClickListener { downloadOrRemoveMenu() }
download_button.setOnLongClickListener {
@ -28,7 +29,7 @@ class ChapterMatHolder(
}
private fun downloadOrRemoveMenu() {
val chapter = adapter.getItem(adapterPosition) ?: return
val chapter = adapter.getItem(adapterPosition) as? ChapterItem ?: return
if (chapter.status == Download.NOT_DOWNLOADED || chapter.status == Download.ERROR) {
adapter.coverListener.downloadChapter(adapterPosition)
} else {
@ -56,7 +57,7 @@ class ChapterMatHolder(
}
}
override fun bind(item: ChapterItem, manga: Manga) {
fun bind(item: ChapterItem, manga: Manga) {
val chapter = item.chapter
val isLocked = item.isLocked
chapter_title.text = when (manga.displayMode) {
@ -67,12 +68,10 @@ class ChapterMatHolder(
else -> chapter.name
}
//chapter_menu.visible()
// Set the correct drawable for dropdown and update the tint to match theme.
//chapter_menu.setVectorCompat(R.drawable.ic_more_vert_black_24dp, view.context
// .getResourceColor(R.attr.icon_color))
localSource = manga.source == LocalSource.ID
download_button.visibleIf(!localSource)
if (isLocked) download_button.invisible()
if (isLocked) download_button.gone()
// Set correct text color
@ -110,7 +109,7 @@ class ChapterMatHolder(
gone()
return
}
visible()
download_button.visibleIf(!localSource)
setDownloadStatus(status, progress)
}
}

View File

@ -4,22 +4,21 @@ import android.content.Context
import android.view.View
import androidx.fragment.app.FragmentActivity
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.ui.manga.MangaDetailsPresenter
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
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(
val controller: MangaDetailsController,
context: Context
) : FlexibleAdapter<ChapterItem>(null, controller, true) {
) : FlexibleAdapter<IFlexible<*>>(null, controller, true) {
val preferences: PreferencesHelper by injectLazy()
@ -36,9 +35,7 @@ class ChaptersAdapter(
val decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols()
.apply { decimalSeparator = '.' })
val dateFormat: DateFormat = preferences.dateFormat().getOrDefault()
override fun updateDataSet(items: List<ChapterItem>?) {
fun setChapters(items: List<ChapterItem>?) {
this.items = items ?: emptyList()
super.updateDataSet(items)
}

View File

@ -156,6 +156,5 @@
tools:text="Sample artist" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@ -30,7 +30,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:clipToPadding="false"
android:paddingStart="20dp"
android:paddingStart="10dp"
android:paddingTop="8dp"
android:paddingEnd="20dp"
android:paddingBottom="6dp"
@ -63,7 +63,7 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="23dp"
android:layout_marginStart="10dp"
android:orientation="horizontal">
<com.google.android.material.checkbox.MaterialCheckBox

View File

@ -18,7 +18,7 @@
<com.google.android.material.textview.MaterialTextView
android:id="@+id/download_text"
style="@style/TextAppearance.Regular.Caption.Light"
style="@style/TextAppearance.MaterialComponents.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/pale_red"
@ -48,7 +48,7 @@
<com.google.android.material.textview.MaterialTextView
android:id="@+id/unread_text"
style="@style/TextAppearance.Regular.Caption.Light"
style="@style/TextAppearance.MaterialComponents.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"

View File

@ -551,8 +551,8 @@
<string name="manga_download">Download</string>
<string name="custom_download">Download custom amount</string>
<string name="download_1">Next chapter</string>
<string name="download_first">First unread chapter</string>
<string name="download_5">Next 5 chapters</string>
<string name="download_first">Next unread chapter</string>
<string name="download_5">Next 5 unread</string>
<string name="download_10">Next 10 chapters</string>
<string name="download_custom">Custom range</string>
<string name="download_all">All chapters</string>