1 use std::sync::{Arc, RwLock};
2 
3 use cursive::view::ViewWrapper;
4 use cursive::Cursive;
5 
6 use crate::command::Command;
7 use crate::commands::CommandResult;
8 use crate::library::Library;
9 use crate::model::album::Album;
10 use crate::model::artist::Artist;
11 use crate::queue::Queue;
12 use crate::traits::ViewExt;
13 use crate::ui::listview::ListView;
14 use crate::ui::tabview::TabView;
15 
16 pub struct AlbumView {
17     album: Album,
18     tabs: TabView,
19 }
20 
21 impl AlbumView {
new(queue: Arc<Queue>, library: Arc<Library>, album: &Album) -> Self22     pub fn new(queue: Arc<Queue>, library: Arc<Library>, album: &Album) -> Self {
23         let mut album = album.clone();
24 
25         album.load_all_tracks(queue.get_spotify());
26 
27         let tracks = if let Some(t) = album.tracks.as_ref() {
28             t.clone()
29         } else {
30             Vec::new()
31         };
32 
33         let artists = album
34             .artist_ids
35             .iter()
36             .zip(album.artists.iter())
37             .map(|(id, name)| Artist::new(id.clone(), name.clone()))
38             .collect();
39 
40         let tabs = TabView::new()
41             .tab(
42                 "tracks",
43                 "Tracks",
44                 ListView::new(
45                     Arc::new(RwLock::new(tracks)),
46                     queue.clone(),
47                     library.clone(),
48                 ),
49             )
50             .tab(
51                 "artists",
52                 "Artists",
53                 ListView::new(Arc::new(RwLock::new(artists)), queue, library),
54             );
55 
56         Self { album, tabs }
57     }
58 }
59 
60 impl ViewWrapper for AlbumView {
61     wrap_impl!(self.tabs: TabView);
62 }
63 
64 impl ViewExt for AlbumView {
title(&self) -> String65     fn title(&self) -> String {
66         format!("{} ({})", self.album.title, self.album.year)
67     }
68 
title_sub(&self) -> String69     fn title_sub(&self) -> String {
70         if let Some(tracks) = &self.album.tracks {
71             let duration_secs: u64 = tracks.iter().map(|t| t.duration as u64 / 1000).sum();
72             let duration = std::time::Duration::from_secs(duration_secs);
73             let duration_str = crate::utils::format_duration(&duration);
74             format!("{} tracks, {}", tracks.len(), duration_str)
75         } else {
76             "".to_string()
77         }
78     }
79 
on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result<CommandResult, String>80     fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result<CommandResult, String> {
81         self.tabs.on_command(s, cmd)
82     }
83 }
84