Bläddra i källkod

Add option to flash white screen on page change in reader for e-ink displays

Closes #2123
arkon 1 år sedan
förälder
incheckning
443d56f69b

+ 5 - 0
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt

@@ -64,6 +64,11 @@ object SettingsReaderScreen : SearchableSettings {
                 pref = readerPref.pageTransitions(),
                 title = stringResource(R.string.pref_page_transitions),
             ),
+            Preference.PreferenceItem.SwitchPreference(
+                pref = readerPref.flashOnPageChange(),
+                title = stringResource(R.string.pref_flash_page),
+                subtitle = stringResource(R.string.pref_flash_page_summ),
+            ),
             getDisplayGroup(readerPreferences = readerPref),
             getReadingGroup(readerPreferences = readerPref),
             getPagedGroup(readerPreferences = readerPref),

+ 45 - 0
app/src/main/java/eu/kanade/presentation/reader/DisplayRefreshHost.kt

@@ -0,0 +1,45 @@
+package eu.kanade.presentation.reader
+
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import kotlinx.coroutines.delay
+
+@Stable
+class DisplayRefreshHost {
+
+    internal var currentDisplayRefresh by mutableStateOf(false)
+
+    fun flash() {
+        currentDisplayRefresh = true
+    }
+}
+
+@Composable
+fun DisplayRefreshHost(
+    hostState: DisplayRefreshHost,
+    modifier: Modifier = Modifier,
+) {
+    val currentDisplayRefresh = hostState.currentDisplayRefresh
+    LaunchedEffect(currentDisplayRefresh) {
+        if (currentDisplayRefresh) {
+            delay(200)
+            hostState.currentDisplayRefresh = false
+        }
+    }
+
+    if (currentDisplayRefresh) {
+        Canvas(
+            modifier = modifier.fillMaxSize(),
+        ) {
+            drawRect(Color.White)
+        }
+    }
+}

+ 5 - 0
app/src/main/java/eu/kanade/presentation/reader/settings/GeneralSettingsPage.kt

@@ -68,4 +68,9 @@ internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
         label = stringResource(R.string.pref_page_transitions),
         pref = screenModel.preferences.pageTransitions(),
     )
+
+    CheckboxItem(
+        label = stringResource(R.string.pref_flash_page),
+        pref = screenModel.preferences.flashOnPageChange(),
+    )
 }

+ 12 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt

@@ -43,6 +43,7 @@ import com.google.android.material.transition.platform.MaterialContainerTransfor
 import dev.chrisbanes.insetter.applyInsetter
 import eu.kanade.domain.base.BasePreferences
 import eu.kanade.presentation.reader.BrightnessOverlay
+import eu.kanade.presentation.reader.DisplayRefreshHost
 import eu.kanade.presentation.reader.OrientationModeSelectDialog
 import eu.kanade.presentation.reader.PageIndicatorText
 import eu.kanade.presentation.reader.ReaderPageActionsDialog
@@ -122,6 +123,7 @@ class ReaderActivity : BaseActivity() {
 
     private var menuToggleToast: Toast? = null
     private var readingModeToast: Toast? = null
+    private val displayRefreshHost = DisplayRefreshHost()
 
     private val windowInsetsController by lazy { WindowInsetsControllerCompat(window, binding.root) }
 
@@ -197,6 +199,9 @@ class ReaderActivity : BaseActivity() {
                     ReaderViewModel.Event.ReloadViewerChapters -> {
                         viewModel.state.value.viewerChapters?.let(::setChapters)
                     }
+                    ReaderViewModel.Event.PageChanged -> {
+                        displayRefreshHost.flash()
+                    }
                     is ReaderViewModel.Event.SetOrientation -> {
                         setOrientation(event.orientation)
                     }
@@ -323,6 +328,7 @@ class ReaderActivity : BaseActivity() {
 
             val isHttpSource = viewModel.getSource() is HttpSource
             val isFullscreen by readerPreferences.fullscreen().collectAsState()
+            val flashOnPageChange by readerPreferences.flashOnPageChange().collectAsState()
 
             val cropBorderPaged by readerPreferences.cropBorders().collectAsState()
             val cropBorderWebtoon by readerPreferences.cropBordersWebtoon().collectAsState()
@@ -375,6 +381,12 @@ class ReaderActivity : BaseActivity() {
                 value = state.brightnessOverlayValue,
             )
 
+            if (flashOnPageChange) {
+                DisplayRefreshHost(
+                    hostState = displayRefreshHost,
+                )
+            }
+
             val onDismissRequest = viewModel::closeDialog
             when (state.dialog) {
                 is ReaderViewModel.Dialog.Loading -> {

+ 3 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt

@@ -429,6 +429,8 @@ class ReaderViewModel @JvmOverloads constructor(
         if (inDownloadRange) {
             downloadNextChapters()
         }
+
+        eventChannel.trySend(Event.PageChanged)
     }
 
     private fun downloadNextChapters() {
@@ -917,6 +919,7 @@ class ReaderViewModel @JvmOverloads constructor(
 
     sealed interface Event {
         data object ReloadViewerChapters : Event
+        data object PageChanged : Event
         data class SetOrientation(val orientation: Int) : Event
         data class SetCoverResult(val result: SetAsCoverResult) : Event
 

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt

@@ -13,6 +13,8 @@ class ReaderPreferences(
 
     fun pageTransitions() = preferenceStore.getBoolean("pref_enable_transitions_key", true)
 
+    fun flashOnPageChange() = preferenceStore.getBoolean("pref_reader_flash", false)
+
     fun doubleTapAnimSpeed() = preferenceStore.getInt("pref_double_tap_anim_speed", 500)
 
     fun showPageNumber() = preferenceStore.getBoolean("pref_show_page_number_key", true)

+ 2 - 0
i18n/src/main/res/values/strings.xml

@@ -333,6 +333,8 @@
     <string name="pref_double_tap_zoom">Double tap to zoom</string>
     <string name="pref_cutout_short">Show content in cutout area</string>
     <string name="pref_page_transitions">Animate page transitions</string>
+    <string name="pref_flash_page">Flash white on page change</string>
+    <string name="pref_flash_page_summ">Reduces ghosting on e-ink displays</string>
     <string name="pref_double_tap_anim_speed">Double tap animation speed</string>
     <string name="pref_show_page_number">Show page number</string>
     <string name="pref_show_reading_mode">Show reading mode</string>