Refactored the Edit/Add modals into their own structs so that adding similar modals in the future is more consistent, uses less RAM (since it's wrapped in an Option now), and is easier to implement. This comes with an initial example of the IndexerSettings UI that needs its own modal now. The modal has been created but it is still not used just yet so that's the next step.
This commit is contained in:
+117
-78
@@ -13,7 +13,10 @@ use crate::models::radarr_models::{
|
||||
IndexerSettings, LogResponse, Movie, MovieCommandBody, MovieHistoryItem, QualityProfile,
|
||||
QueueEvent, Release, ReleaseDownloadBody, RootFolder, SystemStatus, Tag, Task, Update,
|
||||
};
|
||||
use crate::models::servarr_data::radarr_data::ActiveRadarrBlock;
|
||||
use crate::models::servarr_data::radarr::modals::{
|
||||
AddMovieModal, EditCollectionModal, EditMovieModal,
|
||||
};
|
||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||
use crate::models::{HorizontallyScrollableText, Route, Scrollable, ScrollableText};
|
||||
use crate::network::{Network, NetworkEvent, RequestMethod, RequestProps};
|
||||
use crate::utils::{convert_runtime, convert_to_gb};
|
||||
@@ -151,55 +154,76 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
async fn add_movie(&mut self) {
|
||||
info!("Adding new movie to Radarr");
|
||||
let body = {
|
||||
let quality_profile_id = self.extract_quality_profile_id().await;
|
||||
let tag_ids_vec = self.extract_and_add_tag_ids_vec().await;
|
||||
let app = self.app.lock().await;
|
||||
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 tags = self
|
||||
.app
|
||||
.lock()
|
||||
.await
|
||||
.data
|
||||
.radarr_data
|
||||
.add_movie_modal
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.tags
|
||||
.text
|
||||
.clone();
|
||||
let tag_ids_vec = self.extract_and_add_tag_ids_vec(tags).await;
|
||||
let mut app = self.app.lock().await;
|
||||
let AddMovieModal {
|
||||
root_folder_list,
|
||||
monitor_list,
|
||||
minimum_availability_list,
|
||||
quality_profile_list,
|
||||
..
|
||||
} = app.data.radarr_data.add_movie_modal.as_ref().unwrap();
|
||||
let (tmdb_id, title) = if let Route::Radarr(active_radarr_block, _) = *app.get_current_route()
|
||||
{
|
||||
if *active_radarr_block == ActiveRadarrBlock::CollectionDetails {
|
||||
let CollectionMovie { tmdb_id, title, .. } =
|
||||
app.data.radarr_data.collection_movies.current_selection();
|
||||
if active_radarr_block == ActiveRadarrBlock::CollectionDetails {
|
||||
let CollectionMovie { tmdb_id, title, .. } = app
|
||||
.data
|
||||
.radarr_data
|
||||
.collection_movies
|
||||
.current_selection()
|
||||
.clone();
|
||||
(tmdb_id, title.text.clone())
|
||||
} else {
|
||||
let AddMovieSearchResult { tmdb_id, title, .. } =
|
||||
app.data.radarr_data.add_searched_movies.current_selection();
|
||||
let AddMovieSearchResult { tmdb_id, title, .. } = app
|
||||
.data
|
||||
.radarr_data
|
||||
.add_searched_movies
|
||||
.current_selection()
|
||||
.clone();
|
||||
(tmdb_id, title.text.clone())
|
||||
}
|
||||
} else {
|
||||
let AddMovieSearchResult { tmdb_id, title, .. } =
|
||||
app.data.radarr_data.add_searched_movies.current_selection();
|
||||
let AddMovieSearchResult { tmdb_id, title, .. } = app
|
||||
.data
|
||||
.radarr_data
|
||||
.add_searched_movies
|
||||
.current_selection()
|
||||
.clone();
|
||||
(tmdb_id, title.text.clone())
|
||||
};
|
||||
|
||||
let RootFolder { path, .. } = root_folders
|
||||
let quality_profile = quality_profile_list.current_selection();
|
||||
let quality_profile_id = *app
|
||||
.data
|
||||
.radarr_data
|
||||
.quality_profile_map
|
||||
.iter()
|
||||
.filter(|folder| folder.accessible)
|
||||
.reduce(|a, b| {
|
||||
if a.free_space.as_u64().unwrap() > b.free_space.as_u64().unwrap() {
|
||||
a
|
||||
} else {
|
||||
b
|
||||
}
|
||||
})
|
||||
.filter(|(_, value)| *value == quality_profile)
|
||||
.map(|(key, _)| key)
|
||||
.next()
|
||||
.unwrap();
|
||||
let monitor = app
|
||||
.data
|
||||
.radarr_data
|
||||
.monitor_list
|
||||
.current_selection()
|
||||
.to_string();
|
||||
let minimum_availability = app
|
||||
.data
|
||||
.radarr_data
|
||||
.minimum_availability_list
|
||||
.current_selection()
|
||||
.to_string();
|
||||
|
||||
let path = root_folder_list.current_selection().path.clone();
|
||||
let monitor = monitor_list.current_selection().to_string();
|
||||
let minimum_availability = minimum_availability_list.current_selection().to_string();
|
||||
|
||||
app.data.radarr_data.add_movie_modal = None;
|
||||
|
||||
AddMovieBody {
|
||||
tmdb_id: tmdb_id.as_u64().unwrap(),
|
||||
title,
|
||||
root_folder_path: path.to_owned(),
|
||||
root_folder_path: path,
|
||||
minimum_availability,
|
||||
monitored: true,
|
||||
quality_profile_id,
|
||||
@@ -462,21 +486,31 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
info!("Constructing edit collection body");
|
||||
|
||||
let body = {
|
||||
let quality_profile_id = self.extract_quality_profile_id().await;
|
||||
let mut app = self.app.lock().await;
|
||||
let response = app.response.drain(..).collect::<String>();
|
||||
let mut detailed_collection_body: Value = serde_json::from_str(&response).unwrap();
|
||||
|
||||
let root_folder_path: String = app.data.radarr_data.edit_path.drain();
|
||||
|
||||
let monitored = app.data.radarr_data.edit_monitored.unwrap_or_default();
|
||||
let search_on_add = app.data.radarr_data.edit_search_on_add.unwrap_or_default();
|
||||
let minimum_availability = app
|
||||
let EditCollectionModal {
|
||||
path,
|
||||
search_on_add,
|
||||
minimum_availability_list,
|
||||
monitored,
|
||||
quality_profile_list,
|
||||
} = app.data.radarr_data.edit_collection_modal.as_ref().unwrap();
|
||||
let quality_profile = quality_profile_list.current_selection();
|
||||
let quality_profile_id = *app
|
||||
.data
|
||||
.radarr_data
|
||||
.minimum_availability_list
|
||||
.current_selection()
|
||||
.to_string();
|
||||
.quality_profile_map
|
||||
.iter()
|
||||
.filter(|(_, value)| *value == quality_profile)
|
||||
.map(|(key, _)| key)
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
let root_folder_path: String = path.text.clone();
|
||||
let monitored = monitored.unwrap_or_default();
|
||||
let search_on_add = search_on_add.unwrap_or_default();
|
||||
let minimum_availability = minimum_availability_list.current_selection().to_string();
|
||||
|
||||
*detailed_collection_body.get_mut("monitored").unwrap() = json!(monitored);
|
||||
*detailed_collection_body
|
||||
@@ -488,6 +522,8 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
*detailed_collection_body.get_mut("rootFolderPath").unwrap() = json!(root_folder_path);
|
||||
*detailed_collection_body.get_mut("searchOnAdd").unwrap() = json!(search_on_add);
|
||||
|
||||
app.data.radarr_data.edit_collection_modal = None;
|
||||
|
||||
detailed_collection_body
|
||||
};
|
||||
|
||||
@@ -533,28 +569,50 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
info!("Constructing edit movie body");
|
||||
|
||||
let body = {
|
||||
let quality_profile_id = self.extract_quality_profile_id().await;
|
||||
let tag_ids_vec = self.extract_and_add_tag_ids_vec().await;
|
||||
let tags = self
|
||||
.app
|
||||
.lock()
|
||||
.await
|
||||
.data
|
||||
.radarr_data
|
||||
.edit_movie_modal
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.tags
|
||||
.text
|
||||
.clone();
|
||||
let tag_ids_vec = self.extract_and_add_tag_ids_vec(tags).await;
|
||||
let mut app = self.app.lock().await;
|
||||
let response = app.response.drain(..).collect::<String>();
|
||||
let mut detailed_movie_body: Value = serde_json::from_str(&response).unwrap();
|
||||
|
||||
let path: String = app.data.radarr_data.edit_path.drain();
|
||||
|
||||
let monitored = app.data.radarr_data.edit_monitored.unwrap_or_default();
|
||||
let minimum_availability = app
|
||||
let EditMovieModal {
|
||||
monitored,
|
||||
path,
|
||||
minimum_availability_list,
|
||||
quality_profile_list,
|
||||
..
|
||||
} = app.data.radarr_data.edit_movie_modal.as_ref().unwrap();
|
||||
let quality_profile = quality_profile_list.current_selection();
|
||||
let quality_profile_id = *app
|
||||
.data
|
||||
.radarr_data
|
||||
.minimum_availability_list
|
||||
.current_selection()
|
||||
.to_string();
|
||||
.quality_profile_map
|
||||
.iter()
|
||||
.filter(|(_, value)| *value == quality_profile)
|
||||
.map(|(key, _)| key)
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
*detailed_movie_body.get_mut("monitored").unwrap() = json!(monitored);
|
||||
*detailed_movie_body.get_mut("minimumAvailability").unwrap() = json!(minimum_availability);
|
||||
*detailed_movie_body.get_mut("monitored").unwrap() = json!(monitored.unwrap_or_default());
|
||||
*detailed_movie_body.get_mut("minimumAvailability").unwrap() =
|
||||
json!(minimum_availability_list.current_selection().to_string());
|
||||
*detailed_movie_body.get_mut("qualityProfileId").unwrap() = json!(quality_profile_id);
|
||||
*detailed_movie_body.get_mut("path").unwrap() = json!(path);
|
||||
*detailed_movie_body.get_mut("path").unwrap() = json!(path.text.clone());
|
||||
*detailed_movie_body.get_mut("tags").unwrap() = json!(tag_ids_vec);
|
||||
|
||||
app.data.radarr_data.edit_movie_modal = None;
|
||||
|
||||
detailed_movie_body
|
||||
};
|
||||
|
||||
@@ -1408,27 +1466,8 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
}
|
||||
}
|
||||
|
||||
async fn extract_quality_profile_id(&mut self) -> u64 {
|
||||
let app = self.app.lock().await;
|
||||
let quality_profile = app
|
||||
.data
|
||||
.radarr_data
|
||||
.quality_profile_list
|
||||
.current_selection();
|
||||
*app
|
||||
.data
|
||||
.radarr_data
|
||||
.quality_profile_map
|
||||
.iter()
|
||||
.filter(|(_, value)| *value == quality_profile)
|
||||
.map(|(key, _)| key)
|
||||
.next()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn extract_and_add_tag_ids_vec(&mut self) -> Vec<u64> {
|
||||
async fn extract_and_add_tag_ids_vec(&mut self, edit_tags: String) -> Vec<u64> {
|
||||
let tags_map = self.app.lock().await.data.radarr_data.tags_map.clone();
|
||||
let edit_tags = self.app.lock().await.data.radarr_data.edit_tags.drain();
|
||||
let tags = edit_tags.clone();
|
||||
let missing_tags_vec = edit_tags
|
||||
.split(',')
|
||||
|
||||
@@ -16,7 +16,7 @@ mod test {
|
||||
CollectionMovie, IndexerField, IndexerSelectOption, Language, MediaInfo, MinimumAvailability,
|
||||
Monitor, MovieFile, Quality, QualityWrapper, Rating, RatingsList,
|
||||
};
|
||||
use crate::models::servarr_data::radarr_data::ActiveRadarrBlock;
|
||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||
use crate::models::HorizontallyScrollableText;
|
||||
use crate::App;
|
||||
|
||||
@@ -1481,7 +1481,7 @@ mod test {
|
||||
Some(json!({
|
||||
"tmdbId": 1234,
|
||||
"title": "Test",
|
||||
"rootFolderPath": "/nfs",
|
||||
"rootFolderPath": "/nfs2",
|
||||
"minimumAvailability": "announced",
|
||||
"monitored": true,
|
||||
"qualityProfileId": 2222,
|
||||
@@ -1498,7 +1498,11 @@ mod test {
|
||||
|
||||
{
|
||||
let mut app = app_arc.lock().await;
|
||||
app.data.radarr_data.root_folders.set_items(vec![
|
||||
let mut add_movie_modal = AddMovieModal {
|
||||
tags: "usenet, testing".into(),
|
||||
..AddMovieModal::default()
|
||||
};
|
||||
add_movie_modal.root_folder_list.set_items(vec![
|
||||
RootFolder {
|
||||
id: Number::from(1),
|
||||
path: "/nfs".to_owned(),
|
||||
@@ -1514,26 +1518,21 @@ mod test {
|
||||
unmapped_folders: None,
|
||||
},
|
||||
]);
|
||||
add_movie_modal.root_folder_list.state.select(Some(1));
|
||||
add_movie_modal
|
||||
.quality_profile_list
|
||||
.set_items(vec!["HD - 1080p".to_owned()]);
|
||||
add_movie_modal
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(Monitor::iter()));
|
||||
add_movie_modal
|
||||
.minimum_availability_list
|
||||
.set_items(Vec::from_iter(MinimumAvailability::iter()));
|
||||
app.data.radarr_data.add_movie_modal = Some(add_movie_modal);
|
||||
app.data.radarr_data.quality_profile_map =
|
||||
BiMap::from_iter([(2222, "HD - 1080p".to_owned())]);
|
||||
app.data.radarr_data.tags_map =
|
||||
BiMap::from_iter([(1, "usenet".to_owned()), (2, "testing".to_owned())]);
|
||||
app.data.radarr_data.edit_tags = "usenet, testing".to_owned().into();
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.quality_profile_list
|
||||
.set_items(vec!["HD - 1080p".to_owned()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(Monitor::iter()));
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.minimum_availability_list
|
||||
.set_items(Vec::from_iter(MinimumAvailability::iter()));
|
||||
if movie_details_context {
|
||||
app
|
||||
.data
|
||||
@@ -1554,6 +1553,13 @@ mod test {
|
||||
network.handle_radarr_event(RadarrEvent::AddMovie).await;
|
||||
|
||||
async_server.assert_async().await;
|
||||
assert!(app_arc
|
||||
.lock()
|
||||
.await
|
||||
.data
|
||||
.radarr_data
|
||||
.add_movie_modal
|
||||
.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -1617,19 +1623,19 @@ mod test {
|
||||
let mut app = app_arc.lock().await;
|
||||
app.data.radarr_data.tags_map =
|
||||
BiMap::from_iter([(1, "usenet".to_owned()), (2, "testing".to_owned())]);
|
||||
app.data.radarr_data.edit_tags = "usenet, testing".to_owned().into();
|
||||
app.data.radarr_data.edit_path = "/nfs/Test Path".to_owned().into();
|
||||
app.data.radarr_data.edit_monitored = Some(false);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
let mut edit_movie = EditMovieModal {
|
||||
tags: "usenet, testing".to_owned().into(),
|
||||
path: "/nfs/Test Path".to_owned().into(),
|
||||
monitored: Some(false),
|
||||
..EditMovieModal::default()
|
||||
};
|
||||
edit_movie
|
||||
.quality_profile_list
|
||||
.set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
edit_movie
|
||||
.minimum_availability_list
|
||||
.set_items(Vec::from_iter(MinimumAvailability::iter()));
|
||||
app.data.radarr_data.edit_movie_modal = Some(edit_movie);
|
||||
app.data.radarr_data.movies.set_items(vec![Movie {
|
||||
monitored: false,
|
||||
..movie()
|
||||
@@ -1646,8 +1652,7 @@ mod test {
|
||||
|
||||
let app = app_arc.lock().await;
|
||||
assert!(app.response.is_empty());
|
||||
assert!(app.data.radarr_data.edit_path.text.is_empty());
|
||||
assert!(app.data.radarr_data.edit_tags.text.is_empty());
|
||||
assert!(app.data.radarr_data.edit_movie_modal.is_none());
|
||||
assert!(app.data.radarr_data.movie_details.items.is_empty());
|
||||
}
|
||||
|
||||
@@ -1711,19 +1716,19 @@ mod test {
|
||||
.await;
|
||||
{
|
||||
let mut app = app_arc.lock().await;
|
||||
app.data.radarr_data.edit_path = "/nfs/Test Path".to_owned().into();
|
||||
app.data.radarr_data.edit_monitored = Some(false);
|
||||
app.data.radarr_data.edit_search_on_add = Some(false);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
let mut edit_collection_modal = EditCollectionModal {
|
||||
path: "/nfs/Test Path".into(),
|
||||
monitored: Some(false),
|
||||
search_on_add: Some(false),
|
||||
..EditCollectionModal::default()
|
||||
};
|
||||
edit_collection_modal
|
||||
.quality_profile_list
|
||||
.set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
edit_collection_modal
|
||||
.minimum_availability_list
|
||||
.set_items(Vec::from_iter(MinimumAvailability::iter()));
|
||||
app.data.radarr_data.edit_collection_modal = Some(edit_collection_modal);
|
||||
app.data.radarr_data.collections.set_items(vec![Collection {
|
||||
monitored: false,
|
||||
search_on_add: false,
|
||||
@@ -1743,7 +1748,7 @@ mod test {
|
||||
|
||||
let app = app_arc.lock().await;
|
||||
assert!(app.response.is_empty());
|
||||
assert!(app.data.radarr_data.edit_path.text.is_empty());
|
||||
assert!(app.data.radarr_data.edit_collection_modal.is_none());
|
||||
assert!(app.data.radarr_data.movie_details.items.is_empty());
|
||||
}
|
||||
|
||||
@@ -1775,30 +1780,12 @@ mod test {
|
||||
async_server.assert_async().await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_extract_quality_profile_id() {
|
||||
let app_arc = Arc::new(Mutex::new(App::default()));
|
||||
{
|
||||
let mut app = app_arc.lock().await;
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.quality_profile_list
|
||||
.set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]);
|
||||
app.data.radarr_data.quality_profile_map =
|
||||
BiMap::from_iter([(1, "Any".to_owned()), (2, "HD - 1080p".to_owned())]);
|
||||
}
|
||||
let mut network = Network::new(&app_arc, CancellationToken::new());
|
||||
|
||||
assert_eq!(network.extract_quality_profile_id().await, 1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_extract_and_add_tag_ids_vec() {
|
||||
let app_arc = Arc::new(Mutex::new(App::default()));
|
||||
let tags = " test,hi ,, usenet ".to_owned();
|
||||
{
|
||||
let mut app = app_arc.lock().await;
|
||||
app.data.radarr_data.edit_tags = " test,hi ,, usenet ".to_owned().into();
|
||||
app.data.radarr_data.tags_map = BiMap::from_iter([
|
||||
(1, "usenet".to_owned()),
|
||||
(2, "test".to_owned()),
|
||||
@@ -1807,7 +1794,10 @@ mod test {
|
||||
}
|
||||
let mut network = Network::new(&app_arc, CancellationToken::new());
|
||||
|
||||
assert_eq!(network.extract_and_add_tag_ids_vec().await, vec![2, 3, 1]);
|
||||
assert_eq!(
|
||||
network.extract_and_add_tag_ids_vec(tags).await,
|
||||
vec![2, 3, 1]
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -1819,15 +1809,19 @@ mod test {
|
||||
RadarrEvent::GetTags.resource(),
|
||||
)
|
||||
.await;
|
||||
let tags = "usenet, test, testing".to_owned();
|
||||
{
|
||||
let mut app = app_arc.lock().await;
|
||||
app.data.radarr_data.edit_tags = "usenet, test, testing".to_owned().into();
|
||||
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
|
||||
tags: tags.clone().into(),
|
||||
..EditMovieModal::default()
|
||||
});
|
||||
app.data.radarr_data.tags_map =
|
||||
BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]);
|
||||
}
|
||||
let mut network = Network::new(&app_arc, CancellationToken::new());
|
||||
|
||||
let tag_ids_vec = network.extract_and_add_tag_ids_vec().await;
|
||||
let tag_ids_vec = network.extract_and_add_tag_ids_vec(tags).await;
|
||||
|
||||
async_server.assert_async().await;
|
||||
assert_eq!(tag_ids_vec, vec![1, 2, 3]);
|
||||
|
||||
Reference in New Issue
Block a user