use std::ops::{Deref, DerefMut}; use filamento::user::{User, UserStoreFields}; use jid::BareJID; use reactive_stores::{ArcStore, Store}; use leptos::prelude::*; use crate::{client::Client, roster::{Roster, RosterStoreFields}, state_store::{StateListener, StateStore}}; #[derive(Clone, Copy)] pub struct MacawUser { pub user: ArenaItem, // TODO: just store avatar src in user // pub avatar: String, } impl MacawUser { pub fn get(&self) -> ArcStore { self.try_get_value().unwrap().get() } } impl Deref for MacawUser { type Target = ArenaItem; fn deref(&self) -> &Self::Target { &self.user } } impl DerefMut for MacawUser { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.user } } impl From for MacawUser { fn from(value: ArcMacawUser) -> Self { Self { user: ArenaItem::new_with_storage(value), } } } impl From for ArcMacawUser { fn from(value: MacawUser) -> Self { value.user.try_get_value().unwrap() } } #[derive(Clone)] pub struct ArcMacawUser { pub user: StateListener>, } impl ArcMacawUser { pub fn got_user(user: User) -> Self { let user_state_store: StateStore> = use_context().expect("no user state store"); let user = user_state_store.store(user.jid.clone(), ArcStore::new(user)); Self { user } } } impl Deref for ArcMacawUser { type Target = StateListener>; fn deref(&self) -> &Self::Target { &self.user } } impl DerefMut for ArcMacawUser { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.user } } pub const NO_AVATAR: &str = "/assets/no-avatar.png"; 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() } // 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() } }