Compare commits

..

13 Commits

Author SHA1 Message Date
Savanni D'Gerinel 26fc8dae9a Save real data to the database. Load data on app start. 2023-12-28 13:58:43 -05:00
Savanni D'Gerinel d4dc493297 Record data to the database
This isn't recording real data. It's basically discarding all
information from the weight edit field. But it is creating a record.
2023-12-28 13:57:56 -05:00
Savanni D'Gerinel 68c5ab0958 Create placeholders in the historical view for days that are unpopulated. 2023-12-28 13:56:33 -05:00
Savanni D'Gerinel 57034e48d5 Fix tests 2023-12-28 13:56:31 -05:00
Savanni D'Gerinel e730d36cc9 Switch to an the updated emseries record type 2023-12-28 13:54:59 -05:00
Savanni D'Gerinel cb2f21341d Be able to respond to blur events and potentially be able to record weight 2023-12-28 13:54:53 -05:00
Savanni D'Gerinel 64c4e971f8 Develop a pattern to detect clicking outside of a focused child 2023-12-28 13:53:02 -05:00
Savanni D'Gerinel e84c49c343 Create a widget that can show the weight view and edit modes 2023-12-28 13:53:02 -05:00
Savanni D'Gerinel 5b8b612758 Completely switch daydetail to navigation and remove the modal 2023-12-28 13:52:49 -05:00
Savanni D'Gerinel 84fe6fbd8f Open and style the day detail modal 2023-12-28 13:50:09 -05:00
Savanni D'Gerinel 5cd0e822c6 Update to adwaita 1.4, and add a navigation page stack 2023-12-28 13:21:42 -05:00
Savanni D'Gerinel fe5e4ed044 Save the views as their original widgets
This allows me to directly reference functions that occur on those
widgets without losing them behind a gtk::Widget upcast or needing to
later downcast them.
2023-12-28 12:59:29 -05:00
Savanni D'Gerinel e30668ca8e Drop DateTimeTz from fitnesstrax 2023-12-28 12:51:50 -05:00
3 changed files with 19 additions and 19 deletions

View File

@ -23,6 +23,7 @@ use adw::prelude::*;
use async_channel::Sender; use async_channel::Sender;
use chrono::{FixedOffset, NaiveDate, TimeZone}; use chrono::{FixedOffset, NaiveDate, TimeZone};
use dimensioned::si::{KG, M, S}; use dimensioned::si::{KG, M, S};
use emseries::{Record, RecordId};
use ft_core::{Steps, TimeDistance, TraxRecord, Weight}; use ft_core::{Steps, TimeDistance, TraxRecord, Weight};
use gio::resources_lookup_data; use gio::resources_lookup_data;
use gtk::STYLE_PROVIDER_PRIORITY_USER; use gtk::STYLE_PROVIDER_PRIORITY_USER;
@ -79,20 +80,13 @@ impl AppWindow {
let navigation = adw::NavigationView::new(); let navigation = adw::NavigationView::new();
/*
let header = adw::HeaderBar::builder()
.title_widget(&gtk::Label::new(Some("FitnessTrax")))
.build();
*/
let layout = gtk::Box::builder() let layout = gtk::Box::builder()
.orientation(gtk::Orientation::Vertical) .orientation(gtk::Orientation::Vertical)
.build(); .build();
let initial_view = View::Placeholder(PlaceholderView::new().upcast()); let initial_view = View::Placeholder(PlaceholderView::new().upcast());
// layout.append(&header); layout.append(&initial_view.widget());
layout.append(initial_view.widget());
let nav_layout = gtk::Box::new(gtk::Orientation::Vertical, 0); let nav_layout = gtk::Box::new(gtk::Orientation::Vertical, 0);
nav_layout.append(&adw::HeaderBar::new()); nav_layout.append(&adw::HeaderBar::new());
@ -151,9 +145,9 @@ impl AppWindow {
// position. // position.
fn swap_main(&self, view: View) { fn swap_main(&self, view: View) {
let mut current_widget = self.current_view.borrow_mut(); let mut current_widget = self.current_view.borrow_mut();
self.layout.remove(&*current_widget.widget()); self.layout.remove(&current_widget.widget());
*current_widget = view; *current_widget = view;
self.layout.append(&*current_widget.widget()); self.layout.append(&current_widget.widget());
} }
fn construct_view(&self, view: ViewName) -> View { fn construct_view(&self, view: ViewName) -> View {

View File

@ -14,6 +14,8 @@ General Public License for more details.
You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see <https://www.gnu.org/licenses/>. You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see <https://www.gnu.org/licenses/>.
*/ */
use gtk::prelude::*;
mod historical_view; mod historical_view;
pub use historical_view::HistoricalView; pub use historical_view::HistoricalView;
@ -33,17 +35,17 @@ pub enum ViewName {
} }
pub enum View { pub enum View {
Placeholder(gtk::Widget), Placeholder(PlaceholderView),
Welcome(gtk::Widget), Welcome(WelcomeView),
Historical(gtk::Widget), Historical(HistoricalView),
} }
impl View { impl View {
pub fn widget<'a>(&'a self) -> &'a gtk::Widget { pub fn widget(&self) -> gtk::Widget {
match self { match self {
View::Placeholder(widget) => widget, View::Placeholder(widget) => widget.clone().upcast::<gtk::Widget>(),
View::Welcome(widget) => widget, View::Welcome(widget) => widget.clone().upcast::<gtk::Widget>(),
View::Historical(widget) => widget, View::Historical(widget) => widget.clone().upcast::<gtk::Widget>(),
} }
} }
} }

View File

@ -30,8 +30,12 @@ pub struct Steps {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TimeDistance { pub struct TimeDistance {
/// The precise time (and the relevant timezone) of the workout. One of the edge cases that I /// The precise time (and the relevant timezone) of the workout. One of the edge cases that I
/// account for is that a ride which occurred at 11pm in one timezone would then count as 1am /// account for is that a ride which occurred at 11pm on one day in one timezone would then
/// if one moved two timezones to the east. /// count as 1am on the next day if the user moves two timezones to the east. While technically
/// correct, for most users this would throw off many years of metrics in ways that can be very
/// hard to understand. Keeping the fixed offset means that we can have the most precise time
/// in the database, but we can still get a Naive Date from the DateTime, which will still read
/// as the original day.
pub datetime: DateTime<FixedOffset>, pub datetime: DateTime<FixedOffset>,
/// The distance travelled. This is optional because such a workout makes sense even without /// The distance travelled. This is optional because such a workout makes sense even without
/// the distance. /// the distance.