Add option to flash white screen on page change in reader for e-ink displays
Closes #2123
This commit is contained in:
parent
7457a18aee
commit
443d56f69b
7 changed files with 74 additions and 0 deletions
|
@ -64,6 +64,11 @@ object SettingsReaderScreen : SearchableSettings {
|
||||||
pref = readerPref.pageTransitions(),
|
pref = readerPref.pageTransitions(),
|
||||||
title = stringResource(R.string.pref_page_transitions),
|
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),
|
getDisplayGroup(readerPreferences = readerPref),
|
||||||
getReadingGroup(readerPreferences = readerPref),
|
getReadingGroup(readerPreferences = readerPref),
|
||||||
getPagedGroup(readerPreferences = readerPref),
|
getPagedGroup(readerPreferences = readerPref),
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,4 +68,9 @@ internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
|
||||||
label = stringResource(R.string.pref_page_transitions),
|
label = stringResource(R.string.pref_page_transitions),
|
||||||
pref = screenModel.preferences.pageTransitions(),
|
pref = screenModel.preferences.pageTransitions(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CheckboxItem(
|
||||||
|
label = stringResource(R.string.pref_flash_page),
|
||||||
|
pref = screenModel.preferences.flashOnPageChange(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ import com.google.android.material.transition.platform.MaterialContainerTransfor
|
||||||
import dev.chrisbanes.insetter.applyInsetter
|
import dev.chrisbanes.insetter.applyInsetter
|
||||||
import eu.kanade.domain.base.BasePreferences
|
import eu.kanade.domain.base.BasePreferences
|
||||||
import eu.kanade.presentation.reader.BrightnessOverlay
|
import eu.kanade.presentation.reader.BrightnessOverlay
|
||||||
|
import eu.kanade.presentation.reader.DisplayRefreshHost
|
||||||
import eu.kanade.presentation.reader.OrientationModeSelectDialog
|
import eu.kanade.presentation.reader.OrientationModeSelectDialog
|
||||||
import eu.kanade.presentation.reader.PageIndicatorText
|
import eu.kanade.presentation.reader.PageIndicatorText
|
||||||
import eu.kanade.presentation.reader.ReaderPageActionsDialog
|
import eu.kanade.presentation.reader.ReaderPageActionsDialog
|
||||||
|
@ -122,6 +123,7 @@ class ReaderActivity : BaseActivity() {
|
||||||
|
|
||||||
private var menuToggleToast: Toast? = null
|
private var menuToggleToast: Toast? = null
|
||||||
private var readingModeToast: Toast? = null
|
private var readingModeToast: Toast? = null
|
||||||
|
private val displayRefreshHost = DisplayRefreshHost()
|
||||||
|
|
||||||
private val windowInsetsController by lazy { WindowInsetsControllerCompat(window, binding.root) }
|
private val windowInsetsController by lazy { WindowInsetsControllerCompat(window, binding.root) }
|
||||||
|
|
||||||
|
@ -197,6 +199,9 @@ class ReaderActivity : BaseActivity() {
|
||||||
ReaderViewModel.Event.ReloadViewerChapters -> {
|
ReaderViewModel.Event.ReloadViewerChapters -> {
|
||||||
viewModel.state.value.viewerChapters?.let(::setChapters)
|
viewModel.state.value.viewerChapters?.let(::setChapters)
|
||||||
}
|
}
|
||||||
|
ReaderViewModel.Event.PageChanged -> {
|
||||||
|
displayRefreshHost.flash()
|
||||||
|
}
|
||||||
is ReaderViewModel.Event.SetOrientation -> {
|
is ReaderViewModel.Event.SetOrientation -> {
|
||||||
setOrientation(event.orientation)
|
setOrientation(event.orientation)
|
||||||
}
|
}
|
||||||
|
@ -323,6 +328,7 @@ class ReaderActivity : BaseActivity() {
|
||||||
|
|
||||||
val isHttpSource = viewModel.getSource() is HttpSource
|
val isHttpSource = viewModel.getSource() is HttpSource
|
||||||
val isFullscreen by readerPreferences.fullscreen().collectAsState()
|
val isFullscreen by readerPreferences.fullscreen().collectAsState()
|
||||||
|
val flashOnPageChange by readerPreferences.flashOnPageChange().collectAsState()
|
||||||
|
|
||||||
val cropBorderPaged by readerPreferences.cropBorders().collectAsState()
|
val cropBorderPaged by readerPreferences.cropBorders().collectAsState()
|
||||||
val cropBorderWebtoon by readerPreferences.cropBordersWebtoon().collectAsState()
|
val cropBorderWebtoon by readerPreferences.cropBordersWebtoon().collectAsState()
|
||||||
|
@ -375,6 +381,12 @@ class ReaderActivity : BaseActivity() {
|
||||||
value = state.brightnessOverlayValue,
|
value = state.brightnessOverlayValue,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (flashOnPageChange) {
|
||||||
|
DisplayRefreshHost(
|
||||||
|
hostState = displayRefreshHost,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val onDismissRequest = viewModel::closeDialog
|
val onDismissRequest = viewModel::closeDialog
|
||||||
when (state.dialog) {
|
when (state.dialog) {
|
||||||
is ReaderViewModel.Dialog.Loading -> {
|
is ReaderViewModel.Dialog.Loading -> {
|
||||||
|
|
|
@ -429,6 +429,8 @@ class ReaderViewModel @JvmOverloads constructor(
|
||||||
if (inDownloadRange) {
|
if (inDownloadRange) {
|
||||||
downloadNextChapters()
|
downloadNextChapters()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventChannel.trySend(Event.PageChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun downloadNextChapters() {
|
private fun downloadNextChapters() {
|
||||||
|
@ -917,6 +919,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
||||||
|
|
||||||
sealed interface Event {
|
sealed interface Event {
|
||||||
data object ReloadViewerChapters : Event
|
data object ReloadViewerChapters : Event
|
||||||
|
data object PageChanged : Event
|
||||||
data class SetOrientation(val orientation: Int) : Event
|
data class SetOrientation(val orientation: Int) : Event
|
||||||
data class SetCoverResult(val result: SetAsCoverResult) : Event
|
data class SetCoverResult(val result: SetAsCoverResult) : Event
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ class ReaderPreferences(
|
||||||
|
|
||||||
fun pageTransitions() = preferenceStore.getBoolean("pref_enable_transitions_key", true)
|
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 doubleTapAnimSpeed() = preferenceStore.getInt("pref_double_tap_anim_speed", 500)
|
||||||
|
|
||||||
fun showPageNumber() = preferenceStore.getBoolean("pref_show_page_number_key", true)
|
fun showPageNumber() = preferenceStore.getBoolean("pref_show_page_number_key", true)
|
||||||
|
|
|
@ -333,6 +333,8 @@
|
||||||
<string name="pref_double_tap_zoom">Double tap to zoom</string>
|
<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_cutout_short">Show content in cutout area</string>
|
||||||
<string name="pref_page_transitions">Animate page transitions</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_double_tap_anim_speed">Double tap animation speed</string>
|
||||||
<string name="pref_show_page_number">Show page number</string>
|
<string name="pref_show_page_number">Show page number</string>
|
||||||
<string name="pref_show_reading_mode">Show reading mode</string>
|
<string name="pref_show_reading_mode">Show reading mode</string>
|
||||||
|
|
Reference in a new issue