Tablet manga view

(cherry picked from commit 7875f363a8a18659d4cb59774f6ce0e3d0a428ab)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
This commit is contained in:
arkon 2021-05-23 12:36:47 -04:00 committed by Jobobby04
parent 666447faac
commit dd914047f8
5 changed files with 161 additions and 47 deletions

View File

@ -109,7 +109,6 @@ import exh.metadata.metadata.base.FlatMetadata
import exh.recs.RecommendsController
import exh.source.MERGED_SOURCE_ID
import exh.source.getMainSource
import exh.source.isEhBasedSource
import exh.source.isMdBasedSource
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
@ -281,11 +280,17 @@ class MangaController :
override fun onViewCreated(view: View) {
super.onViewCreated(view)
binding.recycler.applyInsetter {
listOfNotNull(binding.fullRecycler, binding.infoRecycler, binding.chaptersRecycler)
.forEach {
it.applyInsetter {
type(navigationBars = true) {
padding()
}
}
it.layoutManager = LinearLayoutManager(view.context)
it.setHasFixedSize(true)
}
binding.actionToolbar.applyInsetter {
type(navigationBars = true) {
margin(bottom = true)
@ -293,59 +298,70 @@ class MangaController :
}
if (manga == null || source == null) return
val adapters: MutableList<RecyclerView.Adapter<out RecyclerView.ViewHolder>?> = mutableListOf()
// Init RecyclerView and adapter
mangaInfoAdapter = MangaInfoHeaderAdapter(this, binding.infoRecycler != null)
chaptersHeaderAdapter = MangaChaptersHeaderAdapter(this)
chaptersAdapter = ChaptersAdapter(this, view.context)
// SY -->
mangaInfoAdapter = MangaInfoHeaderAdapter(this)
adapters += mangaInfoAdapter
val mainSource = presenter.source.getMainSource()
if (mainSource is MetadataSource<*, *>) {
mangaMetaInfoAdapter = mainSource.getDescriptionAdapter(this)
mangaMetaInfoAdapter?.let { adapters += it }
}
mangaInfoItemAdapter = MangaInfoItemAdapter(this, fromSource)
adapters += mangaInfoItemAdapter
if (!preferences.recommendsInOverflow().get() || smartSearchConfig != null) {
mangaInfoButtonsAdapter = MangaInfoButtonsAdapter(this)
adapters += mangaInfoButtonsAdapter
}
mangaInfoItemAdapter = MangaInfoItemAdapter(this, fromSource, binding.infoRecycler != null)
// SY <--
// Phone layout
binding.fullRecycler?.let {
it.adapter = ConcatAdapter(
listOfNotNull(
mangaInfoAdapter,
mangaMetaInfoAdapter,
mangaInfoItemAdapter,
mangaInfoButtonsAdapter,
chaptersHeaderAdapter,
chaptersAdapter
)
)
it.scrollEvents()
.onEach { updateToolbarTitleAlpha() }
.launchIn(viewScope)
}
// Tablet layout
binding.infoRecycler?.let {
it.adapter = ConcatAdapter(
listOfNotNull(
mangaInfoAdapter,
mangaMetaInfoAdapter,
mangaInfoItemAdapter,
mangaInfoButtonsAdapter
)
)
}
binding.chaptersRecycler?.let {
it.adapter = ConcatAdapter(chaptersHeaderAdapter, chaptersAdapter)
}
chaptersHeaderAdapter = MangaChaptersHeaderAdapter(this)
adapters += chaptersHeaderAdapter
chaptersAdapter = ChaptersAdapter(this, view.context)
adapters += chaptersAdapter
binding.recycler.adapter = ConcatAdapter(adapters)
// SY <--
binding.recycler.layoutManager = LinearLayoutManager(view.context)
binding.recycler.setHasFixedSize(true)
chaptersAdapter?.fastScroller = binding.fastScroller
actionFabScrollListener = actionFab?.shrinkOnScroll(binding.recycler)
actionFabScrollListener = actionFab?.shrinkOnScroll(chaptersRecycler)
// Skips directly to chapters list if navigated to from the library
binding.recycler.post {
chaptersRecycler.post {
if (!fromSource && preferences.jumpToChapters()) {
(binding.recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(1, 0)
(chaptersRecycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(1, 0)
}
// Delayed in case we need to jump to chapters
binding.recycler.post {
binding.fullRecycler?.post {
updateToolbarTitleAlpha()
}
}
binding.recycler.scrollEvents()
.onEach { updateToolbarTitleAlpha() }
.launchIn(viewScope)
binding.swipeRefresh.refreshes()
.onEach {
fetchMangaInfoFromSource(manualFetch = true)
@ -376,15 +392,19 @@ class MangaController :
}
private fun updateToolbarTitleAlpha(alpha: Int? = null) {
if (binding.fullRecycler == null) {
return
}
val calculatedAlpha = when {
// Specific alpha provided
alpha != null -> alpha
// First item isn't in view, full opacity
((binding.recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() > 0) -> 255
((binding.fullRecycler!!.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() > 0) -> 255
// Based on scroll amount when first item is in view
else -> min(binding.recycler.computeVerticalScrollOffset(), 255)
else -> min(binding.fullRecycler!!.computeVerticalScrollOffset(), 255)
}
(activity as? MainActivity)?.binding?.toolbar?.setTitleTextColor(
@ -428,7 +448,7 @@ class MangaController :
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
fab.setOnClickListener(null)
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
actionFabScrollListener?.let { binding.fullRecycler?.removeOnScrollListener(it) }
actionFab = null
}
@ -1497,6 +1517,9 @@ class MangaController :
// Tracker sheet - end
private val chaptersRecycler: RecyclerView
get() = binding.fullRecycler ?: binding.chaptersRecycler!!
companion object {
const val FROM_SOURCE_EXTRA = "from_source"
const val MANGA_EXTRA = "manga"

View File

@ -30,7 +30,8 @@ import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
class MangaInfoHeaderAdapter(
private val controller: MangaController
private val controller: MangaController,
private val isTablet: Boolean
) :
RecyclerView.Adapter<MangaInfoHeaderAdapter.HeaderViewHolder>() {
@ -223,11 +224,17 @@ class MangaInfoHeaderAdapter(
*/
private fun setMangaInfo(manga: Manga, source: Source?) {
// Update full title TextView.
binding.mangaFullTitle.text = if (manga.title.isBlank()) {
with(binding.mangaFullTitle) {
if (isTablet) {
isVisible = false
} else {
text = if (manga.title.isBlank()) {
view.context.getString(R.string.unknown)
} else {
manga.title
}
}
}
// Update author TextView.
binding.mangaAuthor.text = if (manga.author.isNullOrBlank()) {

View File

@ -33,7 +33,8 @@ import reactivecircus.flowbinding.android.view.longClicks
class MangaInfoItemAdapter(
private val controller: MangaController,
private val fromSource: Boolean
private val fromSource: Boolean,
private val isTablet: Boolean
) :
RecyclerView.Adapter<MangaInfoItemAdapter.HeaderViewHolder>() {
@ -191,7 +192,7 @@ class MangaInfoItemAdapter(
.launchIn(controller.viewScope)
// Expand manga info if navigated from source listing
if (initialLoad && fromSource) {
if (initialLoad && (fromSource || isTablet)) {
toggleMangaInfo()
initialLoad = false
}

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<eu.kanade.tachiyomi.widget.RevealAnimationView
android:id="@+id/reveal_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorAccent"
android:elevation="5dp"
android:visibility="invisible" />
<eu.kanade.tachiyomi.widget.ThemedSwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/linear_recycler_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/info_recycler"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/chapters_recycler"
app:layout_constraintWidth_percent="0.4"
tools:itemCount="1"
tools:listitem="@layout/manga_info_header" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chapters_recycler"
android:layout_width="0dp"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="@dimen/fab_list_padding"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/info_recycler"
tools:listitem="@layout/chapters_item" />
<eu.kanade.tachiyomi.widget.MaterialFastScroll
android:id="@+id/fast_scroller"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_gravity="end"
app:fastScrollerBubbleEnabled="false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:visibility="visible" />
<eu.kanade.tachiyomi.widget.ActionToolbar
android:id="@+id/action_toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/chapters_recycler"
app:layout_constraintEnd_toEndOf="@+id/chapters_recycler"
app:layout_dodgeInsetEdges="bottom" />
</androidx.constraintlayout.widget.ConstraintLayout>
</eu.kanade.tachiyomi.widget.ThemedSwipeRefreshLayout>
<ImageView
android:id="@+id/expanded_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -18,11 +18,10 @@
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/toolbar_bottom"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:id="@+id/full_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"