Krolyxon
Commit cf9c69a

rmptuisrcpopupsconfirm.rs

69 lines · 1.9 KB · Rust

1use crossterm::event::KeyCode;
2use ratatui::{
3 Frame,
4 layout::{Alignment, Rect},
5 text::{Line, Span},
6 widgets::{Paragraph, Wrap},
7};
8
9use super::{Popup, PopupState, frame_popup};
10use crate::{
11 action::{Action, Context},
12 config::KeyCombo,
13 mpd::Command,
14 screens::Ctx,
15};
16
17/// Asks before running destructive commands.
18pub struct ConfirmPopup {
19 message: String,
20 commands: Vec<Command>,
21}
22
23impl ConfirmPopup {
24 pub fn new(message: impl Into<String>, commands: Vec<Command>) -> Self {
25 Self {
26 message: message.into(),
27 commands,
28 }
29 }
30}
31
32impl Popup for ConfirmPopup {
33 fn draw(&mut self, frame: &mut Frame, area: Rect, ctx: &Ctx) {
34 let inner = frame_popup(frame, area, 50, 5, "Confirm", ctx);
35 let theme = ctx.theme();
36 let text = vec![
37 Line::from(self.message.as_str()),
38 Line::default(),
39 Line::from(vec![
40 Span::styled("[y]", theme.accent()),
41 Span::raw("es "),
42 Span::styled("[n]", theme.accent()),
43 Span::raw("o"),
44 ]),
45 ];
46 frame.render_widget(
47 Paragraph::new(text)
48 .alignment(Alignment::Center)
49 .wrap(Wrap { trim: true }),
50 inner,
51 );
52 }
53
54 fn handle_key(&mut self, key: KeyCombo, ctx: &mut Ctx) -> PopupState {
55 let confirmed = matches!(key.code, KeyCode::Char('y' | 'Y'))
56 || ctx.config.keymap.resolve(&[Context::Navigation], key) == Some(Action::Activate);
57 if confirmed {
58 ctx.client.exec_all(std::mem::take(&mut self.commands));
59 return PopupState::Closed;
60 }
61 let declined = matches!(key.code, KeyCode::Char('n' | 'N'))
62 || ctx.config.keymap.resolve(&[Context::Popup], key) == Some(Action::Close);
63 if declined {
64 PopupState::Closed
65 } else {
66 PopupState::Open
67 }
68 }
69}