🎨 Isolate infra and ui components
The src/base.rs is still to be reworked.
This commit is contained in:
155
src/ui/components/contacts_window/contacts_section.rs
Normal file
155
src/ui/components/contacts_window/contacts_section.rs
Normal file
@@ -0,0 +1,155 @@
|
||||
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 matrix_sdk::{ruma::OwnedRoomId, RoomState};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::base::{ByIdRooms, Room, CHATS_WIN_INTERFACE, ROOMS};
|
||||
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: &OwnedRoomId,
|
||||
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_ref| {
|
||||
let room = room_ref.borrow();
|
||||
|
||||
let room_topic = room
|
||||
.topic
|
||||
.as_ref()
|
||||
.unwrap_or(&RefCell::new(NO_SUBJECT_REPR.to_string()))
|
||||
.borrow()
|
||||
.to_owned();
|
||||
let room_name = room.name().unwrap_or(NO_NAME_REPR.to_string());
|
||||
let room_id = room.id();
|
||||
|
||||
let is_invited = room.matrix_room.state() == RoomState::Invited;
|
||||
|
||||
let formatted = format!(
|
||||
"{room_name} - {}",
|
||||
if is_invited {
|
||||
"Invited - ".to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
);
|
||||
|
||||
rsx! {
|
||||
li {
|
||||
onclick: move |_| on_clicked_room(&room_id, &CHATS_WIN_INTERFACE),
|
||||
img {
|
||||
src: "./images/status_online.png",
|
||||
},
|
||||
p {
|
||||
{formatted},
|
||||
},
|
||||
p {
|
||||
style: "color: darkgrey;",
|
||||
{room_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()},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user