From 914b686c8eaf3954e291355975532eb28662c38c Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Thu, 19 Aug 2021 20:10:05 +0700 Subject: [PATCH] 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). --- .../ui/reader/viewer/ReaderTransitionView.kt | 29 ++----------------- .../ui/reader/viewer/pager/PagerPageHolder.kt | 19 +++++------- .../viewer/pager/PagerTransitionHolder.kt | 4 ++- .../ui/reader/viewer/pager/PagerViewer.kt | 2 +- .../reader/viewer/pager/PagerViewerAdapter.kt | 15 ++++++++-- .../reader/viewer/webtoon/WebtoonAdapter.kt | 15 ++++++++-- .../ui/reader/viewer/webtoon/WebtoonConfig.kt | 13 ++++++--- .../viewer/webtoon/WebtoonPageHolder.kt | 4 +-- .../ui/reader/viewer/webtoon/WebtoonViewer.kt | 15 ++++++---- .../util/system/ContextExtensions.kt | 2 +- .../res/layout/reader_transition_view.xml | 5 ++-- 11 files changed, 64 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt index 570eda886c..864fff384c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt +++ b/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().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 - } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index 3d209a9d48..45a994ad28 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/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) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt index 86f9329e39..c03585d226 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt +++ b/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. diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt index c34d0a2df2..7ba1782c86 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt +++ b/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) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt index 888d83648c..6d70bdf281 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt +++ b/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) + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonAdapter.kt index 40ecc987f5..a48c900604 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonAdapter.kt +++ b/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 { - 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") diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt index 9cd3c28a3f..cc116d6558 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt +++ b/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() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt index 6e0498eb80..2fd37402f7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt +++ b/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 { gravity = Gravity.CENTER_HORIZONTAL updateMargins(top = parentHeight / 4) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt index d6572aa892..34923846af 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt +++ b/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) diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt index 8184381609..d5922fd2ac 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt +++ b/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 diff --git a/app/src/main/res/layout/reader_transition_view.xml b/app/src/main/res/layout/reader_transition_view.xml index b55a5da64e..c2cbdb1f85 100644 --- a/app/src/main/res/layout/reader_transition_view.xml +++ b/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" /> @@ -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" />