feat: Support alternative keymappings for all keys, featuring hjkl movements
This commit is contained in:
@@ -4,6 +4,7 @@ mod tests {
|
||||
|
||||
use chrono::DateTime;
|
||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
@@ -541,6 +542,22 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_blocklist_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 = BlocklistHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_blocklist_item_id() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handle_table_events;
|
||||
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
|
||||
use crate::handlers::table_handler::TableHandlingConfig;
|
||||
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
|
||||
@@ -9,6 +7,7 @@ use crate::models::radarr_models::BlocklistItem;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, BLOCKLIST_BLOCKS};
|
||||
use crate::models::stateful_table::SortOption;
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_table_events, matches_key};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "blocklist_handler_tests.rs"]
|
||||
@@ -51,6 +50,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a,
|
||||
BLOCKLIST_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>,
|
||||
@@ -143,10 +146,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a,
|
||||
let key = self.key;
|
||||
match self.active_radarr_block {
|
||||
ActiveRadarrBlock::Blocklist => match self.key {
|
||||
_ if key == DEFAULT_KEYBINDINGS.refresh.key => {
|
||||
_ if matches_key!(refresh, key) => {
|
||||
self.app.should_refresh = true;
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.clear.key => {
|
||||
_ if matches_key!(clear, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::BlocklistClearAllItemsPrompt.into());
|
||||
@@ -154,7 +157,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a,
|
||||
_ => (),
|
||||
},
|
||||
ActiveRadarrBlock::DeleteBlocklistItemPrompt => {
|
||||
if key == DEFAULT_KEYBINDINGS.confirm.key {
|
||||
if matches_key!(confirm, key) {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteBlocklistItem(
|
||||
self.extract_blocklist_item_id(),
|
||||
@@ -164,7 +167,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a,
|
||||
}
|
||||
}
|
||||
ActiveRadarrBlock::BlocklistClearAllItemsPrompt => {
|
||||
if key == DEFAULT_KEYBINDINGS.confirm.key {
|
||||
if matches_key!(confirm, key) {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::ClearBlocklist);
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handle_table_events;
|
||||
use crate::handlers::table_handler::TableHandlingConfig;
|
||||
use crate::handlers::KeyEventHandler;
|
||||
use crate::models::radarr_models::CollectionMovie;
|
||||
@@ -11,6 +9,7 @@ use crate::models::servarr_data::radarr::radarr_data::{
|
||||
};
|
||||
use crate::models::stateful_table::StatefulTable;
|
||||
use crate::models::BlockSelectionState;
|
||||
use crate::{handle_table_events, matches_key};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "collection_details_handler_tests.rs"]
|
||||
@@ -46,6 +45,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan
|
||||
COLLECTION_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>,
|
||||
@@ -130,7 +133,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan
|
||||
|
||||
fn handle_char_key_event(&mut self) {
|
||||
if self.active_radarr_block == ActiveRadarrBlock::CollectionDetails
|
||||
&& self.key == DEFAULT_KEYBINDINGS.edit.key
|
||||
&& matches_key!(edit, self.key)
|
||||
{
|
||||
self.app.push_navigation_stack(
|
||||
(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_str_eq;
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
@@ -278,6 +279,22 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_collection_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 = CollectionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collection_details_handler_not_ready_when_loading() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -589,6 +589,22 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_collections_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 = CollectionsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collections_handler_not_ready_when_loading() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
|
||||
@@ -7,7 +6,7 @@ use crate::models::servarr_data::radarr::modals::EditCollectionModal;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS};
|
||||
use crate::models::Scrollable;
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_text_box_keys, handle_text_box_left_right_keys};
|
||||
use crate::{handle_text_box_keys, handle_text_box_left_right_keys, matches_key};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "edit_collection_handler_tests.rs"]
|
||||
@@ -69,6 +68,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle
|
||||
EDIT_COLLECTION_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>,
|
||||
@@ -354,7 +357,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle
|
||||
ActiveRadarrBlock::EditCollectionPrompt => {
|
||||
if self.app.data.radarr_data.selected_block.get_active_block()
|
||||
== ActiveRadarrBlock::EditCollectionConfirmPrompt
|
||||
&& key == DEFAULT_KEYBINDINGS.confirm.key
|
||||
&& matches_key!(confirm, key)
|
||||
{
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditCollection(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
mod tests {
|
||||
use bimap::BiMap;
|
||||
use pretty_assertions::assert_str_eq;
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
@@ -926,7 +927,7 @@ mod tests {
|
||||
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
|
||||
|
||||
EditCollectionHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::EditCollectionRootFolderPathInput,
|
||||
None,
|
||||
@@ -942,7 +943,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.path
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1019,6 +1020,22 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_edit_collection_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 = EditCollectionHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_edit_collection_params() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handle_table_events;
|
||||
use crate::handlers::radarr_handlers::collections::collection_details_handler::CollectionDetailsHandler;
|
||||
use crate::handlers::radarr_handlers::collections::edit_collection_handler::EditCollectionHandler;
|
||||
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
|
||||
@@ -14,6 +12,7 @@ use crate::models::servarr_data::radarr::radarr_data::{
|
||||
use crate::models::stateful_table::SortOption;
|
||||
use crate::models::BlockSelectionState;
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_table_events, matches_key};
|
||||
|
||||
mod collection_details_handler;
|
||||
mod edit_collection_handler;
|
||||
@@ -73,6 +72,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
|
||||
|| COLLECTIONS_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>,
|
||||
@@ -145,7 +148,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
|
||||
let key = self.key;
|
||||
match self.active_radarr_block {
|
||||
ActiveRadarrBlock::Collections => match self.key {
|
||||
_ if key == DEFAULT_KEYBINDINGS.edit.key => {
|
||||
_ if matches_key!(edit, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
|
||||
@@ -154,18 +157,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
|
||||
self.app.data.radarr_data.selected_block =
|
||||
BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS);
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.update.key => {
|
||||
_ if matches_key!(update, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.refresh.key => {
|
||||
_ if matches_key!(refresh, key) => {
|
||||
self.app.should_refresh = true;
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
ActiveRadarrBlock::UpdateAllCollectionsPrompt => {
|
||||
if key == DEFAULT_KEYBINDINGS.confirm.key {
|
||||
if matches_key!(confirm, key) {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateCollections);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
@@ -387,6 +388,22 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_downloads_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 = DownloadsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_download_id() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handle_table_events;
|
||||
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
|
||||
use crate::handlers::table_handler::TableHandlingConfig;
|
||||
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
|
||||
use crate::models::radarr_models::DownloadRecord;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS};
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_table_events, matches_key};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "downloads_handler_tests.rs"]
|
||||
@@ -47,6 +46,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DownloadsHandler<'a,
|
||||
DOWNLOADS_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>,
|
||||
@@ -130,18 +133,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DownloadsHandler<'a,
|
||||
let key = self.key;
|
||||
match self.active_radarr_block {
|
||||
ActiveRadarrBlock::Downloads => match self.key {
|
||||
_ if key == DEFAULT_KEYBINDINGS.update.key => {
|
||||
_ if matches_key!(update, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::UpdateDownloadsPrompt.into());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.refresh.key => {
|
||||
_ if matches_key!(refresh, key) => {
|
||||
self.app.should_refresh = true;
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
ActiveRadarrBlock::DeleteDownloadPrompt => {
|
||||
if key == DEFAULT_KEYBINDINGS.confirm.key {
|
||||
if matches_key!(confirm, key) {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action =
|
||||
Some(RadarrEvent::DeleteDownload(self.extract_download_id()));
|
||||
@@ -150,7 +153,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DownloadsHandler<'a,
|
||||
}
|
||||
}
|
||||
ActiveRadarrBlock::UpdateDownloadsPrompt => {
|
||||
if key == DEFAULT_KEYBINDINGS.confirm.key {
|
||||
if matches_key!(confirm, key) {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateDownloads);
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
|
||||
@@ -6,7 +5,9 @@ use crate::models::servarr_data::modals::EditIndexerModal;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_INDEXER_BLOCKS};
|
||||
use crate::models::servarr_models::EditIndexerParams;
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys};
|
||||
use crate::{
|
||||
handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys, matches_key,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "edit_indexer_handler_tests.rs"]
|
||||
@@ -65,6 +66,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditIndexerHandler<'
|
||||
EDIT_INDEXER_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>,
|
||||
@@ -504,7 +509,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditIndexerHandler<'
|
||||
ActiveRadarrBlock::EditIndexerPrompt => {
|
||||
if self.app.data.radarr_data.selected_block.get_active_block()
|
||||
== ActiveRadarrBlock::EditIndexerConfirmPrompt
|
||||
&& self.key == DEFAULT_KEYBINDINGS.confirm.key
|
||||
&& matches_key!(confirm, self.key)
|
||||
{
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action =
|
||||
|
||||
@@ -10,6 +10,7 @@ mod tests {
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_INDEXER_BLOCKS};
|
||||
use crate::models::servarr_models::EditIndexerParams;
|
||||
use pretty_assertions::assert_eq;
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
mod test_handle_scroll_up_and_down {
|
||||
@@ -1597,7 +1598,7 @@ mod tests {
|
||||
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
|
||||
|
||||
EditIndexerHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::EditIndexerNameInput,
|
||||
None,
|
||||
@@ -1613,7 +1614,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.name
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1624,7 +1625,7 @@ mod tests {
|
||||
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
|
||||
|
||||
EditIndexerHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::EditIndexerUrlInput,
|
||||
None,
|
||||
@@ -1640,7 +1641,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.url
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1651,7 +1652,7 @@ mod tests {
|
||||
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
|
||||
|
||||
EditIndexerHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::EditIndexerApiKeyInput,
|
||||
None,
|
||||
@@ -1667,7 +1668,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.api_key
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1678,7 +1679,7 @@ mod tests {
|
||||
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
|
||||
|
||||
EditIndexerHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::EditIndexerSeedRatioInput,
|
||||
None,
|
||||
@@ -1694,7 +1695,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.seed_ratio
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1705,7 +1706,7 @@ mod tests {
|
||||
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
|
||||
|
||||
EditIndexerHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::EditIndexerTagsInput,
|
||||
None,
|
||||
@@ -1721,7 +1722,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.tags
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1793,6 +1794,22 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_edit_indexer_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 = EditIndexerHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_edit_indexer_params() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
|
||||
@@ -7,7 +6,9 @@ use crate::models::servarr_data::radarr::radarr_data::{
|
||||
ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS,
|
||||
};
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys};
|
||||
use crate::{
|
||||
handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys, matches_key,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "edit_indexer_settings_handler_tests.rs"]
|
||||
@@ -37,6 +38,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexerSettingsHandl
|
||||
INDEXER_SETTINGS_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>,
|
||||
@@ -269,7 +274,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexerSettingsHandl
|
||||
ActiveRadarrBlock::AllIndexerSettingsPrompt => {
|
||||
if self.app.data.radarr_data.selected_block.get_active_block()
|
||||
== ActiveRadarrBlock::IndexerSettingsConfirmPrompt
|
||||
&& self.key == DEFAULT_KEYBINDINGS.confirm.key
|
||||
&& matches_key!(confirm, self.key)
|
||||
{
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action = Some(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
@@ -907,7 +908,7 @@ mod tests {
|
||||
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
|
||||
|
||||
IndexerSettingsHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput,
|
||||
None,
|
||||
@@ -923,7 +924,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.whitelisted_hardcoded_subs
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -970,6 +971,22 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_indexer_settings_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 = IndexerSettingsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_edit_indexer_settings_body() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -633,6 +633,22 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_indexers_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 = IndexersHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_indexer_id() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handle_table_events;
|
||||
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
|
||||
use crate::handlers::radarr_handlers::indexers::edit_indexer_handler::EditIndexerHandler;
|
||||
use crate::handlers::radarr_handlers::indexers::edit_indexer_settings_handler::IndexerSettingsHandler;
|
||||
@@ -15,6 +13,7 @@ use crate::models::servarr_data::radarr::radarr_data::{
|
||||
use crate::models::servarr_models::Indexer;
|
||||
use crate::models::BlockSelectionState;
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_table_events, matches_key};
|
||||
|
||||
mod edit_indexer_handler;
|
||||
mod edit_indexer_settings_handler;
|
||||
@@ -70,6 +69,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a,
|
||||
|| INDEXERS_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>,
|
||||
@@ -169,20 +172,20 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a,
|
||||
let key = self.key;
|
||||
match self.active_radarr_block {
|
||||
ActiveRadarrBlock::Indexers => match self.key {
|
||||
_ if key == DEFAULT_KEYBINDINGS.refresh.key => {
|
||||
_ if matches_key!(refresh, key) => {
|
||||
self.app.should_refresh = true;
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.test.key => {
|
||||
_ if matches_key!(test, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::TestIndexer.into());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.test_all.key => {
|
||||
_ if matches_key!(test_all, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::TestAllIndexers.into());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.settings.key => {
|
||||
_ if matches_key!(settings, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
|
||||
@@ -192,7 +195,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a,
|
||||
_ => (),
|
||||
},
|
||||
ActiveRadarrBlock::DeleteIndexerPrompt => {
|
||||
if key == DEFAULT_KEYBINDINGS.confirm.key {
|
||||
if matches_key!(confirm, key) {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action =
|
||||
Some(RadarrEvent::DeleteIndexer(self.extract_indexer_id()));
|
||||
|
||||
@@ -48,6 +48,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for TestAllIndexersHandl
|
||||
active_block == ActiveRadarrBlock::TestAllIndexers
|
||||
}
|
||||
|
||||
fn ignore_alt_navigation(&self) -> bool {
|
||||
self.app.should_ignore_quit_key
|
||||
}
|
||||
|
||||
fn new(
|
||||
key: Key,
|
||||
app: &'a mut App<'b>,
|
||||
|
||||
@@ -7,6 +7,7 @@ mod tests {
|
||||
use crate::models::servarr_data::modals::IndexerTestResultModalItem;
|
||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||
use crate::models::stateful_table::StatefulTable;
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
mod test_handle_esc {
|
||||
@@ -48,6 +49,22 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_test_all_indexers_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 = TestAllIndexersHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_test_all_indexers_handler_is_not_ready_when_loading() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::handlers::table_handler::TableHandlingConfig;
|
||||
use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
|
||||
use crate::models::radarr_models::{
|
||||
@@ -11,7 +10,9 @@ use crate::models::servarr_data::radarr::radarr_data::{
|
||||
use crate::models::stateful_table::StatefulTable;
|
||||
use crate::models::{BlockSelectionState, Scrollable};
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys, App, Key};
|
||||
use crate::{
|
||||
handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys, matches_key, App, Key,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "add_movie_handler_tests.rs"]
|
||||
@@ -132,6 +133,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
|
||||
ADD_MOVIE_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>,
|
||||
@@ -542,7 +547,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
|
||||
ActiveRadarrBlock::AddMoviePrompt => {
|
||||
if self.app.data.radarr_data.selected_block.get_active_block()
|
||||
== ActiveRadarrBlock::AddMovieConfirmPrompt
|
||||
&& key == DEFAULT_KEYBINDINGS.confirm.key
|
||||
&& matches_key!(confirm, key)
|
||||
{
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action =
|
||||
|
||||
@@ -1395,7 +1395,7 @@ mod tests {
|
||||
app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default());
|
||||
|
||||
AddMovieHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::AddMovieSearchInput,
|
||||
None,
|
||||
@@ -1404,7 +1404,7 @@ mod tests {
|
||||
|
||||
assert_str_eq!(
|
||||
app.data.radarr_data.add_movie_search.as_ref().unwrap().text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1414,7 +1414,7 @@ mod tests {
|
||||
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
|
||||
|
||||
AddMovieHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::AddMovieTagsInput,
|
||||
None,
|
||||
@@ -1430,7 +1430,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.tags
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1523,6 +1523,22 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_add_movie_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 = AddMovieHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_movie_search_no_panic_on_none_search_result() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -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::radarr_models::DeleteMovieParams;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS};
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
@@ -37,6 +37,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DeleteMovieHandler<'
|
||||
DELETE_MOVIE_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>,
|
||||
@@ -122,7 +126,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DeleteMovieHandler<'
|
||||
if self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt
|
||||
&& self.app.data.radarr_data.selected_block.get_active_block()
|
||||
== ActiveRadarrBlock::DeleteMovieConfirmPrompt
|
||||
&& self.key == DEFAULT_KEYBINDINGS.confirm.key
|
||||
&& matches_key!(confirm, self.key)
|
||||
{
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action =
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
@@ -313,6 +314,22 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_delete_movie_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 = DeleteMovieHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_delete_movie_params() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
|
||||
@@ -7,7 +6,7 @@ use crate::models::servarr_data::radarr::modals::EditMovieModal;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS};
|
||||
use crate::models::Scrollable;
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_text_box_keys, handle_text_box_left_right_keys};
|
||||
use crate::{handle_text_box_keys, handle_text_box_left_right_keys, matches_key};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "edit_movie_handler_tests.rs"]
|
||||
@@ -68,6 +67,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a,
|
||||
EDIT_MOVIE_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>,
|
||||
@@ -376,7 +379,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a,
|
||||
ActiveRadarrBlock::EditMoviePrompt => {
|
||||
if self.app.data.radarr_data.selected_block.get_active_block()
|
||||
== ActiveRadarrBlock::EditMovieConfirmPrompt
|
||||
&& key == DEFAULT_KEYBINDINGS.confirm.key
|
||||
&& matches_key!(confirm, key)
|
||||
{
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action =
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
mod tests {
|
||||
use bimap::BiMap;
|
||||
use pretty_assertions::assert_str_eq;
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
@@ -1033,7 +1034,7 @@ mod tests {
|
||||
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
|
||||
|
||||
EditMovieHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::EditMoviePathInput,
|
||||
None,
|
||||
@@ -1049,7 +1050,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.path
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1059,7 +1060,7 @@ mod tests {
|
||||
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
|
||||
|
||||
EditMovieHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::EditMovieTagsInput,
|
||||
None,
|
||||
@@ -1075,7 +1076,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.tags
|
||||
.text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1148,6 +1149,22 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_edit_movie_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 = EditMovieHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_edit_movie_params() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -777,6 +777,22 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_library_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 = LibraryHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_library_handler_not_ready_when_loading() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
|
||||
@@ -8,7 +7,6 @@ use crate::handlers::radarr_handlers::library::edit_movie_handler::EditMovieHand
|
||||
use crate::handlers::radarr_handlers::library::movie_details_handler::MovieDetailsHandler;
|
||||
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
|
||||
|
||||
use crate::handle_table_events;
|
||||
use crate::handlers::table_handler::TableHandlingConfig;
|
||||
use crate::models::radarr_models::Movie;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{
|
||||
@@ -17,6 +15,7 @@ use crate::models::servarr_data::radarr::radarr_data::{
|
||||
use crate::models::stateful_table::SortOption;
|
||||
use crate::models::{BlockSelectionState, HorizontallyScrollableText};
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_table_events, matches_key};
|
||||
|
||||
mod add_movie_handler;
|
||||
mod delete_movie_handler;
|
||||
@@ -81,6 +80,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
|
||||
|| LIBRARY_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>,
|
||||
@@ -161,7 +164,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
|
||||
let key = self.key;
|
||||
match self.active_radarr_block {
|
||||
ActiveRadarrBlock::Movies => match self.key {
|
||||
_ if key == DEFAULT_KEYBINDINGS.edit.key => {
|
||||
_ if matches_key!(edit, key) => {
|
||||
self.app.push_navigation_stack(
|
||||
(
|
||||
ActiveRadarrBlock::EditMoviePrompt,
|
||||
@@ -173,25 +176,25 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
|
||||
self.app.data.radarr_data.selected_block =
|
||||
BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS);
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.add.key => {
|
||||
_ if matches_key!(add, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into());
|
||||
self.app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default());
|
||||
self.app.should_ignore_quit_key = true;
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.update.key => {
|
||||
_ if matches_key!(update, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.refresh.key => {
|
||||
_ if matches_key!(refresh, key) => {
|
||||
self.app.should_refresh = true;
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
ActiveRadarrBlock::UpdateAllMoviesPrompt => {
|
||||
if key == DEFAULT_KEYBINDINGS.confirm.key {
|
||||
if matches_key!(confirm, key) {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateAllMovies);
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use serde_json::Number;
|
||||
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handle_table_events;
|
||||
use crate::handlers::table_handler::TableHandlingConfig;
|
||||
use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
|
||||
use crate::models::radarr_models::{
|
||||
@@ -16,6 +14,7 @@ use crate::models::servarr_models::Language;
|
||||
use crate::models::stateful_table::SortOption;
|
||||
use crate::models::{BlockSelectionState, Scrollable};
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_table_events, matches_key};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "movie_details_handler_tests.rs"]
|
||||
@@ -136,6 +135,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
|
||||
MOVIE_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>,
|
||||
@@ -245,13 +248,13 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
|
||||
| ActiveRadarrBlock::Cast
|
||||
| ActiveRadarrBlock::Crew
|
||||
| ActiveRadarrBlock::ManualSearch => match self.key {
|
||||
_ if self.key == DEFAULT_KEYBINDINGS.left.key => {
|
||||
_ if matches_key!(left, self.key) => {
|
||||
self.app.data.radarr_data.movie_info_tabs.previous();
|
||||
self.app.pop_and_push_navigation_stack(
|
||||
self.app.data.radarr_data.movie_info_tabs.get_active_route(),
|
||||
);
|
||||
}
|
||||
_ if self.key == DEFAULT_KEYBINDINGS.right.key => {
|
||||
_ if matches_key!(right, self.key) => {
|
||||
self.app.data.radarr_data.movie_info_tabs.next();
|
||||
self.app.pop_and_push_navigation_stack(
|
||||
self.app.data.radarr_data.movie_info_tabs.get_active_route(),
|
||||
@@ -332,12 +335,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
|
||||
| ActiveRadarrBlock::Cast
|
||||
| ActiveRadarrBlock::Crew
|
||||
| ActiveRadarrBlock::ManualSearch => match self.key {
|
||||
_ if key == DEFAULT_KEYBINDINGS.auto_search.key => {
|
||||
_ if matches_key!(auto_search, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::AutomaticallySearchMoviePrompt.into());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.edit.key => {
|
||||
_ if matches_key!(edit, key) => {
|
||||
self.app.push_navigation_stack(
|
||||
(
|
||||
ActiveRadarrBlock::EditMoviePrompt,
|
||||
@@ -349,35 +352,33 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
|
||||
self.app.data.radarr_data.selected_block =
|
||||
BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS);
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.update.key => {
|
||||
_ if matches_key!(update, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::UpdateAndScanPrompt.into());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.refresh.key => {
|
||||
_ if matches_key!(refresh, key) => {
|
||||
self
|
||||
.app
|
||||
.pop_and_push_navigation_stack(self.active_radarr_block.into());
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
ActiveRadarrBlock::AutomaticallySearchMoviePrompt
|
||||
if key == DEFAULT_KEYBINDINGS.confirm.key =>
|
||||
{
|
||||
ActiveRadarrBlock::AutomaticallySearchMoviePrompt if matches_key!(confirm, key) => {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action =
|
||||
Some(RadarrEvent::TriggerAutomaticSearch(self.extract_movie_id()));
|
||||
|
||||
self.app.pop_navigation_stack();
|
||||
}
|
||||
ActiveRadarrBlock::UpdateAndScanPrompt if key == DEFAULT_KEYBINDINGS.confirm.key => {
|
||||
ActiveRadarrBlock::UpdateAndScanPrompt if matches_key!(confirm, key) => {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action =
|
||||
Some(RadarrEvent::UpdateAndScan(self.extract_movie_id()));
|
||||
|
||||
self.app.pop_navigation_stack();
|
||||
}
|
||||
ActiveRadarrBlock::ManualSearchConfirmPrompt if key == DEFAULT_KEYBINDINGS.confirm.key => {
|
||||
ActiveRadarrBlock::ManualSearchConfirmPrompt if matches_key!(confirm, key) => {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DownloadRelease(
|
||||
self.build_radarr_release_download_body(),
|
||||
|
||||
@@ -1042,6 +1042,22 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_movie_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 = MovieDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_movie_details_handler_is_not_ready_when_loading(
|
||||
#[values(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::handlers::radarr_handlers::blocklist::BlocklistHandler;
|
||||
use crate::handlers::radarr_handlers::collections::CollectionsHandler;
|
||||
use crate::handlers::radarr_handlers::downloads::DownloadsHandler;
|
||||
@@ -8,7 +7,7 @@ use crate::handlers::radarr_handlers::root_folders::RootFoldersHandler;
|
||||
use crate::handlers::radarr_handlers::system::SystemHandler;
|
||||
use crate::handlers::KeyEventHandler;
|
||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||
use crate::{App, Key};
|
||||
use crate::{matches_key, App, Key};
|
||||
|
||||
mod blocklist;
|
||||
mod collections;
|
||||
@@ -65,6 +64,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
|
||||
true
|
||||
}
|
||||
|
||||
fn ignore_alt_navigation(&self) -> bool {
|
||||
self.app.should_ignore_quit_key
|
||||
}
|
||||
|
||||
fn new(
|
||||
key: Key,
|
||||
app: &'a mut App<'b>,
|
||||
@@ -109,11 +112,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
|
||||
pub fn handle_change_tab_left_right_keys(app: &mut App<'_>, key: Key) {
|
||||
let key_ref = key;
|
||||
match key_ref {
|
||||
_ if key == DEFAULT_KEYBINDINGS.left.key => {
|
||||
_ if matches_key!(left, key, app.should_ignore_quit_key) => {
|
||||
app.data.radarr_data.main_tabs.previous();
|
||||
app.pop_and_push_navigation_stack(app.data.radarr_data.main_tabs.get_active_route());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.right.key => {
|
||||
_ if matches_key!(right, key, app.should_ignore_quit_key) => {
|
||||
app.data.radarr_data.main_tabs.next();
|
||||
app.pop_and_push_navigation_stack(app.data.radarr_data.main_tabs.get_active_route());
|
||||
}
|
||||
|
||||
@@ -46,6 +46,76 @@ mod tests {
|
||||
assert_eq!(app.get_current_route(), right_block.into());
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0, ActiveRadarrBlock::System, ActiveRadarrBlock::Collections)]
|
||||
#[case(1, ActiveRadarrBlock::Movies, ActiveRadarrBlock::Downloads)]
|
||||
#[case(2, ActiveRadarrBlock::Collections, ActiveRadarrBlock::Blocklist)]
|
||||
#[case(3, ActiveRadarrBlock::Downloads, ActiveRadarrBlock::RootFolders)]
|
||||
#[case(4, ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Indexers)]
|
||||
#[case(5, ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::System)]
|
||||
#[case(6, ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Movies)]
|
||||
fn test_radarr_handler_change_tab_left_right_keys_alt_navigation(
|
||||
#[case] index: usize,
|
||||
#[case] left_block: ActiveRadarrBlock,
|
||||
#[case] right_block: ActiveRadarrBlock,
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.should_ignore_quit_key = false;
|
||||
app.data.radarr_data.main_tabs.set_index(index);
|
||||
|
||||
handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.left.alt.unwrap());
|
||||
|
||||
assert_eq!(
|
||||
app.data.radarr_data.main_tabs.get_active_route(),
|
||||
left_block.into()
|
||||
);
|
||||
assert_eq!(app.get_current_route(), left_block.into());
|
||||
|
||||
app.data.radarr_data.main_tabs.set_index(index);
|
||||
|
||||
handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.right.alt.unwrap());
|
||||
|
||||
assert_eq!(
|
||||
app.data.radarr_data.main_tabs.get_active_route(),
|
||||
right_block.into()
|
||||
);
|
||||
assert_eq!(app.get_current_route(), right_block.into());
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0, ActiveRadarrBlock::Movies)]
|
||||
#[case(1, ActiveRadarrBlock::Collections)]
|
||||
#[case(2, ActiveRadarrBlock::Downloads)]
|
||||
#[case(3, ActiveRadarrBlock::Blocklist)]
|
||||
#[case(4, ActiveRadarrBlock::RootFolders)]
|
||||
#[case(5, ActiveRadarrBlock::Indexers)]
|
||||
#[case(6, ActiveRadarrBlock::System)]
|
||||
fn test_radarr_handler_change_tab_left_right_keys_alt_navigation_no_op_when_ignoring_quit_key(
|
||||
#[case] index: usize,
|
||||
#[case] block: ActiveRadarrBlock,
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.should_ignore_quit_key = true;
|
||||
app.push_navigation_stack(block.into());
|
||||
app.data.radarr_data.main_tabs.set_index(index);
|
||||
|
||||
handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.left.alt.unwrap());
|
||||
|
||||
assert_eq!(
|
||||
app.data.radarr_data.main_tabs.get_active_route(),
|
||||
block.into()
|
||||
);
|
||||
assert_eq!(app.get_current_route(), block.into());
|
||||
|
||||
handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.right.alt.unwrap());
|
||||
|
||||
assert_eq!(
|
||||
app.data.radarr_data.main_tabs.get_active_route(),
|
||||
block.into()
|
||||
);
|
||||
assert_eq!(app.get_current_route(), block.into());
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_delegates_system_blocks_to_system_handler(
|
||||
#[values(
|
||||
@@ -217,6 +287,22 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_radarr_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 = RadarrHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::Movies,
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_radarr_handler_is_ready() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
|
||||
@@ -8,7 +7,9 @@ use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_F
|
||||
use crate::models::servarr_models::{AddRootFolderBody, RootFolder};
|
||||
use crate::models::HorizontallyScrollableText;
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::{handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys};
|
||||
use crate::{
|
||||
handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys, matches_key,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "root_folders_handler_tests.rs"]
|
||||
@@ -68,6 +69,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RootFoldersHandler<'
|
||||
ROOT_FOLDERS_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>,
|
||||
@@ -195,10 +200,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RootFoldersHandler<'
|
||||
let key = self.key;
|
||||
match self.active_radarr_block {
|
||||
ActiveRadarrBlock::RootFolders => match self.key {
|
||||
_ if key == DEFAULT_KEYBINDINGS.refresh.key => {
|
||||
_ if matches_key!(refresh, key) => {
|
||||
self.app.should_refresh = true;
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.add.key => {
|
||||
_ if matches_key!(add, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into());
|
||||
@@ -215,7 +220,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RootFoldersHandler<'
|
||||
)
|
||||
}
|
||||
ActiveRadarrBlock::DeleteRootFolderPrompt => {
|
||||
if key == DEFAULT_KEYBINDINGS.confirm.key {
|
||||
if matches_key!(confirm, key) {
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_data.prompt_confirm_action =
|
||||
Some(RadarrEvent::DeleteRootFolder(self.extract_root_folder_id()));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
@@ -589,7 +590,7 @@ mod tests {
|
||||
app.data.radarr_data.edit_root_folder = Some(HorizontallyScrollableText::default());
|
||||
|
||||
RootFoldersHandler::new(
|
||||
Key::Char('h'),
|
||||
Key::Char('a'),
|
||||
&mut app,
|
||||
ActiveRadarrBlock::AddRootFolderPrompt,
|
||||
None,
|
||||
@@ -598,7 +599,7 @@ mod tests {
|
||||
|
||||
assert_str_eq!(
|
||||
app.data.radarr_data.edit_root_folder.as_ref().unwrap().text,
|
||||
"h"
|
||||
"a"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -644,6 +645,22 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_root_folders_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 = RootFoldersHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_add_root_folder_body() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
|
||||
use crate::handlers::radarr_handlers::system::system_details_handler::SystemDetailsHandler;
|
||||
use crate::handlers::{handle_clear_errors, KeyEventHandler};
|
||||
use crate::matches_key;
|
||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||
use crate::models::Scrollable;
|
||||
|
||||
@@ -35,6 +35,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemHandler<'a, 'b
|
||||
SystemDetailsHandler::accepts(active_block) || active_block == ActiveRadarrBlock::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, ActiveRadarrBlock> for SystemHandler<'a, 'b
|
||||
if self.active_radarr_block == ActiveRadarrBlock::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(ActiveRadarrBlock::SystemQueuedEvents.into());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.logs.key => {
|
||||
_ if matches_key!(logs, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::SystemLogs.into());
|
||||
@@ -106,12 +110,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemHandler<'a, 'b
|
||||
.set_items(self.app.data.radarr_data.logs.items.to_vec());
|
||||
self.app.data.radarr_data.log_details.scroll_to_bottom();
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.tasks.key => {
|
||||
_ if matches_key!(tasks, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
|
||||
}
|
||||
_ if key == DEFAULT_KEYBINDINGS.update.key => {
|
||||
_ if matches_key!(update, key) => {
|
||||
self
|
||||
.app
|
||||
.push_navigation_stack(ActiveRadarrBlock::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::radarr_models::RadarrTaskName;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS};
|
||||
use crate::models::stateful_list::StatefulList;
|
||||
@@ -36,6 +36,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> 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, ActiveRadarrBlock> for SystemDetailsHandler
|
||||
|
||||
match self.active_radarr_block {
|
||||
ActiveRadarrBlock::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, ActiveRadarrBlock> 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, ActiveRadarrBlock> for SystemDetailsHandler
|
||||
}
|
||||
|
||||
fn handle_char_key_event(&mut self) {
|
||||
if SYSTEM_DETAILS_BLOCKS.contains(&self.active_radarr_block)
|
||||
&& self.key == DEFAULT_KEYBINDINGS.refresh.key
|
||||
if SYSTEM_DETAILS_BLOCKS.contains(&self.active_radarr_block) && matches_key!(refresh, self.key)
|
||||
{
|
||||
self.app.should_refresh = true;
|
||||
}
|
||||
|
||||
if self.active_radarr_block == ActiveRadarrBlock::SystemTaskStartConfirmPrompt
|
||||
&& self.key == DEFAULT_KEYBINDINGS.confirm.key
|
||||
&& matches_key!(confirm, self.key)
|
||||
{
|
||||
self.app.data.radarr_data.prompt_confirm = true;
|
||||
self.app.data.radarr_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;
|
||||
@@ -938,6 +939,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,
|
||||
ActiveRadarrBlock::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_task_name() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -450,6 +450,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,
|
||||
ActiveRadarrBlock::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();
|
||||
|
||||
Reference in New Issue
Block a user