package se.ajpanton.notificationsmaster import android.content.Context import android.view.View import android.widget.ArrayAdapter import android.widget.CheckBox import android.widget.EditText import android.widget.LinearLayout import android.widget.Spinner import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.switchmaterial.SwitchMaterial import se.ajpanton.notificationsmaster.alerts.AlertConfiguration import se.ajpanton.notificationsmaster.alerts.AlertOutcome import se.ajpanton.notificationsmaster.alerts.AlertRule import se.ajpanton.notificationsmaster.alerts.AlertRuleDefinition import se.ajpanton.notificationsmaster.alerts.AlertSource import se.ajpanton.notificationsmaster.alerts.AlertTextField import se.ajpanton.notificationsmaster.alerts.AlertTextMatcher import se.ajpanton.notificationsmaster.alerts.AlertTextMode object AlertRuleDialog { fun show( context: Context, configuration: AlertConfiguration, existing: AlertRule?, apps: List? = null, onSave: (String?, AlertRuleDefinition) -> Unit, ) { val form = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL; setPadding(dp(context, 24), 0, dp(context, 24), 0) } val app = apps?.let { Spinner(context).apply { adapter = ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, it) existing?.let { rule -> setSelection(apps.indexOfFirst { choice -> choice.packageName == rule.packageName }.coerceAtLeast(0)) } }.also(form::addView) } 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)) } } 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 } val pattern = EditText(context).apply { hint = "Text to match (optional)"; setText(existing?.matcher?.value) } val regex = SwitchMaterial(context).apply { text = "Use regular expression"; isChecked = existing?.matcher?.mode == AlertTextMode.REGEX } val protected = SwitchMaterial(context).apply { text = "Play to completion"; isChecked = existing?.playToCompletion == true } val dnd = SwitchMaterial(context).apply { text = "Allow during DND when supported"; isChecked = existing?.allowDuringDnd == true } listOf(profile, post, update, pattern, regex, protected, dnd).forEach(form::addView) val dialog = MaterialAlertDialogBuilder(context).setTitle(if (existing == null) "Add rule" else "Edit rule") .setView(form).setNegativeButton("Cancel", null).setPositiveButton("Save", null).show() dialog.getButton(android.content.DialogInterface.BUTTON_POSITIVE).setOnClickListener { val sources = buildSet { if (post.isChecked) add(AlertSource.NOTIFICATION_POST) if (update.isChecked) add(AlertSource.NOTIFICATION_UPDATE) } if (sources.isEmpty()) { post.error = "Choose an event"; return@setOnClickListener } val value = pattern.text.toString().trim() val matcher = runCatching { AlertTextMatcher( AlertTextField.ANY_TEXT, if (value.isEmpty()) AlertTextMode.ANY else if (regex.isChecked) AlertTextMode.REGEX else AlertTextMode.CONTAINS, value, ) }.getOrElse { pattern.error = "Invalid regular expression" return@setOnClickListener } val definition = AlertRuleDefinition( sources, matcher, AlertOutcome.PLAY_PROFILE, configuration.profiles[profile.selectedItemPosition].id, protected.isChecked, dnd.isChecked, ) onSave(app?.selectedItem?.let { it as InstalledApp }?.packageName, definition) dialog.dismiss() } } private fun dp(context: Context, value: Int) = (value * context.resources.displayMetrics.density).toInt() }