Răsfoiți Sursa

fix: 高亮逻辑问题

HapeLee 5 luni în urmă
părinte
comite
d25568d99a

+ 44 - 30
app/src/main/java/io/legado/app/ui/book/read/sheet/HighlightRuleEditSheet.kt

@@ -32,13 +32,13 @@ import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.StrokeCap
 import androidx.compose.ui.graphics.StrokeCap
 import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringArrayResource
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.drawText
 import androidx.compose.ui.text.drawText
 import androidx.compose.ui.text.rememberTextMeasurer
 import androidx.compose.ui.text.rememberTextMeasurer
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.compose.ui.unit.sp
-import androidx.compose.ui.res.stringArrayResource
 import androidx.core.net.toUri
 import androidx.core.net.toUri
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import io.legado.app.R
 import io.legado.app.R
@@ -73,53 +73,67 @@ fun HighlightRuleEditSheet(
     onSave: (HighlightRule) -> Unit,
     onSave: (HighlightRule) -> Unit,
 ) {
 ) {
     val isNew = rule == null
     val isNew = rule == null
-    val initial = rule ?: HighlightRule()
+    val initial = remember(show, rule) { rule ?: HighlightRule() }
     val context = LocalContext.current
     val context = LocalContext.current
 
 
     // Rule info state
     // Rule info state
-    var pattern by remember { mutableStateOf(initial.pattern) }
-    var name by remember { mutableStateOf(initial.name) }
-    var targetScope by remember { mutableIntStateOf(initial.targetScope) }
-    var enabled by remember { mutableStateOf(initial.enabled) }
-    var sampleText by remember {
+    var pattern by remember(show, rule) { mutableStateOf(initial.pattern) }
+    var name by remember(show, rule) { mutableStateOf(initial.name) }
+    var targetScope by remember(show, rule) { mutableIntStateOf(initial.targetScope) }
+    var enabled by remember(show, rule) { mutableStateOf(initial.enabled) }
+    var sampleText by remember(show, rule) {
         mutableStateOf(initial.sampleText.ifBlank { "她轻声说:今晚就出发。" })
         mutableStateOf(initial.sampleText.ifBlank { "她轻声说:今晚就出发。" })
     }
     }
 
 
     // Style state
     // Style state
-    var textColor by remember { mutableIntStateOf(initial.textColor ?: 0xFF63C37D.toInt()) }
-    var hasTextColor by remember { mutableStateOf(initial.textColor != null) }
-    var bgColor by remember { mutableIntStateOf(initial.bgColor ?: 0x20FFEB3B) }
-    var hasBgColor by remember { mutableStateOf(initial.bgColor != null) }
-    var hasUnderline by remember { mutableStateOf(initial.underlineMode > 0) }
-    var underlineMode by remember { mutableIntStateOf(if (initial.underlineMode > 0) initial.underlineMode else 1) }
-    var underlineColor by remember { mutableIntStateOf(initial.underlineColor ?: 0xFF63C37D.toInt()) }
-    var hasUnderlineColor by remember { mutableStateOf(initial.underlineColor != null) }
-    var underlineWidth by remember { mutableFloatStateOf(initial.underlineWidth) }
-    var underlineOffset by remember { mutableFloatStateOf(initial.underlineOffset) }
-    var underlineSvgPath by remember { mutableStateOf(initial.underlineSvgPath.orEmpty()) }
-    var bgImage by remember { mutableStateOf(initial.bgImage.orEmpty()) }
-    var bgImageFit by remember { mutableIntStateOf(initial.bgImageFit) }
-    var bgImageScale by remember { mutableFloatStateOf(initial.bgImageScale) }
-    var hasBgImage by remember { mutableStateOf(initial.bgImage?.isNotBlank() == true) }
+    var textColor by remember(show, rule) {
+        mutableIntStateOf(
+            initial.textColor ?: 0xFF63C37D.toInt()
+        )
+    }
+    var hasTextColor by remember(show, rule) { mutableStateOf(initial.textColor != null) }
+    var bgColor by remember(show, rule) { mutableIntStateOf(initial.bgColor ?: 0x20FFEB3B) }
+    var hasBgColor by remember(show, rule) { mutableStateOf(initial.bgColor != null) }
+    var hasUnderline by remember(show, rule) { mutableStateOf(initial.underlineMode > 0) }
+    var underlineMode by remember(
+        show,
+        rule
+    ) { mutableIntStateOf(if (initial.underlineMode > 0) initial.underlineMode else 1) }
+    var underlineColor by remember(show, rule) {
+        mutableIntStateOf(
+            initial.underlineColor ?: 0xFF63C37D.toInt()
+        )
+    }
+    var hasUnderlineColor by remember(show, rule) { mutableStateOf(initial.underlineColor != null) }
+    var underlineWidth by remember(show, rule) { mutableFloatStateOf(initial.underlineWidth) }
+    var underlineOffset by remember(show, rule) { mutableFloatStateOf(initial.underlineOffset) }
+    var underlineSvgPath by remember(
+        show,
+        rule
+    ) { mutableStateOf(initial.underlineSvgPath.orEmpty()) }
+    var bgImage by remember(show, rule) { mutableStateOf(initial.bgImage.orEmpty()) }
+    var bgImageFit by remember(show, rule) { mutableIntStateOf(initial.bgImageFit) }
+    var bgImageScale by remember(show, rule) { mutableFloatStateOf(initial.bgImageScale) }
+    var hasBgImage by remember(show, rule) { mutableStateOf(initial.bgImage?.isNotBlank() == true) }
 
 
     // Config binding state — empty set = global (applies to all configs)
     // Config binding state — empty set = global (applies to all configs)
     val allConfigNames = remember { ReadBookConfig.configList.map { it.name }.filter { it.isNotBlank() } }
     val allConfigNames = remember { ReadBookConfig.configList.map { it.name }.filter { it.isNotBlank() } }
-    var configNames by remember {
+    var configNames by remember(show, rule) {
         mutableStateOf(initial.configName.orEmpty().configNames().toSet())
         mutableStateOf(initial.configName.orEmpty().configNames().toSet())
     }
     }
 
 
     // Font state
     // Font state
-    var hasFont by remember { mutableStateOf(initial.fontPath?.isNotBlank() == true) }
-    var fontPath by remember { mutableStateOf(initial.fontPath.orEmpty()) }
+    var hasFont by remember(show, rule) { mutableStateOf(initial.fontPath?.isNotBlank() == true) }
+    var fontPath by remember(show, rule) { mutableStateOf(initial.fontPath.orEmpty()) }
 
 
     // Color picker state
     // Color picker state
-    var showTextColorPicker by remember { mutableStateOf(false) }
-    var showBgColorPicker by remember { mutableStateOf(false) }
-    var showUnderlineColorPicker by remember { mutableStateOf(false) }
-    var showFontSelect by remember { mutableStateOf(false) }
+    var showTextColorPicker by remember(show, rule) { mutableStateOf(false) }
+    var showBgColorPicker by remember(show, rule) { mutableStateOf(false) }
+    var showUnderlineColorPicker by remember(show, rule) { mutableStateOf(false) }
+    var showFontSelect by remember(show, rule) { mutableStateOf(false) }
 
 
     // Validation
     // Validation
-    var patternError by remember { mutableStateOf<String?>(null) }
+    var patternError by remember(show, rule) { mutableStateOf<String?>(null) }
 
 
     // SAF image picker
     // SAF image picker
     val imagePicker = rememberLauncherForActivityResult(
     val imagePicker = rememberLauncherForActivityResult(

+ 10 - 8
app/src/main/java/io/legado/app/ui/book/read/sheet/ReadAloudConfigSheet.kt

@@ -154,22 +154,22 @@ fun SpeakEngineConfigSheet(
 ) {
 ) {
     val items = state.ttsEngineItems
     val items = state.ttsEngineItems
     val selectedValue = state.selectedTtsEngine
     val selectedValue = state.selectedTtsEngine
-    var pendingEngineValue by remember { mutableStateOf<String?>(null) }
+    var pendingEngineSelection by remember { mutableStateOf<PendingSpeakEngineSelection?>(null) }
 
 
     AppAlertDialog(
     AppAlertDialog(
-        show = pendingEngineValue != null,
-        onDismissRequest = { pendingEngineValue = null },
+        show = pendingEngineSelection != null,
+        onDismissRequest = { pendingEngineSelection = null },
         title = stringResource(R.string.speak_engine),
         title = stringResource(R.string.speak_engine),
         text = stringResource(R.string.speak_engine_apply_scope),
         text = stringResource(R.string.speak_engine_apply_scope),
         confirmText = stringResource(R.string.general),
         confirmText = stringResource(R.string.general),
         onConfirm = {
         onConfirm = {
-            onIntent(ReadBookIntent.ApplySpeakEngine(pendingEngineValue))
-            pendingEngineValue = null
+            onIntent(ReadBookIntent.ApplySpeakEngine(pendingEngineSelection?.value))
+            pendingEngineSelection = null
         },
         },
         dismissText = stringResource(R.string.book),
         dismissText = stringResource(R.string.book),
         onDismiss = {
         onDismiss = {
-            onIntent(ReadBookIntent.ApplySpeakEnginePerBook(pendingEngineValue))
-            pendingEngineValue = null
+            onIntent(ReadBookIntent.ApplySpeakEnginePerBook(pendingEngineSelection?.value))
+            pendingEngineSelection = null
         },
         },
     )
     )
 
 
@@ -232,7 +232,7 @@ fun SpeakEngineConfigSheet(
                     } else {
                     } else {
                         null
                         null
                     },
                     },
-                    onClick = { pendingEngineValue = item.value },
+                    onClick = { pendingEngineSelection = PendingSpeakEngineSelection(item.value) },
                     onLongClick = if (httpTtsId != null && !item.loginUrl.isNullOrBlank()) {
                     onLongClick = if (httpTtsId != null && !item.loginUrl.isNullOrBlank()) {
                         { onIntent(ReadBookIntent.OpenHttpTtsLogin(httpTtsId)) }
                         { onIntent(ReadBookIntent.OpenHttpTtsLogin(httpTtsId)) }
                     } else null,
                     } else null,
@@ -256,6 +256,8 @@ fun SpeakEngineConfigSheet(
     }
     }
 }
 }
 
 
+private data class PendingSpeakEngineSelection(val value: String?)
+
 @Composable
 @Composable
 fun HttpTtsEditSheet(
 fun HttpTtsEditSheet(
     show: Boolean,
     show: Boolean,