dergchat/src/xmpp_interface.rs

144 lines
5.2 KiB
Rust
Raw Normal View History

2023-12-09 15:24:57 -05:00
// Dergchat, a free XMPP client.
// Copyright (C) 2023 Werner Kroneman
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
2023-12-09 10:40:03 -05:00
use crate::types::{LoginCredentials, Message};
use dioxus::hooks::{UnboundedReceiver, UseRef};
use futures_util::stream::StreamExt;
use jid::BareJid;
2023-12-10 07:21:59 -05:00
use log::info;
2023-12-09 10:40:03 -05:00
use std::collections::HashMap;
use std::future::Future;
2023-12-10 07:21:59 -05:00
2023-12-09 10:40:03 -05:00
use tokio::select;
use xmpp::parsers::message::MessageType;
2023-12-10 07:21:59 -05:00
use xmpp::Agent;
2023-12-09 10:40:03 -05:00
async fn handle_event(
event: xmpp::Event,
agent: &mut xmpp::Agent,
messages: &mut UseRef<HashMap<BareJid, Vec<Message>>>,
) {
match event {
2023-12-10 07:21:59 -05:00
xmpp::Event::JoinRoom(jid, _conference) => {
2023-12-09 10:40:03 -05:00
println!("Will auto-join room: {}", &jid);
agent.join_room(jid, None, None, "en/us", "online").await;
}
xmpp::Event::RoomJoined(room_jid) => {
println!("Joined room: {}", &room_jid);
messages.with_mut(move |m| {
m.entry(room_jid.clone()).or_insert(vec![]);
});
}
xmpp::Event::RoomLeft(room_jid) => {
println!("Left room: {}", &room_jid);
messages.with_mut(move |m| {
m.remove(&room_jid);
});
}
2023-12-10 07:21:59 -05:00
xmpp::Event::ChatMessage(_id, sender, body) => {
2023-12-09 10:40:03 -05:00
println!("Message from {}: {}", &sender, &body.0);
messages.with_mut(move |m| {
m.entry(sender.clone()).or_insert(vec![]).push(Message {
sender: sender.to_string(),
body: body.0,
});
});
}
2023-12-10 07:21:59 -05:00
xmpp::Event::RoomMessage(_id, room_jid, sender_nick, body) => {
2023-12-09 10:40:03 -05:00
println!(
"Message in {} from {}: {}",
&room_jid, &sender_nick, &body.0
);
messages.with_mut(move |m| {
m.entry(room_jid.clone()).or_insert(vec![]).push(Message {
sender: sender_nick,
body: body.0,
})
});
}
2023-12-10 07:21:59 -05:00
xmpp::Event::RoomPrivateMessage(_id, room_jid, sender_nick, body) => {
2023-12-09 10:40:03 -05:00
println!(
"Private message in {} from {}: {}",
&room_jid, &sender_nick, &body.0
);
messages.with_mut(move |m| {
m.entry(room_jid.clone()).or_insert(vec![]).push(Message {
sender: sender_nick,
body: body.0,
})
});
}
_ => {
log::debug!("Received unsupported event {:?}", event);
}
}
}
#[derive(Debug)]
pub enum NetworkCommand {
TryLogin { credentials: LoginCredentials },
JoinRoom { room: BareJid },
LeaveRoom { room: BareJid },
SendMessage { recipient: BareJid, message: String },
}
pub fn xmpp_mainloop<'a>(
agent: &'a mut Agent,
mut room_data: &'a mut UseRef<HashMap<BareJid, Vec<Message>>>,
commands: &'a mut UnboundedReceiver<NetworkCommand>,
) -> impl Future<Output = ()> + Sized + 'a {
async move {
loop {
select! {
events = agent.wait_for_events() => {
if let Some(events) = events {
for event in events {
handle_event(event, agent, &mut room_data).await;
}
} else {
info!("Disconnected");
}
},
command = commands.next() => {
if let Some(command) = command {
match command {
NetworkCommand::JoinRoom { room } => {
agent.join_room(room.clone(), None, None, "en-us", "online").await;
},
NetworkCommand::LeaveRoom { room } => {
agent.leave_room(
room,
"dergchat".to_string(),
"en-us",
"User left the room.").await;
},
NetworkCommand::SendMessage { recipient, message } => {
agent.send_message(recipient.into(), MessageType::Groupchat, "en-us", &message).await;
},
2023-12-10 07:21:59 -05:00
NetworkCommand::TryLogin { credentials: _ } => {
2023-12-09 10:40:03 -05:00
panic!("Already logged in.");
},
}
} else {
info!("Command channel closed");
break;
}
},
}
}
}
}