From 2d476f266c744cd51e9d1975e8f0943c4677562e Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Mon, 29 Jan 2024 08:26:41 -0500 Subject: [PATCH] Create Duration and Distance structures to handle rendering These structures handle parsing and rendering of a Duration and a Distance, allowing that knowledge to be centralized and reused. Then I'm using those structures in a variety of places in order to ensure that the information gets rendered consistently. --- fitnesstrax/app/src/components/day.rs | 2 +- fitnesstrax/app/src/components/text_entry.rs | 2 +- .../app/src/components/time_distance.rs | 27 +++++++++---------- fitnesstrax/app/src/view_models/day_detail.rs | 18 +++++++------ 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/fitnesstrax/app/src/components/day.rs b/fitnesstrax/app/src/components/day.rs index ee6e4f0..5d1d713 100644 --- a/fitnesstrax/app/src/components/day.rs +++ b/fitnesstrax/app/src/components/day.rs @@ -418,7 +418,7 @@ where biking_button.connect_clicked({ let view_model = view_model.clone(); move |_| { - let workout = view_model.new_record(RecordType::Walk); + let workout = view_model.new_record(RecordType::BikeRide); add_row(workout); } }); diff --git a/fitnesstrax/app/src/components/text_entry.rs b/fitnesstrax/app/src/components/text_entry.rs index 76004df..cb560a4 100644 --- a/fitnesstrax/app/src/components/text_entry.rs +++ b/fitnesstrax/app/src/components/text_entry.rs @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with Fit use crate::types::{ DistanceFormatter, DurationFormatter, FormatOption, ParseError, TimeFormatter, WeightFormatter, }; -use dimensioned::si; use gtk::prelude::*; use std::{cell::RefCell, rc::Rc}; +pub type Renderer = dyn Fn(&T) -> String; pub type Parser = dyn Fn(&str) -> Result; pub type OnUpdate = dyn Fn(Option); diff --git a/fitnesstrax/app/src/components/time_distance.rs b/fitnesstrax/app/src/components/time_distance.rs index 1b09a22..5032ef9 100644 --- a/fitnesstrax/app/src/components/time_distance.rs +++ b/fitnesstrax/app/src/components/time_distance.rs @@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License along with Fit // use dimensioned::si; use crate::{ components::{distance_field, duration_field, time_field}, - types::{DistanceFormatter, DurationFormatter, TimeFormatter}, + types::{DistanceFormatter, DurationFormatter, FormatOption, TimeFormatter}, }; use dimensioned::si; use ft_core::{RecordType, TimeDistance}; @@ -28,20 +28,17 @@ use gtk::{prelude::*, subclass::prelude::*}; use std::{cell::RefCell, rc::Rc}; pub fn time_distance_summary( - distance: si::Meter, - duration: si::Second, + distance: DistanceFormatter, + duration: DurationFormatter, ) -> Option { - let text = match (distance > si::M, duration > si::S) { + let text = match (*distance > si::M, *duration > si::S) { (true, true) => Some(format!( - "{} kilometers of biking in {} minutes", - distance.value_unsafe / 1000., - duration.value_unsafe / 60. + "{} of biking in {}", + distance.format(FormatOption::Full), + duration.format(FormatOption::Full) )), - (true, false) => Some(format!( - "{} kilometers of biking", - distance.value_unsafe / 1000. - )), - (false, true) => Some(format!("{} seconds of biking", duration.value_unsafe / 60.)), + (true, false) => Some(format!("{} of biking", distance.format(FormatOption::Full))), + (false, true) => Some(format!("{} of biking", duration.format(FormatOption::Full))), (false, false) => None, }; @@ -75,7 +72,7 @@ pub fn time_distance_detail(type_: ft_core::RecordType, record: ft_core::TimeDis .label( record .distance - .map(|dist| format!("{}", dist)) + .map(|dist| DistanceFormatter::from(dist).format(FormatOption::Abbreviated)) .unwrap_or("".to_owned()), ) .build(), @@ -87,7 +84,9 @@ pub fn time_distance_detail(type_: ft_core::RecordType, record: ft_core::TimeDis .label( record .duration - .map(|duration| format!("{}", duration)) + .map(|duration| { + DurationFormatter::from(duration).format(FormatOption::Abbreviated) + }) .unwrap_or("".to_owned()), ) .build(), diff --git a/fitnesstrax/app/src/view_models/day_detail.rs b/fitnesstrax/app/src/view_models/day_detail.rs index e82166d..81a22ed 100644 --- a/fitnesstrax/app/src/view_models/day_detail.rs +++ b/fitnesstrax/app/src/view_models/day_detail.rs @@ -14,8 +14,10 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see . */ -use crate::{app::App, types::WeightFormatter}; -use dimensioned::si; +use crate::{ + app::App, + types::{DistanceFormatter, DurationFormatter, WeightFormatter}, +}; use emseries::{Record, RecordId, Recordable}; use ft_core::{RecordType, TimeDistance, TraxRecord}; use std::{ @@ -166,9 +168,9 @@ impl DayDetailViewModel { *record = Some(new_record); } - pub fn biking_summary(&self) -> (si::Meter, si::Second) { + pub fn biking_summary(&self) -> (DistanceFormatter, DurationFormatter) { self.records.read().unwrap().iter().fold( - (0. * si::M, 0. * si::S), + (DistanceFormatter::default(), DurationFormatter::default()), |(acc_distance, acc_duration), (_, record)| match record.data() { Some(Record { data: @@ -178,11 +180,11 @@ impl DayDetailViewModel { .. }) => ( distance - .map(|distance| acc_distance + distance) + .map(|distance| acc_distance + DistanceFormatter::from(distance)) .unwrap_or(acc_distance), - (duration - .map(|duration| acc_duration + duration) - .unwrap_or(acc_duration)), + duration + .map(|duration| acc_duration + DurationFormatter::from(duration)) + .unwrap_or(acc_duration), ), _ => (acc_distance, acc_duration),