blob: 50c798901cb24f1b5c1cc9cd1fa24d1b2d9e2d77 (
plain) (
tree)
|
|
use std::collections::HashSet;
use contact_request_manager::AddContact;
use jid::BareJID;
use leptos::prelude::*;
use reactive_stores::Store;
use roster_list_item::RosterListItem;
use crate::{
components::icon::IconComponent,
icon::Icon,
open_chats::{OpenChatsPanel, OpenChatsPanelStoreFields},
roster::{Roster, RosterStoreFields},
};
mod contact_request_manager;
mod roster_list_item;
#[component]
pub fn RosterList() -> impl IntoView {
let requests: ReadSignal<HashSet<BareJID>> =
use_context().expect("no pending subscriptions in context");
let open_chats: Store<OpenChatsPanel> =
use_context().expect("no open chats panel store in context");
let roster: Store<Roster> = use_context().expect("no roster in context");
let (open_add_contact, set_open_add_contact) = signal(false);
let open_chat = Memo::new(move |_| open_chats.chat_view().get());
provide_context(open_chat);
// TODO: filter new messages signal
view! {
<div class="roster-list panel">
<div class="header">
<h2>Roster</h2>
<div class="add-contact header-icon" class:open=open_add_contact>
<IconComponent
icon=Icon::AddContact24
on:click=move |_| set_open_add_contact.update(|state| *state = !*state)
/>
{move || {
if !requests.read().is_empty() {
view! { <div class="badge"></div> }.into_any()
} else {
view! {}.into_any()
}
}}
</div>
</div>
{move || {
if *open_add_contact.read() {
view! {
<div class="roster-add-contact">
<AddContact />
</div>
}
.into_any()
} else {
view! {}.into_any()
}
}}
<div class="roster-list-roster">
<For
each=move || roster.contacts().get()
key=|contact| contact.0.clone()
let(contact)
>
<RosterListItem contact=contact.1 />
</For>
</div>
</div>
}
}
|