Allow alert rules to cover multiple apps

This commit is contained in:
ajp_anton
2026-08-18 01:55:32 +00:00
parent ba09bed24f
commit 7fac006ad3
2 changed files with 21 additions and 8 deletions
@@ -3,6 +3,7 @@ package se.ajpanton.notificationsmaster
import android.content.Context import android.content.Context
import android.view.View import android.view.View
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.CheckBox import android.widget.CheckBox
import android.widget.EditText import android.widget.EditText
import android.widget.LinearLayout import android.widget.LinearLayout
@@ -24,14 +25,25 @@ object AlertRuleDialog {
configuration: AlertConfiguration, configuration: AlertConfiguration,
existing: AlertRule?, existing: AlertRule?,
apps: List<InstalledApp>? = null, apps: List<InstalledApp>? = null,
onSave: (String?, AlertRuleDefinition) -> Unit, onSave: (List<String>?, AlertRuleDefinition) -> Unit,
onDelete: (() -> Unit)? = null, onDelete: (() -> Unit)? = null,
) { ) {
val form = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL; setPadding(dp(context, 24), 0, dp(context, 24), 0) } val form = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL; setPadding(dp(context, 24), 0, dp(context, 24), 0) }
val app = apps?.let { val selectedApps = linkedSetOf<String>()
Spinner(context).apply { val app = apps?.let { choices ->
adapter = ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, it) Button(context).apply {
existing?.let { rule -> setSelection(apps.indexOfFirst { choice -> choice.packageName == rule.packageName }.coerceAtLeast(0)) } text = "Choose apps"
setOnClickListener {
MaterialAlertDialogBuilder(context).setTitle("Apps this rule applies to")
.setMultiChoiceItems(choices.map { choice -> choice.toString() }.toTypedArray(), choices.map { choice -> choice.packageName in selectedApps }.toBooleanArray()) { _, which, checked ->
if (checked) selectedApps += choices[which].packageName else selectedApps -= choices[which].packageName
text = when (selectedApps.size) {
0 -> "Choose apps"
1 -> choices.first { choice -> choice.packageName in selectedApps }.name
else -> choices.first { choice -> choice.packageName in selectedApps }.name + ""
}
}.setPositiveButton("Done", null).show()
}
}.also(form::addView) }.also(form::addView)
} }
val profile = Spinner(context).apply { val profile = Spinner(context).apply {
@@ -54,6 +66,7 @@ object AlertRuleDialog {
if (update.isChecked) add(AlertSource.NOTIFICATION_UPDATE) if (update.isChecked) add(AlertSource.NOTIFICATION_UPDATE)
} }
if (sources.isEmpty()) { post.error = "Choose an event"; return@setOnClickListener } if (sources.isEmpty()) { post.error = "Choose an event"; return@setOnClickListener }
if (apps != null && selectedApps.isEmpty()) { app?.error = "Choose at least one app"; return@setOnClickListener }
val value = pattern.text.toString().trim() val value = pattern.text.toString().trim()
val matcher = runCatching { val matcher = runCatching {
AlertTextMatcher( AlertTextMatcher(
@@ -73,7 +86,7 @@ object AlertRuleDialog {
protected.isChecked, protected.isChecked,
dnd.isChecked, dnd.isChecked,
) )
onSave(app?.selectedItem?.let { it as InstalledApp }?.packageName, definition) onSave(apps?.let { selectedApps.toList() }, definition)
dialog.dismiss() dialog.dismiss()
} }
if (onDelete != null) dialog.getButton(android.content.DialogInterface.BUTTON_NEUTRAL).setOnClickListener { if (onDelete != null) dialog.getButton(android.content.DialogInterface.BUTTON_NEUTRAL).setOnClickListener {
@@ -44,9 +44,9 @@ class RulesFragment : Fragment(R.layout.fragment_rules) {
val existing = ruleIds?.let { ids -> configuration.rules.first { it.id in ids } } val existing = ruleIds?.let { ids -> configuration.rules.first { it.id in ids } }
AlertRuleDialog.show( AlertRuleDialog.show(
requireContext(), configuration, existing, if (existing == null) InstalledApps.all(requireContext()) else null, requireContext(), configuration, existing, if (existing == null) InstalledApps.all(requireContext()) else null,
onSave = { packageName, definition -> onSave = { packageNames, definition ->
val updated = if (ruleIds == null) { val updated = if (ruleIds == null) {
AlertRuleEditor.addForApps(configuration, listOfNotNull(packageName), definition) AlertRuleEditor.addForApps(configuration, packageNames.orEmpty(), definition)
} else { } else {
AlertRuleEditor.updateConsolidated(configuration, ruleIds, definition) AlertRuleEditor.updateConsolidated(configuration, ruleIds, definition)
} }