use std::sync::Arc;
use derive_more::Debug;
use tokio::sync::broadcast;
use tokio_util::sync::CancellationToken;
use tracing::{instrument, warn};
use wayle_core::Property;
use zbus::Connection;
use crate::{
builder::NotificationServiceBuilder, core::notification::Notification, error::Error,
events::NotificationEvent, persistence::NotificationStore, popup_timer::PopupTimerManager,
types::ClosedReason,
};
#[derive(Debug)]
pub struct NotificationService {
#[debug(skip)]
pub(crate) cancellation_token: CancellationToken,
#[debug(skip)]
pub(crate) notif_tx: broadcast::Sender<NotificationEvent>,
#[debug(skip)]
pub(crate) store: Option<NotificationStore>,
#[debug(skip)]
pub(crate) connection: Connection,
pub notifications: Property<Vec<Arc<Notification>>>,
pub popups: Property<Vec<Arc<Notification>>>,
pub popup_duration: Property<u32>,
pub dnd: Property<bool>,
pub remove_expired: Property<bool>,
pub blocklist: Property<Vec<String>>,
#[debug(skip)]
pub(crate) popup_timers: Arc<PopupTimerManager>,
}
impl NotificationService {
#[instrument(name = "NotificationService::new", err)]
pub async fn new() -> Result<Arc<Self>, Error> {
Self::builder().build().await
}
pub fn builder() -> NotificationServiceBuilder {
NotificationServiceBuilder::new()
}
#[instrument(skip(self), err)]
pub async fn dismiss_all(&self) -> Result<(), Error> {
let notifications = self.notifications.get();
for notif in notifications.iter() {
if let Err(error) = self.notif_tx.send(NotificationEvent::Remove(
notif.id,
ClosedReason::DismissedByUser,
)) {
warn!(error = %error, id = notif.id, "cannot dismiss notification");
}
}
Ok(())
}
pub fn set_dnd(&self, dnd: bool) {
self.dnd.set(dnd)
}
pub fn set_popup_duration(&self, duration: u32) {
self.popup_duration.set(duration)
}
pub fn set_blocklist(&self, patterns: Vec<String>) {
self.blocklist.set(patterns)
}
pub fn dismiss_popup(&self, id: u32) {
self.popup_timers.cancel(id);
let mut list = self.popups.get();
list.retain(|popup| popup.id != id);
self.popups.set(list);
}
pub fn inhibit_popup(&self, id: u32) {
self.popup_timers.pause(id);
}
pub fn release_popup(&self, id: u32) {
self.popup_timers.resume(id);
}
}
impl Drop for NotificationService {
fn drop(&mut self) {
self.cancellation_token.cancel();
}
}