diff --git a/src/app.rs b/src/app.rs index e40b8eb..5607c92 100644 --- a/src/app.rs +++ b/src/app.rs @@ -28,7 +28,7 @@ pub enum Screen { pub enum LogViewPeriod { Day, Week, - Month, + Month, // Represents the last 31 days } pub enum LogViewDayOrder { @@ -1587,17 +1587,29 @@ impl App { } fn load_log_content(&mut self) -> anyhow::Result<()> { - let flag = match self.log_view_period { - LogViewPeriod::Day => "--day", - LogViewPeriod::Week => "--week", - LogViewPeriod::Month => "--month", + let mut command = Command::new("watson"); + command.arg("log").arg("--json"); + + // Handle different period options + match self.log_view_period { + LogViewPeriod::Day => { + command.arg("--day"); + }, + LogViewPeriod::Week => { + command.arg("--week"); + }, + LogViewPeriod::Month => { + // Use --from with date 31 days ago for month view + let thirty_one_days_ago = chrono::Local::now() + .checked_sub_signed(chrono::Duration::days(31)) + .expect("Failed to calculate date from 31 days ago"); + + command.arg("--from"); + command.arg(thirty_one_days_ago.format("%Y-%m-%d").to_string()); + }, }; - let output = Command::new("watson") - .arg("log") - .arg(flag) - .arg("--json") - .output()?; + let output = command.output()?; if output.status.success() { let json_str = String::from_utf8_lossy(&output.stdout); diff --git a/src/ui.rs b/src/ui.rs index 1f71251..b56f424 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -33,10 +33,10 @@ fn render_main(frame: &mut Frame, app: &App) { let has_active_timer = app.state.active_timer.is_some(); let has_status = app.status_message.is_some(); let show_help_hint = app.config.show_help_hint; - + // Show bottom bar if we have any of: timer, status, or help hint let show_bottom_bar = has_active_timer || has_status || show_help_hint; - + let bottom_height = if show_bottom_bar { if has_status { 2 // Need extra line for status @@ -63,41 +63,41 @@ fn render_main(frame: &mut Frame, app: &App) { .borders(Borders::ALL) .title("WAT") .style(Style::default().fg(ACTIVE_COLOR)); - + let text = Paragraph::new("No sections enabled. Edit config (press 'c') to enable sections.") .block(block) .style(Style::default().fg(Color::Yellow)) .alignment(Alignment::Center); - + frame.render_widget(text, frame.size()); return; } // Build constraints for enabled sections let mut constraints = Vec::new(); - + if bottom_height > 0 { // Reserve space for bottom bar first, then split remainder among sections constraints.push(Constraint::Min(0)); // Sections get remaining space constraints.push(Constraint::Length(bottom_height)); // Bottom bar gets fixed height - + let layout = Layout::default() .direction(Direction::Vertical) .constraints(constraints) .split(frame.size()); - + // Split the top area among enabled sections let section_percentage = 100 / enabled_sections as u16; let section_constraints = vec![Constraint::Percentage(section_percentage); enabled_sections]; - + let chunks = Layout::default() .direction(Direction::Vertical) .constraints(section_constraints) .split(layout[0]); - + // Render enabled sections let mut chunk_idx = 0; - + if app.config.show_permanent { render_section( frame, @@ -145,14 +145,14 @@ fn render_main(frame: &mut Frame, app: &App) { // No bottom bar - just render sections let section_percentage = 100 / enabled_sections as u16; let constraints = vec![Constraint::Percentage(section_percentage); enabled_sections]; - + let chunks = Layout::default() .direction(Direction::Vertical) .constraints(constraints) .split(frame.size()); let mut chunk_idx = 0; - + if app.config.show_permanent { render_section( frame, @@ -679,7 +679,7 @@ fn render_log_view(frame: &mut Frame, app: &App) { let period_str = match app.log_view_period { LogViewPeriod::Day => "Day", LogViewPeriod::Week => "Week", - LogViewPeriod::Month => "Month", + LogViewPeriod::Month => "31 Days", }; let grouping_str = match app.log_view_grouping { @@ -812,14 +812,14 @@ fn render_log_view(frame: &mut Frame, app: &App) { // Third pass: render with highlighting and overlap detection let is_by_date = matches!(app.log_view_grouping, LogViewGrouping::ByDate); - + // Pre-calculate overlaps for efficiency - check consecutive entries within same day let mut overlap_entry_indices = std::collections::HashSet::new(); if is_by_date && app.log_view_frame_indices.len() > 1 { // Track which day we're in to avoid comparing across days let mut current_day_start_entry = 0; let mut in_day = false; - + for (line_idx, line) in app.log_view_content.iter().enumerate() { // New day header if !line.starts_with(" ") && !line.is_empty() && !line.starts_with(" ") { @@ -835,12 +835,12 @@ fn render_log_view(frame: &mut Frame, app: &App) { .filter(|l| l.starts_with(" ") && !l.is_empty() && l.trim() != "---") .count() .saturating_sub(1); - + // Only check overlap if not the first entry of the day if entry_idx > current_day_start_entry { let current_frame_idx = app.log_view_frame_indices[entry_idx]; let prev_frame_idx = app.log_view_frame_indices[entry_idx - 1]; - + if let (Some(current), Some(prev)) = ( app.log_view_frames.get(current_frame_idx), app.log_view_frames.get(prev_frame_idx), @@ -859,16 +859,16 @@ fn render_log_view(frame: &mut Frame, app: &App) { } } } - + app.log_view_content .iter() .enumerate() .map(|(idx, line)| { let is_selected = idx >= selected_line_start && idx <= selected_line_end; - + // Skip styling for separator lines let is_separator = line.trim() == "---"; - + // Check if this line corresponds to an overlapping entry let has_overlap = if !is_separator && is_by_date && line.starts_with(" ") && !line.is_empty() { // Count which entry this is (0-based in display order) @@ -878,7 +878,7 @@ fn render_log_view(frame: &mut Frame, app: &App) { .filter(|l| l.starts_with(" ") && !l.is_empty() && l.trim() != "---") .count() .saturating_sub(1); - + overlap_entry_indices.contains(&entry_idx) } else { false @@ -904,7 +904,7 @@ fn render_log_view(frame: &mut Frame, app: &App) { let paragraph = Paragraph::new(text_lines) .block(block) .wrap(ratatui::widgets::Wrap { trim: false }); - + frame.render_widget(paragraph, chunks[0]); // Render help hint at bottom if enabled @@ -928,7 +928,7 @@ fn render_log_view_help(frame: &mut Frame, app: &App) { "Time Periods:", "- d: Switch to Day view (current day)", "- w: Switch to Week view (current week)", - "- m: Switch to Month view (current month)", + "- m: Switch to Month view (last 31 days)", "", "Grouping:", "- g: Toggle between grouping by Date or by Project",