notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

profile.rs (3489B)


      1 use std::collections::HashMap;
      2 
      3 use enostr::{FullKeypair, Pubkey, RelayPool};
      4 use nostrdb::{Ndb, Note, NoteBuildOptions, NoteBuilder, ProfileRecord};
      5 
      6 use tracing::info;
      7 
      8 use crate::{
      9     profile_state::ProfileState,
     10     route::{Route, Router},
     11 };
     12 
     13 pub struct NostrName<'a> {
     14     pub username: Option<&'a str>,
     15     pub display_name: Option<&'a str>,
     16     pub nip05: Option<&'a str>,
     17 }
     18 
     19 impl<'a> NostrName<'a> {
     20     pub fn name(&self) -> &'a str {
     21         if let Some(name) = self.username {
     22             name
     23         } else if let Some(name) = self.display_name {
     24             name
     25         } else {
     26             self.nip05.unwrap_or("??")
     27         }
     28     }
     29 
     30     pub fn unknown() -> Self {
     31         Self {
     32             username: None,
     33             display_name: None,
     34             nip05: None,
     35         }
     36     }
     37 }
     38 
     39 fn is_empty(s: &str) -> bool {
     40     s.chars().all(|c| c.is_whitespace())
     41 }
     42 
     43 pub fn get_display_name<'a>(record: Option<&ProfileRecord<'a>>) -> NostrName<'a> {
     44     if let Some(record) = record {
     45         if let Some(profile) = record.record().profile() {
     46             let display_name = profile.display_name().filter(|n| !is_empty(n));
     47             let username = profile.name().filter(|n| !is_empty(n));
     48             let nip05 = if let Some(raw_nip05) = profile.nip05() {
     49                 if let Some(at_pos) = raw_nip05.find('@') {
     50                     if raw_nip05.starts_with('_') {
     51                         raw_nip05.get(at_pos + 1..)
     52                     } else {
     53                         Some(raw_nip05)
     54                     }
     55                 } else {
     56                     None
     57                 }
     58             } else {
     59                 None
     60             };
     61 
     62             NostrName {
     63                 username,
     64                 display_name,
     65                 nip05,
     66             }
     67         } else {
     68             NostrName::unknown()
     69         }
     70     } else {
     71         NostrName::unknown()
     72     }
     73 }
     74 
     75 pub struct SaveProfileChanges {
     76     pub kp: FullKeypair,
     77     pub state: ProfileState,
     78 }
     79 
     80 impl SaveProfileChanges {
     81     pub fn new(kp: FullKeypair, state: ProfileState) -> Self {
     82         Self { kp, state }
     83     }
     84     pub fn to_note(&self) -> Note {
     85         let sec = &self.kp.secret_key.to_secret_bytes();
     86         add_client_tag(NoteBuilder::new())
     87             .kind(0)
     88             .content(&self.state.to_json())
     89             .options(NoteBuildOptions::default().created_at(true).sign(sec))
     90             .build()
     91             .expect("should build")
     92     }
     93 }
     94 
     95 fn add_client_tag(builder: NoteBuilder<'_>) -> NoteBuilder<'_> {
     96     builder
     97         .start_tag()
     98         .tag_str("client")
     99         .tag_str("Damus Notedeck")
    100 }
    101 
    102 pub enum ProfileAction {
    103     Edit(FullKeypair),
    104     SaveChanges(SaveProfileChanges),
    105 }
    106 
    107 impl ProfileAction {
    108     pub fn process(
    109         &self,
    110         state_map: &mut HashMap<Pubkey, ProfileState>,
    111         ndb: &Ndb,
    112         pool: &mut RelayPool,
    113         router: &mut Router<Route>,
    114     ) {
    115         match self {
    116             ProfileAction::Edit(kp) => {
    117                 router.route_to(Route::EditProfile(kp.pubkey));
    118             }
    119             ProfileAction::SaveChanges(changes) => {
    120                 let raw_msg = format!("[\"EVENT\",{}]", changes.to_note().json().unwrap());
    121 
    122                 let _ = ndb.process_client_event(raw_msg.as_str());
    123                 let _ = state_map.remove_entry(&changes.kp.pubkey);
    124 
    125                 info!("sending {}", raw_msg);
    126                 pool.send(&enostr::ClientMessage::raw(raw_msg));
    127 
    128                 router.go_back();
    129             }
    130         }
    131     }
    132 }