Compare commits
2 Commits
ce80af94ee
...
3fe3d874ca
| Author | SHA1 | Date | |
|---|---|---|---|
| 3fe3d874ca | |||
| 725824003b |
1854
Cargo.lock
generated
1854
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "bard"
|
||||
version = "0.3.5"
|
||||
version = "0.3.8"
|
||||
edition = "2024"
|
||||
description = "Dioxus components that will display a Tavern blogging system Blog."
|
||||
repository = "/CyberMages/tavern"
|
||||
@ -14,12 +14,12 @@ name = "blog"
|
||||
path = "examples/blog.rs"
|
||||
|
||||
[dependencies]
|
||||
dioxus = { version = "*", features = ["router", "fullstack"] }
|
||||
dioxus = { version = "=0.7.0-rc.1", features = ["router", "fullstack"] }
|
||||
tavern = { version = "0.3.0", path = "../tavern", registry="cybermages", optional = true}
|
||||
tokio = { version = "1.0", features = ["rt", "macros"], optional = true }
|
||||
|
||||
|
||||
[features]
|
||||
default = ["web"]
|
||||
default = ["tavern"]
|
||||
web = ["tavern", "dioxus/web"]
|
||||
server = ["tavern/database", "dioxus/server", "tokio"]
|
||||
|
||||
@ -35,6 +35,9 @@
|
||||
|
||||
.blog_list
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
order: 5;
|
||||
|
||||
.blog_title
|
||||
@ -43,6 +46,13 @@
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.blog_title_image
|
||||
{
|
||||
width: 23rem;
|
||||
align-self: center;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.blog_item
|
||||
{
|
||||
margin-bottom: 30px;
|
||||
@ -51,6 +61,16 @@
|
||||
{
|
||||
margin: 0px;
|
||||
color: var(--accent-color);
|
||||
|
||||
a:link, a:visited
|
||||
{
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
|
||||
p
|
||||
@ -140,7 +160,7 @@
|
||||
order: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 70px;
|
||||
margin-top: 185px;
|
||||
margin-right: 70px;
|
||||
position:sticky;
|
||||
top: 150px;
|
||||
|
||||
@ -15,12 +15,12 @@ pub fn BlogItem(title: String, slug: String, author: String, summary: String,
|
||||
tags: Vec<String>)
|
||||
-> Element
|
||||
{
|
||||
let author_future = use_server_future(move ||
|
||||
let author_future = use_resource(move ||
|
||||
{
|
||||
let handle: String = author.clone();
|
||||
|
||||
async move { get_author(handle).await }
|
||||
})?;
|
||||
});
|
||||
|
||||
rsx!
|
||||
{
|
||||
@ -80,13 +80,13 @@ pub fn BlogList(tags: Signal<HashSet<String>>, children: Element) -> Element
|
||||
// Retrieve the provided settings from context.
|
||||
let settings = use_context::<BardSettings>();
|
||||
|
||||
let list = use_server_future(move ||
|
||||
let list = use_resource(move ||
|
||||
{
|
||||
let t = tags();
|
||||
let categories = t.iter().cloned().collect();
|
||||
let tags = tags();
|
||||
let categories: Vec<String> = tags.iter().cloned().collect();
|
||||
|
||||
async move { get_blog_list(categories).await }
|
||||
})?;
|
||||
});
|
||||
|
||||
rsx!
|
||||
{
|
||||
@ -94,20 +94,51 @@ pub fn BlogList(tags: Signal<HashSet<String>>, children: Element) -> Element
|
||||
{
|
||||
class: "blog_list",
|
||||
|
||||
match settings.blog_name
|
||||
match settings.blog_image
|
||||
{
|
||||
Some(title) =>
|
||||
Some(image) =>
|
||||
{
|
||||
rsx!
|
||||
match settings.blog_name
|
||||
{
|
||||
h1 { class: "blog_title", "{title}" }
|
||||
Some(title) =>
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
h1 { class: "blog_title visually_hidden", "{title}" }
|
||||
img { class: "blog_title_image", alt: "{title} blog logo", src: image }
|
||||
}
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
h1 { class: "blog_title visually_hidden", "Blog" }
|
||||
img { class: "blog_title_image", alt: "Blog logo", src: image }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
rsx!
|
||||
match settings.blog_name
|
||||
{
|
||||
h1 { class: "blog_title visually_hidden", "Blog" }
|
||||
Some(title) =>
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
h1 { class: "blog_title", "{title}" }
|
||||
}
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
h1 { class: "blog_title visually_hidden", "Blog" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,6 +149,7 @@ pub fn BlogList(tags: Signal<HashSet<String>>, children: Element) -> Element
|
||||
{
|
||||
BlogItem
|
||||
{
|
||||
key: "{lore.slug}",
|
||||
title: lore.title.clone(),
|
||||
slug: lore.slug.clone(),
|
||||
author: lore.author.clone(),
|
||||
@ -144,6 +176,7 @@ pub fn BlogList(tags: Signal<HashSet<String>>, children: Element) -> Element
|
||||
#[component]
|
||||
pub fn ToggleTag(tag: String, toggled_tags: Signal<HashSet<String>>) -> Element
|
||||
{
|
||||
let is_checked = toggled_tags.read().is_toggled(&tag);
|
||||
rsx!
|
||||
{
|
||||
label
|
||||
@ -153,7 +186,7 @@ pub fn ToggleTag(tag: String, toggled_tags: Signal<HashSet<String>>) -> Element
|
||||
input
|
||||
{
|
||||
r#type: "checkbox",
|
||||
checked: toggled_tags.read().is_toggled(&tag),
|
||||
checked: is_checked,
|
||||
onchange: move |_|
|
||||
{
|
||||
toggled_tags.write().toggle(&tag.clone());
|
||||
@ -182,7 +215,7 @@ pub fn ToggleTag(tag: String, toggled_tags: Signal<HashSet<String>>) -> Element
|
||||
// which tags should be selected based on the current URL, returning both pieces
|
||||
// of data together for clean state management.
|
||||
#[component]
|
||||
pub fn TagSelector(url_tag: ReadOnlySignal<String>,
|
||||
pub fn TagSelector(url_tag: ReadSignal<String>,
|
||||
toggled_tags: Signal<HashSet<String>>) -> Element
|
||||
{
|
||||
// Use use_resource to handle both fetching tags AND initializing selection
|
||||
|
||||
@ -53,7 +53,7 @@ pub fn PostHeader(tale: Tale) -> Element
|
||||
// Get the blog's image to use as a placeholder if there isn't one for the
|
||||
// blog post.
|
||||
// Retrieve the provided settings from context.
|
||||
let _settings = use_context::<BardSettings>();
|
||||
let settings = use_context::<BardSettings>();
|
||||
|
||||
let author_future = use_server_future(move ||
|
||||
{
|
||||
@ -73,7 +73,10 @@ pub fn PostHeader(tale: Tale) -> Element
|
||||
document::Meta { property: "og:title", content: "{tale.lore.title}" }
|
||||
document::Meta { property: "og:description", content: "{tale.lore.summary}" }
|
||||
document::Meta { property: "og:url", content: "{url}" }
|
||||
document::Meta { property: "og:image", content: "" }
|
||||
if let Some(image) = settings.default_post_image
|
||||
{
|
||||
document::Meta { property: "og:image", content: image }
|
||||
}
|
||||
|
||||
h1 { {tale.lore.title} }
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::components::{BlogList, TagSelector};
|
||||
|
||||
/// Blog page
|
||||
#[component]
|
||||
pub fn Blog(tag: ReadOnlySignal<String>) -> Element
|
||||
pub fn Blog(tag: ReadSignal<String>) -> Element
|
||||
{
|
||||
let categories: Signal<HashSet<String>> =
|
||||
use_signal(|| HashSet::new());
|
||||
|
||||
@ -6,7 +6,7 @@ use crate::components::{BlogPost, TagNav};
|
||||
|
||||
/// Blog page
|
||||
#[component]
|
||||
pub fn Post(slug: ReadOnlySignal<String>) -> Element
|
||||
pub fn Post(slug: ReadSignal<String>) -> Element
|
||||
{
|
||||
// Create a copy of the current slug to detect changes.
|
||||
let url_slug = use_signal(|| slug());
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum StylesheetBehavior
|
||||
{
|
||||
@ -23,6 +24,13 @@ pub struct BardSettings
|
||||
/// it is still available for screen readers.
|
||||
pub blog_name: Option<String>,
|
||||
|
||||
/// The image to use for the blog title instead of just the name.
|
||||
pub blog_image: Option<Asset>,
|
||||
|
||||
/// The image to use for the default post image in open graph. This is what
|
||||
/// is shown when sharing the article.
|
||||
pub default_post_image: Option<Asset>,
|
||||
|
||||
/// A user defined stylesheet and how the library should include it.
|
||||
pub stylesheet: StylesheetBehavior
|
||||
}
|
||||
|
||||
@ -1,23 +1,22 @@
|
||||
[package]
|
||||
name = "blog_test"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
authors = ["Myrddin Dundragon <myrddin@cybermages.tech>"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
axum = { version = "0.7.0", optional = true }
|
||||
axum-server = { version = "0.7.1", optional = true }
|
||||
dioxus = { version = "*", features = ["router", "fullstack"] }
|
||||
dioxus-cli-config = { version = "*", optional = true }
|
||||
axum = { version = "0.8.4", optional = true }
|
||||
axum-server = { version = "0.7.2", optional = true }
|
||||
dioxus = { version = "=0.7.0-rc.1", features = ["router", "fullstack"] }
|
||||
bard = { version = "*", path="../bard", optional = true }
|
||||
tokio = { version = "1.0", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["web"]
|
||||
web = ["dioxus/web", "bard"]
|
||||
server = ["dioxus/server", "axum", "axum-server", "tokio/rt-multi-thread", "tokio/macros", "dioxus-cli-config", "bard/server"]
|
||||
default = ["bard"]
|
||||
web = ["dioxus/web", "bard/web"]
|
||||
server = ["dioxus/server", "axum", "axum-server", "tokio/rt-multi-thread", "tokio/macros", "bard/server"]
|
||||
|
||||
[profile.wasm-dev]
|
||||
inherits = "dev"
|
||||
|
||||
BIN
blog_test/assets/runes_and_ramblings_logo.png
Normal file
BIN
blog_test/assets/runes_and_ramblings_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1019 KiB |
BIN
blog_test/assets/runes_and_ramblings_text.png
Normal file
BIN
blog_test/assets/runes_and_ramblings_text.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 335 KiB |
@ -6,6 +6,10 @@ use bard::*;
|
||||
|
||||
const FAVICON: Asset = asset!("/assets/favicon.ico");
|
||||
const BLOG: Asset = asset!("/assets/blog.css");
|
||||
const BLOG_IMAGE: Asset = asset!("/assets/runes_and_ramblings_text.png",
|
||||
AssetOptions::builder().with_hash_suffix(false));
|
||||
const POST_IMAGE: Asset = asset!("/assets/runes_and_ramblings_logo.png",
|
||||
AssetOptions::builder().with_hash_suffix(false));
|
||||
|
||||
|
||||
|
||||
@ -13,13 +17,16 @@ fn main()
|
||||
{
|
||||
#[cfg(feature = "server")]
|
||||
{
|
||||
let _ = tokio::runtime::Runtime::new()
|
||||
.unwrap()
|
||||
.block_on(async move { bard::init_database("/home/myrddin/cybermages/website/tavern.db").await });
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async
|
||||
{
|
||||
let db_path = "/home/myrddin/cybermages/website/tavern.db";
|
||||
|
||||
let _ = bard::init_database(db_path).await;
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "web")]
|
||||
dioxus::launch(App);
|
||||
LaunchBuilder::new().launch(App);
|
||||
}
|
||||
|
||||
#[component]
|
||||
@ -28,6 +35,8 @@ fn App() -> Element
|
||||
let custom_settings = BardSettings
|
||||
{
|
||||
blog_name: Some(String::from("Blog Test")),
|
||||
blog_image: Some(BLOG_IMAGE),
|
||||
default_post_image: Some(POST_IMAGE),
|
||||
stylesheet: StylesheetBehavior::Extend(BLOG),
|
||||
};
|
||||
provide_context(custom_settings);
|
||||
|
||||
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly"
|
||||
Reference in New Issue
Block a user