Add all tags in posts

This commit is contained in:
Florian RICHER 2024-02-18 19:49:06 +01:00
parent 91f2e4c116
commit 0436136cdd
2 changed files with 52 additions and 9 deletions

View file

@ -9,6 +9,7 @@ cfg_if::cfg_if! {
pub posts: Vec<Arc<Post>>, pub posts: Vec<Arc<Post>>,
pub posts_by_slug: HashMap<String, Arc<Post>>, pub posts_by_slug: HashMap<String, Arc<Post>>,
pub posts_by_tag: HashMap<String, Vec<Arc<Post>>>, pub posts_by_tag: HashMap<String, Vec<Arc<Post>>>,
pub tags: Vec<String>,
} }
impl Data { impl Data {
@ -21,6 +22,8 @@ cfg_if::cfg_if! {
.map(Arc::new) .map(Arc::new)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut tags : Vec<String> = Vec::new();
let mut posts_by_slug : HashMap<String, Arc<Post>> = HashMap::new(); let mut posts_by_slug : HashMap<String, Arc<Post>> = HashMap::new();
let mut posts_by_tag : HashMap<String, Vec<Arc<Post>>> = HashMap::new(); let mut posts_by_tag : HashMap<String, Vec<Arc<Post>>> = HashMap::new();
@ -28,19 +31,26 @@ cfg_if::cfg_if! {
posts_by_slug.insert(post.metadata.slug.clone(), post.clone()); posts_by_slug.insert(post.metadata.slug.clone(), post.clone());
for tag in &post.metadata.tags { for tag in &post.metadata.tags {
let tag = tag.to_lowercase(); let tag_lower = tag.to_lowercase();
let posts = posts_by_tag.entry(tag).or_default();
if let None = tags.iter().find(|t| t.to_lowercase().eq(&tag_lower)) {
tags.push(tag.clone());
}
let posts = posts_by_tag.entry(tag_lower).or_default();
posts.push(post.clone()); posts.push(post.clone());
} }
} }
log::info!("Loaded {} posts", posts.len()); log::info!("Loaded {} posts", posts.len());
log::info!("Found {} tags", posts_by_tag.len()); log::info!("Found {} tags in global", tags.len());
log::info!("Found {} tags from posts", posts_by_tag.len());
Ok(Self { Ok(Self {
posts, posts,
posts_by_slug, posts_by_slug,
posts_by_tag, posts_by_tag,
tags
}) })
} }
} }

View file

@ -32,6 +32,16 @@ pub async fn get_posts(
) )
} }
#[server]
pub async fn get_tags() -> Result<Vec<String>, ServerFnError> {
let data : actix_web::web::Data<crate::app::models::Data> = leptos_actix::extract().await?;
let data = data.into_inner();
let mut tags = data.tags.clone();
tags.sort();
Ok(tags)
}
#[server] #[server]
pub async fn get_post( pub async fn get_post(
slug: String slug: String
@ -117,6 +127,7 @@ pub fn PostList() -> impl IntoView {
let query = use_query_map(); let query = use_query_map();
let tag = move || query.with(|query| query.get("tag").cloned()); let tag = move || query.with(|query| query.get("tag").cloned());
let posts = create_resource(move || tag(), move |_| get_posts(tag())); let posts = create_resource(move || tag(), move |_| get_posts(tag()));
let tags = create_resource(|| (), move |_| get_tags());
let posts_view = move || { let posts_view = move || {
posts.and_then(|posts| { posts.and_then(|posts| {
@ -126,18 +137,40 @@ pub fn PostList() -> impl IntoView {
}) })
}; };
let tags_view = move || {
tags.and_then(|tags| {
tags.iter()
.map(|tag| {
let tag = tag.clone();
view! { <A class="tag" href=format!("/posts?tag={}", tag.clone())>{tag}</A> }
})
.collect_view()
})
};
let filter_view = move || { let filter_view = move || {
tag().map(|tag| Some(view! { match tag() {
<div class="mx-auto max-w-3xl mb-5"> Some(tag) => {
Tag sélectionné : <A class="tag" href="/posts".to_string()>{tag}<leptos_icons::Icon icon=icondata::IoClose class="scale-125 ml-1 inline" /></A> view! {
</div> <A class="tag" href="/posts".to_string()>{tag}<leptos_icons::Icon icon=icondata::IoClose class="scale-125 ml-1 inline" /></A>
})) }.into_view()
},
None => {
view! {
<div class="flex flex-wrap gap-2">
{tags_view}
</div>
}.into_view()
}
}
}; };
view! { view! {
<Suspense fallback=move || view! { <Loading title="Chargement des posts...".to_string() /> }> <Suspense fallback=move || view! { <Loading title="Chargement des posts...".to_string() /> }>
<Nav/> <Nav/>
{filter_view} <div class="mx-auto max-w-3xl mb-5">
{filter_view}
</div>
<main class="posts"> <main class="posts">
<div class="posts__cards">{posts_view}</div> <div class="posts__cards">{posts_view}</div>
</main> </main>