Skip to main content

iris_chat_core/
user_profile.rs

1use crate::{present_person_name, PersonNamePresentation, SocialConnectionSnapshot};
2use std::collections::BTreeMap;
3use std::sync::{Arc, RwLock};
4
5/// Current account's presentation of a person. Metadata stays in the core;
6/// native views select an identity, rather than passing cached names/photos.
7#[derive(uniffi::Record, Clone, Debug, PartialEq, Eq)]
8pub struct UserProfileSnapshot {
9    pub owner_pubkey_hex: String,
10    pub name: PersonNamePresentation,
11    pub picture_url: Option<String>,
12    pub social_connection: Option<SocialConnectionSnapshot>,
13}
14
15impl UserProfileSnapshot {
16    pub(crate) fn unknown(owner: String) -> Self {
17        Self {
18            name: present_person_name(String::new(), owner.clone(), None),
19            owner_pubkey_hex: owner,
20            picture_url: None,
21            social_connection: None,
22        }
23    }
24}
25
26pub(crate) type SharedUserProfiles = Arc<RwLock<BTreeMap<String, UserProfileSnapshot>>>;
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31    #[test]
32    fn ffi_lookup_is_direct_and_normalizes_identity_without_an_actor() {
33        use nostr::ToBech32;
34        let app = crate::ffi_app_failure("No worker".into());
35        let owner = "ab".repeat(32);
36        let mut known = UserProfileSnapshot::unknown(owner.clone());
37        known.name = PersonNamePresentation {
38            name: "Ada".into(),
39            is_fallback: false,
40        };
41        app.shared_user_profiles
42            .write()
43            .unwrap()
44            .insert(owner.clone(), known.clone());
45        let encoded = nostr::PublicKey::from_hex(&owner)
46            .unwrap()
47            .to_bech32()
48            .unwrap();
49        assert_eq!(app.user_profile(encoded), known);
50        assert!(app.user_profile("cd".repeat(32)).name.is_fallback);
51        app.shared_user_profiles.write().unwrap().clear();
52        let after = app.user_profile(owner);
53        assert!(after.name.is_fallback);
54        assert!(after.picture_url.is_none());
55    }
56}