1use ratatui::buffer::Buffer;
7use ratatui::layout::{Alignment, Constraint, Direction, Layout, Rect};
8use ratatui::style::{Modifier, Style};
9use ratatui::text::{Line, Span};
10use ratatui::widgets::{Paragraph, Widget};
11
12use crate::app::App;
13use crate::triptych::Pane;
14
15pub fn draw(f: &mut ratatui::Frame<'_>, area: Rect, app: &App) {
16 Statusline { app }.render(area, f.buffer_mut());
17}
18
19pub struct Statusline<'a> {
20 pub app: &'a App,
21}
22
23impl Widget for Statusline<'_> {
24 fn render(self, area: Rect, buf: &mut Buffer) {
25 let muted = Style::default().fg(self.app.capabilities.muted());
26 let tab_hint = Span::styled(
33 "Tab cycle panes",
34 Style::default()
35 .fg(self.app.capabilities.accent())
36 .add_modifier(Modifier::BOLD),
37 );
38 let sep = Span::styled(" · ", muted);
39
40 let contextual = match self.app.focused_pane {
41 Pane::Roster => "/ search · ⏎ open · @ send · q quit",
42 Pane::Detail => "/ filter · w wall · @ send · esc back · q quit",
43 Pane::Mailbox => "[ / ] tabs · ⏎ open · ! broadcast · q quit",
44 };
45
46 let left = Line::from(vec![tab_hint, sep, Span::styled(contextual, muted)]);
47
48 let right = "? help · t tutorial";
50
51 let cols = Layout::default()
52 .direction(Direction::Horizontal)
53 .constraints([
54 Constraint::Min(0),
55 Constraint::Length(right.len() as u16 + 1),
56 ])
57 .split(area);
58
59 Paragraph::new(left)
60 .alignment(Alignment::Left)
61 .render(cols[0], buf);
62 Paragraph::new(right)
63 .style(muted)
64 .alignment(Alignment::Right)
65 .render(cols[1], buf);
66 }
67}