aboutsummaryrefslogtreecommitdiff
path: root/src/components/status.rs
blob: aa2b384d8a5cda959a3d0a41cbdaf8e0b649f495 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use ratatui::prelude::*;
use ratatui::widgets::*;

use crate::app_action::AppAction;
use crate::app_event::AppEvent;
use crate::component::Component;
use crate::keys::key_commands::serialize_key_event;

#[derive(Default, Clone)]
pub struct StatusBar {
    pub message: String,
    pub current_key: String,
    pub error: bool,
    pub url_to_open: Option<url::Url>,
}

impl Component for StatusBar {
    fn handle_key_event(
        &mut self,
        key: crossterm::event::KeyEvent,
    ) -> Option<AppAction> {
        let key_str = serialize_key_event(key);
        self.current_key = key_str;

        None
    }

    fn handle_action(&mut self, action: crate::app_action::AppAction) {
        match action.clone() {
            AppAction::StatusBarSetMessage(message) => {
                self.error = false;
                self.message = message;
            }
            AppAction::StatusBarSetError(message) => {
                self.error = true;
                self.message = message;
            }
            AppAction::OpenUrl => {
                self.url_to_open =
                    Some(url::Url::parse("molerat://example.com").unwrap());
            }
            _ => {}
        }
    }

    fn update(&mut self) -> Option<AppEvent> {
        if let Some(url) = &self.url_to_open {
            let event = AppEvent::OpenUrl(url.clone());
            self.url_to_open = None;
            return Some(event);
        }

        None
    }

    fn render(
        &mut self,
        frame: &mut ratatui::prelude::Frame,
        rect: ratatui::prelude::Rect,
    ) -> eyre::Result<()> {
        let block =
            Block::default().style(Style::default().bg(if self.error {
                Color::Red
            } else {
                Color::DarkGray
            }));

        let layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints(vec![
                Constraint::Percentage(50),
                Constraint::Percentage(50),
            ])
            .split(rect);

        let message = Paragraph::new(self.message.clone()).block(block.clone());
        let current_key = Paragraph::new(self.current_key.clone())
            .block(block)
            .alignment(Alignment::Right);

        frame.render_widget(message, layout[0]);
        frame.render_widget(current_key, layout[1]);

        Ok(())
    }
}