♻️ Add Room domain entity

This commit is contained in:
2024-04-10 13:39:45 +02:00
parent a7bccfa779
commit c580fba315
8 changed files with 447 additions and 339 deletions

View File

@@ -2,22 +2,19 @@
// In order to use/run the rx.next().await statement you will need to extend the [Stream] trait
// (used by [UnboundedReceiver]) by adding 'futures_util' as a dependency to your project
// and adding the use futures_util::stream::StreamExt;
use futures_util::stream::StreamExt;
use std::cell::RefCell;
use std::{collections::HashMap, sync::Arc};
use dioxus::prelude::*;
use futures_util::stream::StreamExt;
use log::{debug, error, warn};
use matrix_sdk::ruma::OwnedRoomId;
use tokio::select;
use crate::domain::model::room::{ByIdRooms, Room};
use crate::domain::model::session::Session;
use crate::infrastructure::messaging::matrix::client::{Client, RoomEvent};
use crate::infrastructure::messaging::matrix::requester::{Receivers, Requester};
use crate::infrastructure::messaging::matrix::worker_tasks::LoginStyle;
use dioxus::prelude::*;
use matrix_sdk::{
room::{Room as MatrixRoom, RoomMember},
ruma::{OwnedRoomId, OwnedUserId},
};
use tokio::select;
use log::{debug, error, warn};
use crate::domain::model::session::Session;
use crate::ui::components::chats_window::interface::Interface as ChatsWinInterface;
// #[derive(Clone, Debug)]
@@ -41,55 +38,6 @@ use crate::ui::components::chats_window::interface::Interface as ChatsWinInterfa
// }
// }
#[derive(Clone)]
pub struct Room {
pub matrix_room: Arc<MatrixRoom>,
pub topic: Option<RefCell<String>>,
pub members: HashMap<OwnedUserId, RoomMember>,
pub is_direct: Option<bool>,
}
impl Room {
pub fn new(
matrix_room: Arc<MatrixRoom>,
topic: Option<RefCell<String>>,
is_direct: Option<bool>,
) -> Self {
Self {
matrix_room,
topic,
members: HashMap::new(),
is_direct,
}
}
pub async fn from_matrix_room(matrix_room: &MatrixRoom) -> Self {
let room_topic = matrix_room.topic().map(RefCell::new);
Self::new(
Arc::new(matrix_room.to_owned()),
room_topic,
matrix_room.is_direct().await.ok(),
)
}
pub fn name(&self) -> Option<String> {
self.matrix_room.name()
}
pub fn id(&self) -> OwnedRoomId {
OwnedRoomId::from(self.matrix_room.room_id())
}
}
impl PartialEq for Room {
fn eq(&self, other: &Self) -> bool {
// TODO: Look for a better way to compare Matrix rooms
self.matrix_room.room_id() == other.matrix_room.room_id()
}
}
pub type ByIdRooms = HashMap<OwnedRoomId, RefCell<Room>>;
// pub type ByIdUserInfos = HashMap<OwnedUserId, UserInfo>;
// #[derive(Clone)]
@@ -153,10 +101,7 @@ async fn on_joining_invitation(
room: Room,
by_id_rooms: &GlobalSignal<ByIdRooms>,
) {
debug!(
"You're invited to join the \"{}\" room",
room.name().unwrap()
);
debug!("You're invited to join the \"{}\" room", room.id());
// TODO: Update rooms
by_id_rooms
.write()
@@ -166,7 +111,7 @@ async fn on_joining_invitation(
async fn on_room_topic(room_id: OwnedRoomId, topic: String, by_id_rooms: &GlobalSignal<ByIdRooms>) {
if let Some(room) = by_id_rooms.read().get(&room_id) {
let mut room = room.borrow_mut();
room.topic = Some(RefCell::new(topic));
room.set_topic(Some(topic));
} else {
warn!("No room found with the \"{}\" id", room_id);
}
@@ -230,6 +175,7 @@ pub async fn login(
}
Err(err) => {
error!("Error during login: {err}");
// TODO: Handle invalid login
// invalid_login.modify(|_| true);
}
}

View File

@@ -1 +1,2 @@
pub(crate) mod room;
pub(crate) mod session;

145
src/domain/model/room.rs Normal file
View File

@@ -0,0 +1,145 @@
use std::cell::RefCell;
use std::{collections::HashMap, sync::Arc};
use matrix_sdk::ruma::OwnedRoomId;
use matrix_sdk::{Room as MatrixRoom, RoomState as MatrixRoomState};
use tracing::error;
pub(crate) type RoomId = OwnedRoomId;
#[derive(Clone, Debug)]
pub(crate) struct Room {
id: RoomId,
name: Option<String>,
topic: Option<String>,
is_direct: Option<bool>,
state: Option<MatrixRoomState>,
}
impl Room {
fn new(
id: RoomId,
name: Option<String>,
topic: Option<String>,
is_direct: Option<bool>,
state: Option<MatrixRoomState>,
) -> Self {
Self {
id,
name,
topic,
is_direct,
state,
}
}
// TODO: Use a factory instead...
pub async fn from_matrix_room(matrix_room: &MatrixRoom) -> Self {
// let room_topic = matrix_room.topic().map(RefCell::new);
let id = RoomId::from(matrix_room.room_id());
let name = matrix_room.name();
let room_topic = matrix_room.topic();
let is_direct = match matrix_room.is_direct().await {
Ok(is_direct) => Some(is_direct),
Err(err) => {
error!("Unable to know if the room \"{id}\" is direct: {err}");
None
}
};
let state = Some(matrix_room.state());
Self::new(id, name, room_topic, is_direct, state)
// room.timeline.subscribe().await
// Arc::new(matrix_room.to_owned()),
}
pub fn id(&self) -> &OwnedRoomId {
&self.id
}
pub fn name(&self) -> &Option<String> {
&self.name
}
pub fn topic(&self) -> &Option<String> {
&self.topic
}
pub fn set_topic(&mut self, topic: Option<String>) {
self.topic = topic;
}
pub fn is_direct(&self) -> &Option<bool> {
&self.is_direct
}
pub fn state(&self) -> &Option<MatrixRoomState> {
&self.state
}
pub fn is_invited(&self) -> Option<bool> {
match self.state {
Some(state) => Some(state == MatrixRoomState::Invited),
None => None,
}
}
}
pub type ByIdRooms = HashMap<OwnedRoomId, RefCell<Room>>;
// pub type ByIdRooms = HashMap<OwnedRoomId, RefCell<Room>>;
// #[derive(Clone)]
// pub struct Room {
// // pub matrix_room: Arc<MatrixRoom>,
// pub topic: Option<RefCell<String>>,
// pub members: HashMap<OwnedUserId, RoomMember>,
// pub is_direct: Option<bool>,
// // pub timeline: Arc<Timeline>,
// }
// impl Room {
// pub async fn new(
// matrix_room: Arc<MatrixRoom>,
// topic: Option<RefCell<String>>,
// is_direct: Option<bool>,
// ) -> Self {
// // TODO: Filter events
// // let timeline = Arc::new(matrix_room.timeline_builder().build().await.ok().unwrap());
// Self {
// matrix_room,
// topic,
// members: HashMap::new(),
// is_direct,
// // timeline,
// }
// }
// pub async fn from_matrix_room(matrix_room: &MatrixRoom) -> Self {
// let room_topic = matrix_room.topic().map(RefCell::new);
// Self::new(
// Arc::new(matrix_room.to_owned()),
// room_topic,
// matrix_room.is_direct().await.ok(),
// )
// .await
// // room.timeline.subscribe().await
// }
// pub fn name(&self) -> Option<String> {
// self.matrix_room.name()
// }
// pub fn id(&self) -> OwnedRoomId {
// OwnedRoomId::from(self.matrix_room.room_id())
// }
// }
// impl PartialEq for Room {
// fn eq(&self, other: &Self) -> bool {
// // TODO: Look for a better way to compare Matrix rooms
// self.matrix_room.room_id() == other.matrix_room.room_id()
// }
// }

View File

@@ -1,10 +1,15 @@
use std::borrow::Borrow;
use std::cell::RefCell;
use std::sync::Arc;
use std::time::Duration;
use async_std::task;
use dioxus::prelude::Task;
use log::{debug, error};
use tokio::sync::broadcast;
use tokio::sync::broadcast::Sender;
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
use tokio::sync::oneshot;
use tokio::task::JoinHandle;
use matrix_sdk::{
@@ -13,25 +18,11 @@ use matrix_sdk::{
room::Room as MatrixRoom,
ruma::{
events::{
key::verification::{
done::{OriginalSyncKeyVerificationDoneEvent, ToDeviceKeyVerificationDoneEvent},
key::{OriginalSyncKeyVerificationKeyEvent, ToDeviceKeyVerificationKeyEvent},
request::ToDeviceKeyVerificationRequestEvent,
start::{OriginalSyncKeyVerificationStartEvent, ToDeviceKeyVerificationStartEvent},
},
presence::PresenceEvent,
reaction::ReactionEventContent,
room::{
member::{
OriginalSyncRoomMemberEvent, RoomMemberEventContent, StrippedRoomMemberEvent,
},
message::RoomMessageEventContent,
name::RoomNameEventContent,
redaction::OriginalSyncRoomRedactionEvent,
member::{RoomMemberEventContent, StrippedRoomMemberEvent},
topic::RoomTopicEventContent,
},
typing::SyncTypingEvent,
SyncMessageLikeEvent, SyncStateEvent,
SyncStateEvent,
},
OwnedRoomId,
},
@@ -40,7 +31,7 @@ use matrix_sdk::{
use super::requester::{Receivers, Requester};
use super::worker_tasks::{LoginStyle, WorkerTask};
use crate::base::Room;
use crate::domain::model::room::Room;
#[derive(thiserror::Error, Debug)]
pub enum ClientError {
@@ -57,49 +48,58 @@ pub enum RoomEvent {
#[derive(Clone)]
struct Senders {
room_sender: Sender<RoomEvent>,
room_events_sender: Sender<RoomEvent>,
}
impl Senders {
fn new(room_sender: Sender<RoomEvent>) -> Self {
Self { room_sender }
fn new(room_events_sender: Sender<RoomEvent>) -> Self {
Self { room_events_sender }
}
}
pub struct Client {
initialized: bool,
client: Option<Arc<MatrixClient>>,
sync_handle: Option<JoinHandle<()>>,
sync_task: Option<Task>,
senders: Senders,
}
impl Client {
pub fn new(client: Arc<MatrixClient>, room_sender: Sender<RoomEvent>) -> Self {
pub fn new(client: Arc<MatrixClient>, room_events_sender: Sender<RoomEvent>) -> Self {
Self {
initialized: false,
client: Some(client),
sync_handle: None,
senders: Senders::new(room_sender),
sync_task: None,
senders: Senders::new(room_events_sender),
}
}
async fn on_sync_typing_event(_ev: SyncTypingEvent, room: MatrixRoom) {
debug!("== on_sync_typing_event ==");
let room_id = room.room_id().to_owned();
dbg!(room_id);
}
// async fn on_sync_typing_event(_ev: SyncTypingEvent, room: MatrixRoom) {
// debug!("== on_sync_typing_event ==");
// let room_id = room.room_id().to_owned();
// dbg!(room_id);
// }
async fn on_presence_event(_ev: PresenceEvent) {
debug!("== on_presence_event ==");
dbg!(_ev);
}
// async fn on_presence_event(_ev: PresenceEvent) {
// debug!("== on_presence_event ==");
// dbg!(_ev);
// }
async fn on_sync_state_event(ev: SyncStateEvent<RoomNameEventContent>, _room: MatrixRoom) {
error!("== on_sync_state_event ==");
if let SyncStateEvent::Original(ev) = ev {
dbg!(ev);
}
}
// async fn on_sync_state_event(ev: SyncStateEvent<RoomNameEventContent>, _room: MatrixRoom) {
// error!("== on_sync_state_event ==");
// if let SyncStateEvent::Original(ev) = ev {
// dbg!(ev);
// }
// }
// async fn on_original_sync_room_message_event(
// ev: OriginalSyncRoomMessageEvent,
// _matrix_room: MatrixRoom,
// _senders: Ctx<Senders>,
// ) {
// error!("== on_original_sync_room_message_event ==");
// error!("ev={:?}", ev.content);
// }
async fn on_stripped_room_member_event(
ev: StrippedRoomMemberEvent,
@@ -107,13 +107,14 @@ impl Client {
matrix_room: MatrixRoom,
senders: Ctx<Senders>,
) {
if ev.state_key == matrix_client.user_id().unwrap() {
if matrix_room.state() == MatrixRoomState::Invited {
if ev.state_key == matrix_client.user_id().unwrap()
&& matrix_room.state() == MatrixRoomState::Invited
{
let room_id = matrix_room.room_id();
let room = Room::from_matrix_room(&matrix_room).await;
if let Err(err) = senders
.room_sender
.room_events_sender
.send(RoomEvent::InviteEvent(room_id.to_owned(), room))
{
error!(
@@ -123,7 +124,6 @@ impl Client {
}
}
}
}
async fn on_room_topic_event(
ev: SyncStateEvent<RoomTopicEventContent>,
@@ -134,7 +134,7 @@ impl Client {
let room_id = matrix_room.room_id();
if let Err(err) = senders
.room_sender
.room_events_sender
.send(RoomEvent::TopicEvent(room_id.to_owned(), ev.content.topic))
{
error!("Unable to publish the \"{}\" new topic: {}", room_id, err);
@@ -148,12 +148,13 @@ impl Client {
senders: Ctx<Senders>,
) {
if let SyncStateEvent::Original(_ev) = ev {
let room_sender = &senders.room_sender;
let room_id = matrix_room.room_id();
let room = Room::from_matrix_room(&matrix_room).await;
if let Err(err) = room_sender.send(RoomEvent::MemberEvent(room_id.to_owned(), room)) {
if let Err(err) = senders
.room_events_sender
.send(RoomEvent::MemberEvent(room_id.to_owned(), room))
{
error!(
"Unable to publish the new room with \"{}\" id: {}",
room_id, err
@@ -162,37 +163,37 @@ impl Client {
}
}
async fn on_sync_message_like_room_message_event(
ev: SyncMessageLikeEvent<RoomMessageEventContent>,
_room: MatrixRoom,
_client: MatrixClient,
) {
debug!("== on_sync_message_like_room_message_event ==");
dbg!(ev);
}
// async fn on_sync_message_like_room_message_event(
// ev: SyncMessageLikeEvent<RoomMessageEventContent>,
// _room: MatrixRoom,
// _client: MatrixClient,
// ) {
// debug!("== on_sync_message_like_room_message_event ==");
// dbg!(ev);
// }
async fn on_sync_message_like_reaction_event(
ev: SyncMessageLikeEvent<ReactionEventContent>,
_room: MatrixRoom,
) {
debug!("== on_sync_message_like_reaction_event ==");
dbg!(ev);
}
// async fn on_sync_message_like_reaction_event(
// ev: SyncMessageLikeEvent<ReactionEventContent>,
// _room: MatrixRoom,
// ) {
// debug!("== on_sync_message_like_reaction_event ==");
// dbg!(ev);
// }
async fn on_original_sync_room_redaction_event(
ev: OriginalSyncRoomRedactionEvent,
_room: MatrixRoom,
) {
debug!("== on_original_sync_room_redaction_event ==");
dbg!(ev);
}
// async fn on_original_sync_room_redaction_event(
// ev: OriginalSyncRoomRedactionEvent,
// _room: MatrixRoom,
// ) {
// debug!("== on_original_sync_room_redaction_event ==");
// dbg!(ev);
// }
async fn on_original_sync_room_member_event(
_ev: OriginalSyncRoomMemberEvent,
_room: MatrixRoom,
_client: MatrixClient,
) {
debug!("== on_original_sync_room_member_event ==");
// async fn on_original_sync_room_member_event(
// _ev: OriginalSyncRoomMemberEvent,
// _room: MatrixRoom,
// _client: MatrixClient,
// ) {
// debug!("== on_original_sync_room_member_event ==");
// let mut store = store_ctx.read().unwrap().to_owned();
// dbg!(store.rooms.keys());
@@ -202,63 +203,67 @@ impl Client {
// Arc::new(RwLock::new(Room::new(Arc::new(room), None, is_direct))),
// );
// let _ = store_ctx.write(store);
}
// }
async fn on_original_sync_key_verif_start_event(
ev: OriginalSyncKeyVerificationStartEvent,
_client: MatrixClient,
) {
debug!("== on_original_sync_key_verif_start_event ==");
dbg!(ev);
}
// async fn on_original_sync_key_verif_start_event(
// ev: OriginalSyncKeyVerificationStartEvent,
// _client: MatrixClient,
// ) {
// debug!("== on_original_sync_key_verif_start_event ==");
// dbg!(ev);
// }
async fn on_original_sync_key_verif_key_event(
ev: OriginalSyncKeyVerificationKeyEvent,
_client: MatrixClient,
) {
debug!("== on_original_sync_key_verif_key_event ==");
dbg!(ev);
}
// async fn on_original_sync_key_verif_key_event(
// ev: OriginalSyncKeyVerificationKeyEvent,
// _client: MatrixClient,
// ) {
// debug!("== on_original_sync_key_verif_key_event ==");
// dbg!(ev);
// }
async fn on_original_sync_key_verif_done_event(
ev: OriginalSyncKeyVerificationDoneEvent,
_client: MatrixClient,
) {
debug!("== on_original_sync_key_verif_done_event ==");
dbg!(ev);
}
// async fn on_original_sync_key_verif_done_event(
// ev: OriginalSyncKeyVerificationDoneEvent,
// _client: MatrixClient,
// ) {
// debug!("== on_original_sync_key_verif_done_event ==");
// dbg!(ev);
// }
async fn on_device_key_verif_req_event(
ev: ToDeviceKeyVerificationRequestEvent,
_client: MatrixClient,
) {
debug!("== on_device_key_verif_req_event ==");
dbg!(ev);
}
// async fn on_device_key_verif_req_event(
// ev: ToDeviceKeyVerificationRequestEvent,
// _client: MatrixClient,
// ) {
// debug!("== on_device_key_verif_req_event ==");
// dbg!(ev);
// }
async fn on_device_key_verif_start_event(
ev: ToDeviceKeyVerificationStartEvent,
_client: MatrixClient,
) {
debug!("== on_device_key_verif_start_event ==");
dbg!(ev);
}
// async fn on_device_key_verif_start_event(
// ev: ToDeviceKeyVerificationStartEvent,
// _client: MatrixClient,
// ) {
// debug!("== on_device_key_verif_start_event ==");
// dbg!(ev);
// }
async fn on_device_key_verif_key_event(
ev: ToDeviceKeyVerificationKeyEvent,
_client: MatrixClient,
) {
debug!("== on_device_key_verif_key_event ==");
dbg!(ev);
}
// async fn on_device_key_verif_key_event(
// ev: ToDeviceKeyVerificationKeyEvent,
// _client: MatrixClient,
// ) {
// debug!("== on_device_key_verif_key_event ==");
// dbg!(ev);
// }
async fn on_device_key_verif_done_event(
ev: ToDeviceKeyVerificationDoneEvent,
_client: MatrixClient,
) {
debug!("== on_device_key_verif_done_event ==");
dbg!(ev);
}
// async fn on_device_key_verif_done_event(
// ev: ToDeviceKeyVerificationDoneEvent,
// _client: MatrixClient,
// ) {
// debug!("== on_device_key_verif_done_event ==");
// dbg!(ev);
// }
// async fn on_room_event(ev: SomeEvent, _senders: Ctx<Senders>) {
// debug!("== on_room_event({}) ==", ev.)
// }
pub async fn spawn(homeserver_url: String) -> Requester {
let (tx, rx) = unbounded_channel::<WorkerTask>();
@@ -275,10 +280,8 @@ impl Client {
let mut client = Client::new(matrix_client.clone(), room_sender);
tokio::spawn({
async move {
dioxus::prelude::spawn(async move {
client.work(rx).await;
}
});
Requester {
@@ -291,61 +294,33 @@ impl Client {
}
fn init(&mut self) {
let client = self.client.clone().unwrap();
if let Some(client) = self.client.borrow() {
client.add_event_handler_context(self.senders.clone());
let _ = client.add_event_handler(Client::on_sync_typing_event);
let _ = client.add_event_handler(Client::on_presence_event);
let _ = client.add_event_handler(Client::on_sync_state_event);
let _ = client.add_event_handler(Client::on_stripped_room_member_event);
let _ = client.add_event_handler(Client::on_sync_message_like_room_message_event);
let _ = client.add_event_handler(Client::on_sync_message_like_reaction_event);
let _ = client.add_event_handler(Client::on_original_sync_room_redaction_event);
let _ = client.add_event_handler(Client::on_original_sync_room_member_event);
let _ = client.add_event_handler(Client::on_original_sync_key_verif_start_event);
let _ = client.add_event_handler(Client::on_original_sync_key_verif_key_event);
let _ = client.add_event_handler(Client::on_original_sync_key_verif_done_event);
let _ = client.add_event_handler(Client::on_device_key_verif_req_event);
let _ = client.add_event_handler(Client::on_device_key_verif_start_event);
let _ = client.add_event_handler(Client::on_device_key_verif_key_event);
let _ = client.add_event_handler(Client::on_device_key_verif_done_event);
let _ = client.add_event_handler(Client::on_room_topic_event);
let _ = client.add_event_handler(Client::on_room_member_event);
// let _ = client.add_event_handler(Client::on_sync_typing_event);
// let _ = client.add_event_handler(Client::on_presence_event);
// let _ = client.add_event_handler(Client::on_sync_state_event);
// let _ = client.add_event_handler(Client::on_original_sync_room_message_event);
// let _ = client.add_event_handler(Client::on_sync_message_like_room_message_event);
// let _ = client.add_event_handler(Client::on_sync_message_like_reaction_event);
// let _ = client.add_event_handler(Client::on_original_sync_room_redaction_event);
// let _ = client.add_event_handler(Client::on_original_sync_room_member_event);
// let _ = client.add_event_handler(Client::on_original_sync_key_verif_start_event);
// let _ = client.add_event_handler(Client::on_original_sync_key_verif_key_event);
// let _ = client.add_event_handler(Client::on_original_sync_key_verif_done_event);
// let _ = client.add_event_handler(Client::on_device_key_verif_req_event);
// let _ = client.add_event_handler(Client::on_device_key_verif_start_event);
// let _ = client.add_event_handler(Client::on_device_key_verif_key_event);
// let _ = client.add_event_handler(Client::on_device_key_verif_done_event);
self.initialized = true;
}
// async fn refresh_rooms(matrix_client: &MatrixClient, room_sender: &Sender<RoomMemberEvent>) {
// let joined_matrix_rooms_ref = &matrix_client.joined_rooms();
// let invited_matrix_rooms_ref = &matrix_client.invited_rooms();
// for matrix_rooms in [joined_matrix_rooms_ref, invited_matrix_rooms_ref] {
// for matrix_room in matrix_rooms.iter() {
// let topic = matrix_room.topic().map(RefCell::new);
// let room = Room::new(
// Arc::new(matrix_room.to_owned()),
// topic,
// matrix_room.is_direct().await.ok(),
// );
// if let Err(err) = room_sender.send(room) {
// warn!("Error: {}", err);
// }
// }
// }
// }
// async fn refresh_rooms_forever(matrix_client: &MatrixClient, room_channel: &Sender<RoomEvent>) {
// // TODO: Add interval to config
// let mut interval = tokio::time::interval(Duration::from_secs(5));
// loop {
// // Self::refresh_rooms(matrix_client, room_channel).await;
// interval.tick().await;
// }
// }
}
async fn login_and_sync(&mut self, style: LoginStyle) -> anyhow::Result<()> {
let client = self.client.clone().unwrap();
@@ -362,10 +337,9 @@ impl Client {
}
}
// let (synchronized_tx, synchronized_rx) = oneshot::channel();
let (synchronized_tx, synchronized_rx) = oneshot::channel::<bool>();
self.sync_handle = tokio::spawn({
async move {
let task = dioxus::prelude::spawn(async move {
// Sync once so we receive the client state and old messages
let sync_token_option = match client.sync_once(SyncSettings::default()).await {
Ok(sync_response) => Some(sync_response.next_batch),
@@ -380,44 +354,78 @@ impl Client {
debug!("User connected to the homeserver, start syncing");
if let Err(err) = synchronized_tx.send(true) {
error!("Unable to notify that the Matrix client is now synchronized ({err})");
}
let _ = client.sync(settings).await;
}
}
})
.into();
});
self.sync_task = Some(task);
// self.start_background_tasks(synchronized_rx);
Ok(())
}
// async fn register_room_events(&self, room_id: OwnedRoomId) {
// let client = self.client.unwrap();
// client.add_room_event_handler(&room_id, Client::on_room_event);
// }
// async fn refresh_rooms(
// matrix_client: &Arc<MatrixClient>,
// room_events_sender: &Sender<RoomEvent>,
// ) {
// let joined_matrix_rooms_ref = &matrix_client.joined_rooms();
// let invited_matrix_rooms_ref = &matrix_client.invited_rooms();
// for matrix_rooms in [joined_matrix_rooms_ref, invited_matrix_rooms_ref] {
// for matrix_room in matrix_rooms.iter() {
// let room = Room::from_matrix_room(matrix_room).await;
// let event = RoomEvent::MemberEvent(room.id().clone(), room);
// if let Err(err) = room_events_sender.send(event) {
// error!("Error: {}", err);
// }
// }
// }
// }
// async fn refresh_rooms_forever(
// matrix_client: Arc<MatrixClient>,
// room_events_sender: &Sender<RoomEvent>,
// ) {
// // TODO: Add interval to config
// let period_sec = Duration::from_secs(5);
// loop {
// Self::refresh_rooms(&matrix_client, room_events_sender).await;
// task::sleep(period_sec).await;
// }
// }
// fn start_background_tasks(&mut self, synchronized_rx: oneshot::Receiver<bool>) {
// let client = self.client.clone().unwrap();
// let room_sender_ref = &self.senders.room_sender;
// let room_events_sender = self.senders.room_events_sender.clone();
// self.load_handle = tokio::spawn({
// to_owned![room_sender_ref];
// async move {
// let task = dioxus::prelude::spawn(async move {
// if let Err(err) = synchronized_rx.await {
// error!("Unable to setup the rx channel notifying that the Matrix client is now synchronized ({err})");
// }
// let rooms_refresh = Self::refresh_rooms_forever(
// client.as_ref(),
// &room_sender_ref
// );
// let ((),) = tokio::join!(rooms_refresh);
// }
// })
// .into();
// debug!("Start room refreshing forever");
// let _ = Self::refresh_rooms_forever(client, &room_events_sender).await;
// });
// self.background_task = Some(task);
// }
async fn work(&mut self, mut rx: UnboundedReceiver<WorkerTask>) {
loop {
let task = rx.recv().await;
match task {
match rx.recv().await {
Some(task) => self.run(task).await,
None => {
break;
@@ -425,8 +433,8 @@ impl Client {
}
}
if let Some(handle) = self.sync_handle.take() {
handle.abort();
if let Some(task) = self.sync_task.take() {
task.cancel()
}
}
@@ -440,7 +448,10 @@ impl Client {
WorkerTask::Login(style, reply) => {
assert!(self.initialized);
reply.send(self.login_and_sync(style).await).await;
}
} // WorkerTask::registerRoomEvents(room_id, reply) => {
// assert!(self.initialized);
// reply.send(self.register_room_events(room_id).await).await;
// }
}
}
}

View File

@@ -37,8 +37,11 @@ impl Requester {
pub async fn init(&self) -> anyhow::Result<()> {
let (reply, mut response) = oneshot();
// TODO: Handle error case.
self.tx.send(WorkerTask::Init(reply)).unwrap();
if let Err(err) = self.tx.send(WorkerTask::Init(reply)) {
let msg = format!("Unable to request the init of the Matrix client: {err}");
return Err(anyhow::Error::msg(msg));
}
match response.recv().await {
Some(result) => Ok(result),
None => Err(anyhow::Error::msg("TBD")),
@@ -48,8 +51,11 @@ impl Requester {
pub async fn login(&self, style: LoginStyle) -> anyhow::Result<()> {
let (reply, mut response) = oneshot();
// TODO: Handle error case.
self.tx.send(WorkerTask::Login(style, reply)).unwrap();
if let Err(err) = self.tx.send(WorkerTask::Login(style, reply)) {
let msg = format!("Unable to request login to the Matrix client: {err}");
return Err(anyhow::Error::msg(msg));
}
match response.recv().await {
Some(result) => result,
None => Err(anyhow::Error::msg("TBD")),

View File

@@ -12,7 +12,8 @@ use log::{debug, error};
use matrix_sdk::ruma::OwnedRoomId;
use tokio::sync::broadcast::Receiver;
use crate::base::{sync_rooms, Room, ROOMS};
use crate::base::{sync_rooms, ROOMS};
use crate::domain::model::room::Room;
use crate::infrastructure::messaging::matrix::requester::Receivers;
use conversation::Conversation;
use navbar::Navbar;
@@ -35,10 +36,13 @@ fn render_rooms_tabs(
let displayed_room_ids = displayed_room_ids.read();
rooms_ref
.values()
.filter(|room| displayed_room_ids.contains(&room.borrow().id()))
.filter(|room| displayed_room_ids.contains(room.borrow().id()))
.map(|room| {
let room = room.borrow();
let room_name = room.name().unwrap_or(room.id().to_string());
let room_name = match room.name() {
Some(room_name) => room_name.clone(),
None => room.id().to_string(),
};
rsx!(
div {
class: ClassName::TAB,
@@ -62,10 +66,13 @@ fn render_rooms_conversations(
let displayed_room_ids = displayed_room_ids.read();
rooms_ref
.values()
.filter(|room| displayed_room_ids.contains(&room.borrow().id()))
.filter(|room| displayed_room_ids.contains(room.borrow().id()))
.map(|room| {
let room_id = room.borrow().id();
rsx!(Conversation { room_id: room_id },)
let room = room.borrow();
let room_id = room.id();
rsx!(Conversation {
room_id: room_id.clone()
},)
})
.collect()
}

View File

@@ -5,9 +5,9 @@ use dioxus::prelude::*;
use dioxus_free_icons::icons::io_icons::IoChevronDown;
use dioxus_free_icons::Icon;
use log::debug;
use matrix_sdk::{ruma::OwnedRoomId, RoomState};
use crate::base::{ByIdRooms, Room, CHATS_WIN_INTERFACE, ROOMS};
use crate::base::{CHATS_WIN_INTERFACE, ROOMS};
use crate::domain::model::room::{ByIdRooms, Room, RoomId};
use crate::ui::components::chats_window::interface::Interface as ChatsWindowInterface;
turf::style_sheet!("src/ui/components/contacts_window/contacts_section.scss");
@@ -32,7 +32,7 @@ pub(super) fn filter_people_conversations(
let mut filtered_rooms = Vec::<RefCell<Room>>::with_capacity(by_id_rooms.len());
for room in by_id_rooms.values() {
let is_direct = room.borrow().is_direct.unwrap();
let is_direct = room.borrow().is_direct().unwrap();
if !is_direct {
filtered_rooms.push(room.to_owned());
}
@@ -48,7 +48,7 @@ pub(super) fn filter_room_conversations(
let mut filtered_rooms = Vec::<RefCell<Room>>::with_capacity(by_id_rooms.len());
for room in by_id_rooms.values() {
let is_direct = room.borrow().is_direct.unwrap();
let is_direct = room.borrow().is_direct().unwrap();
if is_direct {
filtered_rooms.push(room.to_owned());
}
@@ -57,10 +57,7 @@ pub(super) fn filter_room_conversations(
}
// TODO: Handle errors
fn on_clicked_room(
room_id: &OwnedRoomId,
chats_window_interface: &GlobalSignal<ChatsWindowInterface>,
) {
fn on_clicked_room(room_id: &RoomId, chats_window_interface: &GlobalSignal<ChatsWindowInterface>) {
let _ = chats_window_interface.read().toggle_room(room_id.clone());
}
@@ -89,22 +86,19 @@ pub fn ContactsSection(props: ContactsSectionProps) -> Element {
]
.join(" ");
let rendered_contacts = contacts.into_iter().map(|room_ref| {
let room = room_ref.borrow();
let rendered_contacts = contacts.into_iter().map(|room| {
let room = room.borrow();
let room_topic = room
.topic
.as_ref()
.unwrap_or(&RefCell::new(NO_SUBJECT_REPR.to_string()))
.borrow()
.to_owned();
let room_name = room.name().unwrap_or(NO_NAME_REPR.to_string());
let room_id = room.id();
let is_invited = room.matrix_room.state() == RoomState::Invited;
let topic = room.topic().clone().unwrap_or("".to_string());
let name = match room.name() {
Some(name) => name.clone(),
None => NO_NAME_REPR.to_string(),
};
let id = room.id().clone();
let is_invited = room.is_invited().unwrap_or(false);
let formatted = format!(
"{room_name} - {}",
"{name} - {}",
if is_invited {
"Invited - ".to_string()
} else {
@@ -114,7 +108,7 @@ pub fn ContactsSection(props: ContactsSectionProps) -> Element {
rsx! {
li {
onclick: move |_| on_clicked_room(&room_id, &CHATS_WIN_INTERFACE),
onclick: move |_| on_clicked_room(&id, &CHATS_WIN_INTERFACE),
img {
src: "./images/status_online.png",
},
@@ -123,7 +117,7 @@ pub fn ContactsSection(props: ContactsSectionProps) -> Element {
},
p {
style: "color: darkgrey;",
{room_topic},
{topic},
},
}
}

View File

@@ -654,8 +654,6 @@ pub fn Login() -> Element {
let field_errors = errors.field_errors();
on_validation_errors(&field_errors, &handlers);
}
spinner_animated.set(false);
}
};