use super::*;
pub fn ensure_status_participants(mut stanza: Node, group_info: &GroupInfo) -> Node {
use wacore_binary::NodeContent;
use wacore_binary::builder::NodeBuilder;
let bare_to_nodes: Vec<Node> = group_info
.participants
.iter()
.map(|jid| NodeBuilder::new("to").attr("jid", jid.to_non_ad()).build())
.collect();
let children = match &mut stanza.content {
Some(NodeContent::Nodes(nodes)) => nodes,
_ => {
stanza.content = Some(NodeContent::Nodes(vec![]));
match &mut stanza.content {
Some(NodeContent::Nodes(nodes)) => nodes,
_ => unreachable!(),
}
}
};
if let Some(participants_node) = children.iter_mut().find(|n| n.tag == "participants") {
let existing_users: HashSet<CompactString> = participants_node
.children()
.unwrap_or_default()
.iter()
.filter_map(|n| n.attrs.get("jid").and_then(|v| v.to_jid()).map(|j| j.user))
.collect();
let new_to_nodes: Vec<Node> = bare_to_nodes
.into_iter()
.filter(|n| {
n.attrs
.get("jid")
.and_then(|v| v.to_jid())
.is_some_and(|j| !existing_users.contains(&j.user))
})
.collect();
if !new_to_nodes.is_empty() {
match &mut participants_node.content {
Some(NodeContent::Nodes(nodes)) => nodes.extend(new_to_nodes),
_ => {
participants_node.content = Some(NodeContent::Nodes(new_to_nodes));
}
}
}
} else {
let participants_node = NodeBuilder::new("participants")
.children(bare_to_nodes)
.build();
children.insert(0, participants_node);
}
stanza
}
pub fn status_carries_privacy_meta(message: &wa::Message) -> bool {
let msg = unwrap_message(message);
let is_revoke = msg
.protocol_message
.as_option()
.is_some_and(|pm| pm.r#type == Some(wa::message::protocol_message::Type::Revoke));
let is_reaction = msg.reaction_message.is_set() || msg.enc_reaction_message.is_set();
!is_revoke && !is_reaction
}
pub fn status_revoke_target_id(message: &wa::Message) -> Option<&str> {
let protocol_message = unwrap_message(message).protocol_message.as_option()?;
if protocol_message.r#type != Some(wa::message::protocol_message::Type::Revoke) {
return None;
}
protocol_message.key.as_option()?.id.as_deref()
}
pub fn assemble_status_participants<I>(resolved: I, own_lid: &Jid) -> Result<Vec<Jid>>
where
I: IntoIterator<Item = Option<Jid>>,
{
let iter = resolved.into_iter();
let (lower, _upper) = iter.size_hint();
let mut out: Vec<Jid> = Vec::with_capacity(lower.saturating_add(1));
for jid in iter.flatten() {
if !out.iter().any(|r| r.user == jid.user) {
out.push(jid);
}
}
if out.is_empty() {
anyhow::bail!("No valid status recipients after LID resolution");
}
if !out.iter().any(|r| r.user == own_lid.user) {
out.push(own_lid.to_non_ad());
}
Ok(out)
}