use std::ops::{Deref, DerefMut}; use filamento::user::{User, UserStoreFields}; use jid::BareJID; use leptos_fetch::QueryClient; use reactive_stores::{ArcStore, Store}; use leptos::prelude::*; use crate::{client::Client, roster::{Roster, RosterStoreFields}}; async fn get_user(jid: BareJID) -> ArcStore { let client: Client = use_context().expect("no client in context"); ArcStore::new(client.get_user(jid).await.unwrap()) } #[derive(Clone)] pub struct MacawUser { pub user: ArcStore, } impl MacawUser { pub fn got_user(user: User) -> Self { // let avatar = fetch_avatar(&user); // user.avatar = avatar; let query_client: QueryClient = expect_context(); let jid = user.jid.clone(); let user_store = query_client.subscribe_value_local(get_user, move || jid.clone()); if let Some(user_store) = user_store.get() { user_store.set(user); Self { user: user_store } } else { let jid = user.jid.clone(); let user_store = ArcStore::new(user); query_client.set_query_local(get_user, jid, user_store.clone()); Self { user: user_store, } } } } impl Deref for MacawUser { type Target = ArcStore; fn deref(&self) -> &Self::Target { &self.user } } impl DerefMut for MacawUser { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.user } } pub const NO_AVATAR: &str = "/assets/no-avatar.png"; pub async fn fetch_avatar(user: &User) -> Option { if let Some(avatar) = &user.avatar { let client = use_context::().expect("client not in context"); client.file_store.get_src(avatar).await } else { None } } pub async fn get_avatar(user: Store) -> String { if let Some(avatar) = &user.read().avatar { let client = use_context::().expect("client not in context"); if let Some(data) = client.file_store.get_src(avatar).await { data } else { NO_AVATAR.to_string() } // avatar.clone() // TODO: enable avatar fetching // format!("/files/{}", avatar) } else { NO_AVATAR.to_string() } } pub fn get_name(user: Store, note_to_self: bool) -> String { let roster: Store = use_context().expect("no roster in context"); if note_to_self { let client: Client = use_context().expect("no client in context"); if *client.jid == *user.jid().read() { return "Note to self".to_string() } } if let Some(name) = roster .contacts() .read() .get(&user.read().jid) .map(|contact| contact.read().name.clone()) .unwrap_or_default() { name.to_string() } else if let Some(nick) = &user.read().nick { nick.to_string() } else { user.read().jid.to_string() } }