From e7dd62db2d5006d075e31e858bd538b0b76008ac Mon Sep 17 00:00:00 2001 From: lisonge Date: Sat, 25 Nov 2023 00:51:48 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=90=9C=E7=B4=A2=E4=BC=98=E5=8C=96/id?= =?UTF-8?q?=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/li/songe/gkd/ui/SubsVm.kt | 50 ++++++++++++++++----- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/li/songe/gkd/ui/SubsVm.kt b/app/src/main/java/li/songe/gkd/ui/SubsVm.kt index 853db3a22..ea32282dd 100644 --- a/app/src/main/java/li/songe/gkd/ui/SubsVm.kt +++ b/app/src/main/java/li/songe/gkd/ui/SubsVm.kt @@ -7,7 +7,10 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.stateIn +import li.songe.gkd.data.SubsConfig +import li.songe.gkd.data.SubscriptionRaw import li.songe.gkd.data.Tuple3 import li.songe.gkd.db.DbSet import li.songe.gkd.ui.destinations.SubsPageDestination @@ -36,18 +39,21 @@ class SubsVm @Inject constructor(stateHandle: SavedStateHandle) : ViewModel() { private val appsFlow = combine( subsItemFlow, subsIdToRawFlow, appInfoCacheFlow ) { subsItem, subsIdToRaw, appInfoCache -> + val collator = Collator.getInstance(Locale.CHINESE) (subsIdToRaw[subsItem?.id]?.apps ?: emptyList()).sortedWith { a, b -> // 顺序: 已安装(有名字->无名字)->未安装(有名字(来自订阅)->无名字) - Collator.getInstance(Locale.CHINESE) - .compare(appInfoCache[a.id]?.name ?: a.name?.let { "\uFFFF" + it } - ?: ("\uFFFF\uFFFF" + a.id), - appInfoCache[b.id]?.name ?: b.name?.let { "\uFFFF" + it } - ?: ("\uFFFF\uFFFF" + b.id)) + collator.compare(appInfoCache[a.id]?.name ?: a.name?.let { "\uFFFF" + it } + ?: ("\uFFFF\uFFFF" + a.id), + appInfoCache[b.id]?.name ?: b.name?.let { "\uFFFF" + it } + ?: ("\uFFFF\uFFFF" + b.id)) } }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) val searchStrFlow = MutableStateFlow("") + private val debounceSearchStr = searchStrFlow.debounce(200) + .stateIn(viewModelScope, SharingStarted.Eagerly, searchStrFlow.value) + private val appAndConfigsFlow = combine(appsFlow, appSubsConfigsFlow, groupSubsConfigsFlow, @@ -64,16 +70,40 @@ class SubsVm @Inject constructor(stateHandle: SavedStateHandle) : ViewModel() { }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) val filterAppAndConfigsFlow = combine( - appAndConfigsFlow, searchStrFlow, appInfoCacheFlow + appAndConfigsFlow, debounceSearchStr, appInfoCacheFlow ) { appAndConfigs, searchStr, appInfoCache -> if (searchStr.isBlank()) { appAndConfigs } else { - appAndConfigs.filter { a -> - (appInfoCache[a.t0.id]?.name ?: a.t0.name ?: a.t0.id).contains( - searchStr, true - ) + val results = mutableListOf>() + val remnantList = appAndConfigs.toMutableList() + //1. 搜索已安装应用名称 + remnantList.toList().apply { remnantList.clear() }.forEach { a -> + val name = appInfoCache[a.t0.id]?.name + if (name?.contains(searchStr, true) == true) { + results.add(a) + } else { + remnantList.add(a) + } + } + //2. 搜索未安装应用名称 + remnantList.toList().apply { remnantList.clear() }.forEach { a -> + val name = a.t0.name + if (appInfoCache[a.t0.id] == null && name?.contains(searchStr, true) == true) { + results.add(a) + } else { + remnantList.add(a) + } + } + //3. 搜索应用 id + remnantList.toList().apply { remnantList.clear() }.forEach { a -> + if (a.t0.id.contains(searchStr, true)) { + results.add(a) + } else { + remnantList.add(a) + } } + results } }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())