1use ratatui::{
2 buffer::Buffer,
3 layout::Rect,
4 style::{Color, Style, Stylize},
5 text::Text,
6 widgets::{Row, Table, Widget},
7};
8
9use crate::util::{Mode, colors::color_config, keys::KEY_CONFIG};
10
11#[derive(Debug, Clone, Copy, Default)]
12pub struct HelpBox {
13 mode: Mode,
14 expanded: bool,
15}
16
17impl HelpBox {
18 pub fn close(&mut self) {
19 self.expanded = false;
20 }
21
22 pub fn toggle(&mut self) {
23 self.expanded = !self.expanded;
24 }
25
26 pub fn set_mode(&mut self, mode: Mode) {
27 self.mode = mode;
28 }
29
30 #[must_use]
31 pub fn expanded(&self) -> bool {
32 self.expanded
33 }
34}
35
36impl Widget for HelpBox {
37 fn render(self, area: Rect, buf: &mut Buffer)
38 where
39 Self: Sized,
40 {
41 match self.mode {
42 Mode::View => render_markdown_help(self.expanded, area, buf),
43 Mode::FileTree => render_file_tree_help(self.expanded, area, buf),
44 }
45 }
46}
47
48fn render_file_tree_help(expanded: bool, area: Rect, buf: &mut Buffer) {
49 if !expanded {
50 let text = Text::styled("? - Help", Style::default().fg(Color::LightGreen).bold());
51 text.render(area, buf);
52 return;
53 }
54
55 let header = Row::new(vec!["Key", "Action"]);
56
57 let key_actions = [
58 Row::new(vec![
59 format!("{} or \u{2193}", KEY_CONFIG.down),
60 "Move down".to_string(),
61 ]),
62 Row::new(vec![
63 format!("{} or \u{2191}", KEY_CONFIG.up),
64 "Move up".to_string(),
65 ]),
66 Row::new(vec![
67 format!("{} or \u{2190}", KEY_CONFIG.page_up),
68 "Go to previous page".to_string(),
69 ]),
70 Row::new(vec![
71 format!("{} or \u{2192}", KEY_CONFIG.page_down),
72 "Go to next page".to_string(),
73 ]),
74 Row::new(vec![
75 format!("{}", KEY_CONFIG.top),
76 "Move to first file".to_string(),
77 ]),
78 Row::new(vec![
79 format!("{}", KEY_CONFIG.bottom),
80 "Move to last file".to_string(),
81 ]),
82 Row::new(vec![
83 format!("/ or {}", KEY_CONFIG.search),
84 "Search".to_string(),
85 ]),
86 Row::new(vec!["\u{21b5}", "Open file"]),
87 Row::new(vec!["q", "Quit"]),
88 ];
89
90 let widths = [12, 20];
91
92 let table =
93 Table::new(key_actions, widths).header(header.fg(color_config().table_header_fg_color));
94 table.render(area, buf);
95}
96
97fn render_markdown_help(expandend: bool, area: Rect, buf: &mut Buffer) {
98 if !expandend {
99 let text = Text::styled("? - Help", Style::default().fg(Color::LightGreen).bold());
100 text.render(area, buf);
101 return;
102 }
103
104 let header = Row::new(vec!["Key", "Action"]);
105
106 let key_actions = [
107 Row::new(vec![
108 format!("{} or \u{2193}", KEY_CONFIG.down),
109 "Move down".to_string(),
110 ]),
111 Row::new(vec![
112 format!("{} or \u{2191}", KEY_CONFIG.up),
113 "Move up".to_string(),
114 ]),
115 Row::new(vec![
116 format!("{}", KEY_CONFIG.half_page_down),
117 "Move half page down".to_string(),
118 ]),
119 Row::new(vec![
120 format!("{}", KEY_CONFIG.half_page_up),
121 "Move half page up".to_string(),
122 ]),
123 Row::new(vec![
124 format!("{} or \u{2192}", KEY_CONFIG.page_down),
125 "Move full page down".to_string(),
126 ]),
127 Row::new(vec![
128 format!("{} or \u{2190}", KEY_CONFIG.page_up),
129 "Move full page up".to_string(),
130 ]),
131 Row::new(vec![
132 format!("{}", KEY_CONFIG.bottom),
133 "Move to bottom".to_string(),
134 ]),
135 Row::new(vec![
136 format!("{}", KEY_CONFIG.top),
137 "Move to top".to_string(),
138 ]),
139 Row::new(vec![
140 format!("/ or {}", KEY_CONFIG.search),
141 "Search".to_string(),
142 ]),
143 Row::new(vec![
144 format!("{}", KEY_CONFIG.back),
145 "Go back to previous file".to_string(),
146 ]),
147 Row::new(vec![
148 format!("{}", KEY_CONFIG.file_tree),
149 "To file tree".to_string(),
150 ]),
151 Row::new(vec![
152 format!("{}", KEY_CONFIG.select_link),
153 "Enter select mode".to_string(),
154 ]),
155 Row::new(vec!["\u{21b5}", "Open link/file"]),
156 Row::new(vec![
157 format!("{}", KEY_CONFIG.edit),
158 "Edit file".to_string(),
159 ]),
160 Row::new(vec!["q", "Quit"]),
161 ];
162
163 let widths = [12, 25];
164
165 let table =
166 Table::new(key_actions, widths).header(header.fg(color_config().table_header_fg_color));
167
168 table.render(area, buf);
169}