Browse Source

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).
Ivan Iskandar 3 years ago
parent
commit
914b686c8e

+ 3 - 26
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt

@@ -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
-        }
     }
 
     /**

+ 7 - 12
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt

@@ -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.PointF
 import android.graphics.drawable.Animatable
 import android.view.GestureDetector
@@ -30,7 +31,6 @@ import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressIndicator
 import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig.ZoomType
 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 eu.kanade.tachiyomi.widget.ViewPagerAdapter
 import rx.Observable
@@ -46,9 +46,10 @@ import java.util.concurrent.TimeUnit
  */
 @SuppressLint("ViewConstructor")
 class PagerPageHolder(
+    readerThemedContext: Context,
     val viewer: PagerViewer,
     val page: ReaderPage
-) : FrameLayout(viewer.activity), ViewPagerAdapter.PositionableView {
+) : FrameLayout(readerThemedContext), ViewPagerAdapter.PositionableView {
 
     /**
      * Item that identifies this view. Needed by the adapter to not recreate views.
@@ -97,12 +98,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()
@@ -423,7 +418,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
             }
@@ -450,7 +445,7 @@ class PagerPageHolder(
         }
         decodeErrorLayout = decodeLayout
 
-        TextView(readerThemedContext).apply {
+        TextView(context).apply {
             layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
                 setMargins(margins, margins, margins, margins)
             }
@@ -460,7 +455,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)
             }
@@ -474,7 +469,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)
                 }

+ 3 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt

@@ -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.

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt

@@ -77,7 +77,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(
             object : ViewPager.SimpleOnPageChangeListener() {
                 override fun onPageSelected(position: Int) {
@@ -326,6 +325,7 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
      */
     private fun refreshAdapter() {
         val currentItem = pager.currentItem
+        adapter.refresh()
         pager.adapter = adapter
         pager.setCurrentItem(currentItem, false)
     }

+ 13 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt

@@ -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
 
@@ -32,6 +33,12 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
 
     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 and inverting the pages if the viewer
@@ -130,8 +137,8 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
      */
     override fun createView(container: ViewGroup, position: Int): View {
         return when (val item = items[position]) {
-            is ReaderPage -> PagerPageHolder(viewer, item)
-            is ChapterTransition -> PagerTransitionHolder(viewer, item)
+            is ReaderPage -> PagerPageHolder(readerThemedContext, viewer, item)
+            is ChapterTransition -> PagerTransitionHolder(readerThemedContext, viewer, item)
             else -> throw NotImplementedError("Holder for ${item.javaClass} not implemented")
         }
     }
@@ -188,4 +195,8 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
         items.removeAll(insertPages)
         notifyDataSetChanged()
     }
+
+    fun refresh() {
+        readerThemedContext = viewer.activity.createReaderThemeContext(viewer.config.theme)
+    }
 }

+ 13 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonAdapter.kt

@@ -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")

+ 9 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt

@@ -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()
 
     init {
         preferences.cropBordersWebtoon()
@@ -54,8 +56,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)
     }
 
     override var navigator: ViewerNavigation = defaultNavigation()

+ 1 - 3
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt

@@ -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)

+ 10 - 5
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt

@@ -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
      */
     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)
@@ -338,6 +342,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)

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt

@@ -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

+ 3 - 2
app/src/main/res/layout/reader_transition_view.xml

@@ -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>