mirror of
https://gitea.mizah.xyz/mizah/dergchat
synced 2025-01-30 18:40:09 -05:00
Added dedicated types to Room/MucRoom/Direct messages, etc...
It's still a bit of a mess though.
This commit is contained in:
parent
53ad01ed41
commit
837dca3e15
39
src/types.rs
39
src/types.rs
@ -1,39 +0,0 @@
|
||||
// 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/>.
|
||||
|
||||
use crate::passwords::Password;
|
||||
use jid::BareJid;
|
||||
use std::fmt::Debug;
|
||||
use chrono::{DateTime, FixedOffset};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Room {
|
||||
pub messages: Vec<Message>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Message {
|
||||
pub sender: String,
|
||||
pub body: String,
|
||||
pub timestamp: DateTime<FixedOffset>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoginCredentials {
|
||||
pub username: BareJid,
|
||||
pub default_nick: String,
|
||||
pub password: Password,
|
||||
}
|
93
src/types/message.rs
Normal file
93
src/types/message.rs
Normal file
@ -0,0 +1,93 @@
|
||||
// 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/>.
|
||||
|
||||
use chrono::{DateTime, FixedOffset};
|
||||
use crate::types::{DirectMessage, MessageDeliveryError, MucMessage, Nickname};
|
||||
|
||||
/// An outgoing status for a message.
|
||||
///
|
||||
/// See: https://docs.modernxmpp.org/client/design/#conversation-view
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum OutgoingMessageStatus {
|
||||
PendingDelivery,
|
||||
DeliveredToServer,
|
||||
DeliveredToContact,
|
||||
ReadByContact,
|
||||
DeliveryError(MessageDeliveryError),
|
||||
}
|
||||
|
||||
/// An enum type signaling whether a message is incoming or outgoing.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum MessageInOut {
|
||||
/// An incoming message.
|
||||
Incoming,
|
||||
/// An outgoing message, with a status.
|
||||
Outgoing(OutgoingMessageStatus),
|
||||
}
|
||||
|
||||
/// A message, either incoming or outgoing.
|
||||
///
|
||||
/// This is a trait, because MUC messages and direct messages are subtly different.
|
||||
pub trait Message {
|
||||
|
||||
/// Whether the message is incoming or outgoing.
|
||||
/// If outgoing, also contains the status of the message.
|
||||
fn in_out(&self) -> &MessageInOut;
|
||||
|
||||
/// The body of the message, as a string. (TODO: Language?)
|
||||
fn body(&self) -> &String;
|
||||
|
||||
/// The timestamp of the message; when it was sent originally.
|
||||
fn timestamp(&self) -> &DateTime<FixedOffset>;
|
||||
|
||||
fn sender_nick(&self) -> Nickname;
|
||||
}
|
||||
|
||||
impl Message for MucMessage {
|
||||
fn in_out(&self) -> &MessageInOut {
|
||||
&self.in_out
|
||||
}
|
||||
|
||||
fn body(&self) -> &String {
|
||||
&self.body
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> &DateTime<FixedOffset> {
|
||||
&self.timestamp
|
||||
}
|
||||
|
||||
fn sender_nick(&self) -> Nickname {
|
||||
self.sender_nick.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Message for DirectMessage {
|
||||
fn in_out(&self) -> &MessageInOut {
|
||||
&self.in_out
|
||||
}
|
||||
|
||||
fn body(&self) -> &String {
|
||||
&self.body
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> &DateTime<FixedOffset> {
|
||||
&self.timestamp
|
||||
}
|
||||
|
||||
fn sender_nick(&self) -> Nickname {
|
||||
Nickname("Not implemented.".to_string())
|
||||
}
|
||||
}
|
89
src/types/mod.rs
Normal file
89
src/types/mod.rs
Normal file
@ -0,0 +1,89 @@
|
||||
// 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/>.
|
||||
|
||||
use crate::passwords::Password;
|
||||
use jid::BareJid;
|
||||
use std::fmt::Debug;
|
||||
use chrono::{DateTime, FixedOffset};
|
||||
use message::{Message, MessageInOut};
|
||||
|
||||
pub mod message;
|
||||
pub mod room;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct DirectMessageRoom {
|
||||
pub messages: Vec<DirectMessage>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct MucRoom {
|
||||
pub messages: Vec<MucMessage>,
|
||||
}
|
||||
|
||||
pub trait Room {
|
||||
type Message: Message;
|
||||
|
||||
fn messages(&self) -> &Vec<Self::Message>;
|
||||
}
|
||||
|
||||
impl Room for DirectMessageRoom {
|
||||
type Message = DirectMessage;
|
||||
|
||||
fn messages(&self) -> &Vec<Self::Message> {
|
||||
&self.messages
|
||||
}
|
||||
}
|
||||
|
||||
impl Room for MucRoom {
|
||||
type Message = MucMessage;
|
||||
|
||||
fn messages(&self) -> &Vec<Self::Message> {
|
||||
&self.messages
|
||||
}
|
||||
}
|
||||
|
||||
/// A nickname for a user.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Nickname(pub String);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct MucMessage {
|
||||
pub in_out: MessageInOut,
|
||||
pub sender_nick: Nickname,
|
||||
pub body: String,
|
||||
pub timestamp: DateTime<FixedOffset>,
|
||||
pub is_private: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct DirectMessage {
|
||||
pub in_out: MessageInOut,
|
||||
pub body: String,
|
||||
pub timestamp: DateTime<FixedOffset>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoginCredentials {
|
||||
pub username: BareJid,
|
||||
pub default_nick: String,
|
||||
pub password: Password,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct MessageDeliveryError {
|
||||
pub error: String,
|
||||
}
|
||||
|
66
src/types/room.rs
Normal file
66
src/types/room.rs
Normal file
@ -0,0 +1,66 @@
|
||||
// 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/>.
|
||||
|
||||
// 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/>.
|
||||
|
||||
use crate::types::{DirectMessageRoom, MucRoom};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Room {
|
||||
Direct(DirectMessageRoom),
|
||||
Muc(MucRoom),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct WrongRoomType;
|
||||
|
||||
impl<'a> TryInto<&'a mut DirectMessageRoom> for &'a mut Room {
|
||||
type Error = WrongRoomType;
|
||||
|
||||
fn try_into(self) -> Result<&'a mut DirectMessageRoom, Self::Error> {
|
||||
match self {
|
||||
Room::Direct(room) => Ok(room),
|
||||
_ => Err(WrongRoomType),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'a> TryInto<&'a mut MucRoom> for &'a mut Room {
|
||||
type Error = WrongRoomType;
|
||||
|
||||
fn try_into(self) -> Result<&'a mut MucRoom, Self::Error> {
|
||||
match self {
|
||||
Room::Muc(room) => Ok(room),
|
||||
_ => Err(WrongRoomType),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -34,8 +34,9 @@ use dioxus::prelude::*;
|
||||
use futures_util::StreamExt;
|
||||
use jid::BareJid;
|
||||
use log::{error, info};
|
||||
use std::collections::HashMap;
|
||||
use std::string::String;
|
||||
use crate::xmpp_interface::Messages;
|
||||
use crate::types::room::Room;
|
||||
|
||||
pub mod login_screen;
|
||||
pub mod no_room_open;
|
||||
@ -46,7 +47,7 @@ pub mod send_message;
|
||||
pub mod sidebar;
|
||||
|
||||
pub fn App(cx: Scope) -> Element {
|
||||
let messages = use_ref(cx, || HashMap::new());
|
||||
let messages = use_ref(cx, || Messages::new());
|
||||
let current_room = use_state(cx, || None::<BareJid>);
|
||||
let connection_status = use_state(cx, || LoginStatus::LoggedOut);
|
||||
|
||||
@ -73,23 +74,35 @@ pub fn App(cx: Scope) -> Element {
|
||||
}
|
||||
});
|
||||
|
||||
// Can I not clone this? Am I reconstructing the entire VDOM every time? What's happening?
|
||||
// TODO: The borrowing situation here is kinda fucked; how do I fix this?
|
||||
let current_room_messages = current_room.get().clone().and_then(|x| messages.read().messages.get(&x).map(|x| x.clone()));
|
||||
|
||||
render! {
|
||||
|
||||
// If not logged in, show a login screen.
|
||||
if let LoginStatus::LoggedIn(user) = connection_status.get() {
|
||||
|
||||
let room_list = messages.read().messages.iter().map(|(k, v)| {
|
||||
match v {
|
||||
Room::Direct(d) => RoomMeta {
|
||||
room: k.clone(),
|
||||
last_update_time: d.messages.last().map(|x| x.timestamp).map(|x| x.clone()),
|
||||
},
|
||||
Room::Muc(m) => RoomMeta {
|
||||
room: k.clone(),
|
||||
last_update_time: m.messages.last().map(|x| x.timestamp).map(|x| x.clone()),
|
||||
},
|
||||
}
|
||||
}).collect();
|
||||
|
||||
// We're logged in; show a sidebar and a room view.
|
||||
rsx!{
|
||||
|
||||
// Sidebar.
|
||||
SideBar {
|
||||
current_user: user.clone(),
|
||||
rooms: messages.read().iter().map(|(k, v)| {
|
||||
RoomMeta {
|
||||
room: k.clone(),
|
||||
last_update_time: v.last().map(|x| x.timestamp),
|
||||
}
|
||||
}).collect(),
|
||||
rooms: room_list,
|
||||
on_room_picked: move |x: BareJid| {
|
||||
current_room.set(Some(x.clone()));
|
||||
coroutine.send(NetworkCommand::JoinRoom { room: x });
|
||||
@ -109,16 +122,34 @@ pub fn App(cx: Scope) -> Element {
|
||||
}
|
||||
|
||||
// The current room.
|
||||
if let Some(room) = current_room.get() {
|
||||
rsx! {
|
||||
RoomView {
|
||||
room: room.clone(),
|
||||
messages: messages.read().get(&room).expect("Selected non-existant room").to_vec(),
|
||||
on_message_sent: move |x:String| {
|
||||
println!("Message sent: {:?}", x);
|
||||
coroutine.send(NetworkCommand::SendMessage { recipient: room.clone(), message: x });
|
||||
},
|
||||
if let Some(room) = current_room_messages {
|
||||
match (room) {
|
||||
Room::Direct(r) => {
|
||||
// Direct message room
|
||||
rsx! {
|
||||
RoomView {
|
||||
room: current_room.get().clone().unwrap(),
|
||||
messages: r,
|
||||
on_message_sent: move |x:String| {
|
||||
println!("Message sent: {:?}", x);
|
||||
coroutine.send(NetworkCommand::SendMessage { recipient: current_room.get().clone().unwrap(), message: x });
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
Room::Muc(r) => {
|
||||
// MUC room
|
||||
rsx! {
|
||||
RoomView {
|
||||
room: current_room.get().clone().unwrap(),
|
||||
messages: r,
|
||||
on_message_sent: move |x:String| {
|
||||
println!("Message sent: {:?}", x);
|
||||
coroutine.send(NetworkCommand::SendMessage { recipient: current_room.get().clone().unwrap(), message: x });
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
// No room selected
|
||||
|
@ -14,19 +14,20 @@
|
||||
// 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/>.
|
||||
|
||||
use crate::types::Message;
|
||||
use crate::types::message::Message;
|
||||
use crate::widgets::send_message::SendMessage;
|
||||
use dioxus::core::{Element, Scope};
|
||||
use dioxus::core_macro::Props;
|
||||
use dioxus::hooks::use_state;
|
||||
use dioxus::prelude::*;
|
||||
use jid::BareJid;
|
||||
use crate::types::Room;
|
||||
|
||||
/// A widget that shows a room, including a list of messages and a widget to send new messages.
|
||||
#[component]
|
||||
pub fn RoomView<'a>(cx: Scope<'a>,
|
||||
pub fn RoomView<'a, R:Room>(cx: Scope<'a>,
|
||||
room: BareJid,
|
||||
messages: Vec<Message>,
|
||||
messages: R,
|
||||
on_message_sent: EventHandler<'a, String>) -> Element<'a> {
|
||||
|
||||
render! {
|
||||
@ -49,9 +50,9 @@ pub fn RoomView<'a>(cx: Scope<'a>,
|
||||
ul {
|
||||
flex_grow: 1,
|
||||
overflow_y: "scroll",
|
||||
for message in cx.props.messages.iter() {
|
||||
for message in cx.props.messages.messages().iter() {
|
||||
rsx! { li {
|
||||
"{message.sender}: {message.body}"
|
||||
"{message.sender_nick().0}: {message.body()}"
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
@ -14,19 +14,19 @@
|
||||
// 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/>.
|
||||
|
||||
use crate::types::{LoginCredentials, Message};
|
||||
use crate::types::{DirectMessage, DirectMessageRoom, LoginCredentials, MucMessage, MucRoom, Nickname};
|
||||
use dioxus::hooks::{UnboundedReceiver, UseRef, UseState};
|
||||
use futures_util::stream::StreamExt;
|
||||
use jid::BareJid;
|
||||
use log::{error, info};
|
||||
use log::{debug, error, info, warn};
|
||||
use std::collections::HashMap;
|
||||
use std::future::Future;
|
||||
use std::time::Instant;
|
||||
|
||||
use crate::widgets::login_screen::LoginStatus;
|
||||
use tokio::select;
|
||||
use xmpp::parsers::message::MessageType;
|
||||
use xmpp::{Agent, ClientBuilder, ClientType};
|
||||
use crate::types::room::{Room, WrongRoomType};
|
||||
use crate::types::message::MessageInOut;
|
||||
|
||||
/// An enum of commands that can be sent to the XMPP interface.
|
||||
///
|
||||
@ -48,73 +48,124 @@ pub enum NetworkCommand {
|
||||
Logout,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Messages {
|
||||
pub messages: HashMap<BareJid, Room>,
|
||||
}
|
||||
|
||||
impl Messages {
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
messages: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, room: &BareJid) -> Option<&Room> {
|
||||
self.messages.get(room)
|
||||
}
|
||||
|
||||
pub fn get_or_create_mut_direct(&mut self, room: &BareJid) -> Result<&mut DirectMessageRoom, WrongRoomType> {
|
||||
self.messages.entry(room.clone()).or_insert(Room::Direct(DirectMessageRoom {
|
||||
messages: vec![],
|
||||
})).try_into()
|
||||
}
|
||||
|
||||
pub fn get_or_create_mut_muc(&mut self, room: &BareJid) -> Result<&mut MucRoom, WrongRoomType> {
|
||||
self.messages.entry(room.clone()).or_insert(Room::Muc(MucRoom {
|
||||
messages: vec![],
|
||||
})).try_into()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async fn handle_event(
|
||||
event: xmpp::Event,
|
||||
agent: &mut xmpp::Agent,
|
||||
messages: &mut UseRef<HashMap<BareJid, Vec<Message>>>,
|
||||
messages: &mut UseRef<Messages>,
|
||||
) {
|
||||
match event {
|
||||
xmpp::Event::JoinRoom(jid, _conference) => {
|
||||
println!("Will auto-join room: {}", &jid);
|
||||
debug!("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);
|
||||
debug!("Joined room: {}", &room_jid);
|
||||
messages.with_mut(move |m| {
|
||||
m.entry(room_jid.clone()).or_insert(vec![]);
|
||||
m.messages.entry(room_jid.clone()).or_insert(Room::Muc(MucRoom {
|
||||
messages: vec![],
|
||||
}));
|
||||
});
|
||||
}
|
||||
xmpp::Event::RoomLeft(room_jid) => {
|
||||
println!("Left room: {}", &room_jid);
|
||||
debug!("Left room: {}", &room_jid);
|
||||
messages.with_mut(move |m| {
|
||||
m.remove(&room_jid);
|
||||
m.messages.remove(&room_jid);
|
||||
});
|
||||
}
|
||||
xmpp::Event::ChatMessage(_id, sender, body, timestamp) => {
|
||||
println!("Message from {}: {}", &sender, &body.0);
|
||||
debug!("Message from {}: {}", &sender, &body.0);
|
||||
messages.with_mut(move |m| {
|
||||
m.entry(sender.clone()).or_insert(vec![]).push(Message {
|
||||
sender: sender.to_string(),
|
||||
let dms : &mut DirectMessageRoom = m.messages.entry(sender.clone()).or_insert(Room::Direct(DirectMessageRoom {
|
||||
messages: vec![],
|
||||
})).try_into().expect("Received direct message with a JID from a MUC");
|
||||
|
||||
dms.messages.push(DirectMessage {
|
||||
in_out: MessageInOut::Incoming,
|
||||
body: body.0,
|
||||
timestamp,
|
||||
});
|
||||
});
|
||||
}
|
||||
xmpp::Event::RoomMessage(_id, room_jid, sender_nick, body, timestamp) => {
|
||||
println!(
|
||||
debug!(
|
||||
"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,
|
||||
|
||||
let muc : &mut MucRoom = m.get_or_create_mut_muc(&room_jid)
|
||||
.expect("Received direct message with a JID from a MUC");
|
||||
|
||||
muc.messages.push(MucMessage {
|
||||
in_out: MessageInOut::Incoming,
|
||||
sender_nick: Nickname(sender_nick.to_string()),
|
||||
body: body.0,
|
||||
timestamp,
|
||||
})
|
||||
is_private: false,
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
xmpp::Event::RoomPrivateMessage(_id, room_jid, sender_nick, body, timestamp) => {
|
||||
println!(
|
||||
debug!(
|
||||
"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,
|
||||
|
||||
let muc : &mut MucRoom = m.get_or_create_mut_muc(&room_jid)
|
||||
.expect("Received direct message with a JID from a MUC");
|
||||
|
||||
muc.messages.push(MucMessage {
|
||||
in_out: MessageInOut::Incoming,
|
||||
sender_nick: Nickname(sender_nick.to_string()),
|
||||
body: body.0,
|
||||
timestamp,
|
||||
})
|
||||
is_private: true,
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
log::debug!("Received unsupported event {:?}", event);
|
||||
warn!("Received unsupported event {:?}", event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn xmpp_mainloop<'a>(
|
||||
agent: &'a mut Agent,
|
||||
mut room_data: &'a mut UseRef<HashMap<BareJid, Vec<Message>>>,
|
||||
mut room_data: &'a mut UseRef<Messages>,
|
||||
commands: &'a mut UnboundedReceiver<NetworkCommand>,
|
||||
) -> impl Future<Output = ()> + Sized + 'a {
|
||||
async move {
|
||||
@ -203,7 +254,7 @@ async fn await_online(agent: &mut Agent) -> Result<(), String> {
|
||||
|
||||
pub async fn run_xmpp_toplevel(
|
||||
connection_status: UseState<LoginStatus>,
|
||||
mut messages: UseRef<HashMap<BareJid, Vec<Message>>>,
|
||||
mut messages: UseRef<Messages>,
|
||||
mut commands: UnboundedReceiver<NetworkCommand>,
|
||||
) {
|
||||
// Await a login attempt:
|
||||
|
Loading…
Reference in New Issue
Block a user