1mod chrome;
2mod heatmap;
3mod icons;
4mod stats;
5mod widgets;
6
7pub mod dashboard;
8pub mod help;
9pub mod popups;
10pub mod settings;
11pub mod tasks;
12pub mod zen;
13
14use dashboard::*;
15use help::*;
16use popups::*;
17use settings::*;
18use tasks::*;
19use zen::*;
20
21use chrono::Datelike;
22use ratatui::layout::{Alignment, Constraint, Direction, Layout, Rect};
23use ratatui::style::{Color, Modifier, Style};
24use ratatui::text::{Line, Span};
25use ratatui::widgets::{
26 Block, BorderType, Borders, Cell, Clear, Gauge, List, ListItem, Paragraph, Row, Table, Wrap,
27};
28use ratatui::Frame;
29
30use crate::app::{App, FocusTab, InputField, InputMode, TaskFilter};
31use crate::canvas_timer::{
32 draw_break_tip, draw_dashboard_canvas, draw_zen_canvas, format_time_stack, is_break_mode,
33 session_dots, DashboardSceneOptions, ZenSceneOptions,
34};
35use crate::model::TimerMode;
36
37pub use icons::{IconMode, IconSet};
38
39use chrome::{draw_footer, draw_header, draw_tabs};
40use stats::draw_stats;
41use widgets::{
42 active_task_spans, centered_rect, dense_panel, format_minutes, task_status_color,
43 task_status_icon, themed_panel, timer_panel, truncate,
44};
45
46pub fn render(f: &mut Frame, app: &mut App) {
47 let area = f.area();
48 f.render_widget(
49 Block::default().style(Style::default().bg(app.theme.bg)),
50 area,
51 );
52
53 if app.zen_mode && app.tab == FocusTab::Dashboard {
54 draw_zen_dashboard(f, app, area);
55 if let Some(ref popup) = app.popup {
56 draw_popup(f, app, popup);
57 }
58 return;
59 }
60
61 let footer_h = 2;
62 let chunks = Layout::default()
63 .direction(Direction::Vertical)
64 .constraints([
65 Constraint::Length(2),
66 Constraint::Length(2),
67 Constraint::Min(6),
68 Constraint::Length(footer_h),
69 ])
70 .split(area);
71
72 draw_header(f, app, chunks[0]);
73 draw_tabs(f, app, chunks[1]);
74
75 match app.tab {
76 FocusTab::Dashboard => draw_dashboard(f, app, chunks[2]),
77 FocusTab::Tasks => draw_tasks(f, app, chunks[2]),
78 FocusTab::Stats => draw_stats(f, app, chunks[2]),
79 FocusTab::Settings => draw_settings(f, app, chunks[2]),
80 FocusTab::Help => draw_help(f, app, chunks[2]),
81 }
82
83 draw_footer(f, app, chunks[3]);
84
85 if let Some(ref popup) = app.popup {
86 draw_popup(f, app, popup);
87 }
88 if matches!(app.input_mode, InputMode::Editing)
89 && !matches!(
90 app.popup.as_ref(),
91 Some(crate::app::Popup::AddTask) | Some(crate::app::Popup::EditTask(_))
92 )
93 {
94 draw_input(f, app, chunks[2]);
95 }
96}