Skip to content

Commit

Permalink
feat(*): change reps to decimal
Browse files Browse the repository at this point in the history
  • Loading branch information
IgnisDa committed Jul 2, 2024
1 parent 22de99f commit f8a6f6f
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 134 deletions.
11 changes: 3 additions & 8 deletions apps/backend/src/fitness/logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use anyhow::{bail, Result};
use database::ExerciseLot;
use nanoid::nanoid;
use rs_utils::LengthVec;
use rust_decimal::{prelude::FromPrimitive, Decimal};
use rust_decimal_macros::dec;
use sea_orm::{
ActiveModelTrait, ActiveValue, ColumnTrait, DatabaseConnection, EntityTrait, ModelTrait,
Expand Down Expand Up @@ -30,11 +29,7 @@ fn get_best_set_index(records: &[WorkoutSetRecord]) -> Option<usize> {
.max_by_key(|(_, record)| {
record.statistic.duration.unwrap_or(dec!(0))
+ record.statistic.distance.unwrap_or(dec!(0))
+ record
.statistic
.reps
.map(|r| Decimal::from_usize(r).unwrap())
.unwrap_or(dec!(0))
+ record.statistic.reps.unwrap_or(dec!(0))
+ record.statistic.weight.unwrap_or(dec!(0))
})
.map(|(index, _)| index)
Expand Down Expand Up @@ -189,7 +184,7 @@ impl UserWorkoutInput {
if let Some(r) = set.statistic.reps {
total.reps += r;
if let Some(w) = set.statistic.weight {
total.weight += w * Decimal::from_usize(r).unwrap();
total.weight += w * r;
}
}
if let Some(d) = set.statistic.duration {
Expand All @@ -200,7 +195,7 @@ impl UserWorkoutInput {
}
let mut totals = WorkoutSetTotals::default();
if let (Some(we), Some(re)) = (&set.statistic.weight, &set.statistic.reps) {
totals.weight = Some(we * Decimal::from_usize(*re).unwrap());
totals.weight = Some(we * re);
}
let mut value = WorkoutSetRecord {
totals,
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/importer/strong_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
struct Entry {
date: String,
weight: Option<Decimal>,
reps: Option<usize>,
reps: Option<Decimal>,
distance: Option<Decimal>,
seconds: Option<Decimal>,
notes: Option<String>,
Expand Down
11 changes: 5 additions & 6 deletions apps/backend/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use database::{
MediaLot, MediaSource, SeenState, UserToMediaReason, Visibility,
};
use derive_more::{Add, AddAssign, Sum};
use rust_decimal::prelude::FromPrimitive;
use rust_decimal::Decimal;
use rust_decimal_macros::dec;
use schematic::ConfigEnum;
Expand Down Expand Up @@ -1517,7 +1516,7 @@ pub mod fitness {
/// The number of personal bests achieved.
pub personal_bests_achieved: usize,
pub weight: Decimal,
pub reps: usize,
pub reps: Decimal,
pub distance: Decimal,
pub duration: Decimal,
/// The total seconds that were logged in the rest timer.
Expand Down Expand Up @@ -1561,7 +1560,7 @@ pub mod fitness {
pub struct WorkoutSetStatistic {
pub duration: Option<Decimal>,
pub distance: Option<Decimal>,
pub reps: Option<usize>,
pub reps: Option<Decimal>,
pub weight: Option<Decimal>,
pub one_rm: Option<Decimal>,
pub pace: Option<Decimal>,
Expand Down Expand Up @@ -1660,7 +1659,7 @@ pub mod fitness {
// DEV: Formula from https://en.wikipedia.org/wiki/One-repetition_maximum#cite_note-7
pub fn calculate_one_rm(&self) -> Option<Decimal> {
let mut val = (self.statistic.weight? * dec!(36.0))
.checked_div(dec!(37.0) - Decimal::from_usize(self.statistic.reps?).unwrap());
.checked_div(dec!(37.0) - self.statistic.reps?);
if let Some(v) = val {
if v <= dec!(0) {
val = None;
Expand All @@ -1670,7 +1669,7 @@ pub mod fitness {
}

pub fn calculate_volume(&self) -> Option<Decimal> {
Some(self.statistic.weight? * Decimal::from_usize(self.statistic.reps?).unwrap())
Some(self.statistic.weight? * self.statistic.reps?)
}

pub fn calculate_pace(&self) -> Option<Decimal> {
Expand All @@ -1683,7 +1682,7 @@ pub mod fitness {
match pb_type {
WorkoutSetPersonalBest::Weight => self.statistic.weight,
WorkoutSetPersonalBest::Time => self.statistic.duration,
WorkoutSetPersonalBest::Reps => self.statistic.reps.and_then(Decimal::from_usize),
WorkoutSetPersonalBest::Reps => self.statistic.reps,
WorkoutSetPersonalBest::OneRm => self.calculate_one_rm(),
WorkoutSetPersonalBest::Volume => self.calculate_volume(),
WorkoutSetPersonalBest::Pace => self.calculate_pace(),
Expand Down
9 changes: 3 additions & 6 deletions apps/frontend/app/components/media.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,10 @@ export const ReviewItemDisplay = (props: {
if (conf)
deleteReviewFetcher.submit(
{
[redirectToQueryParam]: withoutHost(
window.location.href,
),
[redirectToQueryParam]: withoutHost(location.href),
shouldDelete: "true",
reviewId: props.review.id?.toString(),
// biome-ignore lint/suspicious/noExplicitAny: otherwise an error here
} as any,
reviewId: props.review.id || null,
},
{
method: "post",
action: $path("/actions", {
Expand Down
63 changes: 20 additions & 43 deletions apps/frontend/app/lib/state/workout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
export type ExerciseSet = {
statistic: WorkoutSetStatistic;
lot: SetLot;
confirmed: boolean;
confirmedAt?: string | null;
};

Expand Down Expand Up @@ -121,44 +120,37 @@ const getExerciseDetails = async (exerciseId: string) => {
return { details, userDetails };
};

export const duplicateOldWorkout = async (
workout: WorkoutDetailsQuery["workoutDetails"],
) => {
type TWorkoutDetails = WorkoutDetailsQuery["workoutDetails"];

export const convertHistorySetToCurrentSet = (
s: TWorkoutDetails["information"]["exercises"][number]["sets"][number],
) =>
({
lot: s.lot,
confirmedAt: null,
statistic: s.statistic,
}) satisfies ExerciseSet;

export const duplicateOldWorkout = async (workout: TWorkoutDetails) => {
const inProgress = getDefaultWorkout();
inProgress.name = workout.name;
inProgress.repeatedFrom = workout.id;
for (const [_exerciseIdx, ex] of workout.information.exercises.entries()) {
const sets = ex.sets.map((s) => ({
confirmed: false,
lot: s.lot,
statistic: {
...s.statistic,
duration: s.statistic.duration
? Number(s.statistic.duration)
: undefined,
distance: s.statistic.distance
? Number(s.statistic.distance)
: undefined,
weight: s.statistic.weight ? Number(s.statistic.weight) : undefined,
},
endedAt: s.confirmedAt,
}));
const sets = ex.sets.map(convertHistorySetToCurrentSet);
const exerciseDetails = await getExerciseDetails(ex.name);
inProgress.exercises.push({
identifier: randomUUID(),
isShowDetailsOpen: false,
exerciseDetails: { images: exerciseDetails.details.attributes.images },
images: [],
videos: [],
// biome-ignore lint/suspicious/noExplicitAny: required here
alreadyDoneSets: sets.map((s) => ({ statistic: s.statistic }) as any),
alreadyDoneSets: sets.map((s) => ({ statistic: s.statistic })),
exerciseId: ex.name,
lot: ex.lot,
notes: ex.notes,
supersetWith: [],
restTimer: ex.restTime ? { duration: ex.restTime, enabled: true } : null,
// biome-ignore lint/suspicious/noExplicitAny: required here
sets: sets as any,
sets: sets,
});
}
for (const [idx, exercise] of workout.information.exercises.entries()) {
Expand Down Expand Up @@ -187,18 +179,11 @@ export const addExerciseToWorkout = async (
images: exerciseDetails.details.attributes.images,
},
lot: ex.lot,
sets: [
{
confirmed: false,
statistic: {},
lot: SetLot.Normal,
},
],
sets: [{ statistic: {}, lot: SetLot.Normal }],
supersetWith: [],
alreadyDoneSets:
exerciseDetails.userDetails.history?.at(0)?.sets.map((s) => ({
// biome-ignore lint/suspicious/noExplicitAny: required here
statistic: s.statistic as any,
statistic: s.statistic,
})) || [],
restTimer: { duration: 60, enabled: true },
notes: [],
Expand Down Expand Up @@ -231,19 +216,11 @@ export const currentWorkoutToCreateWorkoutInput = (
for (const exercise of currentWorkout.exercises) {
const sets = Array<UserWorkoutSetRecord>();
for (const set of exercise.sets)
if (set.confirmed) {
if (set.confirmedAt) {
sets.push({
lot: set.lot,
confirmedAt: set.confirmedAt
? new Date(set.confirmedAt).toISOString()
: undefined,
statistic: {
...set.statistic,
distance: set.statistic.distance?.toString(),
duration: set.statistic.duration?.toString(),
weight: set.statistic.weight?.toString(),
// biome-ignore lint/suspicious/noExplicitAny: required here
} as any,
confirmedAt: new Date(set.confirmedAt).toISOString(),
statistic: set.statistic,
});
}
if (sets.length === 0) continue;
Expand Down
Loading

0 comments on commit f8a6f6f

Please sign in to comment.