Skip to content

Commit 282186b

Browse files
committed
Upload file
1 parent 73332de commit 282186b

1 file changed

Lines changed: 114 additions & 124 deletions

File tree

krscript/src/main/java/com/omarea/krscript/ui/ParamsAppChooserRender.kt

Lines changed: 114 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -11,179 +11,169 @@ import com.omarea.common.ui.AdapterAppChooser
1111
import com.omarea.common.ui.DialogAppChooser
1212
import com.omarea.krscript.R
1313
import com.omarea.krscript.model.ActionParamInfo
14-
import java.text.Collator
1514
import java.util.Locale
16-
import java.util.HashMap
17-
import java.util.HashSet
18-
import java.util.ArrayList
19-
20-
class ParamsAppChooserRender(
21-
private var actionParamInfo: ActionParamInfo,
22-
private var context: FragmentActivity
23-
) : DialogAppChooser.Callback {
24-
25-
companion object {
26-
// Cache danh sách app để tránh load lại nhiều lần
27-
private var cachedApps: List<AdapterAppChooser.AppInfo>? = null
28-
private var cachedAppsWithMissing: List<AdapterAppChooser.AppInfo>? = null
29-
}
15+
import java.text.Collator
3016

17+
class ParamsAppChooserRender(private var actionParamInfo: ActionParamInfo, private var context: FragmentActivity) : DialogAppChooser.Callback {
18+
// Sử dụng Configuration để xác định chế độ sáng/tối
3119
private val uiMode = context.resources.configuration.uiMode
32-
private val darkMode =
33-
(uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
20+
private var darkMode: Boolean = (uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
3421

3522
private lateinit var valueView: TextView
3623
private lateinit var nameView: TextView
3724
private lateinit var packages: ArrayList<AdapterAppChooser.AppInfo>
3825

3926
fun render(): View {
40-
val layout = LayoutInflater.from(context)
41-
.inflate(R.layout.kr_param_app, null)
42-
27+
val layout = LayoutInflater.from(context).inflate(R.layout.kr_param_app, null)
4328
valueView = layout.findViewById(R.id.kr_param_app_package)
4429
nameView = layout.findViewById(R.id.kr_param_app_name)
4530

4631
setTextView()
4732

48-
layout.findViewById<View>(R.id.kr_param_app_btn)
49-
.setOnClickListener { openAppChooser() }
50-
51-
nameView.setOnClickListener { openAppChooser() }
33+
layout.findViewById<View>(R.id.kr_param_app_btn).setOnClickListener {
34+
openAppChooser()
35+
}
36+
nameView.setOnClickListener {
37+
openAppChooser()
38+
}
5239

5340
valueView.tag = actionParamInfo.name
41+
5442
return layout
5543
}
5644

5745
private fun openAppChooser() {
5846
setSelectStatus()
59-
DialogAppChooser(
60-
darkMode,
61-
packages,
62-
actionParamInfo.multiple,
63-
this
64-
).show(context.supportFragmentManager, "app-chooser")
47+
48+
// Gọi DialogAppChooser với chế độ tối/sáng
49+
DialogAppChooser(darkMode, packages, actionParamInfo.multiple, this).show(context.supportFragmentManager, "app-chooser")
6550
}
6651

67-
/**
68-
* Load & cache danh sách app (tối ưu PM + tránh O(n²))
69-
*/
70-
private fun loadPackages(includeMissing: Boolean): List<AdapterAppChooser.AppInfo> {
71-
if (!includeMissing && cachedApps != null) return cachedApps!!
72-
if (includeMissing && cachedAppsWithMissing != null) return cachedAppsWithMissing!!
73-
74-
val pm = context.packageManager
75-
val filterSet = actionParamInfo.optionsFromShell
76-
?.mapTo(HashSet()) { it.value }
77-
78-
val appMap = HashMap<String, AdapterAppChooser.AppInfo>(128)
79-
80-
pm.getInstalledApplications(PackageManager.MATCH_ALL).forEach { app ->
81-
val pkg = app.packageName
82-
if (filterSet == null || filterSet.contains(pkg)) {
83-
appMap[pkg] = AdapterAppChooser.AppInfo().apply {
84-
packageName = pkg
85-
appName = app.loadLabel(pm).toString()
86-
}
52+
private fun loadPackages(includeMissing: Boolean = false): ArrayList<AdapterAppChooser.AppInfo> {
53+
val pm = context.packageManager
54+
55+
val filterSet = actionParamInfo.optionsFromShell
56+
?.map { it.value }
57+
?.toHashSet()
58+
59+
val result = HashMap<String, AdapterAppChooser.AppInfo>(128)
60+
61+
pm.getInstalledApplications(PackageManager.MATCH_ALL).forEach { app ->
62+
val pkg = app.packageName
63+
if (filterSet == null || filterSet.contains(pkg)) {
64+
result[pkg] = AdapterAppChooser.AppInfo().apply {
65+
packageName = pkg
66+
appName = app.loadLabel(pm)?.toString() ?: pkg
8767
}
8868
}
69+
}
8970

90-
// include missing packages
91-
if (includeMissing && actionParamInfo.optionsFromShell != null) {
92-
for (item in actionParamInfo.optionsFromShell!!) {
93-
val pkg = item.value ?: continue
94-
if (!appMap.containsKey(pkg)) {
95-
appMap[pkg] = AdapterAppChooser.AppInfo().apply {
96-
packageName = pkg
97-
appName = item.title ?: ""
98-
}
71+
// thêm app bị thiếu
72+
if (includeMissing && actionParamInfo.optionsFromShell != null) {
73+
for (item in actionParamInfo.optionsFromShell!!) {
74+
if (!result.containsKey(item.value)) {
75+
result[item.value] = AdapterAppChooser.AppInfo().apply {
76+
packageName = item.value
77+
appName = item.title ?: item.value
9978
}
10079
}
10180
}
81+
}
10282

103-
val collator = Collator.getInstance(Locale.getDefault())
104-
val result = appMap.values.sortedWith { a, b ->
105-
collator.compare(a.appName ?: "", b.appName ?: "")
106-
}
83+
return ArrayList(result.values)
84+
}
10785

108-
if (includeMissing) {
109-
cachedAppsWithMissing = result
86+
private fun setSelectStatus() {
87+
packages.forEach {
88+
it.selected = false
89+
}
90+
val currentValue = valueView.text
91+
if (actionParamInfo.multiple) {
92+
currentValue.split(actionParamInfo.separator).run {
93+
this.forEach {
94+
val value = it
95+
val app = packages.find { it.packageName == value }
96+
if (app != null) {
97+
app.selected = true
98+
}
99+
}
100+
}
110101
} else {
111-
cachedApps = result
102+
val current = packages.find { it.packageName == currentValue }
103+
val currentIndex = if (current != null) packages.indexOf(current) else -1
104+
if (currentIndex > -1) {
105+
packages[currentIndex].selected = true
106+
}
112107
}
113-
return result
114108
}
115109

116-
/**
117-
* Đặt trạng thái selected (O(n))
118-
*/
119-
private fun setSelectStatus() {
120-
val map = packages
121-
.filter { it.packageName != null }
122-
.associateBy { it.packageName!! }
123-
packages.forEach { it.selected = false }
110+
// 设置界面显示和元素赋值
111+
private fun setTextView() {
112+
packages = loadPackages(actionParamInfo.type == "packages")
124113

125-
if (actionParamInfo.multiple) {
126-
valueView.text
127-
.split(actionParamInfo.separator)
128-
.forEach { map[it]?.selected = true }
129-
} else {
130-
map[valueView.text]?.selected = true
131-
}
114+
// sort theo locale
115+
val collator = Collator.getInstance(Locale.getDefault())
116+
packages.sortWith { a, b ->
117+
collator.compare(a.appName ?: "", b.appName ?: "")
132118
}
133119

134-
/**
135-
* Gán dữ liệu hiển thị ban đầu
136-
*/
137-
private fun setTextView() {
138-
packages = ArrayList(loadPackages(actionParamInfo.type == "packages"))
120+
// map nhanh theo packageName
121+
val packageMap = packages
122+
.filter { it.packageName != null }
123+
.associateBy { it.packageName!! }
139124

140-
if (actionParamInfo.multiple) {
141-
ActionParamsLayoutRender.getParamValues(actionParamInfo)
142-
?.forEach { value ->
143-
packages.firstOrNull { it.packageName == value }?.selected = true
144-
}
145-
onConfirm(packages.filter { it.selected })
146-
} else {
147-
val validOptions = ArrayList<SelectItem>(packages.size)
148-
packages.forEach {
149-
validOptions.add(
150-
SelectItem().apply {
151-
title = it.appName ?: ""
152-
value = it.packageName ?: ""
153-
}
154-
)
125+
if (actionParamInfo.multiple) {
126+
ActionParamsLayoutRender.getParamValues(actionParamInfo)
127+
?.forEach { value ->
128+
packageMap[value]?.selected = true
155129
}
156130

157-
val currentIndex =
158-
ActionParamsLayoutRender.getParamOptionsCurrentIndex(
159-
actionParamInfo,
160-
validOptions
161-
)
131+
// giữ hành vi cũ: hiển thị ngay
132+
onConfirm(packages.filter { it.selected })
162133

163-
if (currentIndex >= 0) {
164-
val item = packages[currentIndex]
165-
valueView.text = item.packageName ?: ""
166-
nameView.text = item.appName ?: ""
167-
} else {
168-
valueView.text = ""
169-
nameView.text = ""
170-
}
134+
} else {
135+
val validOptions = ArrayList<SelectItem>(packages.size)
136+
packages.forEach {
137+
validOptions.add(
138+
SelectItem().apply {
139+
title = it.appName ?: ""
140+
value = it.packageName ?: ""
141+
}
142+
)
143+
}
144+
145+
val currentIndex =
146+
ActionParamsLayoutRender.getParamOptionsCurrentIndex(
147+
actionParamInfo,
148+
validOptions
149+
)
150+
151+
if (currentIndex >= 0) {
152+
val item = packages[currentIndex]
153+
valueView.text = item.packageName.orEmpty()
154+
nameView.text = item.appName.orEmpty()
155+
} else {
156+
valueView.text = ""
157+
nameView.text = ""
171158
}
172159
}
160+
}
173161

174-
/**
175-
* Callback từ DialogAppChooser
176-
*/
177162
override fun onConfirm(apps: List<AdapterAppChooser.AppInfo>) {
178163
if (actionParamInfo.multiple) {
179-
valueView.text =
180-
apps.joinToString(actionParamInfo.separator) { it.packageName ?: "" }
181-
nameView.text =
182-
apps.joinToString("") { it.appName ?: "" }
164+
val values = apps.joinToString(actionParamInfo.separator) { it.packageName }
165+
val labels = apps.joinToString("") { it.appName }
166+
valueView.text = values
167+
nameView.text = labels
183168
} else {
184169
val item = apps.firstOrNull()
185-
valueView.text = item?.packageName.orEmpty()
186-
nameView.text = item?.appName.orEmpty()
170+
if (item == null) {
171+
valueView.text = ""
172+
nameView.text = ""
173+
} else {
174+
valueView.text = item.packageName
175+
nameView.text = item.appName
176+
}
187177
}
188178
}
189179
}

0 commit comments

Comments
 (0)