package se.ajpanton.notificationsmaster import android.Manifest import android.content.ComponentName import android.content.Intent import android.os.Bundle import android.provider.Settings import android.view.View import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment import se.ajpanton.notificationsmaster.alerts.AlertConfigurationStore import se.ajpanton.notificationsmaster.capture.NotificationCaptureService import se.ajpanton.notificationsmaster.databinding.FragmentAlertStatusBinding import se.ajpanton.notificationsmaster.debug.DebugNotifications class AlertStatusFragment : Fragment(R.layout.fragment_alert_status) { private var binding: FragmentAlertStatusBinding? = null private var pendingCount: Int? = null private var pendingCycle = false private var updatingCycle = false private val permissionRequest = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> val context = context ?: return@registerForActivityResult if (granted) { pendingCount?.let { DebugNotifications.setCount(context, it) } if (pendingCycle) DebugNotifications.setCycling(context, true) refreshDebugControls() } else { Toast.makeText(context, R.string.debug_notification_permission_required, Toast.LENGTH_SHORT).show() refreshDebugControls() } pendingCount = null pendingCycle = false } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { binding = FragmentAlertStatusBinding.bind(view) binding!!.notificationAccess.setOnClickListener { startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)) } binding!!.debugMinus10.setOnClickListener { changeDebugCount(-10) } binding!!.debugMinus1.setOnClickListener { changeDebugCount(-1) } binding!!.debugPlus1.setOnClickListener { changeDebugCount(1) } binding!!.debugPlus10.setOnClickListener { changeDebugCount(10) } binding!!.debugReset.setOnClickListener { setDebugCount(0) } binding!!.debugCycle.setOnCheckedChangeListener { _, enabled -> if (updatingCycle) return@setOnCheckedChangeListener if (enabled && !DebugNotifications.hasPermission(requireContext())) { pendingCycle = true permissionRequest.launch(Manifest.permission.POST_NOTIFICATIONS) } else { DebugNotifications.setCycling(requireContext(), enabled) } } } override fun onResume() { super.onResume() val context = requireContext() val config = AlertConfigurationStore(context).load() val access = context.getSystemService(android.app.NotificationManager::class.java) .isNotificationListenerAccessGranted(ComponentName(context, NotificationCaptureService::class.java)) binding?.status?.text = buildString { append(if (access) "Notification access is enabled." else "Notification access is disabled.") append("\n\nCustom alerts are ") append(if (config.enabled) "enabled" else "disabled") append(" with ${config.rules.count { it.enabled }} active rule") append(if (config.rules.count { it.enabled } == 1) "." else "s.") } binding?.notificationAccess?.text = if (access) "Notification access enabled" else "Enable notification access" DebugNotifications.apply(context) refreshDebugControls() } private fun changeDebugCount(delta: Int) = setDebugCount(DebugNotifications.count(requireContext()) + delta) private fun setDebugCount(count: Int) { val desired = count.coerceIn(0, DebugNotifications.MAX_COUNT) if (desired > 0 && !DebugNotifications.hasPermission(requireContext())) { pendingCount = desired permissionRequest.launch(Manifest.permission.POST_NOTIFICATIONS) return } DebugNotifications.setCount(requireContext(), desired) refreshDebugControls() } private fun refreshDebugControls() { val context = context ?: return val count = DebugNotifications.count(context) binding?.debugCount?.text = count.toString() binding?.debugCycle?.isEnabled = count > 0 updatingCycle = true binding?.debugCycle?.isChecked = DebugNotifications.isCycling(context) updatingCycle = false } override fun onDestroyView() { binding = null; super.onDestroyView() } }