forked from janek/mostr
refactor: create own struct for nostr relay users
This commit is contained in:
parent
654f273ad9
commit
78438696ac
3 changed files with 62 additions and 39 deletions
|
@ -464,7 +464,7 @@ async fn main() -> Result<()> {
|
||||||
Some(arg) => {
|
Some(arg) => {
|
||||||
if arg == "@" {
|
if arg == "@" {
|
||||||
tasks.reset_key_filter()
|
tasks.reset_key_filter()
|
||||||
} else if let Some((key, name)) = tasks.find_user_with_displayname(arg) {
|
} else if let Some((key, name)) = tasks.find_user(arg) {
|
||||||
info!("Showing {}'s tasks", name);
|
info!("Showing {}'s tasks", name);
|
||||||
tasks.set_key_filter(key)
|
tasks.set_key_filter(key)
|
||||||
} else {
|
} else {
|
||||||
|
|
50
src/tasks.rs
50
src/tasks.rs
|
@ -1,3 +1,5 @@
|
||||||
|
mod nostr_users;
|
||||||
|
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
|
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::iter::{empty, once, FusedIterator};
|
use std::iter::{empty, once, FusedIterator};
|
||||||
|
@ -16,6 +18,7 @@ use log::{debug, error, info, trace, warn};
|
||||||
use nostr_sdk::{Alphabet, Event, EventBuilder, EventId, JsonUtil, Keys, Kind, Metadata, PublicKey, SingleLetterTag, Tag, TagKind, Timestamp, Url};
|
use nostr_sdk::{Alphabet, Event, EventBuilder, EventId, JsonUtil, Keys, Kind, Metadata, PublicKey, SingleLetterTag, Tag, TagKind, Timestamp, Url};
|
||||||
use regex::bytes::Regex;
|
use regex::bytes::Regex;
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
|
use crate::tasks::nostr_users::NostrUsers;
|
||||||
|
|
||||||
const DEFAULT_PRIO: Prio = 25;
|
const DEFAULT_PRIO: Prio = 25;
|
||||||
const QUICK_PRIO: Prio = 35;
|
const QUICK_PRIO: Prio = 35;
|
||||||
|
@ -54,7 +57,7 @@ pub(crate) struct TasksRelay {
|
||||||
/// History of active tasks by PubKey
|
/// History of active tasks by PubKey
|
||||||
history: HashMap<PublicKey, BTreeMap<Timestamp, Event>>,
|
history: HashMap<PublicKey, BTreeMap<Timestamp, Event>>,
|
||||||
/// Index of known users with metadata
|
/// Index of known users with metadata
|
||||||
users: HashMap<PublicKey, Metadata>,
|
users: NostrUsers,
|
||||||
/// Own pinned tasks
|
/// Own pinned tasks
|
||||||
bookmarks: Vec<EventId>,
|
bookmarks: Vec<EventId>,
|
||||||
|
|
||||||
|
@ -284,7 +287,7 @@ impl TasksRelay {
|
||||||
}
|
}
|
||||||
// TODO show history for active tags
|
// TODO show history for active tags
|
||||||
(
|
(
|
||||||
format!("Time-Tracking History for {}:", self.get_displayname(&key)),
|
format!("Time-Tracking History for {}:", self.users.get_displayname(&key)),
|
||||||
Box::from(full.into_iter()),
|
Box::from(full.into_iter()),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -308,7 +311,7 @@ impl TasksRelay {
|
||||||
"{} - {} by {}",
|
"{} - {} by {}",
|
||||||
format_timestamp_local(start),
|
format_timestamp_local(start),
|
||||||
format_timestamp_relative_to(end, start),
|
format_timestamp_relative_to(end, start),
|
||||||
self.get_displayname(key)
|
self.users.get_displayname(key)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,7 +319,7 @@ impl TasksRelay {
|
||||||
vec.push(format!(
|
vec.push(format!(
|
||||||
"{} started by {}",
|
"{} started by {}",
|
||||||
format_timestamp_local(stamp),
|
format_timestamp_local(stamp),
|
||||||
self.get_displayname(key)
|
self.users.get_displayname(key)
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
vec
|
vec
|
||||||
|
@ -393,7 +396,7 @@ impl TasksRelay {
|
||||||
Some(key) =>
|
Some(key) =>
|
||||||
if key != self.sender.pubkey() {
|
if key != self.sender.pubkey() {
|
||||||
prompt.push_str(" @");
|
prompt.push_str(" @");
|
||||||
prompt.push_str(&self.get_username(&key))
|
prompt.push_str(&self.users.get_username(&key))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for tag in self.tags.iter() {
|
for tag in self.tags.iter() {
|
||||||
|
@ -646,7 +649,7 @@ impl TasksRelay {
|
||||||
}
|
}
|
||||||
"progress" => prog_string.clone(),
|
"progress" => prog_string.clone(),
|
||||||
|
|
||||||
"author" | "creator" => format!("{:.6}", self.get_username(&task.event.pubkey)), // FIXME temporary until proper column alignment
|
"author" | "creator" => format!("{:.6}", self.users.get_username(&task.event.pubkey)), // FIXME temporary until proper column alignment
|
||||||
"prio" => self
|
"prio" => self
|
||||||
.traverse_up_from(Some(task.event.id))
|
.traverse_up_from(Some(task.event.id))
|
||||||
.find_map(Task::priority_raw)
|
.find_map(Task::priority_raw)
|
||||||
|
@ -667,35 +670,8 @@ impl TasksRelay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn find_user_with_displayname(&self, term: &str) -> Option<(PublicKey, String)> {
|
pub(super) fn find_user(&self, name: &str) -> Option<(PublicKey, String)> {
|
||||||
match PublicKey::from_str(term) {
|
self.users.find_user_with_displayname(name)
|
||||||
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)> {
|
|
||||||
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)) ||
|
|
||||||
(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 {
|
|
||||||
self.users.get(pubkey)
|
|
||||||
.and_then(|m| m.name.clone())
|
|
||||||
.unwrap_or_else(|| format!("{:.6}", pubkey.to_string()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movement and Selection
|
// Movement and Selection
|
||||||
|
@ -1161,9 +1137,7 @@ impl TasksRelay {
|
||||||
|
|
||||||
pub(crate) fn add(&mut self, event: Event) {
|
pub(crate) fn add(&mut self, event: Event) {
|
||||||
let author = event.pubkey;
|
let author = event.pubkey;
|
||||||
if !self.users.contains_key(&author) {
|
self.users.create(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()) {
|
||||||
|
|
49
src/tasks/nostr_users.rs
Normal file
49
src/tasks/nostr_users.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use nostr_sdk::{Metadata, PublicKey};
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct NostrUsers {
|
||||||
|
users: HashMap<PublicKey, Metadata>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NostrUsers {
|
||||||
|
pub(crate) fn find_user_with_displayname(&self, term: &str) -> Option<(PublicKey, String)> {
|
||||||
|
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)> {
|
||||||
|
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)) ||
|
||||||
|
(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 {
|
||||||
|
self.users.get(pubkey)
|
||||||
|
.and_then(|m| m.name.clone())
|
||||||
|
.unwrap_or_else(|| format!("{:.6}", pubkey.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn insert(&mut self, pubkey: PublicKey, metadata: Metadata) {
|
||||||
|
self.users.insert(pubkey, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn create(&mut self, pubkey: PublicKey) {
|
||||||
|
if !self.users.contains_key(&pubkey) {
|
||||||
|
self.users.insert(pubkey, Default::default());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue