Skip to content

Commit

Permalink
Add back theming
Browse files Browse the repository at this point in the history
  • Loading branch information
Hampton Moore committed Jan 16, 2024
1 parent 1ebb8ef commit b564388
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 76 deletions.
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"

[dependencies]
axum = { version = "0.7.4", features = ["macros"] }
axum-extra = { version = "0.9.2", features = ["cookie"] }
chrono = "0.4.31"
color-eyre = "0.6.2"
comrak = "0.20.0"
Expand Down
23 changes: 23 additions & 0 deletions assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,27 @@ body[colorscheme="white"] {
--container-header-color: #191919;
--container-backdrop: #000000;
--text-color: #191919
}

body[colorscheme="white"] .themecolors div[theme="white"] {
border: 1px solid #191919;
}

.themecolors {
bottom: 8px;
left: 8px;
display: block;
margin: auto;
position: absolute;
}

.themecolors div {
width: 16px;
height: 16px;
float: left;
margin-left: 8px;
}

.themecolors div:hover {
cursor: pointer;
}
62 changes: 49 additions & 13 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
use axum::{response::Html, routing::get, Router};
use log::{error, info};
use std::sync::Arc;
use tokio::sync::RwLock;
use log::{info, error};
use axum::{
response::Html,
routing::{get},
Router
};

use tower_http::services::ServeDir;
mod site;
mod things;
mod update;
mod utils;
mod things;
mod words;

async fn health() -> Html<String> {
Html(String::from("OK"))
}


#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct ClientState {
pub theme : String,
pub theme: String,
}
// use axum::extract::FromRef;

// impl FromRef<Arc<RwLock<SiteState>>> for ClientState {
// fn from_ref(_: &Arc<RwLock<SiteState>>) -> Self {
// // Your logic to extract or construct ClientState from SiteState
// // For example:
// ClientState {
// theme: "default_theme".to_string(),
// }
// }
// }

#[derive(Clone)]
pub struct SiteState {
Expand All @@ -36,7 +42,8 @@ async fn main() {
env_logger::init();
info!("Starting up!");

let things = things::read_things_from_file("./content/things.csv").expect("Failed to read things");
let things =
things::read_things_from_file("./content/things.csv").expect("Failed to read things");

let words = words::init("./content/words/");

Expand Down Expand Up @@ -64,8 +71,37 @@ async fn main() {
.route("/posts/:slug", get(site::words::post))
.route("/things/", get(site::things::index))
.route("/", get(site::home::home))
.with_state(state);
.with_state(state)
.layer(middleware::from_fn(middleware_apply_client_state));

let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
}

use axum::{
extract::Request,
middleware::{self, Next},
response::Response,
};

use axum_extra::extract::cookie::{CookieJar};

async fn middleware_apply_client_state(
jar: CookieJar,
mut request: Request,
next: Next,
) -> Response {
let mut state = ClientState {
theme: String::from("DEFAULT"),
};

if let Some(cookie) = jar.get("colorscheme") {
state.theme = cookie.value().to_string();
}

request.extensions_mut().insert(state);

let response = next.run(request).await;

response
}
41 changes: 30 additions & 11 deletions src/site/home.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use maud::{html, Markup};
use super::base;
use crate::words::Post;
use crate::{ClientState, SiteState};
use axum::extract::{Extension, State};
use maud::{html, Markup, PreEscaped};
use std::sync::Arc;
use tokio::sync::RwLock;
use axum::extract::State;
use crate::SiteState;
use crate::words::Post;
use super::base;

pub async fn home(State(state): State<Arc<RwLock<SiteState>>>) -> Markup {
pub async fn home(
State(state): State<Arc<RwLock<SiteState>>>,
Extension(client_state): Extension<ClientState>,
) -> Markup {
let state = state.read().await;

let things = state.things[0..5].to_vec();
Expand All @@ -21,10 +24,10 @@ pub async fn home(State(state): State<Arc<RwLock<SiteState>>>) -> Markup {
}

let content = html! {
div class="pure-g hero section" {
div class="pure-g hero section" style="position: relative" {
div class="pure-u-1 pure-u-md-2-3 hero-text" {
h1 { "Hampton Moore" }
p {
p {
"I am an network automations engineer, software developer, and student (CS BS @ UMass Amherst).
Since Summer 2022 I have been working at "
a href="https://arista.com" target = "_blank" { "Arista Networks" }
Expand All @@ -37,14 +40,30 @@ pub async fn home(State(state): State<Arc<RwLock<SiteState>>>) -> Markup {
div class="pure-u-1 pure-u-md-1-3 hero-img" {
img class="pure-img" src="/assets/img/hammy.png" alt="Hampton's avatar";
}
div class="themecolors" {
div style="background-color: #ff5757" theme="red" {}
div style="background-color: #9b5efd" theme="purple" {}
div style="background-color: #fafafa; box-sizing: border-box;" theme="white" {}
div style="background-color: #ffa7d1" theme="pink" {}
div style="background-color: #04a7e7" theme="blue" {}
}
script type="text/javascript" {
(PreEscaped("
[...document.getElementsByClassName('themecolors')[0].children].forEach((c)=>c.onclick=()=>{
theme = c.getAttribute('theme');
document.body.setAttribute('colorscheme', theme);
document.cookie = `colorscheme=${theme}; expires=${(new Date(Date.now()+ 86400*365*1000)).toUTCString()}; path=/`;
})
"))
}
}

div class="pure-g hero section" {
div class="pure-u-1 pure-u-md-1-2" {
h3 { "Things I've Made" }
ul {
@for thing in things.clone() {
li {
li {
(thing.date.format("%Y-%m").to_string()) ": "
a href=(thing.link) { (thing.title) }
@if let Some(description) = &thing.description {
Expand All @@ -62,7 +81,7 @@ pub async fn home(State(state): State<Arc<RwLock<SiteState>>>) -> Markup {
h3 { "Words I've Written" }
ul {
@for post in words {
li {
li {
(post.date.format("%Y").to_string()) " "
a href=(post.link) { (post.title) }
": "
Expand All @@ -81,5 +100,5 @@ pub async fn home(State(state): State<Arc<RwLock<SiteState>>>) -> Markup {

};

base("Home".to_owned(), content, state.clone())
base("Home".to_owned(), content, state.clone(), client_state)
}
13 changes: 6 additions & 7 deletions src/site/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use crate::{ClientState, SiteState};
use maud::{html, Markup};
use crate::SiteState;
use axum::response::Html;
pub mod home;
pub mod words;
pub mod things;
pub mod words;

pub fn base(title: String, content: Markup, state: SiteState) -> Markup {

pub fn base(title: String, content: Markup, _state: SiteState, client: ClientState) -> Markup {
let description = "Hampton Moore";
let title = format!("{} | Hampton Moore", title);

Expand Down Expand Up @@ -34,7 +32,7 @@ pub fn base(title: String, content: Markup, state: SiteState) -> Markup {
meta property="og:theme-color" content="#19191e";
}

body {
body colorscheme=(client.theme) {
div class="main" {
(content);
div class="footer" {
Expand All @@ -57,7 +55,7 @@ pub fn base(title: String, content: Markup, state: SiteState) -> Markup {
a target="_blank" href="https://umass.edu" {
img src="/assets/img/badges/umass.gif" alt="umass";
}
a target="_blank" href="https://ezrizhu.com/" {
a target="_blank" href="https://ezrizhu.com/" {
img src="/assets/img/badges/ezri.png" alt="Ezri";
}
img src="/assets/img/badges/aperture_labs.jpg" alt="aperture_labs";
Expand Down Expand Up @@ -85,6 +83,7 @@ pub fn base(title: String, content: Markup, state: SiteState) -> Markup {
a target="_blank" href="https://github.com/hamptonmoore/www/blob/main/COPYING" { "GNU AGPLv3 license" }
br;
"All opinions here are my own and do not reflect the views of my employers or university: future, past, and present."
br;
}
}
}
Expand Down
22 changes: 15 additions & 7 deletions src/site/things.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
use super::base;
use crate::{ClientState, SiteState};
use axum::extract::{Extension, State};
use maud::{html, Markup};
use std::sync::Arc;
use tokio::sync::RwLock;
use axum::extract::State;
use crate::SiteState;
use super::base;

pub async fn index(State(state): State<Arc<RwLock<SiteState>>>) -> Markup {
pub async fn index(
State(state): State<Arc<RwLock<SiteState>>>,
Extension(client_state): Extension<ClientState>,
) -> Markup {
let state = state.read().await;

let things = state.things.clone();
let things = state.things.clone();

let content = html! {
div class="pure-g hero section" {
div class="pure-u-1" {
h1 { "Things I've Made" }
ul {
@for thing in things.clone() {
li {
li {
(thing.date.format("%Y-%m-%d").to_string()) ": "
a href=(thing.link) { (thing.title) }
@if let Some(description) = &thing.description {
Expand All @@ -34,5 +37,10 @@ pub async fn index(State(state): State<Arc<RwLock<SiteState>>>) -> Markup {
}
};

base("Things".to_owned(), content, state.clone())
base(
"Things".to_owned(),
content,
state.clone(),
client_state,
)
}
Loading

0 comments on commit b564388

Please sign in to comment.