aaalmost theeeereee

This commit is contained in:
Erica Z 2024-11-03 16:27:47 +01:00
parent acd1d7d803
commit fc9eae2eda
4 changed files with 54 additions and 49 deletions

View file

@ -13,58 +13,35 @@ public class Audrey.PlaybinSong : Object {
private static int64 next_counter = 0; private static int64 next_counter = 0;
public int64 counter { get; private set; } public int64 counter { get; private set; }
private Subsonic.Song inner; public string id { get; set; }
public string id { get { return inner.id; } } public string title { get; set; }
public string title { get { return inner.title; } } public string artist { get; set; }
public string artist { get { return inner.artist; } } public string album { get; set; }
public string album { get { return inner.album; } } public string? genre { get; set; }
public string? genre { get { return inner.genre; } } public int64 duration { get; set; }
public int64 duration { get { return inner.duration; } } public int64 track { get; set; }
public int64 track { get { return inner.track; } } public int64 play_count { get; set; }
public int64 play_count { get { return inner.play_count; } }
public string cover_art_url { owned get { return this.api.cover_art_uri (this.id); } } public string cover_art_url { get; set; }
public string stream_url { owned get { return this.api.stream_uri (this.id); } } public string stream_url { get; set; }
public Gdk.Paintable? thumbnail { get; private set; }
private Cancellable cancel_loading_thumbnail;
public PlaybinSong (Subsonic.Client api, Subsonic.Song song) {
this.api = api;
this.inner = song;
construct {
this.counter = next_counter; this.counter = next_counter;
next_counter += 1; next_counter += 1;
} }
private Subsonic.Client api; public PlaybinSong (Subsonic.Client api, Subsonic.Song song) {
this.id = song.id;
this.title = song.title;
this.artist = song.artist;
this.album = song.album;
this.genre = song.genre;
this.duration = song.duration;
this.track = song.track;
this.play_count = song.play_count;
public void need_cover_art () { this.cover_art_url = api.cover_art_uri(this.id);
/* TODO this.stream_url = api.stream_uri(this.id);
if (this.cancel_loading_thumbnail != null) return;
if (this.thumbnail != null) return;
this.cancel_loading_thumbnail = new Cancellable ();
// TODO: dpi scaling maybe?? probably
api.cover_art.begin (this.id, 50, Priority.LOW, this.cancel_loading_thumbnail, (obj, res) => {
try {
var pixbuf = api.cover_art.end (res);
this.thumbnail = Gdk.Texture.for_pixbuf (pixbuf);
} catch (Error e) {
if (!(e is IOError.CANCELLED)) {
warning ("could not fetch cover art for song %s: %s", this.id, e.message);
}
}
this.cancel_loading_thumbnail = null;
});
*/
}
~PlaybinSong () {
if (this.cancel_loading_thumbnail != null) {
this.cancel_loading_thumbnail.cancel ();
}
} }
} }

View file

@ -82,4 +82,19 @@ impl Song {
}; };
url::Url::parse(&url).expect("invalid url from vala side") url::Url::parse(&url).expect("invalid url from vala side")
} }
pub fn from_child(
api: &crate::subsonic::Client,
child: &crate::subsonic::schema::Child,
) -> Self {
glib::Object::builder()
.property("id", &child.id)
.property("title", &child.title)
.property("artist", &child.artist)
.property("album", &child.album)
.property("duration", child.duration as i64)
.property("cover-art-url", api.cover_art_url(&child.id).as_str())
.property("stream-url", api.stream_url(&child.id).as_str())
.build()
}
} }

View file

@ -176,6 +176,10 @@ impl Client {
.map(|response| response.random_songs.song) .map(|response| response.random_songs.song)
} }
pub fn cover_art_url(&self, id: &str) -> url::Url {
self.url(&["rest", "coverArt"], &[("id", id)])
}
pub fn stream_url(&self, id: &str) -> url::Url { pub fn stream_url(&self, id: &str) -> url::Url {
self.url(&["rest", "stream"], &[("id", id)]) self.url(&["rest", "stream"], &[("id", id)])
} }

View file

@ -6,6 +6,12 @@ mod imp {
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::rc::Rc; use std::rc::Rc;
impl crate::playbin2::PlaybinEntry for crate::playbin::Song {
fn url(&self) -> url::Url {
self.stream_url()
}
}
#[derive(gtk::CompositeTemplate, glib::Properties, Default)] #[derive(gtk::CompositeTemplate, glib::Properties, Default)]
#[template(resource = "/eu/callcc/audrey/window.ui")] #[template(resource = "/eu/callcc/audrey/window.ui")]
#[properties(wrapper_type = super::Window)] #[properties(wrapper_type = super::Window)]
@ -27,7 +33,7 @@ mod imp {
pub(super) setup: crate::ui::Setup, pub(super) setup: crate::ui::Setup,
pub(super) playbin2: Rc<crate::playbin2::Playbin<url::Url>>, pub(super) playbin2: Rc<crate::playbin2::Playbin<crate::playbin::Song>>,
pub(super) api2: RefCell<Option<Rc<crate::subsonic::Client>>>, pub(super) api2: RefCell<Option<Rc<crate::subsonic::Client>>>,
} }
@ -126,8 +132,8 @@ mod imp {
let api = self.api2.borrow(); let api = self.api2.borrow();
let api = api.as_ref().unwrap(); let api = api.as_ref().unwrap();
for song in api.get_random_songs(10).await.unwrap().into_iter() { for song in api.get_random_songs(10).await.unwrap().into_iter() {
println!("{song:?}"); self.playbin2
self.playbin2.push_entry(api.stream_url(&song.id)); .push_entry(crate::playbin::Song::from_child(api, &song));
} }
self.obj().set_can_click_shuffle_all(true); self.obj().set_can_click_shuffle_all(true);
} }
@ -189,7 +195,10 @@ impl Window {
let window: Self = glib::Object::builder().property("application", app).build(); let window: Self = glib::Object::builder().property("application", app).build();
// manual bidirectional sync // manual bidirectional sync
window.imp().playbar.set_volume(window.imp().playbin2.volume() as i32); window
.imp()
.playbar
.set_volume(window.imp().playbin2.volume() as i32);
window.imp().playbin2.volume_changed().connect_object( window.imp().playbin2.volume_changed().connect_object(
&*window.imp().playbar, &*window.imp().playbar,
|playbin, playbar, ()| { |playbin, playbar, ()| {