From e670dab4826006dda1bccdd05d99a61b4fe2b900 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 12 Jul 2020 12:33:58 +0530 Subject: add new mode: week view mode accessible via 'v' (single habit week mode toggle) and 'V' (bulk week mode) from any mode, press 'esc' to go back to day mode (this is probably the 'normal' mode of dijo) --- src/app.rs | 29 ++++++++++++++++++--- src/views.rs | 85 +++++++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 82 insertions(+), 32 deletions(-) diff --git a/src/app.rs b/src/app.rs index f39ae3c..1240877 100644 --- a/src/app.rs +++ b/src/app.rs @@ -111,7 +111,7 @@ impl App { fn status(&self) -> StatusLine { let today = chrono::Local::now().naive_utc().date(); let remaining = self.habits.iter().map(|h| h.remaining(today)).sum::(); - let total = self.habits.iter().map(|h| h.total()).sum::(); + let total = self.habits.iter().map(|h| h.goal()).sum::(); let completed = total - remaining; let timestamp = if self.view_month_offset == 0 { @@ -124,7 +124,7 @@ impl App { let months = self.view_month_offset; format!( "{:>width$}", - format!("{} months ago", self.view_month_offset), + format!("{} months ago", months), width = CONFIGURATION.view_width * CONFIGURATION.grid_width ) }; @@ -226,7 +226,7 @@ impl View for App { let view_height = CONFIGURATION.view_height; let width = { if self.habits.len() > 0 { - grid_width * view_width + grid_width * (view_width + 2) } else { 0 } @@ -283,6 +283,29 @@ impl View for App { self.save_state(); return EventResult::with_cb(|s| s.quit()); } + Event::Char('v') => { + if self.habits.is_empty() { + return EventResult::Consumed(None); + } + if self.habits[self.focus].view_mode() == ViewMode::Month { + self.set_mode(ViewMode::Day) + } else { + self.set_mode(ViewMode::Month) + } + return EventResult::Consumed(None); + } + Event::Char('V') => { + for habit in self.habits.iter_mut() { + habit.set_view_mode(ViewMode::Month); + } + return EventResult::Consumed(None); + } + Event::Key(Key::Esc) => { + for habit in self.habits.iter_mut() { + habit.set_view_mode(ViewMode::Day); + } + return EventResult::Consumed(None); + } /* We want sifting to be an app level function, * that later trickles down into each habit diff --git a/src/views.rs b/src/views.rs index 3e623a9..f5ba01b 100644 --- a/src/views.rs +++ b/src/views.rs @@ -7,7 +7,7 @@ use cursive::{Printer, Vec2}; use chrono::prelude::*; use chrono::{Duration, Local, NaiveDate}; -use crate::habit::{Bit, Count, Habit, TrackEvent}; +use crate::habit::{Bit, Count, Habit, TrackEvent, ViewMode}; use crate::CONFIGURATION; @@ -63,37 +63,64 @@ where }, ); - // fn draw_day(&self, p: &Printer) { }; - // fn draw_month(&self, p: &Printer) {}; - - // match self.view_mode() { - // ViewMode::Day => draw_day(self, p), - // ViewMode::Month => - // } - - //let draw_day = |printer: &Printer| { - let mut i = 1; - while let Some(d) = NaiveDate::from_ymd_opt(year, month, i) { - let day_style; - if self.reached_goal(d) { - day_style = goal_reached_style; - } else { - day_style = todo_style; - } - let coords: Vec2 = ((i % 7) * 3, i / 7 + 2).into(); - if let Some(c) = self.get_by_date(d) { - printer.with_style(day_style, |p| { - p.print(coords, &format!("{:^3}", c)); - }); - } else { + let draw_month = |printer: &Printer| { + let days = (1..31) + .map(|i| NaiveDate::from_ymd_opt(year, month, i)) + .flatten() // dates 28-31 may not exist, ignore them if they don't + .collect::>(); + for (week, line_nr) in days.chunks(7).zip(2..) { + let weekly_goal = self.goal() * week.len() as u32; + let is_this_week = week.contains(&Local::now().naive_utc().date()); + let remaining = week.iter().map(|&i| self.remaining(i)).sum::(); + let completions = weekly_goal - remaining; + let full = CONFIGURATION.view_width - 8; + let bars_to_fill = (completions * full as u32) / weekly_goal; + let percentage = (completions as f64 * 100f64) / weekly_goal as f64; printer.with_style(future_style, |p| { - p.print(coords, &format!("{:^3}", CONFIGURATION.future_chr)); + p.print((4, line_nr), &"―".repeat(full)); + }); + printer.with_style(goal_reached_style, |p| { + p.print((4, line_nr), &"―".repeat(bars_to_fill as usize)); }); + printer.with_style( + if is_this_week { + Style::none() + } else { + future_style + }, + |p| { + p.print((0, line_nr), &format!("{:3.0}% ", percentage)); + }, + ); } - i += 1; - } - //}; - //draw_day(printer); + }; + let draw_day = |printer: &Printer| { + let mut i = 1; + while let Some(d) = NaiveDate::from_ymd_opt(year, month, i) { + let day_style; + if self.reached_goal(d) { + day_style = goal_reached_style; + } else { + day_style = todo_style; + } + let coords: Vec2 = ((i % 7) * 3, i / 7 + 2).into(); + if let Some(c) = self.get_by_date(d) { + printer.with_style(day_style, |p| { + p.print(coords, &format!("{:^3}", c)); + }); + } else { + printer.with_style(future_style, |p| { + p.print(coords, &format!("{:^3}", CONFIGURATION.future_chr)); + }); + } + i += 1; + } + }; + match self.view_mode() { + ViewMode::Day => draw_day(printer), + ViewMode::Month => draw_month(printer), + _ => draw_day(printer), + }; } fn required_size(&mut self, _: Vec2) -> Vec2 { -- cgit v1.2.3