Refactor: Make Spotify cloneable

This commit is contained in:
Henrik Friedrichsen
2021-04-03 22:35:08 +02:00
parent 8483653cde
commit 0f573f8247
14 changed files with 49 additions and 62 deletions

View File

@@ -27,7 +27,7 @@ pub struct Album {
} }
impl Album { impl Album {
pub fn load_tracks(&mut self, spotify: Arc<Spotify>) { pub fn load_tracks(&mut self, spotify: Spotify) {
if self.tracks.is_some() { if self.tracks.is_some() {
return; return;
} }

View File

@@ -34,7 +34,7 @@ impl Artist {
} }
} }
pub fn load_albums(&mut self, spotify: Arc<Spotify>) { pub fn load_albums(&mut self, spotify: Spotify) {
if let Some(albums) = self.albums.as_mut() { if let Some(albums) = self.albums.as_mut() {
for album in albums { for album in albums {
album.load_tracks(spotify.clone()); album.load_tracks(spotify.clone());

View File

@@ -37,7 +37,7 @@ pub enum CommandResult {
pub struct CommandManager { pub struct CommandManager {
aliases: HashMap<String, String>, aliases: HashMap<String, String>,
bindings: RefCell<HashMap<String, Command>>, bindings: RefCell<HashMap<String, Command>>,
spotify: Arc<Spotify>, spotify: Spotify,
queue: Arc<Queue>, queue: Arc<Queue>,
library: Arc<Library>, library: Arc<Library>,
config: Arc<Config>, config: Arc<Config>,
@@ -46,7 +46,7 @@ pub struct CommandManager {
impl CommandManager { impl CommandManager {
pub fn new( pub fn new(
spotify: Arc<Spotify>, spotify: Spotify,
queue: Arc<Queue>, queue: Arc<Queue>,
library: Arc<Library>, library: Arc<Library>,
config: Arc<Config>, config: Arc<Config>,

View File

@@ -36,12 +36,12 @@ pub struct Library {
pub user_id: Option<String>, pub user_id: Option<String>,
pub display_name: Option<String>, pub display_name: Option<String>,
ev: EventManager, ev: EventManager,
spotify: Arc<Spotify>, spotify: Spotify,
pub cfg: Arc<Config>, pub cfg: Arc<Config>,
} }
impl Library { impl Library {
pub fn new(ev: &EventManager, spotify: Arc<Spotify>, cfg: Arc<Config>) -> Self { pub fn new(ev: &EventManager, spotify: Spotify, cfg: Arc<Config>) -> Self {
let current_user = spotify.current_user(); let current_user = spotify.current_user();
let user_id = current_user.as_ref().map(|u| u.id.clone()); let user_id = current_user.as_ref().map(|u| u.id.clone());
let display_name = current_user.as_ref().and_then(|u| u.display_name.clone()); let display_name = current_user.as_ref().and_then(|u| u.display_name.clone());

View File

@@ -197,11 +197,7 @@ fn main() {
let event_manager = EventManager::new(cursive.cb_sink().clone()); let event_manager = EventManager::new(cursive.cb_sink().clone());
let spotify = Arc::new(spotify::Spotify::new( let spotify = spotify::Spotify::new(event_manager.clone(), credentials, cfg.clone());
event_manager.clone(),
credentials,
cfg.clone(),
));
let queue = Arc::new(queue::Queue::new(spotify.clone(), cfg.clone())); let queue = Arc::new(queue::Queue::new(spotify.clone(), cfg.clone()));

View File

@@ -28,7 +28,7 @@ type Metadata = HashMap<String, Variant<Box<dyn RefArg>>>;
struct MprisState(String, Option<Playable>); struct MprisState(String, Option<Playable>);
fn get_playbackstatus(spotify: Arc<Spotify>) -> String { fn get_playbackstatus(spotify: Spotify) -> String {
match spotify.get_current_status() { match spotify.get_current_status() {
PlayerEvent::Playing | PlayerEvent::FinishedTrack => "Playing", PlayerEvent::Playing | PlayerEvent::FinishedTrack => "Playing",
PlayerEvent::Paused => "Paused", PlayerEvent::Paused => "Paused",
@@ -136,7 +136,7 @@ fn get_metadata(playable: Option<Playable>) -> Metadata {
fn run_dbus_server( fn run_dbus_server(
ev: EventManager, ev: EventManager,
spotify: Arc<Spotify>, spotify: Spotify,
queue: Arc<Queue>, queue: Arc<Queue>,
rx: mpsc::Receiver<MprisState>, rx: mpsc::Receiver<MprisState>,
) { ) {
@@ -691,11 +691,11 @@ fn run_dbus_server(
pub struct MprisManager { pub struct MprisManager {
tx: mpsc::Sender<MprisState>, tx: mpsc::Sender<MprisState>,
queue: Arc<Queue>, queue: Arc<Queue>,
spotify: Arc<Spotify>, spotify: Spotify,
} }
impl MprisManager { impl MprisManager {
pub fn new(ev: EventManager, spotify: Arc<Spotify>, queue: Arc<Queue>) -> Self { pub fn new(ev: EventManager, spotify: Spotify, queue: Arc<Queue>) -> Self {
let (tx, rx) = mpsc::channel::<MprisState>(); let (tx, rx) = mpsc::channel::<MprisState>();
{ {

View File

@@ -23,7 +23,7 @@ pub struct Playlist {
} }
impl Playlist { impl Playlist {
pub fn load_tracks(&mut self, spotify: Arc<Spotify>) { pub fn load_tracks(&mut self, spotify: Spotify) {
if self.tracks.is_some() { if self.tracks.is_some() {
return; return;
} }
@@ -31,7 +31,7 @@ impl Playlist {
self.tracks = Some(self.get_all_tracks(spotify)); self.tracks = Some(self.get_all_tracks(spotify));
} }
fn get_all_tracks(&self, spotify: Arc<Spotify>) -> Vec<Track> { fn get_all_tracks(&self, spotify: Spotify) -> Vec<Track> {
let mut collected_tracks = Vec::new(); let mut collected_tracks = Vec::new();
let mut tracks_result = spotify.user_playlist_tracks(&self.id, 100, 0); let mut tracks_result = spotify.user_playlist_tracks(&self.id, 100, 0);
@@ -71,12 +71,7 @@ impl Playlist {
}) })
} }
pub fn delete_track( pub fn delete_track(&mut self, index: usize, spotify: Spotify, library: Arc<Library>) -> bool {
&mut self,
index: usize,
spotify: Arc<Spotify>,
library: Arc<Library>,
) -> bool {
let track = self.tracks.as_ref().unwrap()[index].clone(); let track = self.tracks.as_ref().unwrap()[index].clone();
debug!("deleting track: {} {:?}", index, track); debug!("deleting track: {} {:?}", index, track);
match spotify.delete_tracks(&self.id, &self.snapshot_id, &[(&track, track.list_index)]) { match spotify.delete_tracks(&self.id, &self.snapshot_id, &[(&track, track.list_index)]) {
@@ -92,12 +87,7 @@ impl Playlist {
} }
} }
pub fn append_tracks( pub fn append_tracks(&mut self, new_tracks: &[Track], spotify: Spotify, library: Arc<Library>) {
&mut self,
new_tracks: &[Track],
spotify: Arc<Spotify>,
library: Arc<Library>,
) {
let track_ids: Vec<String> = new_tracks let track_ids: Vec<String> = new_tracks
.to_vec() .to_vec()
.iter() .iter()

View File

@@ -25,12 +25,12 @@ pub struct Queue {
pub queue: Arc<RwLock<Vec<Playable>>>, pub queue: Arc<RwLock<Vec<Playable>>>,
random_order: RwLock<Option<Vec<usize>>>, random_order: RwLock<Option<Vec<usize>>>,
current_track: RwLock<Option<usize>>, current_track: RwLock<Option<usize>>,
spotify: Arc<Spotify>, spotify: Spotify,
cfg: Arc<Config>, cfg: Arc<Config>,
} }
impl Queue { impl Queue {
pub fn new(spotify: Arc<Spotify>, cfg: Arc<Config>) -> Queue { pub fn new(spotify: Spotify, cfg: Arc<Config>) -> Queue {
let queue = cfg.state().queue.clone(); let queue = cfg.state().queue.clone();
Queue { Queue {
queue: Arc::new(RwLock::new(queue)), queue: Arc::new(RwLock::new(queue)),
@@ -370,7 +370,7 @@ impl Queue {
} }
} }
pub fn get_spotify(&self) -> Arc<Spotify> { pub fn get_spotify(&self) -> Spotify {
self.spotify.clone() self.spotify.clone()
} }
} }

View File

@@ -21,7 +21,7 @@ pub struct Show {
} }
impl Show { impl Show {
pub fn load_episodes(&mut self, spotify: Arc<Spotify>) { pub fn load_episodes(&mut self, spotify: Spotify) {
if self.episodes.is_some() { if self.episodes.is_some() {
return; return;
} }

View File

@@ -62,16 +62,17 @@ pub enum PlayerEvent {
FinishedTrack, FinishedTrack,
} }
#[derive(Clone)]
pub struct Spotify { pub struct Spotify {
events: EventManager, events: EventManager,
credentials: Credentials, credentials: Credentials,
cfg: Arc<config::Config>, cfg: Arc<config::Config>,
status: RwLock<PlayerEvent>, status: Arc<RwLock<PlayerEvent>>,
api: RwLock<SpotifyAPI>, api: Arc<RwLock<SpotifyAPI>>,
elapsed: RwLock<Option<Duration>>, elapsed: Arc<RwLock<Option<Duration>>>,
since: RwLock<Option<SystemTime>>, since: Arc<RwLock<Option<SystemTime>>>,
token_issued: RwLock<Option<SystemTime>>, token_issued: Arc<RwLock<Option<SystemTime>>>,
channel: RwLock<Option<mpsc::UnboundedSender<WorkerCommand>>>, channel: Arc<RwLock<Option<mpsc::UnboundedSender<WorkerCommand>>>>,
user: Option<String>, user: Option<String>,
country: Option<Country>, country: Option<Country>,
} }
@@ -86,12 +87,12 @@ impl Spotify {
events, events,
credentials, credentials,
cfg: cfg.clone(), cfg: cfg.clone(),
status: RwLock::new(PlayerEvent::Stopped), status: Arc::new(RwLock::new(PlayerEvent::Stopped)),
api: RwLock::new(SpotifyAPI::default()), api: Arc::new(RwLock::new(SpotifyAPI::default())),
elapsed: RwLock::new(None), elapsed: Arc::new(RwLock::new(None)),
since: RwLock::new(None), since: Arc::new(RwLock::new(None)),
token_issued: RwLock::new(None), token_issued: Arc::new(RwLock::new(None)),
channel: RwLock::new(None), channel: Arc::new(RwLock::new(None)),
user: None, user: None,
country: None, country: None,
}; };

View File

@@ -45,7 +45,7 @@ enum ContextMenuAction {
impl ContextMenu { impl ContextMenu {
pub fn add_track_dialog( pub fn add_track_dialog(
library: Arc<Library>, library: Arc<Library>,
spotify: Arc<Spotify>, spotify: Spotify,
track: Track, track: Track,
) -> NamedView<AddToPlaylistMenu> { ) -> NamedView<AddToPlaylistMenu> {
let mut list_select: SelectView<Playlist> = SelectView::new(); let mut list_select: SelectView<Playlist> = SelectView::new();

View File

@@ -16,7 +16,7 @@ use crate::ui::listview::ListView;
pub struct PlaylistView { pub struct PlaylistView {
playlist: Playlist, playlist: Playlist,
list: ListView<Track>, list: ListView<Track>,
spotify: Arc<Spotify>, spotify: Spotify,
library: Arc<Library>, library: Arc<Library>,
queue: Arc<Queue>, queue: Arc<Queue>,
} }

View File

@@ -36,12 +36,12 @@ pub struct SearchResultsView {
results_episodes: Arc<RwLock<Vec<Episode>>>, results_episodes: Arc<RwLock<Vec<Episode>>>,
pagination_episodes: Pagination<Episode>, pagination_episodes: Pagination<Episode>,
tabs: TabView, tabs: TabView,
spotify: Arc<Spotify>, spotify: Spotify,
events: EventManager, events: EventManager,
} }
type SearchHandler<I> = type SearchHandler<I> =
Box<dyn Fn(&Arc<Spotify>, &Arc<RwLock<Vec<I>>>, &str, usize, bool) -> u32 + Send + Sync>; Box<dyn Fn(&Spotify, &Arc<RwLock<Vec<I>>>, &str, usize, bool) -> u32 + Send + Sync>;
impl SearchResultsView { impl SearchResultsView {
pub fn new( pub fn new(
@@ -103,7 +103,7 @@ impl SearchResultsView {
} }
fn get_track( fn get_track(
spotify: &Arc<Spotify>, spotify: &Spotify,
tracks: &Arc<RwLock<Vec<Track>>>, tracks: &Arc<RwLock<Vec<Track>>>,
query: &str, query: &str,
_offset: usize, _offset: usize,
@@ -119,7 +119,7 @@ impl SearchResultsView {
} }
fn search_track( fn search_track(
spotify: &Arc<Spotify>, spotify: &Spotify,
tracks: &Arc<RwLock<Vec<Track>>>, tracks: &Arc<RwLock<Vec<Track>>>,
query: &str, query: &str,
offset: usize, offset: usize,
@@ -142,7 +142,7 @@ impl SearchResultsView {
} }
fn get_album( fn get_album(
spotify: &Arc<Spotify>, spotify: &Spotify,
albums: &Arc<RwLock<Vec<Album>>>, albums: &Arc<RwLock<Vec<Album>>>,
query: &str, query: &str,
_offset: usize, _offset: usize,
@@ -158,7 +158,7 @@ impl SearchResultsView {
} }
fn search_album( fn search_album(
spotify: &Arc<Spotify>, spotify: &Spotify,
albums: &Arc<RwLock<Vec<Album>>>, albums: &Arc<RwLock<Vec<Album>>>,
query: &str, query: &str,
offset: usize, offset: usize,
@@ -181,7 +181,7 @@ impl SearchResultsView {
} }
fn get_artist( fn get_artist(
spotify: &Arc<Spotify>, spotify: &Spotify,
artists: &Arc<RwLock<Vec<Artist>>>, artists: &Arc<RwLock<Vec<Artist>>>,
query: &str, query: &str,
_offset: usize, _offset: usize,
@@ -197,7 +197,7 @@ impl SearchResultsView {
} }
fn search_artist( fn search_artist(
spotify: &Arc<Spotify>, spotify: &Spotify,
artists: &Arc<RwLock<Vec<Artist>>>, artists: &Arc<RwLock<Vec<Artist>>>,
query: &str, query: &str,
offset: usize, offset: usize,
@@ -220,7 +220,7 @@ impl SearchResultsView {
} }
fn get_playlist( fn get_playlist(
spotify: &Arc<Spotify>, spotify: &Spotify,
playlists: &Arc<RwLock<Vec<Playlist>>>, playlists: &Arc<RwLock<Vec<Playlist>>>,
query: &str, query: &str,
_offset: usize, _offset: usize,
@@ -236,7 +236,7 @@ impl SearchResultsView {
} }
fn search_playlist( fn search_playlist(
spotify: &Arc<Spotify>, spotify: &Spotify,
playlists: &Arc<RwLock<Vec<Playlist>>>, playlists: &Arc<RwLock<Vec<Playlist>>>,
query: &str, query: &str,
offset: usize, offset: usize,
@@ -259,7 +259,7 @@ impl SearchResultsView {
} }
fn get_show( fn get_show(
spotify: &Arc<Spotify>, spotify: &Spotify,
shows: &Arc<RwLock<Vec<Show>>>, shows: &Arc<RwLock<Vec<Show>>>,
query: &str, query: &str,
_offset: usize, _offset: usize,
@@ -275,7 +275,7 @@ impl SearchResultsView {
} }
fn search_show( fn search_show(
spotify: &Arc<Spotify>, spotify: &Spotify,
shows: &Arc<RwLock<Vec<Show>>>, shows: &Arc<RwLock<Vec<Show>>>,
query: &str, query: &str,
offset: usize, offset: usize,
@@ -298,7 +298,7 @@ impl SearchResultsView {
} }
fn get_episode( fn get_episode(
spotify: &Arc<Spotify>, spotify: &Spotify,
episodes: &Arc<RwLock<Vec<Episode>>>, episodes: &Arc<RwLock<Vec<Episode>>>,
query: &str, query: &str,
_offset: usize, _offset: usize,
@@ -314,7 +314,7 @@ impl SearchResultsView {
} }
fn search_episode( fn search_episode(
spotify: &Arc<Spotify>, spotify: &Spotify,
episodes: &Arc<RwLock<Vec<Episode>>>, episodes: &Arc<RwLock<Vec<Episode>>>,
query: &str, query: &str,
offset: usize, offset: usize,

View File

@@ -14,7 +14,7 @@ use crate::spotify::{PlayerEvent, Spotify};
pub struct StatusBar { pub struct StatusBar {
queue: Arc<Queue>, queue: Arc<Queue>,
spotify: Arc<Spotify>, spotify: Spotify,
library: Arc<Library>, library: Arc<Library>,
last_size: Vec2, last_size: Vec2,
use_nerdfont: bool, use_nerdfont: bool,