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

232 show album name in playlists and queue #333

Merged
Merged
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
4 changes: 3 additions & 1 deletion src/app/components/artist_details/artist_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl ArtistDetails {

if let Some(store) = model.get_list_store() {
widget.bind_artist_releases(
worker,
worker.clone(),
&*store,
clone!(@weak model => move |id| {
model.open_album(id);
Expand All @@ -143,6 +143,8 @@ impl ArtistDetails {
let playlist = Box::new(Playlist::new(
widget.top_tracks_widget().clone(),
Rc::clone(&model),
worker,
true,
));

Self {
Expand Down
2 changes: 2 additions & 0 deletions src/app/components/details/details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ impl Details {
let playlist = Box::new(Playlist::new(
widget.album_tracks_widget().clone(),
model.clone(),
worker.clone(),
false,
));

let modal = ReleaseDetailsWindow::new();
Expand Down
10 changes: 8 additions & 2 deletions src/app/components/navigation/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,21 @@ impl ScreenFactory {
Rc::clone(&self.app_model),
self.dispatcher.box_clone(),
));
SelectionTools::new(NowPlaying::new(Rc::clone(&model)), model)
SelectionTools::new(
NowPlaying::new(Rc::clone(&model), self.worker.clone()),
model,
)
}

pub fn make_saved_tracks(&self) -> impl ListenerComponent {
let model = Rc::new(SavedTracksModel::new(
Rc::clone(&self.app_model),
self.dispatcher.box_clone(),
));
SelectionTools::new(SavedTracks::new(Rc::clone(&model)), model)
SelectionTools::new(
SavedTracks::new(Rc::clone(&model), self.worker.clone()),
model,
)
}

pub fn make_album_details(&self, id: String) -> impl ListenerComponent {
Expand Down
11 changes: 8 additions & 3 deletions src/app/components/now_playing/now_playing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use gtk::CompositeTemplate;
use std::rc::Rc;

use crate::app::components::{display_add_css_provider, Component, EventListener, Playlist};
use crate::app::{state::PlaybackEvent, AppEvent};
use crate::app::{state::PlaybackEvent, AppEvent, Worker};

use super::NowPlayingModel;

Expand Down Expand Up @@ -79,14 +79,19 @@ pub struct NowPlaying {
}

impl NowPlaying {
pub fn new(model: Rc<NowPlayingModel>) -> Self {
pub fn new(model: Rc<NowPlayingModel>, worker: Worker) -> Self {
let widget = NowPlayingWidget::new();

widget.connect_bottom_edge(clone!(@weak model => move || {
model.load_more();
}));

let playlist = Playlist::new(widget.song_list_widget().clone(), model.clone());
let playlist = Playlist::new(
widget.song_list_widget().clone(),
model.clone(),
worker,
true,
);

Self {
widget,
Expand Down
11 changes: 8 additions & 3 deletions src/app/components/playlist/playlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::app::components::{Component, EventListener, SongWidget};
use crate::app::models::SongModel;
use crate::app::{
state::{PlaybackEvent, SelectionEvent, SelectionState},
AppEvent, ListDiff, ListStore,
AppEvent, ListDiff, ListStore, Worker,
};

#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -64,7 +64,12 @@ impl<Model> Playlist<Model>
where
Model: PlaylistModel + 'static,
{
pub fn new(listview: gtk::ListView, model: Rc<Model>) -> Self {
pub fn new(
listview: gtk::ListView,
model: Rc<Model>,
worker: Worker,
show_song_covers: bool,
) -> Self {
let list_model = ListStore::new();
let selection_model = gtk::NoSelection::new(Some(list_model.unsafe_store()));
let factory = gtk::SignalListItemFactory::new();
Expand All @@ -84,7 +89,7 @@ where
song_model.set_state(Self::get_item_state(&*model, &song_model));

let widget = item.child().unwrap().downcast::<SongWidget>().unwrap();
widget.bind(&song_model);
widget.bind(&song_model, worker.clone(), show_song_covers);

let id = &song_model.get_id();
widget.set_actions(model.actions_for(id).as_ref());
Expand Down
36 changes: 32 additions & 4 deletions src/app/components/playlist/song.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::app::components::display_add_css_provider;
use crate::app::loader::ImageLoader;
use crate::app::models::SongModel;

use crate::app::Worker;
use gio::MenuModel;
use gtk::prelude::*;
use gtk::subclass::prelude::*;
Expand Down Expand Up @@ -32,6 +34,9 @@ mod imp {

#[template_child]
pub menu_btn: TemplateChild<gtk::MenuButton>,

#[template_child]
pub song_cover: TemplateChild<gtk::Image>,
}

#[glib::object_subclass]
Expand Down Expand Up @@ -70,9 +75,9 @@ impl SongWidget {
glib::Object::new(&[]).expect("Failed to create an instance of SongWidget")
}

pub fn for_model(model: SongModel) -> Self {
pub fn for_model(model: SongModel, worker: Worker) -> Self {
let _self = Self::new();
_self.bind(&model);
_self.bind(&model, worker, true);
_self
}

Expand Down Expand Up @@ -114,13 +119,36 @@ impl SongWidget {
}
}

pub fn bind(&self, model: &SongModel) {
fn set_image(&self, pixbuf: Option<&gdk_pixbuf::Pixbuf>) {
imp::SongWidget::from_instance(self)
.song_cover
.set_from_pixbuf(pixbuf);
}

pub fn bind_art(&self, model: &SongModel, worker: Worker) {
if let Some(url) = model.cover_url() {
let _self = self.downgrade();
worker.send_local_task(async move {
if let Some(_self) = _self.upgrade() {
let loader = ImageLoader::new();
let result = loader.load_remote(&url, "jpg", 100, 100).await;
_self.set_image(result.as_ref());
}
});
}
}

pub fn bind(&self, model: &SongModel, worker: Worker, show_cover: bool) {
let widget = imp::SongWidget::from_instance(self);

model.bind_index(&*widget.song_index, "label");
model.bind_title(&*widget.song_title, "label");
model.bind_artist(&*widget.song_artist, "label");
model.bind_duration(&*widget.song_length, "label");
if show_cover {
self.bind_art(model, worker);
} else {
model.bind_index(&*widget.song_index, "label");
}

self.set_playing(model.get_playing());
model.connect_playing_local(clone!(@weak self as _self => move |song| {
Expand Down
8 changes: 8 additions & 0 deletions src/app/components/playlist/song.ui
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@
</style>
</object>
</child>
<child type="overlay">
<object class="GtkImage" id="song_cover">
<property name="pixel-size">30</property>
<style>
<class name="song__cover"/>
</style>
</object>
</child>
<child type="overlay">
<object class="GtkImage" id="song_icon">
<property name="icon-name">media-playback-start-symbolic</property>
Expand Down
2 changes: 2 additions & 0 deletions src/app/components/playlist_details/playlist_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ impl PlaylistDetails {
let playlist = Box::new(Playlist::new(
widget.playlist_tracks_widget().clone(),
model.clone(),
worker.clone(),
true,
));

widget.connect_header();
Expand Down
11 changes: 8 additions & 3 deletions src/app/components/saved_tracks/saved_tracks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::rc::Rc;

use crate::app::components::{display_add_css_provider, Component, EventListener, Playlist};
use crate::app::state::LoginEvent;
use crate::app::AppEvent;
use crate::app::{AppEvent, Worker};

use super::SavedTracksModel;

Expand Down Expand Up @@ -80,14 +80,19 @@ pub struct SavedTracks {
}

impl SavedTracks {
pub fn new(model: Rc<SavedTracksModel>) -> Self {
pub fn new(model: Rc<SavedTracksModel>, worker: Worker) -> Self {
let widget = SavedTracksWidget::new();

widget.connect_bottom_edge(clone!(@weak model => move || {
model.load_more();
}));

let playlist = Playlist::new(widget.song_list_widget().clone(), model.clone());
let playlist = Playlist::new(
widget.song_list_widget().clone(),
model.clone(),
worker,
true,
);

Self {
widget,
Expand Down
30 changes: 28 additions & 2 deletions src/app/models/gtypes/song_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,33 @@ glib::wrapper! {
// Constructor for new instances. This simply calls glib::Object::new() with
// initial values for our two properties and then returns the new instance
impl SongModel {
pub fn new(id: &str, index: u32, title: &str, artist: &str, duration: &str) -> SongModel {
pub fn new(
id: &str,
index: u32,
title: &str,
artist: &str,
duration: &str,
art: &Option<String>,
) -> SongModel {
glib::Object::new::<SongModel>(&[
("index", &index),
("title", &title),
("artist", &artist),
("id", &id),
("duration", &duration),
("art", &art),
])
.expect("Failed to create")
}

pub fn cover_url(&self) -> Option<String> {
self.property("art")
.unwrap()
.get::<&str>()
.ok()
.map(|s| s.to_string())
}

pub fn set_playing(&self, is_playing: bool) {
self.set_property("playing", is_playing)
.expect("set 'playing' failed");
Expand Down Expand Up @@ -128,6 +144,7 @@ mod imp {
title: RefCell<Option<String>>,
artist: RefCell<Option<String>>,
duration: RefCell<Option<String>>,
art: RefCell<Option<String>>,
playing: RefCell<bool>,
selected: RefCell<bool>,
bindings: RefCell<BindingsInner>,
Expand Down Expand Up @@ -176,6 +193,7 @@ mod imp {
title: RefCell::new(None),
artist: RefCell::new(None),
duration: RefCell::new(None),
art: RefCell::new(None),
playing: RefCell::new(false),
selected: RefCell::new(false),
bindings: RefCell::new(Default::default()),
Expand All @@ -185,7 +203,7 @@ mod imp {

// Static array for defining the properties of the new type.
lazy_static! {
static ref PROPERTIES: [glib::ParamSpec; 7] = [
static ref PROPERTIES: [glib::ParamSpec; 8] = [
glib::ParamSpec::new_uint(
"index",
"Index",
Expand Down Expand Up @@ -219,6 +237,7 @@ mod imp {
false,
glib::ParamFlags::READWRITE,
),
glib::ParamSpec::new_string("art", "Art", "", None, glib::ParamFlags::READWRITE,),
];
}

Expand Down Expand Up @@ -268,6 +287,12 @@ mod imp {
.expect("type conformity checked by `Object::set_property`");
self.duration.replace(dur);
}
"art" => {
let art = value
.get()
.expect("type conformity checked by `Object::set_property`");
self.art.replace(art);
}
"playing" => {
let playing = value
.get()
Expand All @@ -293,6 +318,7 @@ mod imp {
"artist" => self.artist.borrow().to_value(),
"id" => self.id.borrow().to_value(),
"duration" => self.duration.borrow().to_value(),
"art" => self.art.borrow().to_value(),
"playing" => self.playing.borrow().to_value(),
"selected" => self.selected.borrow().to_value(),
_ => unimplemented!(),
Expand Down
1 change: 1 addition & 0 deletions src/app/models/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl From<&SongDescription> for SongModel {
&song.title,
&song.artists_name(),
&format_duration(song.duration.into()),
&song.art,
)
}
}
Expand Down