Просмотр исходного кода

fix: 修复书源列表开关状态更新

HapeLee 3 месяцев назад
Родитель
Сommit
8be77ec466

+ 2 - 5
app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt

@@ -20,12 +20,9 @@ class BookSourceActivity : BaseComposeActivity() {
         BookSourceRouteScreen(
         BookSourceRouteScreen(
             onBackClick = ::finish,
             onBackClick = ::finish,
             onAddSource = { startActivity<BookSourceEditActivity>() },
             onAddSource = { startActivity<BookSourceEditActivity>() },
-            onEditSource = { source ->
+            onEditSource = { sourceUrl ->
                 startActivity<BookSourceEditActivity> {
                 startActivity<BookSourceEditActivity> {
-                    putExtra(
-                        "sourceUrl",
-                        source.bookSourceUrl
-                    )
+                    putExtra("sourceUrl", sourceUrl)
                 }
                 }
             },
             },
             onImportLocal = {
             onImportLocal = {

+ 5 - 3
app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceContract.kt

@@ -2,7 +2,6 @@ package io.legado.app.ui.book.source.manage
 
 
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.Stable
-import io.legado.app.data.entities.BookSourcePart
 import io.legado.app.ui.widget.components.list.InteractionState
 import io.legado.app.ui.widget.components.list.InteractionState
 import io.legado.app.ui.widget.components.list.ListUiState
 import io.legado.app.ui.widget.components.list.ListUiState
 import io.legado.app.ui.widget.components.list.SelectableItem
 import io.legado.app.ui.widget.components.list.SelectableItem
@@ -13,10 +12,13 @@ import kotlinx.collections.immutable.persistentSetOf
 
 
 @Immutable
 @Immutable
 data class BookSourceItemUi(
 data class BookSourceItemUi(
-    val source: BookSourcePart,
+    override val id: String,
     val domain: String,
     val domain: String,
+    val name: String,
+    val group: String?,
+    val enabled: Boolean,
+    val customOrder: Int,
 ) : SelectableItem<String> {
 ) : SelectableItem<String> {
-    override val id get() = source.bookSourceUrl
 }
 }
 
 
 @Stable
 @Stable

+ 6 - 7
app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceScreen.kt

@@ -39,7 +39,6 @@ import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import io.legado.app.R
 import io.legado.app.R
-import io.legado.app.data.entities.BookSourcePart
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.adaptiveContentPadding
 import io.legado.app.ui.theme.adaptiveContentPadding
 import io.legado.app.ui.widget.components.ActionItem
 import io.legado.app.ui.widget.components.ActionItem
@@ -67,7 +66,7 @@ fun BookSourceRouteScreen(
     viewModel: BookSourceViewModel = koinViewModel(),
     viewModel: BookSourceViewModel = koinViewModel(),
     onBackClick: () -> Unit,
     onBackClick: () -> Unit,
     onAddSource: () -> Unit,
     onAddSource: () -> Unit,
-    onEditSource: (BookSourcePart) -> Unit,
+    onEditSource: (String) -> Unit,
     onImportLocal: () -> Unit,
     onImportLocal: () -> Unit,
     onImportOnline: (String) -> Unit,
     onImportOnline: (String) -> Unit,
 ) {
 ) {
@@ -90,7 +89,7 @@ fun BookSourceScreen(
     onIntent: (BookSourceIntent) -> Unit,
     onIntent: (BookSourceIntent) -> Unit,
     onBackClick: () -> Unit,
     onBackClick: () -> Unit,
     onAddSource: () -> Unit,
     onAddSource: () -> Unit,
-    onEditSource: (BookSourcePart) -> Unit,
+    onEditSource: (String) -> Unit,
     onImportLocal: () -> Unit,
     onImportLocal: () -> Unit,
     onImportOnline: (String) -> Unit,
     onImportOnline: (String) -> Unit,
 ) {
 ) {
@@ -339,9 +338,9 @@ fun BookSourceScreen(
                                     )
                                     )
                                 }
                                 }
                             },
                             },
-                            title = item.source.bookSourceName,
-                            subtitle = item.source.bookSourceGroup,
-                            isEnabled = item.source.enabled,
+                            title = item.name,
+                            subtitle = item.group,
+                            isEnabled = item.enabled,
                             isSelected = item.id in selectedIds,
                             isSelected = item.id in selectedIds,
                             canReorder = state.sort == BookSourceSort.Default && !state.groupByDomain,
                             canReorder = state.sort == BookSourceSort.Default && !state.groupByDomain,
                             inSelectionMode = selectedIds.isNotEmpty(),
                             inSelectionMode = selectedIds.isNotEmpty(),
@@ -354,7 +353,7 @@ fun BookSourceScreen(
                                     )
                                     )
                                 )
                                 )
                             },
                             },
-                            onClickEdit = { onEditSource(item.source) },
+                            onClickEdit = { onEditSource(item.id) },
                             trailingAction = {
                             trailingAction = {
                                 SmallPlainButton(
                                 SmallPlainButton(
                                     icon = Icons.Default.Delete,
                                     icon = Icons.Default.Delete,

+ 33 - 6
app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt

@@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.flow.update
 import kotlinx.coroutines.flow.update
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
@@ -39,6 +40,7 @@ class BookSourceViewModel(application: Application) : ViewModel() {
     private val sortAscending = MutableStateFlow(true)
     private val sortAscending = MutableStateFlow(true)
     private val groupByDomain = MutableStateFlow(false)
     private val groupByDomain = MutableStateFlow(false)
     private val localItems = MutableStateFlow<List<BookSourcePart>?>(null)
     private val localItems = MutableStateFlow<List<BookSourcePart>?>(null)
+    private val enabledOverrides = MutableStateFlow<Map<String, Boolean>>(emptyMap())
 
 
     val uiState = combine(
     val uiState = combine(
         dao.flowAll(),
         dao.flowAll(),
@@ -49,7 +51,8 @@ class BookSourceViewModel(application: Application) : ViewModel() {
         sort,
         sort,
         sortAscending,
         sortAscending,
         groupByDomain,
         groupByDomain,
-        localItems
+        localItems,
+        enabledOverrides,
     ) { values ->
     ) { values ->
         @Suppress("UNCHECKED_CAST")
         @Suppress("UNCHECKED_CAST")
         val sourceItems = (values[0] as List<BookSourcePart>)
         val sourceItems = (values[0] as List<BookSourcePart>)
@@ -61,13 +64,22 @@ class BookSourceViewModel(application: Application) : ViewModel() {
         val ascending = values[6] as Boolean
         val ascending = values[6] as Boolean
         val byDomain = values[7] as Boolean
         val byDomain = values[7] as Boolean
         val local = values[8] as List<BookSourcePart>?
         val local = values[8] as List<BookSourcePart>?
-        val visible = local ?: sourceItems.filterFor(activeFilter, query)
-            .sortFor(activeSort, ascending, byDomain)
+        val pendingEnabled = values[9] as Map<String, Boolean>
+        val visible = if (local == null) {
+            sourceItems.filterFor(activeFilter, query).sortFor(activeSort, ascending, byDomain)
+        } else {
+            val latestById = sourceItems.associateBy { it.bookSourceUrl }
+            local.mapNotNull { latestById[it.bookSourceUrl] }
+        }
         BookSourceUiState(
         BookSourceUiState(
             items = visible.map { source ->
             items = visible.map { source ->
                 BookSourceItemUi(
                 BookSourceItemUi(
-                    source = source,
+                    id = source.bookSourceUrl,
                     domain = NetworkUtils.getSubDomainOrNull(source.bookSourceUrl) ?: "#",
                     domain = NetworkUtils.getSubDomainOrNull(source.bookSourceUrl) ?: "#",
+                    name = source.bookSourceName,
+                    group = source.bookSourceGroup,
+                    enabled = pendingEnabled[source.bookSourceUrl] ?: source.enabled,
+                    customOrder = source.customOrder,
                 )
                 )
             }.toImmutableList(),
             }.toImmutableList(),
             selectedIds = selected.intersect(visible.map { it.bookSourceUrl }.toSet())
             selectedIds = selected.intersect(visible.map { it.bookSourceUrl }.toSet())
@@ -112,7 +124,7 @@ class BookSourceViewModel(application: Application) : ViewModel() {
                 localItems.value = null; groupByDomain.update { !it }
                 localItems.value = null; groupByDomain.update { !it }
             }
             }
 
 
-            is BookSourceIntent.SetEnabled -> launch { dao.enable(intent.id, intent.enabled) }
+            is BookSourceIntent.SetEnabled -> setEnabled(intent.id, intent.enabled)
             is BookSourceIntent.SetEnabledForSelection -> launch {
             is BookSourceIntent.SetEnabledForSelection -> launch {
                 dao.enable(
                 dao.enable(
                     intent.enabled,
                     intent.enabled,
@@ -137,6 +149,19 @@ class BookSourceViewModel(application: Application) : ViewModel() {
     private fun launch(block: suspend () -> Unit) =
     private fun launch(block: suspend () -> Unit) =
         viewModelScope.launch(Dispatchers.IO) { block() }
         viewModelScope.launch(Dispatchers.IO) { block() }
 
 
+    private fun setEnabled(id: String, enabled: Boolean) {
+        enabledOverrides.update { it + (id to enabled) }
+        viewModelScope.launch(Dispatchers.IO) {
+            runCatching {
+                dao.enable(id, enabled)
+                dao.flowAll().first { sources ->
+                    sources.firstOrNull { it.bookSourceUrl == id }?.enabled == enabled
+                }
+            }
+            enabledOverrides.update { it - id }
+        }
+    }
+
     private fun parts(ids: Set<String>) = dao.allPart.filter { it.bookSourceUrl in ids }
     private fun parts(ids: Set<String>) = dao.allPart.filter { it.bookSourceUrl in ids }
     private fun updateExplore(ids: Set<String>, enabled: Boolean) =
     private fun updateExplore(ids: Set<String>, enabled: Boolean) =
         launch { dao.enableExplore(enabled, parts(ids)) }
         launch { dao.enableExplore(enabled, parts(ids)) }
@@ -166,7 +191,9 @@ class BookSourceViewModel(application: Application) : ViewModel() {
 
 
     private fun moveItem(from: Int, to: Int) {
     private fun moveItem(from: Int, to: Int) {
         if (sort.value != BookSourceSort.Default || groupByDomain.value) return
         if (sort.value != BookSourceSort.Default || groupByDomain.value) return
-        val moved = (localItems.value ?: uiState.value.items.map { it.source }).toMutableList()
+        val moved = (localItems.value ?: uiState.value.items.map { item ->
+            BookSourcePart(bookSourceUrl = item.id, customOrder = item.customOrder)
+        }).toMutableList()
         if (from !in moved.indices || to !in moved.indices) return
         if (from !in moved.indices || to !in moved.indices) return
         moved.add(to, moved.removeAt(from)); localItems.value = moved
         moved.add(to, moved.removeAt(from)); localItems.value = moved
     }
     }