From eea8511a6e5cfae5b66c36961754f2ba230aed46 Mon Sep 17 00:00:00 2001 From: xeruf <27jf@pm.me> Date: Thu, 21 Nov 2024 21:18:26 +0100 Subject: [PATCH] feat: enable finding user by partial key and name --- src/main.rs | 9 +++------ src/tasks.rs | 26 ++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index fbbce77..3670c15 100644 --- a/src/main.rs +++ b/src/main.rs @@ -465,12 +465,9 @@ async fn main() -> Result<()> { Some(arg) => { if arg == "@" { tasks.reset_key_filter() - } else if let Ok(key) = PublicKey::from_str(arg) { - info!("Showing {}'s tasks", tasks.get_username(&key)); + } else if let Some((key, name)) = tasks.find_user_with_displayname(arg) { + info!("Showing {}'s tasks", name); tasks.set_key_filter(key) - } else if let Some((key, meta)) = tasks.find_user(arg) { - info!("Showing {}'s tasks", meta.display_name.as_ref().unwrap_or(meta.name.as_ref().unwrap_or(&key.to_string()))); - tasks.set_key_filter(key.clone()) } else { if parse_hour(arg, 1) .or_else(|| parse_date(arg).map(|utc| utc.with_timezone(&Local))) @@ -622,7 +619,7 @@ async fn main() -> Result<()> { label) }, vec.iter().rev().join("\n")); - } else if let Ok(key) = PublicKey::parse(arg) { // TODO also match name + } else if let Some((key, _)) = tasks.find_user(arg) { let (label, mut times) = tasks.times_tracked_for(&key); println!("{}\n{}", label.italic(), times.join("\n")); diff --git a/src/tasks.rs b/src/tasks.rs index 9e9af93..8d877ef 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -618,11 +618,29 @@ impl TasksRelay { } } + pub(crate) fn find_user_with_displayname(&self, term: &str) -> Option<(PublicKey, String)> { + match PublicKey::from_str(term) { + Ok(key) => Some((key, self.get_displayname(&key))), + Err(_) => self.find_user(term).map(|(k, _)| (*k, self.get_displayname(k))), + } + } + + // Find username or key starting with the given term. pub(crate) fn find_user(&self, term: &str) -> Option<(&PublicKey, &Metadata)> { - self.users.iter().find(|(_, v)| + 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.starts_with(term)) || - v.display_name.as_ref().is_some_and(|n| n.starts_with(term))) + v.display_name.as_ref().is_some_and(|n| n.starts_with(term)) || + (term.len() > 4 && k.to_string().starts_with(term))) + } + + pub(crate) fn get_displayname(&self, pubkey: &PublicKey) -> String { + self.users.get(pubkey) + .and_then(|m| m.display_name.clone().or(m.name.clone())) + .unwrap_or_else(|| pubkey.to_string()) } pub(crate) fn get_username(&self, pubkey: &PublicKey) -> String { @@ -1087,6 +1105,10 @@ impl TasksRelay { } pub(crate) fn add(&mut self, event: Event) { + let author = event.pubkey; + if !self.users.contains_key(&author) { + self.users.insert(author, Metadata::new()); + } match event.kind { Kind::GitIssue => self.add_task(event), Kind::Metadata => match Metadata::from_json(event.content.as_str()) {