From f8f39fc5421257f91f0421408d9e4f541da1ad97 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Thu, 28 Dec 2023 14:34:32 -0500 Subject: [PATCH] Update the historical view when a change happens in the db --- fitnesstrax/app/src/app.rs | 9 +- fitnesstrax/app/src/app_window.rs | 27 +++++- fitnesstrax/app/src/views/historical_view.rs | 90 ++++++++++++-------- 3 files changed, 86 insertions(+), 40 deletions(-) diff --git a/fitnesstrax/app/src/app.rs b/fitnesstrax/app/src/app.rs index f069638..bb6d277 100644 --- a/fitnesstrax/app/src/app.rs +++ b/fitnesstrax/app/src/app.rs @@ -59,6 +59,8 @@ pub enum AppResponse { /// change has happened. Further, the UI needs to save PathBuf to settings, because the /// gio::Settings system can't be run in the fully async background. DatabaseChanged(PathBuf), + + RecordSaved(RecordId), } /// The real, headless application. This is where all of the logic will reside. @@ -100,15 +102,16 @@ impl App { }, AppInvocation::UpdateRecord(record) => match *self.database.write().unwrap() { Some(ref mut database) => { + let id = record.id.clone(); database.update(record).unwrap(); - AppResponse::Records(vec![]) + AppResponse::RecordSaved(id) } None => AppResponse::NoDatabase, }, AppInvocation::PutRecord(record) => match *self.database.write().unwrap() { Some(ref mut database) => { - database.put(record).unwrap(); - AppResponse::Records(vec![]) + let id = database.put(record).unwrap(); + AppResponse::RecordSaved(id) } None => AppResponse::NoDatabase, }, diff --git a/fitnesstrax/app/src/app_window.rs b/fitnesstrax/app/src/app_window.rs index 6adb4f7..4357eaf 100644 --- a/fitnesstrax/app/src/app_window.rs +++ b/fitnesstrax/app/src/app_window.rs @@ -122,6 +122,7 @@ impl AppWindow { } pub fn process_response(&self, response: AppResponse) { + println!("processing response: {:?}", response); match response { AppResponse::DatabaseChanged(db_path) => { self.settings @@ -132,8 +133,32 @@ impl AppWindow { AppResponse::NoDatabase => { self.change_view(ViewName::Welcome); } + AppResponse::RecordSaved(_) => match *self.current_view.borrow_mut() { + View::Historical(ref view) => { + let _ = self + .app_tx + .send_blocking(AppInvocation::RequestRecords(view.time_window())); + } + _ => {} + }, AppResponse::Records(records) => { - self.change_view(ViewName::Historical(records)); + let mut current = self.current_view.borrow_mut(); + if let View::Historical(ref view) = *current { + view.set_records(records); + } else { + self.layout.remove(¤t.widget()); + *current = self.construct_view(ViewName::Historical(records)); + self.layout.append(¤t.widget()); + } + /* + match self.current_view.borrow_mut() { + View::Historical(ref view) => view.set_records(records), + mut current => { + self.layout.remove(¤t.widget()); + *current = self.construct_view(ViewName::Historical(records)); + self.layout.append(¤t.widget()); + } + */ } } } diff --git a/fitnesstrax/app/src/views/historical_view.rs b/fitnesstrax/app/src/views/historical_view.rs index ad68396..20e074d 100644 --- a/fitnesstrax/app/src/views/historical_view.rs +++ b/fitnesstrax/app/src/views/historical_view.rs @@ -27,6 +27,7 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; /// records. pub struct HistoricalViewPrivate { time_window: RefCell, + list_view: gtk::ListView, } #[glib::object_subclass] @@ -36,35 +37,6 @@ impl ObjectSubclass for HistoricalViewPrivate { type ParentType = gtk::Box; fn new() -> Self { - Self { - time_window: RefCell::new(DayInterval::default()), - } - } -} - -impl ObjectImpl for HistoricalViewPrivate {} -impl WidgetImpl for HistoricalViewPrivate {} -impl BoxImpl for HistoricalViewPrivate {} - -glib::wrapper! { - pub struct HistoricalView(ObjectSubclass) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable; -} - -impl HistoricalView { - pub fn new(records: Vec>, on_select_day: Rc) -> Self - where - SelectFn: Fn(chrono::NaiveDate, Vec>) + 'static, - { - let s: Self = Object::builder().build(); - s.set_orientation(gtk::Orientation::Vertical); - s.set_css_classes(&["historical"]); - - let grouped_records = - GroupedRecords::new((*s.imp().time_window.borrow()).clone()).with_data(records); - - let mut model = gio::ListStore::new::(); - model.extend(grouped_records.items()); - let factory = gtk::SignalListItemFactory::new(); factory.connect_setup(move |_, list_item| { list_item @@ -91,12 +63,43 @@ impl HistoricalView { summary.set_data(records.date(), records.records()); }); - let lst = gtk::ListView::builder() - .model(>k::NoSelection::new(Some(model))) - .factory(&factory) - .single_click_activate(true) - .build(); - lst.connect_activate({ + Self { + time_window: RefCell::new(DayInterval::default()), + list_view: gtk::ListView::builder() + .factory(&factory) + .single_click_activate(true) + .build(), + } + } +} + +impl ObjectImpl for HistoricalViewPrivate {} +impl WidgetImpl for HistoricalViewPrivate {} +impl BoxImpl for HistoricalViewPrivate {} + +glib::wrapper! { + pub struct HistoricalView(ObjectSubclass) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable; +} + +impl HistoricalView { + pub fn new(records: Vec>, on_select_day: Rc) -> Self + where + SelectFn: Fn(chrono::NaiveDate, Vec>) + 'static, + { + let s: Self = Object::builder().build(); + s.set_orientation(gtk::Orientation::Vertical); + s.set_css_classes(&["historical"]); + + let grouped_records = + GroupedRecords::new((*s.imp().time_window.borrow()).clone()).with_data(records); + + let mut model = gio::ListStore::new::(); + model.extend(grouped_records.items()); + s.imp() + .list_view + .set_model(Some(>k::NoSelection::new(Some(model)))); + + s.imp().list_view.connect_activate({ let on_select_day = on_select_day.clone(); move |s, idx| { // This gets triggered whenever the user clicks on an item on the list. What we @@ -108,10 +111,25 @@ impl HistoricalView { } }); - s.append(&lst); + s.append(&s.imp().list_view); s } + + pub fn set_records(&self, records: Vec>) { + println!("set_records: {:?}", records); + let grouped_records = + GroupedRecords::new((self.imp().time_window.borrow()).clone()).with_data(records); + let mut model = gio::ListStore::new::(); + model.extend(grouped_records.items()); + self.imp() + .list_view + .set_model(Some(>k::NoSelection::new(Some(model)))); + } + + pub fn time_window(&self) -> DayInterval { + self.imp().time_window.borrow().clone() + } } #[derive(Default)]