Added the Root Folders tab

This commit is contained in:
2023-08-08 10:50:06 -06:00
parent d8a93efd5a
commit 9142d5ab3e
5 changed files with 175 additions and 36 deletions
+46 -6
View File
@@ -13,7 +13,7 @@ use crate::models::{
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
pub struct RadarrData { pub struct RadarrData {
pub root_folders: Vec<RootFolder>, pub root_folders: StatefulTable<RootFolder>,
pub disk_space_vec: Vec<DiskSpace>, pub disk_space_vec: Vec<DiskSpace>,
pub version: String, pub version: String,
pub start_time: DateTime<Utc>, pub start_time: DateTime<Utc>,
@@ -217,7 +217,7 @@ impl RadarrData {
impl Default for RadarrData { impl Default for RadarrData {
fn default() -> RadarrData { fn default() -> RadarrData {
RadarrData { RadarrData {
root_folders: Vec::new(), root_folders: StatefulTable::default(),
disk_space_vec: Vec::new(), disk_space_vec: Vec::new(),
version: String::default(), version: String::default(),
start_time: DateTime::default(), start_time: DateTime::default(),
@@ -259,7 +259,7 @@ impl Default for RadarrData {
title: "Library".to_owned(), title: "Library".to_owned(),
route: ActiveRadarrBlock::Movies.into(), route: ActiveRadarrBlock::Movies.into(),
help: String::default(), help: String::default(),
contextual_help: Some("<a> add | <e> edit | <s> search | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter | <del> delete" contextual_help: Some("<a> add | <e> edit | <del> delete | <s> search | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter"
.to_owned()), .to_owned()),
}, },
TabRoute { TabRoute {
@@ -275,6 +275,12 @@ impl Default for RadarrData {
contextual_help: Some("<s> search | <e> edit | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter" contextual_help: Some("<s> search | <e> edit | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter"
.to_owned()), .to_owned()),
}, },
TabRoute {
title: "Root Folders".to_owned(),
route: ActiveRadarrBlock::RootFolders.into(),
help: String::default(),
contextual_help: Some("<a> add | <del> delete | <r> refresh".to_owned()),
},
]), ]),
movie_info_tabs: TabState::new(vec![ movie_info_tabs: TabState::new(vec![
TabRoute { TabRoute {
@@ -361,6 +367,7 @@ pub enum ActiveRadarrBlock {
MovieDetails, MovieDetails,
MovieHistory, MovieHistory,
Movies, Movies,
RootFolders,
UpdateAndScanPrompt, UpdateAndScanPrompt,
UpdateAllCollectionsPrompt, UpdateAllCollectionsPrompt,
UpdateAllMoviesPrompt, UpdateAllMoviesPrompt,
@@ -561,6 +568,11 @@ impl App {
.dispatch_network_event(RadarrEvent::GetDownloads.into()) .dispatch_network_event(RadarrEvent::GetDownloads.into())
.await; .await;
} }
ActiveRadarrBlock::RootFolders => {
self
.dispatch_network_event(RadarrEvent::GetRootFolders.into())
.await;
}
ActiveRadarrBlock::Movies => { ActiveRadarrBlock::Movies => {
self self
.dispatch_network_event(RadarrEvent::GetMovies.into()) .dispatch_network_event(RadarrEvent::GetMovies.into())
@@ -1046,7 +1058,7 @@ mod tests {
fn test_radarr_data_defaults() { fn test_radarr_data_defaults() {
let radarr_data = RadarrData::default(); let radarr_data = RadarrData::default();
assert_eq!(radarr_data.root_folders, Vec::new()); assert!(radarr_data.root_folders.items.is_empty());
assert_eq!(radarr_data.disk_space_vec, Vec::new()); assert_eq!(radarr_data.disk_space_vec, Vec::new());
assert!(radarr_data.version.is_empty()); assert!(radarr_data.version.is_empty());
assert_eq!(radarr_data.start_time, <DateTime<Utc>>::default()); assert_eq!(radarr_data.start_time, <DateTime<Utc>>::default());
@@ -1087,7 +1099,7 @@ mod tests {
assert!(!radarr_data.is_filtering); assert!(!radarr_data.is_filtering);
assert!(!radarr_data.prompt_confirm); assert!(!radarr_data.prompt_confirm);
assert_eq!(radarr_data.main_tabs.tabs.len(), 3); assert_eq!(radarr_data.main_tabs.tabs.len(), 4);
assert_str_eq!(radarr_data.main_tabs.tabs[0].title, "Library"); assert_str_eq!(radarr_data.main_tabs.tabs[0].title, "Library");
assert_eq!( assert_eq!(
@@ -1096,7 +1108,7 @@ mod tests {
); );
assert!(radarr_data.main_tabs.tabs[0].help.is_empty()); assert!(radarr_data.main_tabs.tabs[0].help.is_empty());
assert_eq!(radarr_data.main_tabs.tabs[0].contextual_help, assert_eq!(radarr_data.main_tabs.tabs[0].contextual_help,
Some("<a> add | <e> edit | <s> search | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter | <del> delete".to_owned())); Some("<a> add | <e> edit | <del> delete | <s> search | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter".to_owned()));
assert_str_eq!(radarr_data.main_tabs.tabs[1].title, "Downloads"); assert_str_eq!(radarr_data.main_tabs.tabs[1].title, "Downloads");
assert_eq!( assert_eq!(
@@ -1118,6 +1130,17 @@ mod tests {
assert_eq!(radarr_data.main_tabs.tabs[2].contextual_help, assert_eq!(radarr_data.main_tabs.tabs[2].contextual_help,
Some("<s> search | <e> edit | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter".to_owned())); Some("<s> search | <e> edit | <f> filter | <r> refresh | <u> update all | <enter> details | <esc> cancel filter".to_owned()));
assert_str_eq!(radarr_data.main_tabs.tabs[3].title, "Root Folders");
assert_eq!(
radarr_data.main_tabs.tabs[3].route,
ActiveRadarrBlock::RootFolders.into()
);
assert!(radarr_data.main_tabs.tabs[3].help.is_empty());
assert_eq!(
radarr_data.main_tabs.tabs[3].contextual_help,
Some("<a> add | <del> delete | <r> refresh".to_owned())
);
assert_eq!(radarr_data.movie_info_tabs.tabs.len(), 6); assert_eq!(radarr_data.movie_info_tabs.tabs.len(), 6);
assert_str_eq!(radarr_data.movie_info_tabs.tabs[0].title, "Details"); assert_str_eq!(radarr_data.movie_info_tabs.tabs[0].title, "Details");
@@ -1506,6 +1529,23 @@ mod tests {
assert_eq!(app.tick_count, 0); assert_eq!(app.tick_count, 0);
} }
#[tokio::test]
async fn test_dispatch_by_root_folders_block() {
let (mut app, mut sync_network_rx) = construct_app_unit();
app
.dispatch_by_radarr_block(&ActiveRadarrBlock::RootFolders)
.await;
assert!(app.is_loading);
assert_eq!(
sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetRootFolders.into()
);
assert!(!app.data.radarr_data.prompt_confirm);
assert_eq!(app.tick_count, 0);
}
#[tokio::test] #[tokio::test]
async fn test_dispatch_by_movies_block() { async fn test_dispatch_by_movies_block() {
let (mut app, mut sync_network_rx) = construct_app_unit(); let (mut app, mut sync_network_rx) = construct_app_unit();
+57 -23
View File
@@ -94,6 +94,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
} }
} }
ActiveRadarrBlock::Downloads => self.app.data.radarr_data.downloads.scroll_up(), ActiveRadarrBlock::Downloads => self.app.data.radarr_data.downloads.scroll_up(),
ActiveRadarrBlock::RootFolders => self.app.data.radarr_data.root_folders.scroll_up(),
_ => (), _ => (),
} }
} }
@@ -122,6 +123,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
} }
} }
ActiveRadarrBlock::Downloads => self.app.data.radarr_data.downloads.scroll_down(), ActiveRadarrBlock::Downloads => self.app.data.radarr_data.downloads.scroll_down(),
ActiveRadarrBlock::RootFolders => self.app.data.radarr_data.root_folders.scroll_down(),
_ => (), _ => (),
} }
} }
@@ -155,6 +157,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
} }
} }
ActiveRadarrBlock::Downloads => self.app.data.radarr_data.downloads.scroll_to_top(), ActiveRadarrBlock::Downloads => self.app.data.radarr_data.downloads.scroll_to_top(),
ActiveRadarrBlock::RootFolders => self.app.data.radarr_data.root_folders.scroll_to_top(),
ActiveRadarrBlock::SearchMovie | ActiveRadarrBlock::SearchCollection => { ActiveRadarrBlock::SearchMovie | ActiveRadarrBlock::SearchCollection => {
self.app.data.radarr_data.search.scroll_home() self.app.data.radarr_data.search.scroll_home()
} }
@@ -194,6 +197,7 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
} }
} }
ActiveRadarrBlock::Downloads => self.app.data.radarr_data.downloads.scroll_to_bottom(), ActiveRadarrBlock::Downloads => self.app.data.radarr_data.downloads.scroll_to_bottom(),
ActiveRadarrBlock::RootFolders => self.app.data.radarr_data.root_folders.scroll_to_bottom(),
ActiveRadarrBlock::SearchMovie | ActiveRadarrBlock::SearchCollection => { ActiveRadarrBlock::SearchMovie | ActiveRadarrBlock::SearchCollection => {
self.app.data.radarr_data.search.reset_offset() self.app.data.radarr_data.search.reset_offset()
} }
@@ -218,23 +222,24 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
fn handle_left_right_action(&mut self) { fn handle_left_right_action(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Movies | ActiveRadarrBlock::Downloads | ActiveRadarrBlock::Collections => { ActiveRadarrBlock::Movies
match self.key { | ActiveRadarrBlock::Downloads
_ if *self.key == DEFAULT_KEYBINDINGS.left.key => { | ActiveRadarrBlock::Collections
self.app.data.radarr_data.main_tabs.previous(); | ActiveRadarrBlock::RootFolders => match self.key {
self.app.pop_and_push_navigation_stack( _ if *self.key == DEFAULT_KEYBINDINGS.left.key => {
*self.app.data.radarr_data.main_tabs.get_active_route(), self.app.data.radarr_data.main_tabs.previous();
); self
} .app
_ if *self.key == DEFAULT_KEYBINDINGS.right.key => { .pop_and_push_navigation_stack(*self.app.data.radarr_data.main_tabs.get_active_route());
self.app.data.radarr_data.main_tabs.next();
self.app.pop_and_push_navigation_stack(
*self.app.data.radarr_data.main_tabs.get_active_route(),
);
}
_ => (),
} }
} _ if *self.key == DEFAULT_KEYBINDINGS.right.key => {
self.app.data.radarr_data.main_tabs.next();
self
.app
.pop_and_push_navigation_stack(*self.app.data.radarr_data.main_tabs.get_active_route());
}
_ => (),
},
ActiveRadarrBlock::DeleteMoviePrompt ActiveRadarrBlock::DeleteMoviePrompt
| ActiveRadarrBlock::DeleteDownloadPrompt | ActiveRadarrBlock::DeleteDownloadPrompt
| ActiveRadarrBlock::UpdateAllMoviesPrompt | ActiveRadarrBlock::UpdateAllMoviesPrompt
@@ -505,6 +510,12 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for RadarrHandler<'a> {
} }
_ => (), _ => (),
}, },
ActiveRadarrBlock::RootFolders => match self.key {
_ if *key == DEFAULT_KEYBINDINGS.refresh.key => {
self.app.should_refresh = true;
}
_ => (),
},
_ if SEARCH_BLOCKS.contains(self.active_radarr_block) => { _ if SEARCH_BLOCKS.contains(self.active_radarr_block) => {
handle_text_box_keys!(self, key, self.app.data.radarr_data.search) handle_text_box_keys!(self, key, self.app.data.radarr_data.search)
} }
@@ -714,7 +725,7 @@ 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::radarr_models::DownloadRecord; use crate::models::radarr_models::{DownloadRecord, RootFolder};
use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; use crate::{simple_stateful_iterable_vec, test_iterable_scroll};
use super::*; use super::*;
@@ -772,12 +783,22 @@ mod tests {
None, None,
title title
); );
test_iterable_scroll!(
test_root_folders_scroll,
RadarrHandler,
root_folders,
simple_stateful_iterable_vec!(RootFolder, String, path),
ActiveRadarrBlock::RootFolders,
None,
path
);
} }
mod test_handle_home_end { mod test_handle_home_end {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use crate::models::radarr_models::DownloadRecord; use crate::models::radarr_models::{DownloadRecord, RootFolder};
use crate::{ use crate::{
extended_stateful_iterable_vec, test_iterable_home_and_end, test_text_box_home_end_keys, extended_stateful_iterable_vec, test_iterable_home_and_end, test_text_box_home_end_keys,
}; };
@@ -838,6 +859,16 @@ mod tests {
title title
); );
test_iterable_home_and_end!(
test_root_folders_home_end,
RadarrHandler,
root_folders,
extended_stateful_iterable_vec!(RootFolder, String, path),
ActiveRadarrBlock::RootFolders,
None,
path
);
#[rstest] #[rstest]
fn test_search_boxes_home_end_keys( fn test_search_boxes_home_end_keys(
#[values(ActiveRadarrBlock::SearchMovie, ActiveRadarrBlock::SearchCollection)] #[values(ActiveRadarrBlock::SearchMovie, ActiveRadarrBlock::SearchCollection)]
@@ -896,10 +927,11 @@ mod tests {
use super::*; use super::*;
#[rstest] #[rstest]
#[case(ActiveRadarrBlock::Movies, 0, ActiveRadarrBlock::Collections)] #[case(ActiveRadarrBlock::Movies, 0, ActiveRadarrBlock::RootFolders)]
#[case(ActiveRadarrBlock::Downloads, 1, ActiveRadarrBlock::Movies)] #[case(ActiveRadarrBlock::Downloads, 1, ActiveRadarrBlock::Movies)]
#[case(ActiveRadarrBlock::Collections, 2, ActiveRadarrBlock::Downloads)] #[case(ActiveRadarrBlock::Collections, 2, ActiveRadarrBlock::Downloads)]
fn test_movies_downloads_collections_left( #[case(ActiveRadarrBlock::RootFolders, 3, ActiveRadarrBlock::Collections)]
fn test_radarr_tab_left(
#[case] active_radarr_block: ActiveRadarrBlock, #[case] active_radarr_block: ActiveRadarrBlock,
#[case] index: usize, #[case] index: usize,
#[case] expected_radarr_block: ActiveRadarrBlock, #[case] expected_radarr_block: ActiveRadarrBlock,
@@ -925,8 +957,9 @@ mod tests {
#[rstest] #[rstest]
#[case(ActiveRadarrBlock::Movies, 0, ActiveRadarrBlock::Downloads)] #[case(ActiveRadarrBlock::Movies, 0, ActiveRadarrBlock::Downloads)]
#[case(ActiveRadarrBlock::Downloads, 1, ActiveRadarrBlock::Collections)] #[case(ActiveRadarrBlock::Downloads, 1, ActiveRadarrBlock::Collections)]
#[case(ActiveRadarrBlock::Collections, 2, ActiveRadarrBlock::Movies)] #[case(ActiveRadarrBlock::Collections, 2, ActiveRadarrBlock::RootFolders)]
fn test_movie_downloads_collections_right( #[case(ActiveRadarrBlock::RootFolders, 3, ActiveRadarrBlock::Movies)]
fn test_radarr_tab_right(
#[case] active_radarr_block: ActiveRadarrBlock, #[case] active_radarr_block: ActiveRadarrBlock,
#[case] index: usize, #[case] index: usize,
#[case] expected_radarr_block: ActiveRadarrBlock, #[case] expected_radarr_block: ActiveRadarrBlock,
@@ -1499,7 +1532,8 @@ mod tests {
#[values( #[values(
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
ActiveRadarrBlock::Downloads ActiveRadarrBlock::Downloads,
ActiveRadarrBlock::RootFolders
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
+12 -1
View File
@@ -22,12 +22,23 @@ pub struct SystemStatus {
pub start_time: DateTime<Utc>, pub start_time: DateTime<Utc>,
} }
#[derive(Deserialize, Debug, Clone, Eq, PartialEq)] #[derive(Derivative, Deserialize, Debug, Clone, Eq, PartialEq)]
#[derivative(Default)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RootFolder { pub struct RootFolder {
#[derivative(Default(value = "Number::from(0)"))]
pub id: Number,
pub path: String, pub path: String,
pub accessible: bool, pub accessible: bool,
#[derivative(Default(value = "Number::from(0)"))]
pub free_space: Number, pub free_space: Number,
pub unmapped_folders: Option<Vec<UnmappedFolder>>,
}
#[derive(Deserialize, Default, Debug, Clone, Eq, PartialEq)]
pub struct UnmappedFolder {
pub name: String,
pub path: String,
} }
#[derive(Derivative, Deserialize, Debug, Clone, PartialEq, Eq)] #[derive(Derivative, Deserialize, Debug, Clone, PartialEq, Eq)]
+12 -5
View File
@@ -639,7 +639,7 @@ impl<'a> Network<'a> {
self self
.handle_request::<(), Vec<RootFolder>>(request_props, |root_folders, mut app| { .handle_request::<(), Vec<RootFolder>>(request_props, |root_folders, mut app| {
app.data.radarr_data.root_folders = root_folders; app.data.radarr_data.root_folders.set_items(root_folders);
}) })
.await; .await;
} }
@@ -732,7 +732,7 @@ impl<'a> Network<'a> {
let quality_profile_id = self.extract_quality_profile_id().await; let quality_profile_id = self.extract_quality_profile_id().await;
let tag_ids_vec = self.extract_and_add_tag_ids_vec().await; let tag_ids_vec = self.extract_and_add_tag_ids_vec().await;
let app = self.app.lock().await; let app = self.app.lock().await;
let root_folders = app.data.radarr_data.root_folders.to_vec(); let root_folders = app.data.radarr_data.root_folders.items.to_vec();
let (tmdb_id, title) = if let Route::Radarr(active_radarr_block, _) = app.get_current_route() let (tmdb_id, title) = if let Route::Radarr(active_radarr_block, _) = app.get_current_route()
{ {
if *active_radarr_block == ActiveRadarrBlock::CollectionDetails { if *active_radarr_block == ActiveRadarrBlock::CollectionDetails {
@@ -2059,6 +2059,7 @@ mod test {
#[tokio::test] #[tokio::test]
async fn test_handle_get_root_folders_event() { async fn test_handle_get_root_folders_event() {
let root_folder_json = json!([{ let root_folder_json = json!([{
"id": 1,
"path": "/nfs", "path": "/nfs",
"accessible": true, "accessible": true,
"freeSpace": 219902325555200u64, "freeSpace": 219902325555200u64,
@@ -2078,7 +2079,7 @@ mod test {
async_server.assert_async().await; async_server.assert_async().await;
assert_eq!( assert_eq!(
app_arc.lock().await.data.radarr_data.root_folders, app_arc.lock().await.data.radarr_data.root_folders.items,
vec![root_folder()] vec![root_folder()]
); );
} }
@@ -2202,18 +2203,22 @@ mod test {
{ {
let mut app = app_arc.lock().await; let mut app = app_arc.lock().await;
app.data.radarr_data.root_folders = vec![ app.data.radarr_data.root_folders.set_items(vec![
RootFolder { RootFolder {
id: Number::from(1),
path: "/nfs".to_owned(), path: "/nfs".to_owned(),
accessible: true, accessible: true,
free_space: Number::from(219902325555200u64), free_space: Number::from(219902325555200u64),
unmapped_folders: None,
}, },
RootFolder { RootFolder {
id: Number::from(2),
path: "/nfs2".to_owned(), path: "/nfs2".to_owned(),
accessible: true, accessible: true,
free_space: Number::from(21990232555520u64), free_space: Number::from(21990232555520u64),
unmapped_folders: None,
}, },
]; ]);
app.data.radarr_data.quality_profile_map = app.data.radarr_data.quality_profile_map =
BiMap::from_iter([(2222, "HD - 1080p".to_owned())]); BiMap::from_iter([(2222, "HD - 1080p".to_owned())]);
app.data.radarr_data.tags_map = app.data.radarr_data.tags_map =
@@ -2926,9 +2931,11 @@ mod test {
fn root_folder() -> RootFolder { fn root_folder() -> RootFolder {
RootFolder { RootFolder {
id: Number::from(1),
path: "/nfs".to_owned(), path: "/nfs".to_owned(),
accessible: true, accessible: true,
free_space: Number::from(219902325555200u64), free_space: Number::from(219902325555200u64),
unmapped_folders: None,
} }
} }
+48 -1
View File
@@ -15,7 +15,7 @@ use crate::app::radarr::{
}; };
use crate::app::App; use crate::app::App;
use crate::logos::RADARR_LOGO; use crate::logos::RADARR_LOGO;
use crate::models::radarr_models::{Collection, DiskSpace, DownloadRecord, Movie}; use crate::models::radarr_models::{Collection, DiskSpace, DownloadRecord, Movie, RootFolder};
use crate::models::{HorizontallyScrollableText, Route}; use crate::models::{HorizontallyScrollableText, Route};
use crate::ui::radarr_ui::add_movie_ui::draw_add_movie_search_popup; use crate::ui::radarr_ui::add_movie_ui::draw_add_movie_search_popup;
use crate::ui::radarr_ui::collection_details_ui::draw_collection_details_popup; use crate::ui::radarr_ui::collection_details_ui::draw_collection_details_popup;
@@ -71,6 +71,7 @@ pub(super) fn draw_radarr_ui<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, ar
11, 11,
), ),
ActiveRadarrBlock::Downloads => draw_downloads(f, app, content_rect), ActiveRadarrBlock::Downloads => draw_downloads(f, app, content_rect),
ActiveRadarrBlock::RootFolders => draw_root_folders(f, app, content_rect),
ActiveRadarrBlock::Collections => draw_collections(f, app, content_rect), ActiveRadarrBlock::Collections => draw_collections(f, app, content_rect),
_ if MOVIE_DETAILS_BLOCKS.contains(&active_radarr_block) => { _ if MOVIE_DETAILS_BLOCKS.contains(&active_radarr_block) => {
draw_large_popup_over(f, app, content_rect, draw_library, draw_movie_info_popup) draw_large_popup_over(f, app, content_rect, draw_library, draw_movie_info_popup)
@@ -720,6 +721,52 @@ fn draw_collections<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect)
); );
} }
fn draw_root_folders<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
draw_table(
f,
area,
layout_block_top_border(),
TableProps {
content: &mut app.data.radarr_data.root_folders,
table_headers: vec!["Path", "Free Space", "Unmapped Folders"],
constraints: vec![
Constraint::Percentage(60),
Constraint::Percentage(20),
Constraint::Percentage(20),
],
help: app
.data
.radarr_data
.main_tabs
.get_active_tab_contextual_help(),
},
|root_folders| {
let RootFolder {
path,
free_space,
unmapped_folders,
..
} = root_folders;
let space: f64 = convert_to_gb(free_space.as_u64().unwrap());
Row::new(vec![
Cell::from(path.to_owned()),
Cell::from(format!("{:.2} GB", space)),
Cell::from(
unmapped_folders
.as_ref()
.unwrap_or(&Vec::new())
.len()
.to_string(),
),
])
.style(style_primary())
},
app.is_loading,
);
}
fn determine_row_style(downloads_vec: &[DownloadRecord], movie: &Movie) -> Style { fn determine_row_style(downloads_vec: &[DownloadRecord], movie: &Movie) -> Style {
if !movie.has_file { if !movie.has_file {
if let Some(download) = downloads_vec if let Some(download) = downloads_vec