Skip to content

Commit dd4a008

Browse files
committed
Update
1 parent a0a4084 commit dd4a008

2 files changed

Lines changed: 38 additions & 80 deletions

File tree

app/src/main/assets/kr-script.conf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ executor_core="file:///android_asset/root/executor.sh"
33
before_start_sh="file:///android_asset/root/start.sh"
44
page_list_config_sh="file:///android_asset/root/more.sh"
55
favorite_config_sh="file:///android_asset/root/home.sh"
6-
#custom_tab3_config_sh="file:///android_asset/root/tab3.sh"
7-
#custom_tab4_config_sh="file:///android_asset/root/tab4.sh"
6+
custom_tab3_config_sh="/data/data/com.tool.tree/files/root/tab3.sh"
7+
custom_tab4_config_sh="/data/data/com.tool.tree/files/root/tab4.sh"
88
toolkit_dir="file:///android_asset/home"

app/src/main/java/com/tool/tree/MainActivity.kt

Lines changed: 36 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import com.omarea.common.shared.FilePathResolver
2222
import com.omarea.common.shell.KeepShellPublic
2323
import com.omarea.common.ui.DialogHelper
2424
import com.omarea.common.ui.ProgressBarDialog
25-
import com.omarea.common.ui.ThemeMode
2625
import com.omarea.krscript.config.PageConfigReader
2726
import com.omarea.krscript.config.PageConfigSh
2827
import com.omarea.krscript.model.*
@@ -32,9 +31,6 @@ import com.tool.tree.databinding.ActivityMainBinding
3231
import com.tool.tree.ui.MainPagerAdapter
3332
import com.tool.tree.ui.TabIconHelper
3433
import kotlinx.coroutines.Dispatchers
35-
import kotlinx.coroutines.async
36-
import kotlinx.coroutines.awaitAll
37-
import kotlinx.coroutines.coroutineScope
3834
import kotlinx.coroutines.isActive
3935
import kotlinx.coroutines.launch
4036
import kotlinx.coroutines.withContext
@@ -51,11 +47,6 @@ class MainActivity : AppCompatActivity() {
5147

5248
private val ACTION_FILE_PATH_CHOOSER = 65400
5349
private lateinit var adapter: MainPagerAdapter
54-
// Lưu icon tương ứng theo đúng vị trí tab THỰC TẾ đã được thêm vào adapter
55-
// (vì một số tab có thể bị bỏ qua nếu không có dữ liệu, nên không thể dùng vị trí cố định 0..3 nữa)
56-
private val tabIcons = ArrayList<Int>()
57-
// 0 = favorites, 1 = pages, 2 = tab3, 3 = tab4 -> loại tab theo đúng thứ tự đã hiển thị thực tế
58-
private val tabSlotOrder = ArrayList<Int>()
5950

6051
override fun onCreate(savedInstanceState: Bundle?) {
6152
super.onCreate(savedInstanceState)
@@ -91,97 +82,58 @@ class MainActivity : AppCompatActivity() {
9182
}
9283
}
9384

94-
// Thêm tab vào adapter nếu có dữ liệu. Icon/slot phải được ghi trước khi gọi adapter.addFragment
95-
// vì TabLayoutMediator sẽ đọc lại tabIcons ngay khi adapter báo có thay đổi.
96-
private fun addTabIfPresent(slot: Int, items: ArrayList<NodeInfoBase>?, titleRes: Int, iconRes: Int, config: PageNode, isFav: Boolean, theme: ThemeMode) {
97-
items?.takeIf { it.isNotEmpty() }?.let { data ->
98-
tabIcons.add(iconRes)
99-
tabSlotOrder.add(slot)
100-
val fragment = ActionListFragment.create(data, getKrScriptActionHandler(config, isFav), null, theme)
101-
adapter.addFragment(fragment, getString(titleRes))
102-
}
103-
}
104-
10585
private fun loadTabs() {
10686
progressBarDialog.showDialog(getString(R.string.please_wait))
107-
tabIcons.clear()
108-
tabSlotOrder.clear()
109-
87+
11088
lifecycleScope.launch(Dispatchers.IO) {
111-
// GIAI ĐOẠN 1: ưu tiên load 2 tab đầu (favorites, pages) trước, song song với nhau
112-
val (favorites, pages) = coroutineScope {
113-
val favoritesDeferred = async { getItems(krScriptConfig.favoriteConfig) }
114-
val pagesDeferred = async { getItems(krScriptConfig.pageListConfig) }
115-
listOf(favoritesDeferred, pagesDeferred).awaitAll()
116-
}
89+
val favorites = getItems(krScriptConfig.favoriteConfig)
90+
val pages = getItems(krScriptConfig.pageListConfig)
91+
val tab3Items = getItems(krScriptConfig.customTab3Config)
92+
val tab4Items = getItems(krScriptConfig.customTab4Config)
11793

11894
if (!isActive) return@launch
11995

12096
withContext(Dispatchers.Main) {
121-
// Ẩn dialog chờ và hiển thị ngay 2 tab đầu, không cần đợi 2 tab sau
12297
progressBarDialog.hideDialog()
12398
val theme = ThemeModeState.getThemeMode()
12499

125-
addTabIfPresent(0, favorites, R.string.tab_favorites, R.drawable.tab_favorites, krScriptConfig.favoriteConfig, true, theme)
126-
addTabIfPresent(1, pages, R.string.tab_pages, R.drawable.tab_pages, krScriptConfig.pageListConfig, false, theme)
127-
128-
setupTabs()
129-
}
130-
131-
// GIAI ĐOẠN 2: load ngầm 2 tab còn lại (tab3, tab4), không chặn UI của 2 tab đầu
132-
val (tab3Items, tab4Items) = coroutineScope {
133-
val tab3Deferred = async { getItems(krScriptConfig.customTab3Config) }
134-
val tab4Deferred = async { getItems(krScriptConfig.customTab4Config) }
135-
listOf(tab3Deferred, tab4Deferred).awaitAll()
136-
}
100+
fun updateTab(pos: Int, items: ArrayList<NodeInfoBase>?, titleRes: Int, config: PageNode, isFav: Boolean) {
101+
items?.takeIf { it.isNotEmpty() }?.let { data ->
102+
val fragment = ActionListFragment.create(data, getKrScriptActionHandler(config, isFav), null, theme)
103+
if (adapter.getFragment(pos) == null) {
104+
adapter.addFragment(fragment, getString(titleRes))
105+
} else {
106+
adapter.replaceFragment(pos, fragment)
107+
}
108+
}
109+
}
137110

138-
if (!isActive) return@launch
111+
updateTab(0, favorites, R.string.tab_favorites, krScriptConfig.favoriteConfig, true)
112+
updateTab(1, pages, R.string.tab_pages, krScriptConfig.pageListConfig, false)
113+
updateTab(2, tab3Items, R.string.tab_custom3, krScriptConfig.customTab3Config, false)
114+
updateTab(3, tab4Items, R.string.tab_custom4, krScriptConfig.customTab4Config, false)
139115

140-
withContext(Dispatchers.Main) {
141-
val theme = ThemeModeState.getThemeMode()
142-
addTabIfPresent(2, tab3Items, R.string.tab_custom3, R.drawable.tab_custom3, krScriptConfig.customTab3Config, false, theme)
143-
addTabIfPresent(3, tab4Items, R.string.tab_custom4, R.drawable.tab_custom4, krScriptConfig.customTab4Config, false, theme)
116+
setupTabs()
144117
}
145118
}
146119
}
147120

148121
private fun reloadTabs() {
149122
lifecycleScope.launch(Dispatchers.IO) {
150-
// Chạy song song thay vì tuần tự - giảm thời gian chờ khi reload
151-
val (favorites, pages, tab3Items, tab4Items) = coroutineScope {
152-
val favoritesDeferred = async { getItems(krScriptConfig.favoriteConfig) }
153-
val pagesDeferred = async { getItems(krScriptConfig.pageListConfig) }
154-
val tab3Deferred = async { getItems(krScriptConfig.customTab3Config) }
155-
val tab4Deferred = async { getItems(krScriptConfig.customTab4Config) }
156-
listOf(favoritesDeferred, pagesDeferred, tab3Deferred, tab4Deferred).awaitAll()
157-
}
123+
val favorites = getItems(krScriptConfig.favoriteConfig)
124+
val pages = getItems(krScriptConfig.pageListConfig)
125+
val tab3Items = getItems(krScriptConfig.customTab3Config)
126+
val tab4Items = getItems(krScriptConfig.customTab4Config)
158127

159128
if (!isActive) return@launch
160129

161130
withContext(Dispatchers.Main) {
162131
val theme = ThemeModeState.getThemeMode()
163-
164-
// Nếu số tab hiện có không còn khớp với dữ liệu mới (tab bị thêm/bớt do có/không có dữ liệu)
165-
// thì load lại toàn bộ để đảm bảo tab rỗng không bị hiển thị và icon luôn đúng vị trí.
166-
val newItemsBySlot = mapOf(0 to favorites, 1 to pages, 2 to tab3Items, 3 to tab4Items)
167-
val newNonEmptySlots = newItemsBySlot.filterValues { !it.isNullOrEmpty() }.keys
168-
if (newNonEmptySlots != tabSlotOrder.toSet()) {
169-
loadTabs()
170-
return@withContext
171-
}
172-
173-
fun configFor(slot: Int) = when (slot) {
174-
0 -> krScriptConfig.favoriteConfig to true
175-
1 -> krScriptConfig.pageListConfig to false
176-
2 -> krScriptConfig.customTab3Config to false
177-
else -> krScriptConfig.customTab4Config to false
178-
}
179-
180-
tabSlotOrder.forEachIndexed { position, slot ->
181-
val items = newItemsBySlot[slot] ?: return@forEachIndexed
182-
val (config, isFav) = configFor(slot)
183-
(adapter.getFragment(position) as? ActionListFragment)?.updateData(items, getKrScriptActionHandler(config, isFav), theme)
184-
}
132+
133+
favorites?.let { (adapter.getFragment(0) as? ActionListFragment)?.updateData(it, getKrScriptActionHandler(krScriptConfig.favoriteConfig, true), theme) }
134+
pages?.let { (adapter.getFragment(1) as? ActionListFragment)?.updateData(it, getKrScriptActionHandler(krScriptConfig.pageListConfig, false), theme) }
135+
tab3Items?.let { (adapter.getFragment(2) as? ActionListFragment)?.updateData(it, getKrScriptActionHandler(krScriptConfig.customTab3Config, false), theme) }
136+
tab4Items?.let { (adapter.getFragment(3) as? ActionListFragment)?.updateData(it, getKrScriptActionHandler(krScriptConfig.customTab4Config, false), theme) }
185137
}
186138
}
187139
}
@@ -192,7 +144,13 @@ class MainActivity : AppCompatActivity() {
192144
// Kết nối TabLayout và ViewPager2
193145
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
194146
val title = adapter.getTitle(position)
195-
val iconRes = tabIcons.getOrElse(position) { R.drawable.tab_home }
147+
val iconRes = when (position) {
148+
0 -> R.drawable.tab_favorites
149+
1 -> R.drawable.tab_pages
150+
2 -> R.drawable.tab_custom3
151+
3 -> R.drawable.tab_custom4
152+
else -> R.drawable.tab_home
153+
}
196154
tab.customView = tabHelper.createTabView(title, getDrawable(iconRes)!!, position == binding.viewPager.currentItem)
197155
}.attach()
198156

0 commit comments

Comments
 (0)