diff --git a/fitnesstrax/app/src/app_window.rs b/fitnesstrax/app/src/app_window.rs index f5f2d46..75f6dbb 100644 --- a/fitnesstrax/app/src/app_window.rs +++ b/fitnesstrax/app/src/app_window.rs @@ -134,7 +134,7 @@ impl AppWindow { } fn show_historical_view(&self, records: Vec>) { - let view = View::Historical(HistoricalView::new(records, { + let view = View::Historical(HistoricalView::new(self.app.clone(), records, { let s = self.clone(); Rc::new(move |date, records| { let layout = gtk::Box::new(gtk::Orientation::Vertical, 0); diff --git a/fitnesstrax/app/src/components/day.rs b/fitnesstrax/app/src/components/day.rs index 7bbd3db..b4b130d 100644 --- a/fitnesstrax/app/src/components/day.rs +++ b/fitnesstrax/app/src/components/day.rs @@ -20,14 +20,12 @@ use crate::{ components::{steps_editor, weight_editor, ActionGroup, Steps, Weight}, view_models::DayDetailViewModel, }; -use emseries::Record; use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; use std::cell::RefCell; pub struct DaySummaryPrivate { date: gtk::Label, - weight: RefCell>, } #[glib::object_subclass] @@ -41,10 +39,7 @@ impl ObjectSubclass for DaySummaryPrivate { .css_classes(["day-summary__date"]) .halign(gtk::Align::Start) .build(); - Self { - date, - weight: RefCell::new(None), - } + Self { date } } } @@ -75,37 +70,34 @@ impl DaySummary { Self::default() } - pub fn set_data(&self, date: chrono::NaiveDate, records: Vec>) { + pub fn set_data(&self, view_model: DayDetailViewModel) { self.imp() .date - .set_text(&date.format("%Y-%m-%d").to_string()); + .set_text(&view_model.date.format("%Y-%m-%d").to_string()); - if let Some(ref weight_label) = *self.imp().weight.borrow() { - self.remove(weight_label); + let row = gtk::Box::builder().build(); + + let label = gtk::Label::builder() + .halign(gtk::Align::Start) + .css_classes(["day-summary__weight"]) + .build(); + if let Some(w) = view_model.weight() { + label.set_label(&w.to_string()) } + row.append(&label); - if let Some(Record { - data: ft_core::TraxRecord::Weight(weight_record), - .. - }) = records.iter().find(|f| f.data.is_weight()) - { - let label = gtk::Label::builder() - .halign(gtk::Align::Start) - .label(weight_record.weight.to_string()) - .css_classes(["day-summary__weight"]) - .build(); - self.append(&label); - *self.imp().weight.borrow_mut() = Some(label); + self.append(&label); + + let label = gtk::Label::builder() + .halign(gtk::Align::Start) + .css_classes(["day-summary__weight"]) + .build(); + if let Some(s) = view_model.steps() { + label.set_label(&format!("{} steps", s.to_string())); } + row.append(&label); - /* - self.append( - >k::Label::builder() - .halign(gtk::Align::Start) - .label("15km of biking in 60 minutes") - .build(), - ); - */ + self.append(&row); } } diff --git a/fitnesstrax/app/src/view_models/day_detail.rs b/fitnesstrax/app/src/view_models/day_detail.rs index f823d6f..f32e75f 100644 --- a/fitnesstrax/app/src/view_models/day_detail.rs +++ b/fitnesstrax/app/src/view_models/day_detail.rs @@ -186,6 +186,24 @@ impl DayDetailViewModel { None => {} } + let steps_record = s.steps.read().unwrap().clone(); + match steps_record { + Some(RecordState::New(steps)) => { + let _ = app.put_record(TraxRecord::Steps(steps)).await; + } + Some(RecordState::Original(_)) => {} + Some(RecordState::Updated(steps)) => { + let _ = app + .update_record(Record { + id: steps.id, + data: TraxRecord::Steps(steps.data), + }) + .await; + } + Some(RecordState::Deleted(_)) => {} + None => {} + } + let records = s .records .write() diff --git a/fitnesstrax/app/src/views/historical_view.rs b/fitnesstrax/app/src/views/historical_view.rs index 23bccad..2e80e40 100644 --- a/fitnesstrax/app/src/views/historical_view.rs +++ b/fitnesstrax/app/src/views/historical_view.rs @@ -14,7 +14,9 @@ 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::{components::DaySummary, types::DayInterval}; +use crate::{ + app::App, components::DaySummary, types::DayInterval, view_models::DayDetailViewModel, +}; use chrono::NaiveDate; use emseries::Record; use ft_core::TraxRecord; @@ -26,7 +28,8 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; /// daily summaries, daily details, and will provide all functions the user may need for editing /// records. pub struct HistoricalViewPrivate { - time_window: RefCell, + app: Rc>>, + time_window: Rc>, list_view: gtk::ListView, } @@ -45,31 +48,42 @@ impl ObjectSubclass for HistoricalViewPrivate { .set_child(Some(&DaySummary::new())); }); - factory.connect_bind(move |_, list_item| { - let records = list_item - .downcast_ref::() - .expect("should be a ListItem") - .item() - .and_downcast::() - .expect("should be a DaySummary"); - - let summary = list_item - .downcast_ref::() - .expect("should be a ListItem") - .child() - .and_downcast::() - .expect("should be a DaySummary"); - - summary.set_data(records.date(), records.records()); - }); - - Self { - time_window: RefCell::new(DayInterval::default()), + let s = Self { + app: Rc::new(RefCell::new(None)), + time_window: Rc::new(RefCell::new(DayInterval::default())), list_view: gtk::ListView::builder() .factory(&factory) .single_click_activate(true) .build(), - } + }; + factory.connect_bind({ + let app = s.app.clone(); + move |_, list_item| { + let records = list_item + .downcast_ref::() + .expect("should be a ListItem") + .item() + .and_downcast::() + .expect("should be a DaySummary"); + + let summary = list_item + .downcast_ref::() + .expect("should be a ListItem") + .child() + .and_downcast::() + .expect("should be a DaySummary"); + + if let Some(app) = app.borrow().clone() { + summary.set_data(DayDetailViewModel::new( + records.date(), + records.records(), + app.clone(), + )); + } + } + }); + + s } } @@ -82,7 +96,11 @@ glib::wrapper! { } impl HistoricalView { - pub fn new(records: Vec>, on_select_day: Rc) -> Self + pub fn new( + app: App, + records: Vec>, + on_select_day: Rc, + ) -> Self where SelectFn: Fn(chrono::NaiveDate, Vec>) + 'static, { @@ -90,6 +108,8 @@ impl HistoricalView { s.set_orientation(gtk::Orientation::Vertical); s.set_css_classes(&["historical"]); + *s.imp().app.borrow_mut() = Some(app); + let grouped_records = GroupedRecords::new((*s.imp().time_window.borrow()).clone()).with_data(records);