use std::fmt::write; use egui::{Color32, RichText, Sense, Vec2}; use song_list_nav::SearchType; use xmpd_cache::DlStatus; use xmpd_manifest::{song::Song, store::BaseStore}; use super::{CompGetter, CompUi}; pub mod song_list_nav; #[derive(Debug, Default)] pub struct SongList { selected_song_id: uuid::Uuid } component_register!(SongList); impl CompUi for SongList { fn draw(ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> { egui::ScrollArea::vertical() .id_source("song_list") .drag_to_scroll(false) .show(ui, |ui| { ui.vertical(|ui| { ui.add_space(3.0); let pid = {handle_error_ui!(super::left_nav::LeftNav::get()).selected_playlist_id.clone()}; match pid { None => { let mut songs: Vec<_> = state.manifest.store().get_songs().iter().collect(); songs.sort_by(|a, b| { let a = a.1.name().to_lowercase(); let b = b.1.name().to_lowercase(); a.cmp(&b) }); for (sid, song) in songs { let query = {handle_error_ui!(song_list_nav::SongListNav::get()).parse_search()}.clone(); let should_display = match query { SearchType::Source(s) if !s.is_empty() => format!("{:?}", &song.source_type()).to_lowercase().contains(&s), SearchType::Author(s) if !s.is_empty() => song.author().to_lowercase().contains(&s), SearchType::Name(s) if !s.is_empty() => song.name().to_owned().contains(&s), _ => true }; if should_display { display_song_tab(ui, sid, song); } } } Some(pid) => { if let Some(playlist) = state.manifest.store().get_playlist(&pid) { let mut songs = Vec::new(); for sid in playlist.songs() { if let Some(song) = state.manifest.store().get_song(&sid) { songs.push((sid, song)); } } songs.sort_by(|a, b| { let a = a.1.name().to_lowercase(); let b = b.1.name().to_lowercase(); a.cmp(&b) }); let query = {handle_error_ui!(song_list_nav::SongListNav::get()).parse_search()}.clone(); for (sid, song) in songs { let should_display = match query { SearchType::Source(ref s) if !s.is_empty() => format!("{:?}", &song.source_type()).to_lowercase().contains(s), SearchType::Author(ref s) if !s.is_empty() => song.author().to_lowercase().contains(s), SearchType::Name(ref s) if !s.is_empty() => song.name().to_owned().contains(s), _ => true }; if should_display { display_song_tab(ui, sid, song); } } } } } }); }); Ok(()) } } fn display_song_tab(ui: &mut egui::Ui, sid: &uuid::Uuid, song: &Song) { let theme = handle_error_ui!(xmpd_settings::Settings::get()).theme.clone(); ui.horizontal(|ui| { let mut clicked = ui.add( egui::Image::new(crate::data::NOTE_ICON) .tint(theme.accent_color) .sense(Sense::click()) .fit_to_exact_size(Vec2::new(32.0, 32.0)) ).clicked(); ui.vertical(|ui| { let selected_song_id = {handle_error_ui!(SongList::get()).selected_song_id}; let label = if selected_song_id == *sid { ui.label( RichText::new(song.name()) .color(theme.accent_color) ) } else { ui.label( RichText::new(song.name()) .color(theme.text_color) ) }; if label.clicked() { clicked = true; } ui.monospace( RichText::new(format!("By {}", song.author())) .color(theme.dim_text_color) .size(10.0) ); }); ui.with_layout(egui::Layout::right_to_left(egui::Align::RIGHT), |ui| { ui.add_space(3.0); let status = { handle_error_ui!(xmpd_cache::Cache::get()).get_cached_song_status(&sid).clone() }; match status { Some(DlStatus::Done(p)) => { let img = ui.add( egui::Image::new(crate::data::CHECK_ICON) .tint(Color32::LIGHT_GREEN) .sense(Sense::hover()) .fit_to_exact_size(Vec2::new(16.0, 16.0)) ); img.on_hover_ui(|ui| { ui.label(format!("Path: {p}")); }); } Some(DlStatus::Downloading) => { ui.add( egui::Spinner::new() .color(theme.accent_color) .size(16.0) ); } Some(DlStatus::Error(e)) => { let img = ui.add( egui::Image::new(crate::data::WARN_ICON) .tint(Color32::LIGHT_YELLOW) .sense(Sense::hover()) .fit_to_exact_size(Vec2::new(16.0, 16.0)) ); img.on_hover_ui(|ui| { ui.label(e); }); } None => { let img = ui.add( egui::Image::new(crate::data::DL_ICON) .tint(theme.accent_color) .sense(Sense::click()) .fit_to_exact_size(Vec2::new(16.0, 16.0)) ); if img.clicked() { handle_error_ui!(xmpd_cache::Cache::get()).download_to_cache(sid.clone(), song.clone()) } } } }); if clicked { handle_error_ui!(SongList::get()).selected_song_id = sid.clone(); } }); ui.separator(); }