fix: 高亮逻辑问题
This commit is contained in:
@@ -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 pattern by remember(show, rule) { mutableStateOf(initial.pattern) }
|
||||||
var name by remember { mutableStateOf(initial.name) }
|
var name by remember(show, rule) { mutableStateOf(initial.name) }
|
||||||
var targetScope by remember { mutableIntStateOf(initial.targetScope) }
|
var targetScope by remember(show, rule) { mutableIntStateOf(initial.targetScope) }
|
||||||
var enabled by remember { mutableStateOf(initial.enabled) }
|
var enabled by remember(show, rule) { mutableStateOf(initial.enabled) }
|
||||||
var sampleText by remember {
|
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 textColor by remember(show, rule) {
|
||||||
var hasTextColor by remember { mutableStateOf(initial.textColor != null) }
|
mutableIntStateOf(
|
||||||
var bgColor by remember { mutableIntStateOf(initial.bgColor ?: 0x20FFEB3B) }
|
initial.textColor ?: 0xFF63C37D.toInt()
|
||||||
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 hasTextColor by remember(show, rule) { mutableStateOf(initial.textColor != null) }
|
||||||
var underlineColor by remember { mutableIntStateOf(initial.underlineColor ?: 0xFF63C37D.toInt()) }
|
var bgColor by remember(show, rule) { mutableIntStateOf(initial.bgColor ?: 0x20FFEB3B) }
|
||||||
var hasUnderlineColor by remember { mutableStateOf(initial.underlineColor != null) }
|
var hasBgColor by remember(show, rule) { mutableStateOf(initial.bgColor != null) }
|
||||||
var underlineWidth by remember { mutableFloatStateOf(initial.underlineWidth) }
|
var hasUnderline by remember(show, rule) { mutableStateOf(initial.underlineMode > 0) }
|
||||||
var underlineOffset by remember { mutableFloatStateOf(initial.underlineOffset) }
|
var underlineMode by remember(
|
||||||
var underlineSvgPath by remember { mutableStateOf(initial.underlineSvgPath.orEmpty()) }
|
show,
|
||||||
var bgImage by remember { mutableStateOf(initial.bgImage.orEmpty()) }
|
rule
|
||||||
var bgImageFit by remember { mutableIntStateOf(initial.bgImageFit) }
|
) { mutableIntStateOf(if (initial.underlineMode > 0) initial.underlineMode else 1) }
|
||||||
var bgImageScale by remember { mutableFloatStateOf(initial.bgImageScale) }
|
var underlineColor by remember(show, rule) {
|
||||||
var hasBgImage by remember { mutableStateOf(initial.bgImage?.isNotBlank() == true) }
|
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 hasFont by remember(show, rule) { mutableStateOf(initial.fontPath?.isNotBlank() == true) }
|
||||||
var fontPath by remember { mutableStateOf(initial.fontPath.orEmpty()) }
|
var fontPath by remember(show, rule) { mutableStateOf(initial.fontPath.orEmpty()) }
|
||||||
|
|
||||||
// Color picker state
|
// Color picker state
|
||||||
var showTextColorPicker by remember { mutableStateOf(false) }
|
var showTextColorPicker by remember(show, rule) { mutableStateOf(false) }
|
||||||
var showBgColorPicker by remember { mutableStateOf(false) }
|
var showBgColorPicker by remember(show, rule) { mutableStateOf(false) }
|
||||||
var showUnderlineColorPicker by remember { mutableStateOf(false) }
|
var showUnderlineColorPicker by remember(show, rule) { mutableStateOf(false) }
|
||||||
var showFontSelect by remember { 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(
|
||||||
|
|||||||
@@ -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,
|
show = pendingEngineSelection != null,
|
||||||
onDismissRequest = { pendingEngineValue = 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))
|
onIntent(ReadBookIntent.ApplySpeakEngine(pendingEngineSelection?.value))
|
||||||
pendingEngineValue = null
|
pendingEngineSelection = null
|
||||||
},
|
},
|
||||||
dismissText = stringResource(R.string.book),
|
dismissText = stringResource(R.string.book),
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
onIntent(ReadBookIntent.ApplySpeakEnginePerBook(pendingEngineValue))
|
onIntent(ReadBookIntent.ApplySpeakEnginePerBook(pendingEngineSelection?.value))
|
||||||
pendingEngineValue = null
|
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,
|
||||||
|
|||||||
Reference in New Issue
Block a user