diff --git a/app/src/main/kotlin/li/songe/gkd/data/ClickLog.kt b/app/src/main/kotlin/li/songe/gkd/data/ClickLog.kt index cd321abc39..f23286fc5f 100644 --- a/app/src/main/kotlin/li/songe/gkd/data/ClickLog.kt +++ b/app/src/main/kotlin/li/songe/gkd/data/ClickLog.kt @@ -73,5 +73,14 @@ data class ClickLog( """ ) suspend fun deleteKeepLatest(): Int + + @Query("SELECT DISTINCT app_id FROM click_log ORDER BY id DESC") + fun queryLatestUniqueAppIds(): Flow> + + @Query("SELECT DISTINCT app_id FROM click_log WHERE subs_id=:subsItemId AND group_type=${SubsConfig.AppGroupType} ORDER BY id DESC") + fun queryLatestUniqueAppIds(subsItemId: Long): Flow> + + @Query("SELECT DISTINCT app_id FROM click_log WHERE subs_id=:subsItemId AND group_key=:globalGroupKey AND group_type=${SubsConfig.GlobalGroupType} ORDER BY id DESC") + fun queryLatestUniqueAppIds(subsItemId: Long, globalGroupKey: Int): Flow> } } diff --git a/app/src/main/kotlin/li/songe/gkd/ui/ClickLogPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/ClickLogPage.kt index 7903b98aa0..54fec3cbfe 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/ClickLogPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/ClickLogPage.kt @@ -119,7 +119,7 @@ fun ClickLogPage() { ) } }, - title = { Text(text = "点击记录" + if (clickLogCount <= 0) "" else ("-$clickLogCount")) }, + title = { Text(text = "触发记录" + if (clickLogCount <= 0) "" else ("-$clickLogCount")) }, actions = { if (clickDataList.isNotEmpty()) { IconButton(onClick = { showDeleteDlg = true }) { @@ -336,8 +336,9 @@ fun ClickLogPage() { } if (showDeleteDlg) { - AlertDialog(onDismissRequest = { showDeleteDlg = false }, - title = { Text(text = "是否删除全部点击记录?") }, + AlertDialog( + onDismissRequest = { showDeleteDlg = false }, + title = { Text(text = "是否删除全部点击触发记录?") }, confirmButton = { TextButton(onClick = scope.launchAsFn(Dispatchers.IO) { showDeleteDlg = false diff --git a/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludePage.kt b/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludePage.kt index c472078b3a..a32e0a5bf3 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludePage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludePage.kt @@ -71,6 +71,7 @@ import li.songe.gkd.service.launcherAppId import li.songe.gkd.ui.component.AppBarTextField import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.ProfileTransitions +import li.songe.gkd.util.SortTypeOption import li.songe.gkd.util.launchTry import li.songe.gkd.util.toast @@ -86,7 +87,7 @@ fun GlobalRuleExcludePage(subsItemId: Long, groupKey: Int) { val showAppInfos = vm.showAppInfosFlow.collectAsState().value val searchStr by vm.searchStrFlow.collectAsState() val showSystemApp by vm.showSystemAppFlow.collectAsState() - val sortByMtime by vm.sortByMtimeFlow.collectAsState() + val sortType by vm.sortTypeFlow.collectAsState() var showEditDlg by remember { mutableStateOf(false) @@ -103,9 +104,7 @@ fun GlobalRuleExcludePage(subsItemId: Long, groupKey: Int) { val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val listState = rememberLazyListState() LaunchedEffect(key1 = showAppInfos, block = { - if (showAppInfos.isNotEmpty()) { - listState.animateScrollToItem(0) - } + listState.animateScrollToItem(0) }) var expanded by remember { mutableStateOf(false) } Scaffold(modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { @@ -173,43 +172,25 @@ fun GlobalRuleExcludePage(subsItemId: Long, groupKey: Int) { expanded = expanded, onDismissRequest = { expanded = false } ) { - DropdownMenuItem( - text = { - Row( - verticalAlignment = Alignment.CenterVertically - ) { - RadioButton(selected = !sortByMtime, - onClick = { - vm.sortByMtimeFlow.value = false - } - ) - Text("按名称") - } - }, - onClick = { - vm.sortByMtimeFlow.value = false - }, - ) - DropdownMenuItem( - text = { - Row( - verticalAlignment = Alignment.CenterVertically - ) { + SortTypeOption.allSubObject.forEach { sortOption -> + DropdownMenuItem( + text = { Row( verticalAlignment = Alignment.CenterVertically ) { - RadioButton( - selected = sortByMtime, - onClick = { vm.sortByMtimeFlow.value = true } + RadioButton(selected = sortType == sortOption, + onClick = { + vm.sortTypeFlow.value = sortOption + } ) - Text("按更新时间") + Text(sortOption.label) } - } - }, - onClick = { - vm.sortByMtimeFlow.value = true - }, - ) + }, + onClick = { + vm.sortTypeFlow.value = sortOption + }, + ) + } HorizontalDivider() DropdownMenuItem( text = { diff --git a/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludeVm.kt b/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludeVm.kt index 9def39c869..71603022af 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludeVm.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludeVm.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.flow.stateIn import li.songe.gkd.data.ExcludeData import li.songe.gkd.db.DbSet import li.songe.gkd.ui.destinations.GlobalRuleExcludePageDestination +import li.songe.gkd.util.SortTypeOption import li.songe.gkd.util.map import li.songe.gkd.util.orderedAppInfosFlow import li.songe.gkd.util.subsIdToRawFlow @@ -38,32 +39,39 @@ class GlobalRuleExcludeVm @Inject constructor(stateHandle: SavedStateHandle) : V private val debounceSearchStrFlow = searchStrFlow.debounce(200) .stateIn(viewModelScope, SharingStarted.Eagerly, searchStrFlow.value) - val sortByMtimeFlow = MutableStateFlow(false) + private val appIdToOrderFlow = + DbSet.clickLogDao.queryLatestUniqueAppIds(args.subsItemId, args.groupKey).map { appIds -> + appIds.mapIndexed { index, appId -> appId to index }.toMap() + } + val sortTypeFlow = MutableStateFlow(SortTypeOption.SortByName) val showSystemAppFlow = MutableStateFlow(false) - val showAppInfosFlow = combine( - debounceSearchStrFlow, - orderedAppInfosFlow, - sortByMtimeFlow, - showSystemAppFlow - ) { str, list, sortByMtime, showSystemApp -> - list.let { - if (sortByMtime) { - it.sortedBy { a -> -a.mtime } + val showAppInfosFlow = + combine(orderedAppInfosFlow.combine(showSystemAppFlow) { apps, showSystemApp -> + if (showSystemApp) { + apps } else { - it + apps.filter { a -> !a.isSystem } } - }.let { - if (!showSystemApp) { - it.filter { a -> !a.isSystem } - } else { - it + }, sortTypeFlow, appIdToOrderFlow) { apps, sortType, appIdToOrder -> + when (sortType) { + SortTypeOption.SortByAppMtime -> { + apps.sortedBy { a -> -a.mtime } + } + + SortTypeOption.SortByTriggerTime -> { + apps.sortedBy { a -> appIdToOrder[a.id] ?: Int.MAX_VALUE } + } + + SortTypeOption.SortByName -> { + apps + } } - }.let { + }.combine(debounceSearchStrFlow) { apps, str -> if (str.isBlank()) { - it + apps } else { - (it.filter { a -> a.name.contains(str) } + it.filter { a -> a.id.contains(str) }).distinct() + (apps.filter { a -> a.name.contains(str) } + apps.filter { a -> a.id.contains(str) }).distinct() } - } - }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) + }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) + } \ No newline at end of file diff --git a/app/src/main/kotlin/li/songe/gkd/ui/SubsPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/SubsPage.kt index 09ef4c2a54..4678777722 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/SubsPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/SubsPage.kt @@ -1,7 +1,6 @@ package li.songe.gkd.ui import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -12,6 +11,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack @@ -68,6 +68,7 @@ import li.songe.gkd.ui.component.SubsAppCard import li.songe.gkd.ui.destinations.AppItemPageDestination import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.ProfileTransitions +import li.songe.gkd.util.SortTypeOption import li.songe.gkd.util.appInfoCacheFlow import li.songe.gkd.util.encodeToJson5String import li.songe.gkd.util.json @@ -121,7 +122,11 @@ fun SubsPage( val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() var expanded by remember { mutableStateOf(false) } val showUninstallApp by vm.showUninstallAppFlow.collectAsState() - val sortByMtime by vm.sortByMtimeFlow.collectAsState() + val sortType by vm.sortTypeFlow.collectAsState() + val listState = rememberLazyListState() + LaunchedEffect(key1 = appAndConfigs, block = { + listState.scrollToItem(0) + }) Scaffold( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), @@ -182,41 +187,26 @@ fun SubsPage( expanded = expanded, onDismissRequest = { expanded = false } ) { - DropdownMenuItem( - text = { - Row( - verticalAlignment = Alignment.CenterVertically - ) { - RadioButton(selected = !sortByMtime, - onClick = { vm.sortByMtimeFlow.value = false } - ) - Text("按名称") - } - }, - onClick = { - vm.sortByMtimeFlow.value = false - }, - ) - DropdownMenuItem( - text = { - Row( - verticalAlignment = Alignment.CenterVertically - ) { + + SortTypeOption.allSubObject.forEach { sortOption -> + DropdownMenuItem( + text = { Row( verticalAlignment = Alignment.CenterVertically ) { - RadioButton( - selected = sortByMtime, - onClick = { vm.sortByMtimeFlow.value = true } + RadioButton(selected = sortType == sortOption, + onClick = { + vm.sortTypeFlow.value = sortOption + } ) - Text("按更新时间") + Text(sortOption.label) } - } - }, - onClick = { - vm.sortByMtimeFlow.value = true - }, - ) + }, + onClick = { + vm.sortTypeFlow.value = sortOption + }, + ) + } HorizontalDivider() DropdownMenuItem( text = { @@ -246,14 +236,15 @@ fun SubsPage( FloatingActionButton(onClick = { showAddDlg = true }) { Icon( imageVector = Icons.Filled.Add, - contentDescription = "add", + contentDescription = null, ) } } }, ) { padding -> LazyColumn( - verticalArrangement = Arrangement.spacedBy(0.dp), modifier = Modifier.padding(padding) + modifier = Modifier.padding(padding), + state = listState ) { itemsIndexed(appAndConfigs, { i, a -> i.toString() + a.t0.id }) { _, a -> val (appRaw, subsConfig, enableSize) = a diff --git a/app/src/main/kotlin/li/songe/gkd/ui/SubsVm.kt b/app/src/main/kotlin/li/songe/gkd/ui/SubsVm.kt index 053e8d9544..2bb36b884e 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/SubsVm.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/SubsVm.kt @@ -8,12 +8,14 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import li.songe.gkd.data.RawSubscription import li.songe.gkd.data.SubsConfig import li.songe.gkd.data.Tuple3 import li.songe.gkd.db.DbSet import li.songe.gkd.ui.destinations.SubsPageDestination +import li.songe.gkd.util.SortTypeOption import li.songe.gkd.util.appInfoCacheFlow import li.songe.gkd.util.collator import li.songe.gkd.util.getGroupRawEnable @@ -40,33 +42,47 @@ class SubsVm @Inject constructor(stateHandle: SavedStateHandle) : ViewModel() { private val categoryConfigsFlow = DbSet.categoryConfigDao.queryConfig(args.subsItemId) .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) - val sortByMtimeFlow = MutableStateFlow(false) + private val appIdToOrderFlow = + DbSet.clickLogDao.queryLatestUniqueAppIds(args.subsItemId).map { appIds -> + appIds.mapIndexed { index, appId -> appId to index }.toMap() + } + val sortTypeFlow = MutableStateFlow(SortTypeOption.SortByName) + val showUninstallAppFlow = MutableStateFlow(false) - private val sortAppsFlow = combine( - subsRawFlow, appInfoCacheFlow, showUninstallAppFlow, sortByMtimeFlow - ) { subsRaw, appInfoCache, showUninstallApp, sortByMtime -> - val apps = (subsRaw?.apps ?: emptyList()).let { - if (showUninstallApp) { - it - } else { - it.filter { a -> appInfoCache.containsKey(a.id) } + private val sortAppsFlow = + combine(combine((subsRawFlow.combine(appInfoCacheFlow) { subs, appInfoCache -> + (subs?.apps ?: emptyList()).sortedWith { a, b -> + // 顺序: 已安装(有名字->无名字)->未安装(有名字(来自订阅)->无名字) + 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)) } - } - apps.sortedWith { a, b -> - // 顺序: 已安装(有名字->无名字)->未安装(有名字(来自订阅)->无名字) - 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)) - }.let { - if (sortByMtime) { - it.sortedBy { a -> -(appInfoCache[a.id]?.mtime ?: 0) } + }), appInfoCacheFlow, showUninstallAppFlow) { apps, appInfoCache, showUninstallApp -> + if (showUninstallApp) { + apps } else { - it + apps.filter { a -> appInfoCache.containsKey(a.id) } } - } - }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) + }, + appInfoCacheFlow, + appIdToOrderFlow, + sortTypeFlow + ) { apps, appInfoCache, appIdToOrder, sortType -> + when (sortType) { + SortTypeOption.SortByAppMtime -> { + apps.sortedBy { a -> -(appInfoCache[a.id]?.mtime ?: 0) } + } + + SortTypeOption.SortByTriggerTime -> { + apps.sortedBy { a -> appIdToOrder[a.id] ?: Int.MAX_VALUE } + } + SortTypeOption.SortByName -> { + apps + } + } + }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) val searchStrFlow = MutableStateFlow("") diff --git a/app/src/main/kotlin/li/songe/gkd/ui/home/AppListPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/home/AppListPage.kt index adc7bb43c3..277ab90870 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/home/AppListPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/home/AppListPage.kt @@ -55,6 +55,7 @@ import com.google.accompanist.drawablepainter.rememberDrawablePainter import li.songe.gkd.ui.component.AppBarTextField import li.songe.gkd.ui.destinations.AppConfigPageDestination import li.songe.gkd.util.LocalNavController +import li.songe.gkd.util.SortTypeOption import li.songe.gkd.util.navigate import li.songe.gkd.util.ruleSummaryFlow @@ -68,7 +69,7 @@ fun useAppListPage(): ScaffoldExt { val vm = hiltViewModel() val showSystemApp by vm.showSystemAppFlow.collectAsState() - val sortByMtime by vm.sortByMtimeFlow.collectAsState() + val sortType by vm.sortTypeFlow.collectAsState() val orderedAppInfos by vm.appInfosFlow.collectAsState() val searchStr by vm.searchStrFlow.collectAsState() val ruleSummary by ruleSummaryFlow.collectAsState() @@ -148,43 +149,25 @@ fun useAppListPage(): ScaffoldExt { expanded = expanded, onDismissRequest = { expanded = false } ) { - DropdownMenuItem( - text = { - Row( - verticalAlignment = Alignment.CenterVertically - ) { - RadioButton(selected = !sortByMtime, - onClick = { - vm.sortByMtimeFlow.value = false - } - ) - Text("按名称") - } - }, - onClick = { - vm.sortByMtimeFlow.value = false - }, - ) - DropdownMenuItem( - text = { - Row( - verticalAlignment = Alignment.CenterVertically - ) { + SortTypeOption.allSubObject.forEach { sortOption -> + DropdownMenuItem( + text = { Row( verticalAlignment = Alignment.CenterVertically ) { - RadioButton( - selected = sortByMtime, - onClick = { vm.sortByMtimeFlow.value = true } + RadioButton(selected = sortType == sortOption, + onClick = { + vm.sortTypeFlow.value = sortOption + } ) - Text("按更新时间") + Text(sortOption.label) } - } - }, - onClick = { - vm.sortByMtimeFlow.value = true - }, - ) + }, + onClick = { + vm.sortTypeFlow.value = sortOption + }, + ) + } HorizontalDivider() DropdownMenuItem( text = { diff --git a/app/src/main/kotlin/li/songe/gkd/ui/home/ControlPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/home/ControlPage.kt index 0abb2491b5..c09ef42de6 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/home/ControlPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/home/ControlPage.kt @@ -202,7 +202,7 @@ fun useControlPage(): ScaffoldExt { ) { Column(modifier = Modifier.weight(1f)) { Text( - text = "点击记录", fontSize = 18.sp + text = "触发记录", fontSize = 18.sp ) Spacer(modifier = Modifier.height(2.dp)) Text( diff --git a/app/src/main/kotlin/li/songe/gkd/ui/home/HomeVm.kt b/app/src/main/kotlin/li/songe/gkd/ui/home/HomeVm.kt index 6884e951b2..098eea6261 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/home/HomeVm.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/home/HomeVm.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import li.songe.gkd.appScope @@ -32,6 +33,7 @@ import li.songe.gkd.data.SubsVersion import li.songe.gkd.db.DbSet import li.songe.gkd.util.FILE_UPLOAD_URL import li.songe.gkd.util.LoadStatus +import li.songe.gkd.util.SortTypeOption import li.songe.gkd.util.appInfoCacheFlow import li.songe.gkd.util.authActionFlow import li.songe.gkd.util.checkUpdate @@ -277,33 +279,46 @@ class HomeVm @Inject constructor() : ViewModel() { refreshingFlow.value = false } - val sortByMtimeFlow = MutableStateFlow(false) + private val appIdToOrderFlow = DbSet.clickLogDao.queryLatestUniqueAppIds().map { appIds -> + appIds.mapIndexed { index, appId -> appId to index }.toMap() + } + + val sortTypeFlow = MutableStateFlow(SortTypeOption.SortByName) val showSystemAppFlow = MutableStateFlow(false) val searchStrFlow = MutableStateFlow("") private val debounceSearchStrFlow = searchStrFlow.debounce(200) .stateIn(viewModelScope, SharingStarted.Eagerly, searchStrFlow.value) - val appInfosFlow = orderedAppInfosFlow.combine(showSystemAppFlow) { appInfos, showSystemApp -> - if (showSystemApp) { - appInfos - } else { - appInfos.filter { a -> !a.isSystem } - } - }.combine(sortByMtimeFlow) { appInfos, sortByMtime -> - if (sortByMtime) { - appInfos.sortedBy { a -> -a.mtime } - } else { - appInfos - } - }.combine(debounceSearchStrFlow) { appInfos, debounceSearchStr -> - if (debounceSearchStr.isBlank()) { - appInfos - } else { - (appInfos.filter { a -> a.name.contains(debounceSearchStr) } + appInfos.filter { a -> - a.id.contains( - debounceSearchStr - ) - }).distinct() - } - }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) + val appInfosFlow = + combine(orderedAppInfosFlow.combine(showSystemAppFlow) { appInfos, showSystemApp -> + if (showSystemApp) { + appInfos + } else { + appInfos.filter { a -> !a.isSystem } + } + }, sortTypeFlow, appIdToOrderFlow) { appInfos, sortType, appIdToOrder -> + when (sortType) { + SortTypeOption.SortByAppMtime -> { + appInfos.sortedBy { a -> -a.mtime } + } + + SortTypeOption.SortByTriggerTime -> { + appInfos.sortedBy { a -> appIdToOrder[a.id] ?: Int.MAX_VALUE } + } + + SortTypeOption.SortByName -> { + appInfos + } + } + }.combine(debounceSearchStrFlow) { appInfos, debounceSearchStr -> + if (debounceSearchStr.isBlank()) { + appInfos + } else { + (appInfos.filter { a -> a.name.contains(debounceSearchStr) } + appInfos.filter { a -> + a.id.contains( + debounceSearchStr + ) + }).distinct() + } + }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) } \ No newline at end of file diff --git a/app/src/main/kotlin/li/songe/gkd/util/Constants.kt b/app/src/main/kotlin/li/songe/gkd/util/Constants.kt index aff54dddfb..f47b8e997a 100644 --- a/app/src/main/kotlin/li/songe/gkd/util/Constants.kt +++ b/app/src/main/kotlin/li/songe/gkd/util/Constants.kt @@ -48,4 +48,4 @@ fun isSafeUrl(url: String): Boolean { return (u.host.endsWith(".jsdelivr.net") && (u.encodedPath.startsWith("/npm/@gkd-kit/") || u.encodedPath.startsWith( "/gh/gkd-kit/" ))) -} +} \ No newline at end of file diff --git a/app/src/main/kotlin/li/songe/gkd/util/SortTypeOption.kt b/app/src/main/kotlin/li/songe/gkd/util/SortTypeOption.kt new file mode 100644 index 0000000000..7667d635dc --- /dev/null +++ b/app/src/main/kotlin/li/songe/gkd/util/SortTypeOption.kt @@ -0,0 +1,12 @@ +package li.songe.gkd.util + +sealed class SortTypeOption(val value: Int, val label: String) { + data object SortByName : SortTypeOption(0, "按名称") + data object SortByAppMtime : SortTypeOption(1, "按更新时间") + data object SortByTriggerTime : SortTypeOption(0, "按触发时间") + + companion object { + // https://stackoverflow.com/questions/47648689 + val allSubObject by lazy { arrayOf(SortByName, SortByAppMtime, SortByTriggerTime) } + } +} \ No newline at end of file