From 653853b4f6689257d26675cfcc38ff5e3af744bc Mon Sep 17 00:00:00 2001 From: Joakim Hulthe Date: Mon, 31 May 2021 23:19:41 +0200 Subject: [PATCH] Improve life calendar and add it to header --- server/src/main.rs | 7 ++ server/src/routes/pages/weeks.rs | 112 ++++++++++++++++++------------- server/static/styles/common.css | 10 ++- server/templates/header.hbs | 8 ++- server/templates/weeks.hbs | 6 +- 5 files changed, 91 insertions(+), 52 deletions(-) diff --git a/server/src/main.rs b/server/src/main.rs index ed816fd..e51acd8 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -9,8 +9,10 @@ use crate::auth::MasterPassword; use crate::database::migrations::migrate; use crate::database::unversioned::global::schema_version; use crate::database::SCHEMA_VERSION; +use crate::routes::pages::weeks::BirthDate; use crate::util::EventNotifier; use bincode::{deserialize, serialize}; +use chrono::NaiveDate; use dotenv::dotenv; use rocket_contrib::serve::StaticFiles; use rocket_contrib::templates::Template; @@ -29,6 +31,10 @@ async fn main() -> io::Result<()> { }) .into(); + let birth_date: BirthDate = env::var("BIRTH_DATE") + .map(|s| BirthDate(s.parse().expect("failed to parse BIRTH_DATE"))) + .unwrap_or_else(|_| BirthDate(NaiveDate::from_ymd(2000, 1, 1))); + let mut sled = sled::open(db_path)?; match sled.insert( serialize(schema_version::K).unwrap(), @@ -56,6 +62,7 @@ async fn main() -> io::Result<()> { })) .manage(sled) .manage(master_pass) + .manage(birth_date) .manage(EventNotifier::new()) .mount("/static", StaticFiles::from("static")) .mount( diff --git a/server/src/routes/pages/weeks.rs b/server/src/routes/pages/weeks.rs index 4f2772f..4212d68 100644 --- a/server/src/routes/pages/weeks.rs +++ b/server/src/routes/pages/weeks.rs @@ -1,30 +1,49 @@ use crate::auth::Authorized; use crate::status_json::StatusJson; use chrono::{Duration, Local, NaiveDate}; -use rocket::get; +use itertools::Itertools; +use rocket::{get, State}; use rocket_contrib::templates::Template; use serde::{Deserialize, Serialize}; use std::borrow::Cow; use std::iter::{once, repeat}; +pub struct BirthDate(pub NaiveDate); + #[get("/weeks")] -pub fn weeks(_auth: Authorized) -> Result { +pub fn weeks(_auth: Authorized, birth_date: State) -> Result { type Color<'a> = Cow<'a, str>; - #[derive(Debug, Clone, Serialize, Deserialize)] - struct WeekCtx<'a> { - border_color: Color<'a>, - fill_color: Option>, + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] + struct Style<'a> { + border: Color<'a>, + fill: Option>, } - impl<'a, T> From for WeekCtx<'a> - where - T: Into>, - { - fn from(color: T) -> Self { - WeekCtx { - border_color: color.into(), - fill_color: None, + #[derive(Debug, Clone, Serialize, Deserialize)] + struct PeriodCtx<'a> { + style: Style<'a>, + weeks: Vec<()>, + } + + impl<'a> Style<'a> { + fn border(border: C) -> Self + where + C: Into>, + { + Style { + border: border.into(), + fill: None, + } + } + + fn fill(border: C, fill: C) -> Self + where + C: Into>, + { + Style { + border: border.into(), + fill: Some(fill.into()), } } } @@ -32,13 +51,11 @@ pub fn weeks(_auth: Authorized) -> Result { #[derive(Debug, Serialize, Deserialize)] struct Ctx<'a> { weeks_left: i64, - weeks: Vec>, + periods: Vec>, } let now = Local::now().date(); - - // TODO: change this - let birth_date = NaiveDate::from_ymd(1999, 01, 01); + let birth_date = birth_date.0; let lived: Duration = now.naive_local() - birth_date; let one_year = Duration::days(365); @@ -51,40 +68,41 @@ pub fn weeks(_auth: Authorized) -> Result { let color_birth = "green"; let color_child = "#ff0"; - let color_teen = "#f0f"; - let color_adult = "#f33"; + let color_teen = "#f33"; + let color_adult = "#f0f"; let color_today = "wheat"; let color_future = "#eee"; let context = Ctx { weeks_left: life_expectancy - lived.num_weeks(), - weeks: once(WeekCtx { - border_color: color_birth.into(), - fill_color: Some(color_birth.into()), - }) - // childhood - .chain((1..childhood_end).map(|_| color_child.into())) - // teens - .chain((childhood_end..teenage_end).map(|_| color_teen.into())) - // adulthood - .chain((teenage_end..).map(|_| color_adult.into())) - // take from above for lived number of weeks - .take(lived.num_weeks() as usize - 1) - // add a week for this week - .chain(once(WeekCtx { - border_color: color_today.into(), - fill_color: Some(color_today.into()), - })) - // fill remaining weeks until death - .chain(repeat(color_future.into())) - .take((life_expectancy - uncertainty * 2) as usize) - // add some fading around expected life span - .chain((0..uncertainty).rev().map(|i| { - let m = u8::MAX as i64; - let alpha = ((m * i) / (uncertainty)) as u8; - format!("#eeeeee{:02x}", alpha).into() - })) - .collect(), + periods: once(Style::fill(color_birth, color_birth)) + // childhood + .chain((1..childhood_end).map(|_| Style::border(color_child))) + // teens + .chain((childhood_end..teenage_end).map(|_| Style::border(color_teen))) + // adulthood + .chain((teenage_end..).map(|_| Style::border(color_adult))) + // take from above for lived number of weeks + .take(lived.num_weeks() as usize - 1) + // add a week for this week + .chain(once(Style::fill(color_today, color_today))) + // fill remaining weeks until death + .chain(repeat(Style::border(color_future))) + .take((life_expectancy - uncertainty * 2) as usize) + // add some fading around expected life span + .chain((0..uncertainty).rev().map(|i| { + let m = u8::MAX as i64; + let alpha = ((m * i) / (uncertainty)) as u8; + Style::border(format!("#eeeeee{:02x}", alpha)) + })) + // group weeks by color to save space + .group_by(|style| style.clone()) + .into_iter() + .map(|(style, weeks)| PeriodCtx { + style, + weeks: vec![(); weeks.count()], + }) + .collect(), }; Ok(Template::render("weeks", &context)) diff --git a/server/static/styles/common.css b/server/static/styles/common.css index 6bfeba5..c9fcf42 100644 --- a/server/static/styles/common.css +++ b/server/static/styles/common.css @@ -241,20 +241,26 @@ ul.striped_list > li:nth-child(odd) ul li:nth-child(odd) { background-color:#30 margin: auto; } -.life_calendar > p { +.life_calendar > span { + display: contents; +} + +.life_calendar > span > p { height: 0.5em; width: 0.5em; margin: 0.1em; border: solid 0.05em; border-radius: 0.5em; + background-color: inherit; } .life_calendar_ticker { position: relative; - top: -20rem; + top: -16rem; width: 100%; text-align: center; font-size: 10rem; + font-family: "Ubuntu Mono"; } .life_calendar_ticker > h1 { diff --git a/server/templates/header.hbs b/server/templates/header.hbs index 8a950ca..7e2209b 100644 --- a/server/templates/header.hbs +++ b/server/templates/header.hbs @@ -1,7 +1,11 @@

- 🗠 + 🕱 + - + 🗠 - stl - - 🕮 + 🕮 + - + 🖹

diff --git a/server/templates/weeks.hbs b/server/templates/weeks.hbs index e67e13b..25aa523 100644 --- a/server/templates/weeks.hbs +++ b/server/templates/weeks.hbs @@ -5,7 +5,11 @@ {{> header}}
- {{#each weeks}}

{{/each}} + {{#each periods}} + + {{#each weeks}}

{{/each}} +
+ {{/each}}

circa