Show and edit the details of a day #133

Merged
savanni merged 9 commits from fitnesstrax/day-detail into main 2023-12-29 16:01:36 +00:00
2 changed files with 112 additions and 22 deletions
Showing only changes of commit 7a6e902fdd - Show all commits

View File

@ -90,12 +90,14 @@ impl DaySummary {
*self.imp().weight.borrow_mut() = Some(label);
}
/*
self.append(
&gtk::Label::builder()
.halign(gtk::Align::Start)
.label("15km of biking in 60 minutes")
.build(),
);
*/
}
}

View File

@ -15,7 +15,8 @@ You should have received a copy of the GNU General Public License along with Fit
*/
use crate::components::DaySummary;
use emseries::{Record, Recordable, Timestamp};
use chrono::{Duration, Local, NaiveDate};
use emseries::Record;
use ft_core::TraxRecord;
use glib::Object;
use gtk::{prelude::*, subclass::prelude::*};
@ -24,7 +25,9 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc};
/// The historical view will show a window into the main database. It will show some version of
/// daily summaries, daily details, and will provide all functions the user may need for editing
/// records.
pub struct HistoricalViewPrivate {}
pub struct HistoricalViewPrivate {
time_window: RefCell<DayInterval>,
}
#[glib::object_subclass]
impl ObjectSubclass for HistoricalViewPrivate {
@ -33,7 +36,9 @@ impl ObjectSubclass for HistoricalViewPrivate {
type ParentType = gtk::Box;
fn new() -> Self {
Self {}
Self {
time_window: RefCell::new(DayInterval::default()),
}
}
}
@ -54,10 +59,11 @@ impl HistoricalView {
s.set_orientation(gtk::Orientation::Vertical);
s.set_css_classes(&["historical"]);
let day_records: GroupedRecords = GroupedRecords::from(records);
let grouped_records =
GroupedRecords::new((*s.imp().time_window.borrow()).clone()).with_data(records);
let model = gio::ListStore::new::<DayRecords>();
model.extend_from_slice(&day_records.0);
let mut model = gio::ListStore::new::<DayRecords>();
model.extend(grouped_records.items());
let factory = gtk::SignalListItemFactory::new();
factory.connect_setup(move |_, list_item| {
@ -149,23 +155,105 @@ impl DayRecords {
}
}
struct GroupedRecords(Vec<DayRecords>);
struct GroupedRecords {
interval: DayInterval,
data: HashMap<NaiveDate, DayRecords>,
}
impl From<Vec<Record<TraxRecord>>> for GroupedRecords {
fn from(records: Vec<Record<TraxRecord>>) -> GroupedRecords {
GroupedRecords(
records
.into_iter()
.fold(HashMap::new(), |mut acc, rec| {
acc.entry(rec.date())
.and_modify(|entry: &mut DayRecords| (*entry).add_record(rec.clone()))
.or_insert(DayRecords::new(rec.date(), vec![rec]));
acc
})
.values()
.cloned()
.collect::<Vec<DayRecords>>(),
)
impl GroupedRecords {
fn new(interval: DayInterval) -> Self {
let mut s = Self {
interval: interval.clone(),
data: HashMap::new(),
};
interval.days().for_each(|date| {
let _ = s.data.insert(date, DayRecords::new(date, vec![]));
});
s
}
fn with_data(mut self, records: Vec<Record<TraxRecord>>) -> Self {
records.into_iter().for_each(|record| {
self.data
.entry(record.date())
.and_modify(|entry: &mut DayRecords| (*entry).add_record(record.clone()))
.or_insert(DayRecords::new(record.date(), vec![record]));
});
self
}
fn items<'a>(&'a self) -> impl Iterator<Item = DayRecords> + 'a {
/*
GroupedRecordIterator {
interval: self.interval.clone(),
data: &self.data,
}
*/
self.interval.days().map(|date| {
self.data
.get(&date)
.map(|rec| rec.clone())
.unwrap_or(DayRecords::new(date, vec![]))
})
}
}
/*
struct GroupedRecordIterator<'a> {
interval: DayInterval,
data: &'a HashMap<NaiveDate, DayRecords>,
}
impl <'a> Iterator for GroupedRecordIterator<'a> {
type Item = &'a DayRecords;
fn next(&mut self) -> Option<&'a DayRecords> {
}
}
*/
#[derive(Clone, Debug, PartialEq, Eq)]
struct DayInterval {
start: NaiveDate,
end: NaiveDate,
}
impl Default for DayInterval {
fn default() -> Self {
Self {
start: (Local::now() - Duration::days(7)).date_naive(),
end: Local::now().date_naive(),
}
}
}
impl DayInterval {
fn days(&self) -> impl Iterator<Item = NaiveDate> {
DayIterator {
current: self.start.clone(),
end: self.end.clone(),
}
}
}
struct DayIterator {
current: NaiveDate,
end: NaiveDate,
}
impl Iterator for DayIterator {
type Item = NaiveDate;
fn next(&mut self) -> Option<Self::Item> {
if self.current <= self.end {
let val = self.current.clone();
self.current += Duration::days(1);
Some(val)
} else {
None
}
}
}