@@ -43,8 +43,8 @@ class ActionPage : AppCompatActivity() {
4343 private lateinit var binding: ActivityActionPageBinding
4444 private var openedSubPage = false
4545
46- // Lưu danh sách các itemId (index) vừa mới được click để tạm chặn việc script ghi đè sai trạng thái
47- private val justClickedItems = HashSet <Int >()
46+ // Sử dụng HashCode của String ID để khóa trạng thái tạm thời, không sợ lệch index
47+ private val justClickedItemIds = HashSet <Int >()
4848
4949 override fun onCreate (savedInstanceState : Bundle ? ) {
5050 super .onCreate(savedInstanceState)
@@ -162,11 +162,13 @@ class ActionPage : AppCompatActivity() {
162162
163163 menu?.clear()
164164
165- menuOptions?.forEachIndexed { index, option ->
165+ menuOptions?.forEach { option ->
166166 if (option.isFab) {
167167 addFab(option)
168168 } else {
169- val menuItem = menu?.add(Menu .NONE , index, index, option.title)
169+ // ĐỔI: Sử dụng hashCode của chuỗi ID duy nhất (option.key hoặc option.id) làm itemId cho Menu
170+ val uniqueItemId = option.key.hashCode()
171+ val menuItem = menu?.add(Menu .NONE , uniqueItemId, Menu .NONE , option.title)
170172 if (option.type == " checkbox" ) {
171173 menuItem?.isCheckable = true
172174 }
@@ -176,9 +178,11 @@ class ActionPage : AppCompatActivity() {
176178 }
177179
178180 override fun onPrepareOptionsMenu (menu : Menu ): Boolean {
179- menuOptions?.forEachIndexed { index, option ->
181+ // Tìm và gán chính xác trạng thái checkbox theo uniqueId
182+ menuOptions?.forEach { option ->
180183 if (! option.isFab && option.type == " checkbox" ) {
181- val menuItem = menu.findItem(index)
184+ val uniqueItemId = option.key.hashCode()
185+ val menuItem = menu.findItem(uniqueItemId)
182186 menuItem?.isChecked = option.checked
183187 }
184188 }
@@ -189,28 +193,29 @@ class ActionPage : AppCompatActivity() {
189193 private fun refreshCheckboxMenuStates () {
190194 val config = currentPageConfig ? : return
191195
192- val checkboxOptionsWithIndex = menuOptions?.mapIndexed { index, option -> index to option }
193- ?.filter { (index, option) ->
194- // SỬA: Nếu checkbox này vừa mới được click và đang đợi script chạy, TẠM THỜI bỏ qua không quét từ hệ thống nữa
195- option.type == " checkbox" && option.checkedSh.isNotEmpty() && ! justClickedItems .contains(index )
196- }
196+ // Lọc danh sách checkbox dựa trên ID duy nhất
197+ val checkboxOptions = menuOptions ?.filter { option ->
198+ val uniqueItemId = option.key.hashCode()
199+ option.type == " checkbox" && option.checkedSh.isNotEmpty() && ! justClickedItemIds .contains(uniqueItemId )
200+ }
197201
198- if (checkboxOptionsWithIndex .isNullOrEmpty() || menuCheckboxRefreshing) return
202+ if (checkboxOptions .isNullOrEmpty() || menuCheckboxRefreshing) return
199203 menuCheckboxRefreshing = true
200204
201205 lifecycleScope.launch(Dispatchers .IO ) {
202- val results = checkboxOptionsWithIndex .map { (originalIndex, option) ->
206+ val results = checkboxOptions .map { option ->
203207 val result = ScriptEnvironmen .executeResultRoot(this @ActionPage, option.checkedSh, config)?.trim()
204- Triple (originalIndex, option, result)
208+ option to result
205209 }
206210
207211 withContext(Dispatchers .Main ) {
208212 menuCheckboxRefreshing = false
209213 var changed = false
210214
211- results.forEach { (originalIndex, option, result) ->
212- // Kiểm tra lại một lần nữa trước khi ghi đè dữ liệu lên option nhằm tránh xung đột chạy song song
213- if (! justClickedItems.contains(originalIndex)) {
215+ results.forEach { (option, result) ->
216+ val uniqueItemId = option.key.hashCode()
217+ // Khớp chính xác ID để tránh đè dữ liệu cũ trong khi lệnh shell click đang thực thi
218+ if (! justClickedItemIds.contains(uniqueItemId)) {
214219 val newChecked = result == " 1" || result?.lowercase() == " true"
215220 if (option.checked != newChecked) changed = true
216221 option.checked = newChecked
@@ -238,21 +243,20 @@ class ActionPage : AppCompatActivity() {
238243
239244 override fun onOptionsItemSelected (item : MenuItem ): Boolean {
240245 val options = menuOptions ? : return false
241- val index = item.itemId
246+ val targetItemId = item.itemId // Đây chính là hashCode của checkbox vừa click
242247
243- if (index in options.indices) {
244- val option = options[index]
245-
248+ // ĐỔI: Tìm option khớp với hashCode của ID thay vì dùng vị trí mảng index
249+ val option = options.find { it.key.hashCode() == targetItemId }
250+
251+ if (option != null ) {
246252 if (option.type == " checkbox" ) {
247253 option.checked = ! option.checked
248254 item.isChecked = option.checked
249255
250- // Đánh dấu ô này vừa click xong để lock (khóa) trạng thái, tránh bị hàm check đồng bộ đè dữ liệu cũ lên
251- justClickedItems.add(index)
252-
253- // Mở khóa sau 1.5 giây - khoảng thời gian dư dả để lệnh Shell cũ thực thi xong hoàn toàn
256+ // Khóa đồng bộ theo ID cụ thể
257+ justClickedItemIds.add(targetItemId)
254258 handler.postDelayed({
255- justClickedItems .remove(index )
259+ justClickedItemIds .remove(targetItemId )
256260 }, 1500 )
257261 }
258262
0 commit comments