Compare commits
No commits in common. "1b0f7dca097e906f9ac604a134a02c21486441b1" and "721c200b97d008bc999d7e08f0e6a4f2d9b5fd94" have entirely different histories.
1b0f7dca09
...
721c200b97
17
src/kinds.rs
17
src/kinds.rs
|
@ -3,18 +3,16 @@ use log::info;
|
|||
use nostr_sdk::{Alphabet, EventBuilder, EventId, Kind, Tag, TagStandard};
|
||||
use nostr_sdk::TagStandard::Hashtag;
|
||||
|
||||
use crate::task::{MARKER_PARENT, State};
|
||||
use crate::task::State;
|
||||
|
||||
pub const METADATA_KIND: u16 = 0;
|
||||
pub const NOTE_KIND: u16 = 1;
|
||||
pub const TASK_KIND: u16 = 1621;
|
||||
pub const TRACKING_KIND: u16 = 1650;
|
||||
pub const KINDS: [u16; 3] = [
|
||||
pub const KINDS: [u16; 9] = [
|
||||
METADATA_KIND,
|
||||
NOTE_KIND,
|
||||
TASK_KIND,
|
||||
];
|
||||
pub const PROP_KINDS: [u16; 6] = [
|
||||
TRACKING_KIND,
|
||||
State::Open as u16,
|
||||
State::Done as u16,
|
||||
|
@ -32,7 +30,7 @@ Immutable:
|
|||
- `parentid` - unique task id of the parent, if any
|
||||
- `name` - initial name of the task
|
||||
- `created` - task creation timestamp
|
||||
- `author` - name or abbreviated key of the task creator
|
||||
- `author` - name of the task creator
|
||||
Task:
|
||||
- `status` - pure task status
|
||||
- `hashtags` - list of hashtags set for the task
|
||||
|
@ -100,16 +98,13 @@ fn format_tag(tag: &Tag) -> String {
|
|||
match tag.as_standardized() {
|
||||
Some(TagStandard::Event {
|
||||
event_id,
|
||||
marker,
|
||||
..
|
||||
}) => format!("{}: {:.8}", marker.as_ref().map(|m| m.to_string()).unwrap_or(MARKER_PARENT.to_string()), event_id),
|
||||
}) => format!("Parent: {}", event_id.to_string()[..8].to_string()),
|
||||
Some(TagStandard::PublicKey {
|
||||
public_key,
|
||||
alias,
|
||||
..
|
||||
}) => format!("Key{}: {:.8}", public_key.to_string(), alias.as_ref().map(|s| format!(" {s}")).unwrap_or_default()),
|
||||
Some(TagStandard::Hashtag(content)) =>
|
||||
format!("#{content}"),
|
||||
}) => format!("Key: {}", public_key.to_string()[..8].to_string()),
|
||||
Some(TagStandard::Hashtag(content)) => format!("#{content}"),
|
||||
_ => tag.content().map_or_else(
|
||||
|| format!("Kind {}", tag.kind()),
|
||||
|content| content.to_string(),
|
||||
|
|
27
src/main.rs
27
src/main.rs
|
@ -23,7 +23,7 @@ use regex::Regex;
|
|||
use xdg::BaseDirectories;
|
||||
|
||||
use crate::helpers::*;
|
||||
use crate::kinds::{KINDS, PROP_KINDS, PROPERTY_COLUMNS, TRACKING_KIND};
|
||||
use crate::kinds::{KINDS, PROPERTY_COLUMNS, TRACKING_KIND};
|
||||
use crate::task::{MARKER_DEPENDS, MARKER_PARENT, State};
|
||||
use crate::tasks::{PropertyCollection, StateFilter, Tasks};
|
||||
|
||||
|
@ -180,19 +180,14 @@ async fn main() {
|
|||
},
|
||||
}
|
||||
|
||||
let sub1 = client.subscribe(vec![
|
||||
let sub_id = client.subscribe(vec![
|
||||
Filter::new().kinds(KINDS.into_iter().map(|k| Kind::from(k)))
|
||||
], None).await;
|
||||
info!("Subscribed to tasks with {:?}", sub1);
|
||||
info!("Subscribed with {:?}", sub_id);
|
||||
|
||||
let mut notifications = client.notifications();
|
||||
client.connect().await;
|
||||
|
||||
let sub2 = client.subscribe(vec![
|
||||
Filter::new().kinds(PROP_KINDS.into_iter().map(|k| Kind::from(k)))
|
||||
], None).await;
|
||||
info!("Subscribed to updates with {:?}", sub2);
|
||||
|
||||
let (tx, rx) = mpsc::channel::<MostrMessage>();
|
||||
let tasks_for_url = |url: Option<Url>| Tasks::from(url, &tx, &keys);
|
||||
let mut relays: HashMap<Url, Tasks> =
|
||||
|
@ -379,12 +374,11 @@ async fn main() {
|
|||
}
|
||||
|
||||
Some('@') => {
|
||||
let key = arg.and_then(|a| PublicKey::from_str(a).ok()).unwrap_or_else(|| keys.public_key());
|
||||
let author = tasks.get_author(&key);
|
||||
let author = arg.and_then(|a| PublicKey::from_str(a).ok()).unwrap_or_else(|| keys.public_key());
|
||||
info!("Filtering for events by {author}");
|
||||
tasks.set_filter(
|
||||
tasks.filtered_tasks(tasks.get_position_ref())
|
||||
.filter(|t| t.event.pubkey == key)
|
||||
.filter(|t| t.event.pubkey == author)
|
||||
.map(|t| t.event.id)
|
||||
.collect()
|
||||
)
|
||||
|
@ -473,13 +467,10 @@ async fn main() {
|
|||
}
|
||||
|
||||
Some(')') => {
|
||||
match arg {
|
||||
None => tasks.move_to(None),
|
||||
Some(arg) => {
|
||||
if parse_tracking_stamp(arg).map(|stamp| tasks.track_at(stamp, None)).is_none() {
|
||||
// So the error message is not covered up
|
||||
continue
|
||||
}
|
||||
tasks.move_to(None);
|
||||
if let Some(arg) = arg {
|
||||
if !tasks.track_from(arg) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
36
src/tasks.rs
36
src/tasks.rs
|
@ -119,21 +119,19 @@ impl Tasks {
|
|||
tasks: Default::default(),
|
||||
history: Default::default(),
|
||||
users: Default::default(),
|
||||
properties: [
|
||||
"author",
|
||||
"state",
|
||||
"rtime",
|
||||
"hashtags",
|
||||
"rpath",
|
||||
"desc",
|
||||
].into_iter().map(|s| s.to_string()).collect(),
|
||||
sorting: [
|
||||
"author",
|
||||
"state",
|
||||
"hashtags",
|
||||
"rtime",
|
||||
"name",
|
||||
].into_iter().map(|s| s.to_string()).collect(),
|
||||
properties: vec![
|
||||
"state".into(),
|
||||
"rtime".into(),
|
||||
"hashtags".into(),
|
||||
"rpath".into(),
|
||||
"desc".into(),
|
||||
],
|
||||
sorting: VecDeque::from([
|
||||
"state".into(),
|
||||
"hashtags".into(),
|
||||
"rtime".into(),
|
||||
"name".into(),
|
||||
]),
|
||||
view: Default::default(),
|
||||
tags: Default::default(),
|
||||
tags_excluded: Default::default(),
|
||||
|
@ -214,11 +212,11 @@ impl Tasks {
|
|||
} else {
|
||||
format_stamp(end, "%H:%M")
|
||||
},
|
||||
self.get_author(key)))
|
||||
key))
|
||||
}
|
||||
iter.into_buffer()
|
||||
.for_each(|(stamp, _)|
|
||||
vec.push(format!("{} started by {}", local_datetimestamp(stamp), self.get_author(key))));
|
||||
vec.push(format!("{} started by {}", local_datetimestamp(stamp), key)));
|
||||
vec
|
||||
}).sorted_unstable(); // TODO sorting depends on timestamp format - needed to interleave different people
|
||||
(format!("Times Tracked on {:?}", self.get_task_title(&id)), Box::from(history))
|
||||
|
@ -427,7 +425,7 @@ impl Tasks {
|
|||
writeln!(lock, "{}\n{}", label.italic(), times_recent.join("\n"))?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
// TODO proper column alignment
|
||||
// TODO hide empty columns
|
||||
writeln!(lock, "{}", self.properties.join("\t").bold())?;
|
||||
|
@ -504,7 +502,7 @@ impl Tasks {
|
|||
pub(crate) fn get_author(&self, pubkey: &PublicKey) -> String {
|
||||
self.users.get(pubkey)
|
||||
.and_then(|m| m.name.clone())
|
||||
.unwrap_or_else(|| format!("{:.6}", pubkey.to_string()))
|
||||
.unwrap_or_else(|| pubkey.to_string())
|
||||
}
|
||||
|
||||
// Movement and Selection
|
||||
|
|
Loading…
Reference in New Issue