died once
This commit is contained in:
parent
301c934567
commit
616aefc1c4
4 changed files with 63 additions and 109 deletions
|
@ -1,21 +0,0 @@
|
||||||
public class Audrey.PlaybinSong : Object {
|
|
||||||
private static int64 next_counter = 0;
|
|
||||||
public int64 counter { get; private set; }
|
|
||||||
|
|
||||||
public string id { get; set; }
|
|
||||||
public string title { get; set; }
|
|
||||||
public string artist { get; set; }
|
|
||||||
public string album { get; set; }
|
|
||||||
public string? genre { get; set; }
|
|
||||||
public int64 duration { get; set; }
|
|
||||||
public int64 track { get; set; }
|
|
||||||
public int64 play_count { get; set; }
|
|
||||||
|
|
||||||
public string cover_art_url { get; set; }
|
|
||||||
public string stream_url { get; set; }
|
|
||||||
|
|
||||||
construct {
|
|
||||||
this.counter = next_counter;
|
|
||||||
next_counter += 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,106 +1,81 @@
|
||||||
pub mod ffi {
|
mod imp {
|
||||||
|
use adw::prelude::*;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
use std::ffi::c_char;
|
use gtk::subclass::prelude::*;
|
||||||
|
use std::cell::{Cell, RefCell};
|
||||||
|
|
||||||
#[repr(C)]
|
static NEXT_COUNTER: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
|
||||||
pub struct AudreyPlaybinSong {
|
|
||||||
_data: [u8; 0],
|
#[derive(glib::Properties, Default)]
|
||||||
|
#[properties(wrapper_type = super::Song)]
|
||||||
|
pub struct Song {
|
||||||
|
#[property(get, set)]
|
||||||
|
counter: Cell<u64>,
|
||||||
|
|
||||||
|
#[property(get, set)]
|
||||||
|
id: RefCell<String>,
|
||||||
|
#[property(get, set)]
|
||||||
|
title: RefCell<String>,
|
||||||
|
#[property(get, set)]
|
||||||
|
artist: RefCell<String>,
|
||||||
|
#[property(get, set)]
|
||||||
|
album: RefCell<String>,
|
||||||
|
#[property(get, set)]
|
||||||
|
genre: RefCell<Option<String>>,
|
||||||
|
#[property(get, set)]
|
||||||
|
duration: Cell<i64>,
|
||||||
|
#[property(get, set)]
|
||||||
|
track: Cell<i64>,
|
||||||
|
|
||||||
|
#[property(get, set)]
|
||||||
|
cover_art_url: RefCell<String>,
|
||||||
|
#[property(get, set)]
|
||||||
|
stream_url: RefCell<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[glib::object_subclass]
|
||||||
pub struct AudreyPlaybinSongClass {
|
impl ObjectSubclass for Song {
|
||||||
_data: [u8; 0],
|
const NAME: &'static str = "AudreyPlaybinSong";
|
||||||
|
type Type = super::Song;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
#[glib::derived_properties]
|
||||||
pub fn audrey_playbin_song_get_type() -> glib::ffi::GType;
|
impl ObjectImpl for Song {
|
||||||
pub fn audrey_playbin_song_get_counter(self_: *mut AudreyPlaybinSong) -> i64;
|
fn constructed(&self) {
|
||||||
pub fn audrey_playbin_song_get_id(self_: *mut AudreyPlaybinSong) -> *const c_char;
|
self.parent_constructed();
|
||||||
pub fn audrey_playbin_song_get_title(self_: *mut AudreyPlaybinSong) -> *const c_char;
|
|
||||||
pub fn audrey_playbin_song_get_artist(self_: *mut AudreyPlaybinSong) -> *const c_char;
|
|
||||||
pub fn audrey_playbin_song_get_album(self_: *mut AudreyPlaybinSong) -> *const c_char;
|
|
||||||
pub fn audrey_playbin_song_get_duration(self_: *mut AudreyPlaybinSong) -> i64;
|
|
||||||
|
|
||||||
pub fn audrey_playbin_song_get_cover_art_url(
|
self.obj()
|
||||||
self_: *mut AudreyPlaybinSong,
|
.set_counter(NEXT_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed));
|
||||||
) -> *const c_char;
|
}
|
||||||
pub fn audrey_playbin_song_get_stream_url(self_: *mut AudreyPlaybinSong) -> *const c_char;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use glib::translate::{from_glib_none, ToGlibPtr};
|
use crate::subsonic;
|
||||||
use glib::GString;
|
use glib::Object;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct Song(Object<ffi::AudreyPlaybinSong, ffi::AudreyPlaybinSongClass>);
|
pub struct Song(ObjectSubclass<imp::Song>);
|
||||||
|
|
||||||
match fn {
|
|
||||||
type_ => || ffi::audrey_playbin_song_get_type(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Song {
|
impl Song {
|
||||||
pub fn counter(&self) -> i64 {
|
pub fn from_child(api: &subsonic::Client, song: &subsonic::schema::Child) -> Self {
|
||||||
unsafe { ffi::audrey_playbin_song_get_counter(self.to_glib_none().0) }
|
Object::builder()
|
||||||
}
|
.property("id", &song.id)
|
||||||
|
.property("title", &song.title)
|
||||||
pub fn id(&self) -> GString {
|
.property("artist", &song.artist)
|
||||||
unsafe { from_glib_none(ffi::audrey_playbin_song_get_id(self.to_glib_none().0)) }
|
.property("album", &song.album)
|
||||||
}
|
.property("genre", &song.genre)
|
||||||
|
.property("duration", song.duration as i64)
|
||||||
pub fn title(&self) -> GString {
|
//.property("track", song.track)
|
||||||
unsafe { from_glib_none(ffi::audrey_playbin_song_get_title(self.to_glib_none().0)) }
|
.property("cover-art-url", api.cover_art_url(&song.id).as_str())
|
||||||
}
|
.property("stream-url", api.stream_url(&song.id).as_str())
|
||||||
|
|
||||||
pub fn artist(&self) -> GString {
|
|
||||||
unsafe { from_glib_none(ffi::audrey_playbin_song_get_artist(self.to_glib_none().0)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn album(&self) -> GString {
|
|
||||||
unsafe { from_glib_none(ffi::audrey_playbin_song_get_album(self.to_glib_none().0)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn duration(&self) -> i64 {
|
|
||||||
unsafe { ffi::audrey_playbin_song_get_duration(self.to_glib_none().0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cover_art_url(&self) -> url::Url {
|
|
||||||
let url: String = unsafe {
|
|
||||||
from_glib_none(ffi::audrey_playbin_song_get_cover_art_url(
|
|
||||||
self.to_glib_none().0,
|
|
||||||
))
|
|
||||||
};
|
|
||||||
url::Url::parse(&url).expect("invalid url from vala side")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stream_url(&self) -> url::Url {
|
|
||||||
let url: String = unsafe {
|
|
||||||
from_glib_none(ffi::audrey_playbin_song_get_stream_url(
|
|
||||||
self.to_glib_none().0,
|
|
||||||
))
|
|
||||||
};
|
|
||||||
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()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::playbin::PlaybinEntry for Song {
|
impl crate::playbin::PlaybinEntry for Song {
|
||||||
fn url(&self) -> url::Url {
|
fn url(&self) -> url::Url {
|
||||||
self.stream_url()
|
url::Url::parse(&self.stream_url()).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub struct Child {
|
||||||
pub starred: Option<chrono::DateTime<chrono::offset::Utc>>, // TODO: check which is best
|
pub starred: Option<chrono::DateTime<chrono::offset::Utc>>, // TODO: check which is best
|
||||||
// applicable
|
// applicable
|
||||||
pub duration: u64,
|
pub duration: u64,
|
||||||
pub play_count: Option<u32>,
|
//pub play_count: Option<u32>,
|
||||||
pub genre: Option<String>,
|
pub genre: Option<String>,
|
||||||
pub cover_art: String,
|
pub cover_art: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,23 +54,23 @@ mod imp {
|
||||||
#[gtk::template_callbacks]
|
#[gtk::template_callbacks]
|
||||||
impl Playbar {
|
impl Playbar {
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn song_title(&self, song: Option<&PlaybinSong>) -> Option<GString> {
|
fn song_title(&self, song: Option<&PlaybinSong>) -> Option<String> {
|
||||||
song.map(|song| song.title())
|
song.map(|song| song.title())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn song_artist(&self, song: Option<&PlaybinSong>) -> Option<GString> {
|
fn song_artist(&self, song: Option<&PlaybinSong>) -> Option<String> {
|
||||||
song.map(|song| song.artist())
|
song.map(|song| song.artist())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn song_album(&self, song: Option<&PlaybinSong>) -> Option<GString> {
|
fn song_album(&self, song: Option<&PlaybinSong>) -> Option<String> {
|
||||||
song.map(|song| song.album())
|
song.map(|song| song.album())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn format_timestamp(&self, s: f64) -> GString {
|
fn format_timestamp(&self, s: f64) -> String {
|
||||||
gformat!("{:02}:{:02}", (s as i64) / 64, (s as i64) % 60)
|
format!("{:02}:{:02}", (s as i64) / 64, (s as i64) % 60)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
|
|
Loading…
Reference in a new issue