feat: CLI and TUI support for track history and track details in Lidarr
This commit is contained in:
@@ -422,6 +422,8 @@ pub struct LidarrHistoryItem {
|
||||
pub album_id: i64,
|
||||
#[serde(deserialize_with = "super::from_i64")]
|
||||
pub artist_id: i64,
|
||||
#[serde(deserialize_with = "super::from_i64")]
|
||||
pub track_id: i64,
|
||||
#[serde(default)]
|
||||
pub quality: QualityWrapper,
|
||||
pub date: DateTime<Utc>,
|
||||
@@ -556,6 +558,7 @@ pub struct Track {
|
||||
pub duration: i64,
|
||||
pub has_file: bool,
|
||||
pub ratings: Ratings,
|
||||
pub track_file: Option<TrackFile>,
|
||||
}
|
||||
|
||||
impl From<LidarrSerdeable> for Serdeable {
|
||||
|
||||
@@ -27,6 +27,7 @@ use itertools::Itertools;
|
||||
use strum::EnumIter;
|
||||
#[cfg(test)]
|
||||
use {
|
||||
super::modals::TrackDetailsModal,
|
||||
crate::models::lidarr_models::{MonitorType, NewItemMonitorType},
|
||||
crate::models::stateful_table::SortOption,
|
||||
crate::network::lidarr_network::lidarr_network_test_utils::test_utils::indexer_settings,
|
||||
@@ -292,7 +293,21 @@ impl LidarrData<'_> {
|
||||
.metadata_profile_list
|
||||
.set_items(vec![metadata_profile().name]);
|
||||
|
||||
let mut album_details_modal = AlbumDetailsModal::default();
|
||||
let mut track_details_modal = TrackDetailsModal::default();
|
||||
track_details_modal.track_details = ScrollableText::with_string("Some details".to_owned());
|
||||
track_details_modal
|
||||
.track_history
|
||||
.set_items(vec![lidarr_history_item()]);
|
||||
track_details_modal.track_history.search = Some("track history search".into());
|
||||
track_details_modal.track_history.filter = Some("track history filter".into());
|
||||
track_details_modal
|
||||
.track_history
|
||||
.sorting(vec![sort_option!(id)]);
|
||||
|
||||
let mut album_details_modal = AlbumDetailsModal {
|
||||
track_details_modal: Some(track_details_modal),
|
||||
..AlbumDetailsModal::default()
|
||||
};
|
||||
album_details_modal.tracks.set_items(vec![track()]);
|
||||
album_details_modal.tracks.search = Some("album search".into());
|
||||
album_details_modal
|
||||
@@ -469,6 +484,8 @@ pub enum ActiveLidarrBlock {
|
||||
FilterHistoryError,
|
||||
FilterArtistHistory,
|
||||
FilterArtistHistoryError,
|
||||
FilterTrackHistory,
|
||||
FilterTrackHistoryError,
|
||||
History,
|
||||
HistoryItemDetails,
|
||||
HistorySortPrompt,
|
||||
@@ -499,12 +516,18 @@ pub enum ActiveLidarrBlock {
|
||||
SearchArtistHistoryError,
|
||||
SearchTracks,
|
||||
SearchTracksError,
|
||||
SearchTrackHistory,
|
||||
SearchTrackHistoryError,
|
||||
System,
|
||||
SystemLogs,
|
||||
SystemQueuedEvents,
|
||||
SystemTasks,
|
||||
SystemTaskStartConfirmPrompt,
|
||||
SystemUpdates,
|
||||
TrackDetails,
|
||||
TrackHistory,
|
||||
TrackHistoryDetails,
|
||||
TrackHistorySortPrompt,
|
||||
UpdateAllArtistsPrompt,
|
||||
UpdateAndScanArtistPrompt,
|
||||
UpdateDownloadsPrompt,
|
||||
@@ -767,6 +790,17 @@ pub static SYSTEM_DETAILS_BLOCKS: [ActiveLidarrBlock; 5] = [
|
||||
ActiveLidarrBlock::SystemUpdates,
|
||||
];
|
||||
|
||||
pub static TRACK_DETAILS_BLOCKS: [ActiveLidarrBlock; 8] = [
|
||||
ActiveLidarrBlock::TrackDetails,
|
||||
ActiveLidarrBlock::TrackHistory,
|
||||
ActiveLidarrBlock::TrackHistoryDetails,
|
||||
ActiveLidarrBlock::SearchTrackHistory,
|
||||
ActiveLidarrBlock::SearchTrackHistoryError,
|
||||
ActiveLidarrBlock::FilterTrackHistory,
|
||||
ActiveLidarrBlock::FilterTrackHistoryError,
|
||||
ActiveLidarrBlock::TrackHistorySortPrompt,
|
||||
];
|
||||
|
||||
impl From<ActiveLidarrBlock> for Route {
|
||||
fn from(active_lidarr_block: ActiveLidarrBlock) -> Route {
|
||||
Route::Lidarr(active_lidarr_block, None)
|
||||
|
||||
@@ -16,6 +16,7 @@ mod tests {
|
||||
EDIT_ARTIST_SELECTION_BLOCKS, EDIT_INDEXER_BLOCKS, EDIT_INDEXER_NZB_SELECTION_BLOCKS,
|
||||
EDIT_INDEXER_TORRENT_SELECTION_BLOCKS, HISTORY_BLOCKS, INDEXER_SETTINGS_BLOCKS,
|
||||
INDEXER_SETTINGS_SELECTION_BLOCKS, INDEXERS_BLOCKS, ROOT_FOLDERS_BLOCKS, SYSTEM_DETAILS_BLOCKS,
|
||||
TRACK_DETAILS_BLOCKS,
|
||||
};
|
||||
use crate::models::{
|
||||
BlockSelectionState, Route,
|
||||
@@ -695,4 +696,17 @@ mod tests {
|
||||
assert!(SYSTEM_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::SystemTaskStartConfirmPrompt));
|
||||
assert!(SYSTEM_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::SystemUpdates));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_track_details_blocks_contents() {
|
||||
assert_eq!(TRACK_DETAILS_BLOCKS.len(), 8);
|
||||
assert!(TRACK_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::TrackDetails));
|
||||
assert!(TRACK_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::TrackHistory));
|
||||
assert!(TRACK_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::TrackHistoryDetails));
|
||||
assert!(TRACK_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::SearchTrackHistory));
|
||||
assert!(TRACK_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::SearchTrackHistoryError));
|
||||
assert!(TRACK_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::FilterTrackHistory));
|
||||
assert!(TRACK_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::FilterTrackHistoryError));
|
||||
assert!(TRACK_DETAILS_BLOCKS.contains(&ActiveLidarrBlock::TrackHistorySortPrompt));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
use super::lidarr_data::{ActiveLidarrBlock, LidarrData};
|
||||
use crate::app::lidarr::lidarr_context_clues::{
|
||||
ALBUM_DETAILS_CONTEXT_CLUES, ALBUM_HISTORY_CONTEXT_CLUES, MANUAL_ALBUM_SEARCH_CONTEXT_CLUES,
|
||||
TRACK_DETAILS_CONTEXT_CLUES, TRACK_HISTORY_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::models::lidarr_models::{LidarrHistoryItem, LidarrRelease, Track, TrackFile};
|
||||
use crate::models::servarr_data::modals::EditIndexerModal;
|
||||
use crate::models::servarr_models::Indexer;
|
||||
use crate::models::stateful_table::StatefulTable;
|
||||
use crate::models::{
|
||||
HorizontallyScrollableText, TabRoute, TabState,
|
||||
HorizontallyScrollableText, ScrollableText, TabRoute, TabState,
|
||||
lidarr_models::{MonitorType, NewItemMonitorType},
|
||||
servarr_models::RootFolder,
|
||||
stateful_list::StatefulList,
|
||||
@@ -226,7 +227,7 @@ impl From<&LidarrData<'_>> for AddRootFolderModal {
|
||||
pub struct AlbumDetailsModal {
|
||||
pub tracks: StatefulTable<Track>,
|
||||
pub track_files: StatefulTable<TrackFile>,
|
||||
// pub track_details_modal: Option<EpisodeDetailsModal>,
|
||||
pub track_details_modal: Option<TrackDetailsModal>,
|
||||
pub album_history: StatefulTable<LidarrHistoryItem>,
|
||||
pub album_releases: StatefulTable<LidarrRelease>,
|
||||
pub album_details_tabs: TabState,
|
||||
@@ -236,7 +237,7 @@ impl Default for AlbumDetailsModal {
|
||||
fn default() -> AlbumDetailsModal {
|
||||
AlbumDetailsModal {
|
||||
tracks: StatefulTable::default(),
|
||||
// TODO episode_details_modal: None,
|
||||
track_details_modal: None,
|
||||
track_files: StatefulTable::default(),
|
||||
album_releases: StatefulTable::default(),
|
||||
album_history: StatefulTable::default(),
|
||||
@@ -263,3 +264,33 @@ impl Default for AlbumDetailsModal {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
pub struct TrackDetailsModal {
|
||||
pub track_details: ScrollableText,
|
||||
pub track_history: StatefulTable<LidarrHistoryItem>,
|
||||
pub track_details_tabs: TabState,
|
||||
}
|
||||
|
||||
impl Default for TrackDetailsModal {
|
||||
fn default() -> Self {
|
||||
TrackDetailsModal {
|
||||
track_details: ScrollableText::default(),
|
||||
track_history: StatefulTable::default(),
|
||||
track_details_tabs: TabState::new(vec![
|
||||
TabRoute {
|
||||
title: "Track Details".to_string(),
|
||||
route: ActiveLidarrBlock::TrackDetails.into(),
|
||||
contextual_help: Some(&TRACK_DETAILS_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "History".to_string(),
|
||||
route: ActiveLidarrBlock::TrackHistory.into(),
|
||||
contextual_help: Some(&TRACK_HISTORY_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
mod tests {
|
||||
use crate::app::lidarr::lidarr_context_clues::{
|
||||
ALBUM_DETAILS_CONTEXT_CLUES, ALBUM_HISTORY_CONTEXT_CLUES, MANUAL_ALBUM_SEARCH_CONTEXT_CLUES,
|
||||
TRACK_DETAILS_CONTEXT_CLUES, TRACK_HISTORY_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::models::lidarr_models::{Artist, MonitorType, NewItemMonitorType};
|
||||
use crate::models::servarr_data::lidarr::lidarr_data::{ActiveLidarrBlock, LidarrData};
|
||||
use crate::models::servarr_data::lidarr::modals::{
|
||||
AddArtistModal, AlbumDetailsModal, EditArtistModal,
|
||||
AddArtistModal, AlbumDetailsModal, EditArtistModal, TrackDetailsModal,
|
||||
};
|
||||
use crate::models::servarr_data::modals::EditIndexerModal;
|
||||
use crate::models::servarr_models::{Indexer, IndexerField, RootFolder};
|
||||
@@ -92,14 +93,14 @@ mod tests {
|
||||
quality_profile_id: 1,
|
||||
metadata_profile_id: 1,
|
||||
path: "/nfs/music/test_artist".to_owned(),
|
||||
tags: vec![serde_json::Number::from(1)],
|
||||
tags: vec![Number::from(1)],
|
||||
..Artist::default()
|
||||
};
|
||||
lidarr_data.artists.set_items(vec![artist]);
|
||||
|
||||
let edit_artist_modal = EditArtistModal::from(&lidarr_data);
|
||||
|
||||
assert_eq!(edit_artist_modal.monitored, Some(true));
|
||||
assert_some_eq_x!(&edit_artist_modal.monitored, &true);
|
||||
assert_eq!(
|
||||
*edit_artist_modal.monitor_list.current_selection(),
|
||||
NewItemMonitorType::All
|
||||
@@ -205,24 +206,24 @@ mod tests {
|
||||
let edit_indexer_modal = EditIndexerModal::from(&lidarr_data);
|
||||
|
||||
assert_str_eq!(edit_indexer_modal.name.text, "Test");
|
||||
assert_eq!(edit_indexer_modal.enable_rss, Some(true));
|
||||
assert_eq!(edit_indexer_modal.enable_automatic_search, Some(true));
|
||||
assert_eq!(edit_indexer_modal.enable_interactive_search, Some(true));
|
||||
assert_some_eq_x!(&edit_indexer_modal.enable_rss, &true);
|
||||
assert_some_eq_x!(&edit_indexer_modal.enable_automatic_search, &true);
|
||||
assert_some_eq_x!(&edit_indexer_modal.enable_interactive_search, &true);
|
||||
assert_eq!(edit_indexer_modal.priority, 1);
|
||||
assert_str_eq!(edit_indexer_modal.url.text, "https://test.com");
|
||||
assert_str_eq!(edit_indexer_modal.api_key.text, "1234");
|
||||
assert!(edit_indexer_modal.seed_ratio.text.is_empty());
|
||||
assert_is_empty!(edit_indexer_modal.seed_ratio.text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_album_details_modal_default() {
|
||||
let album_details_modal = AlbumDetailsModal::default();
|
||||
|
||||
assert!(album_details_modal.tracks.is_empty());
|
||||
// assert!(album_details_modal.track_details_modal.is_none());
|
||||
assert!(album_details_modal.track_files.is_empty());
|
||||
assert!(album_details_modal.album_releases.is_empty());
|
||||
assert!(album_details_modal.album_history.is_empty());
|
||||
assert_is_empty!(album_details_modal.tracks);
|
||||
assert_none!(album_details_modal.track_details_modal);
|
||||
assert_is_empty!(album_details_modal.track_files);
|
||||
assert_is_empty!(album_details_modal.album_releases);
|
||||
assert_is_empty!(album_details_modal.album_history);
|
||||
|
||||
assert_eq!(album_details_modal.album_details_tabs.tabs.len(), 3);
|
||||
|
||||
@@ -234,15 +235,8 @@ mod tests {
|
||||
album_details_modal.album_details_tabs.tabs[0].route,
|
||||
ActiveLidarrBlock::AlbumDetails.into()
|
||||
);
|
||||
assert!(
|
||||
album_details_modal.album_details_tabs.tabs[0]
|
||||
.contextual_help
|
||||
.is_some()
|
||||
);
|
||||
assert_eq!(
|
||||
album_details_modal.album_details_tabs.tabs[0]
|
||||
.contextual_help
|
||||
.unwrap(),
|
||||
assert_some_eq_x!(
|
||||
&album_details_modal.album_details_tabs.tabs[0].contextual_help,
|
||||
&ALBUM_DETAILS_CONTEXT_CLUES
|
||||
);
|
||||
assert_eq!(album_details_modal.album_details_tabs.tabs[0].config, None);
|
||||
@@ -255,15 +249,8 @@ mod tests {
|
||||
album_details_modal.album_details_tabs.tabs[1].route,
|
||||
ActiveLidarrBlock::AlbumHistory.into()
|
||||
);
|
||||
assert!(
|
||||
album_details_modal.album_details_tabs.tabs[1]
|
||||
.contextual_help
|
||||
.is_some()
|
||||
);
|
||||
assert_eq!(
|
||||
album_details_modal.album_details_tabs.tabs[1]
|
||||
.contextual_help
|
||||
.unwrap(),
|
||||
assert_some_eq_x!(
|
||||
&album_details_modal.album_details_tabs.tabs[1].contextual_help,
|
||||
&ALBUM_HISTORY_CONTEXT_CLUES
|
||||
);
|
||||
assert_eq!(album_details_modal.album_details_tabs.tabs[1].config, None);
|
||||
@@ -276,17 +263,48 @@ mod tests {
|
||||
album_details_modal.album_details_tabs.tabs[2].route,
|
||||
ActiveLidarrBlock::ManualAlbumSearch.into()
|
||||
);
|
||||
assert!(
|
||||
album_details_modal.album_details_tabs.tabs[2]
|
||||
.contextual_help
|
||||
.is_some()
|
||||
);
|
||||
assert_eq!(
|
||||
album_details_modal.album_details_tabs.tabs[2]
|
||||
.contextual_help
|
||||
.unwrap(),
|
||||
assert_some_eq_x!(
|
||||
&album_details_modal.album_details_tabs.tabs[2].contextual_help,
|
||||
&MANUAL_ALBUM_SEARCH_CONTEXT_CLUES
|
||||
);
|
||||
assert_eq!(album_details_modal.album_details_tabs.tabs[2].config, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_track_details_modal_default() {
|
||||
let track_details_modal = TrackDetailsModal::default();
|
||||
|
||||
assert_is_empty!(track_details_modal.track_details);
|
||||
assert_is_empty!(track_details_modal.track_history);
|
||||
|
||||
assert_eq!(track_details_modal.track_details_tabs.tabs.len(), 2);
|
||||
|
||||
assert_str_eq!(
|
||||
track_details_modal.track_details_tabs.tabs[0].title,
|
||||
"Track Details"
|
||||
);
|
||||
assert_eq!(
|
||||
track_details_modal.track_details_tabs.tabs[0].route,
|
||||
ActiveLidarrBlock::TrackDetails.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&track_details_modal.track_details_tabs.tabs[0].contextual_help,
|
||||
&TRACK_DETAILS_CONTEXT_CLUES
|
||||
);
|
||||
assert_eq!(track_details_modal.track_details_tabs.tabs[0].config, None);
|
||||
|
||||
assert_str_eq!(
|
||||
track_details_modal.track_details_tabs.tabs[1].title,
|
||||
"History"
|
||||
);
|
||||
assert_eq!(
|
||||
track_details_modal.track_details_tabs.tabs[1].route,
|
||||
ActiveLidarrBlock::TrackHistory.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&track_details_modal.track_details_tabs.tabs[1].contextual_help,
|
||||
&TRACK_HISTORY_CONTEXT_CLUES
|
||||
);
|
||||
assert_eq!(track_details_modal.track_details_tabs.tabs[1].config, None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user