11package li.songe.gkd.ui
22
33import androidx.lifecycle.SavedStateHandle
4- import androidx.lifecycle.ViewModel
54import androidx.lifecycle.viewModelScope
65import com.ramcosta.composedestinations.generated.destinations.SubsAppListPageDestination
76import kotlinx.coroutines.flow.MutableStateFlow
8- import kotlinx.coroutines.flow.SharingStarted
97import kotlinx.coroutines.flow.combine
108import kotlinx.coroutines.flow.debounce
119import kotlinx.coroutines.flow.map
12- import kotlinx.coroutines.flow.stateIn
1310import li.songe.gkd.data.AppConfig
1411import li.songe.gkd.data.RawSubscription
1512import li.songe.gkd.db.DbSet
1613import li.songe.gkd.util.LinkLoad
1714import li.songe.gkd.util.SortTypeOption
15+ import li.songe.gkd.util.ViewModelExt
1816import li.songe.gkd.util.appInfoCacheFlow
1917import li.songe.gkd.util.collator
2018import li.songe.gkd.util.findOption
@@ -23,22 +21,19 @@ import li.songe.gkd.util.map
2321import li.songe.gkd.util.storeFlow
2422import li.songe.gkd.util.subsIdToRawFlow
2523
26- class SubsAppListVm (stateHandle : SavedStateHandle ) : ViewModel () {
24+ class SubsAppListVm (stateHandle : SavedStateHandle ) : ViewModelExt () {
2725 private val args = SubsAppListPageDestination .argsFrom(stateHandle)
2826 val linkLoad = LinkLoad (viewModelScope)
2927 val subsRawFlow = subsIdToRawFlow.map(viewModelScope) { s -> s[args.subsItemId] }
3028
3129 private val appConfigsFlow = DbSet .appConfigDao.queryAppTypeConfig(args.subsItemId)
32- .let (linkLoad::invoke)
33- .stateIn(viewModelScope, SharingStarted .Eagerly , emptyList())
30+ .let (linkLoad::invoke).stateInit(emptyList())
3431
3532 private val groupSubsConfigsFlow = DbSet .subsConfigDao.querySubsGroupTypeConfig(args.subsItemId)
36- .let (linkLoad::invoke)
37- .stateIn(viewModelScope, SharingStarted .Eagerly , emptyList())
33+ .let (linkLoad::invoke).stateInit(emptyList())
3834
3935 private val categoryConfigsFlow = DbSet .categoryConfigDao.queryConfig(args.subsItemId)
40- .let (linkLoad::invoke)
41- .stateIn(viewModelScope, SharingStarted .Eagerly , emptyList())
36+ .let (linkLoad::invoke).stateInit(emptyList())
4237
4338 private val appIdToOrderFlow =
4439 DbSet .actionLogDao.queryLatestUniqueAppIds(args.subsItemId).let (linkLoad::invoke)
@@ -49,46 +44,56 @@ class SubsAppListVm(stateHandle: SavedStateHandle) : ViewModel() {
4944 storeFlow.map(viewModelScope) { SortTypeOption .allSubObject.findOption(it.subsAppSortType) }
5045
5146 val showUninstallAppFlow = storeFlow.map(viewModelScope) { it.subsAppShowUninstallApp }
52- private val sortAppsFlow =
53- combine(
54- combine((subsRawFlow.combine(appInfoCacheFlow) { subs, appInfoCache ->
55- (subs?.apps ? : emptyList()).sortedWith { a, b ->
56- // 顺序: 已安装(有名字->无名字)->未安装(有名字(来自订阅)->无名字)
57- collator.compare(appInfoCache[a.id]?.name ? : a.name?.let { " \uFFFF " + it }
58- ? : (" \uFFFF\uFFFF " + a.id),
59- appInfoCache[b.id]?.name ? : b.name?.let { " \uFFFF " + it }
60- ? : (" \uFFFF\uFFFF " + b.id))
61- }
62- }), appInfoCacheFlow, showUninstallAppFlow) { apps, appInfoCache, showUninstallApp ->
63- if (showUninstallApp) {
64- apps
47+ private val temp0ListFlow = combine(subsRawFlow, appInfoCacheFlow) { subs, appInfoCache ->
48+ (subs?.apps ? : emptyList()).run {
49+ if (any { it.groups.isEmpty() }) {
50+ filterNot { it.groups.isEmpty() }
6551 } else {
66- apps.filter { a -> appInfoCache.containsKey(a.id) }
52+ this
53+ }
54+ }.sortedWith { a, b ->
55+ // 顺序: 已安装(有名字->无名字)->未安装(有名字(来自订阅)->无名字)
56+ collator.compare(appInfoCache[a.id]?.name ? : a.name?.let { " \uFFFF " + it }
57+ ? : (" \uFFFF\uFFFF " + a.id),
58+ appInfoCache[b.id]?.name ? : b.name?.let { " \uFFFF " + it }
59+ ? : (" \uFFFF\uFFFF " + b.id))
60+ }
61+ }
62+ private val temp1ListFlow = combine(
63+ temp0ListFlow,
64+ appInfoCacheFlow,
65+ showUninstallAppFlow
66+ ) { apps, appInfoCache, showUninstallApp ->
67+ if (showUninstallApp) {
68+ apps
69+ } else {
70+ apps.filter { a -> appInfoCache.containsKey(a.id) }
71+ }
72+ }
73+ private val sortAppsFlow = combine(
74+ temp1ListFlow,
75+ appInfoCacheFlow,
76+ appIdToOrderFlow,
77+ sortTypeFlow
78+ ) { apps, appInfoCache, appIdToOrder, sortType ->
79+ when (sortType) {
80+ SortTypeOption .SortByAppMtime -> {
81+ apps.sortedBy { a -> - (appInfoCache[a.id]?.mtime ? : 0 ) }
6782 }
68- },
69- appInfoCacheFlow,
70- appIdToOrderFlow,
71- sortTypeFlow
72- ) { apps, appInfoCache, appIdToOrder, sortType ->
73- when (sortType) {
74- SortTypeOption .SortByAppMtime -> {
75- apps.sortedBy { a -> - (appInfoCache[a.id]?.mtime ? : 0 ) }
76- }
7783
78- SortTypeOption .SortByTriggerTime -> {
79- apps.sortedBy { a -> appIdToOrder[a.id] ? : Int .MAX_VALUE }
80- }
84+ SortTypeOption .SortByTriggerTime -> {
85+ apps.sortedBy { a -> appIdToOrder[a.id] ? : Int .MAX_VALUE }
86+ }
8187
82- SortTypeOption .SortByName -> {
83- apps
84- }
88+ SortTypeOption .SortByName -> {
89+ apps
8590 }
86- }.stateIn(viewModelScope, SharingStarted .Eagerly , emptyList())
91+ }
92+ }.stateInit(emptyList())
8793
8894 val searchStrFlow = MutableStateFlow (" " )
8995
90- private val debounceSearchStr = searchStrFlow.debounce(200 )
91- .stateIn(viewModelScope, SharingStarted .Eagerly , searchStrFlow.value)
96+ private val debounceSearchStr = searchStrFlow.debounce(200 ).stateInit(searchStrFlow.value)
9297
9398
9499 private val appAndConfigsFlow = combine(
@@ -111,7 +116,7 @@ class SubsAppListVm(stateHandle: SavedStateHandle) : ViewModel() {
111116 }
112117 Triple (app, appSubsConfigs.find { s -> s.appId == app.id }, enableSize)
113118 }
114- }.stateIn(viewModelScope, SharingStarted . Eagerly , emptyList())
119+ }.stateInit( emptyList())
115120
116121 val filterAppAndConfigsFlow = combine(
117122 appAndConfigsFlow, debounceSearchStr, appInfoCacheFlow
@@ -149,6 +154,6 @@ class SubsAppListVm(stateHandle: SavedStateHandle) : ViewModel() {
149154 }
150155 results
151156 }
152- }.stateIn(viewModelScope, SharingStarted . Eagerly , emptyList())
157+ }.stateInit( emptyList())
153158
154159}
0 commit comments