Render and be able to edit bike rides (and sorta other time distance workouts) #169

Merged
savanni merged 13 commits from fitnesstrax/time-distance-workout into main 2024-02-09 00:05:26 +00:00
2 changed files with 90 additions and 50 deletions
Showing only changes of commit 74df2880bb - Show all commits

View File

@ -238,8 +238,19 @@ impl DayEdit {
*s.imp().on_finished.borrow_mut() = Box::new(on_finished); *s.imp().on_finished.borrow_mut() = Box::new(on_finished);
*s.imp().view_model.borrow_mut() = Some(view_model.clone()); *s.imp().view_model.borrow_mut() = Some(view_model.clone());
s.append( s.append(&control_buttons(&s, &view_model));
&ActionGroup::builder() s.append(&weight_and_steps_row(&view_model));
s
}
fn finish(&self) {
(self.imp().on_finished.borrow())()
}
}
fn control_buttons(s: &DayEdit, view_model: &DayDetailViewModel) -> ActionGroup {
ActionGroup::builder()
.primary_action("Save", { .primary_action("Save", {
let s = s.clone(); let s = s.clone();
let view_model = view_model.clone(); let view_model = view_model.clone();
@ -252,17 +263,22 @@ impl DayEdit {
let s = s.clone(); let s = s.clone();
let view_model = view_model.clone(); let view_model = view_model.clone();
move || { move || {
view_model.revert(); let s = s.clone();
let view_model = view_model.clone();
glib::spawn_future_local(async move {
view_model.revert().await;
s.finish(); s.finish();
});
} }
}) })
.build(), .build()
); }
let top_row = gtk::Box::builder() fn weight_and_steps_row(view_model: &DayDetailViewModel) -> gtk::Box {
let row = gtk::Box::builder()
.orientation(gtk::Orientation::Horizontal) .orientation(gtk::Orientation::Horizontal)
.build(); .build();
top_row.append( row.append(
&weight_field(view_model.weight().map(WeightFormatter::from), { &weight_field(view_model.weight().map(WeightFormatter::from), {
let view_model = view_model.clone(); let view_model = view_model.clone();
move |w| match w { move |w| match w {
@ -273,7 +289,7 @@ impl DayEdit {
.widget(), .widget(),
); );
top_row.append( row.append(
&steps_editor(view_model.steps(), { &steps_editor(view_model.steps(), {
let view_model = view_model.clone(); let view_model = view_model.clone();
move |s| match s { move |s| match s {
@ -283,12 +299,6 @@ impl DayEdit {
}) })
.widget(), .widget(),
); );
s.append(&top_row);
s row
}
fn finish(&self) {
(self.imp().on_finished.borrow())()
}
} }

View File

@ -374,8 +374,38 @@ impl DayDetailViewModel {
} }
} }
pub fn revert(&self) { pub async fn revert(&self) {
unimplemented!(); self.populate_records().await;
}
async fn populate_records(&self) {
let records = self.provider.records(self.date, self.date).await.unwrap();
let (weight_records, records): (Vec<Record<TraxRecord>>, Vec<Record<TraxRecord>>) =
records.into_iter().partition(|r| r.data.is_weight());
let (step_records, records): (Vec<Record<TraxRecord>>, Vec<Record<TraxRecord>>) =
records.into_iter().partition(|r| r.data.is_steps());
*self.weight.write().unwrap() = weight_records
.first()
.and_then(|r| match r.data {
TraxRecord::Weight(ref w) => Some((r.id.clone(), w.clone())),
_ => None,
})
.map(|(id, w)| RecordState::Original(Record { id, data: w }));
*self.steps.write().unwrap() = step_records
.first()
.and_then(|r| match r.data {
TraxRecord::Steps(ref w) => Some((r.id.clone(), w.clone())),
_ => None,
})
.map(|(id, w)| RecordState::Original(Record { id, data: w }));
*self.records.write().unwrap() = records
.into_iter()
.map(|r| (r.id.clone(), RecordState::Original(r)))
.collect::<HashMap<RecordId, RecordState<TraxRecord>>>();
} }
} }
@ -383,7 +413,7 @@ impl DayDetailViewModel {
mod test { mod test {
use super::*; use super::*;
use async_trait::async_trait; use async_trait::async_trait;
use chrono::{DateTime, FixedOffset, TimeZone}; use chrono::{DateTime, FixedOffset};
use dimensioned::si; use dimensioned::si;
use emseries::Record; use emseries::Record;
@ -640,7 +670,7 @@ mod test {
#[tokio::test] #[tokio::test]
async fn it_can_delete_an_existing_record() { async fn it_can_delete_an_existing_record() {
let (view_model, provider) = create_view_model().await; let (view_model, provider) = create_view_model().await;
let mut workout = view_model.time_distance_records().first().cloned().unwrap(); let workout = view_model.time_distance_records().first().cloned().unwrap();
view_model.remove_record(workout.id); view_model.remove_record(workout.id);
assert_eq!( assert_eq!(