ReaderTransitionView: Use context theme color for texts (#5738)

* Put themed reader context in adapter

This avoids creating themed context everytime the page holder is created, this
also allows the transition view to use the same themed context.

* Check against app night mode to create themed reader context

* ReaderTransitionView: Use context theme color for texts

The whole reader will need to be recreated when changing reader background while
webtoon mode is used, because recreating just the RecyclerView without messing
up the scroll position is impossible (I hope I just missed something).

(cherry picked from commit 914b686c8eaf3954e291355975532eb28662c38c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt
This commit is contained in:
Ivan Iskandar 2021-08-19 20:10:05 +07:00 committed by Jobobby04
parent 6aa59325d0
commit 32fa99377d
11 changed files with 64 additions and 60 deletions

View File

@ -8,22 +8,19 @@ import androidx.core.text.bold
import androidx.core.text.buildSpannedString
import androidx.core.view.isVisible
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.ReaderTransitionViewBinding
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import eu.kanade.tachiyomi.util.system.isNightMode
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
LinearLayout(context, attrs) {
private val binding: ReaderTransitionViewBinding
private val binding: ReaderTransitionViewBinding =
ReaderTransitionViewBinding.inflate(LayoutInflater.from(context), this, true)
init {
binding = ReaderTransitionViewBinding.inflate(LayoutInflater.from(context), this, true)
layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
}
fun bind(transition: ChapterTransition) {
when (transition) {
is ChapterTransition.Prev -> bindPrevChapterTransition(transition)
@ -31,26 +28,6 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At
}
missingChapterWarning(transition)
val color = when (Injekt.get<PreferencesHelper>().readerTheme().get()) {
0 -> context.getColor(android.R.color.black)
3 -> context.getColor(automaticTextColor())
else -> context.getColor(android.R.color.white)
}
listOf(binding.upperText, binding.warningText, binding.lowerText).forEach {
it.setTextColor(color)
}
}
/**
* Picks text color for [ReaderActivity] based on light/dark theme preference
*/
private fun automaticTextColor(): Int {
return if (context.isNightMode()) {
android.R.color.white
} else {
android.R.color.black
}
}
/**

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager
import android.annotation.SuppressLint
import android.app.ActionBar
import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.PointF
import android.graphics.drawable.Animatable
@ -32,7 +33,6 @@ import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig.ZoomType
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.createReaderThemeContext
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.widget.ViewPagerAdapter
import kotlinx.coroutines.CoroutineScope
@ -53,10 +53,11 @@ import kotlin.math.roundToInt
*/
@SuppressLint("ViewConstructor")
class PagerPageHolder(
readerThemedContext: Context,
val viewer: PagerViewer,
val page: ReaderPage,
private var extraPage: ReaderPage? = null
) : FrameLayout(viewer.activity), ViewPagerAdapter.PositionableView {
) : FrameLayout(readerThemedContext), ViewPagerAdapter.PositionableView {
/**
* Item that identifies this view. Needed by the adapter to not recreate views.
@ -115,12 +116,6 @@ class PagerPageHolder(
*/
private var readImageHeaderSubscription: Subscription? = null
/**
* Context that has been wrapped to use the correct theme values based on the
* current app theme and reader background color
*/
private val readerThemedContext = context.createReaderThemeContext(viewer.config.theme)
val stateChangedListener = object : SubsamplingScaleImageView.OnStateChangedListener {
override fun onScaleChanged(newScale: Float, origin: Int) {
viewer.activity.hideMenu()
@ -596,7 +591,7 @@ class PagerPageHolder(
private fun initRetryButton(): PagerButton {
if (retryButton != null) return retryButton!!
retryButton = PagerButton(readerThemedContext, viewer).apply {
retryButton = PagerButton(context, viewer).apply {
layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
gravity = Gravity.CENTER
}
@ -623,7 +618,7 @@ class PagerPageHolder(
}
decodeErrorLayout = decodeLayout
TextView(readerThemedContext).apply {
TextView(context).apply {
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
setMargins(margins, margins, margins, margins)
}
@ -633,7 +628,7 @@ class PagerPageHolder(
decodeLayout.addView(this)
}
PagerButton(readerThemedContext, viewer).apply {
PagerButton(context, viewer).apply {
layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
setMargins(margins, margins, margins, margins)
}
@ -647,7 +642,7 @@ class PagerPageHolder(
val imageUrl = page.imageUrl
if (imageUrl.orEmpty().startsWith("http", true)) {
PagerButton(readerThemedContext, viewer).apply {
PagerButton(context, viewer).apply {
layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
setMargins(margins, margins, margins, margins)
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.ui.reader.viewer.pager
import android.annotation.SuppressLint
import android.content.Context
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
@ -23,9 +24,10 @@ import rx.android.schedulers.AndroidSchedulers
*/
@SuppressLint("ViewConstructor")
class PagerTransitionHolder(
readerThemedContext: Context,
val viewer: PagerViewer,
val transition: ChapterTransition
) : LinearLayout(viewer.activity), ViewPagerAdapter.PositionableView {
) : LinearLayout(readerThemedContext), ViewPagerAdapter.PositionableView {
/**
* Item that identifies this view. Needed by the adapter to not recreate views.

View File

@ -90,7 +90,6 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
pager.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
pager.offscreenPageLimit = 1
pager.id = R.id.reader_pager
pager.adapter = adapter
pager.addOnPageChangeListener(
// SY -->
pagerListener
@ -344,6 +343,7 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
*/
private fun refreshAdapter() {
val currentItem = pager.currentItem
adapter.refresh()
pager.adapter = adapter
pager.setCurrentItem(currentItem, false)
}

View File

@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
import eu.kanade.tachiyomi.ui.reader.viewer.hasMissingChapters
import eu.kanade.tachiyomi.util.system.createReaderThemeContext
import eu.kanade.tachiyomi.widget.ViewPagerAdapter
import timber.log.Timber
import kotlin.math.max
@ -47,6 +48,12 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
private var doubledUp = viewer.config.doublePages
// SY <--
/**
* Context that has been wrapped to use the correct theme values based on the
* current app theme and reader background color
*/
private var readerThemedContext = viewer.activity.createReaderThemeContext(viewer.config.theme)
/**
* Updates this adapter with the given [chapters]. It handles setting a few pages of the
* next/previous chapter to allow seamless transitions and inverting the pages if the viewer
@ -152,8 +159,8 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
val item = joinedItems[position].first
val item2 = joinedItems[position].second
return when (item) {
is ReaderPage -> PagerPageHolder(viewer, item, item2 as? ReaderPage)
is ChapterTransition -> PagerTransitionHolder(viewer, item)
is ReaderPage -> PagerPageHolder(readerThemedContext, viewer, item, item2 as? ReaderPage)
is ChapterTransition -> PagerTransitionHolder(readerThemedContext, viewer, item)
else -> throw NotImplementedError("Holder for ${item.javaClass} not implemented")
}
}
@ -211,8 +218,11 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
notifyDataSetChanged()
}
// SY -->
fun refresh() {
readerThemedContext = viewer.activity.createReaderThemeContext(viewer.config.theme)
}
// SY -->
private fun setJoinedItems(useSecondPage: Boolean = false) {
val oldCurrent = joinedItems.getOrNull(viewer.pager.currentItem)
if (!viewer.config.doublePages) {

View File

@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
import eu.kanade.tachiyomi.ui.reader.viewer.hasMissingChapters
import eu.kanade.tachiyomi.util.system.createReaderThemeContext
/**
* RecyclerView Adapter used by this [viewer] to where [ViewerChapters] updates are posted.
@ -24,6 +25,12 @@ class WebtoonAdapter(val viewer: WebtoonViewer) : RecyclerView.Adapter<RecyclerV
var currentChapter: ReaderChapter? = null
/**
* Context that has been wrapped to use the correct theme values based on the
* current app theme and reader background color
*/
private var readerThemedContext = viewer.activity.createReaderThemeContext(viewer.config.theme)
/**
* Updates this adapter with the given [chapters]. It handles setting a few pages of the
* next/previous chapter to allow seamless transitions.
@ -77,6 +84,10 @@ class WebtoonAdapter(val viewer: WebtoonViewer) : RecyclerView.Adapter<RecyclerV
result.dispatchUpdatesTo(this)
}
fun refresh() {
readerThemedContext = viewer.activity.createReaderThemeContext(viewer.config.theme)
}
/**
* Returns the amount of items of the adapter.
*/
@ -101,11 +112,11 @@ class WebtoonAdapter(val viewer: WebtoonViewer) : RecyclerView.Adapter<RecyclerV
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
PAGE_VIEW -> {
val view = FrameLayout(parent.context)
val view = FrameLayout(readerThemedContext)
WebtoonPageHolder(view, viewer)
}
TRANSITION_VIEW -> {
val view = LinearLayout(parent.context)
val view = LinearLayout(readerThemedContext)
WebtoonTransitionHolder(view, viewer)
}
else -> error("Unknown view type")

View File

@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.ui.reader.viewer.navigation.KindlishNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.LNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.RightAndLeftNavigation
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@ -22,14 +23,15 @@ class WebtoonConfig(
preferences: PreferencesHelper = Injekt.get()
) : ViewerConfig(preferences, scope) {
var themeChangedListener: (() -> Unit)? = null
var imageCropBorders = false
private set
var sidePadding = 0
private set
var theme = preferences.readerTheme().get()
private set
val theme = preferences.readerTheme().get()
// SY -->
var usePageTransitions = false
@ -66,8 +68,11 @@ class WebtoonConfig(
preferences.dualPageInvertWebtoon()
.register({ dualPageInvert = it }, { imagePropertyChangedListener?.invoke() })
preferences.readerTheme()
.register({ theme = it }, { imagePropertyChangedListener?.invoke() })
preferences.readerTheme().asFlow()
.drop(1)
.distinctUntilChanged()
.onEach { themeChangedListener?.invoke() }
.launchIn(scope)
// SY -->
preferences.webtoonEnableZoomOut()

View File

@ -27,7 +27,6 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressIndicator
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.createReaderThemeContext
import eu.kanade.tachiyomi.util.system.dpToPx
import rx.Observable
import rx.Subscription
@ -346,8 +345,7 @@ class WebtoonPageHolder(
progressContainer = FrameLayout(context)
frame.addView(progressContainer, MATCH_PARENT, parentHeight)
val indicatorContext = context.createReaderThemeContext(viewer.config.theme)
val progress = ReaderProgressIndicator(indicatorContext).apply {
val progress = ReaderProgressIndicator(context).apply {
updateLayoutParams<FrameLayout.LayoutParams> {
gravity = Gravity.CENTER_HORIZONTAL
updateMargins(top = parentHeight / 4)

View File

@ -48,6 +48,11 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
*/
private val layoutManager = WebtoonLayoutManager(activity)
/**
* Configuration used by this viewer, like allow taps, or crop image borders.
*/
val config = WebtoonConfig(scope)
/**
* Adapter of the recycler view.
*/
@ -63,11 +68,6 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
*/
/* [EXH] private */ var currentPage: Any? = null
/**
* Configuration used by this viewer, like allow taps, or crop image borders.
*/
val config = WebtoonConfig(scope)
/**
* Subscriptions to keep while this viewer is used.
*/
@ -138,6 +138,10 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
refreshAdapter()
}
config.themeChangedListener = {
activity.recreate()
}
config.navigationModeChangedListener = {
val showOnStart = config.navigationOverlayOnStart || config.forceNavigationOverlay
activity.binding.navigationOverlay.setNavigation(config.navigator, config.tappingEnabled, showOnStart)
@ -365,6 +369,7 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
*/
private fun refreshAdapter() {
val position = layoutManager.findLastEndVisibleItemPosition()
adapter.refresh()
adapter.notifyItemRangeChanged(
max(0, position - 3),
min(position + 3, adapter.itemCount - 1)

View File

@ -310,7 +310,7 @@ fun Context.isNightMode(): Boolean {
fun Context.createReaderThemeContext(readerThemeSelected: Int): Context {
val isDarkBackground = when (readerThemeSelected) {
1, 2 -> true // Black, Gray
3 -> isNightMode() // Automatic bg uses activity background by default
3 -> applicationContext.isNightMode() // Automatic bg uses activity background by default
else -> false // White
}
val expected = if (isDarkBackground) Configuration.UI_MODE_NIGHT_YES else Configuration.UI_MODE_NIGHT_NO

View File

@ -12,7 +12,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:textSize="17.5sp"
android:textAppearance="?attr/textAppearanceSubtitle1"
tools:text="Top" />
<LinearLayout
@ -35,6 +35,7 @@
android:id="@+id/warning_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?attr/textAppearanceSubtitle1"
tools:text="Warning" />
</LinearLayout>
@ -43,7 +44,7 @@
android:id="@+id/lower_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17.5sp"
android:textAppearance="?attr/textAppearanceSubtitle1"
tools:text="Bottom" />
</LinearLayout>