Skip to content

Commit 28fa4c0

Browse files
committed
fix: clipboard update not in time
refactor: optimize the flow after accepting a database bean
1 parent d6fffba commit 28fa4c0

File tree

4 files changed

+73
-73
lines changed

4 files changed

+73
-73
lines changed

app/src/main/java/com/osfans/trime/data/db/ClipboardHelper.kt

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ object ClipboardHelper :
2727
private lateinit var clbDao: DatabaseDao
2828

2929
fun interface OnClipboardUpdateListener {
30-
fun onUpdate(text: String)
30+
fun onUpdate(bean: DatabaseBean)
3131
}
3232

3333
private val mutex = Mutex()
@@ -42,21 +42,11 @@ object ClipboardHelper :
4242
private val onUpdateListeners = WeakHashSet<OnClipboardUpdateListener>()
4343

4444
fun addOnUpdateListener(listener: OnClipboardUpdateListener) {
45-
Timber.d("Add OnUpdateListener: $listener")
46-
val result = onUpdateListeners.add(listener)
47-
Timber.d(
48-
"onUpdateListeners.add: result = $result," +
49-
"onUpdateListeners.size = ${onUpdateListeners.size}",
50-
)
45+
onUpdateListeners.add(listener)
5146
}
5247

5348
fun removeOnUpdateListener(listener: OnClipboardUpdateListener) {
54-
Timber.d("Remove OnUpdateListener: $listener")
55-
val result = onUpdateListeners.remove(listener)
56-
Timber.d(
57-
"onUpdateListeners.remove: result = $result," +
58-
"onUpdateListeners.size = ${onUpdateListeners.size}",
59-
)
49+
onUpdateListeners.remove(listener)
6050
}
6151

6252
private val limit get() = AppPrefs.defaultInstance().clipboard.clipboardLimit
@@ -77,6 +67,11 @@ object ClipboardHelper :
7767

7868
var lastBean: DatabaseBean? = null
7969

70+
private fun updateLastBean(bean: DatabaseBean) {
71+
lastBean = bean
72+
onUpdateListeners.forEach { it.onUpdate(bean) }
73+
}
74+
8075
fun init(context: Context) {
8176
clipboardManager.addPrimaryClipChangedListener(this)
8277
clbDb =
@@ -98,6 +93,16 @@ object ClipboardHelper :
9893

9994
suspend fun unpin(id: Int) = clbDao.updatePinned(id, false)
10095

96+
suspend fun updateText(
97+
id: Int,
98+
text: String,
99+
) {
100+
lastBean?.let {
101+
if (id == it.id) updateLastBean(it.copy(text = text))
102+
}
103+
clbDao.updateText(id, text)
104+
}
105+
101106
suspend fun delete(id: Int) {
102107
clbDao.delete(id)
103108
updateItemCount()
@@ -131,49 +136,32 @@ object ClipboardHelper :
131136
it.text!!.isNotBlank() &&
132137
!it.text.matchesAny(output)
133138
}?.let { b ->
134-
if (b.text?.removeRegexSet(compare)?.isEmpty() == true) return
139+
if (b.text!!.removeRegexSet(compare).isEmpty()) return
135140
Timber.d("Accept clipboard $b")
136141
launch {
137142
mutex.withLock {
138-
val all = clbDao.getAll()
139-
var pinned = false
140-
all.find { b.text == it.text }?.let {
141-
clbDao.delete(it.id)
142-
pinned = it.pinned
143+
clbDao.find(b.text)?.let {
144+
updateLastBean(it.copy(time = b.time))
145+
clbDao.updateTime(it.id, b.time)
146+
return@launch
143147
}
144-
val rowId = clbDao.insert(b.copy(pinned = pinned))
148+
val rowId = clbDao.insert(b)
145149
removeOutdated()
146150
updateItemCount()
147-
clbDao.get(rowId)?.let { newBean ->
148-
lastBean = newBean
149-
onUpdateListeners.forEach { listener ->
150-
listener.onUpdate(newBean.text ?: "")
151-
}
152-
}
151+
updateLastBean(clbDao.get(rowId) ?: b)
153152
}
154153
}
155154
}
156155
}
157156

158157
private suspend fun removeOutdated() {
159-
val all = clbDao.getAll()
160-
if (all.size > limit) {
158+
val unpinned = clbDao.getAllUnpinned()
159+
if (unpinned.size > limit) {
161160
val outdated =
162-
all
163-
.map {
164-
if (it.pinned) {
165-
it.copy(id = Int.MAX_VALUE)
166-
} else {
167-
it
168-
}
169-
}.sortedBy { it.id }
170-
.subList(0, all.size - limit)
171-
clbDao.delete(outdated)
161+
unpinned
162+
.sortedBy { it.id }
163+
.getOrNull(unpinned.size - limit)
164+
clbDao.deletedUnpinnedEarlierThan(outdated?.time ?: System.currentTimeMillis())
172165
}
173166
}
174-
175-
suspend fun updateText(
176-
id: Int,
177-
text: String,
178-
) = clbDao.updateText(id, text)
179167
}

app/src/main/java/com/osfans/trime/data/db/DatabaseDao.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ interface DatabaseDao {
3030
pinned: Boolean,
3131
)
3232

33+
@Query("UPDATE ${DatabaseBean.TABLE_NAME} SET time=:timestamp WHERE id=:id")
34+
suspend fun updateTime(
35+
id: Int,
36+
timestamp: Long,
37+
)
38+
3339
@Delete
3440
suspend fun delete(bean: DatabaseBean)
3541

@@ -48,6 +54,9 @@ interface DatabaseDao {
4854
@Query("DELETE FROM ${DatabaseBean.TABLE_NAME} WHERE NOT pinned")
4955
suspend fun deleteAllUnpinned()
5056

57+
@Query("DELETE FROM ${DatabaseBean.TABLE_NAME} WHERE time<:timestamp AND pinned=0")
58+
suspend fun deletedUnpinnedEarlierThan(timestamp: Long)
59+
5160
@Query("SELECT * FROM ${DatabaseBean.TABLE_NAME} ORDER BY pinned DESC, time DESC")
5261
suspend fun getAll(): List<DatabaseBean>
5362

@@ -60,6 +69,12 @@ interface DatabaseDao {
6069
@Query("SELECT EXISTS(SELECT 1 FROM ${DatabaseBean.TABLE_NAME} WHERE pinned=0)")
6170
suspend fun haveUnpinned(): Boolean
6271

72+
@Query("SELECT * FROM ${DatabaseBean.TABLE_NAME} WHERE pinned=0")
73+
suspend fun getAllUnpinned(): List<DatabaseBean>
74+
75+
@Query("SELECT * FROM ${DatabaseBean.TABLE_NAME} WHERE text=:text LIMIT 1")
76+
suspend fun find(text: String): DatabaseBean?
77+
6378
@Query("SELECT COUNT(*) FROM ${DatabaseBean.TABLE_NAME}")
6479
suspend fun itemCount(): Int
6580
}

app/src/main/java/com/osfans/trime/data/db/DraftHelper.kt

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,12 @@ object DraftHelper : CoroutineScope by CoroutineScope(SupervisorJob() + Dispatch
6464
suspend fun updateText(
6565
id: Int,
6666
text: String,
67-
) = dftDao.updateText(id, text)
67+
) {
68+
lastBean?.let {
69+
if (id == it.id) lastBean = it.copy(text = text)
70+
}
71+
dftDao.updateText(id, text)
72+
}
6873

6974
suspend fun delete(id: Int) {
7075
dftDao.delete(id)
@@ -91,16 +96,15 @@ object DraftHelper : CoroutineScope by CoroutineScope(SupervisorJob() + Dispatch
9196
it.text!!.isNotBlank() &&
9297
!it.text.matchesAny(output)
9398
}?.let { b ->
94-
Timber.d("Accept $b")
99+
Timber.d("Accept draft $b")
95100
launch {
96101
mutex.withLock {
97-
val all = dftDao.getAll()
98-
var pinned = false
99-
all.find { b.text == it.text }?.let {
100-
dftDao.delete(it.id)
101-
pinned = it.pinned
102+
dftDao.find(b.text!!)?.let {
103+
lastBean = it.copy(time = b.time)
104+
dftDao.updateTime(it.id, b.time)
105+
return@launch
102106
}
103-
val rowId = dftDao.insert(b.copy(pinned = pinned))
107+
val rowId = dftDao.insert(b)
104108
removeOutdated()
105109
updateItemCount()
106110
dftDao.get(rowId)?.let { lastBean = it }
@@ -110,19 +114,13 @@ object DraftHelper : CoroutineScope by CoroutineScope(SupervisorJob() + Dispatch
110114
}
111115

112116
private suspend fun removeOutdated() {
113-
val all = dftDao.getAll()
114-
if (all.size > limit) {
117+
val unpinned = dftDao.getAllUnpinned()
118+
if (unpinned.size > limit) {
115119
val outdated =
116-
all
117-
.map {
118-
if (it.pinned) {
119-
it.copy(id = Int.MAX_VALUE)
120-
} else {
121-
it
122-
}
123-
}.sortedBy { it.id }
124-
.subList(0, all.size - limit)
125-
dftDao.delete(outdated)
120+
unpinned
121+
.sortedBy { it.id }
122+
.getOrNull(unpinned.size - limit)
123+
dftDao.deletedUnpinnedEarlierThan(outdated?.time ?: System.currentTimeMillis())
126124
}
127125
}
128126
}

app/src/main/java/com/osfans/trime/ime/symbol/LiquidKeyboard.kt

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ import com.osfans.trime.ime.keyboard.KeyboardWindow
3232
import com.osfans.trime.ime.window.BoardWindow
3333
import com.osfans.trime.ime.window.BoardWindowManager
3434
import com.osfans.trime.ime.window.ResidentWindow
35+
import kotlinx.coroutines.Dispatchers
3536
import kotlinx.coroutines.launch
37+
import kotlinx.coroutines.withContext
3638
import me.tatarka.inject.annotations.Inject
3739
import splitties.dimensions.dp
3840
import splitties.views.recyclerview.verticalLayoutManager
39-
import timber.log.Timber
4041

4142
@InputScope
4243
@Inject
@@ -199,10 +200,6 @@ class LiquidKeyboard(
199200
keyboardView.apply {
200201
layoutManager = oneColStaggeredGridLayoutManager
201202
adapter = dbAdapter
202-
setItemViewCacheSize(10)
203-
setHasFixedSize(false)
204-
// 调用ListView的setSelected(!ListView.isSelected())方法,这样就能及时刷新布局
205-
isSelected = true
206203
}
207204
}
208205

@@ -242,11 +239,13 @@ class LiquidKeyboard(
242239
* 实现 OnClipboardUpdateListener 中的 onUpdate
243240
* 当剪贴板内容变化且剪贴板视图处于开启状态时,更新视图.
244241
*/
245-
override fun onUpdate(text: String) {
246-
if (currentBoardType == SymbolBoardType.CLIPBOARD) {
247-
Timber.v("OnClipboardUpdateListener onUpdate: update clipboard view")
248-
service.lifecycleScope.launch {
249-
dbAdapter.submitList(ClipboardHelper.getAll())
242+
override fun onUpdate(bean: DatabaseBean) {
243+
service.lifecycleScope.launch {
244+
dbAdapter.submitList(ClipboardHelper.getAll())
245+
if (currentBoardType == SymbolBoardType.CLIPBOARD) {
246+
withContext(Dispatchers.Main) {
247+
keyboardView.scrollToPosition(0)
248+
}
250249
}
251250
}
252251
}

0 commit comments

Comments
 (0)