2019-02-05 14:11:02 +01:00
use gdk ::ContextExt ;
use gdk_pixbuf ::PixbufExt ;
use gtk ::* ;
use std ::{
fs ,
} ;
2019-02-08 13:35:58 +01:00
use crate ::{ api ::{ self , execute } , ui ::{ title , card } } ;
2019-02-05 14:11:02 +01:00
2019-02-08 13:35:58 +01:00
pub fn render ( ) -> gtk ::Box {
2019-02-05 14:11:02 +01:00
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 ) ;
2019-02-08 13:35:58 +01:00
let avatar_path = dirs ::cache_dir ( ) . unwrap ( ) . join ( " funkload " ) . join ( " avatar.png " ) ;
2019-02-05 14:11:02 +01:00
2019-02-08 13:35:58 +01:00
let avatar = DrawingArea ::new ( ) ;
2019-02-05 14:11:02 +01:00
avatar . set_size_request ( 128 , 128 ) ;
avatar . set_halign ( Align ::Center ) ;
2019-02-08 13:35:58 +01:00
avatar . connect_draw ( clone! ( avatar_path = > move | da , g | { // More or less stolen from Fractal (https://gitlab.gnome.org/GNOME/fractal/blob/master/fractal-gtk/src/widgets/avatar.rs)
2019-02-05 14:11:02 +01:00
use std ::f64 ::consts ::PI ;
let width = 128.0 f64 ;
let height = 128.0 f64 ;
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 ( ) ;
2019-02-08 13:35:58 +01:00
let pb = gdk_pixbuf ::Pixbuf ::new_from_file_at_scale ( avatar_path . clone ( ) , 128 , 128 , true )
. unwrap_or_else ( | _ | IconTheme ::get_default ( ) . unwrap ( ) . load_icon ( " avatar-default " , 128 , IconLookupFlags ::empty ( ) ) . unwrap ( ) . unwrap ( ) ) ;
2019-02-05 14:11:02 +01:00
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 )
2019-02-08 13:35:58 +01:00
} ) ) ;
2019-02-05 14:11:02 +01:00
cont . add ( & avatar ) ;
2019-02-08 13:35:58 +01:00
let welcome = Label ::new ( " Welcome. " ) ;
welcome . get_style_context ( ) . map ( | c | c . add_class ( " h1 " ) ) ;
cont . add ( & welcome ) ;
2019-02-05 14:11:02 +01:00
let search = SearchEntry ::new ( ) ;
search . set_placeholder_text ( " Search " ) ;
cont . add ( & search ) ;
let results = gtk ::Box ::new ( Orientation ::Vertical , 12 ) ;
2019-02-05 17:32:26 +01:00
results . set_valign ( Align ::Start ) ;
2019-02-05 14:11:02 +01:00
cont . add ( & results ) ;
2019-02-08 13:35:58 +01:00
rc! ( welcome , avatar , results ) ;
clone! ( welcome , avatar , results , avatar_path ) ;
wait! ( execute ( client! ( ) . get ( " /api/v1/users/users/me " ) ) = > | res | {
let res : api ::UserInfo = res . json ( ) . unwrap ( ) ;
welcome . borrow ( ) . set_text ( format! ( " Welcome {} . " , res . username ) . as_ref ( ) ) ;
clone! ( avatar_path , avatar ) ;
wait! ( execute ( client! ( ) . get ( & res . avatar . medium_square_crop . unwrap_or_default ( ) ) ) = > | avatar_dl | {
let mut avatar_file = fs ::File ::create ( avatar_path . clone ( ) ) . unwrap ( ) ;
avatar_dl . copy_to ( & mut avatar_file ) . unwrap ( ) ;
avatar . borrow ( ) . queue_draw ( ) ;
} ) ;
} ) ;
search . connect_activate ( move | s | {
let results = results . clone ( ) ;
wait! ( execute ( client! ( ) . get ( " /api/v1/search " ) . query ( & api ::SearchQuery {
query : s . get_text ( ) . unwrap_or_default ( )
} ) ) = > | res | {
update_results ( res . json ( ) . unwrap ( ) , & results . borrow ( ) ) ;
} ) ;
2019-02-05 14:11:02 +01:00
} ) ;
cont . show_all ( ) ;
cont
}
2019-02-08 13:35:58 +01:00
fn update_results ( res : api ::SearchResult , cont : & gtk ::Box ) {
2019-02-05 14:11:02 +01:00
for ch in cont . get_children ( ) {
cont . remove ( & ch ) ;
}
2019-02-08 13:35:58 +01:00
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 ::render ( artist ) . borrow ( ) ) ;
}
}
if ! res . albums . is_empty ( ) {
cont . add ( & title ( " Albums " ) ) ;
for album in res . albums . clone ( ) {
cont . add ( & * card ::render ( album ) . borrow ( ) ) ;
2019-02-05 14:11:02 +01:00
}
}
2019-02-08 13:35:58 +01:00
if ! res . tracks . is_empty ( ) {
cont . add ( & title ( " Songs " ) ) ;
for track in res . tracks . clone ( ) {
cont . add ( & * card ::render ( track ) . borrow ( ) ) ;
}
}
2019-02-05 14:11:02 +01:00
cont . show_all ( ) ;
}