feat: custom notif desc

This commit is contained in:
lisonge 2024-08-05 15:53:08 +08:00
parent 6747d87459
commit 0c0a00fa07
5 changed files with 57 additions and 24 deletions

View File

@ -6,6 +6,7 @@ import androidx.core.app.NotificationManagerCompat
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 kotlinx.coroutines.launch
import li.songe.gkd.app
@ -16,6 +17,7 @@ import li.songe.gkd.notif.abNotif
import li.songe.gkd.notif.createNotif
import li.songe.gkd.notif.defaultChannel
import li.songe.gkd.util.clickCountFlow
import li.songe.gkd.util.getSubsStatus
import li.songe.gkd.util.ruleSummaryFlow
import li.songe.gkd.util.storeFlow
@ -26,22 +28,22 @@ class ManageService : CompositionService({
val scope = useScope()
scope.launch {
combine(
GkdAbService.isRunning,
storeFlow,
ruleSummaryFlow,
clickCountFlow,
storeFlow,
GkdAbService.isRunning
) { allRules, clickCount, store, abRunning ->
) { abRunning, store, ruleSummary, count ->
if (!abRunning) return@combine "无障碍未授权"
if (!store.enableService) return@combine "服务已暂停"
if (store.useCustomNotifText) {
return@combine store.customNotifText.replace("$" + "{count}", clickCount.toString())
return@combine store.customNotifText
.replace("\${a}", ruleSummary.globalGroups.size.toString())
.replace("\${b}", ruleSummary.appSize.toString())
.replace("\${c}", ruleSummary.appGroupSize.toString())
.replace("\${d}", count.toString())
}
allRules.numText + if (clickCount > 0) {
"/${clickCount}点击"
} else {
""
}
}.stateIn(scope, SharingStarted.Eagerly, "").collect { text ->
return@combine getSubsStatus(ruleSummary, count)
}.debounce(500L).stateIn(scope, SharingStarted.Eagerly, "").collect { text ->
createNotif(
context, defaultChannel.id, abNotif.copy(
text = text

View File

@ -21,6 +21,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import li.songe.gkd.appScope
import li.songe.gkd.data.GithubPoliciesAsset
import li.songe.gkd.data.RawSubscription
import li.songe.gkd.data.RpcError
@ -32,6 +33,7 @@ import li.songe.gkd.util.SortTypeOption
import li.songe.gkd.util.appInfoCacheFlow
import li.songe.gkd.util.clickCountFlow
import li.songe.gkd.util.client
import li.songe.gkd.util.getSubsStatus
import li.songe.gkd.util.launchTry
import li.songe.gkd.util.map
import li.songe.gkd.util.orderedAppInfosFlow
@ -105,13 +107,11 @@ class HomeVm @Inject constructor() : ViewModel() {
}
}.stateIn(viewModelScope, SharingStarted.Eagerly, null)
val subsStatusFlow = combine(ruleSummaryFlow, clickCountFlow) { allRules, clickCount ->
allRules.numText + if (clickCount > 0) {
"/${clickCount}点击"
} else {
""
}
}.stateIn(viewModelScope, SharingStarted.Eagerly, "")
val subsStatusFlow by lazy {
combine(ruleSummaryFlow, clickCountFlow) { ruleSummary, count ->
getSubsStatus(ruleSummary, count)
}.stateIn(appScope, SharingStarted.Eagerly, "")
}
fun addSubsFromUrl(url: String) = viewModelScope.launchTry(Dispatchers.IO) {
if (subsRefreshingFlow.value) return@launchTry

View File

@ -12,10 +12,13 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.filled.Upload
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Card
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
@ -50,6 +53,7 @@ import li.songe.gkd.ui.component.RotatingLoadingIcon
import li.songe.gkd.ui.component.SettingItem
import li.songe.gkd.ui.component.TextMenu
import li.songe.gkd.ui.component.TextSwitch
import li.songe.gkd.ui.component.buildDialogOptions
import li.songe.gkd.ui.destinations.AboutPageDestination
import li.songe.gkd.ui.destinations.AdvancedPageDestination
import li.songe.gkd.ui.style.EmptyHeight
@ -107,9 +111,7 @@ fun useSettingsPage(): ScaffoldExt {
OutlinedTextField(
value = value,
placeholder = {
Text(
text = "请输入提示内容",
)
Text(text = "请输入提示内容")
},
onValueChange = {
value = it.take(maxCharLen)
@ -145,7 +147,28 @@ fun useSettingsPage(): ScaffoldExt {
mutableStateOf(store.customNotifText)
}
val maxCharLen = 64
AlertDialog(title = { Text(text = "通知文案") }, text = {
AlertDialog(title = {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth(),
) {
Text(text = "通知文案")
IconButton(onClick = throttle {
mainVm.dialogFlow.value = buildDialogOptions(
title = "文案规则",
text = "通知文案支持变量替换,规则如下\n\${a} 全局规则数\n\${b} 应用数\n\${c} 应用规则组数\n\${d} 触发次数\n\n示例模板\n\${a}全局/\${b}应用/\${c}规则组/\${d}触发\n\n替换结果\n0全局/1应用/2规则组/3触发",
confirmText = "知道了",
confirmAction = { mainVm.dialogFlow.value = null },
)
}) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.HelpOutline,
contentDescription = null,
)
}
}
}, text = {
OutlinedTextField(
value = value,
placeholder = {

View File

@ -65,7 +65,7 @@ data class Store(
val showSaveSnapshotToast: Boolean = true,
val useSystemToast: Boolean = false,
val useCustomNotifText: Boolean = false,
val customNotifText: String = "GKD",
val customNotifText: String = "\${a}全局/\${b}应用/\${c}规则组/\${d}触发",
)
val storeFlow by lazy {

View File

@ -131,8 +131,8 @@ data class RuleSummary(
val appIdToGroups: ImmutableMap<String, ImmutableList<RawSubscription.RawAppGroup>> = persistentMapOf(),
val appIdToAllGroups: ImmutableMap<String, ImmutableList<ResolvedAppGroup>> = persistentMapOf(),
) {
private val appSize = appIdToRules.keys.size
private val appGroupSize = appIdToGroups.values.sumOf { s -> s.size }
val appSize = appIdToRules.keys.size
val appGroupSize = appIdToGroups.values.sumOf { s -> s.size }
val numText = if (globalGroups.size + appGroupSize > 0) {
if (globalGroups.isNotEmpty()) {
@ -285,6 +285,14 @@ val ruleSummaryFlow by lazy {
}.flowOn(Dispatchers.Default).stateIn(appScope, SharingStarted.Eagerly, RuleSummary())
}
fun getSubsStatus(ruleSummary: RuleSummary, count: Int): String {
return if (count > 0) {
"${ruleSummary.numText}/${count}触发"
} else {
ruleSummary.numText
}
}
private fun loadSubs(id: Long): RawSubscription {
val file = subsFolder.resolve("${id}.json")
if (!file.exists()) {