Преглед изворни кода

Merge pull request #1812 from HapeLee/codex/resolve-pr-1802

fix: resolve theme slider UX changes on latest main
Kudomaga пре 3 месеци
родитељ
комит
f5f4961807

+ 1 - 0
app/src/main/java/io/legado/app/ui/config/ai/AiModelEditScreen.kt

@@ -180,6 +180,7 @@ fun AiModelEditScreen(
                         valueRange = TranslationConstants.MIN_TEMPERATURE..TranslationConstants.MAX_TEMPERATURE,
                         steps = 19,
                         description = state.temperature.toString(),
+                        decimal = true,
                         onValueChange = { onIntent(AiModelEditIntent.UpdateTemperature(it)) }
                     )
                 }

+ 1 - 0
app/src/main/java/io/legado/app/ui/config/ai/summary/AiSummaryConfigScreen.kt

@@ -129,6 +129,7 @@ fun AiSummaryConfigScreen(
                         valueRange = TranslationConstants.MIN_TEMPERATURE..TranslationConstants.MAX_TEMPERATURE,
                         steps = 19,
                         description = state.temperature.toString(),
+                        decimal = true,
                         onValueChange = { onIntent(AiSummaryConfigIntent.UpdateTemperature(it)) }
                     )
                     InputSettingItem(

+ 1 - 17
app/src/main/java/io/legado/app/ui/config/themeConfig/BackgroundImageManageSheet.kt

@@ -12,10 +12,6 @@ import androidx.compose.material.icons.filled.Add
 import androidx.compose.material.icons.filled.Close
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.ContentScale
@@ -26,7 +22,6 @@ import io.legado.app.R
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.widget.components.button.series.SmallTonalButton
 import io.legado.app.ui.widget.components.card.NormalCard
-import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
 import io.legado.app.ui.widget.components.icon.AppIcon
 import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
 
@@ -39,8 +34,6 @@ fun BackgroundImageManageSheet(
     onSelectImage: (Boolean) -> Unit,
     onRemoveImage: (Boolean) -> Unit,
 ) {
-    var showFilePicker by remember { mutableStateOf(false) }
-
     AppModalBottomSheet(
         data = isDarkTheme,
         onDismissRequest = onDismissRequest,
@@ -54,7 +47,7 @@ fun BackgroundImageManageSheet(
 
             if (currentPath.isNullOrBlank()) {
                 NormalCard(
-                    onClick = { showFilePicker = true },
+                    onClick = { onSelectImage(isDark) },
                     cornerRadius = 12.dp,
                     containerColor = LegadoTheme.colorScheme.surfaceContainerHigh,
                     modifier = Modifier
@@ -106,13 +99,4 @@ fun BackgroundImageManageSheet(
         }
     }
 
-    FilePickerSheet(
-        show = showFilePicker,
-        onDismissRequest = { showFilePicker = false },
-        onSelectSysFile = {
-            onSelectImage(isDarkTheme == true)
-            showFilePicker = false
-        },
-        allowExtensions = arrayOf("jpg", "jpeg", "png", "webp")
-    )
 }

+ 7 - 16
app/src/main/java/io/legado/app/ui/config/themeConfig/ThemeConfigScreen.kt

@@ -60,7 +60,6 @@ import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import androidx.constraintlayout.compose.ConstraintLayout
 import io.legado.app.R
-import io.legado.app.base.AppContextWrapper
 import io.legado.app.domain.gateway.AppShellBooleanSetting
 import io.legado.app.domain.gateway.AppShellSettingsUpdate
 import io.legado.app.domain.gateway.AppShellStringSetting
@@ -311,10 +310,9 @@ fun ThemeConfigScreen(
                     )
                     SliderSettingItem(
                         title = stringResource(R.string.font_scale),
-                        description = stringResource(
-                            R.string.font_scale_summary,
-                            AppContextWrapper.getFontScale(context)
-                        ),
+                        valueLabel = {
+                            context.getString(R.string.font_scale_summary, it / 10f)
+                        },
                         value = appShell.fontScale.toFloat(),
                         defaultValue = 10f,
                         valueRange = 8f..16f,
@@ -552,7 +550,6 @@ fun ThemeConfigScreen(
                                 value = theme.colorTemperature.toFloat(),
                                 defaultValue = 50f,
                                 valueRange = 0f..100f,
-                                steps = 99,
                                 onValueChange = {
                                     onIntent(
                                         ThemeConfigIntent.UpdateTheme(
@@ -701,7 +698,6 @@ fun ThemeConfigScreen(
                                 value = theme.topBarOpacity.toFloat(),
                                 defaultValue = 100f,
                                 valueRange = 0f..100f,
-                                steps = 99,
                                 onValueChange = {
                                     updateTheme(ThemeIntSetting.TopBarOpacity, it.toInt())
                                 }
@@ -732,7 +728,6 @@ fun ThemeConfigScreen(
                             value = theme.containerOpacity.toFloat(),
                             defaultValue = 100f,
                             valueRange = 0f..100f,
-                            steps = 99,
                             onValueChange = {
                                 updateTheme(ThemeIntSetting.ContainerOpacity, it.toInt())
                             }
@@ -740,10 +735,10 @@ fun ThemeConfigScreen(
                     }
                 }
 
-                SplicedColumnGroup(title = stringResource(R.string.day)) {
+                SplicedColumnGroup(title = stringResource(R.string.background_image)) {
                     val hasLightBg = !theme.backgroundImageLight.isNullOrBlank()
                     ClickableSettingItem(
-                        title = stringResource(R.string.background_image),
+                        title = stringResource(R.string.day),
                         description = if (hasLightBg) stringResource(R.string.click_to_delete) else stringResource(
                             R.string.select_image
                         ),
@@ -760,18 +755,14 @@ fun ThemeConfigScreen(
                             value = theme.backgroundImageBlurring.toFloat(),
                             defaultValue = 0f,
                             valueRange = 0f..100f,
-                            steps = 99,
                             onValueChange = {
                                 updateTheme(ThemeIntSetting.BackgroundImageBlurring, it.toInt())
                             }
                         )
                     }
-                }
-
-                SplicedColumnGroup(title = stringResource(R.string.night)) {
                     val hasDarkBg = !theme.backgroundImageDark.isNullOrBlank()
                     ClickableSettingItem(
-                        title = stringResource(R.string.background_image),
+                        title = stringResource(R.string.night),
                         description = if (hasDarkBg) stringResource(R.string.click_to_delete) else stringResource(
                             R.string.select_image
                         ),
@@ -788,7 +779,6 @@ fun ThemeConfigScreen(
                             value = theme.backgroundImageDarkBlurring.toFloat(),
                             defaultValue = 0f,
                             valueRange = 0f..100f,
-                            steps = 99,
                             onValueChange = {
                                 updateTheme(ThemeIntSetting.BackgroundImageDarkBlurring, it.toInt())
                             }
@@ -815,6 +805,7 @@ fun ThemeConfigScreen(
                             defaultValue = 1f,
                             valueRange = 0f..5f,
                             steps = 49,
+                            decimal = true,
                             onValueChange = {
                                 updateTheme(ThemeFloatSetting.ItemDividerWidth, it)
                             }

+ 25 - 24
app/src/main/java/io/legado/app/ui/widget/components/settingItem/SliderSettingItem.kt

@@ -53,6 +53,8 @@ fun SliderSettingItem(
     valueRange: ClosedFloatingPointRange<Float>,
     steps: Int = 0,
     description: String? = null,
+    valueLabel: ((Float) -> String)? = null,
+    decimal: Boolean = false,
     onValueChange: (Float) -> Unit
 ) {
 
@@ -61,16 +63,30 @@ fun SliderSettingItem(
     var sliderValue by remember(value) { mutableFloatStateOf(value) }
     val textFieldState = rememberTextFieldState()
 
+    // 默认整数模式:滑动吸附到整数;decimal = true 时保留 0.1 精度
+    fun snap(v: Float): Float =
+        if (decimal) (v * 10).roundToInt() / 10f else v.roundToInt().toFloat()
+
+    fun format(v: Float): String =
+        if (v % 1f == 0f) v.toInt().toString() else v.toString()
+
     LaunchedEffect(value) {
         sliderValue = value
     }
 
-    val sliderAccessibilityValue = description ?: sliderValue.toString()
+    // 拖动过程中让标题下的数值实时跟随滑块,松手后才真正应用
+    val displayDescription = when {
+        valueLabel != null -> valueLabel(sliderValue)
+        sliderValue != value -> format(sliderValue)
+        else -> description
+    }
+
+    val sliderAccessibilityValue = displayDescription ?: sliderValue.toString()
 
     LaunchedEffect(isInputMode) {
         if (isInputMode) {
             textFieldState.edit {
-                replace(0, length, value.toString())
+                replace(0, length, format(value))
             }
         }
     }
@@ -78,8 +94,7 @@ fun SliderSettingItem(
     fun commitValue() {
         if (isInputMode) {
             textFieldState.text.toString().toFloatOrNull()?.let { num ->
-                val rounded = (num * 10).roundToInt() / 10f
-                onValueChange(rounded.coerceIn(valueRange))
+                onValueChange(snap(num).coerceIn(valueRange))
             }
         } else if (sliderValue != value) {
             onValueChange(sliderValue)
@@ -96,7 +111,7 @@ fun SliderSettingItem(
         ) {
             BasicComponent(
                 title = title,
-                summary = description,
+                summary = displayDescription,
                 onClick = {
                     if (expanded) {
                         commitValue()
@@ -131,10 +146,7 @@ fun SliderSettingItem(
                             MiuixSlider(
                                 value = sliderValue,
                                 onValueChange = {
-                                    sliderValue = (it * 10).roundToInt() / 10f
-                                    textFieldState.edit {
-                                        replace(0, length, sliderValue.toString())
-                                    }
+                                    sliderValue = snap(it)
                                 },
                                 onValueChangeFinished = {
                                     onValueChange(sliderValue.coerceIn(valueRange))
@@ -157,11 +169,7 @@ fun SliderSettingItem(
                         onConfirm = {
                             onValueChange(defaultValue)
                             textFieldState.edit {
-                                replace(
-                                    0,
-                                    length,
-                                    defaultValue.toInt().toString()
-                                )
+                                replace(0, length, format(defaultValue))
                             }
                         },
                         dismissText = if (isInputMode) {
@@ -178,7 +186,7 @@ fun SliderSettingItem(
     } else {
         SettingItem(
             title = title,
-            option = description,
+            option = displayDescription,
             expanded = expanded,
             onExpandChange = {
                 if (expanded) {
@@ -220,10 +228,7 @@ fun SliderSettingItem(
                             Slider(
                                 value = sliderValue,
                                 onValueChange = {
-                                    sliderValue = (it * 10).roundToInt() / 10f
-                                    textFieldState.edit {
-                                        replace(0, length, sliderValue.toString())
-                                    }
+                                    sliderValue = snap(it)
                                 },
                                 onValueChangeFinished = {
                                     onValueChange(sliderValue.coerceIn(valueRange))
@@ -247,11 +252,7 @@ fun SliderSettingItem(
                     onConfirm = {
                         onValueChange(defaultValue)
                         textFieldState.edit {
-                            replace(
-                                0,
-                                length,
-                                defaultValue.toInt().toString()
-                            )
+                            replace(0, length, format(defaultValue))
                         }
                     },
                     dismissText = if (isInputMode) {