use super::traits::StanzaHandler;
use crate::client::Client;
use async_trait::async_trait;
use log::debug;
use std::sync::Arc;
use wacore::types::events::{Event, PresenceUpdate};
#[derive(Default)]
pub struct PresenceHandler;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl StanzaHandler for PresenceHandler {
fn tag(&self) -> &'static str {
"presence"
}
#[cfg_attr(
feature = "tracing",
tracing::instrument(name = "wa.recv.presence", level = "debug", skip_all)
)]
async fn handle(
&self,
client: Arc<Client>,
node: Arc<wacore_binary::OwnedNodeRef>,
_cancelled: &mut bool,
) -> bool {
let nr = node.get();
let from_jid = match nr.get_attr("from").and_then(|v| v.to_jid()) {
Some(jid) => jid,
None => {
debug!(target: "PresenceHandler", "Presence stanza missing or invalid 'from' attribute");
return true;
}
};
let unavailable = nr
.get_attr("type")
.is_some_and(|v| v.as_str() == "unavailable");
let last_seen = nr
.get_attr("last")
.map(|v| v.as_str())
.and_then(|s| s.parse::<i64>().ok())
.and_then(wacore::time::from_secs);
debug!(
target: "PresenceHandler",
"Received presence from {}: unavailable={}",
from_jid.observe(), unavailable
);
client.core.event_bus.dispatch(Event::Presence(
PresenceUpdate::builder()
.from(from_jid)
.unavailable(unavailable)
.maybe_last_seen(last_seen)
.build(),
));
true
}
}