Added toggle for dark mode, changed font to OpenDyslexic, details now changes label on open/close.
This commit is contained in:
parent
4fcb8972ff
commit
dfeb15394a
Binary file not shown.
BIN
public/fonts/OpenDyslexic-Bold.otf
Normal file
BIN
public/fonts/OpenDyslexic-Bold.otf
Normal file
Binary file not shown.
BIN
public/fonts/OpenDyslexic-BoldItalic.otf
Normal file
BIN
public/fonts/OpenDyslexic-BoldItalic.otf
Normal file
Binary file not shown.
BIN
public/fonts/OpenDyslexic-Italic.otf
Normal file
BIN
public/fonts/OpenDyslexic-Italic.otf
Normal file
Binary file not shown.
BIN
public/fonts/OpenDyslexic-Regular.otf
Normal file
BIN
public/fonts/OpenDyslexic-Regular.otf
Normal file
Binary file not shown.
BIN
public/images/black_square_button.png
Normal file
BIN
public/images/black_square_button.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 158 B |
BIN
public/images/white_square_button.png
Normal file
BIN
public/images/white_square_button.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 158 B |
2
public/styles/tailwind.min.css
vendored
2
public/styles/tailwind.min.css
vendored
File diff suppressed because one or more lines are too long
@ -7,7 +7,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
{{{style_include}}}
|
||||
</head>
|
||||
<body>
|
||||
<body class="{{dark_mode}}">
|
||||
<div id="main">{{{test}}}</div>
|
||||
</body>
|
||||
</html>
|
@ -8,14 +8,24 @@ extern crate rocket;
|
||||
/// A module that handles the backend for the site.
|
||||
pub mod web_app_backend {
|
||||
|
||||
use std::path::{PathBuf, Path};
|
||||
|
||||
use rocket::fs::FileServer;
|
||||
use rocket::http::{Cookie, CookieJar};
|
||||
use rocket::response::Redirect;
|
||||
use rocket::{Build, Rocket};
|
||||
use rocket_dyn_templates::{context, Template};
|
||||
use void_fe::void_app::{self, PoemRequest, VirtualDom};
|
||||
use void_fe::void_app::{self, PoemRequest, VirtualDom, HomeProps};
|
||||
|
||||
#[get("/")]
|
||||
async fn index() -> Template {
|
||||
let mut vdom = VirtualDom::new(void_app::HomePage);
|
||||
async fn index(cookies: &CookieJar<'_>) -> Template {
|
||||
let dark_mode = match cookies.get("dark-mode") {
|
||||
Some(_) => true,
|
||||
None => false,
|
||||
};
|
||||
let mut vdom = VirtualDom::new_with_props(void_app::HomePage, HomeProps {
|
||||
dark_mode: dark_mode,
|
||||
});
|
||||
let _ = vdom.rebuild();
|
||||
let output = dioxus_ssr::render(&vdom);
|
||||
Template::render(
|
||||
@ -23,17 +33,48 @@ pub mod web_app_backend {
|
||||
context! {
|
||||
app_title: "A Letter to the Void",
|
||||
style_include: "<link href=/styles/tailwind.min.css rel=stylesheet />",
|
||||
test: &output
|
||||
test: &output,
|
||||
dark_mode: match dark_mode {
|
||||
true => "dark",
|
||||
false => ""
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[get("/?set-dark-mode")]
|
||||
async fn dark_mode_root(cookies: &CookieJar<'_>) -> Redirect {
|
||||
match cookies.get("dark-mode") {
|
||||
Some(_) => cookies.remove(Cookie::named("dark-mode")),
|
||||
None => cookies.add(Cookie::new("dark-mode", "true")),
|
||||
};
|
||||
// let path_str = String::from(Path::new("/").join(path).to_str().expect("valid path"));
|
||||
// let angy = path_str.as_str().to_owned();
|
||||
Redirect::to("/")
|
||||
}
|
||||
|
||||
#[get("/poem/<entry>?set-dark-mode")]
|
||||
async fn dark_mode(cookies: &CookieJar<'_>, entry: PathBuf) -> Redirect {
|
||||
match cookies.get("dark-mode") {
|
||||
Some(_) => cookies.remove(Cookie::named("dark-mode")),
|
||||
None => cookies.add(Cookie::new("dark-mode", "true")),
|
||||
};
|
||||
let path_str = String::from(Path::new("/poem/").join(entry).to_str().expect("valid path"));
|
||||
let _angy = path_str.as_str().to_owned();
|
||||
Redirect::to(path_str.as_str().to_owned().clone())
|
||||
}
|
||||
|
||||
#[get("/poem/<entry>")]
|
||||
async fn poem(entry: &str) -> Template {
|
||||
async fn poem(cookies: &CookieJar<'_>, entry: &str) -> Template {
|
||||
let dark_mode = match cookies.get("dark-mode") {
|
||||
Some(_) => true,
|
||||
None => false,
|
||||
};
|
||||
let mut vdom = VirtualDom::new_with_props(
|
||||
void_app::PoemPage,
|
||||
PoemRequest {
|
||||
slug: entry.to_string(),
|
||||
dark_mode: Some(dark_mode),
|
||||
},
|
||||
);
|
||||
let _ = vdom.rebuild();
|
||||
@ -43,7 +84,11 @@ pub mod web_app_backend {
|
||||
context! {
|
||||
app_title: "A Letter to the Void",
|
||||
style_include: "<link href=/styles/tailwind.min.css rel=stylesheet />",
|
||||
test: &output
|
||||
test: &output,
|
||||
dark_mode: match dark_mode {
|
||||
true => "dark",
|
||||
false => ""
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -54,7 +99,7 @@ pub mod web_app_backend {
|
||||
.mount("/images", FileServer::from("public/images"))
|
||||
.mount("/styles", FileServer::from("public/styles"))
|
||||
.mount("/fonts", FileServer::from("public/fonts"))
|
||||
.mount("/", routes![index, poem])
|
||||
.mount("/", routes![dark_mode_root, index, dark_mode, poem])
|
||||
.attach(Template::fairing())
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,6 @@
|
||||
@tailwind utilities;
|
||||
|
||||
@font-face {
|
||||
font-family: "DejaVuSansMono";
|
||||
src: url("/fonts/DejaVuSansMono.ttf");
|
||||
font-family: "OpenDyslexic";
|
||||
src: url("/fonts/OpenDyslexic-Regular.otf");
|
||||
}
|
||||
|
@ -20,6 +20,12 @@ pub mod void_app {
|
||||
#[derive(PartialEq, Props)]
|
||||
pub struct PoemRequest {
|
||||
pub slug: String,
|
||||
pub dark_mode: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Props)]
|
||||
pub struct HomeProps {
|
||||
pub dark_mode: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Props)]
|
||||
@ -28,6 +34,7 @@ pub mod void_app {
|
||||
content: Option<String>,
|
||||
creation_date: Option<String>,
|
||||
slug: Option<String>,
|
||||
dark_mode: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
@ -57,16 +64,41 @@ pub mod void_app {
|
||||
}
|
||||
|
||||
/// Renders the app and returns the rendered Element.
|
||||
pub fn HomePage(cx: Scope) -> Element {
|
||||
pub fn HomePage(cx: Scope<HomeProps>) -> Element {
|
||||
let dark_mode = cx.props.dark_mode.clone();
|
||||
cx.render(rsx!{
|
||||
div { class: "min-h-screen font-nerd bg-alice-werefox-grey-light dark:bg-alice-werefox-grey",
|
||||
div { class: "container space-y-4 mx-auto p-4",
|
||||
div { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
|
||||
p { class: "text-lg text-center",
|
||||
"A Letter to the Void"
|
||||
p { class: "flex flex-row mx-auto max-w-full justify-center text-lg text-center",
|
||||
"A Letter to the Void "
|
||||
a { class: "max-h-sm",
|
||||
href: "?set-dark-mode",
|
||||
match dark_mode {
|
||||
true => {
|
||||
rsx! {
|
||||
img { class: "",
|
||||
src: "/images/white_square_button.png",
|
||||
alt: "A white square button that can toggle dark mode.",
|
||||
}
|
||||
}
|
||||
},
|
||||
false => {
|
||||
rsx! {
|
||||
img { class: "",
|
||||
src: "/images/black_square_button.png",
|
||||
alt: "A black square button that can toggle dark mode.",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PoemList {}
|
||||
div { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light",
|
||||
"This site uses Mutant Standard emoji, which are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -104,18 +136,20 @@ pub mod void_app {
|
||||
|
||||
#[cfg(any(target_family = "unix", target_family = "windows"))]
|
||||
pub fn PoemPage(cx: Scope<PoemRequest>) -> Element {
|
||||
let slug = cx.props.slug.clone();
|
||||
let slug = String::from(cx.props.slug.clone());
|
||||
let dark_mode = cx.props.dark_mode.clone().expect("Dark mode prop not passed.");
|
||||
cx.render(rsx!{
|
||||
div { class: "min-h-screen font-nerd bg-alice-werefox-grey-light dark:bg-alice-werefox-grey",
|
||||
div { class: "container space-y-4 mx-auto p-4",
|
||||
a { href: "/",
|
||||
div { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
|
||||
p { class: "text-lg text-center",
|
||||
"Take me back!"
|
||||
a { href: "/",
|
||||
div { class: "p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
|
||||
p { class: "text-lg text-center",
|
||||
"Take me back!"
|
||||
}
|
||||
}
|
||||
}
|
||||
GetPoem { slug: slug, dark_mode: dark_mode }
|
||||
}
|
||||
GetPoem { slug: slug } }
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -127,6 +161,7 @@ pub mod void_app {
|
||||
.segment("slug")
|
||||
.expect("No slug specified."),
|
||||
);
|
||||
let dark_mode = cx.props.dark_mode.clone().expect("Dark mode prop not passed.");
|
||||
cx.render(rsx!{
|
||||
div { class: "min-h-screen font-nerd bg-alice-werefox-grey-light dark:bg-alice-werefox-grey",
|
||||
div { class: "container space-y-4 mx-auto p-4",
|
||||
@ -137,7 +172,7 @@ pub mod void_app {
|
||||
}
|
||||
}
|
||||
}
|
||||
GetPoem { slug: slug }
|
||||
GetPoem { slug: slug, dark_mode: dark_mode }
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -174,8 +209,10 @@ pub mod void_app {
|
||||
}
|
||||
|
||||
fn GetPoem(cx: Scope<PoemData>) -> Element {
|
||||
let dark_mode = cx.props.dark_mode.clone().expect("Dark mode prop not passed.");
|
||||
let slug = String::from(cx.props.slug.clone().expect("No slug specified."));
|
||||
let filename =
|
||||
String::from(String::from(cx.props.slug.clone().expect("No slug specified.")) + ".md");
|
||||
String::from(String::from(slug.clone()) + ".md");
|
||||
let creation_date =
|
||||
String::from(String::from("<br>Written on: ") + filename.split("_").next().unwrap());
|
||||
let poem_content = Poems::get(&filename).expect("Found poem {filename:?}");
|
||||
@ -189,30 +226,76 @@ pub mod void_app {
|
||||
let poem_content_to_html_string =
|
||||
markdown::to_html_with_options(poem_content.as_str(), &Options::gfm()).unwrap();
|
||||
cx.render(rsx!{
|
||||
MakePoem{ title: poem_title_to_html_string, content: poem_content_to_html_string, creation_date: creation_date } }
|
||||
MakePoem{ title: poem_title_to_html_string, content: poem_content_to_html_string, creation_date: creation_date, slug: slug, dark_mode: dark_mode } }
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(any(target_family = "unix", target_family = "windows"))]
|
||||
fn RenderPoemTitle(cx: Scope<PoemData>) -> Element {
|
||||
let slug = cx.props.slug.clone().expect("Slug prop was not passed.");
|
||||
let dark_mode = cx.props.dark_mode.clone().expect("Dark mode prop not passed.");
|
||||
let title = cx.props.title.clone().expect("No title specified.");
|
||||
cx.render(rsx!{
|
||||
span { class: "mx-auto max-w-fit flex justify-center bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark border-4 border-alice-werefox-red-dark dark:border-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light p-4",
|
||||
"{title}"
|
||||
"{title} "
|
||||
a { class: "max-h-sm",
|
||||
href: "/poem/{slug}?set-dark-mode",
|
||||
match dark_mode {
|
||||
true => {
|
||||
rsx! {
|
||||
img { class: "",
|
||||
src: "/images/white_square_button.png",
|
||||
alt: "A white square button that can toggle dark mode.",
|
||||
}
|
||||
}
|
||||
},
|
||||
false => {
|
||||
rsx! {
|
||||
img { class: "",
|
||||
src: "/images/black_square_button.png",
|
||||
alt: "A black square button that can toggle dark mode.",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_family = "wasm")]
|
||||
fn RenderPoemTitle(cx: Scope<PoemData>) -> Element {
|
||||
let slug = cx.props.slug.clone().expect("Slug prop was not passed.");
|
||||
let dark_mode = cx.props.dark_mode.clone().expect("Dark mode prop not passed.");
|
||||
let title = cx
|
||||
.props
|
||||
.title
|
||||
.clone()
|
||||
.expect("This poem has an empty title.");
|
||||
cx.render(rsx!{
|
||||
p { class: "mx-auto max-w-fit flex justify-center bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark border-4 border-alice-werefox-red-dark dark:border-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light p-4",
|
||||
dangerous_inner_html: "{title}",
|
||||
p { class: "mx-auto max-w-fit flex flex-row justify-center bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark border-4 border-alice-werefox-red-dark dark:border-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light p-4",
|
||||
dangerous_inner_html: "{title} ",
|
||||
a { class: "max-h-sm",
|
||||
href: "/poem/{slug}?set-dark-mode",
|
||||
match dark_mode {
|
||||
true => {
|
||||
rsx! {
|
||||
img { class: "",
|
||||
src: "/images/white_square_button.png",
|
||||
alt: "A white square button that can toggle dark mode.",
|
||||
}
|
||||
}
|
||||
},
|
||||
false => {
|
||||
rsx! {
|
||||
img { class: "",
|
||||
src: "/images/black_square_button.png",
|
||||
alt: "A black square button that can toggle dark mode.",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -226,7 +309,8 @@ pub mod void_app {
|
||||
.clone()
|
||||
.expect("No creation date specified.");
|
||||
cx.render(rsx! {
|
||||
div { class: "font-nerd flex flex-col space-y-4 mx-4 py-4", "{content}{creation_date}" }
|
||||
div { class: "font-nerd flex flex-col space-y-4 mx-4 py-4", "{content}{creation_date} "
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -247,6 +331,8 @@ pub mod void_app {
|
||||
}
|
||||
|
||||
fn MakePoem(cx: Scope<PoemData>) -> Element {
|
||||
let slug = String::from(cx.props.slug.clone().expect("Slug prop was not passed."));
|
||||
let dark_mode = cx.props.dark_mode.clone().expect("Dark mode prop not passed.");
|
||||
let title = cx.props.title.clone().expect("No title specified.");
|
||||
let creation_date = cx
|
||||
.props
|
||||
@ -256,10 +342,9 @@ pub mod void_app {
|
||||
let content = cx.props.content.clone().expect("No content specified.");
|
||||
cx.render(rsx!{
|
||||
div { class: "flex-col space-y-4",
|
||||
RenderPoemTitle { title: title.clone() }
|
||||
details { class: "mx-auto max-w-fit space-y-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark border-4 border-alice-werefox-red-dark dark:border-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light p-4",
|
||||
summary { class: "flex justify-center p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
|
||||
"Open"
|
||||
RenderPoemTitle { title: title.clone(), slug: slug, dark_mode: dark_mode }
|
||||
details { class: "group mx-auto max-w-fit space-y-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark border-4 border-alice-werefox-red-dark dark:border-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light p-4",
|
||||
summary { class: "group-open:before:content-['Close'] before:content-['Open'] flex justify-center p-4 ring-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light hover:text-alice-werefox-blue-dark dark:hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue dark:hover:ring-alice-werefox-blue hover:animate-yip transition",
|
||||
}
|
||||
RenderPoemElement { content: content.clone(), creation_date: creation_date.clone() }
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ module.exports = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
nerd: ["DejaVuSansMono"],
|
||||
nerd: ["OpenDyslexic"],
|
||||
},
|
||||
colors: {
|
||||
"ada-werefox-cyan": {
|
||||
@ -105,5 +105,6 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
},
|
||||
darkMode: 'class',
|
||||
plugins: [],
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user