use std::ops::Deref; use filamento::{chat::Chat, roster::{Contact, ContactStoreFields}, user::{User, UserStoreFields}}; use jid::BareJID; use leptos::prelude::*; use reactive_stores::{ArcStore, Store}; use tracing::debug; use crate::{chat::{ArcMacawChat, MacawChat}, client::Client, components::{avatar::AvatarWithPresence, sidebar::Open}, contact::MacawContact, open_chats::{OpenChatsPanel, OpenChatsPanelStoreFields}, state_store::StateStore, user::{fetch_avatar, get_name, ArcMacawUser}}; #[component] pub fn RosterListItem(contact: MacawContact) -> impl IntoView { let name = move || get_name(contact.user.get().into(), false); let open_chats: Store = use_context().expect("no open chats panel store in context"); let client = use_context::().expect("client not in context"); let chat_state_store: StateStore> = use_context().expect("no chat state store"); let user_state_store: StateStore, ArcRwSignal)> = use_context().expect("no user state store"); let open_chat = Action::new_local(move |_| { let client= client.clone(); async move { let to = contact.user.get().jid().get(); let (chat, user) = match client.get_chat_and_user(to).await { Ok(c) => c, Err(e) => { // TODO: error // set_error.set(Some(e.into())); // set_new_chat_pending.set(false); return; }, }; let chat = { // let user = MacawUser::got_user(user); // let user = user_state_store.store(user.jid.clone(), ArcStore::new(user)); let old_user = user_state_store.get_listener(user.jid.clone()); let user = if let Some(old_user) = old_user { old_user.update(|(old_user, _avatar)| { old_user.set(user); }); old_user } else { let avatar = fetch_avatar(user.avatar.as_deref()).await; let avatar = ArcRwSignal::new(avatar); user_state_store.store(user.jid.clone(), (ArcStore::new(user), avatar)) }; let user = ArcMacawUser { user }; let chat = chat_state_store.store(chat.correspondent.clone(), ArcStore::new(chat)); ArcMacawChat { chat, user } }; open_chats.update(|open_chats| open_chats.open(chat.clone())); } }); let current_open_chat: Memo> = use_context().expect("no open chat memo in context"); let open = move || { if let Some(open_chat) = &*current_open_chat.read() { debug!("got open chat: {:?}", open_chat); if *open_chat == *contact.user.get().jid().read() { return Open::Focused; } } if let Some(_backgrounded_chat) = open_chats .chats() .read() .get(contact.user.get().jid().read().deref()) { return Open::Open; } Open::Closed }; let focused = move || open().is_focused(); let open = move || open().is_open(); view! {
{move || { view! { } }}

{name} - {move || contact.user_jid().read().to_string()}

{move || contact.subscription().read().to_string()}
} }