From c5e4cd605db1a117deda9a8a1e60c4e8d124a447 Mon Sep 17 00:00:00 2001 From: Ada Werefox Date: Mon, 10 Apr 2023 20:37:40 -0500 Subject: [PATCH] Added oldest and latest entry routes/buttons, added new poem entry, minor front end adjustments. --- public/styles/tailwind.min.css | 2 +- void-be/src/lib.rs | 59 ++++- .../data/poems/2023-04-10_ice-coffe-part-2.md | 75 ++++++ void-fe/src/lib.rs | 238 ++++++++++++++---- 4 files changed, 312 insertions(+), 62 deletions(-) create mode 100644 void-fe/data/poems/2023-04-10_ice-coffe-part-2.md diff --git a/public/styles/tailwind.min.css b/public/styles/tailwind.min.css index ea6c80f..96c35c6 100644 --- a/public/styles/tailwind.min.css +++ b/public/styles/tailwind.min.css @@ -1 +1 @@ -/*! tailwindcss v3.3.0 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-6{margin-left:1.5rem}.mr-6{margin-right:1.5rem}.flex{display:flex}.min-h-screen{min-height:100vh}.max-w-fit{max-width:-moz-fit-content;max-width:fit-content}.max-w-full{max-width:100%}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.justify-center{justify-content:center}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.border-4{border-width:4px}.border-alice-werefox-red-dark{--tw-border-opacity:1;border-color:rgb(128 0 8/var(--tw-border-opacity))}.bg-alice-werefox-grey-light{--tw-bg-opacity:1;background-color:rgb(204 204 204/var(--tw-bg-opacity))}.bg-alice-werefox-grey-lightest{--tw-bg-opacity:1;background-color:rgb(238 238 238/var(--tw-bg-opacity))}.p-4{padding:1rem}.py-4{padding-top:1rem;padding-bottom:1rem}.text-center{text-align:center}.font-nerd{font-family:OpenDyslexic}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-alice-werefox-red-dark{--tw-text-opacity:1;color:rgb(128 0 8/var(--tw-text-opacity))}.ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-2,.ring-4{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-4{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-alice-werefox-red-dark{--tw-ring-opacity:1;--tw-ring-color:rgb(128 0 8/var(--tw-ring-opacity))}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}@font-face{font-family:OpenDyslexic;src:url(/fonts/OpenDyslexic-Regular.otf)}.before\:content-\[\'Open\'\]:before{--tw-content:"Open";content:var(--tw-content)}@keyframes yip{0%,to{transform:scale(1)}50%{transform:scale(1.01)}}.hover\:animate-yip:hover{animation:yip .1s ease-in-out}.hover\:text-alice-werefox-blue-dark:hover{--tw-text-opacity:1;color:rgb(51 0 255/var(--tw-text-opacity))}.hover\:ring-alice-werefox-blue:hover{--tw-ring-opacity:1;--tw-ring-color:rgb(27 41 224/var(--tw-ring-opacity))}.group[open] .group-open\:before\:content-\[\'Close\'\]:before{--tw-content:"Close";content:var(--tw-content)}:is(.dark .dark\:border-alice-werefox-red){--tw-border-opacity:1;border-color:rgb(201 52 57/var(--tw-border-opacity))}:is(.dark .dark\:bg-alice-werefox-grey){--tw-bg-opacity:1;background-color:rgb(36 36 36/var(--tw-bg-opacity))}:is(.dark .dark\:bg-alice-werefox-grey-dark){--tw-bg-opacity:1;background-color:rgb(18 18 18/var(--tw-bg-opacity))}:is(.dark .dark\:text-alice-werefox-red-light){--tw-text-opacity:1;color:rgb(224 133 135/var(--tw-text-opacity))}:is(.dark .dark\:ring-alice-werefox-red){--tw-ring-opacity:1;--tw-ring-color:rgb(201 52 57/var(--tw-ring-opacity))}:is(.dark .dark\:hover\:text-alice-werefox-blue-light:hover){--tw-text-opacity:1;color:rgb(145 151 243/var(--tw-text-opacity))}:is(.dark .dark\:hover\:ring-alice-werefox-blue:hover){--tw-ring-opacity:1;--tw-ring-color:rgb(27 41 224/var(--tw-ring-opacity))} \ No newline at end of file +/*! tailwindcss v3.3.0 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-4{margin-left:1rem}.ml-6{margin-left:1.5rem}.mr-4{margin-right:1rem}.mr-6{margin-right:1.5rem}.flex{display:flex}.min-h-screen{min-height:100vh}.max-w-fit{max-width:-moz-fit-content;max-width:fit-content}.max-w-full{max-width:100%}.grow{flex-grow:1}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.justify-center{justify-content:center}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.bg-alice-werefox-grey-light{--tw-bg-opacity:1;background-color:rgb(204 204 204/var(--tw-bg-opacity))}.bg-alice-werefox-grey-lightest{--tw-bg-opacity:1;background-color:rgb(238 238 238/var(--tw-bg-opacity))}.p-4{padding:1rem}.py-4{padding-top:1rem;padding-bottom:1rem}.text-center{text-align:center}.align-middle{vertical-align:middle}.font-nerd{font-family:OpenDyslexic}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.text-alice-werefox-red-dark{--tw-text-opacity:1;color:rgb(128 0 8/var(--tw-text-opacity))}.ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-2,.ring-4{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-4{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-alice-werefox-red-dark{--tw-ring-opacity:1;--tw-ring-color:rgb(128 0 8/var(--tw-ring-opacity))}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}@font-face{font-family:OpenDyslexic;src:url(/fonts/OpenDyslexic-Regular.otf)}.before\:content-\[\'Open\'\]:before{--tw-content:"Open";content:var(--tw-content)}@keyframes yip{0%,to{transform:scale(1)}50%{transform:scale(1.01)}}.hover\:animate-yip:hover{animation:yip .1s ease-in-out}.hover\:text-alice-werefox-blue-dark:hover{--tw-text-opacity:1;color:rgb(51 0 255/var(--tw-text-opacity))}.hover\:ring-alice-werefox-blue:hover{--tw-ring-opacity:1;--tw-ring-color:rgb(27 41 224/var(--tw-ring-opacity))}.group[open] .group-open\:before\:content-\[\'Close\'\]:before{--tw-content:"Close";content:var(--tw-content)}:is(.dark .dark\:bg-alice-werefox-grey){--tw-bg-opacity:1;background-color:rgb(36 36 36/var(--tw-bg-opacity))}:is(.dark .dark\:bg-alice-werefox-grey-dark){--tw-bg-opacity:1;background-color:rgb(18 18 18/var(--tw-bg-opacity))}:is(.dark .dark\:text-alice-werefox-red-light){--tw-text-opacity:1;color:rgb(224 133 135/var(--tw-text-opacity))}:is(.dark .dark\:ring-alice-werefox-red){--tw-ring-opacity:1;--tw-ring-color:rgb(201 52 57/var(--tw-ring-opacity))}:is(.dark .dark\:hover\:text-alice-werefox-blue-light:hover){--tw-text-opacity:1;color:rgb(145 151 243/var(--tw-text-opacity))}:is(.dark .dark\:hover\:ring-alice-werefox-blue:hover){--tw-ring-opacity:1;--tw-ring-color:rgb(27 41 224/var(--tw-ring-opacity))} \ No newline at end of file diff --git a/void-be/src/lib.rs b/void-be/src/lib.rs index 07386f2..f923ab4 100644 --- a/void-be/src/lib.rs +++ b/void-be/src/lib.rs @@ -48,23 +48,70 @@ pub mod web_app_backend { 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/?set-dark-mode")] + #[get("/poems")] + async fn poem_list(cookies: &CookieJar<'_>) -> Template { + let dark_mode = match cookies.get("dark-mode") { + Some(_) => true, + None => false, + }; + let mut vdom = VirtualDom::new_with_props(void_app::PoemListPage, HomeProps { + dark_mode: dark_mode, + }); + let _ = vdom.rebuild(); + let output = dioxus_ssr::render(&vdom); + Template::render( + "index", + context! { + app_title: "A Letter to the Void", + style_include: "", + test: &output, + dark_mode: match dark_mode { + true => "dark", + false => "" + }, + }, + ) + } + + #[get("/poems?set-dark-mode")] + async fn poems_dark_mode(cookies: &CookieJar<'_>) -> Redirect { + dark_mode(cookies, PathBuf::new()).await + } + + + #[get("/poems/?set-dark-mode")] + async fn entry_dark_mode(cookies: &CookieJar<'_>, entry: PathBuf) -> Redirect { + dark_mode(cookies, entry).await + } + 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 path_str = String::from(Path::new("/poems/").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/")] + #[get("/poems/latest")] + 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("/poems/oldest")] + 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("/poems/")] async fn poem(cookies: &CookieJar<'_>, entry: &str) -> Template { let dark_mode = match cookies.get("dark-mode") { Some(_) => true, @@ -99,7 +146,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![dark_mode_root, index, dark_mode, poem]) + .mount("/", routes![dark_mode_root, index, poems_dark_mode, poem_list, latest_entry, oldest_entry, entry_dark_mode, poem]) .attach(Template::fairing()) } } diff --git a/void-fe/data/poems/2023-04-10_ice-coffe-part-2.md b/void-fe/data/poems/2023-04-10_ice-coffe-part-2.md new file mode 100644 index 0000000..66010a4 --- /dev/null +++ b/void-fe/data/poems/2023-04-10_ice-coffe-part-2.md @@ -0,0 +1,75 @@ +# Iced Coffee - Part 2 +*(Author's note: The first part of this is exactly the same as my original poem, "Iced Coffee". I included it both as a way to directly show my own growth in the poem and for convenience.)* + +*Iced coffee, on a cold Winter's day* \ +*Iced coffee, bittersweet at the taste* \ +*Do you see me? I probably fade* \ +*Fade into darkness, and I'll go away* + +Hmm.... + +*Why can't you see me? This mirror is broken* \ +*Why can't you see me? I can't be this broken* \ +*Every line keeping me from satisfaction* \ +*I'm wondering why you can keep me in traction* \ +*I'm falling, I'm sinking, this love is a sinkhole* \ +*I don't understand why you keep me, this freakshow* \ +*I see you and there's so much better contestants* \ +*Competing and winning and gaining attention* \ +*And I'm consolation, the prize for obsession* \ +*Don't know why you'd even give me just a second* + +*Iced coffee, on a cold Winter's day* \ +*Iced coffee, bittersweet at the taste* \ +*Do you see me? I probably fade* \ +*Fade into darkness and I'll go away* + +*Hmmmm....* \ +*Hmmmm....* \ +*Hmmmm....* **(it's like... I don't really even know why I bother)** \ +*Hmmmm....* **(am I even worth paying attention to in the first place?)** \ +*Hmmmm....* \ +*Hmmmm....* + +*Iced coffee, on a cold Winter's day* \ +*Iced coffee, bittersweet at the taste* \ +*Now you see me, and I'll be okay* \ +*I have my darkness so far tucked away* + +(chuckle) + +*I never thought I would tell you I've accepted* \ +*That I've resolved all of my feelings of shame* \ +*I've moved on and found others who keep me present* \ +*Remind me that being alone is okay* \ +*I look back and think about that pain you caused me* \ +*And realize I should have voiced my refrain* \ +*You never owed me all your time and attention* \ +*You never owed me anything, just the same* + +*We both agree there are much bigger aggressions* \ +*Than anger from feeling abandoned or strayed* \ +*I'm happy to find some common resolution* \ +*I'm happy we don't talk and I'm not afraid* \ +*I feel so much better about my own presence* \ +*I feel so much better and now I can say* \ +*That drinking iced coffee no longer reminds me* \ +*Of feeling isolated from your embrace* \ +*So I wrote more verses to speak of acceptance* \ +*I'm closing the book on that unhappy moment* + +*Iced coffee, on a cold Winter's day* \ +*Iced coffee, bittersweet at the taste* \ +*Now you see me, and I'll be okay* \ +*I have my darkness so far tucked away* + +*Hmmmm....* \ +*Hmmmm....* \ +*Hmmmm....* **(I wrote "Iced Coffee" to express some feelings I had at the time)**\ +*Hmmmm....* **(and while those feelings were valid. I realize now)**\ +*Hmmmm....* **(that the insecurity I felt had more to do with my self-worth)**\ +*Hmmmm....* **(and my reliance on needing someone to hold onto)**\ +*Hmmmm....* **(in order to keep myself feeling happy and safe)**\ +*Hmmmm....* **(I just wanted to express that I've grown since then)**\ +*Hmmmm....* \ +*Hmmmm....* \ No newline at end of file diff --git a/void-fe/src/lib.rs b/void-fe/src/lib.rs index ec9987e..595f327 100644 --- a/void-fe/src/lib.rs +++ b/void-fe/src/lib.rs @@ -9,6 +9,7 @@ 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 std::collections::VecDeque; use markdown::{self, Options}; use rust_embed::RustEmbed; @@ -49,7 +50,7 @@ pub mod void_app { cx.render(rsx! { Router { Route { to: "/", HomePage {} } - Route { to: "/poem/:slug/", PoemPage {} } + Route { to: "/poems/:slug/", PoemPage {} } Route { to: "", PageNotFound {} } } }) @@ -65,6 +66,115 @@ pub mod void_app { /// Renders the app and returns the rendered Element. pub fn HomePage(cx: Scope) -> 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-xl 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.", + } + } + }, + } + } + } + } + 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", + "This site uses Mutant Standard emoji, which are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License" + } + } + } + }) + } + + 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 + } + + 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) -> 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", @@ -95,8 +205,24 @@ pub mod void_app { } } } + 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 {} - 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", + 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" } } @@ -104,23 +230,6 @@ pub mod void_app { }) } - 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 - } - fn PoemList(cx: Scope) -> Element { let poem_list = get_poem_list(); cx.render(rsx! { @@ -141,14 +250,26 @@ pub mod void_app { 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 { 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" + } } - } } GetPoem { slug: slug, dark_mode: 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" + } + } + } + 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" + } } } }) @@ -168,11 +289,14 @@ pub mod void_app { 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", - "Take me back!" + "Back to the homepage" } } } GetPoem { slug: slug, dark_mode: dark_mode } + 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" + } } } }) @@ -184,9 +308,9 @@ pub mod void_app { let slug = cx.props.slug.clone().expect("No slug specified."); let slug_ref = slug.as_str(); cx.render(rsx!{ - a { href: "/poem/{slug_ref}", + a { href: "/poems/{slug_ref}", 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: "text-lg text-center", "{title}" } + div { class: "text-xl text-center", "{title}" } } } }) @@ -198,7 +322,7 @@ pub mod void_app { let slug = cx.props.slug.clone().expect("No slug specified."); let slug_ref = slug.as_str(); cx.render(rsx!{ - Link { to: "/poem/{slug_ref}", + Link { to: "/poems/{slug_ref}", 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}" @@ -236,29 +360,31 @@ pub mod void_app { 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} " - 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.", + 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.", + } } - } - }, - false => { - rsx! { - img { class: "", - src: "/images/black_square_button.png", - alt: "A black 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.", + } } - } - }, - } - } + }, + } + } + } } }) } @@ -273,10 +399,10 @@ pub mod void_app { .clone() .expect("This poem has an empty title."); cx.render(rsx!{ - 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", + 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", dangerous_inner_html: "{title} ", - a { class: "max-h-sm", - href: "/poem/{slug}?set-dark-mode", + a { class: "", + href: "/poems/{slug}?set-dark-mode", match dark_mode { true => { rsx! { @@ -343,10 +469,12 @@ pub mod void_app { cx.render(rsx!{ div { class: "flex-col space-y-4", 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", + 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() } } - RenderPoemElement { content: content.clone(), creation_date: creation_date.clone() } } } })