202 lines
6.5 KiB
Rust
202 lines
6.5 KiB
Rust
//! # Rust Letter Backend
|
|
//!
|
|
//! `rust_letter_be` handles the backend execution using Rocket.
|
|
|
|
#[macro_use]
|
|
extern crate rocket;
|
|
|
|
/// A module that handles the backend for the site.
|
|
pub mod web_app_backend {
|
|
|
|
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, DarkModeProps, PoemRequest, VirtualDom};
|
|
|
|
#[get("/")]
|
|
async fn index(cookies: &CookieJar<'_>) -> Template {
|
|
let dark_mode = match cookies.get("dark-mode") {
|
|
Some(c) => {
|
|
if c.value() == "true" {
|
|
true
|
|
} else if c.value() == "false" {
|
|
false
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
None => false,
|
|
};
|
|
let mut vdom = VirtualDom::new_with_props(
|
|
void_app::HomePage,
|
|
DarkModeProps {
|
|
slug: Some(String::new()),
|
|
dark_mode,
|
|
},
|
|
);
|
|
let _ = vdom.rebuild();
|
|
let output = dioxus_ssr::render(&vdom);
|
|
Template::render(
|
|
"index",
|
|
context! {
|
|
app_title: "A Letter to the Void",
|
|
style_include: "<link href=/styles/tailwind.min.css rel=stylesheet />",
|
|
test: &output,
|
|
dark_mode: match dark_mode {
|
|
true => "dark",
|
|
false => ""
|
|
},
|
|
},
|
|
)
|
|
}
|
|
|
|
#[get("/toggle-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")),
|
|
};
|
|
Redirect::to("/")
|
|
}
|
|
|
|
#[get("/")]
|
|
async fn poem_list(cookies: &CookieJar<'_>) -> Template {
|
|
let dark_mode = match cookies.get("dark-mode") {
|
|
Some(c) => {
|
|
if c.value() == "true" {
|
|
true
|
|
} else if c.value() == "false" {
|
|
false
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
None => false,
|
|
};
|
|
let mut vdom = VirtualDom::new_with_props(
|
|
void_app::PoemListPage,
|
|
DarkModeProps {
|
|
slug: Some(String::from("/poems")),
|
|
dark_mode,
|
|
},
|
|
);
|
|
let _ = vdom.rebuild();
|
|
let output = dioxus_ssr::render(&vdom);
|
|
Template::render(
|
|
"index",
|
|
context! {
|
|
app_title: "A Letter to the Void",
|
|
style_include: "<link href=/styles/tailwind.min.css rel=stylesheet />",
|
|
test: &output,
|
|
dark_mode: match dark_mode {
|
|
true => "dark",
|
|
false => ""
|
|
},
|
|
},
|
|
)
|
|
}
|
|
|
|
#[get("/toggle-dark-mode")]
|
|
async fn poems_dark_mode(cookies: &CookieJar<'_>) -> Redirect {
|
|
match cookies.get("dark-mode") {
|
|
Some(_) => cookies.remove(Cookie::named("dark-mode")),
|
|
None => cookies.add(Cookie::new("dark-mode", "true")),
|
|
};
|
|
Redirect::to("/poems/")
|
|
}
|
|
|
|
#[get("/<entry>/toggle-dark-mode")]
|
|
async fn entry_dark_mode(cookies: &CookieJar<'_>, entry: &str) -> Redirect {
|
|
match cookies.get("dark-mode") {
|
|
Some(_) => cookies.remove(Cookie::named("dark-mode")),
|
|
None => cookies.add(Cookie::new("dark-mode", "true")),
|
|
};
|
|
Redirect::to(format!("/poems/{entry}"))
|
|
}
|
|
|
|
#[get("/")]
|
|
async fn latest_entry() -> Redirect {
|
|
let slug = void_app::get_latest_entry();
|
|
let uri = String::from("/poems/".to_string() + slug.as_str());
|
|
Redirect::to(uri)
|
|
}
|
|
|
|
#[get("/")]
|
|
async fn oldest_entry() -> Redirect {
|
|
let slug = void_app::get_oldest_entry();
|
|
let uri = String::from("/poems/".to_string() + slug.as_str());
|
|
Redirect::to(uri)
|
|
}
|
|
|
|
#[get("/?<current>")]
|
|
async fn previous_entry(current: &str) -> Redirect {
|
|
let previous =
|
|
void_app::get_previous_entry(current.to_string()).expect("There is a previous entry.");
|
|
let uri = String::from("/poems/".to_string() + previous.as_str());
|
|
Redirect::to(uri)
|
|
}
|
|
|
|
#[get("/?<current>")]
|
|
async fn next_entry(current: &str) -> Redirect {
|
|
let next = void_app::get_next_entry(current.to_string()).expect("There is a next entry.");
|
|
let uri = String::from("/poems/".to_string() + next.as_str());
|
|
Redirect::to(uri)
|
|
}
|
|
|
|
#[get("/<entry>")]
|
|
async fn poem(cookies: &CookieJar<'_>, entry: &str) -> Template {
|
|
let dark_mode = match cookies.get("dark-mode") {
|
|
Some(c) => {
|
|
if c.value() == "true" {
|
|
true
|
|
} else if c.value() == "false" {
|
|
false
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
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();
|
|
let output = dioxus_ssr::render(&vdom);
|
|
Template::render(
|
|
"index",
|
|
context! {
|
|
app_title: "A Letter to the Void",
|
|
style_include: "<link href=/styles/tailwind.min.css rel=stylesheet />",
|
|
test: &output,
|
|
dark_mode: match dark_mode {
|
|
true => "dark",
|
|
false => ""
|
|
},
|
|
},
|
|
)
|
|
}
|
|
|
|
/// This runs `rocket::build()` with the needed mounts and routes.
|
|
pub async fn build_rocket() -> Rocket<Build> {
|
|
rocket::build()
|
|
.mount("/images", FileServer::from("public/images"))
|
|
.mount("/styles", FileServer::from("public/styles"))
|
|
.mount("/fonts", FileServer::from("public/fonts"))
|
|
.mount("/poems/oldest", routes![oldest_entry])
|
|
.mount("/poems/previous", routes![previous_entry])
|
|
.mount("/poems/next", routes![next_entry])
|
|
.mount("/poems/latest", routes![latest_entry])
|
|
.mount(
|
|
"/poems",
|
|
routes![poems_dark_mode, poem_list, entry_dark_mode, poem],
|
|
)
|
|
.mount("/", routes![dark_mode_root, index])
|
|
.attach(Template::fairing())
|
|
}
|
|
}
|