2023-04-07 17:16:43 -05:00
//! # Rust Letter Frontend
//!
//! Rendering functions for the site using [Dioxus](https://dioxuslabs.com/).
#![ allow(non_snake_case) ]
/// 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 ::* ;
2023-04-10 20:37:40 -05:00
use std ::collections ::VecDeque ;
2023-04-08 20:47:51 -05:00
use markdown ::{ self , Options } ;
2023-04-09 11:27:28 -05:00
use rust_embed ::RustEmbed ;
2023-04-07 17:16:43 -05:00
2023-04-08 20:47:51 -05:00
#[ cfg(any(target_family = " wasm " )) ]
2023-04-09 11:27:28 -05:00
use dioxus_helmet ::Helmet ;
#[ cfg(any(target_family = " wasm " )) ]
use dioxus_router ::{ Link , Redirect , Route , Router } ;
2023-04-07 17:16:43 -05:00
2023-04-08 12:40:57 -05:00
#[ derive(PartialEq, Props) ]
2023-04-08 20:47:51 -05:00
pub struct PoemRequest {
2023-04-09 12:34:40 -05:00
pub slug : String ,
2023-04-10 18:19:02 -05:00
pub dark_mode : Option < bool > ,
}
#[ derive(PartialEq, Props) ]
pub struct HomeProps {
pub dark_mode : bool ,
2023-04-08 12:40:57 -05:00
}
#[ derive(PartialEq, Props) ]
2023-04-08 20:47:51 -05:00
struct PoemData {
title : Option < String > ,
content : Option < String > ,
creation_date : Option < String > ,
slug : Option < String > ,
2023-04-10 18:19:02 -05:00
dark_mode : Option < bool > ,
2023-04-07 17:16:43 -05:00
}
2023-04-09 11:27:28 -05:00
2023-04-07 17:16:43 -05:00
#[ derive(RustEmbed) ]
#[ folder = " data/poems " ]
pub struct Poems ;
2023-04-08 20:47:51 -05:00
#[ cfg(target_family = " wasm " ) ]
pub fn DioxusApp ( cx : Scope ) -> Element {
2023-04-09 11:27:28 -05:00
use dioxus_router ::Redirect ;
let poem_list = get_poem_list ( ) ;
2023-04-08 20:47:51 -05:00
cx . render ( rsx! {
Router {
Route { to : " / " , HomePage { } }
2023-04-10 20:37:40 -05:00
Route { to : " /poems/:slug/ " , PoemPage { } }
2023-04-09 11:27:28 -05:00
Route { to : " " , PageNotFound { } }
2023-04-08 20:47:51 -05:00
}
} )
}
2023-04-09 11:27:28 -05:00
#[ cfg(target_family = " wasm " ) ]
fn PageNotFound ( cx : Scope ) -> Element {
cx . render ( rsx! {
p { " That page doesn't exist, sorry! " }
Redirect { to : " / " }
} )
}
2023-04-07 17:16:43 -05:00
/// Renders the app and returns the rendered Element.
2023-04-10 18:19:02 -05:00
pub fn HomePage ( cx : Scope < HomeProps > ) -> Element {
let dark_mode = cx . props . dark_mode . clone ( ) ;
2023-04-08 20:47:51 -05:00
cx . render ( rsx! {
2023-04-07 17:16:43 -05:00
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 " ,
2023-04-09 11:27:28 -05:00
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 " ,
2023-04-10 20:37:40 -05:00
p { class : " flex flex-row mx-auto max-w-full justify-center text-xl text-center " ,
2023-04-10 18:19:02 -05:00
" 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. " ,
}
}
} ,
}
}
2023-04-08 20:47:51 -05:00
}
}
2023-04-10 20:37:40 -05:00
div { class : " flex p-4 ml-6 mr-6 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 " ,
" Welcome, and I hope you enjoy your stay! "
" \" A Letter to the Void \" is a passion project of mine in which I wrote poems about my past life experiences, present, and hopes for the future throughout my transition. "
" The topics range from my feelings through transitioning (of course), past abuse, mental health exploration, and an overall journey to grow and become a better creature. "
br { }
" I hope you enjoy the time you spend here, and sincerely, thank you. "
br { }
br { }
" 🖤 Alice Icehart Werefox "
}
}
div { class : " flex mx-auto max-w-full justify-center " ,
a { 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 " ,
href : " /poems/latest " ,
div { class : " " ,
p { class : " text-xl text-center " ,
" See Latest Entry "
}
}
}
}
div { class : " flex mx-auto max-w-full justify-center " ,
a { 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 " ,
href : " /poems/oldest " ,
div { class : " " ,
p { class : " text-xl text-center " ,
" See Oldest Entry "
}
}
}
}
div { class : " flex mx-auto max-w-full justify-center " ,
a { 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 " ,
href : " /poems " ,
div { class : " " ,
p { class : " text-xl text-center " ,
" See All Entries "
}
}
}
}
div { class : " flex p-4 text-md text-center 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 " ,
2023-04-10 18:19:02 -05:00
" This site uses Mutant Standard emoji, which are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License "
}
2023-04-07 17:16:43 -05:00
}
}
2023-04-08 20:47:51 -05:00
} )
2023-04-07 17:16:43 -05:00
}
2023-04-09 11:27:28 -05:00
fn get_poem_list ( ) -> Vec < ( String , String ) > {
let mut poem_list = Vec ::new ( ) ;
for p in Poems ::iter ( ) {
let filename = p . to_string ( ) ;
let poem_content = Poems ::get ( & filename ) . expect ( " Found poem {filename:?} " ) ;
let mut poem_to_str = std ::str ::from_utf8 ( poem_content . data . as_ref ( ) )
. expect ( " Title is valid UT8. " )
. lines ( ) ;
let title_markdown = poem_to_str . next ( ) . expect ( " No title specified. " ) ;
let title = markdown ::to_html_with_options ( title_markdown , & Options ::gfm ( ) ) . unwrap ( ) ;
let slug = String ::from ( filename . trim_end_matches ( " .md " ) ) ;
poem_list . push ( ( title . clone ( ) , slug . clone ( ) ) ) ;
}
log ::trace! ( " {poem_list:?} " ) ;
poem_list
}
2023-04-10 20:37:40 -05:00
pub fn get_oldest_entry ( ) -> String {
let mut poem_list = VecDeque ::from ( get_poem_list ( ) ) ;
poem_list . pop_front ( ) . expect ( " There is an entry in this list of poems. " ) . 1
}
pub fn get_latest_entry ( ) -> String {
let mut poem_list = get_poem_list ( ) ;
poem_list . pop ( ) . expect ( " There is an entry in this list of poems. " ) . 1
}
/// Renders the app and returns the rendered Element.
pub fn PoemListPage ( 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 : " 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. " ,
}
}
} ,
}
}
}
}
a { class : " flex 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 " ,
href : " / " ,
div { class : " mx-auto max-w-full justify-center " ,
p { class : " text-lg text-center " ,
" Back to the homepage "
}
}
}
PoemList { }
a { class : " flex 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 " ,
href : " / " ,
div { class : " mx-auto max-w-full justify-center " ,
p { class : " text-lg text-center " ,
" Back to the homepage "
}
}
}
div { class : " flex p-4 text-md text-center 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 "
}
}
}
} )
}
2023-04-09 11:27:28 -05:00
fn PoemList ( cx : Scope ) -> Element {
let poem_list = get_poem_list ( ) ;
cx . render ( rsx! {
ul { class : " space-y-4 " ,
poem_list . into_iter ( ) . map ( | p | {
rsx! {
div { PoemButton { title : p . 0 , slug : p . 1 } }
}
} )
}
} )
}
2023-04-08 12:40:57 -05:00
#[ cfg(any(target_family = " unix " , target_family = " windows " )) ]
2023-04-08 20:47:51 -05:00
pub fn PoemPage ( cx : Scope < PoemRequest > ) -> Element {
2023-04-10 18:19:02 -05:00
let slug = String ::from ( cx . props . slug . clone ( ) ) ;
let dark_mode = cx . props . dark_mode . clone ( ) . expect ( " Dark mode prop not passed. " ) ;
2023-04-08 20:47:51 -05:00
cx . render ( rsx! {
div { class : " min-h-screen font-nerd bg-alice-werefox-grey-light dark:bg-alice-werefox-grey " ,
2023-04-09 12:34:40 -05:00
div { class : " container space-y-4 mx-auto p-4 " ,
2023-04-10 20:37:40 -05:00
a { class : " flex 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 " ,
href : " / " ,
div { class : " mx-auto max-w-full justify-center " ,
p { class : " text-lg text-center " ,
" Back to the homepage "
}
2023-04-10 18:19:02 -05:00
}
2023-04-09 12:34:40 -05:00
}
2023-04-10 18:19:02 -05:00
GetPoem { slug : slug , dark_mode : dark_mode }
2023-04-10 20:37:40 -05:00
a { class : " flex 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 " ,
href : " / " ,
div { class : " mx-auto max-w-full justify-center " ,
p { class : " text-lg text-center " ,
" Back to the homepage "
}
}
}
div { class : " p-4 text-md text-center 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 "
}
2023-04-09 12:34:40 -05:00
}
2023-04-08 20:47:51 -05:00
}
} )
}
#[ cfg(target_family = " wasm " ) ]
fn PoemPage ( cx : Scope ) -> Element {
2023-04-09 11:27:28 -05:00
let slug = String ::from (
dioxus_router ::use_route ( cx )
. segment ( " slug " )
. expect ( " No slug specified. " ) ,
) ;
2023-04-10 18:19:02 -05:00
let dark_mode = cx . props . dark_mode . clone ( ) . expect ( " Dark mode prop not passed. " ) ;
2023-04-08 20:47:51 -05:00
cx . render ( rsx! {
div { class : " min-h-screen font-nerd bg-alice-werefox-grey-light dark:bg-alice-werefox-grey " ,
2023-04-09 12:34:40 -05:00
div { class : " container space-y-4 mx-auto p-4 " ,
Link { to : " / "
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 " ,
2023-04-10 20:37:40 -05:00
" Back to the homepage "
2023-04-09 12:34:40 -05:00
}
}
}
2023-04-10 18:19:02 -05:00
GetPoem { slug : slug , dark_mode : dark_mode }
2023-04-10 20:37:40 -05:00
div { class : " p-4 text-md text-center 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 "
}
2023-04-09 12:34:40 -05:00
}
2023-04-08 20:47:51 -05:00
}
} )
}
#[ cfg(any(target_family = " unix " , target_family = " windows " )) ]
fn PoemButton ( cx : Scope < PoemData > ) -> Element {
let title = cx . props . title . clone ( ) . expect ( " No title specified. " ) ;
let slug = cx . props . slug . clone ( ) . expect ( " No slug specified. " ) ;
let slug_ref = slug . as_str ( ) ;
cx . render ( rsx! {
2023-04-10 20:37:40 -05:00
a { href : " /poems/{slug_ref} " ,
2023-04-09 11:27:28 -05:00
li { class : " p-4 ml-6 mr-6 ring-2 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 " ,
2023-04-10 20:37:40 -05:00
div { class : " text-xl text-center " , " {title} " }
2023-04-08 20:47:51 -05:00
}
}
} )
}
#[ cfg(target_family = " wasm " ) ]
fn PoemButton ( cx : Scope < PoemData > ) -> Element {
let title = cx . props . title . clone ( ) . expect ( " No title specified. " ) ;
let slug = cx . props . slug . clone ( ) . expect ( " No slug specified. " ) ;
let slug_ref = slug . as_str ( ) ;
cx . render ( rsx! {
2023-04-10 20:37:40 -05:00
Link { to : " /poems/{slug_ref} " ,
2023-04-09 11:27:28 -05:00
li { class : " p-4 ml-6 mr-6 ring-2 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 " ,
div { class : " mx-auto max-w-fit flex justify-center text-lg text-center " ,
dangerous_inner_html : " {title} "
2023-04-08 20:47:51 -05:00
}
}
}
} )
}
fn GetPoem ( cx : Scope < PoemData > ) -> Element {
2023-04-10 18:19:02 -05:00
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. " ) ) ;
2023-04-09 11:27:28 -05:00
let filename =
2023-04-10 18:19:02 -05:00
String ::from ( String ::from ( slug . clone ( ) ) + " .md " ) ;
2023-04-09 11:27:28 -05:00
let creation_date =
String ::from ( String ::from ( " <br>Written on: " ) + filename . split ( " _ " ) . next ( ) . unwrap ( ) ) ;
2023-04-08 20:47:51 -05:00
let poem_content = Poems ::get ( & filename ) . expect ( " Found poem {filename:?} " ) ;
2023-04-09 11:27:28 -05:00
let mut poem_to_str = std ::str ::from_utf8 ( poem_content . data . as_ref ( ) )
. expect ( " Title is valid UT8. " )
. lines ( ) ;
2023-04-08 20:47:51 -05:00
let poem_title = poem_to_str . next ( ) . unwrap ( ) ;
let poem_content = poem_to_str . into_iter ( ) . collect ::< Vec < & str > > ( ) . join ( " \n " ) ;
2023-04-09 11:27:28 -05:00
let poem_title_to_html_string =
markdown ::to_html_with_options ( poem_title , & Options ::gfm ( ) ) . unwrap ( ) ;
let poem_content_to_html_string =
markdown ::to_html_with_options ( poem_content . as_str ( ) , & Options ::gfm ( ) ) . unwrap ( ) ;
2023-04-08 20:47:51 -05:00
cx . render ( rsx! {
2023-04-10 18:19:02 -05:00
MakePoem { title : poem_title_to_html_string , content : poem_content_to_html_string , creation_date : creation_date , slug : slug , dark_mode : dark_mode } }
2023-04-08 20:47:51 -05:00
)
}
#[ cfg(any(target_family = " unix " , target_family = " windows " )) ]
fn RenderPoemTitle ( cx : Scope < PoemData > ) -> Element {
2023-04-10 18:19:02 -05:00
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. " ) ;
2023-04-08 20:47:51 -05:00
let title = cx . props . title . clone ( ) . expect ( " No title specified. " ) ;
cx . render ( rsx! {
2023-04-10 20:37:40 -05:00
span { class : " p-4 ml-4 mr-4 flex text-xl text-center 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 " ,
span { class : " flex flex-row align-middle mx-auto max-w-full justify-center " ,
" {title} "
a { class : " " ,
href : " /poems/{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. " ,
}
2023-04-10 18:19:02 -05:00
}
2023-04-10 20:37:40 -05:00
} ,
false = > {
rsx! {
img { class : " " ,
src : " /images/black_square_button.png " ,
alt : " A black square button that can toggle dark mode. " ,
}
2023-04-10 18:19:02 -05:00
}
2023-04-10 20:37:40 -05:00
} ,
}
}
}
2023-04-08 12:40:57 -05:00
}
2023-04-08 20:47:51 -05:00
} )
2023-04-08 12:40:57 -05:00
}
#[ cfg(target_family = " wasm " ) ]
2023-04-08 20:47:51 -05:00
fn RenderPoemTitle ( cx : Scope < PoemData > ) -> Element {
2023-04-10 18:19:02 -05:00
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. " ) ;
2023-04-09 11:27:28 -05:00
let title = cx
. props
. title
. clone ( )
. expect ( " This poem has an empty title. " ) ;
2023-04-08 20:47:51 -05:00
cx . render ( rsx! {
2023-04-10 20:37:40 -05:00
p { class : " mx-auto max-w-fit flex flex-row justify-center 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-4 " ,
2023-04-10 18:19:02 -05:00
dangerous_inner_html : " {title} " ,
2023-04-10 20:37:40 -05:00
a { class : " " ,
href : " /poems/{slug}?set-dark-mode " ,
2023-04-10 18:19:02 -05:00
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. " ,
}
}
} ,
}
}
2023-04-08 12:40:57 -05:00
}
2023-04-08 20:47:51 -05:00
} )
2023-04-08 12:40:57 -05:00
}
2023-04-07 17:16:43 -05:00
#[ cfg(any(target_family = " unix " , target_family = " windows " )) ]
2023-04-08 20:47:51 -05:00
fn RenderPoemElement ( cx : Scope < PoemData > ) -> Element {
let content = cx . props . content . clone ( ) . expect ( " No content specified. " ) ;
2023-04-09 11:27:28 -05:00
let creation_date = cx
. props
. creation_date
. clone ( )
. expect ( " No creation date specified. " ) ;
cx . render ( rsx! {
2023-04-10 18:19:02 -05:00
div { class : " font-nerd flex flex-col space-y-4 mx-4 py-4 " , " {content}{creation_date} "
}
2023-04-08 20:47:51 -05:00
} )
2023-04-07 17:16:43 -05:00
}
#[ cfg(target_family = " wasm " ) ]
2023-04-08 20:47:51 -05:00
fn RenderPoemElement ( cx : Scope < PoemData > ) -> Element {
let content = cx . props . content . clone ( ) . expect ( " No content specified. " ) ;
2023-04-09 11:27:28 -05:00
let creation_date = cx
. props
. creation_date
. clone ( )
. expect ( " No creation date specified. " ) ;
cx . render ( rsx! {
2023-04-08 20:47:51 -05:00
div {
class : " font-nerd flex flex-col space-y-4 mx-4 py-4 " ,
dangerous_inner_html : " {content}{creation_date} "
}
} )
2023-04-07 17:16:43 -05:00
}
2023-04-08 12:40:57 -05:00
fn MakePoem ( cx : Scope < PoemData > ) -> Element {
2023-04-10 18:19:02 -05:00
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. " ) ;
2023-04-08 20:47:51 -05:00
let title = cx . props . title . clone ( ) . expect ( " No title specified. " ) ;
2023-04-09 11:27:28 -05:00
let creation_date = cx
. props
. creation_date
. clone ( )
. expect ( " No creation date specified. " ) ;
2023-04-08 20:47:51 -05:00
let content = cx . props . content . clone ( ) . expect ( " No content specified. " ) ;
cx . render ( rsx! {
2023-04-07 17:16:43 -05:00
div { class : " flex-col space-y-4 " ,
2023-04-10 18:19:02 -05:00
RenderPoemTitle { title : title . clone ( ) , slug : slug , dark_mode : dark_mode }
2023-04-10 20:37:40 -05:00
div { class : " flex p-4 ml-6 mr-6 mx-auto max-w-full justify-center " ,
details { class : " group p-4 max-w-fit space-y-4 bg-alice-werefox-grey-lightest dark:bg-alice-werefox-grey-dark ring-4 ring-alice-werefox-red-dark dark:ring-alice-werefox-red text-alice-werefox-red-dark dark:text-alice-werefox-red-light " ,
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 ( ) }
2023-04-07 17:16:43 -05:00
}
}
}
2023-04-08 20:47:51 -05:00
} )
2023-04-07 17:16:43 -05:00
}
}