151 lines
4.2 KiB
Rust
151 lines
4.2 KiB
Rust
|
use gdk::ContextExt;
|
||
|
use gdk_pixbuf::PixbufExt;
|
||
|
use gtk::*;
|
||
|
use std::{
|
||
|
cell::RefCell,
|
||
|
rc::Rc,
|
||
|
ops::Deref,
|
||
|
fs,
|
||
|
};
|
||
|
use crate::{State, api, ui::{title, card::Card}};
|
||
|
|
||
|
pub fn render(state: State) -> gtk::Box {
|
||
|
let cont = gtk::Box::new(Orientation::Vertical, 12);
|
||
|
cont.set_margin_top(48);
|
||
|
cont.set_margin_bottom(48);
|
||
|
cont.set_margin_start(96);
|
||
|
cont.set_margin_end(96);
|
||
|
|
||
|
let avatar_path = dirs::cache_dir().unwrap().join("funkload-avatar.png");
|
||
|
let user: api::UserInfo = reqwest::Client::new()
|
||
|
.get(&format!("https://{}/api/v1/users/users/me/", state.borrow().instance.clone().unwrap()))
|
||
|
.header(reqwest::header::AUTHORIZATION, format!("JWT {}", state.borrow().token.clone().unwrap_or_default()))
|
||
|
.send()
|
||
|
.unwrap()
|
||
|
.json()
|
||
|
.unwrap();
|
||
|
let pb = match user.avatar.medium_square_crop {
|
||
|
Some(url) => {
|
||
|
let mut avatar_file = fs::File::create(avatar_path.clone()).unwrap();
|
||
|
reqwest::Client::new()
|
||
|
.get(&format!("https://{}{}", state.borrow().instance.clone().unwrap(), url))
|
||
|
.header(reqwest::header::AUTHORIZATION, format!("JWT {}", state.borrow().token.clone().unwrap_or_default()))
|
||
|
.send()
|
||
|
.unwrap()
|
||
|
.copy_to(&mut avatar_file)
|
||
|
.unwrap();
|
||
|
gdk_pixbuf::Pixbuf::new_from_file_at_scale(avatar_path, 128, 128, true).unwrap()
|
||
|
},
|
||
|
None => {
|
||
|
IconTheme::get_default().unwrap().load_icon("avatar-default", 128, IconLookupFlags::empty()).unwrap().unwrap()
|
||
|
}
|
||
|
};
|
||
|
|
||
|
let avatar = DrawingArea::new();
|
||
|
avatar.set_size_request(128, 128);
|
||
|
avatar.set_halign(Align::Center);
|
||
|
avatar.connect_draw(move |da, g| { // More or less stolen from Fractal (https://gitlab.gnome.org/GNOME/fractal/blob/master/fractal-gtk/src/widgets/avatar.rs)
|
||
|
use std::f64::consts::PI;
|
||
|
let width = 128.0f64;
|
||
|
let height = 128.0f64;
|
||
|
|
||
|
g.set_antialias(cairo::Antialias::Best);
|
||
|
|
||
|
let context = da.get_style_context().unwrap();
|
||
|
gtk::render_background(&context, g, 0.0, 0.0, width, height);
|
||
|
|
||
|
g.arc(
|
||
|
width / 2.0,
|
||
|
height / 2.0,
|
||
|
width.min(height) / 2.0,
|
||
|
0.0,
|
||
|
2.0 * PI,
|
||
|
);
|
||
|
g.clip();
|
||
|
|
||
|
let hpos: f64 = (width - (pb.get_height()) as f64) / 2.0;
|
||
|
g.set_source_pixbuf(&pb, 0.0, hpos);
|
||
|
|
||
|
g.rectangle(0.0, 0.0, width, height);
|
||
|
g.fill();
|
||
|
|
||
|
Inhibit(false)
|
||
|
});
|
||
|
|
||
|
cont.add(&avatar);
|
||
|
let lbl = Label::new(format!("Welcome {}.", user.username).as_ref());
|
||
|
lbl.get_style_context().map(|c| c.add_class("h1"));
|
||
|
cont.add(&lbl);
|
||
|
|
||
|
let search = SearchEntry::new();
|
||
|
search.set_placeholder_text("Search");
|
||
|
cont.add(&search);
|
||
|
|
||
|
let results = gtk::Box::new(Orientation::Vertical, 12);
|
||
|
cont.add(&results);
|
||
|
|
||
|
let widgets = Rc::new(RefCell::new(
|
||
|
(search, results)
|
||
|
));
|
||
|
let state = state.clone();
|
||
|
widgets.clone().borrow().0.connect_activate(move |_| {
|
||
|
let res: api::SearchResult = reqwest::Client::new()
|
||
|
.get(&format!("https://{}/api/v1/search", state.borrow().instance.clone().unwrap()))
|
||
|
.header(reqwest::header::AUTHORIZATION, format!("JWT {}", state.borrow().token.clone().unwrap_or_default()))
|
||
|
.query(&api::SearchQuery {
|
||
|
query: widgets.borrow().deref().0.get_text().unwrap_or_default()
|
||
|
})
|
||
|
.send()
|
||
|
.unwrap()
|
||
|
.json()
|
||
|
.unwrap();
|
||
|
|
||
|
state.borrow_mut().search_result = Some(res.clone());
|
||
|
println!("{:#?}", res);
|
||
|
update_results(state.clone(), &widgets.borrow().1);
|
||
|
});
|
||
|
|
||
|
cont.show_all();
|
||
|
cont
|
||
|
}
|
||
|
|
||
|
fn update_results(state: State, cont: >k::Box) {
|
||
|
for ch in cont.get_children() {
|
||
|
cont.remove(&ch);
|
||
|
}
|
||
|
|
||
|
match &state.borrow().search_result {
|
||
|
Some(res) => {
|
||
|
if res.artists.is_empty() && res.albums.is_empty() && res.tracks.is_empty() {
|
||
|
cont.add(&Label::new("No results. Try something else."));
|
||
|
}
|
||
|
|
||
|
if !res.artists.is_empty() {
|
||
|
cont.add(&title("Artists"));
|
||
|
for artist in res.artists.clone() {
|
||
|
cont.add(&Card::new(artist, state.clone()).render());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if !res.albums.is_empty() {
|
||
|
cont.add(&title("Albums"));
|
||
|
for album in res.albums.clone() {
|
||
|
cont.add(&Card::new(album, state.clone()).render());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if !res.tracks.is_empty() {
|
||
|
cont.add(&title("Songs"));
|
||
|
for track in res.tracks.clone() {
|
||
|
cont.add(&Card::new(track, state.clone()).render());
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
None => {
|
||
|
cont.add(&Label::new("Try to search something"));
|
||
|
}
|
||
|
}
|
||
|
cont.show_all();
|
||
|
}
|
||
|
|