Skip to main content

void/ui/
mod.rs

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(popup) = app.popup.clone() {
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(popup) = app.popup.clone() {
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)
92                | Some(crate::app::Popup::EditTask(_))
93                | Some(crate::app::Popup::AddSubtask(_))
94        )
95    {
96        draw_input(f, app, chunks[2]);
97    }
98}