Files
beau-gosse-du-92/src/ui/components/contacts_window/contacts_section.rs

150 lines
3.9 KiB
Rust

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<ByIdRooms>,
) -> Vec<RefCell<Room>> {
let by_id_rooms = by_id_rooms.read();
let mut filtered_rooms = Vec::<RefCell<Room>>::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<ByIdRooms>,
) -> Vec<RefCell<Room>> {
let by_id_rooms = by_id_rooms.read();
let mut filtered_rooms = Vec::<RefCell<Room>>::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<ChatsWindowInterface>) {
let _ = chats_window_interface.read().toggle_room(room_id.clone());
}
#[derive(Props, Clone)]
pub struct ContactsSectionProps {
name: String,
filter: Rc<dyn Fn(&GlobalSignal<ByIdRooms>) -> Vec<RefCell<Room>>>,
}
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()},
},
},
}
}