forked from lavina/lavina
xmpp: add support leaving MUCs via unavailable presence
This commit is contained in:
parent
f02971d407
commit
fe802aca26
|
@ -23,36 +23,17 @@ impl<'a> XmppConnection<'a> {
|
||||||
server,
|
server,
|
||||||
// resources in MUCs are members' personas – not implemented (yet?)
|
// resources in MUCs are members' personas – not implemented (yet?)
|
||||||
resource: Some(_),
|
resource: Some(_),
|
||||||
}) if server.0 == self.hostname_rooms => {
|
}) if server.0 == self.hostname_rooms => match p.r#type.as_deref() {
|
||||||
let mut muc_presence = self.retrieve_muc_presence(&name).await?;
|
None => {
|
||||||
muc_presence.id = p.id;
|
self.join_muc(output, p.id, name).await?;
|
||||||
let subject = Message::<()> {
|
|
||||||
from: Some(Jid {
|
|
||||||
name: Some(name.clone()),
|
|
||||||
server: Server(self.hostname_rooms.clone()),
|
|
||||||
resource: None,
|
|
||||||
}),
|
|
||||||
id: None,
|
|
||||||
to: Some(Jid {
|
|
||||||
name: Some(self.user.xmpp_name.clone()),
|
|
||||||
server: Server(self.hostname.clone()),
|
|
||||||
resource: Some(self.user.xmpp_resource.clone()),
|
|
||||||
}),
|
|
||||||
r#type: MessageType::Groupchat,
|
|
||||||
lang: None,
|
|
||||||
subject: Some(Subject(None)),
|
|
||||||
body: None,
|
|
||||||
custom: vec![],
|
|
||||||
};
|
|
||||||
muc_presence.serialize(output);
|
|
||||||
|
|
||||||
let messages = self.retrieve_message_history(&name).await?;
|
|
||||||
for message in messages {
|
|
||||||
message.serialize(output)
|
|
||||||
}
|
}
|
||||||
// The subject is the last stanza sent during a MUC join process.
|
Some("unavailable") => {
|
||||||
subject.serialize(output);
|
self.leave_muc(output, p.id, name).await?;
|
||||||
}
|
}
|
||||||
|
_ => {
|
||||||
|
tracing::error!("Unimplemented case")
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
// TODO other presence cases
|
// TODO other presence cases
|
||||||
let response = Presence::<()>::default();
|
let response = Presence::<()>::default();
|
||||||
|
@ -62,6 +43,74 @@ impl<'a> XmppConnection<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn join_muc(&mut self, output: &mut Vec<Event<'static>>, id: Option<String>, name: Name) -> Result<()> {
|
||||||
|
// Response presence
|
||||||
|
let mut muc_presence = self.retrieve_muc_presence(&name).await?;
|
||||||
|
muc_presence.id = id;
|
||||||
|
muc_presence.serialize(output);
|
||||||
|
|
||||||
|
// N last messages from the room history before the user joined
|
||||||
|
let messages = self.retrieve_message_history(&name).await?;
|
||||||
|
for message in messages {
|
||||||
|
message.serialize(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The subject is the last stanza sent during a MUC join process.
|
||||||
|
let subject = Message::<()> {
|
||||||
|
from: Some(Jid {
|
||||||
|
name: Some(name.clone()),
|
||||||
|
server: Server(self.hostname_rooms.clone()),
|
||||||
|
resource: None,
|
||||||
|
}),
|
||||||
|
id: None,
|
||||||
|
to: Some(Jid {
|
||||||
|
name: Some(self.user.xmpp_name.clone()),
|
||||||
|
server: Server(self.hostname.clone()),
|
||||||
|
resource: Some(self.user.xmpp_resource.clone()),
|
||||||
|
}),
|
||||||
|
r#type: MessageType::Groupchat,
|
||||||
|
lang: None,
|
||||||
|
subject: Some(Subject(None)),
|
||||||
|
body: None,
|
||||||
|
custom: vec![],
|
||||||
|
};
|
||||||
|
subject.serialize(output);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn leave_muc(&mut self, output: &mut Vec<Event<'static>>, id: Option<String>, name: Name) -> Result<()> {
|
||||||
|
self.user_handle.leave_room(RoomId::try_from(name.0.clone())?).await?;
|
||||||
|
let response = Presence {
|
||||||
|
to: Some(Jid {
|
||||||
|
name: Some(self.user.xmpp_name.clone()),
|
||||||
|
server: Server(self.hostname.clone()),
|
||||||
|
resource: Some(self.user.xmpp_resource.clone()),
|
||||||
|
}),
|
||||||
|
from: Some(Jid {
|
||||||
|
name: Some(name.clone()),
|
||||||
|
server: Server(self.hostname_rooms.clone()),
|
||||||
|
resource: Some(self.user.xmpp_muc_name.clone()),
|
||||||
|
}),
|
||||||
|
r#type: Some("unavailable".into()),
|
||||||
|
custom: vec![XUser {
|
||||||
|
item: XUserItem {
|
||||||
|
affiliation: Affiliation::Member,
|
||||||
|
role: Role::None,
|
||||||
|
jid: Jid {
|
||||||
|
name: Some(self.user.xmpp_name.clone()),
|
||||||
|
server: Server(self.hostname.clone()),
|
||||||
|
resource: Some(self.user.xmpp_resource.clone()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
self_presence: true,
|
||||||
|
just_created: false,
|
||||||
|
}],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
response.serialize(output);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self, output, r#type), name = "XmppConnection::self_presence")]
|
#[tracing::instrument(skip(self, output, r#type), name = "XmppConnection::self_presence")]
|
||||||
async fn self_presence(&mut self, output: &mut Vec<Event<'static>>, r#type: Option<&str>) {
|
async fn self_presence(&mut self, output: &mut Vec<Event<'static>>, r#type: Option<&str>) {
|
||||||
match r#type {
|
match r#type {
|
||||||
|
@ -92,7 +141,7 @@ impl<'a> XmppConnection<'a> {
|
||||||
|
|
||||||
#[tracing::instrument(skip(self), name = "XmppConnection::retrieve_muc_presence")]
|
#[tracing::instrument(skip(self), name = "XmppConnection::retrieve_muc_presence")]
|
||||||
async fn retrieve_muc_presence(&mut self, name: &Name) -> Result<Presence<XUser>> {
|
async fn retrieve_muc_presence(&mut self, name: &Name) -> Result<Presence<XUser>> {
|
||||||
let a = self.user_handle.join_room(RoomId::try_from(name.0.clone())?).await?;
|
let _ = self.user_handle.join_room(RoomId::try_from(name.0.clone())?).await?;
|
||||||
// TODO handle bans
|
// TODO handle bans
|
||||||
let response = Presence {
|
let response = Presence {
|
||||||
to: Some(Jid {
|
to: Some(Jid {
|
||||||
|
@ -273,7 +322,7 @@ mod tests {
|
||||||
just_created: false,
|
just_created: false,
|
||||||
}],
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
assert_eq!(expected, response);
|
assert_eq!(expected, response);
|
||||||
|
|
||||||
drop(conn);
|
drop(conn);
|
||||||
|
|
Loading…
Reference in New Issue