feat: Added support for a system-wide notification popup mechanism that works across Servarrs

This commit is contained in:
2026-02-03 17:03:12 -07:00
parent 447cf6a2b4
commit af573cac2a
16 changed files with 587 additions and 21 deletions
+34 -1
View File
@@ -20,10 +20,10 @@ mod tests {
use crate::handlers::{handle_events, populate_keymapping_table};
use crate::models::HorizontallyScrollableText;
use crate::models::Route;
use crate::models::servarr_data::ActiveKeybindingBlock;
use crate::models::servarr_data::lidarr::lidarr_data::ActiveLidarrBlock;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData};
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
use crate::models::servarr_data::{ActiveKeybindingBlock, Notification};
use crate::models::servarr_models::KeybindingItem;
use crate::models::stateful_table::StatefulTable;
@@ -284,6 +284,39 @@ mod tests {
);
}
#[test]
fn test_handle_events_esc_clears_notification() {
let mut app = App::test_default();
app.notification = Some(Notification::new(
"Download Result".to_owned(),
"Download request sent successfully".to_owned(),
true,
));
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
handle_events(DEFAULT_KEYBINDINGS.esc.key, &mut app);
assert_none!(app.notification);
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into());
}
#[test]
fn test_handle_events_esc_does_not_clear_notification_when_none() {
let mut app = App::test_default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
handle_events(DEFAULT_KEYBINDINGS.esc.key, &mut app);
assert_none!(app.notification);
assert_navigation_popped!(app, ActiveRadarrBlock::Movies.into());
}
fn context_clue_to_keybinding_item(key: &KeyBinding, desc: &&str) -> KeybindingItem {
let (key, alt_key) = if key.alt.is_some() {
(key.key.to_string(), key.alt.as_ref().unwrap().to_string())
+7 -2
View File
@@ -2,11 +2,11 @@ use lidarr_handlers::LidarrHandler;
use radarr_handlers::RadarrHandler;
use sonarr_handlers::SonarrHandler;
use crate::app::App;
use crate::app::context_clues::{
ContextClueProvider, SERVARR_CONTEXT_CLUES, ServarrContextClueProvider,
ContextClueProvider, ServarrContextClueProvider, SERVARR_CONTEXT_CLUES,
};
use crate::app::key_binding::KeyBinding;
use crate::app::App;
use crate::event::Key;
use crate::handlers::keybinding_handler::KeybindingHandler;
use crate::matches_key;
@@ -116,6 +116,7 @@ pub fn handle_events(key: Key, app: &mut App<'_>) {
} else {
app.keymapping_table = None;
}
} else if matches_key!(esc, key) && handle_clear_notification(app) {
} else {
match app.get_current_route() {
_ if app.keymapping_table.is_some() => {
@@ -183,6 +184,10 @@ fn handle_clear_errors(app: &mut App<'_>) {
}
}
fn handle_clear_notification(app: &mut App<'_>) -> bool {
app.notification.take().is_some()
}
fn handle_prompt_toggle(app: &mut App<'_>, key: Key) {
match key {
_ if matches_key!(left, key) || matches_key!(right, key) => match app.get_current_route() {