Added the ability to view Radarr updates and remapped the events queue key to 'z'
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "managarr"
|
name = "managarr"
|
||||||
version = "0.0.18"
|
version = "0.0.19"
|
||||||
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
|
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
|
||||||
description = "A TUI for managing *arr servers"
|
description = "A TUI for managing *arr servers"
|
||||||
keywords = ["managarr", "tui-rs", "dashboard", "servarr"]
|
keywords = ["managarr", "tui-rs", "dashboard", "servarr"]
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ tautulli:
|
|||||||
- [ ] Manage your quality profiles
|
- [ ] Manage your quality profiles
|
||||||
- [ ] Manage your quality definitions
|
- [ ] Manage your quality definitions
|
||||||
- [ ] Manage your indexers
|
- [ ] Manage your indexers
|
||||||
- [x] View and browse logs, tasks, and events queues
|
- [x] View and browse logs, tasks, events queues, and updates
|
||||||
- [x] Manually trigger scheduled tasks
|
- [x] Manually trigger scheduled tasks
|
||||||
|
|
||||||
### Sonarr
|
### Sonarr
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ generate_keybindings! {
|
|||||||
tasks,
|
tasks,
|
||||||
refresh,
|
refresh,
|
||||||
update,
|
update,
|
||||||
|
queue,
|
||||||
home,
|
home,
|
||||||
end,
|
end,
|
||||||
delete,
|
delete,
|
||||||
@@ -91,7 +92,11 @@ pub const DEFAULT_KEYBINDINGS: KeyBindings = KeyBindings {
|
|||||||
},
|
},
|
||||||
update: KeyBinding {
|
update: KeyBinding {
|
||||||
key: Key::Char('u'),
|
key: Key::Char('u'),
|
||||||
desc: "Update All",
|
desc: "Update",
|
||||||
|
},
|
||||||
|
queue: KeyBinding {
|
||||||
|
key: Key::Char('z'),
|
||||||
|
desc: "Queue",
|
||||||
},
|
},
|
||||||
home: KeyBinding {
|
home: KeyBinding {
|
||||||
key: Key::Home,
|
key: Key::Home,
|
||||||
|
|||||||
+13
-4
@@ -54,6 +54,7 @@ pub struct RadarrData<'a> {
|
|||||||
pub log_details: StatefulList<HorizontallyScrollableText>,
|
pub log_details: StatefulList<HorizontallyScrollableText>,
|
||||||
pub tasks: StatefulTable<Task>,
|
pub tasks: StatefulTable<Task>,
|
||||||
pub queued_events: StatefulTable<QueueEvent>,
|
pub queued_events: StatefulTable<QueueEvent>,
|
||||||
|
pub updates: ScrollableText,
|
||||||
pub prompt_confirm_action: Option<RadarrEvent>,
|
pub prompt_confirm_action: Option<RadarrEvent>,
|
||||||
pub main_tabs: TabState,
|
pub main_tabs: TabState,
|
||||||
pub movie_info_tabs: TabState,
|
pub movie_info_tabs: TabState,
|
||||||
@@ -278,6 +279,7 @@ impl<'a> Default for RadarrData<'a> {
|
|||||||
log_details: StatefulList::default(),
|
log_details: StatefulList::default(),
|
||||||
tasks: StatefulTable::default(),
|
tasks: StatefulTable::default(),
|
||||||
queued_events: StatefulTable::default(),
|
queued_events: StatefulTable::default(),
|
||||||
|
updates: ScrollableText::default(),
|
||||||
prompt_confirm_action: None,
|
prompt_confirm_action: None,
|
||||||
search: HorizontallyScrollableText::default(),
|
search: HorizontallyScrollableText::default(),
|
||||||
filter: HorizontallyScrollableText::default(),
|
filter: HorizontallyScrollableText::default(),
|
||||||
@@ -320,7 +322,7 @@ impl<'a> Default for RadarrData<'a> {
|
|||||||
title: "System",
|
title: "System",
|
||||||
route: ActiveRadarrBlock::System.into(),
|
route: ActiveRadarrBlock::System.into(),
|
||||||
help: "",
|
help: "",
|
||||||
contextual_help: Some("<t> open tasks | <u> open queue | <l> open logs | <r> refresh")
|
contextual_help: Some("<t> open tasks | <z> open queue | <l> open logs | <u> open updates | <r> refresh")
|
||||||
}
|
}
|
||||||
]),
|
]),
|
||||||
movie_info_tabs: TabState::new(vec![
|
movie_info_tabs: TabState::new(vec![
|
||||||
@@ -418,9 +420,10 @@ pub enum ActiveRadarrBlock {
|
|||||||
RootFolders,
|
RootFolders,
|
||||||
System,
|
System,
|
||||||
SystemLogs,
|
SystemLogs,
|
||||||
|
SystemQueue,
|
||||||
SystemTasks,
|
SystemTasks,
|
||||||
SystemTaskStartConfirmPrompt,
|
SystemTaskStartConfirmPrompt,
|
||||||
SystemQueue,
|
SystemUpdates,
|
||||||
UpdateAndScanPrompt,
|
UpdateAndScanPrompt,
|
||||||
UpdateAllCollectionsPrompt,
|
UpdateAllCollectionsPrompt,
|
||||||
UpdateAllMoviesPrompt,
|
UpdateAllMoviesPrompt,
|
||||||
@@ -519,11 +522,12 @@ pub static DELETE_MOVIE_SELECTION_BLOCKS: [ActiveRadarrBlock; 3] = [
|
|||||||
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion,
|
ActiveRadarrBlock::DeleteMovieToggleAddListExclusion,
|
||||||
ActiveRadarrBlock::DeleteMovieConfirmPrompt,
|
ActiveRadarrBlock::DeleteMovieConfirmPrompt,
|
||||||
];
|
];
|
||||||
pub static SYSTEM_DETAILS_BLOCKS: [ActiveRadarrBlock; 4] = [
|
pub static SYSTEM_DETAILS_BLOCKS: [ActiveRadarrBlock; 5] = [
|
||||||
ActiveRadarrBlock::SystemLogs,
|
ActiveRadarrBlock::SystemLogs,
|
||||||
ActiveRadarrBlock::SystemTasks,
|
|
||||||
ActiveRadarrBlock::SystemQueue,
|
ActiveRadarrBlock::SystemQueue,
|
||||||
|
ActiveRadarrBlock::SystemTasks,
|
||||||
ActiveRadarrBlock::SystemTaskStartConfirmPrompt,
|
ActiveRadarrBlock::SystemTaskStartConfirmPrompt,
|
||||||
|
ActiveRadarrBlock::SystemUpdates,
|
||||||
];
|
];
|
||||||
|
|
||||||
impl From<ActiveRadarrBlock> for Route {
|
impl From<ActiveRadarrBlock> for Route {
|
||||||
@@ -580,6 +584,11 @@ impl<'a> App<'a> {
|
|||||||
.dispatch_network_event(RadarrEvent::GetLogs.into())
|
.dispatch_network_event(RadarrEvent::GetLogs.into())
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
ActiveRadarrBlock::SystemUpdates => {
|
||||||
|
self
|
||||||
|
.dispatch_network_event(RadarrEvent::GetUpdates.into())
|
||||||
|
.await;
|
||||||
|
}
|
||||||
ActiveRadarrBlock::AddMovieSearchResults => {
|
ActiveRadarrBlock::AddMovieSearchResults => {
|
||||||
self
|
self
|
||||||
.dispatch_network_event(RadarrEvent::SearchNewMovie.into())
|
.dispatch_network_event(RadarrEvent::SearchNewMovie.into())
|
||||||
|
|||||||
+19
-1
@@ -291,6 +291,7 @@ mod tests {
|
|||||||
assert!(radarr_data.log_details.items.is_empty());
|
assert!(radarr_data.log_details.items.is_empty());
|
||||||
assert!(radarr_data.tasks.items.is_empty());
|
assert!(radarr_data.tasks.items.is_empty());
|
||||||
assert!(radarr_data.queued_events.items.is_empty());
|
assert!(radarr_data.queued_events.items.is_empty());
|
||||||
|
assert!(radarr_data.updates.get_text().is_empty());
|
||||||
assert!(radarr_data.prompt_confirm_action.is_none());
|
assert!(radarr_data.prompt_confirm_action.is_none());
|
||||||
assert!(radarr_data.search.text.is_empty());
|
assert!(radarr_data.search.text.is_empty());
|
||||||
assert!(radarr_data.filter.text.is_empty());
|
assert!(radarr_data.filter.text.is_empty());
|
||||||
@@ -355,7 +356,7 @@ mod tests {
|
|||||||
assert!(radarr_data.main_tabs.tabs[4].help.is_empty());
|
assert!(radarr_data.main_tabs.tabs[4].help.is_empty());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
radarr_data.main_tabs.tabs[4].contextual_help,
|
radarr_data.main_tabs.tabs[4].contextual_help,
|
||||||
Some("<t> open tasks | <u> open queue | <l> open logs | <r> refresh")
|
Some("<t> open tasks | <z> open queue | <l> open logs | <u> open updates | <r> refresh")
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(radarr_data.movie_info_tabs.tabs.len(), 6);
|
assert_eq!(radarr_data.movie_info_tabs.tabs.len(), 6);
|
||||||
@@ -708,6 +709,23 @@ mod tests {
|
|||||||
assert_eq!(app.tick_count, 0);
|
assert_eq!(app.tick_count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_dispatch_by_system_updates_block() {
|
||||||
|
let (mut app, mut sync_network_rx) = construct_app_unit();
|
||||||
|
|
||||||
|
app
|
||||||
|
.dispatch_by_radarr_block(&ActiveRadarrBlock::SystemUpdates)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert!(app.is_loading);
|
||||||
|
assert_eq!(
|
||||||
|
sync_network_rx.recv().await.unwrap(),
|
||||||
|
RadarrEvent::GetUpdates.into()
|
||||||
|
);
|
||||||
|
assert!(!app.data.radarr_data.prompt_confirm);
|
||||||
|
assert_eq!(app.tick_count, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_dispatch_by_add_movie_search_results_block() {
|
async fn test_dispatch_by_add_movie_search_results_block() {
|
||||||
let (mut app, mut sync_network_rx) = construct_app_unit();
|
let (mut app, mut sync_network_rx) = construct_app_unit();
|
||||||
|
|||||||
@@ -238,6 +238,25 @@ mod test_utils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! test_scrollable_text_scroll {
|
||||||
|
($func:ident, $handler:ident, $data_ref:ident, $block:expr) => {
|
||||||
|
#[test]
|
||||||
|
fn $func() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.data.radarr_data.$data_ref = ScrollableText::with_string("Test 1\nTest 2".to_owned());
|
||||||
|
|
||||||
|
$handler::with(&DEFAULT_KEYBINDINGS.up.key, &mut app, &$block, &None).handle();
|
||||||
|
|
||||||
|
assert_eq!(app.data.radarr_data.$data_ref.offset, 0);
|
||||||
|
|
||||||
|
$handler::with(&DEFAULT_KEYBINDINGS.down.key, &mut app, &$block, &None).handle();
|
||||||
|
|
||||||
|
assert_eq!(app.data.radarr_data.$data_ref.offset, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! test_iterable_home_and_end {
|
macro_rules! test_iterable_home_and_end {
|
||||||
($func:ident, $handler:ident, $data_ref:ident, $block:expr, $context:expr) => {
|
($func:ident, $handler:ident, $data_ref:ident, $block:expr, $context:expr) => {
|
||||||
@@ -373,6 +392,25 @@ mod test_utils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! test_scrollable_text_home_and_end {
|
||||||
|
($func:ident, $handler:ident, $data_ref:ident, $block:expr) => {
|
||||||
|
#[test]
|
||||||
|
fn $func() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.data.radarr_data.$data_ref = ScrollableText::with_string("Test 1\nTest 2".to_owned());
|
||||||
|
|
||||||
|
$handler::with(&DEFAULT_KEYBINDINGS.end.key, &mut app, &$block, &None).handle();
|
||||||
|
|
||||||
|
assert_eq!(app.data.radarr_data.$data_ref.offset, 1);
|
||||||
|
|
||||||
|
$handler::with(&DEFAULT_KEYBINDINGS.home.key, &mut app, &$block, &None).handle();
|
||||||
|
|
||||||
|
assert_eq!(app.data.radarr_data.$data_ref.offset, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! test_text_box_home_end_keys {
|
macro_rules! test_text_box_home_end_keys {
|
||||||
($handler:ident, $block:expr, $field:ident) => {
|
($handler:ident, $block:expr, $field:ident) => {
|
||||||
|
|||||||
@@ -574,7 +574,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
|
|||||||
_ if *key == DEFAULT_KEYBINDINGS.refresh.key => {
|
_ if *key == DEFAULT_KEYBINDINGS.refresh.key => {
|
||||||
self.app.should_refresh = true;
|
self.app.should_refresh = true;
|
||||||
}
|
}
|
||||||
_ if *key == DEFAULT_KEYBINDINGS.update.key => {
|
_ if *key == DEFAULT_KEYBINDINGS.queue.key => {
|
||||||
self
|
self
|
||||||
.app
|
.app
|
||||||
.push_navigation_stack(ActiveRadarrBlock::SystemQueue.into());
|
.push_navigation_stack(ActiveRadarrBlock::SystemQueue.into());
|
||||||
@@ -596,6 +596,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
|
|||||||
.app
|
.app
|
||||||
.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
|
.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
|
||||||
}
|
}
|
||||||
|
_ if *key == DEFAULT_KEYBINDINGS.update.key => {
|
||||||
|
self
|
||||||
|
.app
|
||||||
|
.push_navigation_stack(ActiveRadarrBlock::SystemUpdates.into());
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
},
|
},
|
||||||
ActiveRadarrBlock::AddRootFolderPrompt => {
|
ActiveRadarrBlock::AddRootFolderPrompt => {
|
||||||
|
|||||||
@@ -23,35 +23,19 @@ mod tests {
|
|||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
use crate::models::radarr_models::ReleaseField;
|
use crate::models::radarr_models::ReleaseField;
|
||||||
use crate::{simple_stateful_iterable_vec, test_enum_scroll, test_iterable_scroll};
|
use crate::{
|
||||||
|
simple_stateful_iterable_vec, test_enum_scroll, test_iterable_scroll,
|
||||||
|
test_scrollable_text_scroll,
|
||||||
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
test_scrollable_text_scroll!(
|
||||||
fn test_movie_details_scroll() {
|
test_movie_details_scroll,
|
||||||
let mut app = App::default();
|
MovieDetailsHandler,
|
||||||
app.data.radarr_data.movie_details = ScrollableText::with_string("Test 1\nTest 2".to_owned());
|
movie_details,
|
||||||
|
ActiveRadarrBlock::MovieDetails
|
||||||
MovieDetailsHandler::with(
|
);
|
||||||
&DEFAULT_KEYBINDINGS.up.key,
|
|
||||||
&mut app,
|
|
||||||
&ActiveRadarrBlock::MovieDetails,
|
|
||||||
&None,
|
|
||||||
)
|
|
||||||
.handle();
|
|
||||||
|
|
||||||
assert_eq!(app.data.radarr_data.movie_details.offset, 0);
|
|
||||||
|
|
||||||
MovieDetailsHandler::with(
|
|
||||||
&DEFAULT_KEYBINDINGS.down.key,
|
|
||||||
&mut app,
|
|
||||||
&ActiveRadarrBlock::MovieDetails,
|
|
||||||
&None,
|
|
||||||
)
|
|
||||||
.handle();
|
|
||||||
|
|
||||||
assert_eq!(app.data.radarr_data.movie_details.offset, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
test_iterable_scroll!(
|
test_iterable_scroll!(
|
||||||
test_movie_history_scroll,
|
test_movie_history_scroll,
|
||||||
@@ -113,35 +97,17 @@ mod tests {
|
|||||||
use crate::models::radarr_models::ReleaseField;
|
use crate::models::radarr_models::ReleaseField;
|
||||||
use crate::{
|
use crate::{
|
||||||
extended_stateful_iterable_vec, test_enum_home_and_end, test_iterable_home_and_end,
|
extended_stateful_iterable_vec, test_enum_home_and_end, test_iterable_home_and_end,
|
||||||
|
test_scrollable_text_home_and_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
test_scrollable_text_home_and_end!(
|
||||||
fn test_movie_details_home_end() {
|
test_movie_details_home_end,
|
||||||
let mut app = App::default();
|
MovieDetailsHandler,
|
||||||
app.data.radarr_data.movie_details = ScrollableText::with_string("Test 1\nTest 2".to_owned());
|
movie_details,
|
||||||
|
ActiveRadarrBlock::MovieDetails
|
||||||
MovieDetailsHandler::with(
|
);
|
||||||
&DEFAULT_KEYBINDINGS.end.key,
|
|
||||||
&mut app,
|
|
||||||
&ActiveRadarrBlock::MovieDetails,
|
|
||||||
&None,
|
|
||||||
)
|
|
||||||
.handle();
|
|
||||||
|
|
||||||
assert_eq!(app.data.radarr_data.movie_details.offset, 1);
|
|
||||||
|
|
||||||
MovieDetailsHandler::with(
|
|
||||||
&DEFAULT_KEYBINDINGS.home.key,
|
|
||||||
&mut app,
|
|
||||||
&ActiveRadarrBlock::MovieDetails,
|
|
||||||
&None,
|
|
||||||
)
|
|
||||||
.handle();
|
|
||||||
|
|
||||||
assert_eq!(app.data.radarr_data.movie_details.offset, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
test_iterable_home_and_end!(
|
test_iterable_home_and_end!(
|
||||||
test_movie_history_home_end,
|
test_movie_history_home_end,
|
||||||
|
|||||||
@@ -921,7 +921,7 @@ mod tests {
|
|||||||
ActiveRadarrBlock::Collections,
|
ActiveRadarrBlock::Collections,
|
||||||
ActiveRadarrBlock::UpdateAllCollectionsPrompt
|
ActiveRadarrBlock::UpdateAllCollectionsPrompt
|
||||||
)]
|
)]
|
||||||
#[case(ActiveRadarrBlock::System, ActiveRadarrBlock::SystemQueue)]
|
#[case(ActiveRadarrBlock::System, ActiveRadarrBlock::SystemUpdates)]
|
||||||
fn test_update_key(
|
fn test_update_key(
|
||||||
#[case] active_radarr_block: ActiveRadarrBlock,
|
#[case] active_radarr_block: ActiveRadarrBlock,
|
||||||
#[case] expected_radarr_block: ActiveRadarrBlock,
|
#[case] expected_radarr_block: ActiveRadarrBlock,
|
||||||
@@ -939,6 +939,24 @@ mod tests {
|
|||||||
assert_eq!(app.get_current_route(), &expected_radarr_block.into());
|
assert_eq!(app.get_current_route(), &expected_radarr_block.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_queue_key() {
|
||||||
|
let mut app = App::default();
|
||||||
|
|
||||||
|
RadarrHandler::with(
|
||||||
|
&DEFAULT_KEYBINDINGS.queue.key,
|
||||||
|
&mut app,
|
||||||
|
&ActiveRadarrBlock::System,
|
||||||
|
&None,
|
||||||
|
)
|
||||||
|
.handle();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
app.get_current_route(),
|
||||||
|
&ActiveRadarrBlock::SystemQueue.into()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn test_refresh_key(
|
fn test_refresh_key(
|
||||||
#[values(
|
#[values(
|
||||||
@@ -1252,7 +1270,8 @@ mod tests {
|
|||||||
ActiveRadarrBlock::System,
|
ActiveRadarrBlock::System,
|
||||||
ActiveRadarrBlock::SystemLogs,
|
ActiveRadarrBlock::SystemLogs,
|
||||||
ActiveRadarrBlock::SystemTasks,
|
ActiveRadarrBlock::SystemTasks,
|
||||||
ActiveRadarrBlock::SystemQueue
|
ActiveRadarrBlock::SystemQueue,
|
||||||
|
ActiveRadarrBlock::SystemUpdates
|
||||||
)]
|
)]
|
||||||
active_radarr_block: ActiveRadarrBlock,
|
active_radarr_block: ActiveRadarrBlock,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
|
|||||||
match self.active_radarr_block {
|
match self.active_radarr_block {
|
||||||
ActiveRadarrBlock::SystemLogs => self.app.data.radarr_data.log_details.scroll_up(),
|
ActiveRadarrBlock::SystemLogs => self.app.data.radarr_data.log_details.scroll_up(),
|
||||||
ActiveRadarrBlock::SystemTasks => self.app.data.radarr_data.tasks.scroll_up(),
|
ActiveRadarrBlock::SystemTasks => self.app.data.radarr_data.tasks.scroll_up(),
|
||||||
|
ActiveRadarrBlock::SystemUpdates => self.app.data.radarr_data.updates.scroll_up(),
|
||||||
ActiveRadarrBlock::SystemQueue => self.app.data.radarr_data.queued_events.scroll_up(),
|
ActiveRadarrBlock::SystemQueue => self.app.data.radarr_data.queued_events.scroll_up(),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@@ -49,6 +50,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
|
|||||||
match self.active_radarr_block {
|
match self.active_radarr_block {
|
||||||
ActiveRadarrBlock::SystemLogs => self.app.data.radarr_data.log_details.scroll_down(),
|
ActiveRadarrBlock::SystemLogs => self.app.data.radarr_data.log_details.scroll_down(),
|
||||||
ActiveRadarrBlock::SystemTasks => self.app.data.radarr_data.tasks.scroll_down(),
|
ActiveRadarrBlock::SystemTasks => self.app.data.radarr_data.tasks.scroll_down(),
|
||||||
|
ActiveRadarrBlock::SystemUpdates => self.app.data.radarr_data.updates.scroll_down(),
|
||||||
ActiveRadarrBlock::SystemQueue => self.app.data.radarr_data.queued_events.scroll_down(),
|
ActiveRadarrBlock::SystemQueue => self.app.data.radarr_data.queued_events.scroll_down(),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@@ -58,6 +60,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
|
|||||||
match self.active_radarr_block {
|
match self.active_radarr_block {
|
||||||
ActiveRadarrBlock::SystemLogs => self.app.data.radarr_data.log_details.scroll_to_top(),
|
ActiveRadarrBlock::SystemLogs => self.app.data.radarr_data.log_details.scroll_to_top(),
|
||||||
ActiveRadarrBlock::SystemTasks => self.app.data.radarr_data.tasks.scroll_to_top(),
|
ActiveRadarrBlock::SystemTasks => self.app.data.radarr_data.tasks.scroll_to_top(),
|
||||||
|
ActiveRadarrBlock::SystemUpdates => self.app.data.radarr_data.updates.scroll_to_top(),
|
||||||
ActiveRadarrBlock::SystemQueue => self.app.data.radarr_data.queued_events.scroll_to_top(),
|
ActiveRadarrBlock::SystemQueue => self.app.data.radarr_data.queued_events.scroll_to_top(),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@@ -67,6 +70,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
|
|||||||
match self.active_radarr_block {
|
match self.active_radarr_block {
|
||||||
ActiveRadarrBlock::SystemLogs => self.app.data.radarr_data.log_details.scroll_to_bottom(),
|
ActiveRadarrBlock::SystemLogs => self.app.data.radarr_data.log_details.scroll_to_bottom(),
|
||||||
ActiveRadarrBlock::SystemTasks => self.app.data.radarr_data.tasks.scroll_to_bottom(),
|
ActiveRadarrBlock::SystemTasks => self.app.data.radarr_data.tasks.scroll_to_bottom(),
|
||||||
|
ActiveRadarrBlock::SystemUpdates => self.app.data.radarr_data.updates.scroll_to_bottom(),
|
||||||
ActiveRadarrBlock::SystemQueue => self.app.data.radarr_data.queued_events.scroll_to_bottom(),
|
ActiveRadarrBlock::SystemQueue => self.app.data.radarr_data.queued_events.scroll_to_bottom(),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@@ -126,12 +130,13 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
|
|||||||
|
|
||||||
fn handle_esc(&mut self) {
|
fn handle_esc(&mut self) {
|
||||||
match self.active_radarr_block {
|
match self.active_radarr_block {
|
||||||
ActiveRadarrBlock::SystemLogs
|
ActiveRadarrBlock::SystemLogs => {
|
||||||
| ActiveRadarrBlock::SystemTasks
|
|
||||||
| ActiveRadarrBlock::SystemQueue => {
|
|
||||||
self.app.data.radarr_data.reset_log_details_list();
|
self.app.data.radarr_data.reset_log_details_list();
|
||||||
self.app.pop_navigation_stack()
|
self.app.pop_navigation_stack()
|
||||||
}
|
}
|
||||||
|
ActiveRadarrBlock::SystemQueue
|
||||||
|
| ActiveRadarrBlock::SystemTasks
|
||||||
|
| ActiveRadarrBlock::SystemUpdates => self.app.pop_navigation_stack(),
|
||||||
ActiveRadarrBlock::SystemTaskStartConfirmPrompt => {
|
ActiveRadarrBlock::SystemTaskStartConfirmPrompt => {
|
||||||
self.app.pop_navigation_stack();
|
self.app.pop_navigation_stack();
|
||||||
self.app.data.radarr_data.prompt_confirm = false;
|
self.app.data.radarr_data.prompt_confirm = false;
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ mod tests {
|
|||||||
mod test_handle_scroll_up_and_down {
|
mod test_handle_scroll_up_and_down {
|
||||||
use rstest::rstest;
|
use rstest::rstest;
|
||||||
|
|
||||||
use crate::models::HorizontallyScrollableText;
|
use crate::models::{HorizontallyScrollableText, ScrollableText};
|
||||||
use crate::{simple_stateful_iterable_vec, test_iterable_scroll};
|
use crate::{simple_stateful_iterable_vec, test_iterable_scroll, test_scrollable_text_scroll};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@@ -47,11 +47,20 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_scrollable_text_scroll!(
|
||||||
|
test_system_updates_scroll,
|
||||||
|
SystemDetailsHandler,
|
||||||
|
updates,
|
||||||
|
ActiveRadarrBlock::SystemUpdates
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test_handle_home_end {
|
mod test_handle_home_end {
|
||||||
use crate::models::HorizontallyScrollableText;
|
use crate::models::{HorizontallyScrollableText, ScrollableText};
|
||||||
use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end};
|
use crate::{
|
||||||
|
extended_stateful_iterable_vec, test_iterable_home_and_end, test_scrollable_text_home_and_end,
|
||||||
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@@ -84,13 +93,21 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_scrollable_text_home_and_end!(
|
||||||
|
test_system_updates_home_end,
|
||||||
|
SystemDetailsHandler,
|
||||||
|
updates,
|
||||||
|
ActiveRadarrBlock::SystemUpdates
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test_handle_left_right_action {
|
mod test_handle_left_right_action {
|
||||||
use super::*;
|
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use rstest::rstest;
|
use rstest::rstest;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_handle_log_details_left_right() {
|
fn test_handle_log_details_left_right() {
|
||||||
let active_radarr_block = ActiveRadarrBlock::SystemLogs;
|
let active_radarr_block = ActiveRadarrBlock::SystemLogs;
|
||||||
@@ -219,9 +236,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod test_handle_submit {
|
mod test_handle_submit {
|
||||||
use crate::network::radarr_network::RadarrEvent;
|
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
use crate::network::radarr_network::RadarrEvent;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key;
|
const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key;
|
||||||
@@ -294,9 +312,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod test_handle_esc {
|
mod test_handle_esc {
|
||||||
use crate::models::HorizontallyScrollableText;
|
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
use crate::models::HorizontallyScrollableText;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
|
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
|
||||||
@@ -354,6 +373,23 @@ mod tests {
|
|||||||
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
|
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_esc_system_updates() {
|
||||||
|
let mut app = App::default();
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::System.into());
|
||||||
|
app.push_navigation_stack(ActiveRadarrBlock::SystemUpdates.into());
|
||||||
|
app
|
||||||
|
.data
|
||||||
|
.radarr_data
|
||||||
|
.queued_events
|
||||||
|
.set_items(vec![QueueEvent::default()]);
|
||||||
|
|
||||||
|
SystemDetailsHandler::with(&ESC_KEY, &mut app, &ActiveRadarrBlock::SystemUpdates, &None)
|
||||||
|
.handle();
|
||||||
|
|
||||||
|
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_system_tasks_start_task_prompt_esc() {
|
fn test_system_tasks_start_task_prompt_esc() {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
@@ -387,7 +423,8 @@ mod tests {
|
|||||||
#[values(
|
#[values(
|
||||||
ActiveRadarrBlock::SystemLogs,
|
ActiveRadarrBlock::SystemLogs,
|
||||||
ActiveRadarrBlock::SystemTasks,
|
ActiveRadarrBlock::SystemTasks,
|
||||||
ActiveRadarrBlock::SystemQueue
|
ActiveRadarrBlock::SystemQueue,
|
||||||
|
ActiveRadarrBlock::SystemUpdates
|
||||||
)]
|
)]
|
||||||
active_radarr_block: ActiveRadarrBlock,
|
active_radarr_block: ActiveRadarrBlock,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -450,3 +450,21 @@ pub struct QueueEvent {
|
|||||||
pub ended: Option<DateTime<Utc>>,
|
pub ended: Option<DateTime<Utc>>,
|
||||||
pub duration: Option<String>,
|
pub duration: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Update {
|
||||||
|
pub version: String,
|
||||||
|
pub release_date: DateTime<Utc>,
|
||||||
|
pub installed: bool,
|
||||||
|
pub latest: bool,
|
||||||
|
pub installed_on: Option<DateTime<Utc>>,
|
||||||
|
pub changes: UpdateChanges,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct UpdateChanges {
|
||||||
|
pub new: Option<Vec<String>>,
|
||||||
|
pub fixed: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use crate::models::radarr_models::{
|
|||||||
AddMovieBody, AddMovieSearchResult, AddOptions, AddRootFolderBody, Collection, CollectionMovie,
|
AddMovieBody, AddMovieSearchResult, AddOptions, AddRootFolderBody, Collection, CollectionMovie,
|
||||||
CommandBody, Credit, CreditType, DiskSpace, DownloadRecord, DownloadsResponse, LogResponse,
|
CommandBody, Credit, CreditType, DiskSpace, DownloadRecord, DownloadsResponse, LogResponse,
|
||||||
Movie, MovieCommandBody, MovieHistoryItem, QualityProfile, QueueEvent, Release,
|
Movie, MovieCommandBody, MovieHistoryItem, QualityProfile, QueueEvent, Release,
|
||||||
ReleaseDownloadBody, RootFolder, SystemStatus, Tag, Task,
|
ReleaseDownloadBody, RootFolder, SystemStatus, Tag, Task, Update,
|
||||||
};
|
};
|
||||||
use crate::models::{HorizontallyScrollableText, Route, Scrollable, ScrollableText};
|
use crate::models::{HorizontallyScrollableText, Route, Scrollable, ScrollableText};
|
||||||
use crate::network::{Network, NetworkEvent, RequestMethod, RequestProps};
|
use crate::network::{Network, NetworkEvent, RequestMethod, RequestProps};
|
||||||
@@ -47,6 +47,7 @@ pub enum RadarrEvent {
|
|||||||
GetStatus,
|
GetStatus,
|
||||||
GetTags,
|
GetTags,
|
||||||
GetTasks,
|
GetTasks,
|
||||||
|
GetUpdates,
|
||||||
HealthCheck,
|
HealthCheck,
|
||||||
SearchNewMovie,
|
SearchNewMovie,
|
||||||
StartTask,
|
StartTask,
|
||||||
@@ -80,6 +81,7 @@ impl RadarrEvent {
|
|||||||
RadarrEvent::GetStatus => "/system/status",
|
RadarrEvent::GetStatus => "/system/status",
|
||||||
RadarrEvent::GetTags => "/tag",
|
RadarrEvent::GetTags => "/tag",
|
||||||
RadarrEvent::GetTasks => "/system/task",
|
RadarrEvent::GetTasks => "/system/task",
|
||||||
|
RadarrEvent::GetUpdates => "/update",
|
||||||
RadarrEvent::StartTask
|
RadarrEvent::StartTask
|
||||||
| RadarrEvent::GetQueuedEvents
|
| RadarrEvent::GetQueuedEvents
|
||||||
| RadarrEvent::TriggerAutomaticSearch
|
| RadarrEvent::TriggerAutomaticSearch
|
||||||
@@ -124,6 +126,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
|||||||
RadarrEvent::GetStatus => self.get_status().await,
|
RadarrEvent::GetStatus => self.get_status().await,
|
||||||
RadarrEvent::GetTags => self.get_tags().await,
|
RadarrEvent::GetTags => self.get_tags().await,
|
||||||
RadarrEvent::GetTasks => self.get_tasks().await,
|
RadarrEvent::GetTasks => self.get_tasks().await,
|
||||||
|
RadarrEvent::GetUpdates => self.get_updates().await,
|
||||||
RadarrEvent::HealthCheck => self.get_healthcheck().await,
|
RadarrEvent::HealthCheck => self.get_healthcheck().await,
|
||||||
RadarrEvent::SearchNewMovie => self.search_movie().await,
|
RadarrEvent::SearchNewMovie => self.search_movie().await,
|
||||||
RadarrEvent::StartTask => self.start_task().await,
|
RadarrEvent::StartTask => self.start_task().await,
|
||||||
@@ -742,6 +745,97 @@ impl<'a, 'b> Network<'a, 'b> {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_updates(&self) {
|
||||||
|
info!("Fetching Radarr updates");
|
||||||
|
|
||||||
|
let request_props = self
|
||||||
|
.radarr_request_props_from(
|
||||||
|
RadarrEvent::GetUpdates.resource(),
|
||||||
|
RequestMethod::Get,
|
||||||
|
None::<()>,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
self
|
||||||
|
.handle_request::<(), Vec<Update>>(request_props, |updates_vec, mut app| {
|
||||||
|
let latest_installed = if updates_vec
|
||||||
|
.iter()
|
||||||
|
.any(|update| update.latest && update.installed_on.is_some())
|
||||||
|
{
|
||||||
|
"already".to_owned()
|
||||||
|
} else {
|
||||||
|
"not".to_owned()
|
||||||
|
};
|
||||||
|
let updates = updates_vec
|
||||||
|
.into_iter()
|
||||||
|
.map(|update| {
|
||||||
|
let install_status = if update.installed_on.is_some() {
|
||||||
|
if update.installed {
|
||||||
|
"(Currently Installed)".to_owned()
|
||||||
|
} else {
|
||||||
|
"(Previously Installed)".to_owned()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
let vec_to_bullet_points = |vec: Vec<String>| {
|
||||||
|
vec
|
||||||
|
.iter()
|
||||||
|
.map(|change| format!(" * {}", change))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut update_info = formatdoc!(
|
||||||
|
"{} - {} {}
|
||||||
|
{}",
|
||||||
|
update.version,
|
||||||
|
update.release_date,
|
||||||
|
install_status,
|
||||||
|
"-".repeat(200)
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(new_changes) = update.changes.new {
|
||||||
|
let changes = vec_to_bullet_points(new_changes);
|
||||||
|
update_info = formatdoc!(
|
||||||
|
"{}
|
||||||
|
New:
|
||||||
|
{}",
|
||||||
|
update_info,
|
||||||
|
changes
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(fixes) = update.changes.fixed {
|
||||||
|
let fixes = vec_to_bullet_points(fixes);
|
||||||
|
update_info = formatdoc!(
|
||||||
|
"{}
|
||||||
|
Fixed:
|
||||||
|
{}",
|
||||||
|
update_info,
|
||||||
|
fixes
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
update_info
|
||||||
|
})
|
||||||
|
.reduce(|version_1, version_2| format!("{}\n\n\n{}", version_1, version_2))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
app.data.radarr_data.updates = ScrollableText::with_string(formatdoc!(
|
||||||
|
"{}
|
||||||
|
|
||||||
|
{}",
|
||||||
|
format!(
|
||||||
|
"The latest version of Radarr is {} installed",
|
||||||
|
latest_installed
|
||||||
|
),
|
||||||
|
updates
|
||||||
|
));
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
async fn add_tag(&self, tag: String) {
|
async fn add_tag(&self, tag: String) {
|
||||||
info!("Adding a new Radarr tag");
|
info!("Adding a new Radarr tag");
|
||||||
|
|
||||||
|
|||||||
@@ -1065,6 +1065,95 @@ mod test {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_handle_get_updates_event() {
|
||||||
|
let tasks_json = json!([{
|
||||||
|
"version": "4.3.2.1",
|
||||||
|
"releaseDate": "2023-04-15T02:02:53Z",
|
||||||
|
"installed": true,
|
||||||
|
"installedOn": "2023-04-15T02:02:53Z",
|
||||||
|
"latest": true,
|
||||||
|
"changes": {
|
||||||
|
"new": [
|
||||||
|
"Cool new thing"
|
||||||
|
],
|
||||||
|
"fixed": [
|
||||||
|
"Some bugs killed"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "3.2.1.0",
|
||||||
|
"releaseDate": "2023-04-15T02:02:53Z",
|
||||||
|
"installed": false,
|
||||||
|
"installedOn": "2023-04-15T02:02:53Z",
|
||||||
|
"latest": false,
|
||||||
|
"changes": {
|
||||||
|
"new": [
|
||||||
|
"Cool new thing (old)",
|
||||||
|
"Other cool new thing (old)"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "2.1.0",
|
||||||
|
"releaseDate": "2023-04-15T02:02:53Z",
|
||||||
|
"installed": false,
|
||||||
|
"latest": false,
|
||||||
|
"changes": {
|
||||||
|
"fixed": [
|
||||||
|
"Killed bug 1",
|
||||||
|
"Fixed bug 2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}]);
|
||||||
|
let line_break = "-".repeat(200);
|
||||||
|
let expected_text = ScrollableText::with_string(formatdoc!(
|
||||||
|
"
|
||||||
|
The latest version of Radarr is already installed
|
||||||
|
|
||||||
|
4.3.2.1 - 2023-04-15 02:02:53 UTC (Currently Installed)
|
||||||
|
{}
|
||||||
|
New:
|
||||||
|
* Cool new thing
|
||||||
|
Fixed:
|
||||||
|
* Some bugs killed
|
||||||
|
|
||||||
|
|
||||||
|
3.2.1.0 - 2023-04-15 02:02:53 UTC (Previously Installed)
|
||||||
|
{}
|
||||||
|
New:
|
||||||
|
* Cool new thing (old)
|
||||||
|
* Other cool new thing (old)
|
||||||
|
|
||||||
|
|
||||||
|
2.1.0 - 2023-04-15 02:02:53 UTC
|
||||||
|
{}
|
||||||
|
Fixed:
|
||||||
|
* Killed bug 1
|
||||||
|
* Fixed bug 2",
|
||||||
|
line_break.clone(),
|
||||||
|
line_break.clone(),
|
||||||
|
line_break
|
||||||
|
));
|
||||||
|
let (async_server, app_arc, _server) = mock_radarr_api(
|
||||||
|
RequestMethod::Get,
|
||||||
|
None,
|
||||||
|
Some(tasks_json),
|
||||||
|
RadarrEvent::GetUpdates.resource(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
let network = Network::new(reqwest::Client::new(), &app_arc);
|
||||||
|
|
||||||
|
network.handle_radarr_event(RadarrEvent::GetUpdates).await;
|
||||||
|
|
||||||
|
async_server.assert_async().await;
|
||||||
|
assert_str_eq!(
|
||||||
|
app_arc.lock().await.data.radarr_data.updates.get_text(),
|
||||||
|
expected_text.get_text()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_add_tag() {
|
async fn test_add_tag() {
|
||||||
let (async_server, app_arc, _server) = mock_radarr_api(
|
let (async_server, app_arc, _server) = mock_radarr_api(
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
use tui::backend::Backend;
|
||||||
|
use tui::layout::Rect;
|
||||||
|
use tui::text::{Span, Text};
|
||||||
|
use tui::widgets::{Cell, ListItem, Paragraph, Row};
|
||||||
|
use tui::Frame;
|
||||||
|
|
||||||
use crate::app::radarr::ActiveRadarrBlock;
|
use crate::app::radarr::ActiveRadarrBlock;
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::Route;
|
use crate::models::Route;
|
||||||
@@ -9,13 +15,8 @@ use crate::ui::radarr_ui::system_ui::{
|
|||||||
use crate::ui::utils::{borderless_block, style_primary, title_block};
|
use crate::ui::utils::{borderless_block, style_primary, title_block};
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
draw_help, draw_large_popup_over, draw_list_box, draw_medium_popup_over, draw_prompt_box,
|
draw_help, draw_large_popup_over, draw_list_box, draw_medium_popup_over, draw_prompt_box,
|
||||||
draw_prompt_popup_over, draw_table, DrawUi, ListProps, TableProps,
|
draw_prompt_popup_over, draw_table, loading, DrawUi, ListProps, TableProps,
|
||||||
};
|
};
|
||||||
use tui::backend::Backend;
|
|
||||||
use tui::layout::Rect;
|
|
||||||
use tui::text::{Span, Text};
|
|
||||||
use tui::widgets::{Cell, ListItem, Row};
|
|
||||||
use tui::Frame;
|
|
||||||
|
|
||||||
pub(super) struct SystemDetailsUi {}
|
pub(super) struct SystemDetailsUi {}
|
||||||
|
|
||||||
@@ -42,6 +43,13 @@ impl DrawUi for SystemDetailsUi {
|
|||||||
draw_system_ui_layout,
|
draw_system_ui_layout,
|
||||||
draw_queued_events,
|
draw_queued_events,
|
||||||
),
|
),
|
||||||
|
ActiveRadarrBlock::SystemUpdates => draw_large_popup_over(
|
||||||
|
f,
|
||||||
|
app,
|
||||||
|
content_rect,
|
||||||
|
draw_system_ui_layout,
|
||||||
|
draw_updates_popup,
|
||||||
|
),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,3 +133,18 @@ fn draw_start_task_prompt<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, p
|
|||||||
app.data.radarr_data.prompt_confirm,
|
app.data.radarr_data.prompt_confirm,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_updates_popup<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Rect) {
|
||||||
|
let updates = app.data.radarr_data.updates.get_text();
|
||||||
|
let block = title_block("Updates");
|
||||||
|
|
||||||
|
if !updates.is_empty() {
|
||||||
|
let updates_paragraph = Paragraph::new(Text::from(updates))
|
||||||
|
.block(block)
|
||||||
|
.scroll((app.data.radarr_data.updates.offset, 0));
|
||||||
|
|
||||||
|
f.render_widget(updates_paragraph, area);
|
||||||
|
} else {
|
||||||
|
loading(f, block, area, app.is_loading);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user