🎨 Isolate infra and ui components

The src/base.rs is still to be reworked.
This commit is contained in:
2024-04-04 14:27:58 +02:00
parent 92bf860101
commit 0ce0764204
67 changed files with 64 additions and 59 deletions

View File

@@ -0,0 +1,164 @@
mod conversation;
mod edit_section;
mod navbar;
pub(crate) mod interface;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use dioxus::prelude::*;
use matrix_sdk::ruma::OwnedRoomId;
use tokio::sync::broadcast::Receiver;
use tracing::{debug, error};
use crate::base::{sync_rooms, Room, ROOMS};
use crate::infrastructure::messaging::matrix::requester::Receivers;
use conversation::Conversation;
use navbar::Navbar;
use interface::{Interface, Tasks};
turf::style_sheet!("src/ui/components/chats_window/chats_window.scss");
#[derive(Props, Clone, PartialEq)]
pub struct ChatsWindowProps {
pub receivers: Receivers,
pub interface: Signal<Interface>,
}
fn render_rooms_tabs(
by_id_rooms: &GlobalSignal<HashMap<OwnedRoomId, RefCell<Room>>>,
displayed_room_ids: Signal<HashSet<OwnedRoomId>>,
) -> Vec<Element> {
let rooms_ref = by_id_rooms.read();
let displayed_room_ids = displayed_room_ids.read();
rooms_ref
.values()
.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());
rsx!(
div {
class: ClassName::TAB,
button {
img {
src: "./images/status_online.png",
},
"{room_name}",
},
},
)
})
.collect()
}
fn render_rooms_conversations(
by_id_rooms: &GlobalSignal<HashMap<OwnedRoomId, RefCell<Room>>>,
displayed_room_ids: Signal<HashSet<OwnedRoomId>>,
) -> Vec<Element> {
let rooms_ref = by_id_rooms.read();
let displayed_room_ids = displayed_room_ids.read();
rooms_ref
.values()
.filter(|room| displayed_room_ids.contains(&room.borrow().id()))
.map(|room| {
let room_id = room.borrow().id();
rsx!(Conversation { room_id: room_id },)
})
.collect()
}
async fn handle_controls(
receiver_ref: &RefCell<Receiver<Tasks>>,
mut displayed_room_ids: Signal<HashSet<OwnedRoomId>>,
) {
loop {
let result = receiver_ref.borrow_mut().recv().await;
match result {
Ok(task) => match task {
Tasks::ToggleRoom(room_id) => {
error!("ON TOGGLE ROOM {}", room_id);
let mut displayed_room_ids = displayed_room_ids.write();
match displayed_room_ids.take(&room_id) {
Some(_) => {
error!("{} room already dispayed... close it", room_id);
}
None => {
error!("{} room isn't dispayed... open it", room_id);
displayed_room_ids.insert(room_id);
}
}
}
},
Err(err) => error!("{}", err),
}
}
}
pub fn ChatsWindow(props: ChatsWindowProps) -> Element {
debug!("ChatsWindow rendering");
let receivers = &props.receivers;
let interface_ref = &props.interface;
let displayed_room_ids = use_signal(HashSet::<OwnedRoomId>::new);
let sync_rooms_coro = use_coroutine(|rx| {
to_owned![receivers];
sync_rooms(rx, receivers, &ROOMS)
});
sync_rooms_coro.send(true);
let _: Coroutine<()> = use_coroutine(|_: UnboundedReceiver<_>| {
to_owned![interface_ref, displayed_room_ids];
async move {
let interface = interface_ref.read();
let receiver = &interface.receiver();
handle_controls(receiver, displayed_room_ids).await
}
});
let rendered_rooms_tabs = render_rooms_tabs(&ROOMS, displayed_room_ids);
let rendered_rooms_conversations = render_rooms_conversations(&ROOMS, displayed_room_ids);
rsx! {
style { {STYLE_SHEET} },
div {
class: ClassName::CHATS_WINDOW,
div {
class: ClassName::TABS,
{rendered_rooms_tabs.into_iter()},
},
div {
class: ClassName::CHAT,
div {
class: ClassName::HEADER,
div {
class: ClassName::INFO,
p {
class: ClassName::ROOM_NAME,
"MON POTE",
},
p {
class: ClassName::ROOM_TOPIC,
"LE STATUT A MON POTE",
},
},
Navbar {},
},
{rendered_rooms_conversations.into_iter()},
},
},
}
}