Expose alert rule outcomes
This commit is contained in:
@@ -46,9 +46,19 @@ object AlertRuleDialog {
|
||||
}
|
||||
}.also(form::addView)
|
||||
}
|
||||
val profiles = configuration.profiles
|
||||
val profile = Spinner(context).apply {
|
||||
adapter = ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, configuration.profiles.map { it.name })
|
||||
existing?.let { rule -> setSelection(configuration.profiles.indexOfFirst { it.id == rule.profileId }.coerceAtLeast(0)) }
|
||||
adapter = ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, profiles.map { it.name })
|
||||
existing?.let { rule -> setSelection(profiles.indexOfFirst { it.id == rule.profileId }.coerceAtLeast(0)) }
|
||||
}
|
||||
val outcomes = listOf(
|
||||
AlertOutcome.PLAY_PROFILE to "Play profile",
|
||||
AlertOutcome.SILENCE_ORIGINAL to "Silence original alert",
|
||||
AlertOutcome.PASS_THROUGH to "Keep original alert",
|
||||
)
|
||||
val outcome = Spinner(context).apply {
|
||||
adapter = ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, outcomes.map { it.second })
|
||||
setSelection(outcomes.indexOfFirst { it.first == existing?.outcome }.coerceAtLeast(0))
|
||||
}
|
||||
val post = CheckBox(context).apply { text = "Appearing"; isChecked = existing == null || AlertSource.NOTIFICATION_POST in existing.sources }
|
||||
val update = CheckBox(context).apply { text = "Edits"; isChecked = existing == null || AlertSource.NOTIFICATION_UPDATE in existing.sources }
|
||||
@@ -59,11 +69,22 @@ object AlertRuleDialog {
|
||||
text = "Allow during DND (requires system support)"
|
||||
isChecked = existing?.allowDuringDnd == true
|
||||
}
|
||||
listOf(profile, post, update, pattern, regex, protected, dnd).forEach(form::addView)
|
||||
listOf(outcome, profile, post, update, pattern, regex, protected, dnd).forEach(form::addView)
|
||||
form.addView(android.widget.TextView(context).apply {
|
||||
text = "Android blocks direct custom alerts during Do Not Disturb. This setting is retained for optional system support, but does not bypass Do Not Disturb in the normal app."
|
||||
textSize = 14f
|
||||
})
|
||||
fun updateOutcomeFields() {
|
||||
val playsProfile = outcomes[outcome.selectedItemPosition].first == AlertOutcome.PLAY_PROFILE
|
||||
profile.isEnabled = playsProfile
|
||||
protected.isEnabled = playsProfile
|
||||
dnd.isEnabled = playsProfile
|
||||
}
|
||||
outcome.onItemSelectedListener = object : android.widget.AdapterView.OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: android.widget.AdapterView<*>?) = Unit
|
||||
override fun onItemSelected(parent: android.widget.AdapterView<*>?, view: View?, position: Int, id: Long) = updateOutcomeFields()
|
||||
}
|
||||
updateOutcomeFields()
|
||||
val dialog = MaterialAlertDialogBuilder(context).setTitle(if (existing == null) "Add rule" else "Edit rule")
|
||||
.setView(form).setNegativeButton("Cancel", null).setPositiveButton("Save", null)
|
||||
.apply { if (onDelete != null) setNeutralButton("Delete", null) }.show()
|
||||
@@ -85,13 +106,20 @@ object AlertRuleDialog {
|
||||
pattern.error = "Invalid regular expression"
|
||||
return@setOnClickListener
|
||||
}
|
||||
val selectedOutcome = outcomes[outcome.selectedItemPosition].first
|
||||
val profileId = if (selectedOutcome == AlertOutcome.PLAY_PROFILE) {
|
||||
profiles.getOrNull(profile.selectedItemPosition)?.id ?: run {
|
||||
android.widget.Toast.makeText(context, "Create a profile first", android.widget.Toast.LENGTH_LONG).show()
|
||||
return@setOnClickListener
|
||||
}
|
||||
} else null
|
||||
val definition = AlertRuleDefinition(
|
||||
sources,
|
||||
matcher,
|
||||
AlertOutcome.PLAY_PROFILE,
|
||||
configuration.profiles[profile.selectedItemPosition].id,
|
||||
protected.isChecked,
|
||||
dnd.isChecked,
|
||||
selectedOutcome,
|
||||
profileId,
|
||||
protected.isEnabled && protected.isChecked,
|
||||
dnd.isEnabled && dnd.isChecked,
|
||||
)
|
||||
onSave(apps?.let { selectedApps.toList() }, definition)
|
||||
dialog.dismiss()
|
||||
|
||||
@@ -53,10 +53,6 @@ class AppRulesFragment : Fragment(R.layout.fragment_app_rules) {
|
||||
|
||||
private fun edit(existing: AlertRule?) {
|
||||
val configuration = store.load()
|
||||
if (configuration.profiles.isEmpty()) {
|
||||
android.widget.Toast.makeText(requireContext(), "Create a profile first", android.widget.Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
AlertRuleDialog.show(requireContext(), configuration, existing,
|
||||
onSave = { _, definition ->
|
||||
store.save(if (existing == null) AlertRuleEditor.addForApps(configuration, listOf(packageName), definition) else AlertRuleEditor.updateForApp(configuration, existing.id, definition))
|
||||
|
||||
@@ -5,6 +5,8 @@ import android.view.View
|
||||
import android.widget.Button
|
||||
import androidx.fragment.app.Fragment
|
||||
import se.ajpanton.notificationsmaster.alerts.AlertConfigurationStore
|
||||
import se.ajpanton.notificationsmaster.alerts.AlertOutcome
|
||||
import se.ajpanton.notificationsmaster.alerts.AlertRuleDefinition
|
||||
import se.ajpanton.notificationsmaster.alerts.AlertRuleEditor
|
||||
import se.ajpanton.notificationsmaster.alerts.AlertSource
|
||||
import se.ajpanton.notificationsmaster.databinding.FragmentRulesBinding
|
||||
@@ -27,8 +29,8 @@ class RulesFragment : Fragment(R.layout.fragment_rules) {
|
||||
binding!!.rules.removeAllViews()
|
||||
AlertRuleEditor.consolidate(configuration.rules).forEach { rule ->
|
||||
binding!!.rules.addView(Button(requireContext()).apply {
|
||||
val profile = configuration.profiles.firstOrNull { it.id == rule.definition.profileId }?.name ?: "Missing profile"
|
||||
text = profile + "\n" + rule.packageNames.joinToString() + " • " + rule.definition.sources.joinToString { it.shortName() }
|
||||
text = rule.definition.outcomeLabel(configuration) + "\n" +
|
||||
rule.packageNames.joinToString() + " • " + rule.definition.sources.joinToString { it.shortName() }
|
||||
isAllCaps = false
|
||||
setOnClickListener { showEditor(rule.ruleIds) }
|
||||
})
|
||||
@@ -37,10 +39,6 @@ class RulesFragment : Fragment(R.layout.fragment_rules) {
|
||||
|
||||
private fun showEditor(ruleIds: Set<String>? = null) {
|
||||
val configuration = store.load()
|
||||
if (configuration.profiles.isEmpty()) {
|
||||
android.widget.Toast.makeText(requireContext(), "Create a profile first", android.widget.Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
val existing = ruleIds?.let { ids -> configuration.rules.first { it.id in ids } }
|
||||
AlertRuleDialog.show(
|
||||
requireContext(), configuration, existing, if (existing == null) InstalledApps.all(requireContext()) else null,
|
||||
@@ -58,4 +56,10 @@ class RulesFragment : Fragment(R.layout.fragment_rules) {
|
||||
}
|
||||
|
||||
private fun AlertSource.shortName() = if (this == AlertSource.NOTIFICATION_POST) "Appearing" else "Edits"
|
||||
|
||||
private fun AlertRuleDefinition.outcomeLabel(configuration: se.ajpanton.notificationsmaster.alerts.AlertConfiguration) = when (outcome) {
|
||||
AlertOutcome.PLAY_PROFILE -> configuration.profiles.firstOrNull { it.id == profileId }?.name ?: "Missing profile"
|
||||
AlertOutcome.SILENCE_ORIGINAL -> "Silence original alert"
|
||||
AlertOutcome.PASS_THROUGH -> "Keep original alert"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user