diff options
Diffstat (limited to '')
| -rw-r--r-- | src/components/avatar.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/components/avatar.rs b/src/components/avatar.rs new file mode 100644 index 0000000..11d2097 --- /dev/null +++ b/src/components/avatar.rs @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: 2025 cel <cel@bunny.garden> +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +use filamento::{presence::PresenceType, user::User}; +use leptos::prelude::*; +use reactive_stores::Store; + +use crate::{ + components::icon::{IconComponent, show_to_icon}, + icon::Icon, + user::{MacawUser, get_avatar}, + user_presences::UserPresences, +}; + +#[component] +pub fn AvatarWithPresence(user: MacawUser) -> impl IntoView { + let user_presences: Store<UserPresences> = use_context().expect("no user presences in context"); + let presence = move || { + user_presences + .write() + .get_user_presences(&user.get().read().jid) + .read() + .presence() + }; + let show_icon = move || { + presence() + .map(|(_, presence)| match presence.presence { + PresenceType::Online(online) => { + if let Some(show) = online.show { + Some(show_to_icon(show)) + } else { + Some(Icon::Available16Color) + } + } + PresenceType::Offline(offline) => None, + }) + .unwrap_or_default() + }; + + view! { + <div class="avatar-with-presence"> + <img class="avatar" src=move || user.avatar().get() /> + {move || { + if let Some(icon) = show_icon() { + view! { <IconComponent icon=icon class:presence-show-icon=true /> }.into_any() + } else { + view! {}.into_any() + } + }} + </div> + } +} |
