Browse Source

fix: 修复规则预览中的 Toast 消息显示,优化规则列表索引

52fisher 4 months ago
parent
commit
935b689afc

+ 6 - 3
app/src/main/java/io/legado/app/ui/book/toc/rule/preview/TxtTocRulePreviewScreen.kt

@@ -33,12 +33,14 @@ import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import io.legado.app.R
 import io.legado.app.data.entities.TxtTocRule
+import io.legado.app.utils.toastOnUi
 import io.legado.app.ui.theme.adaptiveContentPadding
 import io.legado.app.ui.widget.components.AppScaffold
 import io.legado.app.ui.widget.components.card.NormalCard
@@ -64,6 +66,7 @@ fun TxtTocRulePreviewRouteScreen(
     onApplyRule: (String) -> Unit,
 ) {
     val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+    val context = LocalContext.current
 
     LaunchedEffect(bookUrl) {
         viewModel.init(bookUrl, currentTocRegex)
@@ -73,7 +76,7 @@ fun TxtTocRulePreviewRouteScreen(
         viewModel.effects.collect { effect ->
             when (effect) {
                 is TxtTocRulePreviewEffect.ApplyRule -> onApplyRule(effect.rule)
-                is TxtTocRulePreviewEffect.ShowToast -> { /* no-op */ }
+                is TxtTocRulePreviewEffect.ShowToast -> context.toastOnUi(effect.message)
             }
         }
     }
@@ -213,7 +216,7 @@ fun TxtTocRulePreviewScreen(
                 horizontalArrangement = Arrangement.spacedBy(8.dp),
                 verticalArrangement = Arrangement.spacedBy(8.dp),
             ) {
-                itemsIndexed(state.rules, key = { index, item -> "${index}_${item.rule.id}" }) { index, item ->
+                itemsIndexed(state.rules, key = { _, item -> item.rule.id }) { _, item ->
                     RulePreviewCard(
                         item = item,
                         isSelected = item.rule.rule == state.selectedRule,
@@ -237,7 +240,7 @@ fun TxtTocRulePreviewScreen(
                 ),
                 verticalArrangement = Arrangement.spacedBy(4.dp),
             ) {
-                itemsIndexed(state.rules, key = { index, item -> "${index}_${item.rule.id}" }) { index, item ->
+                itemsIndexed(state.rules, key = { _, item -> item.rule.id }) { _, item ->
                     RulePreviewListItem(
                         item = item,
                         isSelected = item.rule.rule == state.selectedRule,

+ 6 - 3
app/src/main/java/io/legado/app/ui/book/toc/rule/preview/TxtTocRulePreviewViewModel.kt

@@ -18,6 +18,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asSharedFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.ensureActive
+import kotlin.coroutines.coroutineContext
 import kotlinx.coroutines.launch
 import java.util.regex.Pattern
 import java.util.regex.PatternSyntaxException
@@ -176,12 +178,12 @@ class TxtTocRulePreviewViewModel(private val app: Application) : ViewModel() {
         if (repository.count() == 0) {
             val defaultRules = DefaultData.txtTocRules
             repository.insert(*defaultRules.toTypedArray())
-            rules = defaultRules
+            rules = repository.all()
         }
         return rules.filter { it.rule.isNotBlank() }.sortedBy { it.serialNumber }
     }
 
-    private fun analyzeWithPattern(book: Book, pattern: Pattern): Pair<List<String>, Int> {
+       private suspend fun analyzeWithPattern(book: Book, pattern: Pattern): Pair<List<String>, Int> {
         val chapters = mutableListOf<String>()
         var totalCount = 0
         val charset = book.fileCharset()
@@ -198,9 +200,10 @@ class TxtTocRulePreviewViewModel(private val app: Application) : ViewModel() {
                 }
                 var length: Int
                 while (bis.read(buffer, bufferStart, bufferSize - bufferStart).also { length = it } > 0) {
+                    coroutineContext.ensureActive()
                     var end = bufferStart + length
                     if (end == bufferSize) {
-                        for (i in bufferStart + length - 1 downTo 0) {
+                        for (i in bufferStart + length - 1 downTo (bufferStart + length - 4096).coerceAtLeast(0)) {
                             if (buffer[i] == blank) {
                                 end = i
                                 break