Compare commits

...

2 Commits

17 changed files with 277 additions and 208 deletions

View File

@ -11,13 +11,17 @@ members = [
]
[workspace.dependencies]
rocket = "=0.5.0-rc.3"
dioxus = "0.3.2"
markdown = "1.0.0-alpha.7"
dioxus-ssr = "0.3.0"
rust-embed = { version = "6.6.1" }
rocket = "=0.5.0"
dioxus = "0.5.0-alpha.0"
markdown = "1.0.0-alpha.16"
dioxus-ssr = "0.5.0-alpha.0"
rust-embed = { version = "8.3.0" }
once_cell = "1.17.1"
[dependencies]
void-be = { path = "./void-be" }
rocket = { workspace = true }
[dependencies.dioxus]
version = "0.5.0-alpha.0"
features = ["router"]

File diff suppressed because one or more lines are too long

View File

@ -16,5 +16,5 @@ rocket = { workspace = true }
# Needed to enable handlebar template support
[dependencies.rocket_dyn_templates]
version = "=0.1.0-rc.3"
version = "=0.1.0"
features = ["handlebars"]

View File

@ -14,9 +14,11 @@ pub mod web_app_backend {
use rocket::response::Redirect;
use rocket::{Build, Rocket};
use rocket_dyn_templates::{context, Template};
use void_fe::utils::prop_structs::{PoemDatabase, VoidProps};
use void_fe::utils::prop_structs::{PoemDatabase, VoidProps, ContentProps};
use void_fe::utils::user_prefs::*;
use void_fe::void_app::{self, VirtualDom};
pub use void_fe::components::void_content::RenderContent;
use void_fe::utils::helpers::get_homepage_paragraph;
static POEM_DATABASE: OnceCell<PoemDatabase> = OnceCell::new();
@ -27,7 +29,7 @@ pub mod web_app_backend {
"light" => ThemePref::Light,
"dark" => ThemePref::Dark,
_ => {
cookies.remove(Cookie::named("theme"));
cookies.remove("theme");
cookies.add(Cookie::new("theme", "auto"));
ThemePref::Auto
}
@ -42,7 +44,7 @@ pub mod web_app_backend {
"nerd" => FontPref::NerdFont,
"open" => FontPref::OpenDyslexic,
_ => {
cookies.remove(Cookie::named("font"));
cookies.remove("font");
cookies.add(Cookie::new("font", "open"));
FontPref::OpenDyslexic
}
@ -57,7 +59,7 @@ pub mod web_app_backend {
async fn set_user_theme(cookies: &CookieJar<'_>, theme: &str) {
if theme == "light" || theme == "dark" || theme == "auto" {
cookies.remove(Cookie::named("theme"));
cookies.remove("theme");
cookies.add(Cookie::new("theme", format!("{theme}")));
} else {
return;
@ -66,7 +68,7 @@ pub mod web_app_backend {
async fn set_user_font(cookies: &CookieJar<'_>, font: &str) {
if font == "nerd" || font == "open" {
cookies.remove(Cookie::named("font"));
cookies.remove("font");
cookies.add(Cookie::new("font", format!("{font}")));
} else {
return;
@ -84,8 +86,13 @@ pub mod web_app_backend {
.clone(),
user_prefs: user_prefs,
};
let mut vdom = VirtualDom::new_with_props(void_app::HomePage, void_props);
let _ = vdom.rebuild();
// let content_props = ContentProps {
// content: get_homepage_paragraph(),
// user_prefs: user_prefs
// };
// let mut vdom = VirtualDom::new_with_props(void_app::HomePage, void_props);
let mut vdom = VirtualDom::new_with_props(void_app::HomePage, void_fe::void_app::HomePageProps { props: void_props });
let _ = vdom.rebuild_in_place();
let output = dioxus_ssr::render(&vdom);
Template::render(
"index",
@ -102,7 +109,7 @@ pub mod web_app_backend {
async fn settings(cookies: &CookieJar<'_>) -> Template {
let user_prefs = get_user_prefs(cookies).await;
let mut vdom = VirtualDom::new_with_props(void_app::SettingsPage, user_prefs);
let _ = vdom.rebuild();
let _ = vdom.rebuild_in_place();
let output = dioxus_ssr::render(&vdom);
Template::render(
"index",
@ -139,7 +146,7 @@ pub mod web_app_backend {
user_prefs: user_prefs,
};
let mut vdom = VirtualDom::new_with_props(void_app::PoemListPage, void_props);
let _ = vdom.rebuild();
let _ = vdom.rebuild_in_place();
let output = dioxus_ssr::render(&vdom);
Template::render(
"index",
@ -164,7 +171,7 @@ pub mod web_app_backend {
user_prefs: user_prefs,
};
let mut vdom = VirtualDom::new_with_props(void_app::PoemPage, void_props);
let _ = vdom.rebuild();
let _ = vdom.rebuild_in_place();
let output = dioxus_ssr::render(&vdom);
Template::render(
"index",

View File

@ -2,15 +2,18 @@
"rust-analyzer.cargo.extraArgs": ["--profile", "rust-analyzer"],
// "rust-analyzer.cargo.buildScripts.invocationLocation": "root",
"rust-analyzer.cargo.target": "wasm32-unknown-unknown",
// "rust-analyzer.cargo.buildScripts.overrideCommand": ["dioxus", "build"],
"rust-analyzer.check.overrideCommand": ["cargo", "check", "--quiet", "--message-format=json"],
"rust-analyzer.cargo.buildScripts.overrideCommand": ["dx", "build"],
"rust-analyzer.check.overrideCommand": ["dx", "check", "--quiet", "--message-format=json"],
"rust-analyzer.check.invocationLocation": "root",
"rust-analyzer.check.targets": ["wasm32-unknown-unknown", "x86_64-unknown-linux-gnu"],
// "rust-analyzer.runnables.command": "dioxus serve",
"rust-analyzer.check.targets": ["wasm32-unknown-unknown"],
"rust-analyzer.runnables.command": "dx serve",
"rust-analyzer.cargo.buildScripts.enable": false,
"rust-analyzer.linkedProjects": [
"./Cargo.toml"
],
"rust-analyzer.diagnostics.disabled": ["unresolved-proc-macro"],
// "rust-analyzer.procMacro.enable": true,
// "rust-analyzer.procMacro.attributes.enable": true,
"rust-analyzer.showUnlinkedFileNotification": false,
"rust-analyzer.hover.actions.run.enable": true,
"rust-analyzer.hover.actions.debug.enable": true,

View File

@ -7,30 +7,36 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dioxus = { workspace = true }
# dioxus = { workspace = true }
markdown = { workspace = true }
dioxus-web = "0.3.1"
dioxus-autofmt = "0.3.0"
once_cell = { workspace = true }
# dioxus-web = "0.5.0-alpha.0"
dioxus-autofmt = "0.5.0-alpha.0"
# WebAssembly Debug
wasm-logger = "0.2.0"
console_error_panic_hook = "0.1.7"
log = "0.4.17"
dioxus-helmet = "0.2.4"
dioxus-use-storage = "0.3.0"
dioxus-use-storage = "0.3.1"
rand = "0.8.5"
dioxus-html-macro = "0.3.0"
[dependencies.getrandom]
version = "0.2.9"
version = "0.2.12"
features = ["js"]
[dependencies.serde]
version = "1.0.160"
version = "1.0.197"
features = ["derive"]
[dependencies.dioxus-router]
version = "0.3.0"
features = ["query", "web"]
version = "0.5.0-alpha.0"
features = ["web"]
[dependencies.rust-embed]
version = "6.6.1"
version = "8.3.0"
features = ["debug-embed"]
[dependencies.dioxus]
version = "0.5.0-alpha.0"
features = ["web"]

View File

@ -1,72 +1,73 @@
use crate::utils::prop_structs::PoemDatabase;
use super::super::utils::{
prop_structs::{ButtonProps, ContentChildren},
prop_structs::{ButtonProps, ContentChildren, VoidProps},
user_prefs::{ThemedComponent, UserPrefs},
};
use dioxus::prelude::*;
use dioxus_router::prelude::*;
#[cfg(target_family = "wasm")]
use dioxus_router::Link;
pub fn BackToHomePage(cx: Scope<UserPrefs>) -> Element {
let (user_theme, user_font) = cx.props.clone().get_pref_classes(ThemedComponent::Button);
pub fn BackToHomePage(props: UserPrefs) -> Element {
let (user_theme, user_font) = props.clone().get_pref_classes(ThemedComponent::Button);
#[cfg(any(target_family = "windows", target_family = "unix"))]
return cx.render(rsx!{
return rsx! {
a { class: "flex justify-center p-4 text-xl text-center ring-2 hover:animate-yip transition {user_theme} {user_font}",
href: "/",
p {
"Back to the homepage"
}
}
});
};
let mut poem_database = PoemDatabase::new();
poem_database.build_poem_database();
#[cfg(target_family = "wasm")]
return cx.render(rsx!{
return render! {
Link { class: "flex justify-center p-4 text-xl text-center ring-2 hover:animate-yip transition {user_theme} {user_font}",
to: "/",
to: crate::void_app::Route::HomePage { props:VoidProps{slug: Some("/".to_string()), poem_database: poem_database.clone(), user_prefs: props.clone(),}},
p {
"Back to the homepage"
}
}
});
};
}
pub fn NavigationButton(cx: Scope<ButtonProps>) -> Element {
let (user_theme, mut user_font) = cx
.props
pub fn NavigationButton(props: ButtonProps) -> Element {
let (user_theme, mut user_font) = props
.user_prefs
.clone()
.get_pref_classes(ThemedComponent::Button);
let title = cx.props.title.clone();
let title = props.title.clone();
let title_ref = title.as_str();
let slug = cx.props.slug.clone();
let slug = props.slug.clone();
let slug_ref = slug.as_str();
match &cx.props.override_font {
match props.override_font {
Some(font) => user_font = font.clone(),
None => (),
}
#[cfg(any(target_family = "windows", target_family = "unix"))]
return cx.render(rsx!{
return rsx! {
a { class: "flex basis-full justify-center p-4 ml-2 mr-2 text-xl text-center ring-2 hover:animate-yip transition {user_theme} {user_font}",
href: "{slug_ref}",
"{title_ref}"
dangerous_inner_html: "{title_ref}",
}
});
};
#[cfg(target_family = "wasm")]
return cx.render(rsx!{
return rsx! {
Link { class: "flex basis-full justify-center p-4 ml-2 mr-2 text-xl text-center ring-2 hover:animate-yip transition {user_theme} {user_font}",
to: "{slug_ref}",
div {
dangerous_inner_html: "{title_ref}",
}
}
});
};
}
pub fn ButtonGroup<'a>(cx: Scope<'a, ContentChildren<'a>>) -> Element {
cx.render(rsx! {
pub fn ButtonGroup(props: ContentChildren) -> Element {
rsx! {
div { class: "flex md:flex-row md:space-y-0 flex-col space-y-4",
&cx.props.children
{props.children}
}
})
}
}

View File

@ -1,21 +1,14 @@
// Might wanna move stuff form `void_poem.rs` into here...
use crate::utils::prop_structs::{ContentProps};
use super::super::utils::user_prefs::ThemedComponent;
use crate::utils::prop_structs::ContentProps;
use dioxus::prelude::*;
pub fn RenderContent(cx: Scope<ContentProps>) -> Element {
let (user_theme, user_font) = cx.props.user_prefs.get_pref_classes(ThemedComponent::Card);
let content = &cx.props.content;
#[cfg(any(target_family = "windows", target_family = "unix"))]
return cx.render(rsx!{
div { class: "flex p-4 md:pl-8 md:pr-8 ml-4 mr-4 text-md text-center ring-4 {user_theme} {user_font}",
"{content}",
}
});
#[cfg(target_family = "wasm")]
return cx.render(rsx!{
pub fn RenderContent(props: ContentProps) -> Element {
let (user_theme, user_font) = props.user_prefs.get_pref_classes(ThemedComponent::Card);
let content = props.content;
return rsx! {
div { class: "flex p-4 md:pl-8 md:pr-8 ml-4 mr-4 text-md text-center ring-4 {user_theme} {user_font}",
dangerous_inner_html: "{content}",
}
});
};
}

View File

@ -4,17 +4,17 @@ use crate::{
};
use dioxus::prelude::*;
pub fn Footer(cx: Scope<UserPrefs>) -> Element {
cx.render(rsx! {
MutantStandardFooter { theme: cx.props.clone().get_theme(), font: cx.props.clone().get_font() }
})
pub fn Footer(props: UserPrefs) -> Element {
rsx! {
MutantStandardFooter { theme: props.clone().get_theme(), font: props.clone().get_font() }
}
}
fn MutantStandardFooter(cx: Scope<UserPrefs>) -> Element {
let user_prefs = UserPrefs::new(cx.props.clone().get_theme(), cx.props.clone().get_font());
let user_theme = cx.props.get_theme_classes(ThemedComponent::Card);
let user_font = cx.props.get_font_class();
cx.render(rsx!{
fn MutantStandardFooter(props: UserPrefs) -> Element {
let user_prefs = UserPrefs::new(props.clone().get_theme(), props.clone().get_font());
let user_theme = props.get_theme_classes(ThemedComponent::Card);
let user_font = props.get_font_class();
rsx! {
div { class: "p-4 flex flex-col space-y-4 mx-auto max-w-full justify-center ring-4 {user_theme} {user_font}",
ButtonGroup{
NavigationButton { title: "⚙️ Settings".to_string(), slug: "/settings".to_string(), user_prefs: user_prefs.clone() }
@ -24,5 +24,5 @@ fn MutantStandardFooter(cx: Scope<UserPrefs>) -> Element {
"This site uses Mutant Standard emoji, which are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License"
}
}
})
}
}

View File

@ -1,13 +1,13 @@
use crate::utils::prop_structs::PageChildren;
use dioxus::prelude::*;
pub fn PageBase<'a>(cx: Scope<'a, PageChildren<'a>>) -> Element {
cx.render(rsx! {
pub fn PageBase(props: PageChildren) -> Element {
rsx! {
span { hidden: true,
a { rel: "me", href: "https://yiff.life/@werefox", "Mastodon" }
}
div { class: "min-h-screen",
div { class: "container space-y-4 pt-4 pb-4 max-w-3xl", &cx.props.children }
div { class: "container space-y-4 pt-4 pb-4 max-w-3xl", {props.children} }
}
})
}
}

View File

@ -4,57 +4,54 @@ use crate::utils::prop_structs::VoidProps;
use crate::utils::{prop_structs::PoemChildren, user_prefs::ThemedComponent};
use dioxus::prelude::*;
pub fn PoemList(cx: Scope<VoidProps>) -> Element {
let poem_list = cx.props.poem_database.get_poem_list();
cx.render(rsx! {
pub fn PoemList(props: VoidProps) -> Element {
let poem_list = props.poem_database.get_poem_list();
rsx! {
ul { class: "flex flex-col space-y-4",
poem_list.into_iter().map(|p| {
{poem_list.into_iter().map(|p| {
let slug = format!("/poems/{}", p.0);
rsx!{
NavigationButton { title: p.1, slug: slug, user_prefs: cx.props.user_prefs.clone() }
NavigationButton { title: p.1, slug: slug, user_prefs: props.user_prefs.clone() }
}
})
})}
}
})
}
}
pub fn MakePoem<'a>(cx: Scope<'a, PoemChildren<'a>>) -> Element {
cx.render(rsx! {
pub fn MakePoem(props: PoemChildren) -> Element {
rsx! {
div { class: "flex-col space-y-4",
&cx.props.children
{props.children}
}
})
}
}
pub fn GetPoem(cx: Scope<VoidProps>) -> Element {
let poem_database = &cx.props.poem_database;
let slug = String::from(&cx.props.slug.clone().expect("No slug specified."));
pub fn GetPoem(props: VoidProps) -> Element {
let poem_database = props.poem_database;
let slug = String::from(props.slug.clone().expect("No slug specified."));
let poem_struct = poem_database.get_poem(slug.clone());
cx.render(rsx! {
Title { title: poem_struct.title.clone(), is_html: true, user_prefs: cx.props.user_prefs.clone() }
rsx! {
Title { title: poem_struct.title.clone(), is_html: true, user_prefs: props.user_prefs.clone() }
MakePoem{
PoemContent { slug: slug, poem_database: poem_database.clone(), user_prefs: cx.props.user_prefs.clone() }
PoemContent { slug: slug, poem_database: poem_database.clone(), user_prefs: props.user_prefs.clone() }
}
})
}
}
pub fn PoemContent(cx: Scope<VoidProps>) -> Element {
let (user_theme, user_font) = cx.props.user_prefs.get_pref_classes(ThemedComponent::Card);
let slug = cx
.props
pub fn PoemContent(props: VoidProps) -> Element {
let (user_theme, user_font) = props.user_prefs.get_pref_classes(ThemedComponent::Card);
let slug = props
.slug
.as_ref()
.expect("Received slug for poem selection.");
let content = &cx
.props
let content = props
.poem_database
.poem_hashmap
.get(slug)
.expect("Grabbed poem stuct from databse.")
.content
.clone();
let creation_date = &cx
.props
let creation_date = props
.poem_database
.poem_hashmap
.get(slug)
@ -63,18 +60,18 @@ pub fn PoemContent(cx: Scope<VoidProps>) -> Element {
.clone();
let publish_string = "\u{003C}br\u{003E}\u{003C}br\u{003E}\u{003C}br\u{003E}Published: ";
#[cfg(any(target_family = "unix", target_family = "windows"))]
return cx.render(rsx! {
return rsx! {
div { class: "flex p-2 mx-auto max-w-full justify-center",
details { class: "group p-4 max-w-fit space-y-4 ring-4 {user_theme} {user_font}",
summary { class: "group-open:before:content-['Close'] before:content-['Open'] flex justify-center p-2 hover:animate-yip transition ring-2 {user_theme} {user_font}",
}
div { class: "flex flex-col space-y-4 py-4 ml-4 mr-4", "{content}{publish_string}{creation_date}"
div { class: "flex flex-col space-y-4 py-4 ml-4 mr-4", dangerous_inner_html: "{content}{publish_string}{creation_date}"
}
}
}
});
};
#[cfg(target_family = "wasm")]
return cx.render(rsx! {
return rsx! {
div { class: "flex p-2 mx-auto max-w-full justify-center",
details { class: "group p-4 max-w-fit space-y-4 ring-4 {user_theme} {user_font}",
summary { class: "group-open:before:content-['Close'] before:content-['Open'] flex justify-center p-2 hover:animate-yip transition ring-2 {user_theme} {user_font}",
@ -84,5 +81,5 @@ pub fn PoemContent(cx: Scope<VoidProps>) -> Element {
}
}
}
});
};
}

View File

@ -2,40 +2,40 @@ use crate::utils::prop_structs::TitleProps;
use super::super::utils::user_prefs::ThemedComponent;
use dioxus::prelude::*;
pub fn Title(cx: Scope<TitleProps>) -> Element {
let user_prefs = cx.props.user_prefs.clone();
pub fn Title(props: TitleProps) -> Element {
let user_prefs = props.user_prefs.clone();
let title_classes = user_prefs.get_theme_classes(ThemedComponent::Card);
let title = cx.props.title.clone();
let is_html = cx.props.is_html;
cx.render(rsx!{
let title = props.title.clone();
let is_html = props.is_html;
rsx!{
div { class: "p-4 ring-4 {title_classes}",
span { class: "flex flex-row mx-auto max-w-full justify-center text-xl text-center",
TitleHtml { title: title, is_html: is_html, user_prefs: user_prefs }
}
}
})
}
}
fn TitleHtml(cx: Scope<TitleProps>) -> Element {
let title = cx.props.title.clone();
if cx.props.is_html {
fn TitleHtml(props: TitleProps) -> Element {
let title = props.title.clone();
if props.is_html {
#[cfg(any(target_family = "unix", target_family = "windows"))]
return cx.render(rsx! {
return rsx! {
span { class: "flex flex-row align-middle mx-auto max-w-full justify-center",
"{title}&nbsp;"
dangerous_inner_html: "{title}&nbsp;"
}
});
};
#[cfg(target_family = "wasm")]
return cx.render(rsx! {
return rsx! {
span { class: "flex flex-row align-middle mx-auto max-w-full justify-center",
div { dangerous_inner_html: "{title}", }
}
});
};
} else {
return cx.render(rsx! {
return rsx! {
span {
"{title}"
}
});
};
}
}

View File

@ -4,9 +4,10 @@
#![allow(non_snake_case)]
mod components;
pub mod utils;
use utils::{prop_structs::PoemDatabase, user_prefs::UserPrefs};
pub mod components;
pub mod utils;
/// A module that handles the functions needed
/// to render the site.
pub mod void_app {
@ -27,45 +28,80 @@ pub mod void_app {
#[cfg(any(target_family = "wasm"))]
use dioxus_helmet::Helmet;
#[cfg(any(target_family = "wasm"))]
use dioxus_router::{Link, Redirect, Route, Router};
use dioxus_router::prelude::*;
#[cfg(any(target_family = "wasm"))]
use dioxus_use_storage::use_local_storage;
#[cfg(any(target_family = "wasm"))]
use once_cell::sync::OnceCell;
#[cfg(any(target_family = "wasm"))]
static POEM_DATABASE: OnceCell<PoemDatabase> = OnceCell::new();
#[cfg(target_family = "wasm")]
pub fn DioxusApp(cx: Scope) -> Element {
#[derive(Routable, PartialEq, Clone)]
pub enum Route {
#[route("/")]
// #[redirect("/")]//, || Route::HomePage {slug: "/".to_string(), poem_database: poem_database.clone(), user_prefs: user_prefs.clone(),})]
HomePage { props: VoidProps },
#[route("/poems")]
PoemListPage {
slug: String,
poem_database: PoemDatabase,
user_prefs: UserPrefs,
},
#[route("/poems/:slug")]
PoemPage {
slug: String,
poem_database: PoemDatabase,
user_prefs: UserPrefs,
},
#[route("/settings")]
SettingsPage { theme: ThemePref, font: FontPref },
// #[route("/settings/dark")]
// SettingsPage { theme: String, font: String },
// #[route("/settings/font")]
// SettingsPage { theme: String, font: String },
#[route("")]
PageNotFound {},
}
#[cfg(target_family = "wasm")]
pub fn DioxusApp() -> Element {
// let mut poem_database = PoemDatabase::new();
// poem_database.build_poem_database();
// let user_prefs = UserPrefs::new(ThemePref::Auto, FontPref::OpenDyslexic);
let mut poem_database = PoemDatabase::new();
poem_database.build_poem_database();
POEM_DATABASE
.set(poem_database)
.expect("Could not initialize poem database.");
let user_prefs = UserPrefs::new(ThemePref::Auto, FontPref::OpenDyslexic);
cx.render(rsx! {
Router {
Route { to: "/", HomePage { slug: "/".to_string(), poem_database: poem_database.clone(), user_prefs: user_prefs.clone(), } }
Route { to: "/poems", PoemListPage { slug: "/poems".to_string(), poem_database: poem_database.clone(), user_prefs: user_prefs.clone(), } }
Route { to: "/poems/:slug", PoemPage { slug: "".to_string(), poem_database: poem_database.clone(), user_prefs: user_prefs.clone(), } }
Route { to: "/settings", SettingsPage { theme: user_prefs.clone().get_theme(), font: user_prefs.clone().get_font() } }
Route { to: "/settings/dark", SettingsPage { theme: user_prefs.clone().get_theme(), font: user_prefs.clone().get_font() } }
Route { to: "/settings/font", SettingsPage { theme: user_prefs.clone().get_theme(), font: user_prefs.clone().get_font() } }
Route { to: "", PageNotFound {} }
}
})
rsx! {
Router::<Route> {}
}
}
#[cfg(target_family = "wasm")]
fn PageNotFound(cx: Scope) -> Element {
cx.render(rsx! {
fn PageNotFound() -> Element {
rsx! {
p { "That page doesn't exist, sorry!" }
Redirect { to: "/" }
})
}
}
#[component]
/// Renders the app and returns the rendered Element.
pub fn HomePage(cx: Scope<VoidProps>) -> Element {
let poem_database = &cx.props.poem_database;
let user_prefs = cx.props.user_prefs.clone();
pub fn HomePage(props: VoidProps) -> Element {
#[cfg(target_family = "wasm")]
let poem_database = POEM_DATABASE
.get()
.expect("Poem database is not initialized")
.clone();
#[cfg(any(target_family = "unix", target_family = "windows"))]
let poem_database = props.poem_database.clone();
let user_prefs = props.user_prefs.clone();
let (user_theme, user_font) = user_prefs.get_pref_classes(ThemedComponent::Page);
let page_title = "A Letter to the Void".to_string();
cx.render(rsx!{
rsx! {
div { class: "{user_theme} {user_font}",
PageBase {
Title { title: page_title, is_html: false, user_prefs: user_prefs.clone() }
@ -79,15 +115,21 @@ pub mod void_app {
Footer { theme: user_prefs.clone().get_theme(), font: user_prefs.get_font() }
}
}
})
}
}
/// Renders the app and returns the rendered Element.
pub fn PoemListPage(cx: Scope<VoidProps>) -> Element {
let poem_database = &cx.props.poem_database;
let user_prefs = cx.props.user_prefs.clone();
pub fn PoemListPage(props: VoidProps) -> Element {
#[cfg(target_family = "wasm")]
let poem_database = POEM_DATABASE
.get()
.expect("Poem database is not initialized")
.clone();
#[cfg(any(target_family = "unix", target_family = "windows"))]
let poem_database = props.poem_database.clone();
let user_prefs = props.user_prefs.clone();
let (user_theme, user_font) = user_prefs.get_pref_classes(ThemedComponent::Page);
cx.render(rsx! {
rsx! {
div { class: "{user_theme} {user_font}",
PageBase {
Title { title: "A Letter to the Void".to_string(), is_html: false, user_prefs: user_prefs.clone() }
@ -97,27 +139,32 @@ pub mod void_app {
Footer { theme: user_prefs.clone().get_theme(), font: user_prefs.get_font() }
}
}
})
}
}
pub fn PoemPage(cx: Scope<VoidProps>) -> Element {
let poem_database = &cx.props.poem_database;
let user_prefs = cx.props.user_prefs.clone();
let (user_theme, user_font) = user_prefs.get_pref_classes(ThemedComponent::Page);
pub fn PoemPage(props: VoidProps) -> Element {
#[cfg(target_family = "wasm")]
let poem_database = POEM_DATABASE
.get()
.expect("Poem database is not initialized")
.clone();
#[cfg(any(target_family = "unix", target_family = "windows"))]
let slug = &cx
.props
let poem_database = props.poem_database.clone();
let user_prefs = props.user_prefs.clone();
let (user_theme, user_font) = user_prefs.get_pref_classes(ThemedComponent::Page);
// #[cfg(any(target_family = "unix", target_family = "windows"))]
let slug = props
.slug
.as_ref()
.expect("A slug was given in the pops.")
.expect("A slug was given in the props.")
.clone();
#[cfg(target_family = "wasm")]
let slug = String::from(
dioxus_router::use_route(cx)
.segment("slug")
.expect("No slug specified."),
);
cx.render(rsx!{
// #[cfg(target_family = "wasm")]
// let slug = String::from(
// use_route()
// .segment("slug")
// .expect("No slug specified."),
// );
rsx! {
div { class: "{user_theme} {user_font}",
PageBase {
BackToHomePage { theme: user_prefs.clone().get_theme(), font: user_prefs.clone().get_font() }
@ -133,15 +180,15 @@ pub mod void_app {
Footer { theme: user_prefs.clone().get_theme(), font: user_prefs.get_font() }
}
}
})
}
}
pub fn SettingsPage(cx: Scope<UserPrefs>) -> Element {
let user_prefs = cx.props.clone();
pub fn SettingsPage(props: UserPrefs) -> Element {
let user_prefs = props.clone();
let (user_theme, user_font) = user_prefs.get_pref_classes(ThemedComponent::Page);
// Get rid of this and create a general card component with children.
let (user_theme_card, user_font_card) = user_prefs.get_pref_classes(ThemedComponent::Card);
cx.render(rsx! {
rsx! {
div { class: "{user_theme} {user_font}",
PageBase {
Title { title: "Settings".to_string(), is_html: false, user_prefs: user_prefs.clone() }
@ -162,14 +209,14 @@ pub mod void_app {
"Font"
}
ButtonGroup {
NavigationButton { title: "Nerd Font".to_string(), slug: "/settings/?font=nerd".to_string(), user_prefs: user_prefs.clone() override_font: "font-nerd".to_string() }
NavigationButton { title: "Open Dyslexic".to_string(), slug: "/settings/?font=open".to_string(), user_prefs: user_prefs.clone() override_font: "font-open".to_string() }
NavigationButton { title: "Nerd Font".to_string(), slug: "/settings/?font=nerd".to_string(), user_prefs: user_prefs.clone(), override_font: "font-nerd".to_string() }
NavigationButton { title: "Open Dyslexic".to_string(), slug: "/settings/?font=open".to_string(), user_prefs: user_prefs.clone(), override_font: "font-open".to_string() }
}
}
}
BackToHomePage { theme: user_prefs.clone().get_theme(), font: user_prefs.get_font() }
}
}
})
}
}
}

View File

@ -18,5 +18,5 @@ fn main() {
wasm_logger::init(wasm_logger::Config::default());
console_error_panic_hook::set_once();
dioxus_web::launch(void_app::DioxusApp);
dioxus::prelude::launch(void_app::DioxusApp);
}

View File

@ -23,6 +23,14 @@ impl PoemDatabase {
// There's no need to actually make a database yet, but maybe in the future...
#[cfg(any(target_family = "unix", target_family = "windows"))]
pub async fn build_poem_database(&mut self) {
use dioxus::dioxus_core::Component;
use markdown::CompileOptions;
let markdown_options = &mut Options::gfm();
markdown_options.compile = CompileOptions {
allow_dangerous_html: true,
..CompileOptions::default()
};
for p in Poems::iter() {
let filename = p.to_string();
let poem_content = Poems::get(&filename).expect("Found poem {filename:?}");
@ -32,7 +40,7 @@ impl PoemDatabase {
let poem_title = poem_to_str.next().expect("No title specified.");
let poem_content = poem_to_str.into_iter().collect::<Vec<&str>>().join("\n");
let poem_title_to_html_string =
markdown::to_html_with_options(poem_title, &Options::gfm()).unwrap();
markdown::to_html_with_options(poem_title, markdown_options).unwrap();
let poem_content_to_html_string =
markdown::to_html_with_options(poem_content.as_str(), &Options::gfm()).unwrap();
let mut split_filename = filename.trim_end_matches(".md").split("_");
@ -41,7 +49,7 @@ impl PoemDatabase {
self.poem_list
.push((creation_date.to_string(), slug.to_string()));
let poem_struct = PoemStruct {
title: poem_title_to_html_string.to_string(),
title: poem_title_to_html_string,
content: poem_content_to_html_string,
creation_date: creation_date.to_string(),
};

View File

@ -1,27 +1,28 @@
use std::collections::HashMap;
use crate::void_app::{Element, Props};
// use crate::void_app::{Element, Props};
use super::user_prefs::UserPrefs;
use dioxus::prelude::*;
#[derive(PartialEq, Props)]
#[derive(PartialEq, Props, Clone)]
pub struct PoemRequest {
pub slug: String,
pub user_prefs: UserPrefs,
}
#[derive(PartialEq, Props)]
#[derive(PartialEq, Props, Clone)]
pub struct TitleProps {
pub title: String,
pub is_html: bool,
pub user_prefs: UserPrefs,
}
#[derive(PartialEq, Props)]
#[derive(PartialEq, Props, Clone)]
pub struct ContentProps {
pub content: String,
pub user_prefs: UserPrefs,
}
#[derive(PartialEq, Props)]
#[derive(PartialEq, Props, Clone)]
pub struct ButtonProps {
pub title: String,
pub slug: String,
@ -29,14 +30,14 @@ pub struct ButtonProps {
pub override_font: Option<String>,
}
#[derive(PartialEq, Props)]
#[derive(Default, PartialEq, Props, Clone)]
pub struct VoidProps {
pub slug: Option<String>,
pub poem_database: PoemDatabase,
pub user_prefs: UserPrefs,
}
#[derive(PartialEq, Props, Clone, Debug)]
#[derive(Default, PartialEq, Props, Clone, Debug)]
pub struct PoemDatabase {
pub poem_list: Vec<(String, String)>,
pub poem_hashmap: HashMap<String, PoemStruct>,
@ -50,17 +51,17 @@ pub struct PoemStruct {
}
// These next three should all just be one prop.
#[derive(Props)]
pub struct PoemChildren<'a> {
pub children: Element<'a>,
#[derive(PartialEq, Props, Clone)]
pub struct PoemChildren {
pub children: Element,
}
#[derive(Props)]
pub struct PageChildren<'a> {
pub children: Element<'a>,
#[derive(PartialEq, Props, Clone)]
pub struct PageChildren {
pub children: Element,
}
#[derive(Props)]
pub struct ContentChildren<'a> {
pub children: Element<'a>,
#[derive(PartialEq, Props, Clone)]
pub struct ContentChildren {
pub children: Element,
}

View File

@ -1,20 +1,22 @@
use dioxus::prelude::*;
#[derive(PartialEq, Props, Clone)]
#[derive(Default, PartialEq, Props, Clone)]
pub struct UserPrefs {
theme: ThemePref,
font: FontPref,
}
#[derive(PartialEq, Clone)]
#[derive(Default, PartialEq, Clone)]
pub enum ThemePref {
Light,
Dark,
#[default]
Auto,
}
#[derive(PartialEq, Clone)]
#[derive(Default, PartialEq, Clone)]
pub enum FontPref {
#[default]
NerdFont,
OpenDyslexic,
}
@ -41,9 +43,9 @@ impl UserPrefs {
// class: "dark:text-alice-werefox-grey-light dark:hover:text-alice-werefox-blue-light dark:hover:ring-alice-werefox-blue"
// class: "text-alice-werefox-grey-light hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue"
const PAGE_CLASSES: &str = "bg-alice-werefox-grey-light dark:bg-alice-werefox-grey";
const CARD_CLASSES: &str = "bg-alice-werefox-grey-lightest ring-alice-werefox-red-dark text-alice-werefox-grey-dark dark:bg-alice-werefox-grey-dark dark:ring-alice-werefox-red dark:text-alice-werefox-grey-light";
const BUTTON_CLASSES: &str = "bg-alice-werefox-grey-lightest ring-alice-werefox-red-dark text-alice-werefox-grey-dark hover:text-alice-werefox-blue-dark hover:ring-alice-werefox-blue dark:bg-alice-werefox-grey-dark dark:ring-alice-werefox-red dark:text-alice-werefox-grey-light dark:hover:text-alice-werefox-blue-light dark:hover:ring-alice-werefox-blue";
const PAGE_CLASSES: &'static str = "bg-alice-werefox-grey-light dark:bg-alice-werefox-grey";
const CARD_CLASSES: &'static str = "bg-alice-werefox-grey-lightest ring-alice-werefox-red-dark text-alice-werefox-grey-dark dark:bg-alice-werefox-grey-dark dark:ring-alice-werefox-red dark:text-alice-werefox-grey-light";
const BUTTON_CLASSES: &'static str = "bg-alice-werefox-grey-lightest ring-alice-werefox-red-dark text-alice-werefox-grey-dark hover:text-alice-werefox-blue-dark hover:ring-alice-werefox-blue dark:bg-alice-werefox-grey-dark dark:ring-alice-werefox-red dark:text-alice-werefox-grey-light dark:hover:text-alice-werefox-blue-light dark:hover:ring-alice-werefox-blue";
pub fn new(theme: ThemePref, font: FontPref) -> UserPrefs {
UserPrefs { theme, font }