feat: format visible time tracking history

This commit is contained in:
xeruf 2024-08-19 11:27:12 +03:00
parent f8375cf879
commit 416a7f195d
2 changed files with 18 additions and 19 deletions

View File

@ -455,11 +455,14 @@ async fn main() {
Some('(') => { Some('(') => {
if let Some(arg) = arg { if let Some(arg) = arg {
if !tasks.track_from(arg) { if tasks.track_from(arg) {
continue; let (prefix, tracked) = tasks.times_tracked();
println!("{}\n{}", prefix.bold(), tracked.rev().take(15).join("\n"));
} }
} else {
let (prefix, mut tracked) = tasks.times_tracked();
println!("{}\n{}", prefix.bold(), tracked.join("\n"));
} }
println!("{}", tasks.times_tracked());
continue; continue;
} }

View File

@ -172,32 +172,28 @@ impl Tasks {
} }
/// Dynamic time tracking overview for current task or current user. /// Dynamic time tracking overview for current task or current user.
pub(crate) fn times_tracked(&self) -> String { pub(crate) fn times_tracked(&self) -> (String, Box<dyn DoubleEndedIterator<Item=String>>) {
match self.get_position() { match self.get_position() {
None => { None => {
let hist = self.history.get(&self.sender.pubkey()); if let Some(set) = self.history.get(&self.sender.pubkey()) {
if let Some(set) = hist { let mut full = Vec::with_capacity(set.len());
let mut full = String::with_capacity(set.len() * 40);
let mut last: Option<String> = None;
full.push_str("Your Time Tracking History:\n");
for event in set { for event in set {
let new = some_non_empty(&event.tags.iter() let new = some_non_empty(&event.tags.iter()
.filter_map(|t| t.content()) .filter_map(|t| t.content())
.map(|str| EventId::from_str(str).ok().map_or(str.to_string(), |id| self.get_task_title(&id))) .map(|str| EventId::from_str(str).ok().map_or(str.to_string(), |id| self.get_task_title(&id)))
.join(" ")); .join(" "));
if new != last { if new.as_ref() != full.last() {
full.push_str(&format!("{:>15} {}\n", relative_datetimestamp(&event.created_at), new.as_ref().unwrap_or(&"---".to_string()))); full.push(format!("{:>15} {}", relative_datetimestamp(&event.created_at), new.as_ref().unwrap_or(&"---".to_string())));
last = new;
} }
} }
full ("Your Time Tracking History:".to_string(), Box::from(full.into_iter()))
} else { } else {
String::from("You have nothing tracked yet") ("You have nothing tracked yet".to_string(), Box::from(empty()))
} }
} }
Some(id) => { Some(id) => {
let ids = vec![&id]; let ids = vec![&id];
once(format!("Times tracked on {}", self.get_task_title(&id))).chain( let history =
self.history.iter().flat_map(|(key, set)| { self.history.iter().flat_map(|(key, set)| {
let mut vec = Vec::with_capacity(set.len() / 2); let mut vec = Vec::with_capacity(set.len() / 2);
let mut iter = timestamps(set.iter(), &ids).tuples(); let mut iter = timestamps(set.iter(), &ids).tuples();
@ -205,7 +201,7 @@ impl Tasks {
vec.push(format!("{} - {} by {}", vec.push(format!("{} - {} by {}",
local_datetimestamp(start), local_datetimestamp(start),
// Only use full stamp when ambiguous (>1day) // Only use full stamp when ambiguous (>1day)
if end.as_u64() - start.as_u64() > 86400 { if end.as_u64() - start.as_u64() > 80_000 {
local_datetimestamp(end) local_datetimestamp(end)
} else { } else {
format_stamp(end, "%H:%M") format_stamp(end, "%H:%M")
@ -216,8 +212,8 @@ impl Tasks {
.for_each(|(stamp, _)| .for_each(|(stamp, _)|
vec.push(format!("{} started by {}", local_datetimestamp(stamp), key))); vec.push(format!("{} started by {}", local_datetimestamp(stamp), key)));
vec vec
}).sorted_unstable() // TODO sorting depends on timestamp format - needed to interleave different people }).sorted_unstable(); // TODO sorting depends on timestamp format - needed to interleave different people
).join("\n") (format!("Times tracked on {}", self.get_task_title(&id)), Box::from(history))
} }
} }
} }
@ -722,7 +718,7 @@ impl Tasks {
info!("{} from {}", self.position.map_or(String::from("Stopping time-tracking"), |id| format!("Tracking \"{}\"", self.get_task_title(&id))), relative_datetimestamp(&time)); info!("{} from {}", self.position.map_or(String::from("Stopping time-tracking"), |id| format!("Tracking \"{}\"", self.get_task_title(&id))), relative_datetimestamp(&time));
let pos = self.get_position(); let pos = self.get_position();
let tracking = build_tracking(pos); let tracking = build_tracking(pos);
// TODO this can lead to funny deletions // TODO this can lead to funny omittals
self.get_own_history().map(|events| { self.get_own_history().map(|events| {
if let Some(event) = events.pop_last() { if let Some(event) = events.pop_last() {
if event.kind.as_u16() == TRACKING_KIND && if event.kind.as_u16() == TRACKING_KIND &&