use super::dom::{attr_value, strip_text, tags_where};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Bell {
pub unread: u64,
pub notifications: Vec<BellNotification>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BellNotification {
pub id: String,
pub title: String,
pub read: bool,
pub status: String,
pub actions: Vec<(String, String)>,
}
pub fn bell(html: &str) -> Option<Bell> {
let trigger = tags_where(html, |tag, attrs| {
tag == "button"
&& attr_value(attrs, "aria-controls").as_deref() == Some("tablo-notifications")
});
if trigger.is_empty() {
return None;
}
let unread = tags_where(html, |tag, attrs| {
tag == "span" && attr_value(attrs, "data-unread").is_some()
})
.first()
.and_then(|(_, attrs, _)| attr_value(attrs, "data-unread")?.parse().ok())
.unwrap_or(0);
let notifications = tags_where(html, |tag, attrs| {
tag == "li" && attr_value(attrs, "data-notification").is_some()
})
.into_iter()
.map(|(_, attrs, inner)| BellNotification {
id: attr_value(&attrs, "data-notification").unwrap_or_default(),
title: tags_where(&inner, |tag, _| tag == "p")
.first()
.map(|(_, _, text)| strip_text(text))
.unwrap_or_default(),
read: attr_value(&attrs, "data-read").as_deref() == Some("true"),
status: attr_value(&attrs, "data-type").unwrap_or_default(),
actions: tags_where(&inner, |tag, _| tag == "a")
.into_iter()
.map(|(_, attrs, text)| {
(
strip_text(&text),
attr_value(&attrs, "href").unwrap_or_default(),
)
})
.collect(),
})
.collect();
Some(Bell {
unread,
notifications,
})
}