Render and be able to edit bike rides (and sorta other time distance workouts) #169
|
@ -110,7 +110,7 @@ where
|
||||||
.map_err(EmseriesReadError::JSONParseError)
|
.map_err(EmseriesReadError::JSONParseError)
|
||||||
.and_then(Record::try_from)
|
.and_then(Record::try_from)
|
||||||
{
|
{
|
||||||
Ok(record) => records.insert(record.id.clone(), record.clone()),
|
Ok(record) => records.insert(record.id, record.clone()),
|
||||||
Err(EmseriesReadError::RecordDeleted(id)) => records.remove(&id),
|
Err(EmseriesReadError::RecordDeleted(id)) => records.remove(&id),
|
||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
|
@ -124,19 +124,16 @@ where
|
||||||
/// Put a new record into the database. A unique id will be assigned to the record and
|
/// Put a new record into the database. A unique id will be assigned to the record and
|
||||||
/// returned.
|
/// returned.
|
||||||
pub fn put(&mut self, entry: T) -> Result<RecordId, EmseriesWriteError> {
|
pub fn put(&mut self, entry: T) -> Result<RecordId, EmseriesWriteError> {
|
||||||
let uuid = RecordId::default();
|
let id = RecordId::default();
|
||||||
let record = Record {
|
let record = Record { id, data: entry };
|
||||||
id: uuid.clone(),
|
|
||||||
data: entry,
|
|
||||||
};
|
|
||||||
self.update(record)?;
|
self.update(record)?;
|
||||||
Ok(uuid)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update an existing record. The [RecordId] of the record passed into this function must match
|
/// Update an existing record. The [RecordId] of the record passed into this function must match
|
||||||
/// the [RecordId] of a record already in the database.
|
/// the [RecordId] of a record already in the database.
|
||||||
pub fn update(&mut self, record: Record<T>) -> Result<(), EmseriesWriteError> {
|
pub fn update(&mut self, record: Record<T>) -> Result<(), EmseriesWriteError> {
|
||||||
self.records.insert(record.id.clone(), record.clone());
|
self.records.insert(record.id, record.clone());
|
||||||
let write_res = match serde_json::to_string(&RecordOnDisk {
|
let write_res = match serde_json::to_string(&RecordOnDisk {
|
||||||
id: record.id,
|
id: record.id,
|
||||||
data: Some(record.data),
|
data: Some(record.data),
|
||||||
|
@ -166,7 +163,7 @@ where
|
||||||
self.records.remove(uuid);
|
self.records.remove(uuid);
|
||||||
|
|
||||||
let rec: RecordOnDisk<T> = RecordOnDisk {
|
let rec: RecordOnDisk<T> = RecordOnDisk {
|
||||||
id: uuid.clone(),
|
id: *uuid,
|
||||||
data: None,
|
data: None,
|
||||||
};
|
};
|
||||||
match serde_json::to_string(&rec) {
|
match serde_json::to_string(&rec) {
|
||||||
|
|
|
@ -166,6 +166,17 @@ impl<T: Clone + Recordable> Record<T> {
|
||||||
pub fn timestamp(&self) -> Timestamp {
|
pub fn timestamp(&self) -> Timestamp {
|
||||||
self.data.timestamp()
|
self.data.timestamp()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn map<Map, U>(self, map: Map) -> Record<U>
|
||||||
|
where
|
||||||
|
Map: Fn(T) -> U,
|
||||||
|
U: Clone + Recordable,
|
||||||
|
{
|
||||||
|
Record {
|
||||||
|
id: self.id,
|
||||||
|
data: map(self.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -23,12 +23,13 @@ use crate::{
|
||||||
types::WeightFormatter,
|
types::WeightFormatter,
|
||||||
view_models::DayDetailViewModel,
|
view_models::DayDetailViewModel,
|
||||||
};
|
};
|
||||||
use ft_core::TimeDistanceActivity;
|
use emseries::Record;
|
||||||
|
use ft_core::{TimeDistanceActivity, TraxRecord};
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{prelude::*, subclass::prelude::*};
|
use gtk::{prelude::*, subclass::prelude::*};
|
||||||
use std::cell::RefCell;
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use super::time_distance_detail;
|
use super::{time_distance::TimeDistanceEdit, time_distance_detail};
|
||||||
|
|
||||||
pub struct DaySummaryPrivate {
|
pub struct DaySummaryPrivate {
|
||||||
date: gtk::Label,
|
date: gtk::Label,
|
||||||
|
@ -237,9 +238,15 @@ 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());
|
||||||
|
|
||||||
|
let workout_buttons = workout_buttons(view_model.clone(), {
|
||||||
|
let s = s.clone();
|
||||||
|
move |workout| s.add_row(workout)
|
||||||
|
});
|
||||||
|
|
||||||
s.append(&control_buttons(&s, &view_model));
|
s.append(&control_buttons(&s, &view_model));
|
||||||
s.append(&weight_and_steps_row(&view_model));
|
s.append(&weight_and_steps_row(&view_model));
|
||||||
s.append(&workout_buttons());
|
s.append(&*s.imp().workout_rows.borrow());
|
||||||
|
s.append(&workout_buttons);
|
||||||
|
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
@ -247,6 +254,17 @@ impl DayEdit {
|
||||||
fn finish(&self) {
|
fn finish(&self) {
|
||||||
(self.imp().on_finished.borrow())()
|
(self.imp().on_finished.borrow())()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_row(&self, workout: Record<TraxRecord>) {
|
||||||
|
println!("add_row: {:?}", workout);
|
||||||
|
let workout_rows = self.imp().workout_rows.borrow();
|
||||||
|
|
||||||
|
#[allow(clippy::single_match)]
|
||||||
|
match workout.data {
|
||||||
|
TraxRecord::TimeDistance(r) => workout_rows.append(&TimeDistanceEdit::new(r, |_| {})),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn control_buttons(s: &DayEdit, view_model: &DayDetailViewModel) -> ActionGroup {
|
fn control_buttons(s: &DayEdit, view_model: &DayDetailViewModel) -> ActionGroup {
|
||||||
|
@ -303,24 +321,37 @@ fn weight_and_steps_row(view_model: &DayDetailViewModel) -> gtk::Box {
|
||||||
row
|
row
|
||||||
}
|
}
|
||||||
|
|
||||||
fn workout_buttons() -> gtk::Box {
|
fn workout_buttons<AddRow>(view_model: DayDetailViewModel, add_row: AddRow) -> gtk::Box
|
||||||
let sunrise_button = gtk::Button::builder()
|
where
|
||||||
.icon_name("daytime-sunrise-symbolic")
|
AddRow: Fn(Record<TraxRecord>) + 'static,
|
||||||
.width_request(64)
|
{
|
||||||
.height_request(64)
|
let add_row = Rc::new(add_row);
|
||||||
.build();
|
|
||||||
|
|
||||||
let walking_button = gtk::Button::builder()
|
let walking_button = gtk::Button::builder()
|
||||||
.icon_name("walking2-symbolic")
|
.icon_name("walking2-symbolic")
|
||||||
.width_request(64)
|
.width_request(64)
|
||||||
.height_request(64)
|
.height_request(64)
|
||||||
.build();
|
.build();
|
||||||
|
walking_button.connect_clicked({
|
||||||
|
let view_model = view_model.clone();
|
||||||
|
let add_row = add_row.clone();
|
||||||
|
move |_| {
|
||||||
|
let workout = view_model.new_time_distance(TimeDistanceActivity::Walking);
|
||||||
|
add_row(workout.map(TraxRecord::TimeDistance));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let running_button = gtk::Button::builder()
|
let running_button = gtk::Button::builder()
|
||||||
.icon_name("running-symbolic")
|
.icon_name("running-symbolic")
|
||||||
.width_request(64)
|
.width_request(64)
|
||||||
.height_request(64)
|
.height_request(64)
|
||||||
.build();
|
.build();
|
||||||
|
running_button.connect_clicked({
|
||||||
|
let view_model = view_model.clone();
|
||||||
|
move |_| {
|
||||||
|
let workout = view_model.new_time_distance(TimeDistanceActivity::Running);
|
||||||
|
add_row(workout.map(TraxRecord::TimeDistance));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let layout = gtk::Box::builder()
|
let layout = gtk::Box::builder()
|
||||||
.orientation(gtk::Orientation::Vertical)
|
.orientation(gtk::Orientation::Vertical)
|
||||||
|
@ -328,7 +359,6 @@ fn workout_buttons() -> gtk::Box {
|
||||||
let row = gtk::Box::builder()
|
let row = gtk::Box::builder()
|
||||||
.orientation(gtk::Orientation::Horizontal)
|
.orientation(gtk::Orientation::Horizontal)
|
||||||
.build();
|
.build();
|
||||||
row.append(&sunrise_button);
|
|
||||||
row.append(&walking_button);
|
row.append(&walking_button);
|
||||||
row.append(&running_button);
|
row.append(&running_button);
|
||||||
layout.append(&row);
|
layout.append(&row);
|
||||||
|
|
|
@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License along with Fit
|
||||||
// use chrono::{Local, NaiveDate};
|
// use chrono::{Local, NaiveDate};
|
||||||
// use dimensioned::si;
|
// use dimensioned::si;
|
||||||
use dimensioned::si;
|
use dimensioned::si;
|
||||||
|
use ft_core::TimeDistance;
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{prelude::*, subclass::prelude::*};
|
use gtk::{prelude::*, subclass::prelude::*};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -130,6 +131,7 @@ impl Default for TimeDistanceEdit {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let s: Self = Object::builder().build();
|
let s: Self = Object::builder().build();
|
||||||
s.set_orientation(gtk::Orientation::Horizontal);
|
s.set_orientation(gtk::Orientation::Horizontal);
|
||||||
|
s.set_hexpand(true);
|
||||||
s.set_css_classes(&["time-distance-edit"]);
|
s.set_css_classes(&["time-distance-edit"]);
|
||||||
|
|
||||||
s
|
s
|
||||||
|
@ -137,12 +139,18 @@ impl Default for TimeDistanceEdit {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TimeDistanceEdit {
|
impl TimeDistanceEdit {
|
||||||
#[allow(unused)]
|
pub fn new<OnUpdate>(record: TimeDistance, _on_update: OnUpdate) -> Self
|
||||||
fn empty<OnUpdate>(_on_update: OnUpdate) -> Self
|
|
||||||
where
|
where
|
||||||
OnUpdate: Fn(&ft_core::TimeDistance),
|
OnUpdate: Fn(&ft_core::TimeDistance),
|
||||||
{
|
{
|
||||||
Self::default()
|
println!("new TimeDistanceEdit");
|
||||||
|
let s = Self::default();
|
||||||
|
|
||||||
|
s.append(>k::Label::new(Some(
|
||||||
|
record.datetime.format("%H:%M").to_string().as_ref(),
|
||||||
|
)));
|
||||||
|
|
||||||
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -30,7 +30,7 @@ use std::{
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum RecordState<T: Clone + Recordable> {
|
enum RecordState<T: Clone + Recordable> {
|
||||||
Original(Record<T>),
|
Original(Record<T>),
|
||||||
New(T),
|
New(Record<T>),
|
||||||
Updated(Record<T>),
|
Updated(Record<T>),
|
||||||
Deleted(Record<T>),
|
Deleted(Record<T>),
|
||||||
}
|
}
|
||||||
|
@ -57,19 +57,13 @@ impl<T: Clone + emseries::Recordable> RecordState<T> {
|
||||||
|
|
||||||
fn set_value(&mut self, value: T) {
|
fn set_value(&mut self, value: T) {
|
||||||
*self = match self {
|
*self = match self {
|
||||||
RecordState::Original(r) => RecordState::Updated(Record {
|
RecordState::Original(r) => RecordState::Updated(Record { data: value, ..*r }),
|
||||||
id: r.id.clone(),
|
RecordState::New(_) => RecordState::New(Record {
|
||||||
data: value,
|
id: RecordId::default(),
|
||||||
}),
|
|
||||||
RecordState::New(_) => RecordState::New(value),
|
|
||||||
RecordState::Updated(r) => RecordState::Updated(Record {
|
|
||||||
id: r.id.clone(),
|
|
||||||
data: value,
|
|
||||||
}),
|
|
||||||
RecordState::Deleted(r) => RecordState::Updated(Record {
|
|
||||||
id: r.id.clone(),
|
|
||||||
data: value,
|
data: value,
|
||||||
}),
|
}),
|
||||||
|
RecordState::Updated(r) => RecordState::Updated(Record { data: value, ..*r }),
|
||||||
|
RecordState::Deleted(r) => RecordState::Updated(Record { data: value, ..*r }),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +88,7 @@ impl<T: Clone + emseries::Recordable> Deref for RecordState<T> {
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
match self {
|
match self {
|
||||||
RecordState::Original(ref r) => &r.data,
|
RecordState::Original(ref r) => &r.data,
|
||||||
RecordState::New(ref r) => r,
|
RecordState::New(ref r) => &r.data,
|
||||||
RecordState::Updated(ref r) => &r.data,
|
RecordState::Updated(ref r) => &r.data,
|
||||||
RecordState::Deleted(ref r) => &r.data,
|
RecordState::Deleted(ref r) => &r.data,
|
||||||
}
|
}
|
||||||
|
@ -105,7 +99,7 @@ impl<T: Clone + emseries::Recordable> std::ops::DerefMut for RecordState<T> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
match self {
|
match self {
|
||||||
RecordState::Original(ref mut r) => &mut r.data,
|
RecordState::Original(ref mut r) => &mut r.data,
|
||||||
RecordState::New(ref mut r) => r,
|
RecordState::New(ref mut r) => &mut r.data,
|
||||||
RecordState::Updated(ref mut r) => &mut r.data,
|
RecordState::Updated(ref mut r) => &mut r.data,
|
||||||
RecordState::Deleted(ref mut r) => &mut r.data,
|
RecordState::Deleted(ref mut r) => &mut r.data,
|
||||||
}
|
}
|
||||||
|
@ -149,7 +143,7 @@ impl DayDetailViewModel {
|
||||||
weight_records
|
weight_records
|
||||||
.first()
|
.first()
|
||||||
.and_then(|r| match r.data {
|
.and_then(|r| match r.data {
|
||||||
TraxRecord::Weight(ref w) => Some((r.id.clone(), w.clone())),
|
TraxRecord::Weight(ref w) => Some((r.id, w.clone())),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.map(|(id, w)| RecordState::Original(Record { id, data: w })),
|
.map(|(id, w)| RecordState::Original(Record { id, data: w })),
|
||||||
|
@ -158,7 +152,7 @@ impl DayDetailViewModel {
|
||||||
step_records
|
step_records
|
||||||
.first()
|
.first()
|
||||||
.and_then(|r| match r.data {
|
.and_then(|r| match r.data {
|
||||||
TraxRecord::Steps(ref w) => Some((r.id.clone(), w.clone())),
|
TraxRecord::Steps(ref w) => Some((r.id, w.clone())),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.map(|(id, w)| RecordState::Original(Record { id, data: w })),
|
.map(|(id, w)| RecordState::Original(Record { id, data: w })),
|
||||||
|
@ -167,7 +161,7 @@ impl DayDetailViewModel {
|
||||||
records: Arc::new(RwLock::new(
|
records: Arc::new(RwLock::new(
|
||||||
records
|
records
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| (r.id.clone(), RecordState::Original(r)))
|
.map(|r| (r.id, RecordState::Original(r)))
|
||||||
.collect::<HashMap<RecordId, RecordState<TraxRecord>>>(),
|
.collect::<HashMap<RecordId, RecordState<TraxRecord>>>(),
|
||||||
)),
|
)),
|
||||||
})
|
})
|
||||||
|
@ -184,9 +178,12 @@ impl DayDetailViewModel {
|
||||||
date: self.date,
|
date: self.date,
|
||||||
weight: new_weight,
|
weight: new_weight,
|
||||||
}),
|
}),
|
||||||
None => RecordState::New(ft_core::Weight {
|
None => RecordState::New(Record {
|
||||||
date: self.date,
|
id: RecordId::default(),
|
||||||
weight: new_weight,
|
data: ft_core::Weight {
|
||||||
|
date: self.date,
|
||||||
|
weight: new_weight,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
*record = Some(new_record);
|
*record = Some(new_record);
|
||||||
|
@ -203,9 +200,12 @@ impl DayDetailViewModel {
|
||||||
date: self.date,
|
date: self.date,
|
||||||
count: new_count,
|
count: new_count,
|
||||||
}),
|
}),
|
||||||
None => RecordState::New(ft_core::Steps {
|
None => RecordState::New(Record {
|
||||||
date: self.date,
|
id: RecordId::default(),
|
||||||
count: new_count,
|
data: ft_core::Steps {
|
||||||
|
date: self.date,
|
||||||
|
count: new_count,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
*record = Some(new_record);
|
*record = Some(new_record);
|
||||||
|
@ -224,7 +224,7 @@ impl DayDetailViewModel {
|
||||||
self.records
|
self.records
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert(id.clone(), RecordState::New(tr));
|
.insert(id, RecordState::New(Record { id, data: tr }));
|
||||||
println!(
|
println!(
|
||||||
"records after new_time_distance: {:?}",
|
"records after new_time_distance: {:?}",
|
||||||
self.records.read().unwrap()
|
self.records.read().unwrap()
|
||||||
|
@ -233,11 +233,10 @@ impl DayDetailViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_time_distance(&self, workout: Record<TimeDistance>) {
|
pub fn update_time_distance(&self, workout: Record<TimeDistance>) {
|
||||||
let id = workout.id.clone();
|
|
||||||
let data = workout.data.clone();
|
let data = workout.data.clone();
|
||||||
|
|
||||||
let mut record_set = self.records.write().unwrap();
|
let mut record_set = self.records.write().unwrap();
|
||||||
record_set.entry(id).and_modify(|record_state| {
|
record_set.entry(workout.id).and_modify(|record_state| {
|
||||||
record_state.set_value(TraxRecord::TimeDistance(data));
|
record_state.set_value(TraxRecord::TimeDistance(data));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -250,7 +249,7 @@ impl DayDetailViewModel {
|
||||||
.filter(|(_, record)| record.exists())
|
.filter(|(_, record)| record.exists())
|
||||||
.filter_map(|(id, record_state)| match **record_state {
|
.filter_map(|(id, record_state)| match **record_state {
|
||||||
TraxRecord::TimeDistance(ref workout) => Some(Record {
|
TraxRecord::TimeDistance(ref workout) => Some(Record {
|
||||||
id: id.clone(),
|
id: *id,
|
||||||
data: workout.clone(),
|
data: workout.clone(),
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -283,7 +282,7 @@ impl DayDetailViewModel {
|
||||||
fn get_record(&self, id: &RecordId) -> Option<Record<TraxRecord>> {
|
fn get_record(&self, id: &RecordId) -> Option<Record<TraxRecord>> {
|
||||||
let record_set = self.records.read().unwrap();
|
let record_set = self.records.read().unwrap();
|
||||||
record_set.get(id).map(|record| Record {
|
record_set.get(id).map(|record| Record {
|
||||||
id: id.clone(),
|
id: *id,
|
||||||
data: (**record).clone(),
|
data: (**record).clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -303,18 +302,19 @@ impl DayDetailViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&self) {
|
pub fn save(&self) {
|
||||||
glib::spawn_future({
|
let s = self.clone();
|
||||||
let s = self.clone();
|
|
||||||
async move { s.async_save().await }
|
glib::spawn_future(async move { s.async_save().await });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn async_save(&self) {
|
pub async fn async_save(&self) {
|
||||||
println!("async_save");
|
|
||||||
let weight_record = self.weight.read().unwrap().clone();
|
let weight_record = self.weight.read().unwrap().clone();
|
||||||
match weight_record {
|
match weight_record {
|
||||||
Some(RecordState::New(data)) => {
|
Some(RecordState::New(data)) => {
|
||||||
let _ = self.provider.put_record(TraxRecord::Weight(data)).await;
|
let _ = self
|
||||||
|
.provider
|
||||||
|
.put_record(TraxRecord::Weight(data.data))
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
Some(RecordState::Original(_)) => {}
|
Some(RecordState::Original(_)) => {}
|
||||||
Some(RecordState::Updated(weight)) => {
|
Some(RecordState::Updated(weight)) => {
|
||||||
|
@ -333,7 +333,7 @@ impl DayDetailViewModel {
|
||||||
let steps_record = self.steps.read().unwrap().clone();
|
let steps_record = self.steps.read().unwrap().clone();
|
||||||
match steps_record {
|
match steps_record {
|
||||||
Some(RecordState::New(data)) => {
|
Some(RecordState::New(data)) => {
|
||||||
let _ = self.provider.put_record(TraxRecord::Steps(data)).await;
|
let _ = self.provider.put_record(TraxRecord::Steps(data.data)).await;
|
||||||
}
|
}
|
||||||
Some(RecordState::Original(_)) => {}
|
Some(RecordState::Original(_)) => {}
|
||||||
Some(RecordState::Updated(steps)) => {
|
Some(RecordState::Updated(steps)) => {
|
||||||
|
@ -361,7 +361,7 @@ impl DayDetailViewModel {
|
||||||
println!("saving record: {:?}", record);
|
println!("saving record: {:?}", record);
|
||||||
match record {
|
match record {
|
||||||
RecordState::New(data) => {
|
RecordState::New(data) => {
|
||||||
let _ = self.provider.put_record(data).await;
|
let _ = self.provider.put_record(data.data).await;
|
||||||
}
|
}
|
||||||
RecordState::Original(_) => {}
|
RecordState::Original(_) => {}
|
||||||
RecordState::Updated(r) => {
|
RecordState::Updated(r) => {
|
||||||
|
@ -389,7 +389,7 @@ impl DayDetailViewModel {
|
||||||
*self.weight.write().unwrap() = weight_records
|
*self.weight.write().unwrap() = weight_records
|
||||||
.first()
|
.first()
|
||||||
.and_then(|r| match r.data {
|
.and_then(|r| match r.data {
|
||||||
TraxRecord::Weight(ref w) => Some((r.id.clone(), w.clone())),
|
TraxRecord::Weight(ref w) => Some((r.id, w.clone())),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.map(|(id, w)| RecordState::Original(Record { id, data: w }));
|
.map(|(id, w)| RecordState::Original(Record { id, data: w }));
|
||||||
|
@ -397,14 +397,14 @@ impl DayDetailViewModel {
|
||||||
*self.steps.write().unwrap() = step_records
|
*self.steps.write().unwrap() = step_records
|
||||||
.first()
|
.first()
|
||||||
.and_then(|r| match r.data {
|
.and_then(|r| match r.data {
|
||||||
TraxRecord::Steps(ref w) => Some((r.id.clone(), w.clone())),
|
TraxRecord::Steps(ref w) => Some((r.id, w.clone())),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.map(|(id, w)| RecordState::Original(Record { id, data: w }));
|
.map(|(id, w)| RecordState::Original(Record { id, data: w }));
|
||||||
|
|
||||||
*self.records.write().unwrap() = records
|
*self.records.write().unwrap() = records
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| (r.id.clone(), RecordState::Original(r)))
|
.map(|r| (r.id, RecordState::Original(r)))
|
||||||
.collect::<HashMap<RecordId, RecordState<TraxRecord>>>();
|
.collect::<HashMap<RecordId, RecordState<TraxRecord>>>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,7 @@ mod test {
|
||||||
fn new(records: Vec<Record<TraxRecord>>) -> Self {
|
fn new(records: Vec<Record<TraxRecord>>) -> Self {
|
||||||
let record_map = records
|
let record_map = records
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| (r.id.clone(), r))
|
.map(|r| (r.id, r))
|
||||||
.collect::<HashMap<RecordId, Record<TraxRecord>>>();
|
.collect::<HashMap<RecordId, Record<TraxRecord>>>();
|
||||||
Self {
|
Self {
|
||||||
records: Arc::new(RwLock::new(record_map)),
|
records: Arc::new(RwLock::new(record_map)),
|
||||||
|
@ -464,26 +464,23 @@ mod test {
|
||||||
async fn put_record(&self, record: TraxRecord) -> Result<RecordId, WriteError> {
|
async fn put_record(&self, record: TraxRecord) -> Result<RecordId, WriteError> {
|
||||||
let id = RecordId::default();
|
let id = RecordId::default();
|
||||||
let record = Record {
|
let record = Record {
|
||||||
id: id.clone(),
|
id: id,
|
||||||
data: record,
|
data: record,
|
||||||
};
|
};
|
||||||
self.put_records.write().unwrap().push(record.clone());
|
self.put_records.write().unwrap().push(record.clone());
|
||||||
self.records.write().unwrap().insert(id.clone(), record);
|
self.records.write().unwrap().insert(id, record);
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_record(&self, record: Record<TraxRecord>) -> Result<(), WriteError> {
|
async fn update_record(&self, record: Record<TraxRecord>) -> Result<(), WriteError> {
|
||||||
println!("updated record: {:?}", record);
|
println!("updated record: {:?}", record);
|
||||||
self.updated_records.write().unwrap().push(record.clone());
|
self.updated_records.write().unwrap().push(record.clone());
|
||||||
self.records
|
self.records.write().unwrap().insert(record.id, record);
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(record.id.clone(), record);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn delete_record(&self, id: RecordId) -> Result<(), WriteError> {
|
async fn delete_record(&self, id: RecordId) -> Result<(), WriteError> {
|
||||||
self.deleted_records.write().unwrap().push(id.clone());
|
self.deleted_records.write().unwrap().push(id);
|
||||||
let _ = self.records.write().unwrap().remove(&id);
|
let _ = self.records.write().unwrap().remove(&id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,18 +134,6 @@ impl TraxRecord {
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn is_time_distance_type(&self, type_: TimeDistanceActivity) -> bool {
|
|
||||||
match type_ {
|
|
||||||
TimeDistanceWorkoutType::BikeRide => matches!(self, TraxRecord::BikeRide(_)),
|
|
||||||
TimeDistanceWorkoutType::Row => matches!(self, TraxRecord::Row(_)),
|
|
||||||
TimeDistanceWorkoutType::Run => matches!(self, TraxRecord::Run(_)),
|
|
||||||
TimeDistanceWorkoutType::Swim => matches!(self, TraxRecord::Swim(_)),
|
|
||||||
TimeDistanceWorkoutType::Walk => matches!(self, TraxRecord::Walk(_)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Recordable for TraxRecord {
|
impl Recordable for TraxRecord {
|
||||||
|
|
Loading…
Reference in New Issue