Skip to content

Commit 73fd9cd

Browse files
committed
refactor: optimisations
1 parent 0b899cf commit 73fd9cd

6 files changed

Lines changed: 38 additions & 25 deletions

File tree

src/components/active_session.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::session_timers::{RestTimerDisplay, SessionDurationDisplay};
33
use crate::components::CompletedExerciseLog;
44
use crate::models::{
55
get_current_timestamp, parse_distance_km, parse_weight_kg, Category, ExerciseLog, Force,
6-
WorkoutSession,
6+
WorkoutSession, HG_PER_KG, M_PER_KM,
77
};
88
use crate::services::exercise_db::{
99
detect_filter_suggestions, exercise_matches_filters, SearchFilter,
@@ -21,6 +21,8 @@ const SEARCH_DEBOUNCE_MS: u32 = 200;
2121
const MAX_FILTER_ONLY_RESULTS: usize = 20;
2222
/// Maximum exercises shown from the full database when a text search query is active.
2323
const MAX_TEXT_SEARCH_RESULTS: usize = 10;
24+
/// Default rest time in seconds offered to the user in the rest input form.
25+
const DEFAULT_REST_SECONDS: u64 = 30;
2426
/// Prefill the weight / reps / distance inputs from the last recorded log for
2527
/// `exercise_id`, or clear them if no prior log exists.
2628
///
@@ -51,7 +53,7 @@ fn prefill_inputs_from_last_log(
5153
if use_active {
5254
if let Some(last_log) = active_log {
5355
if let Some(w) = last_log.weight_hg {
54-
weight_input.set(format!("{:.1}", f64::from(w.0) / 10.0));
56+
weight_input.set(format!("{:.1}", f64::from(w.0) / HG_PER_KG));
5557
} else {
5658
weight_input.set(String::new());
5759
}
@@ -61,7 +63,7 @@ fn prefill_inputs_from_last_log(
6163
reps_input.set(String::new());
6264
}
6365
if let Some(d) = last_log.distance_m {
64-
distance_input.set(format!("{:.2}", f64::from(d.0) / 1000.0));
66+
distance_input.set(format!("{:.2}", f64::from(d.0) / M_PER_KM));
6567
} else {
6668
distance_input.set(String::new());
6769
}
@@ -74,7 +76,7 @@ fn prefill_inputs_from_last_log(
7476
} else {
7577
// Use values from the most-recently completed cross-session log.
7678
if let Some(w) = bests.last_weight_hg {
77-
weight_input.set(format!("{:.1}", f64::from(w.0) / 10.0));
79+
weight_input.set(format!("{:.1}", f64::from(w.0) / HG_PER_KG));
7880
} else {
7981
weight_input.set(String::new());
8082
}
@@ -84,7 +86,7 @@ fn prefill_inputs_from_last_log(
8486
reps_input.set(String::new());
8587
}
8688
if let Some(d) = bests.last_distance_m {
87-
distance_input.set(format!("{:.2}", f64::from(d.0) / 1000.0));
89+
distance_input.set(format!("{:.2}", f64::from(d.0) / M_PER_KM));
8890
} else {
8991
distance_input.set(String::new());
9092
}
@@ -620,7 +622,7 @@ pub fn GlobalSessionHeader() -> Element {
620622
let session = use_memo(move || sessions.read().iter().find(|s| s.is_active()).cloned());
621623
let mut show_rest = use_context::<crate::ShowRestInputSignal>().0;
622624
let rest_duration = use_context::<RestDurationSignal>().0;
623-
let mut rest_input_value = use_signal(|| 30u64.to_string());
625+
let mut rest_input_value = use_signal(|| DEFAULT_REST_SECONDS.to_string());
624626
let mut congratulations = use_context::<crate::CongratulationsSignal>().0;
625627
use_effect(move || {
626628
if *show_rest.read() {

src/components/analytics.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::components::{ActiveTab, BottomNav};
2-
use crate::models::ExerciseLog;
2+
use crate::models::{ExerciseLog, HG_PER_KG, M_PER_KM};
33
use crate::services::storage;
44
use dioxus::prelude::*;
55
#[derive(Clone, Copy, PartialEq, Debug)]
@@ -22,9 +22,9 @@ impl Metric {
2222
#[allow(clippy::cast_precision_loss)]
2323
fn extract_value(self, log: &ExerciseLog) -> Option<f64> {
2424
match self {
25-
Metric::Weight => log.weight_hg.map(|w| f64::from(w.0) / 10.0),
25+
Metric::Weight => log.weight_hg.map(|w| f64::from(w.0) / HG_PER_KG),
2626
Metric::Reps => log.reps.map(f64::from),
27-
Metric::Distance => log.distance_m.map(|d| f64::from(d.0) / 1000.0),
27+
Metric::Distance => log.distance_m.map(|d| f64::from(d.0) / M_PER_KM),
2828
Metric::Duration => log.duration_seconds().map(|d| d as f64 / 60.0),
2929
}
3030
}
@@ -46,7 +46,7 @@ fn adapt_metric_unit(metric: Metric, values: &[f64]) -> (&'static str, f64) {
4646
Metric::Reps => ("reps", 1.0),
4747
Metric::Distance => {
4848
if avg < 1.0 {
49-
("m", 1000.0)
49+
("m", M_PER_KM)
5050
} else {
5151
("km", 1.0)
5252
}

src/components/completed_exercise_log.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::session_exercise_form::ExerciseInputForm;
22
use crate::models::{
33
format_time, parse_distance_km, parse_duration_seconds, parse_weight_kg, Category, ExerciseLog,
4-
Force, WorkoutSession,
4+
Force, WorkoutSession, HG_PER_KG, M_PER_KM,
55
};
66
use crate::services::storage;
77
use dioxus::prelude::*;
@@ -28,13 +28,13 @@ pub fn CompletedExerciseLog(
2828
move |_| {
2929
edit_weight_input.set(
3030
log.weight_hg
31-
.map(|w| format!("{:.1}", f64::from(w.0) / 10.0))
31+
.map(|w| format!("{:.1}", f64::from(w.0) / HG_PER_KG))
3232
.unwrap_or_default(),
3333
);
3434
edit_reps_input.set(log.reps.map(|r| r.to_string()).unwrap_or_default());
3535
edit_distance_input.set(
3636
log.distance_m
37-
.map(|d| format!("{:.2}", f64::from(d.0) / 1000.0))
37+
.map(|d| format!("{:.2}", f64::from(d.0) / M_PER_KM))
3838
.unwrap_or_default(),
3939
);
4040
edit_time_input.set(log.duration_seconds().map(format_time).unwrap_or_default());

src/components/more.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,10 @@ async fn read_file_input(id: &str) -> Option<String> {
408408
let files = input.files()?;
409409
let file = files.get(0)?;
410410
let promise = js_sys::Promise::new(&mut |resolve, reject| {
411-
let reader = web_sys::FileReader::new().expect("FileReader");
411+
let Ok(reader) = web_sys::FileReader::new() else {
412+
let _ = reject.call0(&wasm_bindgen::JsValue::NULL);
413+
return;
414+
};
412415
let reader_clone = reader.clone();
413416
let onload = wasm_bindgen::closure::Closure::once(move |_: web_sys::ProgressEvent| {
414417
let result = reader_clone.result().unwrap_or(wasm_bindgen::JsValue::NULL);

src/models/units.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,48 @@
11
use serde::{Deserialize, Serialize};
22
use std::fmt;
3-
/// Weight stored as hectograms (100 g units). 1 kg = 10 hg.
3+
/// Weight stored as hectograms: 1 kg = 10 hg
4+
pub const HG_PER_KG: f64 = 10.0;
5+
/// Distance stored as meters: 1 km = 1000 m
6+
pub const M_PER_KM: f64 = 1000.0;
7+
48
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
59
pub struct Weight(pub u16);
10+
611
impl fmt::Display for Weight {
712
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8-
if self.0.is_multiple_of(10) {
9-
write!(f, "{} kg", self.0 / 10)
13+
if f64::from(self.0) % HG_PER_KG < f64::EPSILON {
14+
write!(f, "{} kg", f64::from(self.0) / HG_PER_KG)
1015
} else {
11-
write!(f, "{:.1} kg", f64::from(self.0) / 10.0)
16+
write!(f, "{:.1} kg", f64::from(self.0) / HG_PER_KG)
1217
}
1318
}
1419
}
20+
1521
/// Distance stored as meters. 1 km = 1000 m.
1622
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1723
pub struct Distance(pub u32);
24+
1825
impl fmt::Display for Distance {
1926
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20-
if self.0 >= 1000 {
21-
if self.0.is_multiple_of(1000) {
22-
write!(f, "{} km", self.0 / 1000)
27+
if f64::from(self.0) >= M_PER_KM {
28+
if f64::from(self.0) % M_PER_KM < f64::EPSILON {
29+
write!(f, "{} km", f64::from(self.0) / M_PER_KM)
2330
} else {
24-
write!(f, "{:.2} km", f64::from(self.0) / 1000.0)
31+
write!(f, "{:.2} km", f64::from(self.0) / M_PER_KM)
2532
}
2633
} else {
2734
write!(f, "{} m", self.0)
2835
}
2936
}
3037
}
38+
3139
/// Parse a user-entered kg string into a Weight (hectograms).
3240
pub fn parse_weight_kg(input: &str) -> Option<Weight> {
3341
let val: f64 = input.parse().ok()?;
3442
if !val.is_finite() || val <= 0.0 {
3543
return None;
3644
}
37-
let hg = (val * 10.0).round();
45+
let hg = (val * HG_PER_KG).round();
3846
if hg < 1.0 || hg > f64::from(u16::MAX) {
3947
return None;
4048
}
@@ -77,7 +85,7 @@ pub fn parse_distance_km(input: &str) -> Option<Distance> {
7785
if !val.is_finite() || val <= 0.0 {
7886
return None;
7987
}
80-
let m = (val * 1000.0).round();
88+
let m = (val * M_PER_KM).round();
8189
if m < 1.0 || m > f64::from(u32::MAX) {
8290
return None;
8391
}

src/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ pub fn parse_session_exercises(s: &str) -> Vec<SessionExerciseEntry> {
241241
None
242242
} else {
243243
w.parse::<f64>().ok().and_then(|kg| {
244-
let hg = (kg * 10.0).round();
244+
let hg = (kg * crate::models::HG_PER_KG).round();
245245
if (0.0..=f64::from(u32::MAX)).contains(&hg) {
246246
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
247247
Some(hg as u32)

0 commit comments

Comments
 (0)