Skip to content

Commit be9d3ff

Browse files
committed
feat(data): initialize ClipboardHelper to enhance management of clipboard
1 parent af2a1d0 commit be9d3ff

File tree

4 files changed

+134
-1
lines changed

4 files changed

+134
-1
lines changed

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.osfans.trime.data.db
22

3+
import android.content.ClipData
34
import androidx.room.Entity
45
import androidx.room.PrimaryKey
56
import androidx.room.TypeConverter
@@ -10,11 +11,16 @@ data class DatabaseBean(
1011
val id: Int = 0,
1112
val text: String?,
1213
val html: String? = null,
13-
val type: BeanType,
14+
val type: BeanType = BeanType.TEXT,
1415
val time: Long = System.currentTimeMillis()
1516
) {
1617
companion object {
1718
const val TABLE_NAME = "t_data"
19+
20+
fun fromClipData(clipData: ClipData): DatabaseBean? {
21+
val str = clipData.getItemAt(0).text?.toString() ?: return null
22+
return DatabaseBean(text = str)
23+
}
1824
}
1925

2026
enum class BeanType {

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

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ interface DatabaseDao {
2323
@Query("DELETE FROM ${DatabaseBean.TABLE_NAME} WHERE id=:id")
2424
fun delete(id: Int)
2525

26+
@Delete
27+
fun delete(beans: List<DatabaseBean>)
28+
2629
@Query("DELETE FROM ${DatabaseBean.TABLE_NAME}")
2730
fun deleteAll()
2831

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package com.osfans.trime.data.db.clipboard
2+
3+
import android.content.ClipboardManager
4+
import android.content.Context
5+
import androidx.room.Room
6+
import com.osfans.trime.data.AppPrefs
7+
import com.osfans.trime.data.db.Database
8+
import com.osfans.trime.data.db.DatabaseBean
9+
import com.osfans.trime.data.db.DatabaseDao
10+
import com.osfans.trime.util.StringUtils.mismatch
11+
import com.osfans.trime.util.StringUtils.replace
12+
import com.osfans.trime.util.WeakHashSet
13+
import com.osfans.trime.util.clipboardManager
14+
import timber.log.Timber
15+
16+
object ClipboardHelper : ClipboardManager.OnPrimaryClipChangedListener {
17+
private lateinit var clbDb: Database
18+
private lateinit var clbDao: DatabaseDao
19+
20+
fun interface OnClipboardUpdateListener {
21+
fun onUpdate(text: String)
22+
}
23+
24+
private val onUpdateListeners = WeakHashSet<OnClipboardUpdateListener>()
25+
26+
fun addOnUpdateListener(listener: OnClipboardUpdateListener) {
27+
onUpdateListeners.add(listener)
28+
}
29+
30+
fun removeOnUpdateListener(listener: OnClipboardUpdateListener) {
31+
onUpdateListeners.remove(listener)
32+
}
33+
34+
private val limit get() = AppPrefs.defaultInstance().other.clipboardLimit.toInt()
35+
private val compare get() = AppPrefs.defaultInstance().other.clipboardCompareRules
36+
.trim().split('\n')
37+
private val output get() = AppPrefs.defaultInstance().other.clipboardOutputRules
38+
.trim().split('\n')
39+
40+
fun init(context: Context) {
41+
clipboardManager.addPrimaryClipChangedListener(this)
42+
clbDb = Room
43+
.databaseBuilder(context, Database::class.java, "clipboard")
44+
.fallbackToDestructiveMigration()
45+
.build()
46+
clbDao = clbDb.databaseDao()
47+
}
48+
49+
fun getAll() = clbDao.getAll()
50+
51+
fun delete(id: Int) {
52+
clbDao.delete(id)
53+
}
54+
55+
fun deleteAll() {
56+
clbDao.deleteAll()
57+
}
58+
59+
override fun onPrimaryClipChanged() {
60+
if (!(limit != 0 && this::clbDao.isInitialized)) {
61+
return
62+
}
63+
clipboardManager
64+
.primaryClip
65+
?.let { DatabaseBean.fromClipData(it) }
66+
?.takeIf {
67+
it.text!!.isNotBlank()
68+
it.text.mismatch(output.toTypedArray())
69+
}
70+
?.let { b ->
71+
if (b.text!!.replace(compare.toTypedArray()).isEmpty()) return
72+
Timber.d("Accept $b")
73+
val all = clbDao.getAll()
74+
all.find { b.text == it.text }?.let {
75+
clbDao.delete(it.id)
76+
}
77+
clbDao.insert(b)
78+
removeOutdated()
79+
onUpdateListeners.forEach { listener ->
80+
listener.onUpdate(b.text)
81+
}
82+
}
83+
}
84+
85+
private fun removeOutdated() {
86+
val all = clbDao.getAll()
87+
if (all.size > limit) {
88+
val outdated = all
89+
.sortedBy { it.id }
90+
.subList(0, all.size - limit)
91+
clbDao.delete(outdated)
92+
}
93+
}
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.osfans.trime.util
2+
3+
import java.util.WeakHashMap
4+
5+
class WeakHashSet<T> : MutableSet<T> {
6+
7+
private val core = WeakHashMap<T, PlaceHolder>()
8+
9+
private object PlaceHolder
10+
11+
val view = object : Set<T> by core.keys {}
12+
override val size get() = core.size
13+
14+
override fun iterator(): MutableIterator<T> = core.keys.iterator()
15+
16+
override fun add(element: T) = core.put(element, PlaceHolder) != null
17+
override fun addAll(elements: Collection<T>) = elements.all(::add)
18+
19+
override fun remove(element: T) = core.remove(element) != null
20+
override fun removeAll(elements: Collection<T>) = elements.all(::remove)
21+
override fun clear() = core.clear()
22+
23+
override fun retainAll(elements: Collection<T>) =
24+
removeAll(core.keys.filter { it !in elements })
25+
26+
override operator fun contains(element: T) = core.containsKey(element)
27+
override fun containsAll(elements: Collection<T>) = elements.all(::contains)
28+
29+
override fun isEmpty() = core.isEmpty()
30+
}

0 commit comments

Comments
 (0)