Add ability to unblur backdrops (#5216)
* Add preference for enabling background blur on backdrops * value for strings.xml for enabling backdrop blur feature * Respect preference option for enabling backdrop blur feature * update new customization screen * Added Enum for backdrop state * Added a new screen for CustomizationBackdrops * Combined backdrop enabled and blur into a single behavior modified type to enum , removed checkbox, instead added a subroute, updated BackgroundService to reflect new type values * rename pref variable and run migration * Misc fixes --------- Co-authored-by: Niels van Velzen <git@ndat.nl>
This commit is contained in:
@@ -15,6 +15,7 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jellyfin.androidtv.auth.model.Server
|
import org.jellyfin.androidtv.auth.model.Server
|
||||||
import org.jellyfin.androidtv.preference.UserPreferences
|
import org.jellyfin.androidtv.preference.UserPreferences
|
||||||
|
import org.jellyfin.androidtv.preference.constant.BackdropBehavior
|
||||||
import org.jellyfin.androidtv.util.apiclient.getUrl
|
import org.jellyfin.androidtv.util.apiclient.getUrl
|
||||||
import org.jellyfin.androidtv.util.apiclient.itemBackdropImages
|
import org.jellyfin.androidtv.util.apiclient.itemBackdropImages
|
||||||
import org.jellyfin.androidtv.util.apiclient.parentBackdropImages
|
import org.jellyfin.androidtv.util.apiclient.parentBackdropImages
|
||||||
@@ -59,12 +60,14 @@ class BackgroundService(
|
|||||||
* Use all available backdrops from [baseItem] as background.
|
* Use all available backdrops from [baseItem] as background.
|
||||||
*/
|
*/
|
||||||
fun setBackground(baseItem: BaseItemDto?) {
|
fun setBackground(baseItem: BaseItemDto?) {
|
||||||
|
val backdropBehavior = userPreferences[UserPreferences.backdropBehavior]
|
||||||
|
|
||||||
// Check if item is set and backgrounds are enabled
|
// Check if item is set and backgrounds are enabled
|
||||||
if (baseItem == null || !userPreferences[UserPreferences.backdropEnabled])
|
if (baseItem == null || backdropBehavior == BackdropBehavior.DISABLED)
|
||||||
return clearBackgrounds()
|
return clearBackgrounds()
|
||||||
|
|
||||||
// Enable blur for backdrops
|
// Enable blur for backdrops
|
||||||
_blurBackground.value = true
|
_blurBackground.value = backdropBehavior == BackdropBehavior.BACKDROP_WITH_BLUR
|
||||||
|
|
||||||
// Get all backdrop urls
|
// Get all backdrop urls
|
||||||
val backdropUrls = (baseItem.itemBackdropImages + baseItem.parentBackdropImages)
|
val backdropUrls = (baseItem.itemBackdropImages + baseItem.parentBackdropImages)
|
||||||
@@ -79,7 +82,7 @@ class BackgroundService(
|
|||||||
*/
|
*/
|
||||||
fun setBackground(server: Server) {
|
fun setBackground(server: Server) {
|
||||||
// Check if item is set and backgrounds are enabled
|
// Check if item is set and backgrounds are enabled
|
||||||
if (!userPreferences[UserPreferences.backdropEnabled])
|
if (userPreferences[UserPreferences.backdropBehavior] == BackdropBehavior.DISABLED)
|
||||||
return clearBackgrounds()
|
return clearBackgrounds()
|
||||||
|
|
||||||
// Check if splashscreen is enabled in (cached) branding options
|
// Check if splashscreen is enabled in (cached) branding options
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import androidx.preference.PreferenceManager
|
|||||||
import org.jellyfin.androidtv.preference.UserPreferences.Companion.screensaverInAppEnabled
|
import org.jellyfin.androidtv.preference.UserPreferences.Companion.screensaverInAppEnabled
|
||||||
import org.jellyfin.androidtv.preference.constant.AppTheme
|
import org.jellyfin.androidtv.preference.constant.AppTheme
|
||||||
import org.jellyfin.androidtv.preference.constant.AudioBehavior
|
import org.jellyfin.androidtv.preference.constant.AudioBehavior
|
||||||
|
import org.jellyfin.androidtv.preference.constant.BackdropBehavior
|
||||||
import org.jellyfin.androidtv.preference.constant.ClockBehavior
|
import org.jellyfin.androidtv.preference.constant.ClockBehavior
|
||||||
import org.jellyfin.androidtv.preference.constant.NextUpBehavior
|
import org.jellyfin.androidtv.preference.constant.NextUpBehavior
|
||||||
import org.jellyfin.androidtv.preference.constant.RefreshRateSwitchingBehavior
|
import org.jellyfin.androidtv.preference.constant.RefreshRateSwitchingBehavior
|
||||||
@@ -40,9 +41,9 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
|
|||||||
var appTheme = enumPreference("app_theme", AppTheme.DARK)
|
var appTheme = enumPreference("app_theme", AppTheme.DARK)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable background images while browsing
|
* Behavior of app background while browsing
|
||||||
*/
|
*/
|
||||||
var backdropEnabled = booleanPreference("pref_show_backdrop", true)
|
var backdropBehavior = enumPreference("backdrop_behavior", BackdropBehavior.BACKDROP_WITH_BLUR)
|
||||||
|
|
||||||
/* Playback - General*/
|
/* Playback - General*/
|
||||||
/**
|
/**
|
||||||
@@ -232,7 +233,7 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
|
|||||||
var assDirectPlay = booleanPreference("libass_enabled", false)
|
var assDirectPlay = booleanPreference("libass_enabled", false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable PGS subtitle direct-play.
|
* Enable PGS subtitle direct-play.
|
||||||
*/
|
*/
|
||||||
var pgsDirectPlay = booleanPreference("pgs_enabled", true)
|
var pgsDirectPlay = booleanPreference("pgs_enabled", true)
|
||||||
}
|
}
|
||||||
@@ -263,6 +264,13 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
|
|||||||
migration(toVersion = 9) {
|
migration(toVersion = 9) {
|
||||||
// Reset subtitle text size as we changed from fractional sizing to absolute sizing
|
// Reset subtitle text size as we changed from fractional sizing to absolute sizing
|
||||||
remove("subtitles_text_size")
|
remove("subtitles_text_size")
|
||||||
|
|
||||||
|
// Set the BackdropBehavior if it was enabled in a previous version
|
||||||
|
val backdropEnabled = it.getBoolean("pref_show_backdrop", true)
|
||||||
|
putString(
|
||||||
|
"backdrop_behavior",
|
||||||
|
if (backdropEnabled) BackdropBehavior.BACKDROP_WITH_BLUR.name else BackdropBehavior.DISABLED.name
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.jellyfin.androidtv.preference.constant
|
||||||
|
|
||||||
|
import org.jellyfin.androidtv.R
|
||||||
|
import org.jellyfin.preference.PreferenceEnum
|
||||||
|
|
||||||
|
enum class BackdropBehavior(
|
||||||
|
override val nameRes: Int,
|
||||||
|
) : PreferenceEnum {
|
||||||
|
DISABLED(R.string.state_disabled),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When selected, backdrop is shown with a blur effect.
|
||||||
|
*/
|
||||||
|
BACKDROP_WITH_BLUR(R.string.backdrop_behavior_with_blur),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When selected, backdrop is shown without any blur effect.
|
||||||
|
*/
|
||||||
|
BACKDROP_WITHOUT_BLUR(R.string.backdrop_behavior_without_blur),
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import org.jellyfin.androidtv.ui.settings.screen.authentication.SettingsAuthenti
|
|||||||
import org.jellyfin.androidtv.ui.settings.screen.authentication.SettingsAuthenticationServerScreen
|
import org.jellyfin.androidtv.ui.settings.screen.authentication.SettingsAuthenticationServerScreen
|
||||||
import org.jellyfin.androidtv.ui.settings.screen.authentication.SettingsAuthenticationServerUserScreen
|
import org.jellyfin.androidtv.ui.settings.screen.authentication.SettingsAuthenticationServerUserScreen
|
||||||
import org.jellyfin.androidtv.ui.settings.screen.authentication.SettingsAuthenticationSortByScreen
|
import org.jellyfin.androidtv.ui.settings.screen.authentication.SettingsAuthenticationSortByScreen
|
||||||
|
import org.jellyfin.androidtv.ui.settings.screen.customization.SettingsCustomizationBackdropScreen
|
||||||
import org.jellyfin.androidtv.ui.settings.screen.customization.SettingsCustomizationClockScreen
|
import org.jellyfin.androidtv.ui.settings.screen.customization.SettingsCustomizationClockScreen
|
||||||
import org.jellyfin.androidtv.ui.settings.screen.customization.SettingsCustomizationScreen
|
import org.jellyfin.androidtv.ui.settings.screen.customization.SettingsCustomizationScreen
|
||||||
import org.jellyfin.androidtv.ui.settings.screen.customization.SettingsCustomizationThemeScreen
|
import org.jellyfin.androidtv.ui.settings.screen.customization.SettingsCustomizationThemeScreen
|
||||||
@@ -62,6 +63,7 @@ object Routes {
|
|||||||
const val CUSTOMIZATION_THEME = "/customization/theme"
|
const val CUSTOMIZATION_THEME = "/customization/theme"
|
||||||
const val CUSTOMIZATION_CLOCK = "/customization/clock"
|
const val CUSTOMIZATION_CLOCK = "/customization/clock"
|
||||||
const val CUSTOMIZATION_WATCHED_INDICATOR = "/customization/watch-indicators"
|
const val CUSTOMIZATION_WATCHED_INDICATOR = "/customization/watch-indicators"
|
||||||
|
const val CUSTOMIZATION_BACKDROP = "/customization/backdrop"
|
||||||
const val CUSTOMIZATION_SCREENSAVER = "/customization/screensaver"
|
const val CUSTOMIZATION_SCREENSAVER = "/customization/screensaver"
|
||||||
const val CUSTOMIZATION_SCREENSAVER_TIMEOUT = "/customization/screensaver/timeout"
|
const val CUSTOMIZATION_SCREENSAVER_TIMEOUT = "/customization/screensaver/timeout"
|
||||||
const val CUSTOMIZATION_SCREENSAVER_AGE_RATING = "/customization/screensaver/age-rating"
|
const val CUSTOMIZATION_SCREENSAVER_AGE_RATING = "/customization/screensaver/age-rating"
|
||||||
@@ -139,6 +141,9 @@ val routes = mapOf<String, RouteComposable>(
|
|||||||
Routes.CUSTOMIZATION_WATCHED_INDICATOR to {
|
Routes.CUSTOMIZATION_WATCHED_INDICATOR to {
|
||||||
SettingsCustomizationWatchedIndicatorScreen()
|
SettingsCustomizationWatchedIndicatorScreen()
|
||||||
},
|
},
|
||||||
|
Routes.CUSTOMIZATION_BACKDROP to {
|
||||||
|
SettingsCustomizationBackdropScreen()
|
||||||
|
},
|
||||||
Routes.CUSTOMIZATION_SCREENSAVER to {
|
Routes.CUSTOMIZATION_SCREENSAVER to {
|
||||||
SettingsScreensaverScreen()
|
SettingsScreensaverScreen()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package org.jellyfin.androidtv.ui.settings.screen.customization
|
||||||
|
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import org.jellyfin.androidtv.R
|
||||||
|
import org.jellyfin.androidtv.preference.UserPreferences
|
||||||
|
import org.jellyfin.androidtv.preference.constant.BackdropBehavior
|
||||||
|
import org.jellyfin.androidtv.ui.base.Text
|
||||||
|
import org.jellyfin.androidtv.ui.base.form.RadioButton
|
||||||
|
import org.jellyfin.androidtv.ui.base.list.ListButton
|
||||||
|
import org.jellyfin.androidtv.ui.base.list.ListSection
|
||||||
|
import org.jellyfin.androidtv.ui.navigation.LocalRouter
|
||||||
|
import org.jellyfin.androidtv.ui.settings.compat.rememberPreference
|
||||||
|
import org.jellyfin.androidtv.ui.settings.composable.SettingsColumn
|
||||||
|
import org.koin.compose.koinInject
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SettingsCustomizationBackdropScreen() {
|
||||||
|
val router = LocalRouter.current
|
||||||
|
val userPreferences = koinInject<UserPreferences>()
|
||||||
|
var backdropBehavior by rememberPreference(userPreferences, UserPreferences.backdropBehavior)
|
||||||
|
|
||||||
|
SettingsColumn {
|
||||||
|
item {
|
||||||
|
ListSection(
|
||||||
|
overlineContent = { Text(stringResource(R.string.pref_customization).uppercase()) },
|
||||||
|
headingContent = { Text(stringResource(R.string.lbl_show_backdrop)) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
items(BackdropBehavior.entries) { entry ->
|
||||||
|
ListButton(
|
||||||
|
headingContent = { Text(stringResource(entry.nameRes)) },
|
||||||
|
trailingContent = { RadioButton(checked = backdropBehavior == entry) },
|
||||||
|
onClick = {
|
||||||
|
backdropBehavior = entry
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,13 +62,12 @@ fun SettingsCustomizationScreen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
item {
|
item {
|
||||||
var backdropEnabled by rememberPreference(userPreferences, UserPreferences.backdropEnabled)
|
var backdropBehavior by rememberPreference(userPreferences, UserPreferences.backdropBehavior)
|
||||||
|
|
||||||
ListButton(
|
ListButton(
|
||||||
headingContent = { Text(stringResource(R.string.lbl_show_backdrop)) },
|
headingContent = { Text(stringResource(R.string.lbl_show_backdrop)) },
|
||||||
trailingContent = { Checkbox(checked = backdropEnabled) },
|
captionContent = { Text(stringResource(backdropBehavior.nameRes)) },
|
||||||
captionContent = { Text(stringResource(R.string.pref_show_backdrop_description)) },
|
onClick = { router.push(Routes.CUSTOMIZATION_BACKDROP) }
|
||||||
onClick = { backdropEnabled = !backdropEnabled }
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,7 +195,6 @@
|
|||||||
<string name="lbl_play_next_up">Play next up</string>
|
<string name="lbl_play_next_up">Play next up</string>
|
||||||
<string name="lbl_open">Open</string>
|
<string name="lbl_open">Open</string>
|
||||||
<string name="lbl_show_backdrop">Show backdrops</string>
|
<string name="lbl_show_backdrop">Show backdrops</string>
|
||||||
<string name="pref_show_backdrop_description">Change background image to selected items</string>
|
|
||||||
<string name="lbl_show_premieres">Show season premieres</string>
|
<string name="lbl_show_premieres">Show season premieres</string>
|
||||||
<string name="desc_premieres">Show a row of new episode pilots for any series you watch</string>
|
<string name="desc_premieres">Show a row of new episode pilots for any series you watch</string>
|
||||||
<string name="lbl_in_x_days">In %d days</string>
|
<string name="lbl_in_x_days">In %d days</string>
|
||||||
@@ -578,6 +577,8 @@
|
|||||||
<string name="video_player_external">External app</string>
|
<string name="video_player_external">External app</string>
|
||||||
<string name="playback_video_player_external_empty">You don\'t have any video player apps installed on your device that can open Jellyfin videos.</string>
|
<string name="playback_video_player_external_empty">You don\'t have any video player apps installed on your device that can open Jellyfin videos.</string>
|
||||||
<string name="filters">Filters</string>
|
<string name="filters">Filters</string>
|
||||||
|
<string name="backdrop_behavior_with_blur">Backdrop with blur</string>
|
||||||
|
<string name="backdrop_behavior_without_blur">Backdrop without blur</string>
|
||||||
<plurals name="seconds">
|
<plurals name="seconds">
|
||||||
<item quantity="one">%1$s second</item>
|
<item quantity="one">%1$s second</item>
|
||||||
<item quantity="other">%1$s seconds</item>
|
<item quantity="other">%1$s seconds</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user