Broadcast new occupant presence to existing occupants

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2022-09-12 00:53:29 +02:00
parent 769939be0a
commit 2f35111210
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
2 changed files with 80 additions and 39 deletions

View file

@ -78,17 +78,36 @@ impl Room {
// Send occupants
debug!("Sending occupants for {}", realjid);
let presence = Presence::new(PresenceType::None)
// Other participants to new participant
let presence_to_new = Presence::new(PresenceType::None)
// New occupant with a single session
.with_to(new_occupant.sessions[0].clone())
.with_payloads(vec![MucUser {
status: Vec::new(),
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
}.into()]);
}
.into()]);
// New participant to other participants
let presence_to_old = Presence::new(PresenceType::None)
.with_from(Jid::Full(new_occupant.participant.clone()))
.with_payloads(vec![MucUser {
status: Vec::new(),
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
}
.into()]);
for (_, occupant) in self.occupants.iter() {
let presence = presence.clone()
.with_from(occupant.participant.clone());
component.send_stanza(presence).await?;
component
.send_stanza(
presence_to_new
.clone()
.with_from(occupant.participant.clone()),
)
.await?;
for session in occupant.iter() {
component
.send_stanza(presence_to_old.clone().with_to(session.clone()))
.await?;
}
}
// Add into occupants

View file

@ -229,26 +229,40 @@ async fn test_join_presence_existing_room() {
// Ignore message subject for first participant
component.expect_message(|_| ());
// Occupant presences for participant2
// Participant1 presence for participant2
component.expect(
Presence::new(PresenceType::None)
.with_from(Jid::Full(participant1.clone()))
.with_to(Jid::Full(realjid2.clone()))
.with_payloads(vec![MucUser {
status: Vec::new(),
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
}.into()])
.with_from(Jid::Full(participant1.clone()))
.with_to(Jid::Full(realjid2.clone()))
.with_payloads(vec![MucUser {
status: Vec::new(),
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
}
.into()]),
);
// Participant2 presence for participant1
component.expect(
Presence::new(PresenceType::None)
.with_from(Jid::Full(participant2.clone()))
.with_to(Jid::Full(realjid1.clone()))
.with_payloads(vec![MucUser {
status: Vec::new(),
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
}
.into()]),
);
// self-presence for participant2
component.expect(
Presence::new(PresenceType::None)
.with_from(Jid::Full(participant2))
.with_to(Jid::Full(realjid2.clone()))
.with_payloads(vec![MucUser {
status: vec![MucStatus::SelfPresence, MucStatus::AssignedNick],
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
}.into()])
.with_from(Jid::Full(participant2))
.with_to(Jid::Full(realjid2.clone()))
.with_payloads(vec![MucUser {
status: vec![MucStatus::SelfPresence, MucStatus::AssignedNick],
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
}
.into()]),
);
// Subject for participant2
@ -334,13 +348,15 @@ async fn test_leave_last_participant() {
// Ignore subject message for participant1
component.expect_message(|_| ());
component.expect(Presence::new(PresenceType::Unavailable)
.with_from(Jid::Full(participant1.clone()))
.with_to(Jid::Full(realjid1.clone()))
.with_payloads(vec![MucUser {
status: vec![MucStatus::SelfPresence],
items: vec![MucItem::new(Affiliation::Owner, Role::None)],
}.into()])
component.expect(
Presence::new(PresenceType::Unavailable)
.with_from(Jid::Full(participant1.clone()))
.with_to(Jid::Full(realjid1.clone()))
.with_payloads(vec![MucUser {
status: vec![MucStatus::SelfPresence],
items: vec![MucItem::new(Affiliation::Owner, Role::None)],
}
.into()]),
);
handle_stanza(&mut component, &mut rooms).await.unwrap();
@ -386,25 +402,31 @@ async fn test_leave_room_not_last() {
component.expect_presence(|_| ());
// Ignore self-presence for participant2
component.expect_presence(|_| ());
// Ignore participant2 presence for participant1
component.expect_presence(|_| ());
// Ignore subject message for participant2
component.expect_message(|_| ());
component.expect(Presence::new(PresenceType::Unavailable)
.with_from(Jid::Full(participant2.clone()))
.with_to(Jid::Full(realjid2.clone()))
.with_payloads(vec![MucUser {
status: vec![MucStatus::SelfPresence],
items: vec![MucItem::new(Affiliation::Owner, Role::None)],
}.into()])
component.expect(
Presence::new(PresenceType::Unavailable)
.with_from(Jid::Full(participant2.clone()))
.with_to(Jid::Full(realjid2.clone()))
.with_payloads(vec![MucUser {
status: vec![MucStatus::SelfPresence],
items: vec![MucItem::new(Affiliation::Owner, Role::None)],
}
.into()]),
);
component.expect(Presence::new(PresenceType::Unavailable)
.with_from(Jid::Full(participant2.clone()))
.with_to(Jid::Full(realjid1.clone()))
.with_payloads(vec![MucUser {
status: Vec::new(),
items: vec![MucItem::new(Affiliation::Owner, Role::None)],
}.into()])
component.expect(
Presence::new(PresenceType::Unavailable)
.with_from(Jid::Full(participant2.clone()))
.with_to(Jid::Full(realjid1.clone()))
.with_payloads(vec![MucUser {
status: Vec::new(),
items: vec![MucItem::new(Affiliation::Owner, Role::None)],
}
.into()]),
);
handle_stanza(&mut component, &mut rooms).await.unwrap();