tauri_plugin_matrix_svelte/matrix/
user_profile.rs

1use std::sync::Arc;
2
3use crossbeam_queue::SegQueue;
4use matrix_sdk::{
5    room::RoomMember,
6    ruma::{OwnedMxcUri, OwnedRoomId, OwnedUserId},
7};
8
9use super::singletons::{broadcast_event, UIUpdateMessage};
10
11/// The currently-known state of a user's avatar.
12#[derive(Clone, Debug)]
13#[allow(unused)]
14pub enum AvatarState {
15    /// It isn't yet known if this user has an avatar.
16    Unknown,
17    /// It is known that this user does or does not have an avatar.
18    Known(Option<OwnedMxcUri>),
19    /// This user does have an avatar, and it has been fetched successfully.
20    Loaded(Arc<[u8]>),
21    /// This user does have an avatar, but we failed to fetch it.
22    Failed,
23}
24impl AvatarState {
25    /// Returns the avatar data, if in the `Loaded` state.
26    pub fn data(&self) -> Option<&Arc<[u8]>> {
27        if let AvatarState::Loaded(data) = self {
28            Some(data)
29        } else {
30            None
31        }
32    }
33
34    /// Returns the avatar URI, if in the `Known` state and it exists.
35    pub fn uri(&self) -> Option<&OwnedMxcUri> {
36        if let AvatarState::Known(Some(uri)) = self {
37            Some(uri)
38        } else {
39            None
40        }
41    }
42}
43
44/// Information retrieved about a user: their displayable name, ID, and known avatar state.
45#[derive(Clone, Debug)]
46pub struct UserProfile {
47    pub user_id: OwnedUserId,
48    /// The user's default display name, if set.
49    /// Note that a user may have per-room display names,
50    /// so this should be considered a fallback.
51    pub username: Option<String>,
52    pub avatar_state: AvatarState,
53}
54impl UserProfile {
55    /// Returns the user's displayable name, using the user ID as a fallback.
56    pub fn displayable_name(&self) -> &str {
57        if let Some(un) = self.username.as_ref() {
58            if !un.is_empty() {
59                return un.as_str();
60            }
61        }
62        self.user_id.as_str()
63    }
64}
65
66/// The queue of user profile updates waiting to be processed by the UI thread's event handler.
67static PENDING_USER_PROFILE_UPDATES: SegQueue<UserProfileUpdate> = SegQueue::new();
68
69/// Enqueues a new user profile update and signals the UI that an update is available.
70pub fn enqueue_user_profile_update(update: UserProfileUpdate) {
71    PENDING_USER_PROFILE_UPDATES.push(update);
72    broadcast_event(UIUpdateMessage::RefreshUI).expect("Couldn't broadcast event to UI");
73}
74
75/// A user profile update, which can include changes to a user's full profile
76/// and/or room membership info.
77pub enum UserProfileUpdate {
78    /// A fully-fetched user profile, with info about the user's membership in a given room.
79    Full {
80        new_profile: UserProfile,
81        room_id: OwnedRoomId,
82        room_member: RoomMember,
83    },
84    /// An update to the user's room membership info only, without any profile changes.
85    RoomMemberOnly {
86        room_id: OwnedRoomId,
87        room_member: RoomMember,
88    },
89    /// An update to the user's profile only, without changes to room membership info.
90    UserProfileOnly(UserProfile),
91}