Skip to content

Commit

Permalink
better filter management (separate menu)
Browse files Browse the repository at this point in the history
  • Loading branch information
YilunAllenChen committed Nov 11, 2023
1 parent 0df9c62 commit 1c91ba3
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 57 deletions.
96 changes: 46 additions & 50 deletions src/pages/hall.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::collections::HashSet;

use yew::prelude::*;

use crate::artifact::{ArticleComponent, BuiltYaml, ExhibitionHall};
use crate::html_utils::render_text_tag;
use crate::html_utils::scroll::try_scroll_to;
use crate::pages::hall_components::HallNav;
use crate::pages::hall_components::{FilterMgmtMenu, HallNav};

pub struct HallComponent {
active_hall: Option<ExhibitionHall>,
Expand Down Expand Up @@ -68,13 +69,26 @@ impl Component for HallComponent {
let yaml = include_str!("../artifacts/build/compiled.yaml");
let built_yaml: BuiltYaml = serde_yaml::from_str(yaml).unwrap();

let mut all_available_tags = built_yaml
.artifacts
.iter()
.flat_map(|article| {
let mut article_tags = article.tags.clone();
article_tags.push(article.language.to_string());
article_tags
})
.collect::<Vec<String>>();
let set: HashSet<_> = all_available_tags.drain(..).collect(); // dedup
all_available_tags.extend(set);
all_available_tags.sort();

let hall_name = match &self.active_hall {
Some(hall) => hall.to_string(),
None => "The Everything Hall".to_string(),
};
let desc = match &self.active_hall {
Some(hall) => hall.desc(),
None => "You're currently viewing all artifacts. Select a hall (🏛️), or click on the tags to filter the artifacts."
None => "You're currently viewing all artifacts. Select a hall ( 🏛️ ), or click on the tags ( 🏷️ ) to filter the artifacts."
};

let mut loaded_articles = built_yaml.artifacts;
Expand Down Expand Up @@ -110,65 +124,47 @@ impl Component for HallComponent {
0 => html! {
<div class="my-20 mx-12 text-center text-gray-300 space-y-4">
<p>{"This room seems to be empty 🤔..."}</p>
<p>{"Did you forget to clear your filter (🏷️)?"}</p>
<p>{"Did you forget to clear your filter ( 🏷️ )?"}</p>
</div>
},
_ => html! {
<div class="my-20 mx-12 text-center text-gray-300 space-y-4">
<p>{"You've reached the end of the this room."}</p>
<p>{"Hope you enjoyed your visit!"}</p>
<p>{"If you want to see more, check out the other halls (🏛️)!"}</p>
</div>
},
};

let emitter = ctx.link().clone();
let nav_cb = Callback::from(move |msg| emitter.send_message(msg));

let clear_filter_button = match self.filter_tags.len() {
0 => html! {},
_ => {
let clear_individual_tags = self
.filter_tags
.iter()
.map(|tag| {
let tagc= tag.clone();
html! {
<div
onclick={ctx.link().callback(move |_| HallMsg::ToggleTag(tagc.clone()))}
>
{
Html::from_html_unchecked(
render_text_tag(tag).into()
)
}
</div>
}
})
.collect::<Html>();
let see_more = match self.filter_tags.len() {
0 => html! {
<p>
{"If you want to see more, check out the other halls ( 🏛️ )!"}
</p>
},
_ => html! {
<p>
{"If you want to see more, check out the other halls ( 🏛️ ), or clear some of your active filters ( 🏷️ )!"}
</p>
},
};
html! {
<div class="select-none z-30 animate-enter-bottom fixed left-36 bottom-4">
<div class="flex gap-x-2">
<div class="flex-none rounded-full bg-indigo-500/20 p-1">
<button
class="w-12 h-12 bg-indigo-500 text-white rounded-full text-2xl flex items-center justify-center"
onclick={ctx.link().callback(|_| HallMsg::ClearTags)}>
{"🏷️"}
</button>
</div>
<div class="grid grid-rows-2 grid-flow-col gap-0">
{clear_individual_tags}
</div>
</div>
<div class="my-20 mx-12 text-center text-gray-300 space-y-4">
<p>{"You've reached the end of the this room."}</p>
<p>{"Hope you enjoyed your visit!"}</p>
{see_more}
</div>
}
}
};

let emitter = ctx.link().clone();
let nav_cb = Callback::from(move |msg| emitter.send_message(msg));

let emitter = ctx.link().clone();
let filter_mgmt_cb = Callback::from(move |msg| emitter.send_message(msg));

html! {
<>
<HallNav active_hall_name={hall_name.clone()} hall_cb={nav_cb}/>
{clear_filter_button}
<FilterMgmtMenu
available_tags={all_available_tags}
filter_tags={self.filter_tags.clone()}
hall_msg_cb={filter_mgmt_cb}
/>


<div class="z-10 fixed w-full h-20 bottom-0 bg-black/80"/>

Expand Down
120 changes: 120 additions & 0 deletions src/pages/hall_components/filter_mgmt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
use yew::*;

use crate::{html_utils::render_text_tag, pages::HallMsg};

#[derive(Properties, PartialEq)]
pub struct Props {
pub hall_msg_cb: Callback<HallMsg>,
pub available_tags: Vec<String>,
pub filter_tags: Vec<String>,
}

#[function_component]
pub fn FilterMgmtMenu(props: &Props) -> Html {
let show_menu = use_state(|| !props.filter_tags.is_empty());

let toggle_popup = {
let show_popup = show_menu.clone();
Callback::from(move |_| show_popup.set(!*show_popup))
};

let menu_btn = html! {
<div class="select-none z-30 animate-enter-bottom fixed left-36 bottom-4">
<div class="flex gap-x-2">
<div class="flex-none rounded-full bg-indigo-500/20 p-1">
<button
class="w-12 h-12 bg-indigo-500 text-white rounded-full text-2xl flex items-center justify-center"
onclick={toggle_popup.clone()}>
{"🏷️"}
</button>
</div>
</div>
</div>
};

let tag_to_toggle_button = |tag: &String| {
let tagc = tag.clone();
html! {
<div
onclick={props.hall_msg_cb.clone().reform(move |_| HallMsg::ToggleTag(tagc.clone()))}
>
{ Html::from_html_unchecked( render_text_tag(tag).into()) }
</div>
}
};

let enable_tag = props
.available_tags
.iter()
.filter(|tag| !props.filter_tags.contains(tag))
.map(tag_to_toggle_button)
.collect::<Html>();

let clear_individual_tags = match props.filter_tags.len() {
0 => html! {
<p class="text-gray-700">{"No active filters"}</p>
},
_ => props
.filter_tags
.iter()
.filter(|tag| props.available_tags.contains(tag))
.map(tag_to_toggle_button)
.collect::<Html>(),
};

let menu = html! {
<div class="relative z-40">
<div class="fixed inset-0 bg-gray-500 bg-opacity-25 transition-opacity"></div>
<div
class="select-none fixed inset-0 z-50 w-screen overflow-y-auto overflow-x-auto"
onclick={toggle_popup.clone()}
>
<div class="flex ease-in min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<div class="w-full bg-black bg-opacity-80 text-white overflow-hidden rounded-lg text-center sm:max-w-2xl"
onclick={|e: MouseEvent| e.stop_propagation()}>
<p class="text-2xl font-semibold mt-4">
{"Filter Management"}
</p>


<p class="text-xl mt-8">
{"Active Filters"}
</p>
<div class="px-4 flex flex-wrap justify-center gap-x-2 gap-y-2 mt-4">
{clear_individual_tags}
</div>

<p class="text-xl mt-8">
{"Available Filters"}
</p>
<div class="px-4 flex flex-wrap justify-center gap-x-2 gap-y-2 mt-4">
{enable_tag}
</div>

<div class="flex justify-center m-10 gap-x-4">
<p class="text-center text-xl w-1/2 md:w-1/4 rounded-lg p-2 bg-indigo-500 font-semibold"
onclick={props.hall_msg_cb.clone().reform(|_| HallMsg::ClearTags)}
>
{"Clear All"}
</p>
<p class="text-center text-xl w-1/2 md:w-1/4 rounded-lg p-2 bg-red-500 font-semibold"
onclick={toggle_popup}
>
{"Close"}
</p>
</div>
</div>
</div>
</div>
</div>
};

match *show_menu {
false => html! {
{menu_btn}
},
true => html! {
{menu}
},
}
}
3 changes: 3 additions & 0 deletions src/pages/hall_components/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
mod hall_nav;
pub use hall_nav::HallNav;

mod filter_mgmt;
pub use filter_mgmt::FilterMgmtMenu;
12 changes: 5 additions & 7 deletions src/pages/nav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use yew_router::scope_ext::RouterScopeExt;
use crate::Route;

pub struct Nav {
show_sidebar: bool,
show_nav: bool,
}

#[derive(Properties, PartialEq)]
Expand All @@ -20,9 +20,7 @@ impl Component for Nav {
type Properties = NavProps;

fn create(_ctx: &Context<Self>) -> Self {
Self {
show_sidebar: false,
}
Self { show_nav: false }
}

fn changed(&mut self, _ctx: &Context<Self>, _old_props: &Self::Properties) -> bool {
Expand All @@ -32,11 +30,11 @@ impl Component for Nav {
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::ToggleSidebar(show) => {
self.show_sidebar = show;
self.show_nav = show;
true
}
Msg::SelectPage(page) => {
self.show_sidebar = false;
self.show_nav = false;
let navigator = ctx.link().navigator().unwrap();
navigator.push(&page);
true
Expand All @@ -45,7 +43,7 @@ impl Component for Nav {
}

fn view(&self, ctx: &Context<Self>) -> Html {
if !self.show_sidebar {
if !self.show_nav {
html! {
<div class="select-none z-30 animate-enter-bottom fixed left-2 bottom-4 left-4">
<div class="flex-none rounded-full bg-blue-500/20 p-1">
Expand Down

0 comments on commit 1c91ba3

Please sign in to comment.