From eaa7ee0ee10836e2ea1ada042db260e443da2fa4 Mon Sep 17 00:00:00 2001 From: lisonge Date: Fri, 14 Jun 2024 22:21:22 +0800 Subject: [PATCH] feat: tow line text, inner disable explain, --- .../kotlin/li/songe/gkd/ui/AppConfigPage.kt | 51 +++++++++++++++---- .../kotlin/li/songe/gkd/ui/AppConfigVm.kt | 2 + .../kotlin/li/songe/gkd/ui/AppItemPage.kt | 18 ++----- .../kotlin/li/songe/gkd/ui/CategoryPage.kt | 14 ++--- .../li/songe/gkd/ui/GlobalRuleExcludePage.kt | 18 ++----- .../kotlin/li/songe/gkd/ui/GlobalRulePage.kt | 13 ++--- .../main/kotlin/li/songe/gkd/ui/SubsPage.kt | 15 ++---- .../li/songe/gkd/ui/component/TowLineText.kt | 28 ++++++++++ .../kotlin/li/songe/gkd/util/SubsState.kt | 4 +- 9 files changed, 99 insertions(+), 64 deletions(-) create mode 100644 app/src/main/kotlin/li/songe/gkd/ui/component/TowLineText.kt diff --git a/app/src/main/kotlin/li/songe/gkd/ui/AppConfigPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/AppConfigPage.kt index 577f9ec3c..d509462fc 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/AppConfigPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/AppConfigPage.kt @@ -1,6 +1,7 @@ package li.songe.gkd.ui import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -19,6 +20,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.Sort import androidx.compose.material.icons.filled.Edit +import androidx.compose.material3.AlertDialog import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.FloatingActionButton @@ -30,6 +32,7 @@ import androidx.compose.material3.RadioButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Switch import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable @@ -177,6 +180,7 @@ fun AppConfigPage(appId: String) { } val checked = getChecked(excludeData, g.group, appId, appInfo) AppGroupCard( + vm = vm, group = g.group, checked = checked, onClick = { @@ -211,15 +215,20 @@ fun AppConfigPage(appId: String) { } } items(appGroups) { g -> - AppGroupCard(g.group, g.enable, onClick = { - navController.navigate( - AppItemPageDestination( - g.subsItem.id, - appId, - g.group.key, + AppGroupCard( + vm = vm, + group = g.group, + checked = g.enable, + onClick = { + navController.navigate( + AppItemPageDestination( + g.subsItem.id, + appId, + g.group.key, + ) ) - ) - }) { + } + ) { vm.viewModelScope.launchTry { DbSet.subsConfigDao.insert( g.config?.copy(enable = it) ?: SubsConfig( @@ -248,10 +257,28 @@ fun AppConfigPage(appId: String) { } } } + + val innerDisabledDlg by vm.innerDisabledDlgFlow.collectAsState() + if (innerDisabledDlg) { + AlertDialog( + title = { Text(text = "内置禁用") }, + text = { + Text(text = "此规则组已经在其 apps 字段中配置对当前应用的禁用, 因此无法手动开启规则组\n\n提示: 这种情况一般在此全局规则无法适配/跳过适配当前应用时出现") + }, + onDismissRequest = { vm.innerDisabledDlgFlow.value = false }, + confirmButton = { + TextButton(onClick = { vm.innerDisabledDlgFlow.value = false }) { + Text(text = "我知道了") + } + } + ) + + } } @Composable private fun AppGroupCard( + vm: AppConfigVm, group: RawSubscription.RawGroupProps, checked: Boolean?, onClick: () -> Unit, @@ -313,7 +340,13 @@ private fun AppGroupCard( Switch( checked = false, enabled = false, - onCheckedChange = onCheckedChange + onCheckedChange = null, + modifier = Modifier.clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + ) { + vm.innerDisabledDlgFlow.value = true + } ) } } diff --git a/app/src/main/kotlin/li/songe/gkd/ui/AppConfigVm.kt b/app/src/main/kotlin/li/songe/gkd/ui/AppConfigVm.kt index e6545c879..1aee3d260 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/AppConfigVm.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/AppConfigVm.kt @@ -74,5 +74,7 @@ class AppConfigVm @Inject constructor(stateHandle: SavedStateHandle) : ViewModel } }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) + val innerDisabledDlgFlow = MutableStateFlow(false) + } diff --git a/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt index 56abec9da..06713ebcf 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt @@ -67,6 +67,7 @@ import li.songe.gkd.data.RawSubscription import li.songe.gkd.data.SubsConfig import li.songe.gkd.data.stringify import li.songe.gkd.db.DbSet +import li.songe.gkd.ui.component.TowLineText import li.songe.gkd.ui.component.getDialogResult import li.songe.gkd.ui.destinations.GroupItemPageDestination import li.songe.gkd.ui.style.itemPadding @@ -132,19 +133,10 @@ fun AppItemPage( ) } }, title = { - Column { - Text( - text = subsRaw?.name ?: subsItemId.toString(), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Text( - text = appInfoCache[appId]?.name ?: appRaw.name ?: appId, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - style = MaterialTheme.typography.bodyMedium, - ) - } + TowLineText( + title = subsRaw?.name ?: subsItemId.toString(), + subTitle = appInfoCache[appId]?.name ?: appRaw.name ?: appId + ) }, actions = {}) }, floatingActionButton = { if (editable) { diff --git a/app/src/main/kotlin/li/songe/gkd/ui/CategoryPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/CategoryPage.kt index 60b29ea55..9ff0dfe0d 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/CategoryPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/CategoryPage.kt @@ -40,7 +40,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.viewModelScope @@ -50,6 +49,7 @@ import kotlinx.coroutines.Dispatchers import li.songe.gkd.data.CategoryConfig import li.songe.gkd.data.RawSubscription import li.songe.gkd.db.DbSet +import li.songe.gkd.ui.component.TowLineText import li.songe.gkd.ui.component.getDialogResult import li.songe.gkd.ui.style.itemPadding import li.songe.gkd.util.EnableGroupOption @@ -94,14 +94,10 @@ fun CategoryPage(subsItemId: Long) { ) } }, title = { - Column { - Text( - text = subsRaw?.name ?: subsItemId.toString(), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Text(text = "规则类别", style = MaterialTheme.typography.bodyMedium) - } + TowLineText( + title = subsRaw?.name ?: subsItemId.toString(), + subTitle = "规则类别" + ) }, actions = {}) }, floatingActionButton = { if (editable) { 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 64f48fd09..4edeee45a 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludePage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/GlobalRuleExcludePage.kt @@ -69,6 +69,7 @@ import li.songe.gkd.data.stringify import li.songe.gkd.db.DbSet import li.songe.gkd.service.launcherAppId import li.songe.gkd.ui.component.AppBarTextField +import li.songe.gkd.ui.component.TowLineText import li.songe.gkd.ui.style.appItemPadding import li.songe.gkd.ui.style.menuPadding import li.songe.gkd.util.LocalNavController @@ -129,19 +130,10 @@ fun GlobalRuleExcludePage(subsItemId: Long, groupKey: Int) { modifier = Modifier.focusRequester(focusRequester) ) } else { - Column { - Text( - text = rawSubs?.name ?: subsItemId.toString(), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Text( - text = (group?.name ?: groupKey.toString()), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - style = MaterialTheme.typography.bodyMedium - ) - } + TowLineText( + title = rawSubs?.name ?: subsItemId.toString(), + subTitle = (group?.name ?: groupKey.toString()) + ) } }, actions = { if (showSearchBar) { diff --git a/app/src/main/kotlin/li/songe/gkd/ui/GlobalRulePage.kt b/app/src/main/kotlin/li/songe/gkd/ui/GlobalRulePage.kt index 502110179..55dd08c42 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/GlobalRulePage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/GlobalRulePage.kt @@ -63,6 +63,7 @@ import kotlinx.coroutines.Dispatchers import li.songe.gkd.data.RawSubscription import li.songe.gkd.data.SubsConfig import li.songe.gkd.db.DbSet +import li.songe.gkd.ui.component.TowLineText import li.songe.gkd.ui.component.getDialogResult import li.songe.gkd.ui.destinations.GlobalRuleExcludePageDestination import li.songe.gkd.ui.destinations.GroupItemPageDestination @@ -116,14 +117,10 @@ fun GlobalRulePage(subsItemId: Long, focusGroupKey: Int? = null) { ) } }, title = { - Column { - Text( - text = rawSubs?.name ?: subsItemId.toString(), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Text(text = "全局规则", style = MaterialTheme.typography.bodyMedium) - } + TowLineText( + title = rawSubs?.name ?: subsItemId.toString(), + subTitle = "全局规则" + ) }) }, floatingActionButton = { 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 09c85976f..6b757ca90 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.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -46,7 +45,6 @@ import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.viewModelScope @@ -58,6 +56,7 @@ import li.songe.gkd.data.SubsConfig import li.songe.gkd.db.DbSet import li.songe.gkd.ui.component.AppBarTextField import li.songe.gkd.ui.component.SubsAppCard +import li.songe.gkd.ui.component.TowLineText import li.songe.gkd.ui.component.getDialogResult import li.songe.gkd.ui.destinations.AppItemPageDestination import li.songe.gkd.ui.style.menuPadding @@ -150,14 +149,10 @@ fun SubsPage( modifier = Modifier.focusRequester(focusRequester) ) } else { - Column { - Text( - text = subsRaw?.name ?: subsItemId.toString(), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Text(text = "应用规则", style = MaterialTheme.typography.bodyMedium) - } + TowLineText( + title = subsRaw?.name ?: subsItemId.toString(), + subTitle = "应用规则", + ) } }, actions = { if (showSearchBar) { diff --git a/app/src/main/kotlin/li/songe/gkd/ui/component/TowLineText.kt b/app/src/main/kotlin/li/songe/gkd/ui/component/TowLineText.kt new file mode 100644 index 000000000..dae4addeb --- /dev/null +++ b/app/src/main/kotlin/li/songe/gkd/ui/component/TowLineText.kt @@ -0,0 +1,28 @@ +package li.songe.gkd.ui.component + +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.style.TextOverflow + +@Composable +fun TowLineText( + title: String, + subTitle: String +) { + Column { + Text( + text = title, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = MaterialTheme.typography.titleMedium + ) + Text( + text = subTitle, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = MaterialTheme.typography.titleSmall + ) + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/li/songe/gkd/util/SubsState.kt b/app/src/main/kotlin/li/songe/gkd/util/SubsState.kt index 7bc712612..6e18ee06c 100644 --- a/app/src/main/kotlin/li/songe/gkd/util/SubsState.kt +++ b/app/src/main/kotlin/li/songe/gkd/util/SubsState.kt @@ -189,8 +189,8 @@ val ruleSummaryFlow by lazy { val subGlobalGroupToRules = mutableMapOf>() rawSubs.globalGroups.filter { g -> - g.valid && (subGlobalSubsConfigs.find { c -> c.groupKey == g.key }?.enable - ?: g.enable ?: true) + (subGlobalSubsConfigs.find { c -> c.groupKey == g.key }?.enable + ?: g.enable ?: true) && g.valid }.forEach { groupRaw -> val config = subGlobalSubsConfigs.find { c -> c.groupKey == groupRaw.key } val g = ResolvedGlobalGroup(