//! # Rust Letter Frontend //! //! Rendering functions for the site using [Dioxus](https://dioxuslabs.com/). #![allow(non_snake_case)] 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 { // import the prelude to get access to the `rsx!` macro and the `Scope` and `Element` types pub use dioxus::prelude::*; use crate::components::void_buttons::*; use crate::components::void_content::*; use crate::components::void_footer::*; use crate::components::void_page::PageBase; use crate::components::void_poem::*; use crate::components::void_title::*; use crate::utils::helpers; use crate::utils::prop_structs::*; use crate::utils::user_prefs::*; #[cfg(any(target_family = "wasm"))] use dioxus_helmet::Helmet; #[cfg(any(target_family = "wasm"))] 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 = OnceCell::new(); #[cfg(target_family = "wasm")] #[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."); rsx! { Router:: {} } } #[cfg(target_family = "wasm")] fn PageNotFound() -> Element { rsx! { p { "That page doesn't exist, sorry!" } } } #[component] /// Renders the app and returns the rendered Element. 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(); rsx! { div { class: "{user_theme} {user_font}", PageBase { Title { title: page_title, is_html: false, user_prefs: user_prefs.clone() } RenderContent { content: helpers::get_homepage_paragraph(), user_prefs: user_prefs.clone() } ButtonGroup { NavigationButton { title: "See Latest Entry".to_string(), slug: poem_database.get_latest_entry("".to_string()), user_prefs: user_prefs.clone() } NavigationButton { title: "See Oldest Entry".to_string(), slug: poem_database.get_oldest_entry("".to_string()), user_prefs: user_prefs.clone() } NavigationButton { title: "See A Random Entry".to_string(), slug: poem_database.get_random_entry(), user_prefs: user_prefs.clone() } NavigationButton { title: "See All Entries".to_string(), slug: "/poems".to_string(), user_prefs: user_prefs.clone() } } Footer { theme: user_prefs.clone().get_theme(), font: user_prefs.get_font() } } } } } /// Renders the app and returns the rendered Element. 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); 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() } BackToHomePage { theme: user_prefs.clone().get_theme(), font: user_prefs.clone().get_font() } PoemList { poem_database: poem_database.clone(), user_prefs: user_prefs.clone() } BackToHomePage { theme: user_prefs.clone().get_theme(), font: user_prefs.clone().get_font() } Footer { theme: user_prefs.clone().get_theme(), font: user_prefs.get_font() } } } } } 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 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 props.") .clone(); // #[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() } GetPoem { slug: slug.clone(), poem_database: poem_database.clone(), user_prefs: user_prefs.clone() } ButtonGroup { NavigationButton { title: "Oldest".to_string(), slug: poem_database.get_oldest_entry(slug.clone()), user_prefs: user_prefs.clone() } NavigationButton { title: "Previous".to_string(), slug: poem_database.get_previous_entry(slug.clone()), user_prefs: user_prefs.clone() } NavigationButton { title: "Random".to_string(), slug: poem_database.get_random_entry(), user_prefs: user_prefs.clone() } NavigationButton { title: "Next".to_string(), slug: poem_database.get_next_entry(slug.clone()), user_prefs: user_prefs.clone() } NavigationButton { title: "Latest".to_string(), slug: poem_database.get_latest_entry(slug.clone()), user_prefs: user_prefs.clone() } } BackToHomePage { theme: user_prefs.clone().get_theme(), font: user_prefs.clone().get_font() } Footer { theme: user_prefs.clone().get_theme(), font: user_prefs.get_font() } } } } } 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); rsx! { div { class: "{user_theme} {user_font}", PageBase { Title { title: "Settings".to_string(), is_html: false, user_prefs: user_prefs.clone() } BackToHomePage { theme: user_prefs.clone().get_theme(), font: user_prefs.clone().get_font() } div { class: "p-4 flex flex-col space-y-4 mx-auto max-w-full justify-center", div { class: "p-4 flex flex-col space-y-4 text-xl text-center ring-4 {user_theme_card} {user_font_card}", p { "Theme" } ButtonGroup { NavigationButton { title: "Light".to_string(), slug: "/settings/?theme=light".to_string(), user_prefs: user_prefs.clone() } NavigationButton { title: "Dark".to_string(), slug: "/settings/?theme=dark".to_string(), user_prefs: user_prefs.clone() } NavigationButton { title: "Auto".to_string(), slug: "/settings/?theme=auto".to_string(), user_prefs: user_prefs.clone() } } } div { class: "p-4 flex flex-col space-y-4 text-xl text-center ring-4 {user_theme_card} {user_font_card}", p { "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() } } } } BackToHomePage { theme: user_prefs.clone().get_theme(), font: user_prefs.get_font() } } } } } }