rust_kanban/app/
state.rs

1use crate::{
2    app::{actions::Action, kanban::Card},
3    constants::{DEFAULT_VIEW, MOUSE_OUT_OF_BOUNDS_COORDINATES},
4    inputs::{key::Key, mouse::Mouse},
5    io::io_handler::CloudData,
6    ui::{text_box::TextBox, theme::Theme, PopUp, View},
7    util::get_term_bg_color,
8};
9use linked_hash_map::LinkedHashMap;
10use log::debug;
11use ratatui::widgets::{ListState, TableState};
12use serde::{Deserialize, Serialize};
13use std::{
14    ops::{Deref, DerefMut},
15    str::FromStr,
16    time::Instant,
17    vec,
18};
19use strum::{Display, EnumString, IntoEnumIterator};
20use strum_macros::EnumIter;
21
22#[derive(Debug, Clone)]
23pub struct AppState<'a> {
24    pub all_available_tags: Option<Vec<(String, u32)>>,
25    pub app_list_states: AppListStates,
26    pub app_status: AppStatus,
27    pub app_table_states: AppTableStates,
28    pub card_being_edited: Option<((u64, u64), Card)>, // (board_id, card)
29    pub card_drag_mode: bool,
30    pub cloud_data: Option<Vec<CloudData>>,
31    pub current_board_id: Option<(u64, u64)>,
32    pub current_card_id: Option<(u64, u64)>,
33    pub current_mouse_coordinates: (u16, u16),
34    pub debug_menu_toggled: bool,
35    pub default_theme_mode: bool,
36    pub edited_keybinding: Option<Vec<Key>>,
37    pub encryption_key_from_arguments: Option<String>,
38    pub filter_tags: Option<Vec<String>>,
39    pub focus: Focus,
40    pub hovered_board: Option<(u64, u64)>,
41    pub hovered_card_dimensions: Option<(u16, u16)>,
42    pub hovered_card: Option<((u64, u64), (u64, u64))>,
43    pub last_mouse_action: Option<Mouse>,
44    pub last_reset_password_link_sent_time: Option<Instant>,
45    pub mouse_focus: Option<Focus>,
46    pub mouse_list_index: Option<u16>,
47    pub z_stack: ZStack,
48    pub prev_focus: Option<Focus>,
49    pub prev_view: Option<View>,
50    pub preview_file_name: Option<String>,
51    pub preview_visible_boards_and_cards: LinkedHashMap<(u64, u64), Vec<(u64, u64)>>,
52    pub previous_mouse_coordinates: (u16, u16),
53    pub term_background_color: (u8, u8, u8),
54    pub theme_being_edited: Theme,
55    pub current_view: View,
56    pub ui_render_time: Vec<u128>,
57    pub user_login_data: UserLoginData,
58    pub path_check_state: PathCheckState,
59    pub text_buffers: TextBuffers<'a>,
60    pub show_password: bool,
61    pub last_cursor_set_pos: (u16, u16),
62}
63
64impl AppState<'_> {
65    pub fn set_focus(&mut self, focus: Focus) {
66        self.focus = focus;
67    }
68    pub fn get_card_being_edited(&self) -> Option<((u64, u64), Card)> {
69        self.card_being_edited.clone()
70    }
71    pub fn get_theme_being_edited(&self) -> Theme {
72        self.theme_being_edited.clone()
73    }
74}
75
76impl Default for AppState<'_> {
77    fn default() -> AppState<'static> {
78        AppState {
79            all_available_tags: None,
80            app_list_states: AppListStates::default(),
81            app_status: AppStatus::default(),
82            app_table_states: AppTableStates::default(),
83            card_being_edited: None,
84            card_drag_mode: false,
85            cloud_data: None,
86            current_board_id: None,
87            current_card_id: None,
88            current_mouse_coordinates: MOUSE_OUT_OF_BOUNDS_COORDINATES, // make sure it's out of bounds when mouse mode is disabled
89            debug_menu_toggled: false,
90            default_theme_mode: false,
91            edited_keybinding: None,
92            encryption_key_from_arguments: None,
93            filter_tags: None,
94            focus: Focus::NoFocus,
95            hovered_board: None,
96            hovered_card_dimensions: None,
97            hovered_card: None,
98            last_mouse_action: None,
99            last_reset_password_link_sent_time: None,
100            mouse_focus: None,
101            mouse_list_index: None,
102            z_stack: ZStack::default(),
103            prev_focus: None,
104            prev_view: None,
105            preview_file_name: None,
106            preview_visible_boards_and_cards: LinkedHashMap::new(),
107            previous_mouse_coordinates: MOUSE_OUT_OF_BOUNDS_COORDINATES,
108            term_background_color: get_term_bg_color(),
109            theme_being_edited: Theme::default(),
110            current_view: DEFAULT_VIEW,
111            ui_render_time: Vec::new(),
112            user_login_data: UserLoginData {
113                email_id: None,
114                auth_token: None,
115                refresh_token: None,
116                user_id: None,
117            },
118            path_check_state: PathCheckState::default(),
119            text_buffers: TextBuffers::default(),
120            show_password: false,
121            last_cursor_set_pos: MOUSE_OUT_OF_BOUNDS_COORDINATES,
122        }
123    }
124}
125
126#[derive(Debug, Clone, Default)]
127pub struct ZStack(Vec<PopUp>);
128
129impl ZStack {
130    pub fn checked_disabled_last(&self) -> Option<&PopUp> {
131        if let Some(popup) = self.0.last() {
132            if self.0.len() > 1 && popup.requires_previous_element_disabled() {
133                self.0.get(self.0.len() - 2)
134            } else {
135                Some(popup)
136            }
137        } else {
138            None
139        }
140    }
141
142    pub fn checked_control_last(&self) -> Option<&PopUp> {
143        if let Some(popup) = self.0.last() {
144            if self.0.len() > 1 && popup.requires_previous_element_control() {
145                self.0.get(self.0.len() - 2)
146            } else {
147                Some(popup)
148            }
149        } else {
150            None
151        }
152    }
153}
154
155impl Deref for ZStack {
156    type Target = Vec<PopUp>;
157
158    fn deref(&self) -> &Self::Target {
159        &self.0
160    }
161}
162
163impl DerefMut for ZStack {
164    fn deref_mut(&mut self) -> &mut Self::Target {
165        &mut self.0
166    }
167}
168
169#[derive(Debug, Clone, Default)]
170pub struct AppListStates {
171    pub card_priority_selector: ListState,
172    pub card_status_selector: ListState,
173    pub card_view_comment_list: ListState,
174    pub card_view_list: ListState,
175    pub card_view_tag_list: ListState,
176    pub tag_picker: ListState,
177    pub command_palette_board_search: ListState,
178    pub command_palette_card_search: ListState,
179    pub command_palette_command_search: ListState,
180    pub date_format_selector: ListState,
181    pub default_view: ListState,
182    pub edit_specific_style: [ListState; 3],
183    pub filter_by_tag_list: ListState,
184    pub load_save: ListState,
185    pub logs: ListState,
186    pub main_menu: ListState,
187    pub theme_selector: ListState,
188}
189
190#[derive(Debug, Clone, Default)]
191pub struct AppTableStates {
192    pub config: TableState,
193    pub edit_keybindings: TableState,
194    pub help: TableState,
195    pub theme_editor: TableState,
196}
197
198#[derive(Debug, Clone)]
199pub struct TextBuffers<'a> {
200    pub board_name: TextBox<'a>,
201    pub board_description: TextBox<'a>,
202    pub card_name: TextBox<'a>,
203    pub card_description: TextBox<'a>,
204    pub card_tags: Vec<TextBox<'a>>,
205    pub card_comments: Vec<TextBox<'a>>,
206    pub email_id: TextBox<'a>,
207    pub password: TextBox<'a>,
208    pub confirm_password: TextBox<'a>,
209    pub reset_password_link: TextBox<'a>,
210    pub general_config: TextBox<'a>,
211    pub command_palette: TextBox<'a>,
212    pub theme_editor_fg_hex: TextBox<'a>,
213    pub theme_editor_bg_hex: TextBox<'a>,
214}
215
216impl<'a> Default for TextBuffers<'a> {
217    fn default() -> Self {
218        TextBuffers {
219            board_name: TextBox::new(vec!["".to_string()], true),
220            board_description: TextBox::new(vec!["".to_string()], false),
221            card_name: TextBox::new(vec!["".to_string()], true),
222            card_description: TextBox::new(vec!["".to_string()], false),
223            card_tags: Vec::new(),
224            card_comments: Vec::new(),
225            email_id: TextBox::new(vec!["".to_string()], true),
226            password: TextBox::new(vec!["".to_string()], true),
227            confirm_password: TextBox::new(vec!["".to_string()], true),
228            reset_password_link: TextBox::new(vec!["".to_string()], true),
229            general_config: TextBox::new(vec!["".to_string()], true),
230            command_palette: TextBox::new(vec!["".to_string()], true),
231            theme_editor_fg_hex: TextBox::new(vec!["".to_string()], true),
232            theme_editor_bg_hex: TextBox::new(vec!["".to_string()], true),
233        }
234    }
235}
236
237impl<'a> TextBuffers<'a> {
238    pub fn prepare_tags_and_comments_for_card(&mut self, card: &Card) {
239        self.card_tags = card
240            .tags
241            .iter()
242            .map(|tag| TextBox::new(vec![tag.clone()], true))
243            .collect();
244        self.card_comments = card
245            .comments
246            .iter()
247            .map(|comment| TextBox::new(vec![comment.clone()], true))
248            .collect();
249    }
250}
251
252#[derive(Debug, Clone, Default)]
253pub struct PathCheckState {
254    pub path_last_checked: String,
255    pub path_exists: bool,
256    pub potential_completion: Option<String>,
257    pub recheck_required: bool,
258    pub path_check_mode: bool,
259}
260
261#[derive(Debug, Clone, Default)]
262pub struct UserLoginData {
263    pub auth_token: Option<String>,
264    pub email_id: Option<String>,
265    pub refresh_token: Option<String>,
266    pub user_id: Option<String>,
267}
268
269#[derive(Clone, PartialEq, Debug, Default)]
270pub enum AppStatus {
271    #[default]
272    Init,
273    Initialized,
274    KeyBindMode,
275    UserInput,
276}
277
278#[derive(Clone, PartialEq, Debug, Copy, Default)]
279pub enum Focus {
280    Body,
281    CardComments,
282    CardDescription,
283    CardDueDate,
284    CardName,
285    CardPriority,
286    CardStatus,
287    CardTags,
288    ChangeCardPriorityPopup,
289    ChangeCardStatusPopup,
290    ChangeDateFormatPopup,
291    ChangeViewPopup,
292    CloseButton,
293    CommandPaletteBoard,
294    CommandPaletteCard,
295    CommandPaletteCommand,
296    ConfigHelp,
297    ConfigTable,
298    ConfirmPasswordField,
299    EditGeneralConfigPopup,
300    EditKeybindingsTable,
301    EditSpecificKeyBindingPopup,
302    EmailIDField,
303    ExtraFocus, // Used in cases where defining a new focus is not necessary
304    FilterByTagPopup,
305    Help,
306    LoadSave,
307    Log,
308    MainMenu,
309    NewBoardDescription,
310    NewBoardName,
311    #[default]
312    NoFocus,
313    PasswordField,
314    ResetPasswordLinkField,
315    SelectDefaultView,
316    SendResetPasswordLinkButton,
317    StyleEditorBG,
318    StyleEditorFG,
319    StyleEditorModifier,
320    SubmitButton,
321    TextInput,
322    ThemeEditor,
323    ThemeSelector,
324    Title,
325    DTPCalender,
326    DTPMonth,
327    DTPYear,
328    DTPToggleTimePicker,
329    DTPHour,
330    DTPMinute,
331    DTPSecond,
332}
333
334#[derive(Serialize, Deserialize, Debug, Clone)]
335pub struct KeyBindings {
336    pub accept: Vec<Key>,
337    pub change_card_status_to_active: Vec<Key>,
338    pub change_card_status_to_completed: Vec<Key>,
339    pub change_card_status_to_stale: Vec<Key>,
340    pub change_card_priority_to_high: Vec<Key>,
341    pub change_card_priority_to_medium: Vec<Key>,
342    pub change_card_priority_to_low: Vec<Key>,
343    pub clear_all_toasts: Vec<Key>,
344    pub delete_board: Vec<Key>,
345    pub delete_card: Vec<Key>,
346    pub down: Vec<Key>,
347    pub go_to_main_menu: Vec<Key>,
348    pub go_to_previous_view_or_cancel: Vec<Key>,
349    pub hide_ui_element: Vec<Key>,
350    pub left: Vec<Key>,
351    pub move_card_down: Vec<Key>,
352    pub move_card_left: Vec<Key>,
353    pub move_card_right: Vec<Key>,
354    pub move_card_up: Vec<Key>,
355    pub new_board: Vec<Key>,
356    pub new_card: Vec<Key>,
357    pub next_focus: Vec<Key>,
358    pub open_config_menu: Vec<Key>,
359    pub prv_focus: Vec<Key>,
360    pub quit: Vec<Key>,
361    pub redo: Vec<Key>,
362    pub reset_ui: Vec<Key>,
363    pub right: Vec<Key>,
364    pub save_state: Vec<Key>,
365    pub stop_user_input: Vec<Key>,
366    pub take_user_input: Vec<Key>,
367    pub toggle_command_palette: Vec<Key>,
368    pub undo: Vec<Key>,
369    pub up: Vec<Key>,
370}
371
372#[derive(Serialize, Deserialize, Debug, Clone, Copy, EnumIter, PartialEq, EnumString, Display)]
373pub enum KeyBindingEnum {
374    Accept,
375    ChangeCardStatusToActive,
376    ChangeCardStatusToCompleted,
377    ChangeCardStatusToStale,
378    ChangeCardPriorityToHigh,
379    ChangeCardPriorityToMedium,
380    ChangeCardPriorityToLow,
381    ClearAllToasts,
382    DeleteBoard,
383    DeleteCard,
384    Down,
385    GoToMainMenu,
386    GoToPreviousViewOrCancel,
387    HideUiElement,
388    Left,
389    MoveCardDown,
390    MoveCardLeft,
391    MoveCardRight,
392    MoveCardUp,
393    NewBoard,
394    NewCard,
395    NextFocus,
396    OpenConfigMenu,
397    PrvFocus,
398    Quit,
399    Redo,
400    ResetUI,
401    Right,
402    SaveState,
403    StopUserInput,
404    TakeUserInput,
405    ToggleCommandPalette,
406    Undo,
407    Up,
408}
409
410impl AppStatus {
411    pub fn initialized() -> Self {
412        Self::Initialized
413    }
414
415    pub fn is_initialized(&self) -> bool {
416        matches!(self, &Self::Initialized { .. })
417    }
418}
419
420impl Focus {
421    pub fn next(&self, available_tabs: &[Focus]) -> Self {
422        if let Some(index) = available_tabs.iter().position(|x| x == self) {
423            if index == available_tabs.len() - 1 {
424                available_tabs[0]
425            } else {
426                available_tabs[index + 1]
427            }
428        } else {
429            available_tabs[0]
430        }
431    }
432    pub fn prev(&self, available_tabs: &[Focus]) -> Self {
433        if let Some(index) = available_tabs.iter().position(|x| x == self) {
434            if index == 0 {
435                available_tabs[available_tabs.len() - 1]
436            } else {
437                available_tabs[index - 1]
438            }
439        } else {
440            available_tabs[0]
441        }
442    }
443}
444
445impl KeyBindings {
446    pub fn iter(&self) -> impl Iterator<Item = (KeyBindingEnum, &Vec<Key>)> {
447        KeyBindingEnum::iter().map(|enum_variant| {
448            let value = match enum_variant {
449                KeyBindingEnum::Accept => &self.accept,
450                KeyBindingEnum::ChangeCardStatusToActive => &self.change_card_status_to_active,
451                KeyBindingEnum::ChangeCardStatusToCompleted => {
452                    &self.change_card_status_to_completed
453                }
454                KeyBindingEnum::ChangeCardStatusToStale => &self.change_card_status_to_stale,
455                KeyBindingEnum::ChangeCardPriorityToHigh => &self.change_card_priority_to_high,
456                KeyBindingEnum::ChangeCardPriorityToMedium => &self.change_card_priority_to_medium,
457                KeyBindingEnum::ChangeCardPriorityToLow => &self.change_card_priority_to_low,
458                KeyBindingEnum::ClearAllToasts => &self.clear_all_toasts,
459                KeyBindingEnum::DeleteBoard => &self.delete_board,
460                KeyBindingEnum::DeleteCard => &self.delete_card,
461                KeyBindingEnum::Down => &self.down,
462                KeyBindingEnum::GoToMainMenu => &self.go_to_main_menu,
463                KeyBindingEnum::GoToPreviousViewOrCancel => &self.go_to_previous_view_or_cancel,
464                KeyBindingEnum::HideUiElement => &self.hide_ui_element,
465                KeyBindingEnum::Left => &self.left,
466                KeyBindingEnum::MoveCardDown => &self.move_card_down,
467                KeyBindingEnum::MoveCardLeft => &self.move_card_left,
468                KeyBindingEnum::MoveCardRight => &self.move_card_right,
469                KeyBindingEnum::MoveCardUp => &self.move_card_up,
470                KeyBindingEnum::NewBoard => &self.new_board,
471                KeyBindingEnum::NewCard => &self.new_card,
472                KeyBindingEnum::NextFocus => &self.next_focus,
473                KeyBindingEnum::OpenConfigMenu => &self.open_config_menu,
474                KeyBindingEnum::PrvFocus => &self.prv_focus,
475                KeyBindingEnum::Quit => &self.quit,
476                KeyBindingEnum::Redo => &self.redo,
477                KeyBindingEnum::ResetUI => &self.reset_ui,
478                KeyBindingEnum::Right => &self.right,
479                KeyBindingEnum::SaveState => &self.save_state,
480                KeyBindingEnum::StopUserInput => &self.stop_user_input,
481                KeyBindingEnum::TakeUserInput => &self.take_user_input,
482                KeyBindingEnum::ToggleCommandPalette => &self.toggle_command_palette,
483                KeyBindingEnum::Undo => &self.undo,
484                KeyBindingEnum::Up => &self.up,
485            };
486            (enum_variant, value)
487        })
488    }
489
490    pub fn key_to_action(&self, key: &Key) -> Option<Action> {
491        let keybinding_enum = self
492            .iter()
493            .find(|(_, keybinding)| keybinding.contains(key))
494            .map(|(keybinding_enum, _)| keybinding_enum);
495        keybinding_enum.map(|keybinding_enum| self.keybinding_enum_to_action(keybinding_enum))
496    }
497
498    pub fn keybinding_enum_to_action(&self, keybinding_enum: KeyBindingEnum) -> Action {
499        match keybinding_enum {
500            KeyBindingEnum::Accept => Action::Accept,
501            KeyBindingEnum::ChangeCardStatusToActive => Action::ChangeCardStatusToActive,
502            KeyBindingEnum::ChangeCardStatusToCompleted => Action::ChangeCardStatusToCompleted,
503            KeyBindingEnum::ChangeCardStatusToStale => Action::ChangeCardStatusToStale,
504            KeyBindingEnum::ChangeCardPriorityToHigh => Action::ChangeCardPriorityToHigh,
505            KeyBindingEnum::ChangeCardPriorityToMedium => Action::ChangeCardPriorityToMedium,
506            KeyBindingEnum::ChangeCardPriorityToLow => Action::ChangeCardPriorityToLow,
507            KeyBindingEnum::ClearAllToasts => Action::ClearAllToasts,
508            KeyBindingEnum::DeleteBoard => Action::DeleteBoard,
509            KeyBindingEnum::DeleteCard => Action::Delete,
510            KeyBindingEnum::Down => Action::Down,
511            KeyBindingEnum::GoToMainMenu => Action::GoToMainMenu,
512            KeyBindingEnum::GoToPreviousViewOrCancel => Action::GoToPreviousViewOrCancel,
513            KeyBindingEnum::HideUiElement => Action::HideUiElement,
514            KeyBindingEnum::Left => Action::Left,
515            KeyBindingEnum::MoveCardDown => Action::MoveCardDown,
516            KeyBindingEnum::MoveCardLeft => Action::MoveCardLeft,
517            KeyBindingEnum::MoveCardRight => Action::MoveCardRight,
518            KeyBindingEnum::MoveCardUp => Action::MoveCardUp,
519            KeyBindingEnum::NewBoard => Action::NewBoard,
520            KeyBindingEnum::NewCard => Action::NewCard,
521            KeyBindingEnum::NextFocus => Action::NextFocus,
522            KeyBindingEnum::OpenConfigMenu => Action::OpenConfigMenu,
523            KeyBindingEnum::PrvFocus => Action::PrvFocus,
524            KeyBindingEnum::Quit => Action::Quit,
525            KeyBindingEnum::Redo => Action::Redo,
526            KeyBindingEnum::ResetUI => Action::ResetUI,
527            KeyBindingEnum::Right => Action::Right,
528            KeyBindingEnum::SaveState => Action::SaveState,
529            KeyBindingEnum::StopUserInput => Action::StopUserInput,
530            KeyBindingEnum::TakeUserInput => Action::TakeUserInput,
531            KeyBindingEnum::ToggleCommandPalette => Action::ToggleCommandPalette,
532            KeyBindingEnum::Undo => Action::Undo,
533            KeyBindingEnum::Up => Action::Up,
534        }
535    }
536
537    pub fn edit_keybinding(&mut self, key: &str, keybinding: Vec<Key>) -> &mut Self {
538        let mut keybinding = keybinding;
539        keybinding.dedup();
540        let keybinding_enum = KeyBindingEnum::from_str(key);
541        if let Ok(keybinding_enum) = keybinding_enum {
542            match keybinding_enum {
543                KeyBindingEnum::Accept => self.accept = keybinding,
544                KeyBindingEnum::ChangeCardStatusToActive => {
545                    self.change_card_status_to_active = keybinding
546                }
547                KeyBindingEnum::ChangeCardStatusToCompleted => {
548                    self.change_card_status_to_completed = keybinding
549                }
550                KeyBindingEnum::ChangeCardStatusToStale => {
551                    self.change_card_status_to_stale = keybinding
552                }
553                KeyBindingEnum::ChangeCardPriorityToHigh => {
554                    self.change_card_priority_to_high = keybinding
555                }
556                KeyBindingEnum::ChangeCardPriorityToMedium => {
557                    self.change_card_priority_to_medium = keybinding
558                }
559                KeyBindingEnum::ChangeCardPriorityToLow => {
560                    self.change_card_priority_to_low = keybinding
561                }
562                KeyBindingEnum::ClearAllToasts => self.clear_all_toasts = keybinding,
563                KeyBindingEnum::DeleteBoard => self.delete_board = keybinding,
564                KeyBindingEnum::DeleteCard => self.delete_card = keybinding,
565                KeyBindingEnum::Down => self.down = keybinding,
566                KeyBindingEnum::GoToMainMenu => self.go_to_main_menu = keybinding,
567                KeyBindingEnum::GoToPreviousViewOrCancel => {
568                    self.go_to_previous_view_or_cancel = keybinding
569                }
570                KeyBindingEnum::HideUiElement => self.hide_ui_element = keybinding,
571                KeyBindingEnum::Left => self.left = keybinding,
572                KeyBindingEnum::MoveCardDown => self.move_card_down = keybinding,
573                KeyBindingEnum::MoveCardLeft => self.move_card_left = keybinding,
574                KeyBindingEnum::MoveCardRight => self.move_card_right = keybinding,
575                KeyBindingEnum::MoveCardUp => self.move_card_up = keybinding,
576                KeyBindingEnum::NewBoard => self.new_board = keybinding,
577                KeyBindingEnum::NewCard => self.new_card = keybinding,
578                KeyBindingEnum::NextFocus => self.next_focus = keybinding,
579                KeyBindingEnum::OpenConfigMenu => self.open_config_menu = keybinding,
580                KeyBindingEnum::PrvFocus => self.prv_focus = keybinding,
581                KeyBindingEnum::Quit => self.quit = keybinding,
582                KeyBindingEnum::Redo => self.redo = keybinding,
583                KeyBindingEnum::ResetUI => self.reset_ui = keybinding,
584                KeyBindingEnum::Right => self.right = keybinding,
585                KeyBindingEnum::SaveState => self.save_state = keybinding,
586                KeyBindingEnum::StopUserInput => self.stop_user_input = keybinding,
587                KeyBindingEnum::TakeUserInput => self.take_user_input = keybinding,
588                KeyBindingEnum::ToggleCommandPalette => self.toggle_command_palette = keybinding,
589                KeyBindingEnum::Undo => self.undo = keybinding,
590                KeyBindingEnum::Up => self.up = keybinding,
591            }
592        } else {
593            debug!("Invalid keybinding: {}", key);
594        }
595        self
596    }
597
598    pub fn get_keybindings(&self, keybinding_enum: KeyBindingEnum) -> Option<Vec<Key>> {
599        match keybinding_enum {
600            KeyBindingEnum::Accept => Some(self.accept.clone()),
601            KeyBindingEnum::ChangeCardStatusToActive => {
602                Some(self.change_card_status_to_active.clone())
603            }
604            KeyBindingEnum::ChangeCardStatusToCompleted => {
605                Some(self.change_card_status_to_completed.clone())
606            }
607            KeyBindingEnum::ChangeCardStatusToStale => {
608                Some(self.change_card_status_to_stale.clone())
609            }
610            KeyBindingEnum::ChangeCardPriorityToHigh => {
611                Some(self.change_card_priority_to_high.clone())
612            }
613            KeyBindingEnum::ChangeCardPriorityToMedium => {
614                Some(self.change_card_priority_to_medium.clone())
615            }
616            KeyBindingEnum::ChangeCardPriorityToLow => {
617                Some(self.change_card_priority_to_low.clone())
618            }
619            KeyBindingEnum::ClearAllToasts => Some(self.clear_all_toasts.clone()),
620            KeyBindingEnum::DeleteBoard => Some(self.delete_board.clone()),
621            KeyBindingEnum::DeleteCard => Some(self.delete_card.clone()),
622            KeyBindingEnum::Down => Some(self.down.clone()),
623            KeyBindingEnum::GoToMainMenu => Some(self.go_to_main_menu.clone()),
624            KeyBindingEnum::GoToPreviousViewOrCancel => {
625                Some(self.go_to_previous_view_or_cancel.clone())
626            }
627            KeyBindingEnum::HideUiElement => Some(self.hide_ui_element.clone()),
628            KeyBindingEnum::Left => Some(self.left.clone()),
629            KeyBindingEnum::MoveCardDown => Some(self.move_card_down.clone()),
630            KeyBindingEnum::MoveCardLeft => Some(self.move_card_left.clone()),
631            KeyBindingEnum::MoveCardRight => Some(self.move_card_right.clone()),
632            KeyBindingEnum::MoveCardUp => Some(self.move_card_up.clone()),
633            KeyBindingEnum::NewBoard => Some(self.new_board.clone()),
634            KeyBindingEnum::NewCard => Some(self.new_card.clone()),
635            KeyBindingEnum::NextFocus => Some(self.next_focus.clone()),
636            KeyBindingEnum::OpenConfigMenu => Some(self.open_config_menu.clone()),
637            KeyBindingEnum::PrvFocus => Some(self.prv_focus.clone()),
638            KeyBindingEnum::Quit => Some(self.quit.clone()),
639            KeyBindingEnum::Redo => Some(self.redo.clone()),
640            KeyBindingEnum::ResetUI => Some(self.reset_ui.clone()),
641            KeyBindingEnum::Right => Some(self.right.clone()),
642            KeyBindingEnum::SaveState => Some(self.save_state.clone()),
643            KeyBindingEnum::StopUserInput => Some(self.stop_user_input.clone()),
644            KeyBindingEnum::TakeUserInput => Some(self.take_user_input.clone()),
645            KeyBindingEnum::ToggleCommandPalette => Some(self.toggle_command_palette.clone()),
646            KeyBindingEnum::Undo => Some(self.undo.clone()),
647            KeyBindingEnum::Up => Some(self.up.clone()),
648        }
649    }
650}
651
652impl Default for KeyBindings {
653    fn default() -> Self {
654        Self {
655            accept: vec![Key::Enter],
656            change_card_status_to_completed: vec![Key::Char('1')],
657            change_card_status_to_active: vec![Key::Char('2')],
658            change_card_status_to_stale: vec![Key::Char('3')],
659            change_card_priority_to_high: vec![Key::Char('4')],
660            change_card_priority_to_medium: vec![Key::Char('5')],
661            change_card_priority_to_low: vec![Key::Char('6')],
662            clear_all_toasts: vec![Key::Char('t')],
663            delete_board: vec![Key::Char('D')],
664            delete_card: vec![Key::Char('d'), Key::Delete],
665            down: vec![Key::Down],
666            go_to_main_menu: vec![Key::Char('m')],
667            go_to_previous_view_or_cancel: vec![Key::Esc],
668            hide_ui_element: vec![Key::Char('h')],
669            left: vec![Key::Left],
670            move_card_down: vec![Key::ShiftDown],
671            move_card_left: vec![Key::ShiftLeft],
672            move_card_right: vec![Key::ShiftRight],
673            move_card_up: vec![Key::ShiftUp],
674            new_board: vec![Key::Char('b')],
675            new_card: vec![Key::Char('n')],
676            next_focus: vec![Key::Tab],
677            open_config_menu: vec![Key::Char('c')],
678            prv_focus: vec![Key::BackTab],
679            quit: vec![Key::Ctrl('c'), Key::Char('q')],
680            redo: vec![Key::Ctrl('y')],
681            reset_ui: vec![Key::Char('r')],
682            right: vec![Key::Right],
683            save_state: vec![Key::Ctrl('s')],
684            stop_user_input: vec![Key::Ins],
685            take_user_input: vec![Key::Char('i')],
686            toggle_command_palette: vec![Key::Ctrl('p')],
687            undo: vec![Key::Ctrl('z')],
688            up: vec![Key::Up],
689        }
690    }
691}