use crate::components::component::{Component, ComponentAction};
use crate::components::footer::Footer;
use crate::components::header::Header;
use crate::components::message_box::MessageBox;
use crate::config::Config;
use crate::keymap::Action;
use crate::ui::Screen;
use crate::utils::create_standard_layout;
use anyhow::Result;
use crossterm::event::{Event, KeyEventKind, MouseButton, MouseEventKind};
use ratatui::prelude::*;
use ratatui::widgets::{Block, Clear};
pub struct MessageComponent {
title: String,
message: String,
screen_type: Screen,
config: Option<Config>,
}
impl MessageComponent {
#[must_use]
pub fn new(title: String, message: String, screen_type: Screen) -> Self {
Self {
title,
message,
screen_type,
config: None,
}
}
#[must_use]
pub fn with_config(mut self, config: Config) -> Self {
self.config = Some(config);
self
}
}
impl Component for MessageComponent {
fn render(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
frame.render_widget(Clear, area);
let t = crate::styles::theme();
let background = Block::default().style(t.background_style());
frame.render_widget(background, area);
let (header_chunk, content_chunk, footer_chunk) = create_standard_layout(area, 5, 3);
let description = match self.screen_type {
Screen::SyncWithRemote => "Syncing with remote repository...",
_ => "Important Notice",
};
let _ = Header::render(frame, header_chunk, &self.title, description)?;
let message_color = match self.screen_type {
Screen::SyncWithRemote => Some(t.success), _ => Some(t.warning), };
MessageBox::render(
frame,
content_chunk,
&self.message,
None, message_color,
)?;
let _ = Footer::render(frame, footer_chunk, "Press any key or click to continue")?;
Ok(())
}
fn handle_event(&mut self, event: Event) -> Result<ComponentAction> {
match event {
Event::Key(key) if key.kind == KeyEventKind::Press => {
let action = self
.config
.as_ref()
.and_then(|c| c.keymap.get_action(key.code, key.modifiers));
match action {
Some(
Action::Confirm | Action::ToggleSelect | Action::Quit | Action::Cancel,
) => Ok(ComponentAction::Navigate(Screen::MainMenu)),
_ => {
Ok(ComponentAction::Navigate(Screen::MainMenu))
}
}
}
Event::Mouse(mouse) => {
match mouse.kind {
MouseEventKind::Down(MouseButton::Left) => {
Ok(ComponentAction::Navigate(Screen::MainMenu))
}
_ => Ok(ComponentAction::None),
}
}
_ => Ok(ComponentAction::None),
}
}
}