Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save tracks to library from dot menu #559

Open
wants to merge 7 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/app/components/artist_details/artist_details_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ impl PlaylistModel for ArtistDetailsModel {
group.add_action(&song.make_album_action(self.dispatcher.box_clone(), None));
group.add_action(&song.make_link_action(None));
group.add_action(&song.make_queue_action(self.dispatcher.box_clone(), None));
group.add_action(&song.make_like_action(
self.dispatcher.box_clone(),
self.app_model.clone(),
None,
));
group.add_action(&song.make_unlike_action(
self.dispatcher.box_clone(),
self.app_model.clone(),
None,
));

Some(group.upcast())
}
Expand All @@ -132,6 +142,8 @@ impl PlaylistModel for ArtistDetailsModel {

menu.append(Some(&*labels::COPY_LINK), Some("song.copy_link"));
menu.append(Some(&*labels::ADD_TO_QUEUE), Some("song.queue"));
menu.append(Some(&*labels::ADD_TO_LIBRARY), Some("song.like"));
menu.append(Some(&*labels::REMOVE_FROM_LIBRARY), Some("song.unlike"));
Some(menu.upcast())
}

Expand Down
12 changes: 12 additions & 0 deletions src/app/components/details/details_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,16 @@ impl PlaylistModel for DetailsModel {
}
group.add_action(&song.make_link_action(None));
group.add_action(&song.make_queue_action(self.dispatcher.box_clone(), None));
group.add_action(&song.make_like_action(
self.dispatcher.box_clone(),
self.app_model.clone(),
None,
));
group.add_action(&song.make_unlike_action(
self.dispatcher.box_clone(),
self.app_model.clone(),
None,
));

Some(group.upcast())
}
Expand All @@ -213,6 +223,8 @@ impl PlaylistModel for DetailsModel {

menu.append(Some(&*labels::COPY_LINK), Some("song.copy_link"));
menu.append(Some(&*labels::ADD_TO_QUEUE), Some("song.queue"));
menu.append(Some(&*labels::ADD_TO_LIBRARY), Some("song.like"));
menu.append(Some(&*labels::REMOVE_FROM_LIBRARY), Some("song.unlike"));
Some(menu.upcast())
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/app/components/labels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ lazy_static! {

// translators: This is part of a contextual menu attached to a single track; this entry removes a track from the play queue.
pub static ref REMOVE_FROM_QUEUE: String = gettext("Remove from queue");

// translators: This is part of a contextual menu attached to a single track; this entry adds a track to the library.
pub static ref ADD_TO_LIBRARY: String = gettext("Add to library");

// translators: This is part of a contextual menu attached to a single track; this entry removes a track from the library.
pub static ref REMOVE_FROM_LIBRARY: String = gettext("Remove from library");
}

pub fn add_to_playlist_label(playlist: &str) -> String {
Expand Down
12 changes: 12 additions & 0 deletions src/app/components/now_playing/now_playing_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ impl PlaylistModel for NowPlayingModel {
group.add_action(&song.make_album_action(self.dispatcher.box_clone(), None));
group.add_action(&song.make_link_action(None));
group.add_action(&song.make_dequeue_action(self.dispatcher.box_clone(), None));
group.add_action(&song.make_like_action(
self.dispatcher.box_clone(),
self.app_model.clone(),
None,
));
group.add_action(&song.make_unlike_action(
self.dispatcher.box_clone(),
self.app_model.clone(),
None,
));

Some(group.upcast())
}
Expand All @@ -99,6 +109,8 @@ impl PlaylistModel for NowPlayingModel {

menu.append(Some(&*labels::COPY_LINK), Some("song.copy_link"));
menu.append(Some(&*labels::REMOVE_FROM_QUEUE), Some("song.dequeue"));
menu.append(Some(&*labels::ADD_TO_LIBRARY), Some("song.like"));
menu.append(Some(&*labels::REMOVE_FROM_LIBRARY), Some("song.unlike"));

Some(menu.upcast())
}
Expand Down
56 changes: 54 additions & 2 deletions src/app/components/playlist/song_actions.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use gdk::prelude::*;
use gettextrs::gettext;
use gio::SimpleAction;
use std::rc::Rc;

use crate::app::models::SongDescription;
use crate::app::state::{AppAction, PlaybackAction};
use crate::app::ActionDispatcher;
use crate::app::state::{AppAction, PlaybackAction, SelectionAction};
use crate::app::{ActionDispatcher, AppModel};

impl SongDescription {
pub fn make_queue_action(
Expand Down Expand Up @@ -79,4 +81,54 @@ impl SongDescription {
})
.collect()
}

pub fn make_like_action(
&self,
dispatcher: Box<dyn ActionDispatcher>,
app_model: Rc<AppModel>,
name: Option<&str>,
) -> SimpleAction {
let track_id = self.id.clone();
let song = self.clone();
let like_track = SimpleAction::new(name.unwrap_or("like"), None);
like_track.connect_activate(move |_, _| {
let track_id = track_id.clone();
let song = song.clone();
let api = app_model.get_spotify();
dispatcher.dispatch(SelectionAction::Select(vec![song]).into());
dispatcher.call_spotify_and_dispatch_many(move || async move {
api.save_tracks(vec![track_id]).await?;
Ok(vec![
AppAction::SaveSelection,
AppAction::ShowNotification(gettext("Track saved!")),
])
});
});
like_track
}

pub fn make_unlike_action(
&self,
dispatcher: Box<dyn ActionDispatcher>,
app_model: Rc<AppModel>,
name: Option<&str>,
) -> SimpleAction {
let track_id = self.id.clone();
let song = self.clone();
let unlike_track = SimpleAction::new(name.unwrap_or("unlike"), None);
unlike_track.connect_activate(move |_, _| {
let track_id = track_id.clone();
let song = song.clone();
let api = app_model.get_spotify();
dispatcher.dispatch(SelectionAction::Select(vec![song]).into());
dispatcher.call_spotify_and_dispatch_many(move || async move {
api.remove_saved_tracks(vec![track_id]).await?;
Ok(vec![
AppAction::UnsaveSelection,
AppAction::ShowNotification(gettext("Track unsaved!")),
])
});
});
unlike_track
}
}
12 changes: 12 additions & 0 deletions src/app/components/playlist_details/playlist_details_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,16 @@ impl PlaylistModel for PlaylistDetailsModel {
group.add_action(&song.make_album_action(self.dispatcher.box_clone(), None));
group.add_action(&song.make_link_action(None));
group.add_action(&song.make_queue_action(self.dispatcher.box_clone(), None));
group.add_action(&song.make_like_action(
self.dispatcher.box_clone(),
self.app_model.clone(),
None,
));
group.add_action(&song.make_unlike_action(
self.dispatcher.box_clone(),
self.app_model.clone(),
None,
));

Some(group.upcast())
}
Expand All @@ -151,6 +161,8 @@ impl PlaylistModel for PlaylistDetailsModel {

menu.append(Some(&*labels::COPY_LINK), Some("song.copy_link"));
menu.append(Some(&*labels::ADD_TO_QUEUE), Some("song.queue"));
menu.append(Some(&*labels::ADD_TO_LIBRARY), Some("song.like"));
menu.append(Some(&*labels::REMOVE_FROM_LIBRARY), Some("song.unlike"));

Some(menu.upcast())
}
Expand Down
6 changes: 6 additions & 0 deletions src/app/components/saved_tracks/saved_tracks_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ impl PlaylistModel for SavedTracksModel {
}
group.add_action(&song.make_album_action(self.dispatcher.box_clone(), None));
group.add_action(&song.make_link_action(None));
group.add_action(&song.make_unlike_action(
self.dispatcher.box_clone(),
self.app_model.clone(),
None,
));

Some(group.upcast())
}
Expand All @@ -115,6 +120,7 @@ impl PlaylistModel for SavedTracksModel {
}

menu.append(Some(&*labels::COPY_LINK), Some("song.copy_link"));
menu.append(Some(&*labels::REMOVE_FROM_LIBRARY), Some("song.unlike"));

Some(menu.upcast())
}
Expand Down