use super::traits::StanzaHandler;
use crate::client::Client;
use async_trait::async_trait;
use log::debug;
use std::sync::Arc;
use wacore::iq::chatstate::{
ChatstateParseError, ChatstateSource, ChatstateStanza, ReceivedChatState,
};
use wacore_binary::jid::Jid;
use wacore_binary::node::Node;
#[derive(Debug, Clone)]
pub struct ChatStateEvent {
pub chat: Jid,
pub participant: Option<Jid>,
pub state: ReceivedChatState,
}
impl ChatStateEvent {
pub fn from_stanza(stanza: ChatstateStanza) -> Self {
let (chat, participant) = match stanza.source {
ChatstateSource::User { from } => (from, None),
ChatstateSource::Group { from, participant } => (from, Some(participant)),
};
Self {
chat,
participant,
state: stanza.state,
}
}
}
#[derive(Default)]
pub struct ChatstateHandler;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl StanzaHandler for ChatstateHandler {
fn tag(&self) -> &'static str {
"chatstate"
}
async fn handle(&self, client: Arc<Client>, node: Arc<Node>, _cancelled: &mut bool) -> bool {
match ChatstateStanza::parse(&node) {
Ok(stanza) => {
debug!(
target: "ChatstateHandler",
"Received chatstate: {:?} from {:?}",
stanza.state,
stanza.source
);
client.dispatch_chatstate_event(stanza).await;
}
Err(ChatstateParseError::SelfEcho) => {
debug!(
target: "ChatstateHandler",
"Ignoring self-echo chatstate"
);
}
Err(e) => {
log::warn!(
target: "ChatstateHandler",
"Failed to parse chatstate stanza: {e}"
);
}
}
true
}
}