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, } fn render_rooms_tabs( by_id_rooms: &GlobalSignal>>, displayed_room_ids: Signal>, ) -> Vec { 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>>, displayed_room_ids: Signal>, ) -> Vec { 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>, mut displayed_room_ids: Signal>, ) { 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::::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()}, }, }, } }