style changes

This commit is contained in:
Daniel Bulant 2024-11-20 15:52:52 +01:00
parent 16c6a2c2a5
commit 8cf183e5c8
No known key found for this signature in database
5 changed files with 111 additions and 75 deletions

26
Cargo.lock generated
View file

@ -467,9 +467,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]] [[package]]
name = "attribute-derive" name = "attribute-derive"
version = "0.10.2" version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1800e974930e9079c965b9ffbcb6667a40401063a26396c7b4f15edc92da690" checksum = "0053e96dd3bec5b4879c23a138d6ef26f2cb936c9cdc96274ac2b9ed44b5bb54"
dependencies = [ dependencies = [
"attribute-derive-macro", "attribute-derive-macro",
"derive-where", "derive-where",
@ -481,9 +481,9 @@ dependencies = [
[[package]] [[package]]
name = "attribute-derive-macro" name = "attribute-derive-macro"
version = "0.10.2" version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d908eb786ef94296bff86f90130b3b748b49401dc81fd2bb8b3dccd44cfacbd" checksum = "463b53ad0fd5b460af4b1915fe045ff4d946d025fb6c4dc3337752eaa980f71b"
dependencies = [ dependencies = [
"collection_literals", "collection_literals",
"interpolator", "interpolator",
@ -1179,7 +1179,7 @@ checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
[[package]] [[package]]
name = "cushy" name = "cushy"
version = "0.4.0" version = "0.4.0"
source = "git+https://github.com/khonsulabs/cushy.git?branch=main#620ab2dc44cd3ea9c6c3c61ca0086fee42baef37" source = "git+https://github.com/khonsulabs/cushy.git?branch=main#477ce9bc45b71f0f7e8ddd53ef3e3800eaea15d1"
dependencies = [ dependencies = [
"ahash", "ahash",
"alot", "alot",
@ -1209,7 +1209,7 @@ dependencies = [
[[package]] [[package]]
name = "cushy-macros" name = "cushy-macros"
version = "0.4.0" version = "0.4.0"
source = "git+https://github.com/khonsulabs/cushy.git?branch=main#620ab2dc44cd3ea9c6c3c61ca0086fee42baef37" source = "git+https://github.com/khonsulabs/cushy.git?branch=main#477ce9bc45b71f0f7e8ddd53ef3e3800eaea15d1"
dependencies = [ dependencies = [
"attribute-derive", "attribute-derive",
"manyhow", "manyhow",
@ -2886,7 +2886,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]] [[package]]
name = "kludgine" name = "kludgine"
version = "0.11.0" version = "0.11.0"
source = "git+https://github.com/khonsulabs/kludgine#3d7b7164230449f914fa48cc4ccdf2d28b7188f2" source = "git+https://github.com/khonsulabs/kludgine#c4be86b402a0eb911e2489292526f77b8dd0dfc0"
dependencies = [ dependencies = [
"ahash", "ahash",
"alot", "alot",
@ -2985,7 +2985,7 @@ dependencies = [
[[package]] [[package]]
name = "librespot-audio" name = "librespot-audio"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#b52a176c3076285006c6d39c6a0455e2b1033790" source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#1b9192b52a983f5aca2c145621393ac0d12ace1a"
dependencies = [ dependencies = [
"aes", "aes",
"bytes", "bytes",
@ -3005,7 +3005,7 @@ dependencies = [
[[package]] [[package]]
name = "librespot-core" name = "librespot-core"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#b52a176c3076285006c6d39c6a0455e2b1033790" source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#1b9192b52a983f5aca2c145621393ac0d12ace1a"
dependencies = [ dependencies = [
"aes", "aes",
"base64 0.22.1", "base64 0.22.1",
@ -3062,7 +3062,7 @@ dependencies = [
[[package]] [[package]]
name = "librespot-metadata" name = "librespot-metadata"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#b52a176c3076285006c6d39c6a0455e2b1033790" source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#1b9192b52a983f5aca2c145621393ac0d12ace1a"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@ -3079,7 +3079,7 @@ dependencies = [
[[package]] [[package]]
name = "librespot-oauth" name = "librespot-oauth"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#b52a176c3076285006c6d39c6a0455e2b1033790" source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#1b9192b52a983f5aca2c145621393ac0d12ace1a"
dependencies = [ dependencies = [
"log", "log",
"oauth2", "oauth2",
@ -3090,7 +3090,7 @@ dependencies = [
[[package]] [[package]]
name = "librespot-playback" name = "librespot-playback"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#b52a176c3076285006c6d39c6a0455e2b1033790" source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#1b9192b52a983f5aca2c145621393ac0d12ace1a"
dependencies = [ dependencies = [
"futures-util", "futures-util",
"librespot-audio", "librespot-audio",
@ -3110,7 +3110,7 @@ dependencies = [
[[package]] [[package]]
name = "librespot-protocol" name = "librespot-protocol"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#b52a176c3076285006c6d39c6a0455e2b1033790" source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#1b9192b52a983f5aca2c145621393ac0d12ace1a"
dependencies = [ dependencies = [
"protobuf", "protobuf",
"protobuf-codegen", "protobuf-codegen",

View file

@ -22,7 +22,7 @@
alsa-lib alsa-lib
cargo-flamegraph # cargo-flamegraph
]; ];
in { in {
config.devshells.default = { config.devshells.default = {

View file

@ -40,13 +40,15 @@ static CLIENT: LazyLock<ClientWithMiddleware> = LazyLock::new(|| {
impl ImageExt for Image { impl ImageExt for Image {
fn new_empty() -> Self { fn new_empty() -> Self {
Image::new(Dynamic::new(get_empty_texture())) // println!("new empty");
Image::new(Dynamic::new(get_empty_texture())).aspect_fit()
} }
/// Makes the image connected to a URL /// Makes the image connected to a URL
/// Calling this multiple times on a single image may cause memory leaks /// Calling this multiple times on a single image may cause memory leaks
fn load_url(&mut self, url: Dynamic<Option<String>>) -> CallbackHandle { fn load_url(&mut self, url: Dynamic<Option<String>>) -> CallbackHandle {
// let texture = Dynamic::new(get_empty_texture()); // let texture = Dynamic::new(get_empty_texture());
// println!("load_url called");
match &mut self.contents { match &mut self.contents {
Value::Constant(_) => self.contents = Value::Dynamic(Dynamic::new(get_empty_texture())), Value::Constant(_) => self.contents = Value::Dynamic(Dynamic::new(get_empty_texture())),
Value::Dynamic(dynamic) => dynamic.set(get_empty_texture()), Value::Dynamic(dynamic) => dynamic.set(get_empty_texture()),
@ -64,7 +66,6 @@ impl ImageExt for Image {
if texture_count <= 1 { if texture_count <= 1 {
return Err(CallbackDisconnected); return Err(CallbackDisconnected);
} }
println!("loading url {:?}", url);
let guard = tokio_runtime().enter(); let guard = tokio_runtime().enter();
let url = url.clone(); let url = url.clone();
let prev_request_join = prev_request_join.clone(); let prev_request_join = prev_request_join.clone();
@ -75,7 +76,6 @@ impl ImageExt for Image {
if let Some(prev_request_join) = prev_request_join.take() { if let Some(prev_request_join) = prev_request_join.take() {
prev_request_join.abort(); prev_request_join.abort();
} }
println!("loading url {:?}", url);
if let Some(url) = url { if let Some(url) = url {
let texture = texture.clone(); let texture = texture.clone();
let client = client.clone(); let client = client.clone();
@ -83,7 +83,7 @@ impl ImageExt for Image {
let response = client.get(url).send().await.unwrap(); let response = client.get(url).send().await.unwrap();
let bytes = response.bytes().await.unwrap(); let bytes = response.bytes().await.unwrap();
let image = image::load_from_memory(&bytes).unwrap(); let image = image::load_from_memory(&bytes).unwrap();
// let image = image.resize(128, 128, FilterType::Lanczos3); let image = image.resize(128, 128, FilterType::Lanczos3);
let image_texture = LazyTexture::from_image( let image_texture = LazyTexture::from_image(
image, image,
cushy::kludgine::wgpu::FilterMode::Linear, cushy::kludgine::wgpu::FilterMode::Linear,

View file

@ -1,7 +1,8 @@
use cushy::figures::units::Lp; use cushy::figures::units::Lp;
use cushy::figures::Size; use cushy::figures::Size;
use cushy::kludgine::Color; use cushy::kludgine::Color;
use cushy::styles::{Dimension, DimensionRange}; use cushy::styles::{CornerRadii, Dimension, DimensionRange};
use cushy::widgets::image::ImageCornerRadius;
use cushy::{ use cushy::{
value::{Destination, Dynamic, IntoDynamic, IntoValue, Source, Value}, value::{Destination, Dynamic, IntoDynamic, IntoValue, Source, Value},
widget::{MakeWidget, WidgetList}, widget::{MakeWidget, WidgetList},
@ -88,6 +89,8 @@ where
let (background, background_hover) = get_colors(is_active); let (background, background_hover) = get_colors(is_active);
Image::new_empty() Image::new_empty()
.with_url(url) .with_url(url)
.with(&ImageCornerRadius, Dimension::Lp(Lp::points(4)))
.size(Size::squared(Dimension::Lp(Lp::points(40))))
.and(text.into_value().align_left()) .and(text.into_value().align_left())
.into_columns() .into_columns()
.into_button() .into_button()

View file

@ -3,12 +3,14 @@ use std::{
sync::{Arc, RwLock}, sync::{Arc, RwLock},
}; };
use chrono::TimeDelta;
use cushy::{ use cushy::{
figures::{units::Lp, Size}, figures::{units::Lp, Size},
styles::{Dimension, DimensionRange}, styles::{CornerRadii, Dimension, DimensionRange, Edges},
value::{Destination, Dynamic, Source}, value::{Destination, Dynamic, Source},
widget::{MakeWidget, WidgetInstance}, widget::{MakeWidget, WidgetInstance},
widgets::{ widgets::{
image::ImageCornerRadius,
label::{Displayable, LabelOverflow}, label::{Displayable, LabelOverflow},
Image, Label, Space, VirtualList, Image, Label, Space, VirtualList,
}, },
@ -88,7 +90,7 @@ impl LikedSongsPage {
{ {
pages_loading.write().unwrap().insert(page); pages_loading.write().unwrap().insert(page);
tokio_runtime().spawn(async move { tokio_runtime().spawn(async move {
println!("Loading page {} idx {}", page, index); // println!("Loading page {} idx {}", page, index);
let saved_tracks = context let saved_tracks = context
.current_user_saved_tracks( .current_user_saved_tracks(
Some(PER_PAGE as _), Some(PER_PAGE as _),
@ -100,7 +102,7 @@ impl LikedSongsPage {
// pages_loading.write().unwrap().remove(&page); // pages_loading.write().unwrap().remove(&page);
return; return;
}; };
println!("Loaded page {} got tracks {}", page, saved_tracks.total); // println!("Loaded page {} got tracks {}", page, saved_tracks.total);
total_tracks.set(saved_tracks.total as usize); total_tracks.set(saved_tracks.total as usize);
tracks.map_mut(|mut tracks| { tracks.map_mut(|mut tracks| {
for (i, track) in saved_tracks.items.into_iter().enumerate() { for (i, track) in saved_tracks.items.into_iter().enumerate() {
@ -114,6 +116,11 @@ impl LikedSongsPage {
let track = tracks.map_each(move |tracks| tracks.get(&index).cloned()); let track = tracks.map_each(move |tracks| tracks.get(&index).cloned());
index index
.to_string() .to_string()
.size(Size {
width: Dimension::Lp(Lp::points(40)).into(),
height: DimensionRange::default(),
})
.fit_horizontally()
.and({ .and({
get_or_create_track_image(&track_images, index, || { get_or_create_track_image(&track_images, index, || {
Image::new_empty() Image::new_empty()
@ -123,78 +130,104 @@ impl LikedSongsPage {
.map(|track| track.track.album.images[0].url.clone()) .map(|track| track.track.album.images[0].url.clone())
})) }))
.size(Size::squared(Dimension::Lp(Lp::points(40)))) .size(Size::squared(Dimension::Lp(Lp::points(40))))
.with(&ImageCornerRadius, Dimension::Lp(Lp::points(4)))
.make_widget() .make_widget()
}) })
.size(Size::squared(Dimension::Lp(Lp::points(40))))
}) })
.and(track.map_each(|track| { .and(
track track
.as_ref() .map_each(|track| {
.map(|track| {
Label::new(track.track.name.clone())
.overflow(LabelOverflow::Clip)
.and(
Label::new(
(track.track.artists)
.iter()
.map(|artist| artist.name.clone())
.join(", "),
)
.overflow(LabelOverflow::Clip),
)
.into_rows()
.make_widget()
})
.unwrap_or(Space::primary().make_widget())
}))
.and(track.map_each(|track| {
track
.as_ref()
.map(|track| {
track track
.track .as_ref()
.album .map(|track| {
.name Label::new(track.track.name.clone())
.clone() .overflow(LabelOverflow::Clip)
.into_label() .align_left()
.overflow(LabelOverflow::Clip) .and(
.make_widget() Label::new(
(track.track.artists)
.iter()
.map(|artist| artist.name.clone())
.join(", "),
)
.overflow(LabelOverflow::Clip)
.align_left(),
)
.into_rows()
.make_widget()
})
.unwrap_or(Space::primary().make_widget())
}) })
.unwrap_or(Space::primary().make_widget()) .align_left()
})) .expand_weighted(2),
.and(track.map_each(|track| { )
.and(
track track
.as_ref() .map_each(|track| {
.map(|track| {
track track
.added_at .as_ref()
.to_string() .map(|track| {
.into_label() track
.overflow(LabelOverflow::Clip) .track
.make_widget() .album
.name
.clone()
.into_label()
.overflow(LabelOverflow::Clip)
.make_widget()
})
.unwrap_or(Space::primary().make_widget())
}) })
.unwrap_or(Space::primary().make_widget()) .align_left()
})) .expand_weighted(1),
.and(track.map_each(|track| { )
.and(
track track
.as_ref() .map_each(|track| {
.map(|track| {
track track
.track .as_ref()
.duration .map(|track| {
.to_string() track
.into_label() .added_at
.overflow(LabelOverflow::Clip) .format("%B %-e, %Y")
.make_widget() .to_string()
.into_label()
.overflow(LabelOverflow::Clip)
.make_widget()
})
.unwrap_or(Space::primary().make_widget())
}) })
.unwrap_or(Space::primary().make_widget()) .align_left()
})) .expand_weighted(1),
)
.and(
track
.map_each(|track| {
track
.as_ref()
.map(|track| {
format_delta(track.track.duration)
.into_label()
.overflow(LabelOverflow::Clip)
.make_widget()
})
.unwrap_or(Space::primary().make_widget())
})
.pad_by(Edges::default().with_horizontal(Dimension::Lp(Lp::points(5)))),
)
.into_columns() .into_columns()
.size(Size { .size(Size {
width: DimensionRange::default(), width: DimensionRange::default(),
height: Dimension::Lp(Lp::points(60)).into(), height: Dimension::Lp(Lp::points(60)).into(),
}) })
.expand_horizontally()
}, },
) )
.expand_horizontally() .expand_horizontally()
} }
} }
fn format_delta(delta: TimeDelta) -> String {
format!("{}:{:02}", delta.num_minutes(), delta.num_seconds() % 60)
}