From 766fd30842f2d5ecff622020301928f9241a0090 Mon Sep 17 00:00:00 2001 From: Joakim Hulthe Date: Fri, 30 Apr 2021 16:56:04 +0200 Subject: [PATCH] Make bump session button pretty --- server/src/main.rs | 4 +- server/src/routes/api.rs | 44 --------------- server/src/routes/pages.rs | 70 +++++++++++++++++++++++- server/src/routes/pages/stats.rs | 83 +++++++++++++++-------------- server/static/styles/calendar.css | 5 +- server/static/styles/common.css | 30 +++++++++++ server/templates/category_entry.hbs | 30 +++++++++-- server/templates/head.hbs | 2 + server/templates/index.hbs | 23 +++++--- server/templates/stats_chart.hbs | 2 +- 10 files changed, 192 insertions(+), 101 deletions(-) diff --git a/server/src/main.rs b/server/src/main.rs index c16f591..065a0ec 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -64,6 +64,9 @@ async fn main() -> io::Result<()> { routes::pages::index, routes::pages::history, routes::pages::session_edit, + routes::pages::start_session, + routes::pages::end_session, + routes::pages::bump_session, routes::pages::stats::single_stats, routes::pages::stats::all_stats, ], @@ -80,7 +83,6 @@ async fn main() -> io::Result<()> { routes::api::category::set_parent, routes::api::start_session, routes::api::end_session, - routes::api::bump_session, routes::api::edit_session, routes::api::delete_session, routes::api::wait_for_event, diff --git a/server/src/routes/api.rs b/server/src/routes/api.rs index 82c86c7..ce810a9 100644 --- a/server/src/routes/api.rs +++ b/server/src/routes/api.rs @@ -15,50 +15,6 @@ use rocket_contrib::uuid::Uuid; use sled::Transactional; use stl_lib::wfe::WaitForEvent; -#[post("/category//bump_session/minutes/")] -pub fn bump_session( - _auth: Authorized, - category_uuid: Uuid, - minutes: i64, - db: State<'_, sled::Db>, -) -> Result { - use crate::database::latest::trees::category; - - let duration = Duration::minutes(minutes); - let category_uuid_s = sled::IVec::from(serialize(&category_uuid.into_inner())?); - - let categories_tree = db.open_tree(category::NAME)?; - - (&categories_tree).transaction(|tx_categories| { - match tx_categories.get(&category_uuid_s)? { - None => Ok(Err(Status::NotFound.into())), - Some(data) => { - let mut category: category::V = deserialize(&data).unwrap(); - match category.started.as_mut() { - Some(started) => { - if let Some(new_started) = started.checked_sub_signed(duration) { - *started = new_started; - tx_categories - .insert(&category_uuid_s, serialize(&category).unwrap())?; - } else { - return Ok(Err(StatusJson::new( - Status::BadRequest, - "Duration subtract resulted in overflow", - ))); - } - - Ok(Ok(Redirect::to(uri!(pages::index)))) - } - None => Ok(Err(StatusJson::new( - Status::BadRequest, - "No active session", - ))), - } - } - } - })? -} - #[post("/category//start_session")] pub fn start_session( _auth: Authorized, diff --git a/server/src/routes/pages.rs b/server/src/routes/pages.rs index 3536cab..34c59f7 100644 --- a/server/src/routes/pages.rs +++ b/server/src/routes/pages.rs @@ -3,9 +3,11 @@ pub mod stats; use crate::auth::Authorized; use crate::database::latest::trees::{category, session}; use crate::status_json::StatusJson; +use crate::util::EventNotifier; use bincode::{deserialize, serialize}; use rocket::http::Status; -use rocket::{get, State}; +use rocket::response::Redirect; +use rocket::{get, post, uri, State}; use rocket_contrib::templates::Template; use rocket_contrib::uuid::Uuid; use serde_derive::{Deserialize, Serialize}; @@ -89,6 +91,72 @@ pub fn index(_auth: Authorized, db: State<'_, sled::Db>) -> Result/start_session")] +pub fn start_session( + _auth: Authorized, + category_uuid: Uuid, + event_notifier: State<'_, EventNotifier>, + db: State<'_, sled::Db>, +) -> Result { + super::api::toggle_category_session(category_uuid, true, event_notifier, db)?; + Ok(Redirect::to(uri!(index))) +} + +#[post("/category//end_session")] +pub fn end_session( + _auth: Authorized, + category_uuid: Uuid, + event_notifier: State<'_, EventNotifier>, + db: State<'_, sled::Db>, +) -> Result { + super::api::toggle_category_session(category_uuid, false, event_notifier, db)?; + Ok(Redirect::to(uri!(index))) +} + +#[post("/category//bump_session/minutes/")] +pub fn bump_session( + _auth: Authorized, + category_uuid: Uuid, + minutes: i64, + db: State<'_, sled::Db>, +) -> Result { + use crate::database::latest::trees::category; + + let duration = chrono::Duration::minutes(minutes); + let category_uuid_s = sled::IVec::from(serialize(&category_uuid.into_inner())?); + + let categories_tree = db.open_tree(category::NAME)?; + + (&categories_tree).transaction(|tx_categories| { + match tx_categories.get(&category_uuid_s)? { + None => Ok(Err(Status::NotFound.into())), + Some(data) => { + let mut category: category::V = deserialize(&data).unwrap(); + match category.started.as_mut() { + Some(started) => { + if let Some(new_started) = started.checked_sub_signed(duration) { + *started = new_started; + tx_categories + .insert(&category_uuid_s, serialize(&category).unwrap())?; + } else { + return Ok(Err(StatusJson::new( + Status::BadRequest, + "Duration subtract resulted in overflow", + ))); + } + + Ok(Ok(Redirect::to(uri!(index)))) + } + None => Ok(Err(StatusJson::new( + Status::BadRequest, + "No active session", + ))), + } + } + } + })? +} + #[get("/session//edit")] pub fn session_edit( _auth: Authorized, diff --git a/server/src/routes/pages/stats.rs b/server/src/routes/pages/stats.rs index 5076d9f..61b069e 100644 --- a/server/src/routes/pages/stats.rs +++ b/server/src/routes/pages/stats.rs @@ -300,7 +300,7 @@ struct CalendarDayCtx { #[derive(Debug, Serialize, Deserialize)] struct CalendarCtx { - days: Vec>>, + weeks: Vec>>, } fn compute_calendar_stats<'a, I>(sessions: I) -> CalendarCtx @@ -339,54 +339,57 @@ where .num_seconds() as f32; let weeks = days.iter().group_by(|(day, _)| day.iso_week()); + let mut weeks: Vec<_> = weeks + .into_iter() + .map(|(week, weekdays)| { + weekdays + .map(|(&day, duration)| { + let duration = if duration.is_zero() { + None + } else { + Some(duration.num_seconds() as u64) + }; - CalendarCtx { - days: weeks - .into_iter() - .map(|(week, weekdays)| { - weekdays - .map(|(&day, duration)| { - let duration = if duration.is_zero() { - None - } else { - Some(duration.num_seconds() as u64) - }; + let month = day.month(); - let month = day.month(); + let month_border = |other_day| match days.get(&other_day) { + Some(_) => other_day.month() != month, + None => true, + }; - let month_border = |other_day| match days.get(&other_day) { - Some(_) => other_day.month() != month, - None => true, - }; + let month_or_week_border = |other_day| match days.get(&other_day) { + Some(_) => other_day.iso_week() != week || month_border(other_day), + None => true, + }; - let month_or_week_border = |other_day| match days.get(&other_day) { - Some(_) => other_day.iso_week() != week || month_border(other_day), - None => true, - }; + const MIN_WEIGHT: f32 = 0.5; - const MIN_WEIGHT: f32 = 0.5; + let ctx = CalendarDayCtx { + border_left: month_border(day - Duration::weeks(1)), + border_right: month_border(day + Duration::weeks(1)), + border_top: month_or_week_border(day - Duration::days(1)), + border_bottom: month_or_week_border(day + Duration::days(1)), - let ctx = CalendarDayCtx { - border_left: month_border(day - Duration::weeks(1)), - border_right: month_border(day + Duration::weeks(1)), - border_top: month_or_week_border(day - Duration::days(1)), - border_bottom: month_or_week_border(day + Duration::days(1)), + weight: duration + .map(|d| d as f32 / biggest_day_duration) + .map(|w| (MIN_WEIGHT + w * (1.0 - MIN_WEIGHT)).clamp(0.0, 1.0)) + .unwrap_or(1.0), - weight: duration - .map(|d| d as f32 / biggest_day_duration) - .map(|w| (MIN_WEIGHT + w * (1.0 - MIN_WEIGHT)).clamp(0.0, 1.0)) - .unwrap_or(1.0), + duration, + }; - duration, - }; + //(day.weekday(), Some(ctx)) + Some(ctx) + }) + .collect() + }) + .collect(); - //(day.weekday(), Some(ctx)) - Some(ctx) - }) - .collect() - }) - .collect(), - } + // calendar is shown as flex-direction: row-reverse + // because it should be scrolled from the right + weeks.reverse(); + + CalendarCtx { weeks } } #[cfg(test)] diff --git a/server/static/styles/calendar.css b/server/static/styles/calendar.css index 0811629..d64f5fa 100644 --- a/server/static/styles/calendar.css +++ b/server/static/styles/calendar.css @@ -1,6 +1,9 @@ .cal { display: flex; - flex-direction: row; + flex-direction: row-reverse; + overflow-y: auto; + max-width: max-content; + padding-left: 2rem; } .cal_col { diff --git a/server/static/styles/common.css b/server/static/styles/common.css index 9832632..451078f 100644 --- a/server/static/styles/common.css +++ b/server/static/styles/common.css @@ -120,6 +120,36 @@ ul.striped_list > li:nth-child(odd) ul li:nth-child(odd) { background-color:#30 border-width: 0px 0 0px 50px; } +.category_bump_button { + position: absolute; + border: 0; + padding: 0; + margin: 0; + + width: 3rem; + height: 3rem; + margin-left: -1.2rem; + border-radius: 1.5rem; + border: solid #a4829c 0.3rem; + font-family: Ubuntu; + font-weight: 1000; + background: dimgray; + color: wheat; + + transition: all ease-in-out 0.2s; +} + +.category_bump_button:hover { + background: wheat; + color: dimgray; + cursor: pointer; + + transition: background color ease-in-out 0.2s; +} + +.category_bump_button:active { +} + .history_entry { padding: 0.2em; padding-left: 0.5em; diff --git a/server/templates/category_entry.hbs b/server/templates/category_entry.hbs index 23a8414..a885d55 100644 --- a/server/templates/category_entry.hbs +++ b/server/templates/category_entry.hbs @@ -4,14 +4,34 @@ style="background-color: {{this.category.color}}" > {{this.category.name}} - {{#if this.category.started}} -
- -
- {{/if}}
+ {{#if this.category.started}} +
+ + {{/if}} + + + +