diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt index e26c1a677..fd8af2ced 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.text.AnnotatedString import com.hippo.ehviewer.ui.login.LocalNavController import com.hippo.ehviewer.ui.openBrowser import com.hippo.ehviewer.ui.settings.PreferenceTokens.PreferenceTextPadding +import com.jamal.composeprefs3.ui.prefs.SpannedTextPref import com.jamal.composeprefs3.ui.prefs.SwitchPref import com.jamal.composeprefs3.ui.prefs.TextPref import kotlin.reflect.KMutableProperty0 @@ -54,10 +55,10 @@ fun Preference(title: String, summary: String? = null, onClick: () -> Unit = {}) } @Composable -fun SwitchPreference(title: String, summary: String?, value: KMutableProperty0) { +fun SwitchPreference(title: String, summary: String?, value: KMutableProperty0, enabled: Boolean = true) { var v by remember { mutableStateOf(value.get()) } fun mutate() = value.set((!value.get()).also { v = it }) - SwitchPref(checked = v, onMutate = ::mutate, title = title, summary = summary) + SwitchPref(checked = v, onMutate = ::mutate, title = title, summary = summary, enabled = enabled) } @Composable @@ -68,5 +69,5 @@ fun UrlPreference(title: String, url: String) { @Composable fun HtmlPreference(title: String, summary: AnnotatedString? = null, onClick: () -> Unit = {}) { - TextPref(title = title, summary = summary, onClick = onClick) + SpannedTextPref(title = title, summary = summary, onClick = onClick) } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/SecurityScreen.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/SecurityScreen.kt index f094d454b..db1c1d4f0 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/settings/SecurityScreen.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/SecurityScreen.kt @@ -13,9 +13,11 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import com.hippo.ehviewer.R import com.hippo.ehviewer.Settings +import com.hippo.ehviewer.ui.isAuthenticationSupported import com.hippo.ehviewer.ui.login.LocalNavController @Composable @@ -36,6 +38,12 @@ fun SecurityScreen() { }, ) { Column(modifier = Modifier.padding(it).nestedScroll(scrollBehavior.nestedScrollConnection)) { + SwitchPreference( + title = stringResource(id = R.string.settings_privacy_require_unlock), + summary = null, + value = Settings::security, + enabled = LocalContext.current.isAuthenticationSupported(), + ) SwitchPreference( title = stringResource(id = R.string.settings_privacy_secure), summary = stringResource(id = R.string.settings_privacy_secure_summary), diff --git a/app/src/main/java/com/jamal/composeprefs3/ui/prefs/SliderPref.kt b/app/src/main/java/com/jamal/composeprefs3/ui/prefs/SliderPref.kt new file mode 100644 index 000000000..4bba04294 --- /dev/null +++ b/app/src/main/java/com/jamal/composeprefs3/ui/prefs/SliderPref.kt @@ -0,0 +1,85 @@ +package com.jamal.composeprefs3.ui.prefs + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Slider +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.remember +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.unit.dp +import com.jamal.composeprefs3.ui.roundToDP + +/** + * Preference which shows a slider just below the [title] + * + * @param key Key used to identify this Pref in the DataStore + * @param title Main text which describes the Pref + * @param modifier Modifier applied to the Text aspect of this Pref + * @param defaultValue Default value of the slider. Used if this key is not found in the DataStore + * @param onValueChangeFinished Same as onValueChangeFinished parameter in [Slider] + * @param valueRange Same as valueRange parameter in [Slider] + * @param showValue If the current slider value should be shown on the side of the slider. + * @param enabled If false, this slider cannot be interacted with. + * @param steps Same as steps parameter in [Slider] + * @param textColor Text colour of the [title] and shown value if [showValue] is true. + * @param enabled If [enabled] is not true, this Pref cannot be checked/unchecked + * @param leadingIcon Icon which is positioned at the start of the Pref + */ +@Composable +fun SliderPref( + title: String, + modifier: Modifier = Modifier, + defaultValue: Float = 0f, + onValueChangeFinished: ((Float) -> Unit)? = null, + valueRange: ClosedFloatingPointRange = 0f..1f, + showValue: Boolean = false, + steps: Int = 0, + textColor: Color = MaterialTheme.colorScheme.onBackground, + enabled: Boolean = true, + leadingIcon: @Composable (() -> Unit)? = null, +) { + var value by remember { mutableFloatStateOf(defaultValue) } + Column( + verticalArrangement = Arrangement.Center, + ) { + TextPref( + title = title, + modifier = modifier, + textColor = textColor, + minimalHeight = true, + leadingIcon = leadingIcon, + ) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Slider( + value = value, + onValueChange = { value = it }, + modifier = Modifier.weight(2.1f).padding(start = 16.dp, end = 16.dp), + valueRange = valueRange, + steps = steps, + onValueChangeFinished = { onValueChangeFinished?.invoke(value) }, + enabled = enabled, + ) + if (showValue) { + Text( + text = roundToDP(value, 2).toString(), + color = textColor, + modifier = Modifier.weight(0.5f).padding(start = 8.dp), + ) + } + } + } +} diff --git a/app/src/main/java/com/jamal/composeprefs3/ui/prefs/TextPref.kt b/app/src/main/java/com/jamal/composeprefs3/ui/prefs/TextPref.kt index 7186ad608..0f1d11e83 100644 --- a/app/src/main/java/com/jamal/composeprefs3/ui/prefs/TextPref.kt +++ b/app/src/main/java/com/jamal/composeprefs3/ui/prefs/TextPref.kt @@ -53,7 +53,7 @@ fun TextPref( } @Composable -fun TextPref( +fun SpannedTextPref( title: String, modifier: Modifier = Modifier, summary: AnnotatedString? = null,