Thoroughly fill out the day detail view model along with proper automated testing #179
|
@ -222,12 +222,21 @@ impl DayDetail {
|
||||||
|
|
||||||
pub struct DayEditPrivate {
|
pub struct DayEditPrivate {
|
||||||
on_finished: RefCell<Box<dyn Fn()>>,
|
on_finished: RefCell<Box<dyn Fn()>>,
|
||||||
|
workout_rows: RefCell<gtk::Box>,
|
||||||
|
view_model: RefCell<Option<DayDetailViewModel>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DayEditPrivate {
|
impl Default for DayEditPrivate {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
on_finished: RefCell::new(Box::new(|| {})),
|
on_finished: RefCell::new(Box::new(|| {})),
|
||||||
|
workout_rows: RefCell::new(
|
||||||
|
gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Vertical)
|
||||||
|
.hexpand(true)
|
||||||
|
.build(),
|
||||||
|
),
|
||||||
|
view_model: RefCell::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,6 +266,7 @@ impl DayEdit {
|
||||||
s.set_hexpand(true);
|
s.set_hexpand(true);
|
||||||
|
|
||||||
*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.append(
|
s.append(
|
||||||
&ActionGroup::builder()
|
&ActionGroup::builder()
|
||||||
|
|
|
@ -75,12 +75,9 @@ impl<T: Clone + emseries::Recordable> Deref for RecordState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Clone)]
|
||||||
struct DayDetailViewModelInner {}
|
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
|
||||||
pub struct DayDetailViewModel {
|
pub struct DayDetailViewModel {
|
||||||
app: Option<App>,
|
app: App,
|
||||||
pub date: chrono::NaiveDate,
|
pub date: chrono::NaiveDate,
|
||||||
weight: Arc<RwLock<Option<RecordState<ft_core::Weight>>>>,
|
weight: Arc<RwLock<Option<RecordState<ft_core::Weight>>>>,
|
||||||
steps: Arc<RwLock<Option<RecordState<ft_core::Steps>>>>,
|
steps: Arc<RwLock<Option<RecordState<ft_core::Steps>>>>,
|
||||||
|
@ -94,7 +91,7 @@ impl DayDetailViewModel {
|
||||||
let (step_records, records): (Vec<Record<TraxRecord>>, Vec<Record<TraxRecord>>) =
|
let (step_records, records): (Vec<Record<TraxRecord>>, Vec<Record<TraxRecord>>) =
|
||||||
records.into_iter().partition(|r| r.data.is_steps());
|
records.into_iter().partition(|r| r.data.is_steps());
|
||||||
Self {
|
Self {
|
||||||
app: Some(app),
|
app,
|
||||||
date,
|
date,
|
||||||
weight: Arc::new(RwLock::new(
|
weight: Arc::new(RwLock::new(
|
||||||
weight_records
|
weight_records
|
||||||
|
@ -168,62 +165,62 @@ impl DayDetailViewModel {
|
||||||
glib::spawn_future({
|
glib::spawn_future({
|
||||||
let s = self.clone();
|
let s = self.clone();
|
||||||
async move {
|
async move {
|
||||||
if let Some(app) = s.app {
|
let weight_record = s.weight.read().unwrap().clone();
|
||||||
let weight_record = s.weight.read().unwrap().clone();
|
match weight_record {
|
||||||
match weight_record {
|
Some(RecordState::New(data)) => {
|
||||||
Some(RecordState::New(weight)) => {
|
let _ = s.app.put_record(TraxRecord::Weight(data)).await;
|
||||||
let _ = app.put_record(TraxRecord::Weight(weight)).await;
|
|
||||||
}
|
|
||||||
Some(RecordState::Original(_)) => {}
|
|
||||||
Some(RecordState::Updated(weight)) => {
|
|
||||||
let _ = app
|
|
||||||
.update_record(Record {
|
|
||||||
id: weight.id,
|
|
||||||
data: TraxRecord::Weight(weight.data),
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
Some(RecordState::Deleted(_)) => {}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
Some(RecordState::Original(_)) => {}
|
||||||
let steps_record = s.steps.read().unwrap().clone();
|
Some(RecordState::Updated(weight)) => {
|
||||||
match steps_record {
|
let _ = s
|
||||||
Some(RecordState::New(steps)) => {
|
.app
|
||||||
let _ = app.put_record(TraxRecord::Steps(steps)).await;
|
.update_record(Record {
|
||||||
}
|
id: weight.id,
|
||||||
Some(RecordState::Original(_)) => {}
|
data: TraxRecord::Weight(weight.data),
|
||||||
Some(RecordState::Updated(steps)) => {
|
})
|
||||||
let _ = app
|
.await;
|
||||||
.update_record(Record {
|
|
||||||
id: steps.id,
|
|
||||||
data: TraxRecord::Steps(steps.data),
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
Some(RecordState::Deleted(_)) => {}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
Some(RecordState::Deleted(_)) => {}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
let records = s
|
let steps_record = s.steps.read().unwrap().clone();
|
||||||
.records
|
match steps_record {
|
||||||
.write()
|
Some(RecordState::New(data)) => {
|
||||||
.unwrap()
|
let _ = s.app.put_record(TraxRecord::Steps(data)).await;
|
||||||
.drain()
|
}
|
||||||
.map(|(_, record)| record)
|
Some(RecordState::Original(_)) => {}
|
||||||
.collect::<Vec<RecordState<TraxRecord>>>();
|
Some(RecordState::Updated(steps)) => {
|
||||||
|
let _ = s
|
||||||
|
.app
|
||||||
|
.update_record(Record {
|
||||||
|
id: steps.id,
|
||||||
|
data: TraxRecord::Steps(steps.data),
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
Some(RecordState::Deleted(_)) => {}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
for record in records {
|
let records = s
|
||||||
match record {
|
.records
|
||||||
RecordState::New(data) => {
|
.write()
|
||||||
let _ = app.put_record(data).await;
|
.unwrap()
|
||||||
}
|
.drain()
|
||||||
RecordState::Original(_) => {}
|
.map(|(_, record)| record)
|
||||||
RecordState::Updated(r) => {
|
.collect::<Vec<RecordState<TraxRecord>>>();
|
||||||
let _ = app.update_record(r.clone()).await;
|
|
||||||
}
|
for record in records {
|
||||||
RecordState::Deleted(_) => unimplemented!(),
|
match record {
|
||||||
|
RecordState::New(data) => {
|
||||||
|
let _ = s.app.put_record(data).await;
|
||||||
}
|
}
|
||||||
|
RecordState::Original(_) => {}
|
||||||
|
RecordState::Updated(r) => {
|
||||||
|
let _ = s.app.update_record(r.clone()).await;
|
||||||
|
}
|
||||||
|
RecordState::Deleted(_) => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ use std::cell::RefCell;
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DayDetailViewPrivate {
|
pub struct DayDetailViewPrivate {
|
||||||
container: Singleton,
|
container: Singleton,
|
||||||
view_model: RefCell<DayDetailViewModel>,
|
view_model: RefCell<Option<DayDetailViewModel>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -47,7 +47,7 @@ glib::wrapper! {
|
||||||
impl DayDetailView {
|
impl DayDetailView {
|
||||||
pub fn new(view_model: DayDetailViewModel) -> Self {
|
pub fn new(view_model: DayDetailViewModel) -> Self {
|
||||||
let s: Self = Object::builder().build();
|
let s: Self = Object::builder().build();
|
||||||
*s.imp().view_model.borrow_mut() = view_model;
|
*s.imp().view_model.borrow_mut() = Some(view_model);
|
||||||
|
|
||||||
s.append(&s.imp().container);
|
s.append(&s.imp().container);
|
||||||
|
|
||||||
|
@ -57,20 +57,28 @@ impl DayDetailView {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) {
|
fn view(&self) {
|
||||||
self.imp()
|
let view_model = self.imp().view_model.borrow();
|
||||||
.container
|
let view_model = view_model
|
||||||
.swap(&DayDetail::new(self.imp().view_model.borrow().clone(), {
|
.as_ref()
|
||||||
let s = self.clone();
|
.expect("DayDetailView has not been initialized with a view_model")
|
||||||
move || s.edit()
|
.clone();
|
||||||
}));
|
|
||||||
|
self.imp().container.swap(&DayDetail::new(view_model, {
|
||||||
|
let s = self.clone();
|
||||||
|
move || s.edit()
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edit(&self) {
|
fn edit(&self) {
|
||||||
self.imp()
|
let view_model = self.imp().view_model.borrow();
|
||||||
.container
|
let view_model = view_model
|
||||||
.swap(&DayEdit::new(self.imp().view_model.borrow().clone(), {
|
.as_ref()
|
||||||
let s = self.clone();
|
.expect("DayDetailView has not been initialized with a view_model")
|
||||||
move || s.view()
|
.clone();
|
||||||
}));
|
|
||||||
|
self.imp().container.swap(&DayEdit::new(view_model, {
|
||||||
|
let s = self.clone();
|
||||||
|
move || s.view()
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue