Adding and moving a lot of components.
This is the main thrust of the library. I know it is a lot of changes, but I was running out of time and had to hammer them all in.
This commit is contained in:
194
bard/src/components/list.rs
Normal file
194
bard/src/components/list.rs
Normal file
@ -0,0 +1,194 @@
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::HashSet;
|
||||
use std::hash::Hash;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use tavern::{Adventurer, Legend, Lore, Tale};
|
||||
|
||||
use crate::togglable::Togglable;
|
||||
use crate::page::Page;
|
||||
use crate::server::*;
|
||||
use super::tags::*;
|
||||
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn BlogAuthor() -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
section
|
||||
{
|
||||
class: "blog_author_style",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn BlogItem(title: String, slug: String, author: String, summary: String,
|
||||
tags: Vec<String>)
|
||||
-> Element
|
||||
{
|
||||
println!("Blog Item: {title} -- [{tags:?}]");
|
||||
rsx!
|
||||
{
|
||||
li
|
||||
{
|
||||
key: "{slug}",
|
||||
class: "blog_item",
|
||||
|
||||
Link
|
||||
{
|
||||
to: Page::Post { slug: slug.clone() },
|
||||
h1 { "{title}" }
|
||||
}
|
||||
|
||||
TagList
|
||||
{
|
||||
for tag in tags
|
||||
{
|
||||
TagItem
|
||||
{
|
||||
tag: tag.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h4 { "Author: {author}" }
|
||||
|
||||
p { "{summary}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn BlogList(tags: Signal<HashSet<String>>, children: Element) -> Element
|
||||
{
|
||||
let list = use_server_future(move || {
|
||||
let categories = tags().iter().cloned().collect();
|
||||
|
||||
async move { get_blog_list(categories).await }
|
||||
})?;
|
||||
|
||||
rsx!
|
||||
{
|
||||
section
|
||||
{
|
||||
class: "blog_list_style",
|
||||
ul
|
||||
{
|
||||
class: "blog_list",
|
||||
|
||||
if let Some(Ok(lores)) = &*list.read()
|
||||
{
|
||||
for lore in lores
|
||||
{
|
||||
BlogItem
|
||||
{
|
||||
title: lore.title.clone(),
|
||||
slug: lore.slug.clone(),
|
||||
author: lore.author.clone(),
|
||||
summary: lore.summary.clone(),
|
||||
tags: lore.tags.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
else if let Some(Err(e)) = &*list.read()
|
||||
{
|
||||
p { "Unable to show post header." }
|
||||
p { "{e}" }
|
||||
}
|
||||
else
|
||||
{
|
||||
p { "Loading..." }
|
||||
}
|
||||
|
||||
{children}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ToggleTag(tag: String, toggled_tags: Signal<HashSet<String>>) -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
label
|
||||
{
|
||||
class: "toggle_button",
|
||||
|
||||
input
|
||||
{
|
||||
r#type: "checkbox",
|
||||
checked: toggled_tags.read().is_toggled(&tag),
|
||||
onchange: move |_|
|
||||
{
|
||||
toggled_tags.write().toggle(&tag.clone());
|
||||
},
|
||||
}
|
||||
|
||||
span { "{tag}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn TagSelector(show_all: Signal<bool>, toggled_tags: Signal<HashSet<String>>) -> Element
|
||||
{
|
||||
let toggle_all: bool = show_all();
|
||||
|
||||
println!("Tag Selector toggled tags: {:?}", toggled_tags());
|
||||
let tags_future = use_server_future(move || async move { get_tags().await })?;
|
||||
|
||||
use_effect(move ||
|
||||
{
|
||||
if let Some(Ok(tags)) = &*tags_future.read()
|
||||
{
|
||||
if toggle_all
|
||||
{
|
||||
for tag in tags
|
||||
{
|
||||
toggled_tags.write().insert(tag.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
rsx!
|
||||
{
|
||||
section
|
||||
{
|
||||
class: "blog_nav_style",
|
||||
div
|
||||
{
|
||||
class: "tag_style",
|
||||
h2 { "Categories" }
|
||||
ul
|
||||
{
|
||||
class: "tag_list",
|
||||
|
||||
if let Some(Ok(tags)) = tags_future()
|
||||
{
|
||||
for tag in tags
|
||||
{
|
||||
li
|
||||
{
|
||||
key: "selector-{tag}",
|
||||
class: "tag_item",
|
||||
|
||||
ToggleTag
|
||||
{
|
||||
tag: &tag,
|
||||
toggled_tags: toggled_tags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
bard/src/components/mod.rs
Normal file
8
bard/src/components/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
mod list;
|
||||
mod post;
|
||||
mod tags;
|
||||
|
||||
|
||||
pub use self::list::*;
|
||||
pub use self::post::*;
|
||||
pub use self::tags::*;
|
||||
180
bard/src/components/post.rs
Normal file
180
bard/src/components/post.rs
Normal file
@ -0,0 +1,180 @@
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::HashSet;
|
||||
use std::hash::Hash;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use tavern::{Adventurer, Legend, Lore, Tale};
|
||||
|
||||
use crate::togglable::Togglable;
|
||||
use crate::page::Page;
|
||||
use crate::server::*;
|
||||
use super::tags::*;
|
||||
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn BlogAuthor() -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
section
|
||||
{
|
||||
class: "blog_author_style",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn PostHeaderAuthor(adventurer: Adventurer) -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
h4
|
||||
{
|
||||
"Author: ",
|
||||
a { href: "{adventurer.legend.profile}", "{adventurer.name} @{adventurer.handle}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn PostHeader(tale: Tale) -> Element
|
||||
{
|
||||
let author_future = use_server_future(move ||
|
||||
{
|
||||
let handle: String = tale.lore.author.clone();
|
||||
|
||||
async move { get_author(handle).await }
|
||||
})?;
|
||||
|
||||
rsx!
|
||||
{
|
||||
h1 { {tale.lore.title} }
|
||||
|
||||
TagList
|
||||
{
|
||||
for tag in tale.lore.tags
|
||||
{
|
||||
TagItem
|
||||
{
|
||||
tag: tag.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(Ok(Some(adventurer))) = (author_future.value())()
|
||||
{
|
||||
PostHeaderAuthor { adventurer: adventurer }
|
||||
}
|
||||
else
|
||||
{
|
||||
p { "Loading author..." }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Story(text: String) -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
div { dangerous_inner_html: "{text}" }
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn BlogPost(slug: Signal<String>, children: Element) -> Element
|
||||
{
|
||||
// Run a once off server fetch of the unchanging blog data.
|
||||
let post_future = use_server_future(move ||
|
||||
{
|
||||
// Make this reactive so that as the page changes it should rerun this.
|
||||
let url_slug = slug();
|
||||
|
||||
async move { get_blog_post(url_slug).await }
|
||||
})?;
|
||||
|
||||
rsx!
|
||||
{
|
||||
article
|
||||
{
|
||||
class: "blog_post_style",
|
||||
|
||||
if let Some(Ok(tale)) = (post_future.value())()
|
||||
{
|
||||
PostHeader
|
||||
{
|
||||
tale: tale.clone()
|
||||
}
|
||||
|
||||
Story { text: tale.story }
|
||||
|
||||
|
||||
//Author {}
|
||||
}
|
||||
else if let Some(Err(e)) = (post_future.value())()
|
||||
{
|
||||
p { "Unable to load desired post: {slug.read()}" }
|
||||
p { "{e}" }
|
||||
}
|
||||
else
|
||||
{
|
||||
p { "Loading..." }
|
||||
}
|
||||
|
||||
{children}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn TagNav() -> Element
|
||||
{
|
||||
let tags = use_server_future(move || async move { get_tags().await })?;
|
||||
|
||||
rsx!
|
||||
{
|
||||
section
|
||||
{
|
||||
class: "blog_nav_style",
|
||||
div
|
||||
{
|
||||
class: "tag_style",
|
||||
h2 { "Categories" }
|
||||
ul
|
||||
{
|
||||
class: "tag_list",
|
||||
if let Some(Ok(categories)) = &*tags.read()
|
||||
{
|
||||
for tag in categories
|
||||
{
|
||||
li
|
||||
{
|
||||
key: "{tag}",
|
||||
class: "tag_item",
|
||||
Link
|
||||
{
|
||||
to: Page::Blog { tag: tag.clone() },
|
||||
|
||||
"{tag}"
|
||||
}
|
||||
|
||||
//a { href: "/blog/{tag}", "{tag}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
else if let Some(Err(e)) = &*tags.read()
|
||||
{
|
||||
p { "Unable to show desired post." }
|
||||
p { "{e}" }
|
||||
}
|
||||
else
|
||||
{
|
||||
p { "Loading..." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
bard/src/components/tags.rs
Normal file
51
bard/src/components/tags.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::page::Page;
|
||||
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn TagItem(tag: String, style: Option<String>) -> Element
|
||||
{
|
||||
let tag_style: String = match style
|
||||
{
|
||||
None => { String::new() }
|
||||
Some(s) => { s }
|
||||
};
|
||||
|
||||
rsx!
|
||||
{
|
||||
li
|
||||
{
|
||||
key: "{tag}",
|
||||
class: "tag_item",
|
||||
|
||||
Link
|
||||
{
|
||||
class: "{tag_style}",
|
||||
|
||||
to: Page::Blog { tag: tag.clone() },
|
||||
|
||||
"{tag}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn TagList(children: Element) -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
h5
|
||||
{
|
||||
class: "blog_tag_style",
|
||||
|
||||
ul
|
||||
{
|
||||
class: "tag_list",
|
||||
{children}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user