Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow hiding TUT and RPE UI elements #58

Merged
merged 1 commit into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Descriptions of measuring points on body fat page
- Archiving of routines
- Button for saving changes during guided training session
- Settings for hiding UI elements related to RPE and TUT

### Changed

Expand Down
6 changes: 4 additions & 2 deletions frontend/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1220,8 +1220,10 @@ pub fn view_element_with_description<Ms>(element: Node<Ms>, description: &str) -
pub fn format_set(
reps: Option<u32>,
time: Option<u32>,
show_tut: bool,
weight: Option<f32>,
rpe: Option<f32>,
show_rpe: bool,
) -> String {
let mut parts = vec![];

Expand All @@ -1232,7 +1234,7 @@ pub fn format_set(
}

if let Some(time) = time {
if time > 0 {
if show_tut && time > 0 {
parts.push(format!("{time} s"));
}
}
Expand All @@ -1246,7 +1248,7 @@ pub fn format_set(
let mut result = parts.join(" × ");

if let Some(rpe) = rpe {
if rpe > 0.0 {
if show_rpe && rpe > 0.0 {
result.push_str(&format!(" @ {rpe}"));
}
}
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub fn init(url: Url, _orders: &mut impl Orders<Msg>) -> Model {
theme: Theme::Light,
automatic_metronome: false,
notifications: false,
show_rpe: true,
show_tut: true,
});
let ongoing_training_session =
gloo_storage::LocalStorage::get(STORAGE_KEY_ONGOING_TRAINING_SESSION).unwrap_or(None);
Expand Down Expand Up @@ -425,11 +427,14 @@ pub enum TrainingSessionElement {
}

#[derive(serde::Serialize, serde::Deserialize)]
#[allow(clippy::struct_excessive_bools)]
pub struct Settings {
pub beep_volume: u8,
pub theme: Theme,
pub automatic_metronome: bool,
pub notifications: bool,
pub show_rpe: bool,
pub show_tut: bool,
}

#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq)]
Expand Down Expand Up @@ -1104,6 +1109,8 @@ pub enum Msg {
SetTheme(Theme),
SetAutomaticMetronome(bool),
SetNotifications(bool),
SetShowRPE(bool),
SetShowTUT(bool),

StartTrainingSession(u32),
UpdateTrainingSession(usize, TimerState),
Expand Down Expand Up @@ -1974,6 +1981,14 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
model.settings.notifications = value;
local_storage_set(STORAGE_KEY_SETTINGS, &model.settings, &mut model.errors);
}
Msg::SetShowRPE(value) => {
model.settings.show_rpe = value;
local_storage_set(STORAGE_KEY_SETTINGS, &model.settings, &mut model.errors);
}
Msg::SetShowTUT(value) => {
model.settings.show_tut = value;
local_storage_set(STORAGE_KEY_SETTINGS, &model.settings, &mut model.errors);
}

Msg::StartTrainingSession(training_session_id) => {
model.ongoing_training_session = Some(OngoingTrainingSession::new(training_session_id));
Expand Down
64 changes: 64 additions & 0 deletions frontend/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ enum Msg {
SetTheme(data::Theme),
ToggleAutomaticMetronome,
ToggleNotifications,
ToggleShowRPE,
ToggleShowTUT,
UpdateApp,
GoUp,
LogOut,
Expand Down Expand Up @@ -358,6 +360,18 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
.send_msg(Msg::Data(data::Msg::SetNotifications(true)));
}
},
Msg::ToggleShowRPE => {
orders.send_msg(Msg::Data(data::Msg::SetShowRPE(not(model
.data
.settings
.show_rpe))));
}
Msg::ToggleShowTUT => {
orders.send_msg(Msg::Data(data::Msg::SetShowTUT(not(model
.data
.settings
.show_tut))));
}
Msg::UpdateApp => {
orders.skip().send_msg(Msg::Data(data::Msg::UpdateApp));
}
Expand Down Expand Up @@ -772,6 +786,56 @@ fn view_settings_dialog(data_model: &data::Model) -> Node<Msg> {
},
],
],
p![
C!["mb-5"],
h1![C!["subtitle"], "Rating of Perceived Exertion (RPE)"],
div![
C!["field"],
C!["is-grouped"],
div![
C!["control"],
button![
C!["button"],
if data_model.settings.show_rpe {
C!["is-primary"]
} else {
C![]
},
ev(Ev::Click, |_| Msg::ToggleShowRPE),
if data_model.settings.show_rpe {
"Enabled"
} else {
"Disabled"
},
]
],
],
],
p![
C!["mb-5"],
h1![C!["subtitle"], "Time Under Tension (TUT)"],
div![
C!["field"],
C!["is-grouped"],
div![
C!["control"],
button![
C!["button"],
if data_model.settings.show_tut {
C!["is-primary"]
} else {
C![]
},
ev(Ev::Click, |_| Msg::ToggleShowTUT),
if data_model.settings.show_tut {
"Enabled"
} else {
"Disabled"
},
]
],
],
],
{
let permission = web_sys::Notification::permission();
let notifications_enabled = data_model.settings.notifications;
Expand Down
161 changes: 91 additions & 70 deletions frontend/src/page/exercise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,18 +272,28 @@ pub fn view(model: &Model, data_model: &data::Model) -> Node<Msg> {
&exercise_interval,
Msg::ChangeInterval
),
view_charts(&training_sessions, &model.interval, data_model.theme()),
view_charts(
&training_sessions,
&model.interval,
data_model.theme(),
data_model.settings.show_rpe,
data_model.settings.show_tut,
),
view_calendar(&training_sessions, &model.interval),
training::view_table(
&training_sessions,
&data_model.routines,
&data_model.base_url,
Msg::ShowDeleteTrainingSessionDialog
Msg::ShowDeleteTrainingSessionDialog,
data_model.settings.show_rpe,
data_model.settings.show_tut,
),
view_sets(
&training_sessions,
&data_model.routines,
&data_model.base_url,
data_model.settings.show_rpe,
data_model.settings.show_tut,
),
view_dialog(&model.dialog, model.loading),
common::view_fab("edit", |_| Msg::EditExercise),
Expand Down Expand Up @@ -441,6 +451,8 @@ pub fn view_charts<Ms>(
training_sessions: &[&data::TrainingSession],
interval: &common::Interval,
theme: &data::Theme,
show_rpe: bool,
show_tut: bool,
) -> Vec<Node<Ms>> {
let mut set_volume: BTreeMap<NaiveDate, f32> = BTreeMap::new();
let mut volume_load: BTreeMap<NaiveDate, f32> = BTreeMap::new();
Expand Down Expand Up @@ -486,6 +498,42 @@ pub fn view_charts<Ms>(
.or_insert(vec![avg_time]);
}
}

let mut labels = vec![("Repetitions", common::COLOR_REPS)];

let mut data = vec![(
reps_rpe
.iter()
.map(|(date, (avg_reps, _))| {
#[allow(clippy::cast_precision_loss)]
(*date, avg_reps.iter().sum::<f32>() / avg_reps.len() as f32)
})
.collect::<Vec<_>>(),
common::COLOR_REPS,
)];

if show_rpe {
labels.push(("+ Repetititions in reserve", common::COLOR_REPS_RIR));
data.push((
reps_rpe
.into_iter()
.filter_map(|(date, (avg_reps_values, avg_rpe_values))| {
#[allow(clippy::cast_precision_loss)]
let avg_reps =
avg_reps_values.iter().sum::<f32>() / avg_reps_values.len() as f32;
#[allow(clippy::cast_precision_loss)]
let avg_rpe = avg_rpe_values.iter().sum::<f32>() / avg_rpe_values.len() as f32;
if avg_rpe_values.is_empty() {
None
} else {
Some((date, avg_reps + 10.0 - avg_rpe))
}
})
.collect::<Vec<_>>(),
common::COLOR_REPS_RIR,
));
}

nodes![
common::view_chart(
&[("Set volume", common::COLOR_SET_VOLUME)],
Expand Down Expand Up @@ -517,55 +565,24 @@ pub fn view_charts<Ms>(
),
false,
),
IF![show_tut =>
common::view_chart(
&[("Time under tension (s)", common::COLOR_TUT)],
common::plot_line_chart(
&[(tut.into_iter().collect::<Vec<_>>(), common::COLOR_TUT,)],
interval.first,
interval.last,
Some(0.),
Some(10.),
theme,
),
false,
)
],
common::view_chart(
&[("Time under tension (s)", common::COLOR_TUT)],
common::plot_line_chart(
&[(tut.into_iter().collect::<Vec<_>>(), common::COLOR_TUT,)],
interval.first,
interval.last,
Some(0.),
Some(10.),
theme,
),
false,
),
common::view_chart(
&[
("Repetitions", common::COLOR_REPS),
("+ Repetititions in reserve", common::COLOR_REPS_RIR)
],
&labels,
common::plot_line_chart(
&[
(
reps_rpe
.iter()
.map(|(date, (avg_reps, _))| {
#[allow(clippy::cast_precision_loss)]
(*date, avg_reps.iter().sum::<f32>() / avg_reps.len() as f32)
})
.collect::<Vec<_>>(),
common::COLOR_REPS,
),
(
reps_rpe
.into_iter()
.filter_map(|(date, (avg_reps_values, avg_rpe_values))| {
#[allow(clippy::cast_precision_loss)]
let avg_reps = avg_reps_values.iter().sum::<f32>()
/ avg_reps_values.len() as f32;
#[allow(clippy::cast_precision_loss)]
let avg_rpe = avg_rpe_values.iter().sum::<f32>()
/ avg_rpe_values.len() as f32;
if avg_rpe_values.is_empty() {
None
} else {
Some((date, avg_reps + 10.0 - avg_rpe))
}
})
.collect::<Vec<_>>(),
common::COLOR_REPS_RIR,
),
],
&data,
interval.first,
interval.last,
Some(0.),
Expand Down Expand Up @@ -595,26 +612,28 @@ pub fn view_charts<Ms>(
),
false,
),
common::view_chart(
&[("Time (s)", common::COLOR_TIME)],
common::plot_line_chart(
&[(
time.into_iter()
.map(|(date, values)| {
#[allow(clippy::cast_precision_loss)]
(date, values.iter().sum::<f32>() / values.len() as f32)
})
.collect::<Vec<_>>(),
common::COLOR_TIME,
)],
interval.first,
interval.last,
Some(0.),
Some(10.),
theme,
),
false,
),
IF![show_tut =>
common::view_chart(
&[("Time (s)", common::COLOR_TIME)],
common::plot_line_chart(
&[(
time.into_iter()
.map(|(date, values)| {
#[allow(clippy::cast_precision_loss)]
(date, values.iter().sum::<f32>() / values.len() as f32)
})
.collect::<Vec<_>>(),
common::COLOR_TIME,
)],
interval.first,
interval.last,
Some(0.),
Some(10.),
theme,
),
false,
)
],
]
}

Expand Down Expand Up @@ -665,6 +684,8 @@ fn view_sets(
training_sessions: &[&data::TrainingSession],
routines: &BTreeMap<u32, data::Routine>,
base_url: &Url,
show_rpe: bool,
show_tut: bool,
) -> Vec<Node<Msg>> {
training_sessions
.iter()
Expand Down Expand Up @@ -711,7 +732,7 @@ fn view_sets(
div![
span![
style! {St::WhiteSpace => "nowrap" },
common::format_set(*reps, *time, *weight, *rpe)
common::format_set(*reps, *time, show_tut, *weight, *rpe, show_rpe)
]
]
} else {
Expand Down
Loading