Added configuration options to e-ink page flashes (#625)
* Recommit for e-ink pref changes * Fixed state holder for flash interval * Detekt * Refactor suggested by Antsy * inverted currentDisplayRefresh check for early exit
This commit is contained in:
@@ -7,19 +7,42 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import tachiyomi.presentation.core.util.collectAsState
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@Stable
|
||||
class DisplayRefreshHost {
|
||||
|
||||
internal var currentDisplayRefresh by mutableStateOf(false)
|
||||
private val readerPreferences = Injekt.get<ReaderPreferences>()
|
||||
|
||||
internal val flashMillis = readerPreferences.flashDurationMillis()
|
||||
internal val flashMode = readerPreferences.flashColor()
|
||||
|
||||
internal val flashIntervalPref = readerPreferences.flashPageInterval()
|
||||
|
||||
// Internal State for Flash
|
||||
private var flashInterval = flashIntervalPref.get()
|
||||
private var timesCalled = 0
|
||||
|
||||
fun flash() {
|
||||
currentDisplayRefresh = true
|
||||
if (timesCalled % flashInterval == 0) {
|
||||
currentDisplayRefresh = true
|
||||
}
|
||||
timesCalled += 1
|
||||
}
|
||||
|
||||
fun setInterval(interval: Int) {
|
||||
flashInterval = interval
|
||||
timesCalled = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,18 +52,39 @@ fun DisplayRefreshHost(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val currentDisplayRefresh = hostState.currentDisplayRefresh
|
||||
val refreshDuration by hostState.flashMillis.collectAsState()
|
||||
val flashMode by hostState.flashMode.collectAsState()
|
||||
val flashInterval by hostState.flashIntervalPref.collectAsState()
|
||||
|
||||
var currentColor by remember { mutableStateOf<Color?>(null) }
|
||||
|
||||
LaunchedEffect(currentDisplayRefresh) {
|
||||
if (currentDisplayRefresh) {
|
||||
delay(1.5.seconds)
|
||||
hostState.currentDisplayRefresh = false
|
||||
if (!currentDisplayRefresh) {
|
||||
currentColor = null
|
||||
return@LaunchedEffect
|
||||
}
|
||||
|
||||
val refreshDurationHalf = refreshDuration.milliseconds / 2
|
||||
currentColor = if (flashMode == ReaderPreferences.FlashColor.BLACK) {
|
||||
Color.Black
|
||||
} else {
|
||||
Color.White
|
||||
}
|
||||
delay(refreshDurationHalf)
|
||||
if (flashMode == ReaderPreferences.FlashColor.WHITE_BLACK) {
|
||||
currentColor = Color.Black
|
||||
}
|
||||
delay(refreshDurationHalf)
|
||||
hostState.currentDisplayRefresh = false
|
||||
}
|
||||
|
||||
LaunchedEffect(flashInterval) {
|
||||
hostState.setInterval(flashInterval)
|
||||
}
|
||||
|
||||
Canvas(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
) {
|
||||
if (currentDisplayRefresh) {
|
||||
drawRect(Color.Black)
|
||||
}
|
||||
currentColor?.let { drawRect(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,13 @@ import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.CheckboxItem
|
||||
import tachiyomi.presentation.core.components.SettingsChipRow
|
||||
import tachiyomi.presentation.core.components.SliderItem
|
||||
import tachiyomi.presentation.core.i18n.pluralStringResource
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import tachiyomi.presentation.core.util.collectAsState
|
||||
|
||||
@@ -19,9 +22,27 @@ private val themes = listOf(
|
||||
MR.strings.automatic_background to 3,
|
||||
)
|
||||
|
||||
private val flashColors = listOf(
|
||||
MR.strings.pref_flash_style_black to ReaderPreferences.FlashColor.BLACK,
|
||||
MR.strings.pref_flash_style_white to ReaderPreferences.FlashColor.WHITE,
|
||||
MR.strings.pref_flash_style_white_black to ReaderPreferences.FlashColor.WHITE_BLACK,
|
||||
)
|
||||
|
||||
@Composable
|
||||
internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
|
||||
val readerTheme by screenModel.preferences.readerTheme().collectAsState()
|
||||
|
||||
val flashPageState by screenModel.preferences.flashOnPageChange().collectAsState()
|
||||
|
||||
val flashMillisPref = screenModel.preferences.flashDurationMillis()
|
||||
val flashMillis by flashMillisPref.collectAsState()
|
||||
|
||||
val flashIntervalPref = screenModel.preferences.flashPageInterval()
|
||||
val flashInterval by flashIntervalPref.collectAsState()
|
||||
|
||||
val flashColorPref = screenModel.preferences.flashColor()
|
||||
val flashColor by flashColorPref.collectAsState()
|
||||
|
||||
SettingsChipRow(MR.strings.pref_reader_theme) {
|
||||
themes.map { (labelRes, value) ->
|
||||
FilterChip(
|
||||
@@ -73,4 +94,33 @@ internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
|
||||
label = stringResource(MR.strings.pref_flash_page),
|
||||
pref = screenModel.preferences.flashOnPageChange(),
|
||||
)
|
||||
if (flashPageState) {
|
||||
SliderItem(
|
||||
value = flashMillis / ReaderPreferences.MILLI_CONVERSION,
|
||||
label = stringResource(MR.strings.pref_flash_duration),
|
||||
valueText = stringResource(MR.strings.pref_flash_duration_summary, flashMillis),
|
||||
onChange = { flashMillisPref.set(it * ReaderPreferences.MILLI_CONVERSION) },
|
||||
min = 1,
|
||||
max = 15,
|
||||
)
|
||||
SliderItem(
|
||||
value = flashInterval,
|
||||
label = stringResource(MR.strings.pref_flash_page_interval),
|
||||
valueText = pluralStringResource(MR.plurals.pref_pages, flashInterval, flashInterval),
|
||||
onChange = {
|
||||
flashIntervalPref.set(it)
|
||||
},
|
||||
min = 1,
|
||||
max = 10,
|
||||
)
|
||||
SettingsChipRow(MR.strings.pref_flash_with) {
|
||||
flashColors.map { (labelRes, value) ->
|
||||
FilterChip(
|
||||
selected = flashColor == value,
|
||||
onClick = { flashColorPref.set(value) },
|
||||
label = { Text(stringResource(labelRes)) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user