Skip to content

Commit 6b33a9b

Browse files
committed
feat(ui): persist schema list (deploy) after changing enabled schemas
1 parent 04546ed commit 6b33a9b

2 files changed

Lines changed: 86 additions & 4 deletions

File tree

app/src/main/java/com/osfans/trime/ui/main/settings/schema/SchemaListFragment.kt

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66
package com.osfans.trime.ui.main.settings.schema
77

88
import android.view.View
9+
import androidx.lifecycle.lifecycleScope
910
import com.osfans.trime.core.SchemaItem
11+
import com.osfans.trime.daemon.RimeDaemon
1012
import com.osfans.trime.daemon.launchOnReady
1113
import com.osfans.trime.ui.components.OnItemChangedListener
1214
import com.osfans.trime.ui.main.settings.ProgressFragment
15+
import com.osfans.trime.util.NaiveDustman
16+
import kotlinx.coroutines.Dispatchers
17+
import kotlinx.coroutines.NonCancellable
18+
import kotlinx.coroutines.launch
1319

1420
class SchemaListFragment :
1521
ProgressFragment(),
@@ -28,6 +34,8 @@ class SchemaListFragment :
2834

2935
private lateinit var ui: SchemaListUi
3036

37+
private val dustman = NaiveDustman<SchemaItem>()
38+
3139
override suspend fun initialize(): View {
3240
val available = rime.runOnReady { availableSchemata().toSet() }
3341
val enabled = rime.runOnReady { enabledSchemata().map { it.id } }
@@ -38,6 +46,7 @@ class SchemaListFragment :
3846
initialEntries = entries,
3947
contentSource = { (available - adapter.items.toSet()).toTypedArray() },
4048
)
49+
resetDustman()
4150
ui.adapter.setViewModel(viewModel)
4251
ui.adapter.addOnItemChangedListener(this)
4352
viewModel.enableToolbarEditButton(enabled.isNotEmpty()) {
@@ -56,6 +65,7 @@ class SchemaListFragment :
5665
}
5766

5867
override fun onStop() {
68+
persistSchemaList()
5969
if (::ui.isInitialized) {
6070
ui.adapter.exitMultiSelect()
6171
}
@@ -74,21 +84,34 @@ class SchemaListFragment :
7484
idx: Int,
7585
item: SchemaItem,
7686
) {
77-
updateSchemaState()
87+
dustman.addOrUpdate(item.toString(), item)
7888
}
7989

8090
override fun onItemRemoved(
8191
idx: Int,
8292
item: SchemaItem,
8393
) {
84-
updateSchemaState()
94+
dustman.remove(item.toString())
8595
}
8696

8797
override fun onItemAddedBatch(items: List<SchemaItem>) {
88-
updateSchemaState()
98+
items.forEach { dustman.addOrUpdate(it.toString(), it) }
8999
}
90100

91101
override fun onItemRemovedBatch(items: List<SchemaItem>) {
92-
updateSchemaState()
102+
items.forEach { dustman.remove(it.toString()) }
103+
}
104+
105+
private fun persistSchemaList() {
106+
if (!dustman.dirty) return
107+
resetDustman()
108+
lifecycleScope.launch(NonCancellable + Dispatchers.Default) {
109+
updateSchemaState()
110+
RimeDaemon.restartRime(true)
111+
}
112+
}
113+
114+
private fun resetDustman() {
115+
dustman.reset(ui.adapter.items.associateBy { it.toString() })
93116
}
94117
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2015 - 2025 Rime community
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*/
5+
package com.osfans.trime.util
6+
7+
import kotlin.properties.Delegates
8+
9+
class NaiveDustman<T> {
10+
11+
private val initialValues = mutableMapOf<String, T>()
12+
13+
private val dirtyStatus = mutableSetOf<String>()
14+
15+
var dirty by Delegates.observable(false) { _, old, new ->
16+
if (old != new) {
17+
if (new) {
18+
onDirty?.invoke()
19+
} else {
20+
onClean?.invoke()
21+
}
22+
}
23+
}
24+
private set
25+
26+
var onDirty: (() -> Unit)? = null
27+
var onClean: (() -> Unit)? = null
28+
29+
fun forceDirty() {
30+
dirty = true
31+
}
32+
33+
private fun updateDirtyStatus(key: String, boolean: Boolean) {
34+
if (boolean) {
35+
dirtyStatus.add(key)
36+
} else {
37+
dirtyStatus.remove(key)
38+
}
39+
dirty = dirtyStatus.isNotEmpty()
40+
}
41+
42+
fun addOrUpdate(key: String, value: T) {
43+
if (initialValues.containsKey(key)) {
44+
updateDirtyStatus(key, initialValues[key] != value)
45+
} else {
46+
updateDirtyStatus(key, true)
47+
}
48+
}
49+
50+
fun remove(key: String) {
51+
updateDirtyStatus(key, initialValues.containsKey(key))
52+
}
53+
54+
fun reset(initial: Map<String, T>) {
55+
dirty = false
56+
dirtyStatus.clear()
57+
initialValues.putAll(initial)
58+
}
59+
}

0 commit comments

Comments
 (0)