use std::cell::RefCell; use std::rc::Rc; use dioxus::prelude::*; use dioxus_free_icons::icons::io_icons::IoChevronDown; use dioxus_free_icons::Icon; use log::debug; 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"); fn ContactsArrow() -> Element { rsx! { style { {STYLE_SHEET} }, Icon { icon: IoChevronDown, }, } } static NO_NAME_REPR: &str = "No name"; static NO_SUBJECT_REPR: &str = "No subject"; pub(super) fn filter_people_conversations( by_id_rooms: &GlobalSignal, ) -> Vec> { let by_id_rooms = by_id_rooms.read(); let mut filtered_rooms = Vec::>::with_capacity(by_id_rooms.len()); for room in by_id_rooms.values() { let is_direct = room.borrow().is_direct().unwrap(); if !is_direct { filtered_rooms.push(room.to_owned()); } } filtered_rooms } pub(super) fn filter_room_conversations( by_id_rooms: &GlobalSignal, ) -> Vec> { let by_id_rooms = by_id_rooms.read(); let mut filtered_rooms = Vec::>::with_capacity(by_id_rooms.len()); for room in by_id_rooms.values() { let is_direct = room.borrow().is_direct().unwrap(); if is_direct { filtered_rooms.push(room.to_owned()); } } filtered_rooms } // TODO: Handle errors fn on_clicked_room(room_id: &RoomId, chats_window_interface: &GlobalSignal) { let _ = chats_window_interface.read().toggle_room(room_id.clone()); } #[derive(Props, Clone)] pub struct ContactsSectionProps { name: String, filter: Rc) -> Vec>>, } impl PartialEq for ContactsSectionProps { fn eq(&self, other: &Self) -> bool { self.name == other.name && Rc::ptr_eq(&self.filter, &other.filter) } } pub fn ContactsSection(props: ContactsSectionProps) -> Element { debug!("ContactsSection rendering"); let contacts = props.filter.to_owned()(&ROOMS); let contacts_len = contacts.len(); let mut show = use_signal(|| false); let classes = [ ClassName::SECTION, if *show.read() { ClassName::ACTIVE } else { "" }, ] .join(" "); let rendered_contacts = contacts.into_iter().map(|room| { let room = room.borrow(); 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!( "{name} - {}", if is_invited { "Invited - ".to_string() } else { "".to_string() } ); rsx! { li { onclick: move |_| on_clicked_room(&id, &CHATS_WIN_INTERFACE), img { src: "/public/images/status_online.png", }, p { {formatted}, }, p { style: "color: darkgrey;", {topic}, }, } } }); rsx! { style { {STYLE_SHEET} }, div { class: "{classes}", p { class: ClassName::HEADER, onclick: move |_| { let state = *show.read(); show.set(!state) }, ContactsArrow {}, {format!("{} ({contacts_len})", props.name)}, }, ul { {rendered_contacts.into_iter()}, }, }, } }