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}