feat: Support alternative keymappings for all keys, featuring hjkl movements

This commit is contained in:
2025-03-17 22:02:15 -06:00
parent c633347ecc
commit 0048d71b74
77 changed files with 1247 additions and 304 deletions
+10 -6
View File
@@ -1,9 +1,9 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App;
use crate::event::Key;
use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::sonarr_handlers::system::system_details_handler::SystemDetailsHandler;
use crate::handlers::{handle_clear_errors, KeyEventHandler};
use crate::matches_key;
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
use crate::models::Scrollable;
@@ -35,6 +35,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SystemHandler<'a, 'b
SystemDetailsHandler::accepts(active_block) || active_block == ActiveSonarrBlock::System
}
fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key,
app: &'a mut App<'b>,
@@ -86,15 +90,15 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SystemHandler<'a, 'b
if self.active_sonarr_block == ActiveSonarrBlock::System {
let key = self.key;
match self.key {
_ if key == DEFAULT_KEYBINDINGS.refresh.key => {
_ if matches_key!(refresh, key) => {
self.app.should_refresh = true;
}
_ if key == DEFAULT_KEYBINDINGS.events.key => {
_ if matches_key!(events, key) => {
self
.app
.push_navigation_stack(ActiveSonarrBlock::SystemQueuedEvents.into());
}
_ if key == DEFAULT_KEYBINDINGS.logs.key => {
_ if matches_key!(logs, key) => {
self
.app
.push_navigation_stack(ActiveSonarrBlock::SystemLogs.into());
@@ -106,12 +110,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SystemHandler<'a, 'b
.set_items(self.app.data.sonarr_data.logs.items.to_vec());
self.app.data.sonarr_data.log_details.scroll_to_bottom();
}
_ if key == DEFAULT_KEYBINDINGS.tasks.key => {
_ if matches_key!(tasks, key) => {
self
.app
.push_navigation_stack(ActiveSonarrBlock::SystemTasks.into());
}
_ if key == DEFAULT_KEYBINDINGS.update.key => {
_ if matches_key!(update, key) => {
self
.app
.push_navigation_stack(ActiveSonarrBlock::SystemUpdates.into());
@@ -1,7 +1,7 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App;
use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
use crate::matches_key;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SYSTEM_DETAILS_BLOCKS};
use crate::models::sonarr_models::SonarrTaskName;
use crate::models::stateful_list::StatefulList;
@@ -36,6 +36,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SystemDetailsHandler
SYSTEM_DETAILS_BLOCKS.contains(&active_block)
}
fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key,
app: &'a mut App<'b>,
@@ -114,7 +118,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SystemDetailsHandler
match self.active_sonarr_block {
ActiveSonarrBlock::SystemLogs => match self.key {
_ if key == DEFAULT_KEYBINDINGS.left.key => {
_ if matches_key!(left, key) => {
self
.app
.data
@@ -124,7 +128,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SystemDetailsHandler
.iter()
.for_each(|log| log.scroll_right());
}
_ if key == DEFAULT_KEYBINDINGS.right.key => {
_ if matches_key!(right, key) => {
self
.app
.data
@@ -178,14 +182,13 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SystemDetailsHandler
}
fn handle_char_key_event(&mut self) {
if SYSTEM_DETAILS_BLOCKS.contains(&self.active_sonarr_block)
&& self.key == DEFAULT_KEYBINDINGS.refresh.key
if SYSTEM_DETAILS_BLOCKS.contains(&self.active_sonarr_block) && matches_key!(refresh, self.key)
{
self.app.should_refresh = true;
}
if self.active_sonarr_block == ActiveSonarrBlock::SystemTaskStartConfirmPrompt
&& self.key == DEFAULT_KEYBINDINGS.confirm.key
&& matches_key!(confirm, self.key)
{
self.app.data.sonarr_data.prompt_confirm = true;
self.app.data.sonarr_data.prompt_confirm_action =
@@ -1,6 +1,7 @@
#[cfg(test)]
mod tests {
use pretty_assertions::{assert_eq, assert_str_eq};
use rstest::rstest;
use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -960,6 +961,22 @@ mod tests {
})
}
#[rstest]
fn test_system_details_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveSonarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test]
fn test_extract_task_name() {
let mut app = App::test_default();
@@ -456,6 +456,22 @@ mod tests {
})
}
#[rstest]
fn test_system_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = SystemHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveSonarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test]
fn test_system_handler_is_not_ready_when_loading() {
let mut app = App::test_default();