died once

This commit is contained in:
Erica Z 2024-11-03 20:00:46 +01:00
parent 301c934567
commit 616aefc1c4
4 changed files with 63 additions and 109 deletions

View file

@ -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;
}
}

View file

@ -1,106 +1,81 @@
pub mod ffi {
mod imp {
use adw::prelude::*;
use gtk::glib;
use std::ffi::c_char;
use gtk::subclass::prelude::*;
use std::cell::{Cell, RefCell};
#[repr(C)]
pub struct AudreyPlaybinSong {
_data: [u8; 0],
static NEXT_COUNTER: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(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)]
pub struct AudreyPlaybinSongClass {
_data: [u8; 0],
#[glib::object_subclass]
impl ObjectSubclass for Song {
const NAME: &'static str = "AudreyPlaybinSong";
type Type = super::Song;
}
extern "C" {
pub fn audrey_playbin_song_get_type() -> glib::ffi::GType;
pub fn audrey_playbin_song_get_counter(self_: *mut AudreyPlaybinSong) -> i64;
pub fn audrey_playbin_song_get_id(self_: *mut AudreyPlaybinSong) -> *const c_char;
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;
#[glib::derived_properties]
impl ObjectImpl for Song {
fn constructed(&self) {
self.parent_constructed();
pub fn audrey_playbin_song_get_cover_art_url(
self_: *mut AudreyPlaybinSong,
) -> *const c_char;
pub fn audrey_playbin_song_get_stream_url(self_: *mut AudreyPlaybinSong) -> *const c_char;
self.obj()
.set_counter(NEXT_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed));
}
}
}
use glib::translate::{from_glib_none, ToGlibPtr};
use glib::GString;
use crate::subsonic;
use glib::Object;
use gtk::glib;
glib::wrapper! {
pub struct Song(Object<ffi::AudreyPlaybinSong, ffi::AudreyPlaybinSongClass>);
match fn {
type_ => || ffi::audrey_playbin_song_get_type(),
}
pub struct Song(ObjectSubclass<imp::Song>);
}
impl Song {
pub fn counter(&self) -> i64 {
unsafe { ffi::audrey_playbin_song_get_counter(self.to_glib_none().0) }
}
pub fn id(&self) -> GString {
unsafe { from_glib_none(ffi::audrey_playbin_song_get_id(self.to_glib_none().0)) }
}
pub fn title(&self) -> GString {
unsafe { from_glib_none(ffi::audrey_playbin_song_get_title(self.to_glib_none().0)) }
}
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())
pub fn from_child(api: &subsonic::Client, song: &subsonic::schema::Child) -> Self {
Object::builder()
.property("id", &song.id)
.property("title", &song.title)
.property("artist", &song.artist)
.property("album", &song.album)
.property("genre", &song.genre)
.property("duration", song.duration as i64)
//.property("track", song.track)
.property("cover-art-url", api.cover_art_url(&song.id).as_str())
.property("stream-url", api.stream_url(&song.id).as_str())
.build()
}
}
impl crate::playbin::PlaybinEntry for Song {
fn url(&self) -> url::Url {
self.stream_url()
url::Url::parse(&self.stream_url()).unwrap()
}
}

View file

@ -47,7 +47,7 @@ pub struct Child {
pub starred: Option<chrono::DateTime<chrono::offset::Utc>>, // TODO: check which is best
// applicable
pub duration: u64,
pub play_count: Option<u32>,
//pub play_count: Option<u32>,
pub genre: Option<String>,
pub cover_art: String,
}

View file

@ -54,23 +54,23 @@ mod imp {
#[gtk::template_callbacks]
impl Playbar {
#[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())
}
#[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())
}
#[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())
}
#[template_callback]
fn format_timestamp(&self, s: f64) -> GString {
gformat!("{:02}:{:02}", (s as i64) / 64, (s as i64) % 60)
fn format_timestamp(&self, s: f64) -> String {
format!("{:02}:{:02}", (s as i64) / 64, (s as i64) % 60)
}
#[template_callback]