A little app to serve my photography from my personal website

mobile styles, timestamp in footer

ericwood.org f496dacb 70c4e809

Waiting for spindle ...
+48 -2
+9 -1
assets/app.js
··· 1 1 const longFormatter = new Intl.DateTimeFormat(undefined, { 2 2 month: "short", 3 3 day: "numeric", 4 - year: "numeric" 4 + year: "numeric", 5 5 }); 6 6 7 7 const shortFormatter = new Intl.DateTimeFormat(undefined, { ··· 10 10 year: "2-digit", 11 11 }); 12 12 13 + const timeFormatter = new Intl.DateTimeFormat(undefined, { 14 + dateStyle: "medium", 15 + timeStyle: "medium", 16 + }); 17 + 13 18 const initTimestamps = () => { 14 19 document.querySelectorAll('time').forEach((el) => { 15 20 let formatter = longFormatter 16 21 const isShort = el.dataset.short === "true"; 22 + const hasTime = el.dataset.time === "true"; 17 23 if (isShort) { 18 24 formatter = shortFormatter; 25 + } else if (hasTime) { 26 + formatter = timeFormatter; 19 27 } 20 28 21 29 const timeStr = el.attributes.datetime;
+4
src/date_time.rs
··· 11 11 pub struct DateTime(chrono::DateTime<FixedOffset>); 12 12 13 13 impl DateTime { 14 + pub fn now() -> Self { 15 + Self(chrono::Utc::now().fixed_offset()) 16 + } 17 + 14 18 pub fn min_date() -> Self { 15 19 Self(chrono::DateTime::<FixedOffset>::MIN_UTC.fixed_offset()) 16 20 }
+12
src/styles/app.css
··· 89 89 flex-direction: column; 90 90 } 91 91 92 + header .home { 93 + padding: 10px 20px; 94 + } 95 + 92 96 header nav ul { 93 97 flex-direction: column; 98 + } 99 + 100 + header nav ul a { 101 + padding: 10px 20px; 102 + } 103 + 104 + .layout { 105 + padding: 20px; 94 106 } 95 107 } 96 108
+7
src/styles/posts.css
··· 76 76 border: solid var(--foreground) 2px; 77 77 background-color: var(--background); 78 78 } 79 + 80 + @media (max-width: 850px) { 81 + .posts__entries li { 82 + flex-direction: column; 83 + gap: 10px; 84 + } 85 + }
+8 -1
src/templates.rs
··· 4 4 use serde::Serialize; 5 5 use std::{fs::read_to_string, path::Path}; 6 6 7 - use crate::config::Config; 7 + use crate::{config::Config, date_time::DateTime}; 8 8 9 9 #[derive(Serialize)] 10 10 struct NavLink<'a> { ··· 42 42 env.add_function("photo_url", photo_url); 43 43 env.add_function("assets_path", assets_path); 44 44 env.add_function("year", year); 45 + env.add_function("timestamp", timestamp); 45 46 env.add_global( 46 47 "nav_links", 47 48 Value::from_serialize([ ··· 139 140 let year = chrono::Utc::now().year(); 140 141 format!("{year}") 141 142 } 143 + 144 + fn timestamp() -> String { 145 + let now = DateTime::now(); 146 + let time_str: String = now.into(); 147 + format!("<time datetime=\"{time_str}\" data-time=\"true\">{time_str}</time>") 148 + }
+6
src/views/blog/show/style.css
··· 110 110 opacity: 0.75; 111 111 } 112 112 113 + @media (max-width: 850px) { 114 + .blog__title { 115 + margin-top: 0; 116 + font-size: 22pt; 117 + } 118 + }
+1
src/views/projects/index/template.jinja
··· 10 10 {% block body %} 11 11 <div class="layout"> 12 12 {{ posts_macro.header("Projects", tag=tag) }} 13 + <p>Write-ups of things I've worked on outside of my day-job</p> 13 14 {{ posts_macro.table(posts, root_path="/projects", tag=tag) }} 14 15 </div> 15 16 <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="display: none">
+1
templates/layout.jinja
··· 54 54 </div> 55 55 <footer> 56 56 © Eric Wood {{ year() }} 57 + <div>Rendered {{ timestamp() }}</div> 57 58 </footer> 58 59 </div> 59 60