mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-11-05 18:30:59 +01:00
Adds option to dim the screensaver (#1834)
## Description Adds a new sceensaver setting to add dimming. A larger value is darker This works with or without the in-app screensaver. If dimming is enabled, the screen be will be dimmed after inactivity. If both dimming and the in-app screensaver are enabled, the screensaver will show dimmed after inactivity. ### Related issues Closes #1179 ### Testing Emulator ## Screenshots N/A, it's just darker ## AI or LLM usage None
This commit is contained in:
parent
197af604d6
commit
c4264a3263
8 changed files with 144 additions and 9 deletions
|
|
@ -17,6 +17,7 @@ import androidx.compose.runtime.rememberUpdatedState
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.Lifecycle
|
||||
|
|
@ -136,12 +137,26 @@ fun MainContent(
|
|||
val screenSaverState by screensaverService.state.collectAsState()
|
||||
if (screenSaverState.enabled || screenSaverState.enabledTemp) {
|
||||
AnimatedVisibility(
|
||||
screenSaverState.show,
|
||||
Modifier.fillMaxSize(),
|
||||
visible = screenSaverState.show,
|
||||
enter = ScreensaverService.enterAnimation,
|
||||
exit = ScreensaverService.exitAnimation,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
AppScreensaver(userPreferences.appPreferences, Modifier.fillMaxSize())
|
||||
}
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = screenSaverState.showDim || (screenSaverState.dimEnabled && screenSaverState.show),
|
||||
enter = ScreensaverService.enterAnimation,
|
||||
exit = ScreensaverService.exitAnimation,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
val alpha =
|
||||
userPreferences.appPreferences.interfacePreferences.screensaverPreference.dimPercent / 100f
|
||||
Box(
|
||||
Modifier.background(Color.Black.copy(alpha = alpha)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.lifecycle.Lifecycle
|
||||
|
|
@ -94,6 +95,14 @@ class WholphinDreamService :
|
|||
preferencesDataStore.data.collectLatest { prefs = it }
|
||||
}
|
||||
prefs?.let { prefs ->
|
||||
val alpha =
|
||||
prefs.interfacePreferences.screensaverPreference.run {
|
||||
if (dimEnabled) {
|
||||
dimPercent / 100f
|
||||
} else {
|
||||
1f
|
||||
}
|
||||
}
|
||||
CoilConfig(
|
||||
prefs = prefs,
|
||||
okHttpClient = okHttpClient,
|
||||
|
|
@ -109,7 +118,10 @@ class WholphinDreamService :
|
|||
showClock = screensaverPrefs.showClock,
|
||||
duration = screensaverPrefs.duration.milliseconds,
|
||||
animate = screensaverPrefs.animate,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.alpha(alpha = alpha),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1338,6 +1338,14 @@ val screensaverPreferences =
|
|||
ScreensaverPreference.Start,
|
||||
),
|
||||
),
|
||||
PreferenceGroup(
|
||||
title = R.string.dim_screen,
|
||||
preferences =
|
||||
listOf(
|
||||
ScreensaverPreference.DimToggle,
|
||||
ScreensaverPreference.DimPercentage,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
data class AppSwitchPreference<Pref>(
|
||||
|
|
|
|||
|
|
@ -176,6 +176,37 @@ object ScreensaverPreference {
|
|||
},
|
||||
)
|
||||
|
||||
val DimToggle =
|
||||
AppSwitchPreference<AppPreferences>(
|
||||
title = R.string.dim_after_delay,
|
||||
defaultValue = AppPreference.ShowClock.defaultValue,
|
||||
getter = { it.interfacePreferences.screensaverPreference.dimEnabled },
|
||||
setter = { prefs, value ->
|
||||
prefs.updateScreensaverPreferences { dimEnabled = value }
|
||||
},
|
||||
summaryOn = R.string.yes,
|
||||
summaryOff = R.string.no,
|
||||
)
|
||||
|
||||
val DimPercentage =
|
||||
AppSliderPreference<AppPreferences>(
|
||||
title = R.string.dim_percentage,
|
||||
defaultValue = 75,
|
||||
min = 0,
|
||||
max = 95,
|
||||
interval = 5,
|
||||
getter = {
|
||||
it.interfacePreferences.screensaverPreference.dimPercent
|
||||
.toLong()
|
||||
},
|
||||
setter = { prefs, value ->
|
||||
prefs.updateScreensaverPreferences { dimPercent = value.toInt() }
|
||||
},
|
||||
summarizer = { value ->
|
||||
value?.let { "$value%" }
|
||||
},
|
||||
)
|
||||
|
||||
val Start =
|
||||
AppClickablePreference<AppPreferences>(
|
||||
title = R.string.start_screensaver,
|
||||
|
|
|
|||
|
|
@ -418,5 +418,13 @@ class AppUpgradeHandler
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (previous.isEqualOrBefore(Version.fromString("1.0.6-0-g0"))) {
|
||||
appPreferences.updateData {
|
||||
it.updateScreensaverPreferences {
|
||||
dimPercent = ScreensaverPreference.DimPercentage.defaultValue.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package com.github.damontecres.wholphin.services
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import coil3.imageLoader
|
||||
import coil3.request.ImageRequest
|
||||
import com.github.damontecres.wholphin.services.hilt.DefaultCoroutineScope
|
||||
|
|
@ -57,6 +60,7 @@ class ScreensaverService
|
|||
val keepScreenOn = MutableStateFlow(false)
|
||||
|
||||
private var waitJob: Job? = null
|
||||
private var dimJob: Job? = null
|
||||
|
||||
init {
|
||||
userPreferencesService.flow
|
||||
|
|
@ -65,7 +69,14 @@ class ScreensaverService
|
|||
val enabled =
|
||||
prefs.appPreferences.interfacePreferences.screensaverPreference.enabled
|
||||
keepScreenOnInternal(enabled)
|
||||
ScreensaverState(enabled, false, false, false)
|
||||
ScreensaverState(
|
||||
enabled = enabled,
|
||||
enabledTemp = false,
|
||||
active = false,
|
||||
paused = false,
|
||||
dimEnabled = prefs.appPreferences.interfacePreferences.screensaverPreference.dimEnabled,
|
||||
dimActive = false,
|
||||
)
|
||||
}
|
||||
}.launchIn(scope)
|
||||
}
|
||||
|
|
@ -74,12 +85,16 @@ class ScreensaverService
|
|||
* Reset the timer before showing the in-app screensaver
|
||||
*/
|
||||
fun pulse() {
|
||||
Timber.v("state=%s", _state.value)
|
||||
waitJob?.cancel()
|
||||
if (_state.value.enabled) {
|
||||
// Timber.v("pulse")
|
||||
_state.update {
|
||||
if (!it.active) {
|
||||
it.copy(active = false)
|
||||
it.copy(
|
||||
active = false,
|
||||
dimActive = false,
|
||||
)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
|
|
@ -94,7 +109,30 @@ class ScreensaverService
|
|||
.appPreferences.interfacePreferences.screensaverPreference.startDelay.milliseconds
|
||||
delay(startDelay)
|
||||
_state.update {
|
||||
it.copy(active = true)
|
||||
it.copy(
|
||||
active = true,
|
||||
dimActive = it.dimEnabled,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dimJob?.cancel()
|
||||
if (_state.value.dimEnabled) {
|
||||
_state.update {
|
||||
it.copy(dimActive = false)
|
||||
}
|
||||
if (!_state.value.paused) {
|
||||
dimJob =
|
||||
scope.launch(ExceptionHandler()) {
|
||||
val startDelay =
|
||||
userPreferencesService
|
||||
.getCurrent()
|
||||
.appPreferences.interfacePreferences.screensaverPreference.startDelay.milliseconds
|
||||
delay(startDelay)
|
||||
Timber.v("state dim=%s", _state.value)
|
||||
_state.update {
|
||||
it.copy(dimActive = !_state.value.paused)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -109,6 +147,7 @@ class ScreensaverService
|
|||
it.copy(
|
||||
enabledTemp = true,
|
||||
active = true,
|
||||
dimActive = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -121,9 +160,13 @@ class ScreensaverService
|
|||
it.copy(
|
||||
enabledTemp = false,
|
||||
active = false,
|
||||
dimActive = false,
|
||||
)
|
||||
}
|
||||
if (cancelJob) waitJob?.cancel()
|
||||
if (cancelJob) {
|
||||
waitJob?.cancel()
|
||||
dimJob?.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -131,12 +174,16 @@ class ScreensaverService
|
|||
*/
|
||||
fun keepScreenOn(keep: Boolean) {
|
||||
scope.launchDefault {
|
||||
val screensaverEnabled = _state.value.enabled
|
||||
val screensaverEnabled = _state.value.run { enabled || dimEnabled }
|
||||
Timber.d("Keep screen on: %s, screensaverEnabled=%s", keep, screensaverEnabled)
|
||||
if (screensaverEnabled) {
|
||||
// Page is requesting to keep screen on, so we don't wait to show the screensaver
|
||||
_state.update {
|
||||
it.copy(active = false, paused = keep)
|
||||
it.copy(
|
||||
active = false,
|
||||
dimActive = false,
|
||||
paused = keep,
|
||||
)
|
||||
}
|
||||
if (!keep) {
|
||||
pulse()
|
||||
|
|
@ -245,6 +292,11 @@ class ScreensaverService
|
|||
)
|
||||
return ApiRequestPager(api, request, GetItemsRequestHandler, scope).init()
|
||||
}
|
||||
|
||||
companion object {
|
||||
val enterAnimation = fadeIn(animationSpec = tween(durationMillis = 1000))
|
||||
val exitAnimation = fadeOut(animationSpec = tween(durationMillis = 500))
|
||||
}
|
||||
}
|
||||
|
||||
data class ScreensaverState(
|
||||
|
|
@ -252,6 +304,10 @@ data class ScreensaverState(
|
|||
val enabledTemp: Boolean,
|
||||
val active: Boolean,
|
||||
val paused: Boolean,
|
||||
val dimEnabled: Boolean = false,
|
||||
val dimActive: Boolean = false,
|
||||
) {
|
||||
val show get() = (enabled || enabledTemp) && active && !paused
|
||||
|
||||
val showDim get() = dimEnabled && dimActive && !paused
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,6 +174,8 @@ message ScreensaverPreferences{
|
|||
bool enabled = 5;
|
||||
repeated string item_types = 6;
|
||||
bool show_clock = 7;
|
||||
bool dim_enabled = 8;
|
||||
int32 dim_percent = 9;
|
||||
}
|
||||
|
||||
message SearchPreferences {
|
||||
|
|
|
|||
|
|
@ -910,4 +910,7 @@
|
|||
<string name="audio_books">Audio books</string>
|
||||
<string name="server_version_not_supported">Server version not supported</string>
|
||||
<string name="appears_on">Appears on</string>
|
||||
<string name="dim_after_delay">Dim screen after delay</string>
|
||||
<string name="dim_percentage">Dim percentage</string>
|
||||
<string name="dim_screen">Dim screen</string>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue