feat: enable finding user by partial key and name

This commit is contained in:
xeruf 2024-11-21 21:18:26 +01:00
parent 5032b4db93
commit eea8511a6e
2 changed files with 27 additions and 8 deletions

View File

@ -465,12 +465,9 @@ async fn main() -> Result<()> {
Some(arg) => { Some(arg) => {
if arg == "@" { if arg == "@" {
tasks.reset_key_filter() tasks.reset_key_filter()
} else if let Ok(key) = PublicKey::from_str(arg) { } else if let Some((key, name)) = tasks.find_user_with_displayname(arg) {
info!("Showing {}'s tasks", tasks.get_username(&key)); info!("Showing {}'s tasks", name);
tasks.set_key_filter(key) 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 { } else {
if parse_hour(arg, 1) if parse_hour(arg, 1)
.or_else(|| parse_date(arg).map(|utc| utc.with_timezone(&Local))) .or_else(|| parse_date(arg).map(|utc| utc.with_timezone(&Local)))
@ -622,7 +619,7 @@ async fn main() -> Result<()> {
label) label)
}, },
vec.iter().rev().join("\n")); 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); let (label, mut times) = tasks.times_tracked_for(&key);
println!("{}\n{}", label.italic(), println!("{}\n{}", label.italic(),
times.join("\n")); times.join("\n"));

View File

@ -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)> { 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 // TODO regex word boundary
v.name.as_ref().is_some_and(|n| n.starts_with(term)) || 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 { pub(crate) fn get_username(&self, pubkey: &PublicKey) -> String {
@ -1087,6 +1105,10 @@ impl TasksRelay {
} }
pub(crate) fn add(&mut self, event: Event) { 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 { match event.kind {
Kind::GitIssue => self.add_task(event), Kind::GitIssue => self.add_task(event),
Kind::Metadata => match Metadata::from_json(event.content.as_str()) { Kind::Metadata => match Metadata::from_json(event.content.as_str()) {