From 8c1902c1d3fb6d4cc1e123ef12e37640574f1416 Mon Sep 17 00:00:00 2001 From: xeruf <27jf@pm.me> Date: Thu, 23 Jan 2025 14:59:26 +0100 Subject: [PATCH] enhance: sort users by newest first for name matching --- src/tasks.rs | 4 ++-- src/tasks/nostr_users.rs | 30 ++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/tasks.rs b/src/tasks.rs index abbaac9..8e54abd 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -158,7 +158,7 @@ impl TasksRelay { metadata: Option, ) -> Self { let mut new = Self::with_sender(EventSender::from(url, tx, keys)); - metadata.map(|m| new.users.insert(keys.public_key(), m)); + metadata.map(|m| new.users.insert(keys.public_key(), m, Timestamp::now())); new } @@ -1228,7 +1228,7 @@ impl TasksRelay { match event.kind { Kind::GitIssue => self.add_task(event), Kind::Metadata => match Metadata::from_json(event.content.as_str()) { - Ok(metadata) => { self.users.insert(event.pubkey, metadata); } + Ok(metadata) => { self.users.insert(event.pubkey, metadata, event.created_at); } Err(e) => warn!("Cannot parse metadata: {} from {:?}", e, event), }, Kind::Bookmarks => { diff --git a/src/tasks/nostr_users.rs b/src/tasks/nostr_users.rs index 156dc02..f3db26f 100644 --- a/src/tasks/nostr_users.rs +++ b/src/tasks/nostr_users.rs @@ -1,10 +1,12 @@ -use nostr_sdk::{Keys, Metadata, PublicKey, Tag}; +use itertools::Itertools; +use nostr_sdk::{Keys, Metadata, PublicKey, Tag, Timestamp}; use std::collections::HashMap; use std::str::FromStr; #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct NostrUsers { users: HashMap, + user_times: HashMap, } impl NostrUsers { @@ -23,11 +25,17 @@ impl NostrUsers { if let Ok(key) = PublicKey::from_str(term) { return self.users.get_key_value(&key); } - self.users.iter().find(|(k, v)| - // TODO regex word boundary - v.name.as_ref().is_some_and(|n| n.to_ascii_lowercase().starts_with(term)) || - v.display_name.as_ref().is_some_and(|n| n.to_ascii_lowercase().starts_with(term)) || - (term.len() > 4 && k.to_string().starts_with(term))) + self.users.iter() + .sorted_unstable_by_key(|(k, v)| match self.user_times.get(k) { + Some(t) => t.as_u64(), + None => Timestamp::zero().as_u64(), + }) + .rev() + .find(|(k, v)| + // TODO regex word boundary + v.name.as_ref().is_some_and(|n| n.to_ascii_lowercase().starts_with(term)) || + v.display_name.as_ref().is_some_and(|n| n.to_ascii_lowercase().starts_with(term)) || + (term.len() > 4 && k.to_string().starts_with(term))) } pub(crate) fn get_displayname(&self, pubkey: &PublicKey) -> String { @@ -38,12 +46,14 @@ impl NostrUsers { pub(crate) fn get_username(&self, pubkey: &PublicKey) -> String { self.users.get(pubkey) - .and_then(|m| m.name.clone()) - .unwrap_or_else(|| format!("{:.6}", pubkey.to_string())) + .and_then(|m| m.name.as_ref()) + .map_or_else(|| format!("{:.6}", pubkey.to_string()), + |m| format!("{}@{:.6}", m, pubkey.to_string())) } - pub(super) fn insert(&mut self, pubkey: PublicKey, metadata: Metadata) { + pub(super) fn insert(&mut self, pubkey: PublicKey, metadata: Metadata, timestamp: Timestamp) { self.users.insert(pubkey, metadata); + self.user_times.insert(pubkey, timestamp); } pub(super) fn create(&mut self, pubkey: PublicKey) { @@ -57,7 +67,7 @@ impl NostrUsers { fn test_user_extract() { let keys = Keys::generate(); let mut users = NostrUsers::default(); - users.insert(keys.public_key, Metadata::new().display_name("Tester Jo")); + users.insert(keys.public_key, Metadata::new().display_name("Tester Jo"), Timestamp::now()); assert_eq!(crate::kinds::extract_tags("Hello @test", &users), ("Hello".to_string(), vec![Tag::public_key(keys.public_key)])); } \ No newline at end of file