🚧 Add an interface to the ChatsWindows to drive its behavior

For now, only the ChatsWindow tabs are toggled on clicks on room names (from ContactsSection).
This commit is contained in:
2023-12-30 23:31:51 +01:00
parent 2fed770f62
commit 116bbcb247
9 changed files with 208 additions and 92 deletions

View File

@@ -1,56 +1,115 @@
pub mod interface;
mod edit_section;
use std::collections::{HashMap, HashSet};
use dioxus::prelude::*;
use fermi::*;
use tracing::debug;
use matrix_sdk::ruma::OwnedRoomId;
use tokio::sync::broadcast::Receiver;
use tracing::{debug, error};
use crate::base::{sync_rooms, ROOMS};
use crate::base::{sync_rooms, Room, ROOMS};
use crate::components::avatar_selector::AvatarSelector;
use crate::components::icons::DownArrowIcon;
use crate::matrix_interface::requester::Receivers;
use edit_section::EditSection;
use interface::{Interface, Tasks};
turf::style_sheet!("src/components/chats_window/chats_window.scss");
pub struct ChatsWindowProps {
pub receivers: Receivers,
pub interface: UseAtomRef<Interface>,
}
fn render_rooms_tabs<'a>(
rooms_atom_ref: &'a UseAtomRef<HashMap<OwnedRoomId, RefCell<Room>>>,
displayed_room_ids_ref: &'a UseRef<HashSet<OwnedRoomId>>,
) -> Vec<LazyNodes<'a, 'a>> {
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<Receiver<Tasks>>,
displayed_room_ids_ref: &'a UseRef<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_ref.write();
match displayed_room_ids.take(&room_id) {
Some(_) => {
error!("Toggle {} already dispayed... close it", room_id);
}
None => {
displayed_room_ids.insert(room_id);
}
}
}
Tasks::Test(msg) => error!("TEST {}", msg),
},
Err(err) => error!("{}", err),
}
}
}
pub fn ChatsWindow(cx: Scope<ChatsWindowProps>) -> Element {
debug!("ChatsWindow rendering");
let receivers = &cx.props.receivers;
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::<OwnedRoomId>::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 rooms = rooms_ref.read();
let rendered_room_tabs = rooms.values().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}",
},
},
)
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 },
@@ -60,7 +119,7 @@ pub fn ChatsWindow(cx: Scope<ChatsWindowProps>) -> Element {
div {
class: ClassName::TABS,
rendered_room_tabs.into_iter(),
rendered_rooms_tabs.into_iter(),
},
div {