Skip to content

Commit 9ea36ab

Browse files
committed
refactor: some cleanups
- Simplify some utility methods' implementation (may also rename them) - Reduce redundant logic of some places - Update DeviceInfo output format and info - Remove some deprecated API usage
1 parent d651a65 commit 9ea36ab

File tree

11 files changed

+93
-168
lines changed

11 files changed

+93
-168
lines changed

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import android.content.ClipboardManager
44
import android.content.Context
55
import androidx.room.Room
66
import com.osfans.trime.data.AppPrefs
7-
import com.osfans.trime.util.StringUtils.mismatch
8-
import com.osfans.trime.util.StringUtils.replace
7+
import com.osfans.trime.util.StringUtils.matches
8+
import com.osfans.trime.util.StringUtils.removeAll
99
import com.osfans.trime.util.WeakHashSet
1010
import kotlinx.coroutines.CoroutineScope
1111
import kotlinx.coroutines.Dispatchers
@@ -96,10 +96,10 @@ object ClipboardHelper :
9696
?.let { DatabaseBean.fromClipData(it) }
9797
?.takeIf {
9898
it.text!!.isNotBlank() &&
99-
it.text.mismatch(output.toTypedArray())
99+
!it.text.matches(output.toTypedArray())
100100
}
101101
?.let { b ->
102-
if (b.text!!.replace(compare.toTypedArray()).isEmpty()) return
102+
if (b.text!!.removeAll(compare.toTypedArray()).isEmpty()) return
103103
Timber.d("Accept clipboard $b")
104104
launch {
105105
mutex.withLock {

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import android.content.Context
44
import androidx.room.Room
55
import com.osfans.trime.data.AppPrefs
66
import com.osfans.trime.ime.core.Trime
7-
import com.osfans.trime.util.StringUtils.mismatch
7+
import com.osfans.trime.util.StringUtils.matches
88
import kotlinx.coroutines.CoroutineScope
99
import kotlinx.coroutines.Dispatchers
1010
import kotlinx.coroutines.SupervisorJob
@@ -68,7 +68,7 @@ object DraftHelper : CoroutineScope by CoroutineScope(SupervisorJob() + Dispatch
6868
?.let { DatabaseBean.fromInputConnection(it) }
6969
?.takeIf {
7070
it.text!!.isNotBlank() &&
71-
it.text.mismatch(output.toTypedArray())
71+
!it.text.matches(output.toTypedArray())
7272
}
7373
?.let { b ->
7474
Timber.d("Accept $b")

app/src/main/java/com/osfans/trime/ime/core/Trime.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ public static Trime getServiceOrNull() {
225225

226226
private static final Handler syncBackgroundHandler =
227227
new Handler(
228+
Looper.getMainLooper(),
228229
msg -> {
229230
if (!((Trime) msg.obj).isShowInputRequested()) { // 若当前没有输入面板,则后台同步。防止面板关闭后5秒内再次打开
230231
ShortcutUtils.INSTANCE.syncInBackground();
@@ -1150,8 +1151,7 @@ private boolean hookKeyboard(int code, int mask) { // 編輯操作
11501151
etr.token = 0;
11511152
ExtractedText et = ic.getExtractedText(etr, 0);
11521153
if (et != null) {
1153-
int move_to =
1154-
StringUtils.INSTANCE.findNextSection(et.text, et.startOffset + et.selectionEnd);
1154+
int move_to = StringUtils.findSectionAfter(et.text, et.startOffset + et.selectionEnd);
11551155
ic.setSelection(move_to, move_to);
11561156
return true;
11571157
}
@@ -1164,7 +1164,7 @@ private boolean hookKeyboard(int code, int mask) { // 編輯操作
11641164
ExtractedText et = ic.getExtractedText(etr, 0);
11651165
if (et != null) {
11661166
int move_to =
1167-
StringUtils.INSTANCE.findPrevSection(et.text, et.startOffset + et.selectionStart);
1167+
StringUtils.findSectionBefore(et.text, et.startOffset + et.selectionStart);
11681168
ic.setSelection(move_to, move_to);
11691169
return true;
11701170
}

app/src/main/java/com/osfans/trime/ui/fragments/AboutFragment.kt

+20-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import com.osfans.trime.core.Rime
1515
import com.osfans.trime.data.opencc.OpenCCDictManager
1616
import com.osfans.trime.ui.components.PaddingPreferenceFragment
1717
import com.osfans.trime.ui.main.MainViewModel
18-
import com.osfans.trime.util.AppVersionUtils.writeLibraryVersionToSummary
1918
import com.osfans.trime.util.Const
2019
import splitties.systemservices.clipboardManager
2120

@@ -42,10 +41,26 @@ class AboutFragment : PaddingPreferenceFragment() {
4241
true
4342
}
4443
}
45-
get<Preference>("about__librime_version")
46-
?.writeLibraryVersionToSummary(Rime.getLibrimeVersion())
47-
get<Preference>("about__opencc_version")
48-
?.writeLibraryVersionToSummary(OpenCCDictManager.getOpenCCVersion())
44+
get<Preference>("about__librime_version")?.apply {
45+
val version = Rime.getLibrimeVersion()
46+
summary = version
47+
intent = intent?.let {
48+
Intent(
49+
Intent.ACTION_VIEW,
50+
Uri.withAppendedPath(it.data, "commits/$version"),
51+
)
52+
}
53+
}
54+
get<Preference>("about__opencc_version").apply {
55+
val version = OpenCCDictManager.getOpenCCVersion()
56+
summary = version
57+
intent = intent?.let {
58+
Intent(
59+
Intent.ACTION_VIEW,
60+
Uri.withAppendedPath(it.data, "commits/$version"),
61+
)
62+
}
63+
}
4964
get<Preference>("pref_trime_custom_qq")
5065
?.hidden()
5166
get<Preference>("about__open_source_licenses")?.apply {

app/src/main/java/com/osfans/trime/ui/setup/SetupFragment.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import androidx.fragment.app.Fragment
88
import androidx.fragment.app.activityViewModels
99
import com.osfans.trime.databinding.FragmentSetupBinding
1010
import com.osfans.trime.ui.setup.SetupPage.Companion.isLastPage
11+
import com.osfans.trime.util.serializable
1112

1213
class SetupFragment : Fragment() {
1314
private val viewModel: SetupViewModel by activityViewModels()
1415
private lateinit var binding: FragmentSetupBinding
1516

16-
private val page: SetupPage by lazy { requireArguments().get("page") as SetupPage }
17+
private val page: SetupPage by lazy { requireArguments().serializable("page")!! }
1718

1819
private var isDone: Boolean = false
1920
set(new) {

app/src/main/java/com/osfans/trime/util/AppVersionUtils.kt

-36
This file was deleted.

app/src/main/java/com/osfans/trime/util/CollectionUtils.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ object CollectionUtils {
4242

4343
@JvmStatic
4444
fun obtainFloat(map: Map<String, Any?>?, key: String, defValue: Float = 0f): Float {
45-
if (map == null || map.isEmpty() || key.isEmpty()) return defValue
45+
if (map.isNullOrEmpty() || key.isEmpty()) return defValue
4646
val s = obtainString(map, key)
4747
return runCatching {
4848
if (s.isNotEmpty()) s.toFloat() else defValue

app/src/main/java/com/osfans/trime/util/DeviceInfo.kt

+14-13
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,24 @@ package com.osfans.trime.util
55

66
import android.content.Context
77
import android.content.res.Configuration
8-
import com.blankj.utilcode.util.ScreenUtils
8+
import android.os.Build
99
import com.osfans.trime.BuildConfig
1010

1111
// Adapted from https://gist.github.com/hendrawd/01f215fd332d84793e600e7f82fc154b
1212
object DeviceInfo {
1313
fun get(context: Context) =
1414
buildString {
15-
appendLine("App Package Name: ${BuildConfig.APPLICATION_ID}")
16-
appendLine("App Version Name: ${BuildConfig.VERSION_NAME}")
17-
appendLine("App Version Code: ${BuildConfig.VERSION_CODE}")
18-
appendLine("OS Name: ${android.os.Build.DISPLAY}")
19-
appendLine("OS Version: ${System.getProperty("os.version")} (${android.os.Build.VERSION.INCREMENTAL})")
20-
appendLine("OS API Level: ${android.os.Build.VERSION.SDK_INT}")
21-
appendLine("Device: ${android.os.Build.DEVICE}")
22-
appendLine("Model (product): ${android.os.Build.MODEL} (${android.os.Build.PRODUCT})")
23-
appendLine("Manufacturer: ${android.os.Build.MANUFACTURER}")
24-
appendLine("Tags: ${android.os.Build.TAGS}")
25-
appendLine("Screen Size: ${ScreenUtils.getScreenWidth()} x ${ScreenUtils.getScreenHeight()}")
26-
appendLine("Screen Density: ${ScreenUtils.getScreenDensity()}")
15+
appendLine("--------- Device Info")
16+
appendLine("OS Name: ${Build.DISPLAY}")
17+
appendLine("OS Version: ${System.getProperty("os.version")} (${Build.VERSION.INCREMENTAL})")
18+
appendLine("OS API Level: ${Build.VERSION.SDK_INT}")
19+
appendLine("Device: ${Build.DEVICE}")
20+
appendLine("Model (product): ${Build.MODEL} (${Build.PRODUCT})")
21+
appendLine("Manufacturer: ${Build.MANUFACTURER}")
22+
appendLine("Tags: ${Build.TAGS}")
23+
val metrics = context.resources.displayMetrics
24+
appendLine("Screen Size: ${metrics.widthPixels} x ${metrics.heightPixels}")
25+
appendLine("Screen Density: ${metrics.density}")
2726
appendLine(
2827
"Screen orientation: ${
2928
when (context.resources.configuration.orientation) {
@@ -34,5 +33,7 @@ object DeviceInfo {
3433
}
3534
}",
3635
)
36+
appendLine("--------- Build Info")
37+
appendLine(BuildConfig.BUILD_INFO)
3738
}
3839
}

app/src/main/java/com/osfans/trime/util/InputMethodUtils.kt

+5-9
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,17 @@ object InputMethodUtils {
1212
private val serviceName =
1313
ComponentName(appContext, TrimeImeService::class.java).flattenToShortString()
1414

15-
fun checkIsTrimeEnabled(): Boolean {
16-
val activeImeIds = Settings.Secure.getString(
17-
appContext.contentResolver,
18-
Settings.Secure.ENABLED_INPUT_METHODS,
19-
) ?: "(none)"
15+
private fun getSecureSettings(name: String) =
16+
Settings.Secure.getString(appContext.contentResolver, name)
2017

18+
fun checkIsTrimeEnabled(): Boolean {
19+
val activeImeIds = getSecureSettings(Settings.Secure.ENABLED_INPUT_METHODS) ?: "(none)"
2120
Timber.i("List of active IMEs: $activeImeIds")
2221
return activeImeIds.split(":").contains(serviceName)
2322
}
2423

2524
fun checkIsTrimeSelected(): Boolean {
26-
val selectedImeIds = Settings.Secure.getString(
27-
appContext.contentResolver,
28-
Settings.Secure.DEFAULT_INPUT_METHOD,
29-
) ?: "(none)"
25+
val selectedImeIds = getSecureSettings(Settings.Secure.DEFAULT_INPUT_METHOD) ?: "(none)"
3026
Timber.i("Selected IME: $selectedImeIds")
3127
return selectedImeIds == serviceName
3228
}
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,52 @@
11
package com.osfans.trime.util
22

3-
import android.view.KeyEvent
4-
import kotlin.math.max
5-
import kotlin.math.min
6-
73
object StringUtils {
84
private const val SECTION_DIVIDER = ",.?!~:,。:~?!…\t\r\n\\/"
95

10-
fun findNextSection(str: CharSequence?, start: Int): Int {
11-
if (str != null) {
12-
var i = Math.max(0, start)
13-
if (i < str.length) {
14-
var c = str[i]
15-
var judge =
16-
if (SECTION_DIVIDER.indexOf(c) < 0) true else false
17-
while (i < str.length) {
18-
c = str[i]
19-
if (SECTION_DIVIDER.indexOf(c) < 0) {
20-
judge =
21-
true
22-
} else if (judge) {
23-
return i
24-
}
25-
i++
26-
}
27-
}
6+
@JvmStatic
7+
fun findSectionAfter(cs: CharSequence?, startIndex: Int): Int {
8+
cs ?: return 0
9+
val index = startIndex.coerceAtLeast(0)
10+
for ((i, c) in cs.withIndex()) {
11+
if (i < index) continue
12+
if (SECTION_DIVIDER.contains(c)) return i
2813
}
29-
return str!!.length
14+
return cs.length
3015
}
3116

32-
fun findPrevSection(str: CharSequence?, start: Int): Int {
33-
if (str != null) {
34-
var i = Math.min(start, str.length) - 1
35-
if (i >= 0) {
36-
var c = str[i]
37-
var judge =
38-
if (SECTION_DIVIDER.indexOf(c) < 0) true else false
39-
while (i >= 0) {
40-
c = str[i]
41-
if (SECTION_DIVIDER.indexOf(c) < 0) {
42-
judge =
43-
true
44-
} else if (judge) {
45-
return i
46-
}
47-
i--
48-
}
49-
}
17+
@JvmStatic
18+
fun findSectionBefore(cs: CharSequence?, startIndex: Int): Int {
19+
cs ?: return 0
20+
val index = startIndex.coerceAtMost(cs.length) - 1
21+
for ((i, c) in cs.withIndex().reversed()) {
22+
if (i > index) continue
23+
if (SECTION_DIVIDER.contains(c)) return i
5024
}
5125
return 0
5226
}
5327

28+
/**
29+
* Remove all parts that match given [regexes] in the string.
30+
*/
5431
@JvmStatic
55-
fun String.replace(rules: Array<String>): String {
56-
var s = this
57-
for (r in rules) {
58-
s = s.replace(r.toRegex(), "")
59-
if (s.isEmpty()) return ""
32+
fun String.removeAll(regexes: Array<String>): String {
33+
if (this.isEmpty()) return ""
34+
var result = this
35+
for (r in regexes) {
36+
result = result.replace(r.toRegex(), "")
6037
}
61-
return s
38+
return result
6239
}
6340

41+
/**
42+
* Verify if the string matches any regex in the given [regexes].
43+
*/
6444
@JvmStatic
65-
fun String.mismatch(rules: Array<String>): Boolean {
45+
fun String.matches(regexes: Array<String>): Boolean {
6646
if (this.isEmpty()) return false
67-
for (r in rules) {
68-
if (this.matches(r.toRegex())) return false
69-
}
70-
return true
71-
}
72-
73-
// KeyCode Android keycode -> 可录入的按键字符
74-
// 考虑到可能存在魔改机型的keycode有差异,而KeyEvent.keyCodeToString(keyCode)无法从keyCode获得按键字符,故重写这个从keyCode获取Char的方法。
75-
@JvmStatic
76-
fun toCharString(keyCode: Int): String {
77-
when (keyCode) {
78-
KeyEvent.KEYCODE_TAB -> return "\t"
79-
KeyEvent.KEYCODE_SPACE -> return " "
80-
KeyEvent.KEYCODE_PLUS -> return "+"
81-
KeyEvent.KEYCODE_MINUS -> return "-"
82-
KeyEvent.KEYCODE_STAR -> return "*"
83-
KeyEvent.KEYCODE_SLASH -> return "/"
84-
KeyEvent.KEYCODE_EQUALS -> return "="
85-
KeyEvent.KEYCODE_AT -> return "@"
86-
KeyEvent.KEYCODE_POUND -> return "#"
87-
KeyEvent.KEYCODE_APOSTROPHE -> return "'"
88-
KeyEvent.KEYCODE_BACKSLASH -> return "\\"
89-
KeyEvent.KEYCODE_COMMA -> return ","
90-
KeyEvent.KEYCODE_PERIOD -> return "."
91-
KeyEvent.KEYCODE_LEFT_BRACKET -> return "["
92-
KeyEvent.KEYCODE_RIGHT_BRACKET -> return "]"
93-
KeyEvent.KEYCODE_SEMICOLON -> return ";"
94-
KeyEvent.KEYCODE_GRAVE -> return "`"
95-
KeyEvent.KEYCODE_NUMPAD_ADD -> return "+"
96-
KeyEvent.KEYCODE_NUMPAD_SUBTRACT -> return "-"
97-
KeyEvent.KEYCODE_NUMPAD_MULTIPLY -> return "*"
98-
KeyEvent.KEYCODE_NUMPAD_DIVIDE -> return "/"
99-
KeyEvent.KEYCODE_NUMPAD_EQUALS -> return "="
100-
KeyEvent.KEYCODE_NUMPAD_COMMA -> return ","
101-
KeyEvent.KEYCODE_NUMPAD_DOT -> return "."
102-
KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN -> return "("
103-
KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN -> return ")"
104-
}
105-
var c = 0
106-
if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
107-
c = '0'.code + keyCode - KeyEvent.KEYCODE_0
108-
} else if (keyCode >= KeyEvent.KEYCODE_NUMPAD_0 && keyCode <= KeyEvent.KEYCODE_NUMPAD_9) {
109-
c = '0'.code + keyCode - KeyEvent.KEYCODE_NUMPAD_0
110-
} else if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {
111-
c = 'a'.code + keyCode - KeyEvent.KEYCODE_A
47+
for (r in regexes) {
48+
if (this.matches(r.toRegex())) return true
11249
}
113-
return if (c > 0) c.toChar().toString() else ""
50+
return false
11451
}
11552
}

0 commit comments

Comments
 (0)