From 6b43ae7558eeca2f8a6f34e6805ee39488f535cf Mon Sep 17 00:00:00 2001 From: Mike Dilger Date: Tue, 25 Jul 2023 09:46:56 +1200 Subject: [PATCH] Major rework away from PublicKeyHex towards using PublicKey instead. NOTES: We plan to switch to a different secp256k1 library soon, at which point this PublicKey will become interoperable again, e.g. in gossip-relay-picker --- src/comms.rs | 18 +-- src/feed.rs | 25 ++- src/globals.rs | 10 +- src/nip05.rs | 40 ++--- src/overlord/minion/mod.rs | 40 +++-- src/overlord/mod.rs | 116 +++++++------- src/people.rs | 280 +++++++++++++++------------------- src/process.rs | 41 +++-- src/relay_picker_hooks.rs | 8 +- src/storage/migrations/mod.rs | 3 +- src/storage/mod.rs | 13 +- src/ui/feed/mod.rs | 4 +- src/ui/feed/note/content.rs | 17 ++- src/ui/feed/note/mod.rs | 8 +- src/ui/feed/notedata.rs | 8 +- src/ui/feed/notes.rs | 4 +- src/ui/feed/post.rs | 2 +- src/ui/mod.rs | 67 +++----- src/ui/people/followed.rs | 6 +- src/ui/people/muted.rs | 8 +- src/ui/people/person.rs | 66 ++++---- src/ui/relays/mod.rs | 2 +- src/ui/search.rs | 12 +- src/ui/you/metadata.rs | 4 +- 24 files changed, 367 insertions(+), 435 deletions(-) diff --git a/src/comms.rs b/src/comms.rs index 1b7838b9..2e9a9e8e 100644 --- a/src/comms.rs +++ b/src/comms.rs @@ -1,5 +1,5 @@ use nostr_types::{ - Event, Id, IdHex, Metadata, MilliSatoshi, PublicKey, PublicKeyHex, RelayUrl, Tag, UncheckedUrl, + Event, Id, IdHex, Metadata, MilliSatoshi, PublicKey, RelayUrl, Tag, UncheckedUrl, }; /// This is a message sent to the Overlord @@ -38,14 +38,14 @@ pub enum ToOverlordMessage { RankRelay(RelayUrl, u8), SaveSettings, Search(String), - SetActivePerson(PublicKeyHex), + SetActivePerson(PublicKey), AdjustRelayUsageBit(RelayUrl, u64, bool), - SetThreadFeed(Id, Id, Vec, Option), + SetThreadFeed(Id, Id, Vec, Option), Shutdown, UnlockKey(String), UpdateFollowing(bool), - UpdateMetadata(PublicKeyHex), - UpdateMetadataInBulk(Vec), + UpdateMetadata(PublicKey), + UpdateMetadataInBulk(Vec), VisibleNotesChanged(Vec), ZapStart(Id, PublicKey, UncheckedUrl), Zap(Id, PublicKey, MilliSatoshi, String), @@ -77,12 +77,12 @@ pub enum ToMinionPayloadDetail { Shutdown, SubscribeAugments(Vec), SubscribeConfig, - SubscribeDiscover(Vec), - SubscribeGeneralFeed(Vec), + SubscribeDiscover(Vec), + SubscribeGeneralFeed(Vec), SubscribeMentions, - SubscribePersonFeed(PublicKeyHex), + SubscribePersonFeed(PublicKey), SubscribeThreadFeed(IdHex, Vec), - TempSubscribeMetadata(Vec), + TempSubscribeMetadata(Vec), UnsubscribePersonFeed, UnsubscribeThreadFeed, } diff --git a/src/feed.rs b/src/feed.rs index 5871a958..ab0968ed 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -1,7 +1,7 @@ use crate::comms::{ToMinionMessage, ToMinionPayload, ToMinionPayloadDetail, ToOverlordMessage}; use crate::error::Error; use crate::globals::GLOBALS; -use nostr_types::{EventDelegation, EventKind, Id, PublicKey, PublicKeyHex, RelayUrl, Unixtime}; +use nostr_types::{EventDelegation, EventKind, Id, PublicKey, RelayUrl, Unixtime}; use parking_lot::RwLock; use std::collections::HashSet; use std::sync::atomic::{AtomicBool, Ordering}; @@ -15,9 +15,9 @@ pub enum FeedKind { Thread { id: Id, referenced_by: Id, - author: Option, + author: Option, }, - Person(PublicKeyHex), + Person(PublicKey), } pub struct Feed { @@ -106,12 +106,12 @@ impl Feed { id: Id, referenced_by: Id, relays: Vec, - author: Option, + author: Option, ) { *self.current_feed_kind.write() = FeedKind::Thread { id, referenced_by, - author: author.clone(), + author, }; // Parent starts with the post itself @@ -136,8 +136,8 @@ impl Feed { )); } - pub fn set_feed_to_person(&self, pubkey: PublicKeyHex) { - *self.current_feed_kind.write() = FeedKind::Person(pubkey.clone()); + pub fn set_feed_to_person(&self, pubkey: PublicKey) { + *self.current_feed_kind.write() = FeedKind::Person(pubkey); *self.thread_parent.write() = None; // Recompute as they switch @@ -243,12 +243,7 @@ impl Feed { let current_feed_kind = self.current_feed_kind.read().to_owned(); match current_feed_kind { FeedKind::Followed(with_replies) => { - let mut followed_pubkeys: Vec = GLOBALS - .people - .get_followed_pubkeys() - .iter() - .map(|pk| PublicKey::try_from_hex_string(pk).unwrap()) - .collect(); + let mut followed_pubkeys: Vec = GLOBALS.people.get_followed_pubkeys(); if let Some(pubkey) = GLOBALS.signer.public_key() { followed_pubkeys.push(pubkey); // add the user @@ -371,11 +366,11 @@ impl Feed { if dismissed.contains(&e.id) { return false; } // not dismissed - if e.pubkey.as_hex_string() == person_pubkey.as_str() { + if e.pubkey == person_pubkey { true } else { if let EventDelegation::DelegatedBy(pk) = e.delegation() { - pk.as_hex_string() == person_pubkey.as_str() + pk == person_pubkey } else { false } diff --git a/src/globals.rs b/src/globals.rs index 7372f4b7..386ace73 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -4,7 +4,7 @@ use crate::delegation::Delegation; use crate::feed::Feed; use crate::fetcher::Fetcher; use crate::media::Media; -use crate::people::{Person, People}; +use crate::people::{People, Person}; use crate::relay_picker_hooks::Hooks; use crate::settings::Settings; use crate::signer::Signer; @@ -12,9 +12,7 @@ use crate::status::StatusQueue; use crate::storage::Storage; use dashmap::DashMap; use gossip_relay_picker::RelayPicker; -use nostr_types::{ - Event, Id, PayRequestData, Profile, PublicKey, PublicKeyHex, RelayUrl, UncheckedUrl, -}; +use nostr_types::{Event, Id, PayRequestData, Profile, PublicKey, RelayUrl, UncheckedUrl}; use parking_lot::RwLock as PRwLock; use regex::Regex; use rusqlite::Connection; @@ -83,7 +81,7 @@ pub struct Globals { /// Failed Avatars /// If in this map, the avatar failed to load or process and is unrecoverable /// (but we will take them out and try again if new metadata flows in) - pub failed_avatars: RwLock>, + pub failed_avatars: RwLock>, pub pixels_per_point_times_100: AtomicU32, @@ -108,7 +106,7 @@ pub struct Globals { /// UI note cache invalidation per person // when we update a Person, the UI must recompute all notes by them - pub ui_people_to_invalidate: PRwLock>, + pub ui_people_to_invalidate: PRwLock>, /// Current zap data, for UI pub current_zap: PRwLock, diff --git a/src/nip05.rs b/src/nip05.rs index 982e7ed9..9b602764 100644 --- a/src/nip05.rs +++ b/src/nip05.rs @@ -2,7 +2,7 @@ use crate::db::PersonRelay; use crate::error::{Error, ErrorKind}; use crate::globals::GLOBALS; use crate::people::Person; -use nostr_types::{Metadata, Nip05, PublicKeyHex, RelayUrl, Unixtime}; +use nostr_types::{Metadata, Nip05, PublicKey, RelayUrl, Unixtime}; use std::sync::atomic::Ordering; // This updates the people map and the database with the result @@ -50,13 +50,26 @@ pub async fn validate_nip05(person: Person) -> Result<(), Error> { let mut valid = false; match nip05file.names.get(&user) { Some(pk) => { - if *pk == person.pubkey { - // Validated + if let Ok(pubkey) = PublicKey::try_from_hex_string(pk) { + if pubkey == person.pubkey { + // Validated + GLOBALS + .people + .upsert_nip05_validity( + &person.pubkey, + Some(nip05.clone()), + true, + now.0 as u64, + ) + .await?; + valid = true; + } + } else { + // Failed GLOBALS .people - .upsert_nip05_validity(&person.pubkey, Some(nip05.clone()), true, now.0 as u64) + .upsert_nip05_validity(&person.pubkey, Some(nip05.clone()), false, now.0 as u64) .await?; - valid = true; } } None => { @@ -69,10 +82,7 @@ pub async fn validate_nip05(person: Person) -> Result<(), Error> { } // UI cache invalidation (so notes of the person get rerendered) - GLOBALS - .ui_people_to_invalidate - .write() - .push(person.pubkey.clone()); + GLOBALS.ui_people_to_invalidate.write().push(person.pubkey); if valid { update_relays(nip05, nip05file, &person.pubkey).await?; @@ -90,7 +100,7 @@ pub async fn get_and_follow_nip05(nip05: String) -> Result<(), Error> { // Get their pubkey let pubkey = match nip05file.names.get(&user) { - Some(pk) => pk.to_owned(), + Some(pk) => PublicKey::try_from_hex_string(pk)?, None => return Err((ErrorKind::Nip05KeyNotFound, file!(), line!()).into()), }; @@ -115,13 +125,9 @@ pub async fn get_and_follow_nip05(nip05: String) -> Result<(), Error> { Ok(()) } -async fn update_relays( - nip05: String, - nip05file: Nip05, - pubkey: &PublicKeyHex, -) -> Result<(), Error> { +async fn update_relays(nip05: String, nip05file: Nip05, pubkey: &PublicKey) -> Result<(), Error> { // Set their relays - let relays = match nip05file.relays.get(pubkey) { + let relays = match nip05file.relays.get(&(*pubkey).into()) { Some(relays) => relays, None => return Ok(()), }; @@ -132,7 +138,7 @@ async fn update_relays( // Save person_relay PersonRelay::upsert_last_suggested_nip05( - pubkey.to_owned(), + (*pubkey).into(), relay_url, Unixtime::now().unwrap().0 as u64, ) diff --git a/src/overlord/minion/mod.rs b/src/overlord/minion/mod.rs index 854a48e8..eba02bc8 100644 --- a/src/overlord/minion/mod.rs +++ b/src/overlord/minion/mod.rs @@ -15,8 +15,8 @@ use http::uri::{Parts, Scheme}; use http::Uri; use mime::Mime; use nostr_types::{ - ClientMessage, EventKind, Filter, Id, IdHex, IdHexPrefix, PublicKeyHex, PublicKeyHexPrefix, - RelayInformationDocument, RelayUrl, Unixtime, + ClientMessage, EventKind, Filter, Id, IdHex, IdHexPrefix, PublicKey, PublicKeyHex, + PublicKeyHexPrefix, RelayInformationDocument, RelayUrl, Unixtime, }; use reqwest::Response; use std::borrow::Cow; @@ -347,16 +347,15 @@ impl Minion { ToMinionPayloadDetail::SubscribeDiscover(pubkeys) => { self.subscribe_discover(message.job_id, pubkeys).await?; } - ToMinionPayloadDetail::SubscribePersonFeed(pubkeyhex) => { - self.subscribe_person_feed(message.job_id, pubkeyhex) - .await?; + ToMinionPayloadDetail::SubscribePersonFeed(pubkey) => { + self.subscribe_person_feed(message.job_id, pubkey).await?; } ToMinionPayloadDetail::SubscribeThreadFeed(main, parents) => { self.subscribe_thread_feed(message.job_id, main, parents) .await?; } - ToMinionPayloadDetail::TempSubscribeMetadata(pubkeyhexs) => { - self.temp_subscribe_metadata(message.job_id, pubkeyhexs) + ToMinionPayloadDetail::TempSubscribeMetadata(pubkeys) => { + self.temp_subscribe_metadata(message.job_id, pubkeys) .await?; } ToMinionPayloadDetail::UnsubscribePersonFeed => { @@ -406,7 +405,7 @@ impl Minion { async fn subscribe_general_feed( &mut self, job_id: u64, - followed_pubkeys: Vec, + followed_pubkeys: Vec, ) -> Result<(), Error> { let mut filters: Vec = Vec::new(); let (overlap, feed_chunk) = { @@ -472,7 +471,7 @@ impl Minion { if !followed_pubkeys.is_empty() { let pkp: Vec = followed_pubkeys .iter() - .map(|pk| pk.prefix(16)) // quarter-size + .map(|pk| Into::::into(*pk).prefix(16)) // quarter-size .collect(); // feed related by people followed @@ -493,7 +492,7 @@ impl Minion { .people .get_followed_pubkeys_needing_relay_lists(&followed_pubkeys) .drain(..) - .map(|pk| pk.prefix(16)) // quarter-size + .map(|pk| Into::::into(pk).prefix(16)) // quarter-size .collect(); if !keys_needing_relay_lists.is_empty() { @@ -634,10 +633,13 @@ impl Minion { async fn subscribe_discover( &mut self, job_id: u64, - pubkeys: Vec, + pubkeys: Vec, ) -> Result<(), Error> { if !pubkeys.is_empty() { - let pkp: Vec = pubkeys.iter().map(|pk| pk.prefix(16)).collect(); // quarter-size prefix + let pkp: Vec = pubkeys + .iter() + .map(|pk| Into::::into(*pk).prefix(16)) + .collect(); // quarter-size prefix let filters: Vec = vec![Filter { authors: pkp, @@ -653,11 +655,7 @@ impl Minion { } // Subscribe to the posts a person generates on the relays they write to - async fn subscribe_person_feed( - &mut self, - job_id: u64, - pubkey: PublicKeyHex, - ) -> Result<(), Error> { + async fn subscribe_person_feed(&mut self, job_id: u64, pubkey: PublicKey) -> Result<(), Error> { // NOTE we do not unsubscribe to the general feed // Allow all feed related event kinds @@ -667,7 +665,7 @@ impl Minion { .retain(|f| *f != EventKind::EncryptedDirectMessage && *f != EventKind::Reaction); let filters: Vec = vec![Filter { - authors: vec![pubkey.clone().into()], + authors: vec![Into::::into(pubkey).prefix(16)], kinds: event_kinds, // No since, just a limit on quantity of posts limit: Some(25), @@ -922,12 +920,12 @@ impl Minion { async fn temp_subscribe_metadata( &mut self, job_id: u64, - mut pubkeyhexs: Vec, + mut pubkeys: Vec, ) -> Result<(), Error> { - let pkhp: Vec = pubkeyhexs + let pkhp: Vec = pubkeys .drain(..) .map( - |pk| pk.prefix(16), // quarter-size + |pk| Into::::into(pk).prefix(16), // quarter-size ) .collect(); diff --git a/src/overlord/mod.rs b/src/overlord/mod.rs index f5ca00af..b0d31e0c 100644 --- a/src/overlord/mod.rs +++ b/src/overlord/mod.rs @@ -3,7 +3,7 @@ mod minion; use crate::comms::{ RelayJob, ToMinionMessage, ToMinionPayload, ToMinionPayloadDetail, ToOverlordMessage, }; -use crate::db::{PersonRelay, DbRelay}; +use crate::db::{DbRelay, PersonRelay}; use crate::error::{Error, ErrorKind}; use crate::globals::{ZapState, GLOBALS}; use crate::people::People; @@ -15,9 +15,8 @@ use gossip_relay_picker::{Direction, RelayAssignment}; use http::StatusCode; use minion::Minion; use nostr_types::{ - EncryptedPrivateKey, EventKind, Id, IdHex, Metadata, MilliSatoshi, NostrBech32, - PayRequestData, PreEvent, PrivateKey, Profile, PublicKey, PublicKeyHex, RelayUrl, Tag, - UncheckedUrl, Unixtime, + EncryptedPrivateKey, EventKind, Id, IdHex, Metadata, MilliSatoshi, NostrBech32, PayRequestData, + PreEvent, PrivateKey, Profile, PublicKey, PublicKeyHex, RelayUrl, Tag, UncheckedUrl, Unixtime, }; use std::collections::HashMap; use std::sync::atomic::Ordering; @@ -715,7 +714,7 @@ impl Overlord { } ToOverlordMessage::UpdateMetadata(pubkey) => { let best_relays = - PersonRelay::get_best_relays(pubkey.clone(), Direction::Write).await?; + PersonRelay::get_best_relays(pubkey.into(), Direction::Write).await?; let num_relays_per_person = GLOBALS.settings.read().num_relays_per_person; // we do 1 more than num_relays_per_person, which is really for main posts, @@ -730,9 +729,7 @@ impl Overlord { reason: "tmp-metadata", payload: ToMinionPayload { job_id: rand::random::(), - detail: ToMinionPayloadDetail::TempSubscribeMetadata(vec![ - pubkey.clone() - ]), + detail: ToMinionPayloadDetail::TempSubscribeMetadata(vec![pubkey]), }, persistent: false, }], @@ -746,16 +743,16 @@ impl Overlord { } ToOverlordMessage::UpdateMetadataInBulk(mut pubkeys) => { let num_relays_per_person = GLOBALS.settings.read().num_relays_per_person; - let mut map: HashMap> = HashMap::new(); + let mut map: HashMap> = HashMap::new(); for pubkey in pubkeys.drain(..) { let best_relays = - PersonRelay::get_best_relays(pubkey.clone(), Direction::Write).await?; + PersonRelay::get_best_relays(pubkey.into(), Direction::Write).await?; for (relay_url, _score) in best_relays.iter().take(num_relays_per_person as usize + 1) { map.entry(relay_url.to_owned()) - .and_modify(|entry| entry.push(pubkey.clone())) - .or_insert_with(|| vec![pubkey.clone()]); + .and_modify(|entry| entry.push(pubkey)) + .or_insert_with(|| vec![pubkey]); } } for (relay_url, pubkeys) in map.drain() { @@ -826,14 +823,13 @@ impl Overlord { pubkeystr: String, relay: RelayUrl, ) -> Result<(), Error> { - let pk = match PublicKey::try_from_bech32_string(&pubkeystr) { + let pubkey = match PublicKey::try_from_bech32_string(&pubkeystr) { Ok(pk) => pk, Err(_) => PublicKey::try_from_hex_string(&pubkeystr)?, }; - let pkhex: PublicKeyHex = pk.into(); - GLOBALS.people.async_follow(&pkhex, true).await?; + GLOBALS.people.async_follow(&pubkey, true).await?; - tracing::debug!("Followed {}", &pkhex); + tracing::debug!("Followed {}", &pubkey.as_hex_string()); // Save relay let db_relay = DbRelay::new(relay.clone()); @@ -843,7 +839,7 @@ impl Overlord { // Save person_relay PersonRelay::insert(PersonRelay { - person: pkhex.to_string(), + person: pubkey.as_hex_string(), relay, last_fetched: None, last_suggested_kind3: Some(now), // consider it our claim in our contact list @@ -860,7 +856,7 @@ impl Overlord { // Pick relays to start tracking them now self.pick_relays().await; - tracing::info!("Setup 1 relay for {}", &pkhex); + tracing::info!("Setup 1 relay for {}", &pubkey.as_hex_string()); Ok(()) } @@ -1347,23 +1343,23 @@ impl Overlord { // add own pubkey as well if let Some(pubkey) = GLOBALS.signer.public_key() { - pubkeys.push(pubkey.into()) + pubkeys.push(pubkey) } let num_relays_per_person = GLOBALS.settings.read().num_relays_per_person; - let mut map: HashMap> = HashMap::new(); + let mut map: HashMap> = HashMap::new(); // Sort the people into the relays we will find their metadata at for pubkey in &pubkeys { - for relayscore in PersonRelay::get_best_relays(pubkey.to_owned(), Direction::Write) + for relayscore in PersonRelay::get_best_relays((*pubkey).into(), Direction::Write) .await? .drain(..) .take(num_relays_per_person as usize) { map.entry(relayscore.0) - .and_modify(|e| e.push(pubkey.to_owned())) - .or_insert_with(|| vec![pubkey.to_owned()]); + .and_modify(|e| e.push(*pubkey)) + .or_insert_with(|| vec![*pubkey]); } } @@ -1503,7 +1499,7 @@ impl Overlord { id: Id, referenced_by: Id, mut relays: Vec, - author: Option, + author: Option, ) -> Result<(), Error> { // We are responsible for loading all the ancestors and all the replies, and // process.rs is responsible for building the relationships. @@ -1522,19 +1518,25 @@ impl Overlord { // Include the relays where the referenced_by event was seen relays.extend( - GLOBALS.storage.get_event_seen_on_relay(referenced_by)? + GLOBALS + .storage + .get_event_seen_on_relay(referenced_by)? .drain(..) - .map(|(url, _time)| url)); + .map(|(url, _time)| url), + ); relays.extend( - GLOBALS.storage.get_event_seen_on_relay(id)? + GLOBALS + .storage + .get_event_seen_on_relay(id)? .drain(..) - .map(|(url, _time)| url)); + .map(|(url, _time)| url), + ); // If we have less than 2 relays, include the write relays of the author if relays.len() < 2 { - if let Some(pkh) = author { + if let Some(pk) = author { let author_relays: Vec = - PersonRelay::get_best_relays(pkh, Direction::Write) + PersonRelay::get_best_relays(pk.into(), Direction::Write) .await? .drain(..) .map(|pair| pair.0) @@ -1626,8 +1628,7 @@ impl Overlord { } async fn follow_nprofile(&mut self, nprofile: Profile) -> Result<(), Error> { - let pubkey = nprofile.pubkey.into(); - GLOBALS.people.async_follow(&pubkey, true).await?; + GLOBALS.people.async_follow(&nprofile.pubkey, true).await?; // Set their relays for relay in nprofile.relays.iter() { @@ -1638,7 +1639,7 @@ impl Overlord { // Save person_relay PersonRelay::upsert_last_suggested_nip05( - pubkey.to_owned(), + nprofile.pubkey.into(), relay_url, Unixtime::now().unwrap().0 as u64, ) @@ -1756,7 +1757,7 @@ impl Overlord { } }; - let mut pubkeys: Vec = Vec::new(); + let mut pubkeys: Vec = Vec::new(); let now = Unixtime::now().unwrap(); @@ -1768,33 +1769,34 @@ impl Overlord { .. } = tag { - // Make sure we have that person - GLOBALS - .people - .create_all_if_missing(&[pubkey.to_owned()]) - .await?; + if let Ok(pubkey) = PublicKey::try_from_hex_string(pubkey) { + // Make sure we have that person + GLOBALS + .people + .create_all_if_missing(&[pubkey.to_owned()]) + .await?; - // Save the pubkey for actual following them (outside of the loop in a batch) - pubkeys.push(pubkey.to_owned()); + // Save the pubkey for actual following them (outside of the loop in a batch) + pubkeys.push(pubkey.to_owned()); - // If there is a URL - if let Some(url) = recommended_relay_url - .as_ref() - .and_then(|rru| RelayUrl::try_from_unchecked_url(rru).ok()) - { - // Save relay if missing - GLOBALS.storage.write_relay_if_missing(&url)?; + // If there is a URL + if let Some(url) = recommended_relay_url + .as_ref() + .and_then(|rru| RelayUrl::try_from_unchecked_url(rru).ok()) + { + // Save relay if missing + GLOBALS.storage.write_relay_if_missing(&url)?; - // create or update person_relay last_suggested_kind3 - PersonRelay::upsert_last_suggested_kind3( - pubkey.to_string(), - url, - now.0 as u64, - ) - .await?; + // create or update person_relay last_suggested_kind3 + PersonRelay::upsert_last_suggested_kind3( + pubkey.as_hex_string(), + url, + now.0 as u64, + ) + .await?; + } + // TBD: do something with the petname } - - // TBD: do something with the petname } } diff --git a/src/people.rs b/src/people.rs index 3c5d9411..7f6e477b 100644 --- a/src/people.rs +++ b/src/people.rs @@ -20,7 +20,7 @@ use tokio::task; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Person { - pub pubkey: PublicKeyHex, + pub pubkey: PublicKey, pub petname: Option, pub followed: u8, pub followed_last_updated: i64, @@ -36,7 +36,7 @@ pub struct Person { } impl Person { - pub fn new(pubkey: PublicKeyHex) -> Person { + pub fn new(pubkey: PublicKey) -> Person { Person { pubkey, petname: None, @@ -103,30 +103,30 @@ impl Person { } pub struct People { - people: DashMap, + people: DashMap, // active person's relays (pull from db as needed) - active_person: RwLock>, + active_person: RwLock>, active_persons_write_relays: RwLock>, // We fetch (with Fetcher), process, and temporarily hold avatars // until the UI next asks for them, at which point we remove them // and hand them over. This way we can do the work that takes // longer and the UI can do as little work as possible. - avatars_temp: DashMap, - avatars_pending_processing: DashSet, + avatars_temp: DashMap, + avatars_pending_processing: DashSet, // When we manually ask for updating metadata, we want to recheck // the person's NIP-05 when that metadata come in. We remember this here. - recheck_nip05: DashSet, + recheck_nip05: DashSet, // People that need metadata, which the UI has asked for. These people // might simply not be loaded from the database yet. - need_metadata: DashSet, + need_metadata: DashSet, // People who we already tried to get their metadata. We only try once // per gossip run (this set only grows) - tried_metadata: DashSet, + tried_metadata: DashSet, // Date of the last self-owned contact list we have an event for pub last_contact_list_asof: AtomicI64, @@ -173,25 +173,25 @@ impl People { }); } - pub fn get_followed_pubkeys(&self) -> Vec { - let mut output: Vec = Vec::new(); + pub fn get_followed_pubkeys(&self) -> Vec { + let mut output: Vec = Vec::new(); for person in self .people .iter() .filter_map(|p| if p.followed == 1 { Some(p) } else { None }) { - output.push(person.pubkey.clone()); + output.push(person.pubkey); } output } pub fn get_followed_pubkeys_needing_relay_lists( &self, - among_these: &[PublicKeyHex], - ) -> Vec { + among_these: &[PublicKey], + ) -> Vec { // FIXME make this a setting (8 hours) let one_day_ago = Unixtime::now().unwrap().0 - (60 * 60 * 8); - let mut output: Vec = Vec::new(); + let mut output: Vec = Vec::new(); for person in self.people.iter().filter_map(|p| { if p.followed == 1 && p.relay_list_last_received < one_day_ago @@ -202,22 +202,22 @@ impl People { None } }) { - output.push(person.pubkey.clone()); + output.push(person.pubkey); } output } - pub fn create_if_missing_sync(&self, pubkey: PublicKeyHex) { - task::spawn(async { + pub fn create_if_missing_sync(&self, pubkey: PublicKey) { + task::spawn(async move { if let Err(e) = GLOBALS.people.create_all_if_missing(&[pubkey]).await { tracing::error!("{}", e); } }); } - pub async fn create_all_if_missing(&self, pubkeys: &[PublicKeyHex]) -> Result<(), Error> { + pub async fn create_all_if_missing(&self, pubkeys: &[PublicKey]) -> Result<(), Error> { // Collect the public keys that we don't have already (by checking in memory). - let pubkeys: Vec<&PublicKeyHex> = pubkeys + let pubkeys: Vec<&PublicKey> = pubkeys .iter() .filter(|pk| !self.people.contains_key(pk)) .collect(); @@ -231,7 +231,7 @@ impl People { sql.push_str(&"(?),".repeat(pubkeys.len())); sql.pop(); // remove trailing comma - let pubkey_strings: Vec = pubkeys.iter().map(|p| p.to_string()).collect(); + let pubkey_strings: Vec = pubkeys.iter().map(|p| p.as_hex_string()).collect(); task::spawn_blocking(move || { let db = GLOBALS.db.blocking_lock(); @@ -249,9 +249,7 @@ impl People { // Now load them from the database (some of them may have had records already) let mut loaded_people = Self::fetch_many(&pubkeys).await?; for loaded_person in loaded_people.drain(..) { - let _ = self - .people - .insert(loaded_person.pubkey.clone(), loaded_person); + let _ = self.people.insert(loaded_person.pubkey, loaded_person); } Ok(()) @@ -259,23 +257,23 @@ impl People { // If this person doesn't have metadata, and we are automatically fetching // metadata, then add this person to the list of people that need metadata. - pub fn person_of_interest(&self, pubkeyhex: PublicKeyHex) { + pub fn person_of_interest(&self, pubkey: PublicKey) { // Don't get metadata if disabled if !GLOBALS.settings.read().automatically_fetch_metadata { return; } // Don't try over and over. We try just once per gossip run. - if self.tried_metadata.contains(&pubkeyhex) { + if self.tried_metadata.contains(&pubkey) { return; } - match self.people.get(&pubkeyhex) { + match self.people.get(&pubkey) { Some(person) => { // If we haven't loaded the person from the database yet if !person.loaded { // Trigger a future load - self.create_if_missing_sync(pubkeyhex.clone()); + self.create_if_missing_sync(pubkey); // Don't load metadata now, we may have it on disk and get // it from the future load. @@ -296,13 +294,13 @@ impl People { // Record that we need it. // the periodic task will take care of it. - if !self.need_metadata.contains(&pubkeyhex) { - self.need_metadata.insert(pubkeyhex.clone()); + if !self.need_metadata.contains(&pubkey) { + self.need_metadata.insert(pubkey); } } None => { // Trigger a future create and load - self.create_if_missing_sync(pubkeyhex.clone()); + self.create_if_missing_sync(pubkey); // Don't load metadata now, we may have it on disk and get // it from the future load. @@ -313,10 +311,10 @@ impl People { // This is run periodically. It checks the database first, only then does it // ask the overlord to update the metadata from the relays. async fn maybe_fetch_metadata(&self) { - let mut verified_need: Vec = Vec::new(); + let mut verified_need: Vec = Vec::new(); // Take from self.need_metadata; - let mut need_metadata: Vec = self + let mut need_metadata: Vec = self .need_metadata .iter() .map(|refmulti| refmulti.key().to_owned()) @@ -330,8 +328,8 @@ impl People { for pubkey in need_metadata.drain(..) { if let Some(person) = self.people.get(&pubkey) { if person.loaded { - tracing::debug!("Seeking metadata for {}", &pubkey); - verified_need.push(pubkey.clone()); + tracing::debug!("Seeking metadata for {}", pubkey.as_hex_string()); + verified_need.push(pubkey); self.tried_metadata.insert(pubkey); } } @@ -342,30 +340,30 @@ impl People { .send(ToOverlordMessage::UpdateMetadataInBulk(verified_need)); } - pub fn recheck_nip05_on_update_metadata(&self, pubkeyhex: &PublicKeyHex) { - self.recheck_nip05.insert(pubkeyhex.to_owned()); + pub fn recheck_nip05_on_update_metadata(&self, pubkey: &PublicKey) { + self.recheck_nip05.insert(pubkey.to_owned()); } pub async fn update_metadata( &self, - pubkeyhex: &PublicKeyHex, + pubkey: &PublicKey, metadata: Metadata, asof: Unixtime, ) -> Result<(), Error> { // Sync in from database first - self.create_all_if_missing(&[pubkeyhex.to_owned()]).await?; + self.create_all_if_missing(&[*pubkey]).await?; let now = Unixtime::now().unwrap(); // Update metadata_last_received, even if we don't update the metadata { // Update in memory - if let Some(mut person) = self.people.get_mut(pubkeyhex) { + if let Some(mut person) = self.people.get_mut(pubkey) { person.metadata_last_received = now.0; } // Update in database - let pkh = pubkeyhex.as_str().to_owned(); + let pkh: String = pubkey.as_hex_string(); task::spawn_blocking(move || { let db = GLOBALS.db.blocking_lock(); let mut stmt = @@ -377,10 +375,10 @@ impl People { } // Copy the person - let mut person = self.people.get(pubkeyhex).unwrap().to_owned(); + let mut person = self.people.get(pubkey).unwrap().to_owned(); // Remove from the list of people that need metadata - self.need_metadata.remove(pubkeyhex); + self.need_metadata.remove(pubkey); // Determine whether it is fresh let fresh = match person.metadata_created_at { @@ -397,7 +395,7 @@ impl People { // Update person in the map, and the local variable person = { - let mut person_mut = self.people.get_mut(pubkeyhex).unwrap(); + let mut person_mut = self.people.get_mut(pubkey).unwrap(); person_mut.metadata = Some(metadata); person_mut.metadata_created_at = Some(asof.0); if nip05_changed { @@ -408,7 +406,7 @@ impl People { }; // Update the database - let pubkeyhex2 = pubkeyhex.to_owned(); + let pubkeyhex2: PublicKeyHex = (*pubkey).into(); let person_inner = person.clone(); task::spawn_blocking(move || { let db = GLOBALS.db.blocking_lock(); @@ -434,14 +432,11 @@ impl People { .await??; // UI cache invalidation (so notes of the person get rerendered) - GLOBALS - .ui_people_to_invalidate - .write() - .push(pubkeyhex.to_owned()); + GLOBALS.ui_people_to_invalidate.write().push(*pubkey); } // Remove from failed avatars list so the UI will try to fetch the avatar again if missing - GLOBALS.failed_avatars.write().await.remove(pubkeyhex); + GLOBALS.failed_avatars.write().await.remove(pubkey); // Only if they have a nip05 dns id set if matches!( @@ -454,8 +449,8 @@ impl People { // Recheck nip05 every day if invalid, and every two weeks if valid let recheck = { - if self.recheck_nip05.contains(pubkeyhex) { - self.recheck_nip05.remove(pubkeyhex); + if self.recheck_nip05.contains(pubkey) { + self.recheck_nip05.remove(pubkey); true } else if let Some(last) = person.nip05_last_checked { // FIXME make these settings @@ -471,8 +466,7 @@ impl People { }; if recheck { - self.update_nip05_last_checked(person.pubkey.clone()) - .await?; + self.update_nip05_last_checked(person.pubkey).await?; task::spawn(async move { if let Err(e) = crate::nip05::validate_nip05(person).await { tracing::error!("{}", e); @@ -521,7 +515,7 @@ impl People { }; let pk: String = row.get(0)?; output.push(Person { - pubkey: PublicKeyHex::try_from_string(pk)?, + pubkey: PublicKey::try_from_hex_string(&pk)?, petname: row.get(1)?, followed: row.get(2)?, followed_last_updated: row.get(3)?, @@ -541,25 +535,25 @@ impl People { .await?; for person in output? { - self.people.insert(person.pubkey.clone(), person); + self.people.insert(person.pubkey, person); } Ok(()) } // Get from our memory map. If missing, eventually load from the database - pub fn get(&self, pubkeyhex: &PublicKeyHex) -> Option { - if self.people.contains_key(pubkeyhex) { - self.people.get(pubkeyhex).map(|o| o.value().to_owned()) + pub fn get(&self, pubkey: &PublicKey) -> Option { + if self.people.contains_key(pubkey) { + self.people.get(pubkey).map(|o| o.value().to_owned()) } else { // We can't get it now, but we can setup a task to do it soon - let pubkeyhex = pubkeyhex.to_owned(); + let pubkey = pubkey.to_owned(); tokio::spawn(async move { #[allow(clippy::map_entry)] - if !GLOBALS.people.people.contains_key(&pubkeyhex) { - match People::fetch_one(&pubkeyhex).await { + if !GLOBALS.people.people.contains_key(&pubkey) { + match People::fetch_one(&pubkey).await { Ok(Some(person)) => { - let _ = GLOBALS.people.people.insert(pubkeyhex, person); + let _ = GLOBALS.people.people.insert(pubkey, person); } Err(e) => tracing::error!("{}", e), _ => {} @@ -578,7 +572,7 @@ impl People { .map(|s| s.to_lowercase()) .cmp(&b.display_name().map(|s| s.to_lowercase())); if c == std::cmp::Ordering::Equal { - a.pubkey.cmp(&b.pubkey) + a.pubkey.as_hex_string().cmp(&b.pubkey.as_hex_string()) } else { c } @@ -586,19 +580,19 @@ impl People { v } - pub fn get_avatar(&self, pubkeyhex: &PublicKeyHex) -> Option { + pub fn get_avatar(&self, pubkey: &PublicKey) -> Option { // If we have it, hand it over (we won't need a copy anymore) - if let Some(th) = self.avatars_temp.remove(pubkeyhex) { + if let Some(th) = self.avatars_temp.remove(pubkey) { return Some(th.1); } // If it failed before, error out now - if GLOBALS.failed_avatars.blocking_read().contains(pubkeyhex) { + if GLOBALS.failed_avatars.blocking_read().contains(pubkey) { return None; // cannot recover. } // If it is pending processing, respond now - if self.avatars_pending_processing.contains(pubkeyhex) { + if self.avatars_pending_processing.contains(pubkey) { return None; // will recover after processing completes } @@ -608,7 +602,7 @@ impl People { } // Get the person this is about - let person = match self.people.get(pubkeyhex) { + let person = match self.people.get(pubkey) { Some(person) => person, None => { return None; // can recover once the person is loaded @@ -618,10 +612,7 @@ impl People { // Fail permanently if they don't have a picture url if person.picture().is_none() { // this cannot recover without new metadata - GLOBALS - .failed_avatars - .blocking_write() - .insert(pubkeyhex.to_owned()); + GLOBALS.failed_avatars.blocking_write().insert(*pubkey); return None; } @@ -632,10 +623,7 @@ impl People { Ok(url) => url, Err(_) => { // this cannot recover without new metadata - GLOBALS - .failed_avatars - .blocking_write() - .insert(pubkeyhex.to_owned()); + GLOBALS.failed_avatars.blocking_write().insert(*pubkey); return None; } @@ -649,7 +637,7 @@ impl People { Ok(None) => None, Ok(Some(bytes)) => { // Finish this later (spawn) - let apubkeyhex = pubkeyhex.to_owned(); + let apubkey = *pubkey; tokio::spawn(async move { let size = AVATAR_SIZE * 3 // 3x feed size, 1x people page size * GLOBALS @@ -691,7 +679,7 @@ impl People { if GLOBALS.settings.read().theme.round_image() { round_image(&mut color_image); } - GLOBALS.people.avatars_temp.insert(apubkeyhex, color_image); + GLOBALS.people.avatars_temp.insert(apubkey, color_image); } else if let Ok(mut color_image) = egui_extras::image::load_svg_bytes_with_size( &bytes, FitTo::Size(size, size), @@ -699,26 +687,19 @@ impl People { if GLOBALS.settings.read().theme.round_image() { round_image(&mut color_image); } - GLOBALS.people.avatars_temp.insert(apubkeyhex, color_image); + GLOBALS.people.avatars_temp.insert(apubkey, color_image); } else { // this cannot recover without new metadata - GLOBALS - .failed_avatars - .write() - .await - .insert(apubkeyhex.to_owned()); + GLOBALS.failed_avatars.write().await.insert(apubkey); }; }); - self.avatars_pending_processing.insert(pubkeyhex.to_owned()); + self.avatars_pending_processing.insert(pubkey.to_owned()); None } Err(e) => { tracing::error!("{}", e); // this cannot recover without new metadata - GLOBALS - .failed_avatars - .blocking_write() - .insert(pubkeyhex.to_owned()); + GLOBALS.failed_avatars.blocking_write().insert(*pubkey); None } } @@ -735,7 +716,7 @@ impl People { let search = String::from(text).to_lowercase(); // grab all results then sort by score - let mut results: Vec<(u16, String, PublicKeyHex)> = self + let mut results: Vec<(u16, String, PublicKey)> = self .people .iter() .filter_map(|person| { @@ -773,13 +754,13 @@ impl People { // if there is not a name, fallback to showing the initial chars of the pubkey, // but this is probably unnecessary and will never happen if result_name.is_empty() { - result_name = person.pubkey.to_string(); + result_name = person.pubkey.as_hex_string(); } // bigger names have a higher match chance, but they should be scored lower score -= result_name.len() as u16; - return Some((score, result_name, person.pubkey.clone())); + return Some((score, result_name, person.pubkey)); } None @@ -794,12 +775,7 @@ impl People { }; results[0..max] .iter() - .map(|r| { - ( - r.1.to_owned(), - PublicKey::try_from_hex_string(&r.2).unwrap(), - ) - }) + .map(|r| (r.1.to_owned(), r.2.to_owned())) .collect() } @@ -823,10 +799,10 @@ impl People { let pubkeys = self.get_followed_pubkeys(); for pubkey in &pubkeys { // Get their best relay - let relays = PersonRelay::get_best_relays(pubkey.clone(), Direction::Write).await?; + let relays = PersonRelay::get_best_relays((*pubkey).into(), Direction::Write).await?; let maybeurl = relays.get(0); p_tags.push(Tag::Pubkey { - pubkey: pubkey.clone(), + pubkey: (*pubkey).into(), recommended_relay_url: maybeurl.map(|(u, _)| u.to_unchecked_url()), petname: None, trailing: Vec::new(), @@ -862,19 +838,19 @@ impl People { GLOBALS.signer.sign_preevent(pre_event, None, None) } - pub fn follow(&self, pubkeyhex: &PublicKeyHex, follow: bool) { + pub fn follow(&self, pubkey: &PublicKey, follow: bool) { // We can't do it now, but we spawn a task to do it soon - let pubkeyhex = pubkeyhex.to_owned(); + let pubkey = pubkey.to_owned(); tokio::spawn(async move { - if let Err(e) = GLOBALS.people.async_follow(&pubkeyhex, follow).await { + if let Err(e) = GLOBALS.people.async_follow(&pubkey, follow).await { tracing::error!("{}", e); } }); } - pub async fn async_follow(&self, pubkeyhex: &PublicKeyHex, follow: bool) -> Result<(), Error> { + pub async fn async_follow(&self, pubkey: &PublicKey, follow: bool) -> Result<(), Error> { // Skip if they are already followed (or already not followed) - let already_followed = self.get_followed_pubkeys().contains(pubkeyhex); + let already_followed = self.get_followed_pubkeys().contains(pubkey); if follow == already_followed { return Ok(()); } @@ -884,22 +860,22 @@ impl People { // Follow in database let sql = "INSERT INTO PERSON (pubkey, followed) values (?, ?) \ ON CONFLICT(pubkey) DO UPDATE SET followed=?"; - let pubkeyhex2 = pubkeyhex.to_owned(); + let pubkeyhexstr = pubkey.as_hex_string(); task::spawn_blocking(move || { let db = GLOBALS.db.blocking_lock(); let mut stmt = db.prepare(sql)?; - stmt.execute((pubkeyhex2.as_str(), &follow, &follow))?; + stmt.execute((pubkeyhexstr, &follow, &follow))?; Ok::<(), Error>(()) }) .await??; // Make sure memory matches - if let Some(mut dbperson) = self.people.get_mut(pubkeyhex) { + if let Some(mut dbperson) = self.people.get_mut(pubkey) { dbperson.followed = follow; } else { // load - if let Some(person) = Self::fetch_one(pubkeyhex).await? { - self.people.insert(pubkeyhex.to_owned(), person); + if let Some(person) = Self::fetch_one(pubkey).await? { + self.people.insert(pubkey.to_owned(), person); } } @@ -907,13 +883,13 @@ impl People { GLOBALS .ui_people_to_invalidate .write() - .push(pubkeyhex.to_owned()); + .push(pubkey.to_owned()); if follow > 0 { // Add the person to the relay_picker for picking - GLOBALS.relay_picker.add_someone(pubkeyhex.to_owned())?; + GLOBALS.relay_picker.add_someone(pubkey.to_owned())?; } else { - GLOBALS.relay_picker.remove_someone(pubkeyhex.to_owned()); + GLOBALS.relay_picker.remove_someone(pubkey.to_owned()); } // Update last_contact_list_edit @@ -923,7 +899,7 @@ impl People { Ok(()) } - pub async fn follow_all(&self, pubkeys: &[PublicKeyHex], merge: bool) -> Result<(), Error> { + pub async fn follow_all(&self, pubkeys: &[PublicKey], merge: bool) -> Result<(), Error> { // If merging, and we already follow all these keys, // then just bail out if merge { @@ -956,7 +932,8 @@ impl People { repeat_vars(pubkeys.len()) ); - let pubkey_strings: Vec = pubkeys.iter().map(|p| p.to_string()).collect(); + let pubkey_strings: Vec = pubkeys.iter().map(|p| p.as_hex_string()).collect(); + let pubkey_strings2 = pubkey_strings.clone(); let now = Unixtime::now().unwrap(); @@ -982,14 +959,12 @@ impl People { repeat_vars(pubkeys.len()) ); - let pubkey_strings: Vec = pubkeys.iter().map(|p| p.to_string()).collect(); - task::spawn_blocking(move || { let db = GLOBALS.db.blocking_lock(); let mut stmt = db.prepare(&sql)?; stmt.raw_bind_parameter(1, now.0)?; let mut pos = 2; - for pk in pubkey_strings.iter() { + for pk in pubkey_strings2.iter() { stmt.raw_bind_parameter(pos, pk)?; pos += 1; } @@ -1001,9 +976,9 @@ impl People { // Make sure memory matches for mut elem in self.people.iter_mut() { - let pkh = elem.key().clone(); + let pk = *elem.key(); let person = elem.value_mut(); - if pubkeys.contains(&pkh) { + if pubkeys.contains(&pk) { person.followed = 1; } else if !merge { person.followed = 0; @@ -1038,38 +1013,37 @@ impl People { Ok(()) } - pub fn mute(&self, pubkeyhex: &PublicKeyHex, mute: bool) { + pub fn mute(&self, pubkey: PublicKey, mute: bool) { // We can't do it now, but we spawn a task to do it soon - let pubkeyhex = pubkeyhex.to_owned(); tokio::spawn(async move { - if let Err(e) = GLOBALS.people.async_mute(&pubkeyhex, mute).await { + if let Err(e) = GLOBALS.people.async_mute(&pubkey, mute).await { tracing::error!("{}", e); } }); } - pub async fn async_mute(&self, pubkeyhex: &PublicKeyHex, mute: bool) -> Result<(), Error> { + pub async fn async_mute(&self, pubkey: &PublicKey, mute: bool) -> Result<(), Error> { let mute: u8 = u8::from(mute); // Mute in database let sql = "INSERT INTO PERSON (pubkey, muted) values (?, ?) \ ON CONFLICT(pubkey) DO UPDATE SET muted=?"; - let pubkeyhex2 = pubkeyhex.to_owned(); + let pubkeyhexstr = pubkey.as_hex_string(); task::spawn_blocking(move || { let db = GLOBALS.db.blocking_lock(); let mut stmt = db.prepare(sql)?; - stmt.execute((pubkeyhex2.as_str(), &mute, &mute))?; + stmt.execute((pubkeyhexstr, &mute, &mute))?; Ok::<(), Error>(()) }) .await??; // Make sure memory matches - if let Some(mut dbperson) = self.people.get_mut(pubkeyhex) { + if let Some(mut dbperson) = self.people.get_mut(pubkey) { dbperson.muted = mute; } else { // load - if let Some(person) = Self::fetch_one(pubkeyhex).await? { - self.people.insert(pubkeyhex.to_owned(), person); + if let Some(person) = Self::fetch_one(pubkey).await? { + self.people.insert(pubkey.to_owned(), person); } } @@ -1077,7 +1051,7 @@ impl People { GLOBALS .ui_people_to_invalidate .write() - .push(pubkeyhex.to_owned()); + .push(pubkey.to_owned()); Ok(()) } @@ -1085,14 +1059,14 @@ impl People { // Returns true if the date passed in is newer than what we already had pub async fn update_relay_list_stamps( &self, - pubkeyhex: PublicKeyHex, + pubkey: PublicKey, mut created_at: i64, ) -> Result { let now = Unixtime::now().unwrap().0; let mut retval = false; - if let Some(mut person) = self.people.get_mut(&pubkeyhex) { + if let Some(mut person) = self.people.get_mut(&pubkey) { person.relay_list_last_received = now; if let Some(old_at) = person.relay_list_created_at { @@ -1116,7 +1090,7 @@ impl People { "UPDATE person SET relay_list_last_received=?, \ relay_list_created_at=? WHERE pubkey=?", )?; - stmt.execute((&now, &created_at, pubkeyhex.as_str()))?; + stmt.execute((&now, &created_at, pubkey.as_hex_string()))?; Ok::<(), Error>(()) }) .await??; @@ -1124,17 +1098,17 @@ impl People { Ok(retval) } - pub async fn update_nip05_last_checked(&self, pubkeyhex: PublicKeyHex) -> Result<(), Error> { + pub async fn update_nip05_last_checked(&self, pubkey: PublicKey) -> Result<(), Error> { let now = Unixtime::now().unwrap().0; - if let Some(mut person) = self.people.get_mut(&pubkeyhex) { + if let Some(mut person) = self.people.get_mut(&pubkey) { person.nip05_last_checked = Some(now as u64); } task::spawn_blocking(move || { let db = GLOBALS.db.blocking_lock(); let mut stmt = db.prepare("UPDATE person SET nip05_last_checked=? WHERE pubkey=?")?; - stmt.execute((&now, pubkeyhex.as_str()))?; + stmt.execute((&now, pubkey.as_hex_string()))?; Ok(()) }) .await? @@ -1142,13 +1116,13 @@ impl People { pub async fn upsert_nip05_validity( &self, - pubkeyhex: &PublicKeyHex, + pubkey: &PublicKey, nip05: Option, nip05_valid: bool, nip05_last_checked: u64, ) -> Result<(), Error> { // Update memory - if let Some(mut dbperson) = self.people.get_mut(pubkeyhex) { + if let Some(mut dbperson) = self.people.get_mut(pubkey) { if let Some(metadata) = &mut dbperson.metadata { metadata.nip05 = nip05.clone() } else { @@ -1166,7 +1140,7 @@ impl People { ON CONFLICT(pubkey) DO \ UPDATE SET metadata=json_patch(metadata, ?), nip05_valid=?, nip05_last_checked=?"; - let pubkeyhex2 = pubkeyhex.to_owned(); + let pubkey2 = pubkey.to_owned(); task::spawn_blocking(move || { let db = GLOBALS.db.blocking_lock(); let mut metadata = Metadata::new(); @@ -1177,7 +1151,7 @@ impl People { let mut stmt = db.prepare(sql)?; stmt.execute(( - pubkeyhex2.as_str(), + pubkey2.as_hex_string(), &metadata_json, &nip05_valid, &nip05_last_checked, @@ -1193,7 +1167,7 @@ impl People { GLOBALS .ui_people_to_invalidate .write() - .push(pubkeyhex.to_owned()); + .push(pubkey.to_owned()); Ok(()) } @@ -1224,7 +1198,7 @@ impl People { }; let pk: String = row.get(0)?; output.push(Person { - pubkey: PublicKeyHex::try_from_string(pk)?, + pubkey: PublicKey::try_from_hex_string(&pk)?, petname: row.get(1)?, followed: row.get(2)?, followed_last_updated: row.get(3)?, @@ -1246,8 +1220,8 @@ impl People { output } - async fn fetch_one(pubkeyhex: &PublicKeyHex) -> Result, Error> { - let people = Self::fetch(Some(&format!("pubkey='{}'", pubkeyhex))).await?; + async fn fetch_one(pubkey: &PublicKey) -> Result, Error> { + let people = Self::fetch(Some(&format!("pubkey='{}'", pubkey.as_hex_string()))).await?; if people.is_empty() { Ok(None) @@ -1256,7 +1230,7 @@ impl People { } } - async fn fetch_many(pubkeys: &[&PublicKeyHex]) -> Result, Error> { + async fn fetch_many(pubkeys: &[&PublicKey]) -> Result, Error> { let sql = format!( "SELECT pubkey, petname, \ followed, followed_last_updated, muted, \ @@ -1267,7 +1241,7 @@ impl People { repeat_vars(pubkeys.len()) ); - let pubkey_strings: Vec = pubkeys.iter().map(|p| p.to_string()).collect(); + let pubkey_strings: Vec = pubkeys.iter().map(|p| p.as_hex_string()).collect(); let output: Result, Error> = task::spawn_blocking(move || { let db = GLOBALS.db.blocking_lock(); @@ -1288,7 +1262,7 @@ impl People { }; let pk: String = row.get(0)?; people.push(Person { - pubkey: PublicKeyHex::try_from_string(pk)?, + pubkey: PublicKey::try_from_hex_string(&pk)?, petname: row.get(1)?, followed: row.get(2)?, followed_last_updated: row.get(3)?, @@ -1318,19 +1292,19 @@ impl People { } */ - pub async fn set_active_person(&self, pubkey: PublicKeyHex) -> Result<(), Error> { + pub async fn set_active_person(&self, pubkey: PublicKey) -> Result<(), Error> { // Set the active person - *self.active_person.write().await = Some(pubkey.clone()); + *self.active_person.write().await = Some(pubkey); // Load their relays - let best_relays = PersonRelay::get_best_relays(pubkey, Direction::Write).await?; + let best_relays = PersonRelay::get_best_relays(pubkey.into(), Direction::Write).await?; *self.active_persons_write_relays.write().await = best_relays; Ok(()) } - pub fn get_active_person(&self) -> Option { - self.active_person.blocking_read().clone() + pub fn get_active_person(&self) -> Option { + *self.active_person.blocking_read() } pub fn get_active_person_write_relays(&self) -> Vec<(RelayUrl, u64)> { diff --git a/src/process.rs b/src/process.rs index 2275952c..246061c3 100644 --- a/src/process.rs +++ b/src/process.rs @@ -1,9 +1,9 @@ use crate::comms::ToOverlordMessage; -use crate::db::{PersonRelay, DbRelay}; +use crate::db::{DbRelay, PersonRelay}; use crate::error::Error; use crate::globals::GLOBALS; use nostr_types::{ - Event, EventKind, Metadata, NostrBech32, RelayUrl, SimpleRelayList, Tag, Unixtime, + Event, EventKind, Metadata, NostrBech32, PublicKey, RelayUrl, SimpleRelayList, Tag, Unixtime, }; use std::sync::atomic::Ordering; @@ -83,7 +83,7 @@ pub async fn process_new_event( // Create the person if missing in the database GLOBALS .people - .create_all_if_missing(&[event.pubkey.into()]) + .create_all_if_missing(&[event.pubkey]) .await?; if let Some(ref url) = seen_on { @@ -114,22 +114,21 @@ pub async fn process_new_event( recommended_relay_url: Some(should_be_url), .. } => { - if let Ok(url) = RelayUrl::try_from_unchecked_url(should_be_url) { - GLOBALS.storage.write_relay_if_missing(&url)?; + if let Ok(pubkey) = PublicKey::try_from_hex_string(pubkey) { + if let Ok(url) = RelayUrl::try_from_unchecked_url(should_be_url) { + GLOBALS.storage.write_relay_if_missing(&url)?; - // Add person if missing - GLOBALS - .people - .create_all_if_missing(&[pubkey.clone()]) + // Add person if missing + GLOBALS.people.create_all_if_missing(&[pubkey]).await?; + + // upsert person_relay.last_suggested_bytag + PersonRelay::upsert_last_suggested_bytag( + pubkey.as_hex_string(), + url, + now.0 as u64, + ) .await?; - - // upsert person_relay.last_suggested_bytag - PersonRelay::upsert_last_suggested_bytag( - pubkey.to_string(), - url, - now.0 as u64, - ) - .await?; + } } } _ => {} @@ -138,7 +137,7 @@ pub async fn process_new_event( } // Save event relationships (whether from a relay or not) - let invalid_ids = GLOBALS.storage.process_relationships_of_event(&event)?; + let invalid_ids = GLOBALS.storage.process_relationships_of_event(event)?; // Invalidate UI events indicated by those relationships GLOBALS.ui_notes_to_invalidate.write().extend(&invalid_ids); @@ -157,7 +156,7 @@ pub async fn process_new_event( GLOBALS .people - .update_metadata(&event.pubkey.into(), metadata, event.created_at) + .update_metadata(&event.pubkey, metadata, event.created_at) .await?; } @@ -235,7 +234,7 @@ async fn process_relay_list(event: &Event) -> Result<(), Error> { // if this relay list happens to be newer) let newer = GLOBALS .people - .update_relay_list_stamps(event.pubkey.into(), event.created_at.0) + .update_relay_list_stamps(event.pubkey, event.created_at.0) .await?; if !newer { @@ -339,7 +338,7 @@ async fn process_somebody_elses_contact_list(event: &Event) -> Result<(), Error> // if this relay list happens to be newer) let newer = GLOBALS .people - .update_relay_list_stamps(event.pubkey.into(), event.created_at.0) + .update_relay_list_stamps(event.pubkey, event.created_at.0) .await?; if !newer { diff --git a/src/relay_picker_hooks.rs b/src/relay_picker_hooks.rs index 3b171d51..017914d2 100644 --- a/src/relay_picker_hooks.rs +++ b/src/relay_picker_hooks.rs @@ -3,7 +3,7 @@ use crate::error::Error; use crate::globals::GLOBALS; use async_trait::async_trait; use gossip_relay_picker::{Direction, RelayPickerHooks}; -use nostr_types::{PublicKeyHex, RelayUrl}; +use nostr_types::{PublicKey, RelayUrl}; #[derive(Default)] pub struct Hooks {} @@ -23,10 +23,10 @@ impl RelayPickerHooks for Hooks { /// Returns all relays that this public key uses in the given Direction async fn get_relays_for_pubkey( &self, - pubkey: PublicKeyHex, + pubkey: PublicKey, direction: Direction, ) -> Result, Error> { - PersonRelay::get_best_relays(pubkey, direction).await + PersonRelay::get_best_relays(pubkey.into(), direction).await } /// Is the relay currently connected? @@ -46,7 +46,7 @@ impl RelayPickerHooks for Hooks { } /// Returns the public keys of all the people followed - fn get_followed_pubkeys(&self) -> Vec { + fn get_followed_pubkeys(&self) -> Vec { GLOBALS.people.get_followed_pubkeys() } diff --git a/src/storage/migrations/mod.rs b/src/storage/migrations/mod.rs index fcbf8118..cb246d06 100644 --- a/src/storage/migrations/mod.rs +++ b/src/storage/migrations/mod.rs @@ -12,7 +12,8 @@ impl Storage { return Err(ErrorKind::General(format!( "Migration level {} unknown: This client is older than your data.", level - )).into()); + )) + .into()); } while level < Self::MIGRATION_LEVEL { diff --git a/src/storage/mod.rs b/src/storage/mod.rs index f5eda23f..ab648f90 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -831,7 +831,6 @@ impl Storage { // This returns IDs that should be UI invalidated pub fn process_relationships_of_event(&self, event: &Event) -> Result, Error> { - let mut invalidate: Vec = Vec::new(); // replies to @@ -841,11 +840,7 @@ impl Storage { // reacts to if let Some((id, reaction, _maybe_url)) = event.reacts_to() { - self.write_relationship( - id, - event.id, - Relationship::Reaction(event.pubkey, reaction), - )?; + self.write_relationship(id, event.id, Relationship::Reaction(event.pubkey, reaction))?; invalidate.push(id); } @@ -857,11 +852,7 @@ impl Storage { for id in ids { // since it is a delete, we don't actually desire the event. - self.write_relationship( - id, - event.id, - Relationship::Deletion(reason.clone()), - )?; + self.write_relationship(id, event.id, Relationship::Deletion(reason.clone()))?; } } diff --git a/src/ui/feed/mod.rs b/src/ui/feed/mod.rs index d7ba1991..49655f78 100644 --- a/src/ui/feed/mod.rs +++ b/src/ui/feed/mod.rs @@ -137,13 +137,13 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram render_a_feed(app, ctx, frame, ui, vec![parent], true, &id.as_hex_string()); } } - FeedKind::Person(pubkeyhex) => { + FeedKind::Person(pubkey) => { ui.horizontal(|ui| { recompute_btn(app, ui); }); let feed = GLOBALS.feed.get_person_feed(); - render_a_feed(app, ctx, frame, ui, feed, false, pubkeyhex.as_str()); + render_a_feed(app, ctx, frame, ui, feed, false, &pubkey.as_hex_string()); } } diff --git a/src/ui/feed/note/content.rs b/src/ui/feed/note/content.rs index c405faa9..5d4cb220 100644 --- a/src/ui/feed/note/content.rs +++ b/src/ui/feed/note/content.rs @@ -7,7 +7,7 @@ use eframe::{ epaint::Vec2, }; use egui::{RichText, Ui}; -use nostr_types::{ContentSegment, Id, IdHex, NostrBech32, PublicKeyHex, Span, Tag, Url}; +use nostr_types::{ContentSegment, Id, IdHex, NostrBech32, PublicKey, Span, Tag, Url}; use std::{ cell::{Ref, RefCell}, rc::Rc, @@ -95,10 +95,10 @@ pub(super) fn render_content( } } NostrBech32::Profile(prof) => { - render_profile_link(app, ui, &prof.pubkey.into()); + render_profile_link(app, ui, &prof.pubkey); } - NostrBech32::Pubkey(pk) => { - render_profile_link(app, ui, &(*pk).into()); + NostrBech32::Pubkey(pubkey) => { + render_profile_link(app, ui, pubkey); } NostrBech32::Relay(url) => { ui.label(RichText::new(&url.0).underline()); @@ -109,7 +109,10 @@ pub(super) fn render_content( if let Some(tag) = note.event.tags.get(*num) { match tag { Tag::Pubkey { pubkey, .. } => { - render_profile_link(app, ui, pubkey); + if let Ok(pubkey) = PublicKey::try_from_hex_string(pubkey.as_str()) + { + render_profile_link(app, ui, &pubkey); + } } Tag::Event { id, .. } => { let mut render_link = true; @@ -192,8 +195,8 @@ pub(super) fn render_plain(ui: &mut Ui, note: &Ref, textspan: &Span, a } } -pub(super) fn render_profile_link(app: &mut GossipUi, ui: &mut Ui, pubkey: &PublicKeyHex) { - let nam = GossipUi::display_name_from_pubkeyhex_lookup(pubkey); +pub(super) fn render_profile_link(app: &mut GossipUi, ui: &mut Ui, pubkey: &PublicKey) { + let nam = GossipUi::display_name_from_pubkey_lookup(pubkey); let nam = format!("@{}", nam); if ui.link(&nam).clicked() { app.set_page(Page::Person(pubkey.to_owned())); diff --git a/src/ui/feed/note/mod.rs b/src/ui/feed/note/mod.rs index ef8a0abd..f8c474f4 100644 --- a/src/ui/feed/note/mod.rs +++ b/src/ui/feed/note/mod.rs @@ -273,7 +273,7 @@ fn render_note_inner( ) .clicked() { - app.set_page(Page::Person(note.author.pubkey.clone())); + app.set_page(Page::Person(note.author.pubkey)); }; ui.add_space(avatar_margin_left); @@ -293,7 +293,7 @@ fn render_note_inner( app.set_page(Page::Feed(FeedKind::Thread { id: irt, referenced_by: note.event.id, - author: Some(note.event.pubkey.into()), + author: Some(note.event.pubkey), })); }; ui.reset_style(); @@ -343,7 +343,7 @@ fn render_note_inner( app.set_page(Page::Feed(FeedKind::Thread { id: note.event.id, referenced_by: note.event.id, - author: Some(note.event.pubkey.into()), + author: Some(note.event.pubkey), })); } } @@ -431,7 +431,7 @@ fn render_note_inner( app.set_page(Page::Feed(FeedKind::Thread { id: note.event.id, referenced_by: note.event.id, - author: Some(note.event.pubkey.into()), + author: Some(note.event.pubkey), })); } } diff --git a/src/ui/feed/notedata.rs b/src/ui/feed/notedata.rs index 6383491f..5c3d7773 100644 --- a/src/ui/feed/notedata.rs +++ b/src/ui/feed/notedata.rs @@ -1,6 +1,6 @@ use crate::{globals::GLOBALS, people::Person}; use nostr_types::{ - ContentSegment, Event, EventDelegation, EventKind, Id, MilliSatoshi, NostrBech32, PublicKeyHex, + ContentSegment, Event, EventDelegation, EventKind, Id, MilliSatoshi, NostrBech32, PublicKey, ShatteredContent, Tag, }; @@ -154,10 +154,10 @@ impl NoteData { }; // If delegated, use the delegated person - let author_pubkey: PublicKeyHex = if let EventDelegation::DelegatedBy(pubkey) = delegation { - pubkey.into() + let author_pubkey: PublicKey = if let EventDelegation::DelegatedBy(pubkey) = delegation { + pubkey } else { - event.pubkey.into() + event.pubkey }; let author = match GLOBALS.people.get(&author_pubkey) { diff --git a/src/ui/feed/notes.rs b/src/ui/feed/notes.rs index cc4d2521..39b64e46 100644 --- a/src/ui/feed/notes.rs +++ b/src/ui/feed/notes.rs @@ -1,6 +1,6 @@ use super::notedata::NoteData; use crate::globals::GLOBALS; -use nostr_types::{Id, PublicKeyHex}; +use nostr_types::{Id, PublicKey}; use std::{cell::RefCell, collections::HashMap, rc::Rc}; /// a 'note' is a processed event @@ -29,7 +29,7 @@ impl Notes { } /// Drop all NoteData for a given person - pub(in crate::ui) fn cache_invalidate_person(&mut self, pubkey: &PublicKeyHex) { + pub(in crate::ui) fn cache_invalidate_person(&mut self, pubkey: &PublicKey) { self.notes .retain(|_, note| note.borrow().author.pubkey != *pubkey); } diff --git a/src/ui/feed/post.rs b/src/ui/feed/post.rs index 8902e190..a0f7048d 100644 --- a/src/ui/feed/post.rs +++ b/src/ui/feed/post.rs @@ -322,7 +322,7 @@ fn real_posting_area(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram NostrBech32::Profile(prof) => &prof.pubkey, _ => continue, }; - let rendered = if let Some(person) = GLOBALS.people.get(&pk.as_hex_string().into()) { + let rendered = if let Some(person) = GLOBALS.people.get(pk) { match person.name() { Some(name) => name.to_owned(), None => format!("{}", bech32), diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 3ce4e3c7..27e3018a 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -42,7 +42,7 @@ use egui::{ #[cfg(feature = "video-ffmpeg")] use egui_video::{AudioDevice, Player}; use egui_winit::egui::Response; -use nostr_types::{Id, IdHex, Metadata, MilliSatoshi, PublicKey, PublicKeyHex, UncheckedUrl, Url}; +use nostr_types::{Id, IdHex, Metadata, MilliSatoshi, PublicKey, UncheckedUrl, Url}; use std::collections::{HashMap, HashSet}; #[cfg(feature = "video-ffmpeg")] use std::rc::Rc; @@ -98,7 +98,7 @@ enum Page { PeopleList, PeopleFollow, PeopleMuted, - Person(PublicKeyHex), + Person(PublicKey), YourKeys, YourMetadata, YourDelegation, @@ -200,7 +200,7 @@ struct GossipUi { icon: TextureHandle, placeholder_avatar: TextureHandle, settings: Settings, - avatars: HashMap, + avatars: HashMap, images: HashMap, /// used when settings.show_media=false to explicitly show media_show_list: HashSet, @@ -500,7 +500,7 @@ impl GossipUi { }) => { GLOBALS .feed - .set_feed_to_thread(*id, *referenced_by, vec![], author.clone()); + .set_feed_to_thread(*id, *referenced_by, vec![], *author); } Page::Feed(FeedKind::Person(pubkey)) => { GLOBALS.feed.set_feed_to_person(pubkey.to_owned()); @@ -626,15 +626,14 @@ impl eframe::App for GossipUi { ))); } if let Some(pubkey) = GLOBALS.signer.public_key() { - let pubkeyhex: PublicKeyHex = pubkey.into(); if self.add_selected_label( ui, - matches!(&self.page, Page::Feed(FeedKind::Person(key)) if key.as_str() == pubkeyhex.as_str()), + matches!(&self.page, Page::Feed(FeedKind::Person(key)) if *key == pubkey), "My Notes", ) .clicked() { - self.set_page(Page::Feed(FeedKind::Person(pubkeyhex))); + self.set_page(Page::Feed(FeedKind::Person(pubkey))); } } if self.add_selected_label( @@ -868,28 +867,15 @@ impl GossipUi { /// A short rendering of a `PublicKey` pub fn pubkey_short(pk: &PublicKey) -> String { let npub = pk.as_bech32_string(); - format!("{}…", &npub.get(0..20).unwrap_or("????????????????????")) - } - - /// A short rendering of a `PublicKeyHex` - pub fn pubkeyhex_short(pubkeyhex: &PublicKeyHex) -> String { format!( "{}_{}...{}_{}", - &pubkeyhex.as_str()[0..4], - &pubkeyhex.as_str()[4..8], - &pubkeyhex.as_str()[56..60], - &pubkeyhex.as_str()[60..64], + &npub.get(0..4).unwrap_or("????"), + &npub.get(4..8).unwrap_or("????"), + &npub.get(56..60).unwrap_or("????"), + &npub.get(60..64).unwrap_or("????") ) } - /// A short rendering of a `PublicKeyHex`, with attempt to convert to bech32 - pub fn pubkeyhex_convert_short(pubkeyhex: &PublicKeyHex) -> String { - match PublicKey::try_from_hex_string(pubkeyhex) { - Ok(pk) => Self::pubkey_short(&pk), - Err(_) => GossipUi::pubkeyhex_short(pubkeyhex), - } - } - pub fn hex_id_short(idhex: &IdHex) -> String { idhex.as_str()[0..8].to_string() } @@ -898,22 +884,21 @@ impl GossipUi { pub fn display_name_from_dbperson(dbperson: &Person) -> String { match dbperson.display_name() { Some(name) => name.to_owned(), - None => Self::pubkeyhex_convert_short(&dbperson.pubkey), + None => Self::pubkey_short(&dbperson.pubkey), } } - /// A display name for a `PublicKeyHex`, via trying to lookup the person - pub fn display_name_from_pubkeyhex_lookup(pkh: &PublicKeyHex) -> String { - match GLOBALS.people.get(pkh) { + pub fn display_name_from_pubkey_lookup(pubkey: &PublicKey) -> String { + match GLOBALS.people.get(pubkey) { Some(dbperson) => Self::display_name_from_dbperson(&dbperson), - None => Self::pubkeyhex_convert_short(pkh), + None => Self::pubkey_short(pubkey), } } pub fn render_person_name_line(app: &mut GossipUi, ui: &mut Ui, person: &Person) { // Let the 'People' manager know that we are interested in displaying this person. // It will take all actions necessary to make the data eventually available. - GLOBALS.people.person_of_interest(person.pubkey.clone()); + GLOBALS.people.person_of_interest(person.pubkey); ui.horizontal_wrapped(|ui| { let name = GossipUi::display_name_from_dbperson(person); @@ -921,7 +906,7 @@ impl GossipUi { ui.menu_button(&name, |ui| { let mute_label = if person.muted == 1 { "Unmute" } else { "Mute" }; if ui.button(mute_label).clicked() { - GLOBALS.people.mute(&person.pubkey, person.muted == 0); + GLOBALS.people.mute(person.pubkey, person.muted == 0); app.notes.cache_invalidate_person(&person.pubkey); } if person.followed == 0 && ui.button("Follow").clicked() { @@ -932,10 +917,10 @@ impl GossipUi { if ui.button("Update Metadata").clicked() { let _ = GLOBALS .to_overlord - .send(ToOverlordMessage::UpdateMetadata(person.pubkey.clone())); + .send(ToOverlordMessage::UpdateMetadata(person.pubkey)); } if ui.button("View Their Posts").clicked() { - app.set_page(Page::Feed(FeedKind::Person(person.pubkey.clone()))); + app.set_page(Page::Feed(FeedKind::Person(person.pubkey))); } }); @@ -966,28 +951,24 @@ impl GossipUi { }); } - pub fn try_get_avatar( - &mut self, - ctx: &Context, - pubkeyhex: &PublicKeyHex, - ) -> Option { + pub fn try_get_avatar(&mut self, ctx: &Context, pubkey: &PublicKey) -> Option { // Do not keep retrying if failed - if GLOBALS.failed_avatars.blocking_read().contains(pubkeyhex) { + if GLOBALS.failed_avatars.blocking_read().contains(pubkey) { return None; } - if let Some(th) = self.avatars.get(pubkeyhex) { + if let Some(th) = self.avatars.get(pubkey) { return Some(th.to_owned()); } - if let Some(color_image) = GLOBALS.people.get_avatar(pubkeyhex) { + if let Some(color_image) = GLOBALS.people.get_avatar(pubkey) { let texture_handle = ctx.load_texture( - pubkeyhex.to_string(), + pubkey.as_hex_string(), color_image, TextureOptions::default(), ); self.avatars - .insert(pubkeyhex.to_owned(), texture_handle.clone()); + .insert(pubkey.to_owned(), texture_handle.clone()); Some(texture_handle) } else { None diff --git a/src/ui/people/followed.rs b/src/ui/people/followed.rs index 936098d0..d1291736 100644 --- a/src/ui/people/followed.rs +++ b/src/ui/people/followed.rs @@ -175,13 +175,11 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra .add(Image::new(&avatar, Vec2 { x: size, y: size }).sense(Sense::click())) .clicked() { - app.set_page(Page::Person(person.pubkey.clone())); + app.set_page(Page::Person(person.pubkey)); }; ui.vertical(|ui| { - ui.label( - RichText::new(GossipUi::pubkeyhex_convert_short(&person.pubkey)).weak(), - ); + ui.label(RichText::new(GossipUi::pubkey_short(&person.pubkey)).weak()); GossipUi::render_person_name_line(app, ui, person); }); }); diff --git a/src/ui/people/muted.rs b/src/ui/people/muted.rs index 69455e59..cbba0afb 100644 --- a/src/ui/people/muted.rs +++ b/src/ui/people/muted.rs @@ -44,17 +44,15 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra .add(Image::new(&avatar, Vec2 { x: size, y: size }).sense(Sense::click())) .clicked() { - app.set_page(Page::Person(person.pubkey.clone())); + app.set_page(Page::Person(person.pubkey)); }; ui.vertical(|ui| { - ui.label( - RichText::new(GossipUi::pubkeyhex_convert_short(&person.pubkey)).weak(), - ); + ui.label(RichText::new(GossipUi::pubkey_short(&person.pubkey)).weak()); GossipUi::render_person_name_line(app, ui, person); if ui.button("UNMUTE").clicked() { - GLOBALS.people.mute(&person.pubkey, false); + GLOBALS.people.mute(person.pubkey, false); } }); }); diff --git a/src/ui/people/person.rs b/src/ui/people/person.rs index 46fc3e7c..5f5a4053 100644 --- a/src/ui/people/person.rs +++ b/src/ui/people/person.rs @@ -6,17 +6,17 @@ use crate::ui::widgets::CopyButton; use crate::AVATAR_SIZE_F32; use eframe::egui; use egui::{Context, Frame, RichText, ScrollArea, Ui, Vec2}; -use nostr_types::{PublicKey, PublicKeyHex}; +use nostr_types::PublicKey; use serde_json::Value; pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Frame, ui: &mut Ui) { - let (pubkeyhex, person) = match &app.page { - Page::Person(pubkeyhex) => { - let person = match GLOBALS.people.get(pubkeyhex) { + let (pubkey, person) = match &app.page { + Page::Person(pubkey) => { + let person = match GLOBALS.people.get(pubkey) { Some(p) => p, - None => Person::new(pubkeyhex.to_owned()), + None => Person::new(pubkey.to_owned()), }; - (pubkeyhex.to_owned(), person) + (pubkey.to_owned(), person) } _ => { ui.label("ERROR"); @@ -33,22 +33,16 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra .max_width(f32::INFINITY) .auto_shrink([false, false]) .show(ui, |ui| { - content(app, ctx, ui, pubkeyhex, person); + content(app, ctx, ui, pubkey, person); }); } -fn content( - app: &mut GossipUi, - ctx: &Context, - ui: &mut Ui, - pubkeyhex: PublicKeyHex, - person: Person, -) { +fn content(app: &mut GossipUi, ctx: &Context, ui: &mut Ui, pubkey: PublicKey, person: Person) { ui.add_space(24.0); ui.horizontal(|ui| { // Avatar first - let avatar = if let Some(avatar) = app.try_get_avatar(ctx, &pubkeyhex) { + let avatar = if let Some(avatar) = app.try_get_avatar(ctx, &pubkey) { avatar } else { app.placeholder_avatar.clone() @@ -63,32 +57,29 @@ fn content( ui.vertical(|ui| { let name = GossipUi::display_name_from_dbperson(&person); ui.heading(name); - ui.label(RichText::new(GossipUi::pubkeyhex_convert_short(&pubkeyhex)).weak()); + ui.label(RichText::new(GossipUi::pubkey_short(&pubkey)).weak()); GossipUi::render_person_name_line(app, ui, &person); }); }); ui.add_space(12.0); - let mut npub = "Unable to get npub".to_owned(); - if let Ok(pk) = PublicKey::try_from_hex_string(&pubkeyhex) { - npub = pk.as_bech32_string(); - ui.horizontal_wrapped(|ui| { - ui.label(RichText::new("Public Key: ").strong()); - ui.label(&npub); - if ui - .add(CopyButton {}) - .on_hover_text("Copy Public Key") - .clicked() - { - ui.output_mut(|o| o.copied_text = npub.to_owned()); - } - if ui.button("⚃").on_hover_text("Show as QR code").clicked() { - app.qr_codes.remove("person_qr"); - app.person_qr = Some("npub"); - } - }); - } + let npub = pubkey.as_bech32_string(); + ui.horizontal_wrapped(|ui| { + ui.label(RichText::new("Public Key: ").strong()); + ui.label(&npub); + if ui + .add(CopyButton {}) + .on_hover_text("Copy Public Key") + .clicked() + { + ui.output_mut(|o| o.copied_text = npub.to_owned()); + } + if ui.button("⚃").on_hover_text("Show as QR code").clicked() { + app.qr_codes.remove("person_qr"); + app.person_qr = Some("npub"); + } + }); if let Some(name) = person.name() { ui.horizontal_wrapped(|ui| { @@ -198,8 +189,9 @@ fn content( } let mut need_to_set_active_person = true; + if let Some(ap) = GLOBALS.people.get_active_person() { - if ap == pubkeyhex { + if ap == pubkey { need_to_set_active_person = false; app.setting_active_person = false; @@ -217,6 +209,6 @@ fn content( app.setting_active_person = true; let _ = GLOBALS .to_overlord - .send(ToOverlordMessage::SetActivePerson(pubkeyhex.clone())); + .send(ToOverlordMessage::SetActivePerson(pubkey)); } } diff --git a/src/ui/relays/mod.rs b/src/ui/relays/mod.rs index b939ee07..fddbe4eb 100644 --- a/src/ui/relays/mod.rs +++ b/src/ui/relays/mod.rs @@ -106,7 +106,7 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram for elem in GLOBALS.relay_picker.pubkey_counts_iter() { let pk = elem.key(); let count = elem.value(); - let name = GossipUi::display_name_from_pubkeyhex_lookup(pk); + let name = GossipUi::display_name_from_pubkey_lookup(pk); ui.label(format!("{}: coverage short by {} relay(s)", name, count)); } } else { diff --git a/src/ui/search.rs b/src/ui/search.rs index 6ea4451c..e9ed95d0 100644 --- a/src/ui/search.rs +++ b/src/ui/search.rs @@ -77,14 +77,11 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut Frame, ui: ) .clicked() { - app.set_page(Page::Person(person.pubkey.clone())); + app.set_page(Page::Person(person.pubkey)); }; ui.vertical(|ui| { - ui.label( - RichText::new(GossipUi::pubkeyhex_convert_short(&person.pubkey)) - .weak(), - ); + ui.label(RichText::new(GossipUi::pubkey_short(&person.pubkey)).weak()); GossipUi::render_person_name_line(app, ui, person); }); }); @@ -104,8 +101,7 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut Frame, ui: .weak(), ); - let pubkeyhex = event.pubkey.into(); - if let Some(person) = GLOBALS.people.get(&pubkeyhex) { + if let Some(person) = GLOBALS.people.get(&event.pubkey) { GossipUi::render_person_name_line(app, ui, &person); } else { ui.label(event.pubkey.as_bech32_string()); @@ -122,7 +118,7 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut Frame, ui: app.set_page(Page::Feed(FeedKind::Thread { id: event.id, referenced_by: event.id, - author: Some(event.pubkey.into()), + author: Some(event.pubkey), })); } } diff --git a/src/ui/you/metadata.rs b/src/ui/you/metadata.rs index ab927b1a..3908792c 100644 --- a/src/ui/you/metadata.rs +++ b/src/ui/you/metadata.rs @@ -29,11 +29,11 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr } }; - let you = match GLOBALS.people.get(&public_key.into()) { + let you = match GLOBALS.people.get(&public_key) { Some(dbp) => dbp, None => { ui.label("I cannot find you."); - GLOBALS.people.create_if_missing_sync(public_key.into()); + GLOBALS.people.create_if_missing_sync(public_key); return; } };