use std::collections::{HashMap, HashSet}; use jid::BareJID; use leptos::prelude::*; use reactive_stores::Store; use crate::components::{ chats_list::ChatsList, personal_status::PersonalStatus, roster_list::RosterList, }; #[derive(PartialEq, Eq, Clone, Copy, Hash)] pub enum SidebarOpen { Roster, Chats, } #[derive(Store)] pub struct Drawer { open: SidebarOpen, hovering: bool, } pub enum Open { /// Currently on screen Focused, /// Open in background somewhere (e.g. in another chat tab) Open, /// Closed Closed, } impl Open { pub fn is_focused(&self) -> bool { match self { Open::Focused => true, Open::Open => false, Open::Closed => false, } } pub fn is_open(&self) -> bool { match self { Open::Focused => true, Open::Open => true, Open::Closed => false, } } } /// returns whether the state was changed to open (true) or closed (false) pub fn toggle_open(state: &mut Option, open: SidebarOpen) -> bool { match state { Some(opened) => { if *opened == open { *state = None; false } else { *state = Some(open); true } } None => { *state = Some(open); true } } } #[component] pub fn Sidebar() -> impl IntoView { let requests: ReadSignal> = use_context().expect("no pending subscriptions in context"); // for what has been clicked open (in the background) let (open, set_open) = signal(None::); // for what is just in the hovered state (not clicked to be pinned open yet necessarily) let open = Memo::new(move |_| open.get()); let (hovered, set_hovered) = signal(None::); let hovered = Memo::new(move |_| hovered.get()); let (just_closed, set_just_closed) = signal(false); let just_closed = Memo::new(move |_| just_closed.get()); let pages = Memo::new(move |_| { let mut pages = HashSet::new(); if let Some(hovered) = *hovered.read() { pages.insert(hovered); } if let Some(opened) = *open.read() { pages.insert(opened); } pages }); view! { } }