From 39bc6604783385d7f62441227771f8fa7bcfcf0f Mon Sep 17 00:00:00 2001 From: ecco257 <72117210+ecco257@users.noreply.github.com> Date: Fri, 15 Mar 2024 16:59:29 -0400 Subject: [PATCH] Add searchbar component --- src/searchbar.rs | 154 +++++++++++++++++++++++++++++++++++++++++++ style/main.scss | 7 ++ style/searchbar.scss | 99 ++++++++++++++++++++++++++++ style/theme.scss | 1 + 4 files changed, 261 insertions(+) create mode 100644 src/searchbar.rs create mode 100644 style/searchbar.scss diff --git a/src/searchbar.rs b/src/searchbar.rs new file mode 100644 index 0000000..9cd8c9d --- /dev/null +++ b/src/searchbar.rs @@ -0,0 +1,154 @@ +use crate::search::search; +use crate::playstatus::PlayStatus; +use crate::song::Song; +use crate::models::Album; +use crate::models::Artist; +use crate::models::Song; +use leptos::*; +use leptos::ev::*; +use leptos::leptos_dom::*; +use leptos_icons::*; +use leptos_icons::BsIcon::*; + +const OPTIONS_BTN_SIZE: &str = "2.5rem"; + +#[component] +pub fn SearchBar(status: RwSignal) -> impl IntoView { + let search_query = create_rw_signal(String::new()); + let search_results = create_rw_signal((Vec::<(Album, f32)>::new(), Vec::<(Artist, f32)>::new(), Vec::<(Song, f32)>::new())); + let search_limit = 10; + + let on_input = move |e: Event| { + search_query.set(event_target_value(&e)); + + log!("Search Query: {:?}", search_query.get_untracked()); + + if search_query.get_untracked().len() < 3 { + search_results.set((Vec::<(Album, f32)>::new(), Vec::<(Artist, f32)>::new(), Vec::<(Song, f32)>::new())); + return; + } + spawn_local(async move { + log!("Searching for: {:?}", search_query.get_untracked()); + let results = search(search_query.get_untracked(), search_limit).await; + match results { + Ok((albums, artists, songs)) => { + search_results.set((albums, artists, songs)); + } + Err(err) => { + log!("Error searching: {:?}", err); + } + } + }); + }; + + let on_disabled = move |_e: FocusEvent| { + + log!("Search Bar Disabled"); + }; + + let on_enabled = move |_e: FocusEvent| { + status.update(|status| { + status.search_active = true; + }); + log!("Search Bar Enabled"); + }; + + let prevent_focus = move |e: MouseEvent| { + e.prevent_default(); + }; + + view! { +
+ +
+
    + { + move || search_results.with(|(albums, artists, songs)| -> Vec<_> { + let mut album_index = 0; + let mut artist_index = 0; + let mut song_index = 0; + let mut views = Vec::new(); + while album_index < albums.len() || artist_index < artists.len() || song_index < songs.len() { + const RM_BTN_SIZE: &str = "2.5rem"; + let album_score = if album_index < albums.len() { albums[album_index].1 } else { f32::MAX }; + let artist_score = if artist_index < artists.len() { artists[artist_index].1 } else { f32::MAX }; + let song_score = if song_index < songs.len() { songs[song_index].1 } else { f32::MAX }; + if artist_score <= album_score && artist_score <= song_score { + let artist = &artists[artist_index].0; + artist_index += 1; + views.push(view! { +
  • +
    +
    + {artist.name.clone()} +
    +
    +
    + "(Artist)" +
    + +
    +
    +
  • + }); + } + else if album_score <= artist_score && album_score <= song_score { + let album = &albums[album_index].0; + album_index += 1; + views.push(view! { +
  • +
    +
    + {album.title.clone()} + {match album.release_date { + Some(date) => format!(" ({})", date), + None => "".to_string() + }} +
    +
    +
    + "(Album)" +
    + +
    +
    +
  • + }); + } + else if song_score <= artist_score && song_score <= album_score { + let song = &songs[song_index].0; + song_index += 1; + views.push(view! { +
  • +
    + path, + None => "".to_string() + } song_title=song.title.clone() song_artist="".to_string() /> +
    +
    + "(Song)" +
    + +
    +
    +
  • + }); + } + } + views + }) + } +
+
+
+ } +} diff --git a/style/main.scss b/style/main.scss index 6706ef1..33362b5 100644 --- a/style/main.scss +++ b/style/main.scss @@ -3,6 +3,8 @@ @import 'queue.scss'; @import 'login.scss'; @import 'signup.scss'; +@import 'song.scss'; +@import 'searchbar.scss'; body { font-family: sans-serif; @@ -11,3 +13,8 @@ body { margin: 0; padding: 0; } + +.home { + width: 100%; + height: 100%; +} diff --git a/style/searchbar.scss b/style/searchbar.scss new file mode 100644 index 0000000..0a9d2b3 --- /dev/null +++ b/style/searchbar.scss @@ -0,0 +1,99 @@ +@import 'theme.scss'; + +.search-container { + display: flex; + margin: 5px auto; + margin-left: 282px; + border-radius: 5px; + height: 100%; + width: calc(100% - 690px); + background-color: $search-background-color; +} + +.search-bar { + background-color: transparent; + border-radius: 5px; + padding: 10px; + display: flex; + justify-content: left; + z-index: 10; +} + +.search-bar input[type="search"] { + background-color: gray; + border: none; + outline: none; + color: black; + padding: 10px; + border-radius: 5px; + font-size: 16px; + &::placeholder { + color: rgb(61, 61, 61); + } +} + +.search-results { + background-color: #212121; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + display: flex; + margin-top: 55px; + height: calc(100% - 143px); + width: calc(100% - 690px); + position: absolute; + + ul { + list-style: none; + padding: 0; + margin: 0; + width: 100%; + + li { + width: calc(100% - 20px); + padding: 10px; + border-bottom: 1px solid #333; + border-radius: 5px; + color: white; + font-size: 16px; + cursor: pointer; + &:hover { + background-color: #333; + } + + &:first-child { + border-top: 2px solid #333; + } + + .result-container { + display: flex; + align-items: center; + justify-content: space-between; + + } + + .right-side-result { + display: flex; + align-items: center; + justify-content: space-between; + + .search-item-type { + color: #666; + margin-right: 10px; + } + + .search-result-options { + background-color: transparent; + border: none; + + &:hover { + color: #666; + } + + &:active { + color: #999; + } + } + } + } + } +} diff --git a/style/theme.scss b/style/theme.scss index 2d80285..c4e29e6 100644 --- a/style/theme.scss +++ b/style/theme.scss @@ -7,6 +7,7 @@ $play-bar-background-color: #212121; $play-grad-start: #0a0533; $play-grad-end: $accent-color; $queue-background-color: $play-bar-background-color; +$search-background-color: $play-bar-background-color; $auth-inputs: #796dd4; $auth-containers: white;