Visual indicators for skips and overlaps, fix bottom bar

This commit is contained in:
Ian Keane 2025-11-25 19:32:28 -05:00
parent 31049a53dd
commit c61e66b1f6
3 changed files with 253 additions and 83 deletions

View file

@ -7,11 +7,11 @@ use std::process::Command;
#[derive(Debug, Deserialize, Clone)]
pub(crate) struct WatsonFrame {
id: String,
project: String,
start: String,
stop: String,
tags: Vec<String>,
pub id: String,
pub project: String,
pub start: String,
pub stop: String,
pub tags: Vec<String>,
}
pub enum Screen {
@ -80,6 +80,11 @@ pub enum NewEntryMode {
impl App {
// Helper to determine if a line is an entry line based on grouping mode
fn is_entry_line(&self, line: &str) -> bool {
// Exclude separator lines (time gap markers)
if line.trim() == "---" {
return false;
}
match self.log_view_grouping {
LogViewGrouping::ByProject => line.starts_with("\t\t"),
LogViewGrouping::ByDate => line.starts_with('\t') && !line.starts_with("\t\t"),
@ -606,7 +611,9 @@ impl App {
for (_sort_key, (display_date, frames)) in dates {
lines.push(display_date.clone());
for (idx, frame) in frames {
let mut prev_stop: Option<DateTime<Local>> = None;
for (frame_idx, (idx, frame)) in frames.iter().enumerate() {
if let (Ok(start_dt), Ok(stop_dt)) = (
DateTime::parse_from_rfc3339(&frame.start),
DateTime::parse_from_rfc3339(&frame.stop),
@ -614,20 +621,35 @@ impl App {
let start_local: DateTime<Local> = start_dt.into();
let stop_local: DateTime<Local> = stop_dt.into();
// Check for time gap and add separator line if enabled
if self.config.show_time_gaps && frame_idx > 0 {
if let Some(prev) = prev_stop {
let gap = start_local.signed_duration_since(prev);
if gap.num_minutes() >= 5 {
lines.push("\t ---".to_string());
// Note: don't add to frame_indices - separator is not an entry
}
}
}
let start_time = format!("{:02}:{:02}", start_local.hour(), start_local.minute());
let stop_time = format!("{:02}:{:02}", stop_local.hour(), stop_local.minute());
let tags_str = if frame.tags.is_empty() {
String::new()
let display_text = if frame.tags.is_empty() {
frame.project.clone()
} else {
format!(" [{}]", frame.tags.join(", "))
format!("{} [{}]", frame.tags.join(", "), frame.project)
};
lines.push(format!(
"\t{} to {} {}{}",
start_time, stop_time, frame.project, tags_str
));
frame_indices.push(*idx);
let line_text = format!(
"\t{} to {} {}",
start_time, stop_time, display_text
);
lines.push(line_text);
frame_indices.push(*idx); // Only add actual entries to frame_indices
prev_stop = Some(stop_local);
}
}
lines.push(String::new()); // Empty line between dates