forked from janek/mostr
feat: show named task authors
This commit is contained in:
parent
d88cae4273
commit
86654c8348
10
src/kinds.rs
10
src/kinds.rs
|
@ -2,10 +2,18 @@ use itertools::Itertools;
|
||||||
use log::info;
|
use log::info;
|
||||||
use nostr_sdk::{Alphabet, EventBuilder, EventId, Kind, Tag, TagStandard};
|
use nostr_sdk::{Alphabet, EventBuilder, EventId, Kind, Tag, TagStandard};
|
||||||
|
|
||||||
|
pub const METADATA_KIND: u16 = 0;
|
||||||
|
pub const NOTE_KIND: u16 = 1;
|
||||||
pub const TASK_KIND: u16 = 1621;
|
pub const TASK_KIND: u16 = 1621;
|
||||||
pub const PROCEDURE_KIND: u16 = 1639;
|
pub const PROCEDURE_KIND: u16 = 1639;
|
||||||
pub const TRACKING_KIND: u16 = 1650;
|
pub const TRACKING_KIND: u16 = 1650;
|
||||||
pub const KINDS: [u16; 8] = [1, TASK_KIND, TRACKING_KIND, PROCEDURE_KIND, 1630, 1631, 1632, 1633];
|
pub const KINDS: [u16; 9] = [
|
||||||
|
METADATA_KIND,
|
||||||
|
NOTE_KIND,
|
||||||
|
TASK_KIND,
|
||||||
|
TRACKING_KIND,
|
||||||
|
PROCEDURE_KIND,
|
||||||
|
1630, 1631, 1632, 1633];
|
||||||
|
|
||||||
pub const PROPERTY_COLUMNS: &str = "Available properties:
|
pub const PROPERTY_COLUMNS: &str = "Available properties:
|
||||||
- `id`
|
- `id`
|
||||||
|
|
29
src/main.rs
29
src/main.rs
|
@ -180,21 +180,11 @@ async fn main() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
let sub_id = client.subscribe(vec![Filter::new().kinds(KINDS.into_iter().map(|k| Kind::from(k)))], None).await;
|
let sub_id = client.subscribe(vec![
|
||||||
|
Filter::new().kinds(KINDS.into_iter().map(|k| Kind::from(k)))
|
||||||
|
], None).await;
|
||||||
info!("Subscribed with {:?}", sub_id);
|
info!("Subscribed with {:?}", sub_id);
|
||||||
|
|
||||||
// TODO user data from config file or home relay?
|
|
||||||
//let metadata = Metadata::new()
|
|
||||||
// .name("username")
|
|
||||||
// .display_name("My Username")
|
|
||||||
// .about("Description")
|
|
||||||
// .picture(Url::parse("https://example.com/avatar.png")?)
|
|
||||||
// .banner(Url::parse("https://example.com/banner.png")?)
|
|
||||||
// .nip05("username@example.com")
|
|
||||||
// .lud16("yuki@getalby.com")
|
|
||||||
// .custom_field("custom_field", "my value");
|
|
||||||
//client.set_metadata(&metadata).await?;
|
|
||||||
|
|
||||||
let mut notifications = client.notifications();
|
let mut notifications = client.notifications();
|
||||||
client.connect().await;
|
client.connect().await;
|
||||||
|
|
||||||
|
@ -207,6 +197,19 @@ async fn main() {
|
||||||
let mut queue: Option<(Url, Vec<Event>)> = None;
|
let mut queue: Option<(Url, Vec<Event>)> = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
if let Ok(user) = var("USER") {
|
||||||
|
let metadata = Metadata::new()
|
||||||
|
.name(user);
|
||||||
|
// .display_name("My Username")
|
||||||
|
// .about("Description")
|
||||||
|
// .picture(Url::parse("https://example.com/avatar.png")?)
|
||||||
|
// .banner(Url::parse("https://example.com/banner.png")?)
|
||||||
|
// .nip05("username@example.com")
|
||||||
|
// .lud16("yuki@getalby.com")
|
||||||
|
// .custom_field("custom_field", "my value");
|
||||||
|
or_print(client.set_metadata(&metadata).await);
|
||||||
|
}
|
||||||
|
|
||||||
let result_received = rx.recv_timeout(Duration::from_secs(INACTVITY_DELAY));
|
let result_received = rx.recv_timeout(Duration::from_secs(INACTVITY_DELAY));
|
||||||
match result_received {
|
match result_received {
|
||||||
Ok(MostrMessage::NewRelay(url)) => {
|
Ok(MostrMessage::NewRelay(url)) => {
|
||||||
|
|
28
src/tasks.rs
28
src/tasks.rs
|
@ -11,7 +11,7 @@ use chrono::Local;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
use nostr_sdk::{Event, EventBuilder, EventId, Keys, Kind, PublicKey, Tag, TagStandard, Timestamp, UncheckedUrl, Url};
|
use nostr_sdk::{Event, EventBuilder, EventId, JsonUtil, Keys, Kind, Metadata, PublicKey, Tag, TagStandard, Timestamp, UncheckedUrl, Url};
|
||||||
use nostr_sdk::prelude::Marker;
|
use nostr_sdk::prelude::Marker;
|
||||||
use TagStandard::Hashtag;
|
use TagStandard::Hashtag;
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ pub(crate) struct Tasks {
|
||||||
tasks: TaskMap,
|
tasks: TaskMap,
|
||||||
/// History of active tasks by PubKey
|
/// History of active tasks by PubKey
|
||||||
history: HashMap<PublicKey, BTreeSet<Event>>,
|
history: HashMap<PublicKey, BTreeSet<Event>>,
|
||||||
|
/// Index of found users with metadata
|
||||||
|
users: HashMap<PublicKey, Metadata>,
|
||||||
|
|
||||||
/// The task properties currently visible
|
/// The task properties currently visible
|
||||||
properties: Vec<String>,
|
properties: Vec<String>,
|
||||||
|
@ -118,6 +120,7 @@ impl Tasks {
|
||||||
Tasks {
|
Tasks {
|
||||||
tasks: Default::default(),
|
tasks: Default::default(),
|
||||||
history: Default::default(),
|
history: Default::default(),
|
||||||
|
users: Default::default(),
|
||||||
properties: vec![
|
properties: vec![
|
||||||
"state".into(),
|
"state".into(),
|
||||||
"rtime".into(),
|
"rtime".into(),
|
||||||
|
@ -329,12 +332,19 @@ impl Tasks {
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn referenced_tasks<F: Fn(&mut Task)>(&mut self, event: &Event, f: F) {
|
/// Executes the given function with each task referenced by this event.
|
||||||
|
/// Returns true if any task was found.
|
||||||
|
pub(crate) fn referenced_tasks<F: Fn(&mut Task)>(&mut self, event: &Event, f: F) -> bool {
|
||||||
|
let mut found = false;
|
||||||
for tag in event.tags.iter() {
|
for tag in event.tags.iter() {
|
||||||
if let Some(TagStandard::Event { event_id, .. }) = tag.as_standardized() {
|
if let Some(TagStandard::Event { event_id, .. }) = tag.as_standardized() {
|
||||||
self.tasks.get_mut(event_id).map(|t| f(t));
|
self.tasks.get_mut(event_id).map(|t| {
|
||||||
|
found = true;
|
||||||
|
f(t)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
found
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -462,6 +472,7 @@ impl Tasks {
|
||||||
state.get_colored_label()
|
state.get_colored_label()
|
||||||
}.to_string()
|
}.to_string()
|
||||||
}
|
}
|
||||||
|
"author" => self.get_author(&task.event.pubkey),
|
||||||
"progress" => prog_string.clone(),
|
"progress" => prog_string.clone(),
|
||||||
"path" => self.get_task_path(Some(task.event.id)),
|
"path" => self.get_task_path(Some(task.event.id)),
|
||||||
"rpath" => self.relative_path(task.event.id),
|
"rpath" => self.relative_path(task.event.id),
|
||||||
|
@ -472,6 +483,12 @@ impl Tasks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_author(&self, pubkey: &PublicKey) -> String {
|
||||||
|
self.users.get(pubkey)
|
||||||
|
.and_then(|m| m.name.clone())
|
||||||
|
.unwrap_or_else(|| pubkey.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
// Movement and Selection
|
// Movement and Selection
|
||||||
|
|
||||||
pub(crate) fn set_filter(&mut self, view: Vec<EventId>) {
|
pub(crate) fn set_filter(&mut self, view: Vec<EventId>) {
|
||||||
|
@ -760,6 +777,11 @@ impl Tasks {
|
||||||
Some(c) => { c.insert(event); }
|
Some(c) => { c.insert(event); }
|
||||||
None => { self.history.insert(event.pubkey, BTreeSet::from([event])); }
|
None => { self.history.insert(event.pubkey, BTreeSet::from([event])); }
|
||||||
},
|
},
|
||||||
|
METADATA_KIND =>
|
||||||
|
match Metadata::from_json(event.content()) {
|
||||||
|
Ok(metadata) => { self.users.insert(event.pubkey, metadata); }
|
||||||
|
Err(e) => warn!("Cannot parse metadata: {} from {:?}", e, event)
|
||||||
|
}
|
||||||
_ => self.add_prop(&event),
|
_ => self.add_prop(&event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue