use egui::{Color32, RichText, Vec2}; use song_list_nav::SearchType; use xmpd_manifest::{query::QueryType, 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) => true, SearchType::Author(ref s) if !s.is_empty() && song.author().to_lowercase().contains(s) => true, SearchType::Name(ref s) if !s.is_empty() && song.name().to_owned().contains(s) => true, _ => false }; if should_display { display_song_tab(ui, sid, song); } } } } } }); }); Ok(()) } } fn display_song_tab(ui: &mut egui::Ui, sid: &uuid::Uuid, song: &Song) { let rct = ui.horizontal(|ui| { ui.add( egui::Image::new(crate::data::NOTE_ICON) .tint(crate::data::C_ACCENT) .fit_to_exact_size(Vec2::new(32.0, 32.0)) ); ui.vertical(|ui| { let selected_song_id = {handle_error_ui!(SongList::get()).selected_song_id}; if selected_song_id == *sid { ui.label(RichText::new(song.name()).color(crate::data::C_ACCENT)); } else { ui.label(song.name()); }; ui.monospace( RichText::new(format!("By {}", song.author())) .color(crate::data::C_TEXT_DIM) .size(10.0) ); }); }).response.rect; if ui.interact(rct, format!("song_list_{sid:?}").into(), egui::Sense::click()).clicked() { handle_error_ui!(SongList::get()).selected_song_id = sid.clone(); } ui.separator(); }