mod conversation; mod edit_section; pub mod interface; mod navbar; use std::collections::{HashMap, HashSet}; use dioxus::prelude::*; use fermi::*; use matrix_sdk::ruma::OwnedRoomId; use tokio::sync::broadcast::Receiver; use tracing::{debug, error}; use crate::base::{sync_rooms, Room, ROOMS}; use crate::matrix_interface::requester::Receivers; use conversation::Conversation; use navbar::Navbar; use interface::{Interface, Tasks}; turf::style_sheet!("src/components/chats_window/chats_window.scss"); pub struct ChatsWindowProps { pub receivers: Receivers, pub interface: UseAtomRef, } fn render_rooms_tabs<'a>( rooms_atom_ref: &'a UseAtomRef>>, displayed_room_ids_ref: &'a UseRef>, ) -> Vec> { let rooms_ref = rooms_atom_ref.read(); let displayed_room_ids = displayed_room_ids_ref.read(); rooms_ref .values() .filter(|room| displayed_room_ids.contains(&room.borrow().id())) .map(|room| -> LazyNodes { 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() } async fn handle_controls<'a>( receiver_ref: &'a RefCell>, displayed_room_ids_ref: &'a UseRef>, ) { 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_ref.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(cx: Scope) -> Element { debug!("ChatsWindow rendering"); use_init_atom_root(cx); let receivers = &cx.props.receivers; let interface_ref = &cx.props.interface; let rooms_ref = use_atom_ref(cx, &ROOMS); let displayed_room_ids = use_ref(cx, HashSet::::new); let sync_rooms_coro = use_coroutine(cx, |rx| { to_owned![receivers]; sync_rooms(rx, receivers, rooms_ref.clone()) }); sync_rooms_coro.send(true); let _: &Coroutine<()> = use_coroutine(cx, |_: 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_ref, displayed_room_ids); cx.render(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 {}, }, Conversation {}, }, }, }) }