From 80d9810e4cc9d02faf402e11b234d66640b5c23e Mon Sep 17 00:00:00 2001 From: Isaac Serrano Date: Sun, 20 Sep 2026 14:08:21 -0700 Subject: [PATCH] feat(aod): add new aod wallpaper timeout and custom section --- .../data/repository/SettingsRepository.kt | 27 ++++++++++-- .../handlers/AodWallpaperOverlayHandler.kt | 26 ++++++++++-- .../tiles/ScreenOffAccessibilityService.kt | 1 + .../display/AodWallpaperSettingsUI.kt | 42 +++++++++++++++---- .../essentials/viewmodels/MainViewModel.kt | 24 ++++++++--- app/src/main/res/values/strings.xml | 5 +++ 6 files changed, 104 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/sameerasw/essentials/data/repository/SettingsRepository.kt b/app/src/main/java/com/sameerasw/essentials/data/repository/SettingsRepository.kt index 49d4c43df..f120e0da5 100644 --- a/app/src/main/java/com/sameerasw/essentials/data/repository/SettingsRepository.kt +++ b/app/src/main/java/com/sameerasw/essentials/data/repository/SettingsRepository.kt @@ -361,6 +361,7 @@ class SettingsRepository( const val KEY_AOD_WALLPAPER_ENABLED = "aod_wallpaper_enabled" const val KEY_AOD_WALLPAPER_OPACITY = "aod_wallpaper_opacity" const val KEY_AOD_WALLPAPER_TIMEOUT = "aod_wallpaper_timeout" + const val KEY_AOD_WALLPAPER_CUSTOM_TIMEOUT = "aod_wallpaper_custom_timeout" const val KEY_AOD_WALLPAPER_BLUR = "aod_wallpaper_blur" const val KEY_AOD_WALLPAPER_VIGNETTE = "aod_wallpaper_vignette" const val KEY_AOD_WALLPAPER_BLACK_THRESHOLD = "aod_wallpaper_black_threshold" @@ -3200,10 +3201,30 @@ class SettingsRepository( fun setAodWallpaperOpacity(value: Float) = putFloat(KEY_AOD_WALLPAPER_OPACITY, value) - // timeout in minutes; 0 = Never, default = 3 - fun getAodWallpaperTimeout(): Int = getInt(KEY_AOD_WALLPAPER_TIMEOUT, 3) + // timeout as string (e.g., "never", "5s", "15s", "30s", "1m", "3m", "5m", "10m"); default = "3m" + fun getAodWallpaperTimeout(): String { + return try { + getString(KEY_AOD_WALLPAPER_TIMEOUT, "3m") ?: "3m" + } catch (e: Exception) { + val oldInt = getInt(KEY_AOD_WALLPAPER_TIMEOUT, 3) + val strVal = when (oldInt) { + 0 -> "never" + 1 -> "1m" + 3 -> "3m" + 5 -> "5m" + 10 -> "10m" + else -> "${oldInt}m" + } + setAodWallpaperTimeout(strVal) + strVal + } + } + + fun setAodWallpaperTimeout(value: String) = putString(KEY_AOD_WALLPAPER_TIMEOUT, value) + + fun getAodWallpaperCustomTimeout(): Float = getFloat(KEY_AOD_WALLPAPER_CUSTOM_TIMEOUT, 30f) - fun setAodWallpaperTimeout(value: Int) = putInt(KEY_AOD_WALLPAPER_TIMEOUT, value) + fun setAodWallpaperCustomTimeout(value: Float) = putFloat(KEY_AOD_WALLPAPER_CUSTOM_TIMEOUT, value) // blur 0-25 fun getAodWallpaperBlur(): Float = getFloat(KEY_AOD_WALLPAPER_BLUR, 0f) diff --git a/app/src/main/java/com/sameerasw/essentials/services/handlers/AodWallpaperOverlayHandler.kt b/app/src/main/java/com/sameerasw/essentials/services/handlers/AodWallpaperOverlayHandler.kt index 3805e635f..ca2a7d844 100644 --- a/app/src/main/java/com/sameerasw/essentials/services/handlers/AodWallpaperOverlayHandler.kt +++ b/app/src/main/java/com/sameerasw/essentials/services/handlers/AodWallpaperOverlayHandler.kt @@ -542,9 +542,29 @@ class AodWallpaperOverlayHandler( return } - val timeoutMinutes = prefs.getInt(SettingsRepository.KEY_AOD_WALLPAPER_TIMEOUT, 3) - if (timeoutMinutes > 0) { - handler.postDelayed(timeoutRunnable, timeoutMinutes * 60_000L) + val timeoutStr = try { + prefs.getString(SettingsRepository.KEY_AOD_WALLPAPER_TIMEOUT, "3m") ?: "3m" + } catch (e: Exception) { + val oldInt = prefs.getInt(SettingsRepository.KEY_AOD_WALLPAPER_TIMEOUT, 3) + if (oldInt == 0) "never" else "${oldInt}m" + } + + val millis = parseTimeoutToMillis(timeoutStr) + if (millis > 0L) { + handler.postDelayed(timeoutRunnable, millis) + } + } + + private fun parseTimeoutToMillis(timeout: String): Long { + return when { + timeout == "never" || timeout == "0" -> 0L + timeout == "custom" -> { + val customSecs = prefs.getFloat(SettingsRepository.KEY_AOD_WALLPAPER_CUSTOM_TIMEOUT, 30f).toLong() + customSecs * 1000L + } + timeout.endsWith("s") -> (timeout.dropLast(1).toLongOrNull() ?: 0L) * 1000L + timeout.endsWith("m") -> (timeout.dropLast(1).toLongOrNull() ?: 0L) * 60_000L + else -> (timeout.toLongOrNull() ?: 0L) * 60_000L } } diff --git a/app/src/main/java/com/sameerasw/essentials/services/tiles/ScreenOffAccessibilityService.kt b/app/src/main/java/com/sameerasw/essentials/services/tiles/ScreenOffAccessibilityService.kt index ee876f8d2..4f4f1f60d 100644 --- a/app/src/main/java/com/sameerasw/essentials/services/tiles/ScreenOffAccessibilityService.kt +++ b/app/src/main/java/com/sameerasw/essentials/services/tiles/ScreenOffAccessibilityService.kt @@ -238,6 +238,7 @@ class ScreenOffAccessibilityService : } else if (key == SettingsRepository.KEY_AOD_WALLPAPER_ENABLED || key == SettingsRepository.KEY_AOD_WALLPAPER_OPACITY || key == SettingsRepository.KEY_AOD_WALLPAPER_TIMEOUT || + key == SettingsRepository.KEY_AOD_WALLPAPER_CUSTOM_TIMEOUT || key == SettingsRepository.KEY_AOD_WALLPAPER_BLUR || key == SettingsRepository.KEY_AOD_WALLPAPER_VIGNETTE || key == SettingsRepository.KEY_AOD_WALLPAPER_BLACK_THRESHOLD || diff --git a/app/src/main/java/com/sameerasw/essentials/ui/features/display/AodWallpaperSettingsUI.kt b/app/src/main/java/com/sameerasw/essentials/ui/features/display/AodWallpaperSettingsUI.kt index 10e9dd35f..756c2a52d 100644 --- a/app/src/main/java/com/sameerasw/essentials/ui/features/display/AodWallpaperSettingsUI.kt +++ b/app/src/main/java/com/sameerasw/essentials/ui/features/display/AodWallpaperSettingsUI.kt @@ -191,13 +191,17 @@ fun AodWallpaperSettingsUI( val timeoutOptions = listOf( - 0 to stringResource(R.string.feat_aod_wallpaper_timeout_never), - 1 to stringResource(R.string.feat_aod_wallpaper_timeout_1m), - 3 to stringResource(R.string.feat_aod_wallpaper_timeout_3m), - 5 to stringResource(R.string.feat_aod_wallpaper_timeout_5m), - 10 to stringResource(R.string.feat_aod_wallpaper_timeout_10m), + "never" to stringResource(R.string.feat_aod_wallpaper_timeout_never), + "5s" to stringResource(R.string.feat_aod_wallpaper_timeout_5s), + "15s" to stringResource(R.string.feat_aod_wallpaper_timeout_15s), + "30s" to stringResource(R.string.feat_aod_wallpaper_timeout_30s), + "1m" to stringResource(R.string.feat_aod_wallpaper_timeout_1m), + "3m" to stringResource(R.string.feat_aod_wallpaper_timeout_3m), + "5m" to stringResource(R.string.feat_aod_wallpaper_timeout_5m), + "10m" to stringResource(R.string.feat_aod_wallpaper_timeout_10m), + "custom" to stringResource(R.string.feat_aod_wallpaper_timeout_custom), ) - val currentTimeout = viewModel.aodWallpaperTimeout.intValue + val currentTimeout = viewModel.aodWallpaperTimeout.value val selectedLabel = timeoutOptions.firstOrNull { it.first == currentTimeout }?.second ?: stringResource(R.string.feat_aod_wallpaper_timeout_3m) @@ -206,16 +210,36 @@ fun AodWallpaperSettingsUI( selectedValue = selectedLabel, iconRes = R.drawable.rounded_timer_24, ) { - timeoutOptions.forEach { (minutes, label) -> + timeoutOptions.forEach { (optionValue, label) -> SegmentedDropdownMenuItem( text = { Text(label) }, onClick = { HapticUtil.performVirtualKeyHaptic(view) - viewModel.setAodWallpaperTimeout(minutes) + viewModel.setAodWallpaperTimeout(optionValue) }, ) } } + + AnimatedVisibility( + visible = currentTimeout == "custom", + enter = expandVertically(animationSpec = tween(durationMillis = 300)) + fadeIn(animationSpec = tween(durationMillis = 300)), + exit = shrinkVertically(animationSpec = tween(durationMillis = 300)) + fadeOut(animationSpec = tween(durationMillis = 300)), + ) { + val customTimeout = viewModel.aodWallpaperCustomTimeout.floatValue + ConfigSliderItem( + title = stringResource(R.string.feat_aod_wallpaper_custom_timeout_slider), + value = customTimeout, + onValueChange = { viewModel.setAodWallpaperCustomTimeout(it) }, + valueRange = 1f..180f, + increment = 1f, + valueFormatter = { + val secs = it.toInt() + if (secs < 60) "${secs}s" else if (secs % 60 == 0) "${secs / 60}m" else "${secs / 60}m ${secs % 60}s" + }, + iconRes = R.drawable.rounded_timer_24, + ) + } } } } @@ -223,7 +247,7 @@ fun AodWallpaperSettingsUI( val isNotificationListenerGranted = viewModel.isNotificationListenerEnabled.value val isAlbumArtEnabled = viewModel.isAodWallpaperUseAlbumArt.value val isKeepOnMedia = viewModel.isAodWallpaperKeepOnMedia.value - val isTimeoutNever = viewModel.aodWallpaperTimeout.intValue == 0 + val isTimeoutNever = viewModel.aodWallpaperTimeout.value == "never" || viewModel.aodWallpaperTimeout.value == "0" Text( text = stringResource(R.string.feat_aod_wallpaper_media_section_title), diff --git a/app/src/main/java/com/sameerasw/essentials/viewmodels/MainViewModel.kt b/app/src/main/java/com/sameerasw/essentials/viewmodels/MainViewModel.kt index cfe35e694..a5fc4455f 100644 --- a/app/src/main/java/com/sameerasw/essentials/viewmodels/MainViewModel.kt +++ b/app/src/main/java/com/sameerasw/essentials/viewmodels/MainViewModel.kt @@ -277,7 +277,8 @@ class MainViewModel : ViewModel() { val isAodForceTurnOffEnabled = mutableStateOf(false) val isAodWallpaperEnabled = mutableStateOf(false) val aodWallpaperOpacity = mutableFloatStateOf(0.3f) - val aodWallpaperTimeout = mutableIntStateOf(3) + val aodWallpaperTimeout = mutableStateOf("3m") + val aodWallpaperCustomTimeout = mutableFloatStateOf(30f) val aodWallpaperBlur = mutableFloatStateOf(0f) val aodWallpaperVignette = mutableFloatStateOf(0f) val aodWallpaperBlackThreshold = mutableFloatStateOf(15f) @@ -1160,9 +1161,13 @@ class MainViewModel : ViewModel() { settingsRepository.getFloat(key, 0.3f) SettingsRepository.KEY_AOD_WALLPAPER_TIMEOUT -> - aodWallpaperTimeout.intValue = + aodWallpaperTimeout.value = settingsRepository.getAodWallpaperTimeout() + SettingsRepository.KEY_AOD_WALLPAPER_CUSTOM_TIMEOUT -> + aodWallpaperCustomTimeout.floatValue = + settingsRepository.getAodWallpaperCustomTimeout() + SettingsRepository.KEY_AOD_WALLPAPER_BLUR -> aodWallpaperBlur.floatValue = settingsRepository.getAodWallpaperBlur() @@ -2462,8 +2467,10 @@ class MainViewModel : ViewModel() { settingsRepository.getBoolean(SettingsRepository.KEY_AOD_WALLPAPER_ENABLED) aodWallpaperOpacity.floatValue = settingsRepository.getAodWallpaperOpacity() - aodWallpaperTimeout.intValue = + aodWallpaperTimeout.value = settingsRepository.getAodWallpaperTimeout() + aodWallpaperCustomTimeout.floatValue = + settingsRepository.getAodWallpaperCustomTimeout() aodWallpaperBlur.floatValue = settingsRepository.getAodWallpaperBlur() aodWallpaperVignette.floatValue = @@ -8416,9 +8423,14 @@ class MainViewModel : ViewModel() { aodWallpaperOpacity.floatValue = opacity } - fun setAodWallpaperTimeout(minutes: Int) { - settingsRepository.setAodWallpaperTimeout(minutes) - aodWallpaperTimeout.intValue = minutes + fun setAodWallpaperTimeout(timeout: String) { + settingsRepository.setAodWallpaperTimeout(timeout) + aodWallpaperTimeout.value = timeout + } + + fun setAodWallpaperCustomTimeout(seconds: Float) { + settingsRepository.setAodWallpaperCustomTimeout(seconds) + aodWallpaperCustomTimeout.floatValue = seconds } fun setAodWallpaperBlur(radius: Float) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7427bc969..c91fb1a1d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2506,10 +2506,15 @@ Opacity Wallpaper timeout Never + 5 sec + 15 sec + 30 sec 1 min 3 min 5 min 10 min + Custom + Custom duration Blur Vignette Black threshold