Add custom alert queue controller
This commit is contained in:
@@ -150,6 +150,22 @@ data class AlertDecision(
|
||||
val allowDuringDnd: Boolean,
|
||||
)
|
||||
|
||||
/** Resolved at match time so queued alerts never point at mutable settings. */
|
||||
data class AlertSnapshot(
|
||||
val soundUri: String?,
|
||||
val vibrationPattern: List<Long>,
|
||||
val playToCompletion: Boolean,
|
||||
val allowDuringDnd: Boolean,
|
||||
) {
|
||||
init {
|
||||
require(soundUri != null || vibrationPattern.any { it > 0 })
|
||||
}
|
||||
}
|
||||
|
||||
fun AlertDecision.snapshot(): AlertSnapshot? = profile?.let {
|
||||
AlertSnapshot(it.soundUri, it.vibrationPattern, playToCompletion, allowDuringDnd)
|
||||
}
|
||||
|
||||
data class AlertEvaluation(
|
||||
val decisions: List<AlertDecision>,
|
||||
val silenceUnmatchedDirectAlert: Boolean,
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package se.ajpanton.notificationsmaster.alerts
|
||||
|
||||
data class QueuedAlert(
|
||||
val ruleId: String,
|
||||
val snapshot: AlertSnapshot,
|
||||
)
|
||||
|
||||
/** The first alert is playing; any following alerts are waiting. */
|
||||
data class AlertQueue(
|
||||
val alerts: List<QueuedAlert> = emptyList(),
|
||||
) {
|
||||
val current get() = alerts.firstOrNull()
|
||||
}
|
||||
|
||||
data class AlertQueueTransition(
|
||||
val queue: AlertQueue,
|
||||
val started: QueuedAlert? = null,
|
||||
val interrupted: QueuedAlert? = null,
|
||||
val dropped: QueuedAlert? = null,
|
||||
val completed: QueuedAlert? = null,
|
||||
)
|
||||
|
||||
object AlertQueueController {
|
||||
fun enqueue(
|
||||
queue: AlertQueue,
|
||||
incoming: QueuedAlert,
|
||||
settings: AlertQueueSettings,
|
||||
): AlertQueueTransition {
|
||||
val alerts = queue.alerts
|
||||
if (alerts.isEmpty()) return AlertQueueTransition(AlertQueue(listOf(incoming)), started = incoming)
|
||||
|
||||
val tail = alerts.last()
|
||||
val appended = if (tail.snapshot.playToCompletion) alerts + incoming else alerts.dropLast(1) + incoming
|
||||
val interrupted = tail.takeUnless { tail.snapshot.playToCompletion }
|
||||
if (appended.size <= settings.maximumLength) {
|
||||
return AlertQueueTransition(
|
||||
AlertQueue(appended),
|
||||
started = incoming.takeIf { tail == alerts.first() && interrupted != null },
|
||||
interrupted = interrupted,
|
||||
)
|
||||
}
|
||||
return when (settings.overflow) {
|
||||
AlertQueueOverflow.DROP_NEWEST -> AlertQueueTransition(queue, dropped = incoming)
|
||||
AlertQueueOverflow.DROP_OLDEST -> {
|
||||
val next = appended.drop(1)
|
||||
AlertQueueTransition(
|
||||
AlertQueue(next),
|
||||
started = next.first(),
|
||||
interrupted = alerts.first(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun completeCurrent(queue: AlertQueue): AlertQueueTransition {
|
||||
val current = queue.current ?: return AlertQueueTransition(queue)
|
||||
val next = queue.alerts.drop(1)
|
||||
return AlertQueueTransition(AlertQueue(next), started = next.firstOrNull(), completed = current)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user