refactor: 重构TXT目录规则界面为MVI架构
This commit is contained in:
@@ -14,10 +14,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.SnackbarResult
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -44,29 +42,57 @@ import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
|
||||
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
|
||||
import io.legado.app.ui.widget.components.icon.AppIcons
|
||||
import io.legado.app.ui.widget.components.importComponents.BatchImportDialog
|
||||
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
|
||||
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
|
||||
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
|
||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
||||
import io.legado.app.ui.widget.components.rules.RuleEditFields
|
||||
import io.legado.app.ui.widget.components.rules.RuleEditSheet
|
||||
import io.legado.app.ui.widget.components.rules.RuleListScaffold
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
import sh.calvin.reorderable.rememberReorderableLazyListState
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun TxtRuleScreen(
|
||||
fun TxtRuleRouteScreen(
|
||||
viewModel: TxtTocRuleViewModel = koinViewModel(),
|
||||
initialRule: String? = null,
|
||||
onPickRule: ((String) -> Unit)? = null,
|
||||
onBackClick: () -> Unit
|
||||
) {
|
||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
val importState by viewModel.importState.collectAsStateWithLifecycle()
|
||||
|
||||
TxtRuleScreen(
|
||||
state = uiState,
|
||||
importState = importState,
|
||||
events = viewModel.events,
|
||||
onIntent = viewModel::onIntent,
|
||||
onPasteRule = viewModel::pasteRule,
|
||||
initialRule = initialRule,
|
||||
onPickRule = onPickRule,
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun TxtRuleScreen(
|
||||
state: TxtTocRuleUiState,
|
||||
importState: BaseImportUiState<TxtTocRule>,
|
||||
events: Flow<BaseRuleEvent>,
|
||||
onIntent: (TxtTocRuleIntent) -> Unit,
|
||||
onPasteRule: () -> TxtTocRule?,
|
||||
initialRule: String? = null,
|
||||
onPickRule: ((String) -> Unit)? = null,
|
||||
onBackClick: () -> Unit
|
||||
) {
|
||||
|
||||
val context = LocalContext.current
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
|
||||
val rules = uiState.items
|
||||
val selectedIds = uiState.selectedIds
|
||||
val rules = state.items
|
||||
val selectedIds = state.selectedIds
|
||||
val isPickMode = onPickRule != null
|
||||
val inSelectionMode = if (isPickMode) false else selectedIds.isNotEmpty()
|
||||
|
||||
@@ -82,17 +108,15 @@ fun TxtRuleScreen(
|
||||
var showExportSheet by remember { mutableStateOf(false) }
|
||||
|
||||
val reorderableState = rememberReorderableLazyListState(listState) { from, to ->
|
||||
viewModel.moveItemInList(from.index, to.index)
|
||||
onIntent(TxtTocRuleIntent.MoveItem(from.index, to.index))
|
||||
hapticFeedback.performHapticFeedback(HapticFeedbackType.SegmentFrequentTick)
|
||||
}
|
||||
|
||||
val clipboardManager = LocalClipboard.current
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val importState by viewModel.importState.collectAsStateWithLifecycle()
|
||||
val sheetState = rememberModalBottomSheetState()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.events.collect { event ->
|
||||
events.collect { event ->
|
||||
when (event) {
|
||||
is BaseRuleEvent.ShowSnackbar -> {
|
||||
val result = snackbarHostState.showSnackbar(
|
||||
@@ -121,7 +145,7 @@ fun TxtRuleScreen(
|
||||
uri?.let {
|
||||
context.contentResolver.openInputStream(it)?.use { stream ->
|
||||
val text = stream.reader().readText()
|
||||
viewModel.importSource(text)
|
||||
onIntent(TxtTocRuleIntent.ImportSource(text))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,7 +154,7 @@ fun TxtRuleScreen(
|
||||
val exportDoc = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.CreateDocument("application/json"),
|
||||
onResult = { uri ->
|
||||
uri?.let { viewModel.exportToUri(it, rules, selectedIds) }
|
||||
uri?.let { onIntent(TxtTocRuleIntent.ExportSelection(it)) }
|
||||
}
|
||||
)
|
||||
|
||||
@@ -140,7 +164,7 @@ fun TxtRuleScreen(
|
||||
onDismissRequest = { showUrlInput = false },
|
||||
onConfirm = {
|
||||
showUrlInput = false
|
||||
viewModel.importSource(it)
|
||||
onIntent(TxtTocRuleIntent.ImportSource(it))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -154,7 +178,7 @@ fun TxtRuleScreen(
|
||||
},
|
||||
onUpload = {
|
||||
showExportSheet = false
|
||||
viewModel.uploadSelectedRules(selectedIds, rules)
|
||||
onIntent(TxtTocRuleIntent.UploadSelection)
|
||||
},
|
||||
allowExtensions = arrayOf("json")
|
||||
)
|
||||
@@ -178,11 +202,11 @@ fun TxtRuleScreen(
|
||||
BatchImportDialog(
|
||||
title = stringResource(R.string.import_txt_toc_rule),
|
||||
importState = importState,
|
||||
onDismissRequest = { viewModel.cancelImport() },
|
||||
onToggleItem = { viewModel.toggleImportSelection(it) },
|
||||
onToggleAll = { viewModel.toggleImportAll(it) },
|
||||
onUpdateItem = { index, rule -> viewModel.updateImportItem(index, rule) },
|
||||
onConfirm = { viewModel.saveImportedRules() },
|
||||
onDismissRequest = { onIntent(TxtTocRuleIntent.CancelImport) },
|
||||
onToggleItem = { onIntent(TxtTocRuleIntent.ToggleImportSelection(it)) },
|
||||
onToggleAll = { onIntent(TxtTocRuleIntent.ToggleImportAll(it)) },
|
||||
onUpdateItem = { index, rule -> onIntent(TxtTocRuleIntent.UpdateImportItem(index, rule)) },
|
||||
onConfirm = { onIntent(TxtTocRuleIntent.SaveImportedRules) },
|
||||
itemTitle = { rule -> rule.name },
|
||||
itemSubtitle = { rule ->
|
||||
rule.rule.takeIf { it.isNotBlank() }
|
||||
@@ -191,7 +215,7 @@ fun TxtRuleScreen(
|
||||
|
||||
LaunchedEffect(reorderableState.isAnyItemDragging) {
|
||||
if (!reorderableState.isAnyItemDragging) {
|
||||
viewModel.saveSortOrder()
|
||||
onIntent(TxtTocRuleIntent.SaveSortOrder)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +226,7 @@ fun TxtRuleScreen(
|
||||
text = stringResource(R.string.sure_del),
|
||||
confirmText = stringResource(R.string.ok),
|
||||
onConfirm = { rule ->
|
||||
viewModel.delete(rule)
|
||||
onIntent(TxtTocRuleIntent.DeleteRule(rule))
|
||||
showDeleteRuleDialog = null
|
||||
},
|
||||
dismissText = stringResource(R.string.cancel),
|
||||
@@ -220,17 +244,12 @@ fun TxtRuleScreen(
|
||||
editingRule = null
|
||||
},
|
||||
onSave = { updatedRule ->
|
||||
//TODO:我很想把他改为自增主键,但为了兼容性日后再�?
|
||||
if (editingRule == null) {
|
||||
viewModel.insert(updatedRule)
|
||||
} else {
|
||||
viewModel.update(updatedRule)
|
||||
}
|
||||
onIntent(TxtTocRuleIntent.SaveRule(updatedRule, isNew = editingRule == null))
|
||||
showEditSheet = false
|
||||
editingRule = null
|
||||
},
|
||||
onCopy = { viewModel.copyRule(it) },
|
||||
onPaste = { viewModel.pasteRule() },
|
||||
onCopy = { onIntent(TxtTocRuleIntent.CopyRule(it)) },
|
||||
onPaste = onPasteRule,
|
||||
toFields = { r ->
|
||||
RuleEditFields(
|
||||
name = r?.name ?: "",
|
||||
@@ -257,27 +276,22 @@ fun TxtRuleScreen(
|
||||
} else {
|
||||
stringResource(R.string.txt_toc_rule)
|
||||
},
|
||||
state = uiState,
|
||||
state = state,
|
||||
onBackClick = { onBackClick() },
|
||||
onSearchToggle = { active ->
|
||||
viewModel.setSearchMode(active)
|
||||
onIntent(TxtTocRuleIntent.SetSearchMode(active))
|
||||
},
|
||||
onSearchQueryChange = { viewModel.setSearchKey(it) },
|
||||
onSearchQueryChange = { onIntent(TxtTocRuleIntent.UpdateSearchQuery(it)) },
|
||||
searchPlaceholder = stringResource(R.string.replace_purify_search),
|
||||
onClearSelection = { viewModel.setSelection(emptySet()) },
|
||||
onSelectAll = { viewModel.setSelection(rules.map { it.id }.toSet()) },
|
||||
onSelectInvert = {
|
||||
val allIds = rules.map { it.id }.toSet()
|
||||
viewModel.setSelection(allIds - selectedIds)
|
||||
},
|
||||
onClearSelection = { onIntent(TxtTocRuleIntent.ClearSelection) },
|
||||
onSelectAll = { onIntent(TxtTocRuleIntent.SelectAll) },
|
||||
onSelectInvert = { onIntent(TxtTocRuleIntent.InvertSelection) },
|
||||
selectionSecondaryActions = listOf(
|
||||
ActionItem(text = stringResource(R.string.enable), onClick = {
|
||||
viewModel.enableSelectionByIds(selectedIds)
|
||||
viewModel.setSelection(emptySet())
|
||||
onIntent(TxtTocRuleIntent.EnableSelection)
|
||||
}),
|
||||
ActionItem(text = stringResource(R.string.disable_selection), onClick = {
|
||||
viewModel.disableSelectionByIds(selectedIds)
|
||||
viewModel.setSelection(emptySet())
|
||||
onIntent(TxtTocRuleIntent.DisableSelection)
|
||||
}),
|
||||
ActionItem(
|
||||
text = stringResource(R.string.export),
|
||||
@@ -285,8 +299,8 @@ fun TxtRuleScreen(
|
||||
),
|
||||
onDeleteSelected = { ids ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
viewModel.delSelectionByIds(ids as Set<Long>)
|
||||
viewModel.setSelection(emptySet())
|
||||
onIntent(TxtTocRuleIntent.SetSelection(ids as Set<Long>))
|
||||
onIntent(TxtTocRuleIntent.DeleteSelection)
|
||||
},
|
||||
onAddClick = {
|
||||
editingRule = null
|
||||
@@ -302,7 +316,7 @@ fun TxtRuleScreen(
|
||||
) { paddingValues ->
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.fillMaxSize()
|
||||
) {
|
||||
FastScrollLazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
@@ -334,10 +348,12 @@ fun TxtRuleScreen(
|
||||
onPickRule.invoke(item.rule.rule)
|
||||
onBackClick()
|
||||
} else {
|
||||
viewModel.toggleSelection(item.id)
|
||||
onIntent(TxtTocRuleIntent.ToggleSelection(item.id))
|
||||
}
|
||||
},
|
||||
onEnabledChange = { enabled -> viewModel.update(item.rule.copy(enable = enabled)) },
|
||||
onEnabledChange = { enabled ->
|
||||
onIntent(TxtTocRuleIntent.SetRuleEnabled(item.rule, enabled))
|
||||
},
|
||||
onClickEdit = { editingRule = item.rule; showEditSheet = true },
|
||||
trailingAction = {
|
||||
SmallPlainButton(
|
||||
@@ -353,7 +369,7 @@ fun TxtRuleScreen(
|
||||
listState = listState,
|
||||
items = rules,
|
||||
selectedIds = selectedIds,
|
||||
onSelectionChange = { viewModel.setSelection(it) },
|
||||
onSelectionChange = { onIntent(TxtTocRuleIntent.SetSelection(it)) },
|
||||
idProvider = { it.id },
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
@@ -364,4 +380,3 @@ fun TxtRuleScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class TxtTocRuleActivity : BaseComposeActivity() {
|
||||
val initialRule = intent.getStringExtra("tocRegex")
|
||||
|
||||
AppTheme {
|
||||
TxtRuleScreen(
|
||||
TxtRuleRouteScreen(
|
||||
initialRule = initialRule,
|
||||
onPickRule = if (initialRule != null) { rule ->
|
||||
val data = Intent().apply {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package io.legado.app.ui.book.toc.rule
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.compose.runtime.Immutable
|
||||
import io.legado.app.data.entities.TxtTocRule
|
||||
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
|
||||
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.SelectableItem
|
||||
|
||||
@Immutable
|
||||
data class TxtTocRuleItemUi(
|
||||
override val id: Long,
|
||||
val name: String,
|
||||
val isEnabled: Boolean,
|
||||
val rule: TxtTocRule,
|
||||
val example: String = ""
|
||||
) : SelectableItem<Long>
|
||||
|
||||
data class TxtTocRuleUiState(
|
||||
override val items: List<TxtTocRuleItemUi> = emptyList(),
|
||||
override val selectedIds: Set<Long> = emptySet(),
|
||||
override val searchKey: String = "",
|
||||
val interaction: InteractionState = InteractionState()
|
||||
) : ListUiState<TxtTocRuleItemUi> {
|
||||
override val isSearch: Boolean get() = interaction.isSearchMode
|
||||
override val isLoading: Boolean get() = interaction.isUploading
|
||||
}
|
||||
|
||||
sealed interface TxtTocRuleIntent {
|
||||
data class SetSearchMode(val active: Boolean) : TxtTocRuleIntent
|
||||
data class UpdateSearchQuery(val query: String) : TxtTocRuleIntent
|
||||
data object ClearSelection : TxtTocRuleIntent
|
||||
data object SelectAll : TxtTocRuleIntent
|
||||
data object InvertSelection : TxtTocRuleIntent
|
||||
data class SetSelection(val ids: Set<Long>) : TxtTocRuleIntent
|
||||
data class ToggleSelection(val id: Long) : TxtTocRuleIntent
|
||||
data object EnableSelection : TxtTocRuleIntent
|
||||
data object DisableSelection : TxtTocRuleIntent
|
||||
data object DeleteSelection : TxtTocRuleIntent
|
||||
data object UploadSelection : TxtTocRuleIntent
|
||||
data class ExportSelection(val uri: Uri) : TxtTocRuleIntent
|
||||
data class MoveItem(val from: Int, val to: Int) : TxtTocRuleIntent
|
||||
data object SaveSortOrder : TxtTocRuleIntent
|
||||
data class SaveRule(val rule: TxtTocRule, val isNew: Boolean) : TxtTocRuleIntent
|
||||
data class DeleteRule(val rule: TxtTocRule) : TxtTocRuleIntent
|
||||
data class SetRuleEnabled(val rule: TxtTocRule, val enabled: Boolean) : TxtTocRuleIntent
|
||||
data class CopyRule(val rule: TxtTocRule) : TxtTocRuleIntent
|
||||
data class ImportSource(val text: String) : TxtTocRuleIntent
|
||||
data object CancelImport : TxtTocRuleIntent
|
||||
data class ToggleImportSelection(val index: Int) : TxtTocRuleIntent
|
||||
data class ToggleImportAll(val isSelected: Boolean) : TxtTocRuleIntent
|
||||
data class UpdateImportItem(val index: Int, val rule: TxtTocRule) : TxtTocRuleIntent
|
||||
data object SaveImportedRules : TxtTocRuleIntent
|
||||
}
|
||||
|
||||
sealed interface TxtTocRuleEffect
|
||||
|
||||
data class TxtTocRuleRenderState(
|
||||
val uiState: TxtTocRuleUiState,
|
||||
val importState: BaseImportUiState<TxtTocRule>,
|
||||
)
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.legado.app.ui.book.toc.rule
|
||||
|
||||
import android.app.Application
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseRuleViewModel
|
||||
@@ -10,8 +9,6 @@ import io.legado.app.data.repository.TxtTocRuleRepository
|
||||
import io.legado.app.data.repository.UploadRepository
|
||||
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
|
||||
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.SelectableItem
|
||||
import io.legado.app.utils.GSON
|
||||
import io.legado.app.utils.fromJsonArray
|
||||
import io.legado.app.utils.fromJsonObject
|
||||
@@ -21,28 +18,9 @@ import io.legado.app.utils.isJsonObject
|
||||
import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Immutable
|
||||
data class TxtTocRuleItemUi(
|
||||
override val id: Long,
|
||||
val name: String,
|
||||
val isEnabled: Boolean,
|
||||
val rule: TxtTocRule,
|
||||
val example: String = ""
|
||||
) : SelectableItem<Long>
|
||||
|
||||
data class TxtTocRuleUiState(
|
||||
override val items: List<TxtTocRuleItemUi> = emptyList(),
|
||||
override val selectedIds: Set<Long> = emptySet(),
|
||||
override val searchKey: String = "",
|
||||
val interaction: InteractionState = InteractionState()
|
||||
) : ListUiState<TxtTocRuleItemUi> {
|
||||
override val isSearch: Boolean get() = interaction.isSearchMode
|
||||
override val isLoading: Boolean get() = interaction.isUploading
|
||||
}
|
||||
|
||||
|
||||
class TxtTocRuleViewModel(
|
||||
application: Application,
|
||||
uploadRepository: UploadRepository
|
||||
@@ -55,9 +33,54 @@ class TxtTocRuleViewModel(
|
||||
|
||||
override val rawDataFlow: Flow<List<TxtTocRule>> = repository.flowAll()
|
||||
|
||||
fun onIntent(intent: TxtTocRuleIntent) {
|
||||
when (intent) {
|
||||
is TxtTocRuleIntent.SetSearchMode -> setSearchMode(intent.active)
|
||||
is TxtTocRuleIntent.UpdateSearchQuery -> setSearchKey(intent.query)
|
||||
TxtTocRuleIntent.ClearSelection -> setSelection(emptySet())
|
||||
TxtTocRuleIntent.SelectAll -> selectAll()
|
||||
TxtTocRuleIntent.InvertSelection -> invertSelection()
|
||||
is TxtTocRuleIntent.SetSelection -> setSelection(intent.ids)
|
||||
is TxtTocRuleIntent.ToggleSelection -> toggleSelection(intent.id)
|
||||
TxtTocRuleIntent.EnableSelection -> {
|
||||
enableSelectionByIds(uiState.value.selectedIds)
|
||||
setSelection(emptySet())
|
||||
}
|
||||
TxtTocRuleIntent.DisableSelection -> {
|
||||
disableSelectionByIds(uiState.value.selectedIds)
|
||||
setSelection(emptySet())
|
||||
}
|
||||
TxtTocRuleIntent.DeleteSelection -> {
|
||||
delSelectionByIds(uiState.value.selectedIds)
|
||||
setSelection(emptySet())
|
||||
}
|
||||
TxtTocRuleIntent.UploadSelection -> {
|
||||
val state = uiState.value
|
||||
uploadSelectedRules(state.selectedIds, state.items)
|
||||
}
|
||||
is TxtTocRuleIntent.ExportSelection -> {
|
||||
val state = uiState.value
|
||||
exportToUri(intent.uri, state.items, state.selectedIds)
|
||||
}
|
||||
is TxtTocRuleIntent.MoveItem -> moveItemInList(intent.from, intent.to)
|
||||
TxtTocRuleIntent.SaveSortOrder -> saveSortOrder()
|
||||
is TxtTocRuleIntent.SaveRule -> save(intent.rule)
|
||||
is TxtTocRuleIntent.DeleteRule -> delete(intent.rule)
|
||||
is TxtTocRuleIntent.SetRuleEnabled -> update(intent.rule.copy(enable = intent.enabled))
|
||||
is TxtTocRuleIntent.CopyRule -> copyRule(intent.rule)
|
||||
is TxtTocRuleIntent.ImportSource -> importSource(intent.text)
|
||||
TxtTocRuleIntent.CancelImport -> cancelImport()
|
||||
is TxtTocRuleIntent.ToggleImportSelection -> toggleImportSelection(intent.index)
|
||||
is TxtTocRuleIntent.ToggleImportAll -> toggleImportAll(intent.isSelected)
|
||||
is TxtTocRuleIntent.UpdateImportItem -> updateImportItem(intent.index, intent.rule)
|
||||
TxtTocRuleIntent.SaveImportedRules -> saveImportedRules()
|
||||
}
|
||||
}
|
||||
|
||||
override fun TxtTocRule.toUiItem() =
|
||||
TxtTocRuleItemUi(id, name, enable, this, example = example ?: "")
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun filterData(data: List<TxtTocRule>, key: String): List<TxtTocRule> {
|
||||
val filtered = if (key.isEmpty()) data
|
||||
else data.filter { it.name.contains(key, ignoreCase = true) }
|
||||
@@ -83,7 +106,7 @@ class TxtTocRuleViewModel(
|
||||
)
|
||||
}
|
||||
|
||||
fun saveSortOrder() {
|
||||
private fun saveSortOrder() {
|
||||
val currentLocal = _localItems.value ?: return
|
||||
viewModelScope.launch {
|
||||
repository.saveOrder(currentLocal.map { it.rule })
|
||||
@@ -91,7 +114,7 @@ class TxtTocRuleViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
fun save(rule: TxtTocRule) {
|
||||
private fun save(rule: TxtTocRule) {
|
||||
viewModelScope.launch {
|
||||
if (rule.id == 0L) {
|
||||
repository.insert(rule)
|
||||
@@ -101,9 +124,10 @@ class TxtTocRuleViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
fun update(vararg rules: TxtTocRule) = viewModelScope.launch { repository.update(*rules) }
|
||||
fun insert(vararg rules: TxtTocRule) = viewModelScope.launch { repository.insert(*rules) }
|
||||
fun delete(vararg rules: TxtTocRule) = viewModelScope.launch { repository.delete(*rules) }
|
||||
private fun update(vararg rules: TxtTocRule) = viewModelScope.launch { repository.update(*rules) }
|
||||
private fun insert(vararg rules: TxtTocRule) = viewModelScope.launch { repository.insert(*rules) }
|
||||
private fun delete(vararg rules: TxtTocRule) = viewModelScope.launch { repository.delete(*rules) }
|
||||
|
||||
fun enableSelectionByIds(ids: Set<Long>) =
|
||||
viewModelScope.launch { repository.enableByIds(ids, true) }
|
||||
|
||||
@@ -112,6 +136,15 @@ class TxtTocRuleViewModel(
|
||||
|
||||
fun delSelectionByIds(ids: Set<Long>) = viewModelScope.launch { repository.deleteByIds(ids) }
|
||||
|
||||
private fun selectAll() {
|
||||
setSelection(uiState.value.items.map { it.id }.toSet())
|
||||
}
|
||||
|
||||
private fun invertSelection() {
|
||||
val state = uiState.value
|
||||
setSelection(state.items.map { it.id }.toSet() - state.selectedIds)
|
||||
}
|
||||
|
||||
override suspend fun generateJson(entities: List<TxtTocRule>): String = GSON.toJson(entities)
|
||||
|
||||
override fun parseImportRules(text: String): List<TxtTocRule> {
|
||||
@@ -141,7 +174,7 @@ class TxtTocRuleViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
fun copyRule(rule: TxtTocRule) {
|
||||
private fun copyRule(rule: TxtTocRule) {
|
||||
context.sendToClip(GSON.toJson(rule))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user