forked from lavina/lavina
1
0
Fork 0

send subject

This commit is contained in:
Nikita Vilunov 2024-05-15 14:18:19 +02:00
parent a22017ee8f
commit 8b05c852e7
3 changed files with 49 additions and 17 deletions

View File

@ -5,7 +5,7 @@ use quick_xml::events::Event;
use lavina_core::room::RoomId;
use proto_xmpp::bind::{Jid, Name, Server};
use proto_xmpp::client::Presence;
use proto_xmpp::client::{Message, MessageType, Presence};
use proto_xmpp::muc::XUser;
use proto_xmpp::xml::{Ignore, ToXml};
@ -23,11 +23,30 @@ impl<'a> XmppConnection<'a> {
// resources in MUCs are members' personas not implemented (yet?)
resource: Some(_),
}) if server.0 == self.hostname_rooms => {
let response = self.muc_presence(&name).await?;
let response = self.muc_presence(p.id.as_ref(), &name).await?;
let message = Message::<()> {
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: None,
}),
r#type: MessageType::Groupchat,
subject: Some("".into()),
id: None,
lang: None,
body: "".into(),
custom: vec![],
};
response.serialize(output);
message.serialize(output);
}
_ => {
// TODO other presence cases
// TODO other presence casess
let response = Presence::<()>::default();
response.serialize(output);
}
@ -56,15 +75,18 @@ impl<'a> XmppConnection<'a> {
};
response.serialize(output);
}
_ => todo!(),
_ => {
tracing::error!("TODO");
}
}
}
// todo: return Presence and serialize on the outside.
async fn muc_presence(&mut self, name: &Name) -> Result<(Presence<XUser>)> {
async fn muc_presence(&mut self, id: Option<&String>, name: &Name) -> Result<(Presence<XUser>)> {
let a = self.user_handle.join_room(RoomId::from(name.0.clone())?).await?;
// TODO handle bans
let response = Presence {
id: id.map(ToOwned::to_owned),
to: Some(Jid {
name: Some(self.user.xmpp_name.clone()),
server: Server(self.hostname.clone()),

View File

@ -20,7 +20,7 @@ pub struct Message<T> {
// default is Normal
pub r#type: MessageType,
pub lang: Option<Str>,
pub subject: Option<Str>,
pub subject: Option<Str>, // TODO there are three states of <subject -- not present, empty and some string
pub body: Str,
pub custom: Vec<T>,
}
@ -50,6 +50,7 @@ enum MessageParserInner<T: FromXml> {
InBody(MessageParserState<T>),
InCustom(MessageParserState<T>, T::P),
}
#[derive(Default)]
struct MessageParserState<T> {
from: Option<Jid>,
@ -61,6 +62,7 @@ struct MessageParserState<T> {
body: Option<Str>,
custom: Vec<T>,
}
impl<T: FromXml> Parser for MessageParser<T> {
type Output = Result<Message<T>>;
@ -208,9 +210,18 @@ impl<T: ToXml> ToXml for Message<T> {
value: self.r#type.as_str().as_bytes().into(),
});
events.push(Event::Start(bytes));
events.push(Event::Start(BytesStart::new("body")));
events.push(Event::Text(BytesText::new(&self.body).into_owned()));
events.push(Event::End(BytesEnd::new("body")));
if self.subject.is_none() {
// TODO make body optional
events.push(Event::Start(BytesStart::new("body")));
events.push(Event::Text(BytesText::new(&self.body).into_owned()));
events.push(Event::End(BytesEnd::new("body")));
}
if let Some(subject) = &self.subject {
// TODO make subject tri-state
events.push(Event::Start(BytesStart::new("subject")));
events.push(Event::Text(BytesText::new(&subject).into_owned()));
events.push(Event::End(BytesEnd::new("subject")));
}
events.push(Event::End(BytesEnd::new("message")));
}
}
@ -266,6 +277,7 @@ pub struct IqError {
pub enum IqErrorCondition {
ItemNotFound,
}
impl IqErrorCondition {
pub fn as_str(&self) -> &'static str {
match self {
@ -286,6 +298,7 @@ pub enum IqErrorType {
/// Retry after waiting (the error is temporary)
Wait,
}
impl IqErrorType {
pub fn as_str(&self) -> &'static str {
match self {
@ -345,6 +358,7 @@ enum IqParserInner<T: FromXml> {
ParsingBody(IqParserState<T>, T::P),
Final(IqParserState<T>),
}
struct IqParserState<T> {
pub from: Option<Jid>,
pub id: Option<String>,
@ -706,7 +720,7 @@ mod tests {
to: Some(Jid {
name: Some(Name("chelik".into())),
server: Server("xmpp.ru".into()),
resource: None
resource: None,
}),
r#type: MessageType::Chat,
lang: None,
@ -729,7 +743,7 @@ mod tests {
to: Some(Jid {
name: Some(Name("chelik".into())),
server: Server("xmpp.ru".into()),
resource: None
resource: None,
}),
r#type: MessageType::Chat,
lang: None,
@ -751,7 +765,7 @@ mod tests {
id: "bind_1".to_string(),
to: None,
r#type: IqType::Set,
body: BindRequest(Resource("mobile".into()))
body: BindRequest(Resource("mobile".into())),
}
)
}

View File

@ -155,13 +155,9 @@ impl ToXml for XUser {
let mut meg = BytesStart::new("item");
meg.push_attribute(("affiliation", "owner"));
meg.push_attribute(("role", "moderator"));
meg.push_attribute(("jid", "sauer@localhost"));
meg.push_attribute(("jid", "user@localhost/user"));
output.push(Event::Empty(meg));
let mut veg = BytesStart::new("status");
veg.push_attribute(("code", "100"));
output.push(Event::Empty(veg));
let mut veg = BytesStart::new("status");
veg.push_attribute(("code", "110"));
output.push(Event::Empty(veg));