// This file is part of Deja-vu. // // Deja-vu is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Deja-vu is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Deja-vu. If not, see . // use color_eyre::Result; use ratatui::{prelude::*, widgets::*}; use serde::{Deserialize, Serialize}; use strum::Display; use tokio::sync::mpsc::UnboundedSender; use super::Component; use crate::{action::Action, app::Mode, config::Config}; #[derive(Default, Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)] pub enum Type { #[default] Info, Error, Success, } #[derive(Default)] pub struct Popup { command_tx: Option>, config: Config, mode: Mode, popup_type: Type, popup_text: String, } impl Popup { pub fn new() -> Self { Self { popup_text: String::from("Scanning Disks..."), ..Default::default() } } } impl Component for Popup { fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<()> { self.command_tx = Some(tx); Ok(()) } fn register_config_handler(&mut self, config: Config) -> Result<()> { self.config = config; Ok(()) } fn update(&mut self, action: Action) -> Result> { match action { Action::Tick => { // add any logic here that should run on every tick } Action::Render => { // add any logic here that should run on every render } Action::DismissPopup => self.popup_text.clear(), Action::DisplayPopup(new_type, new_text) => { self.popup_type = new_type; self.popup_text = String::from(new_text); } Action::Process => { if !self.popup_text.is_empty() && self.mode == Mode::InstallDrivers { self.popup_text = String::from(""); if let Some(command_tx) = self.command_tx.clone() { command_tx.send(Action::NextScreen)?; } } } Action::SetMode(mode) => { if mode == Mode::ScanDisks { self.popup_text = String::from("Scanning Disks..."); } self.mode = mode; } _ => {} } Ok(None) } fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> { if self.popup_text.is_empty() { // Only show popup if popup_text is set return Ok(()); } // Set style/color let mut style = Style::default().bold(); match self.popup_type { Type::Info => style = style.cyan(), Type::Error => style = style.red(), Type::Success => style = style.green(), } // Build block let popup_block = Block::default().borders(Borders::ALL).style(style); let popup = Paragraph::new(String::from(&self.popup_text)) .block(popup_block) .centered() .wrap(Wrap { trim: false }); frame.render_widget(Clear, area); frame.render_widget(popup, area); Ok(()) } }