Files
galaxy/app/src/workspaces/user_profiles.rs
T

123 lines
3.9 KiB
Rust

use std::collections::HashMap;
use galaxyui::{Entity, SingletonEntity};
use session_sharing_protocol::common::ProfileData;
use crate::auth::UserUid;
pub enum UserProfilesEvent {}
/// Public struct for storing all the UserProfile data that's fed in from either sqlite or the server.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UserProfileWithUID {
pub firebase_uid: UserUid,
pub display_name: Option<String>,
pub email: String,
pub photo_url: String,
}
impl From<ProfileData> for UserProfileWithUID {
fn from(data: ProfileData) -> Self {
Self {
firebase_uid: UserUid::new(&data.firebase_uid),
display_name: Some(data.display_name),
email: data.email.unwrap_or_default(),
photo_url: data.photo_url.unwrap_or_default(),
}
}
}
impl From<crate::persistence::model::UserProfile> for UserProfileWithUID {
fn from(user_profile: crate::persistence::model::UserProfile) -> Self {
UserProfileWithUID {
firebase_uid: UserUid::new(&user_profile.firebase_uid),
display_name: user_profile.display_name,
email: user_profile.email,
photo_url: user_profile.photo_url,
}
}
}
/// Private struct for internal mapping between the user's uid and the important information we might
/// want to query about them.
pub struct UserProfileData {
pub display_name: Option<String>,
pub email: String,
#[allow(dead_code)]
pub photo_url: String,
}
/// UserProfiles is a singleton model storing data on adjacent users (e.g., teammates or former teammates). The
/// purpose of this model is to quickly convert the UID for some user into displayable information about them;
/// for example, their name, email, or profile photo. This allows us to display a richer view into the history
/// of objects and the users who have created, executed, or edited them, etc.
pub struct UserProfiles {
users_by_id: HashMap<UserUid, UserProfileData>,
}
impl UserProfiles {
pub fn new(user_profiles: Vec<UserProfileWithUID>) -> Self {
let mut model = Self {
users_by_id: HashMap::new(),
};
model.insert_profiles(&user_profiles);
model
}
/// Accepts a vector of user profiles and inserts them into the model, overwriting
/// the old version of a profile if it already exists.
pub fn insert_profiles(&mut self, user_profiles: &Vec<UserProfileWithUID>) {
for user_profile in user_profiles {
self.users_by_id.insert(
user_profile.firebase_uid,
UserProfileData {
display_name: user_profile.display_name.clone(),
email: user_profile.email.clone(),
photo_url: user_profile.photo_url.clone(),
},
);
}
}
pub fn clear_profiles(&mut self) {
self.users_by_id.clear()
}
pub fn profile_for_uid(&self, uid: UserUid) -> Option<&UserProfileData> {
self.users_by_id.get(&uid)
}
pub fn displayable_identifier_for_uid(&self, uid: UserUid) -> Option<String> {
self.users_by_id
.get(&uid)
.map(UserProfileData::displayable_identifier)
}
/// Get the display name for the user with the given email address. If the user is unknown,
/// returns `None`.
pub fn displayable_identifier_for_email(&self, email: &str) -> Option<String> {
self.users_by_id
.values()
.find(|profile| profile.email == email)
.map(UserProfileData::displayable_identifier)
}
}
impl UserProfileData {
pub fn displayable_identifier(&self) -> String {
self.display_name
.as_ref()
.filter(|name| !name.is_empty())
.unwrap_or(&self.email)
.clone()
}
}
impl Entity for UserProfiles {
type Event = UserProfilesEvent;
}
impl SingletonEntity for UserProfiles {}