Skip to main content

void/ui/
help.rs

1use super::*;
2
3pub(crate) fn draw_help(f: &mut Frame, app: &App, area: Rect) {
4    let theme = &app.theme;
5    let text = vec![
6        Line::from(Span::styled(
7            "Void - keyboard shortcuts",
8            Style::default()
9                .fg(theme.accent)
10                .add_modifier(Modifier::BOLD),
11        )),
12        Line::from(""),
13        Line::from(Span::styled("Global", Style::default().fg(theme.accent))),
14        Line::from("  Tab / 1-5   Switch tab (Dashboard, Tasks, Stats, Settings, Help)"),
15        Line::from("  q / Esc     Quit (auto-saves)"),
16        Line::from("  Ctrl-S      Export JSON backup"),
17        Line::from(""),
18        Line::from(Span::styled("Timer", Style::default().fg(theme.accent))),
19        Line::from("  s / Space   Start / resume timer"),
20        Line::from("  p           Pause timer"),
21        Line::from("  r           Reset timer"),
22        Line::from("  n           Skip (logs elapsed; does not advance pomodoro cycle)"),
23        Line::from("  E           End session (pause + summary)"),
24        Line::from("  m           Cycle mode (Focus / Short / Long / Custom)"),
25        Line::from("  + / =       Increase duration by 1 min"),
26        Line::from("  -           Decrease duration by 1 min"),
27        Line::from("  z           Toggle zen mode (distraction-free timer)"),
28        Line::from("  Enter       Cycle active task status (Todo → Active → Done)"),
29        Line::from("  x           Mark active task done"),
30        Line::from(""),
31        Line::from(Span::styled("Pomodoro", Style::default().fg(theme.accent))),
32        Line::from("  Cycle position persists across restarts"),
33        Line::from("  After focus, auto-switches to break (enable auto-start in Settings)"),
34        Line::from("  Long break every N focus sessions (configurable)"),
35        Line::from("  All tasks done → free focus, pause, or prompt (Settings)"),
36        Line::from(""),
37        Line::from(Span::styled("Stats", Style::default().fg(theme.accent))),
38        Line::from("  j / k       Select recent session"),
39        Line::from("  d           Delete selected session"),
40        Line::from("  + / -       Adjust session minutes"),
41        Line::from("  E           End session"),
42        Line::from(""),
43        Line::from(Span::styled("Tasks", Style::default().fg(theme.accent))),
44        Line::from("  a           Add task (title, notes, estimate, due, tags)"),
45        Line::from("  e           Edit selected task"),
46        Line::from("  d           Delete selected task (with confirmation)"),
47        Line::from("  Enter       Cycle status: Pending → In Progress → Done"),
48        Line::from("  Space       Set as active task for timer"),
49        Line::from("  f           Start focus on selected task"),
50        Line::from("  t           Toggle today-queue flag"),
51        Line::from("  g           Cycle filter (All / Open / Done / Today)"),
52        Line::from("  /           Search tasks by title, notes, or tags"),
53        Line::from("  1 / 2 / 3   Set priority Low / Med / High"),
54        Line::from("  j / k       Navigate list"),
55        Line::from("  Ctrl+j/k    Reorder task in queue"),
56        Line::from(""),
57        Line::from(Span::styled("Settings", Style::default().fg(theme.accent))),
58        Line::from("  Up / Down   Navigate"),
59        Line::from("  Enter / +-  Increment value"),
60        Line::from("  Left / -    Decrement value"),
61        Line::from("  Theme       Cycle Dark / Light / Polaris / Matrix in Settings"),
62        Line::from(""),
63        Line::from(Span::styled("Data", Style::default().fg(theme.accent))),
64        Line::from("  Data persists locally in SQLite (~/.local/share/void/)."),
65        Line::from("  Ctrl-S or Settings exports a JSON backup."),
66        Line::from("  Void never sends your tasks anywhere — fully offline."),
67    ];
68    let block = Block::default()
69        .title(Span::styled(
70            format!(" {} Help ", app.icons.help),
71            Style::default().fg(theme.accent),
72        ))
73        .borders(Borders::ALL)
74        .border_type(BorderType::Rounded)
75        .border_style(Style::default().fg(theme.dim));
76    f.render_widget(
77        Paragraph::new(text).block(block).wrap(Wrap { trim: false }),
78        area,
79    );
80}