Compare commits

...

4 commits

Author SHA1 Message Date
xeruf
0de4e2e55d fix(nostr_users): only keep latest user metadata 2025-01-23 15:25:56 +01:00
xeruf
3ed60c3457 feat(main): allow setting active key with MOSTR_ID 2025-01-23 15:23:35 +01:00
xeruf
7acdede38c fix(nostr_users): don't attach key to username
Somehow filtering consistently shows all tasks of same-named users anyways
2025-01-23 15:00:40 +01:00
xeruf
8c1902c1d3 enhance: sort users by newest first for name matching 2025-01-23 14:59:26 +01:00
3 changed files with 34 additions and 14 deletions

View file

@ -21,7 +21,8 @@ use rustyline::config::Configurer;
use rustyline::error::ReadlineError;
use rustyline::DefaultEditor;
use std::collections::{HashMap, VecDeque};
use std::env::{args, var};
use std::env;
use std::env::{args};
use std::fs;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
@ -147,7 +148,7 @@ async fn main() -> Result<()> {
.inspect(|_| { or_warn!(fs::remove_file(key_file)); }));
}
let keys_entry = Entry::new("mostr", "keys")?;
let keys_entry = Entry::new("mostr", &env::var("MOSTR_ID").unwrap_or("keys".to_string()))?;
let keys =
if args.peek().is_some_and(|arg| arg.trim_start_matches('-') == "import") {
args.next();
@ -189,7 +190,7 @@ async fn main() -> Result<()> {
let relays_file = config_dir.join("relays");
// TODO use NewRelay message for all relays
match var("MOSTR_RELAY") {
match env::var("MOSTR_RELAY") {
Ok(relay) => {
or_warn!(client.add_relay(relay).await);
}

View file

@ -158,7 +158,7 @@ impl TasksRelay {
metadata: Option<Metadata>,
) -> 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 => {

View file

@ -1,10 +1,13 @@
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;
use log::debug;
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct NostrUsers {
users: HashMap<PublicKey, Metadata>,
user_times: HashMap<PublicKey, Timestamp>,
}
impl NostrUsers {
@ -23,11 +26,14 @@ 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)| self.get_user_time(k))
.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 {
@ -42,8 +48,21 @@ impl NostrUsers {
.unwrap_or_else(|| format!("{:.6}", pubkey.to_string()))
}
pub(super) fn insert(&mut self, pubkey: PublicKey, metadata: Metadata) {
self.users.insert(pubkey, metadata);
fn get_user_time(&self, pubkey: &PublicKey) -> u64 {
match self.user_times.get(pubkey) {
Some(t) => t.as_u64(),
None => Timestamp::zero().as_u64(),
}
}
pub(super) fn insert(&mut self, pubkey: PublicKey, metadata: Metadata, timestamp: Timestamp) {
if self.get_user_time(&pubkey) < timestamp.as_u64() {
debug!("Inserting user metadata for {}", pubkey);
self.users.insert(pubkey, metadata);
self.user_times.insert(pubkey, timestamp);
} else {
debug!("Skipping older user metadata for {}", pubkey);
}
}
pub(super) fn create(&mut self, pubkey: PublicKey) {
@ -57,7 +76,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)]));
}