|
|
@ -16,15 +16,47 @@ interface ProgressState { |
|
|
|
currentIndex: number |
|
|
|
lastTransition: WorkoutState |
|
|
|
lastValue: WorkoutState |
|
|
|
toNext: { current: number, max: number } |
|
|
|
toNext: ToNext |
|
|
|
stopped: boolean |
|
|
|
} |
|
|
|
|
|
|
|
interface ToNext { |
|
|
|
current: number, |
|
|
|
max: number, |
|
|
|
} |
|
|
|
|
|
|
|
interface ProgressChange { |
|
|
|
skip?: boolean |
|
|
|
workoutState?: WorkoutState |
|
|
|
} |
|
|
|
|
|
|
|
function calculateToNext( |
|
|
|
step: ProgramStep & StepMeta, |
|
|
|
lastValue: WorkoutState, |
|
|
|
lastTransition: WorkoutState, |
|
|
|
): ToNext { |
|
|
|
if (step.duration) { |
|
|
|
if (step.duration.time) { |
|
|
|
return { |
|
|
|
current: lastValue.time - lastTransition.time, |
|
|
|
max: step.duration.time, |
|
|
|
}; |
|
|
|
} else if (step.duration.calories && lastTransition.calories !== undefined && lastValue.calories !== undefined) { |
|
|
|
return { |
|
|
|
current: lastValue.calories - lastTransition.calories, |
|
|
|
max: step.duration.calories, |
|
|
|
}; |
|
|
|
} else if (step.duration.distance && lastTransition.distance !== undefined && lastValue.distance !== undefined) { |
|
|
|
return { |
|
|
|
current: lastValue.distance - lastTransition.distance, |
|
|
|
max: step.duration.distance, |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
throw new Error("Illegal state"); |
|
|
|
} |
|
|
|
|
|
|
|
function programReducer(state: ProgressState, change: ProgressChange) { |
|
|
|
let {steps, currentIndex, lastTransition, lastValue, toNext, stopped} = state; |
|
|
|
|
|
|
@ -53,21 +85,16 @@ function programReducer(state: ProgressState, change: ProgressChange) { |
|
|
|
const step = steps[currentIndex]; |
|
|
|
|
|
|
|
if (step.duration) { |
|
|
|
if (step.duration.time) { |
|
|
|
toNext.current = lastValue.time - lastTransition.time; |
|
|
|
toNext.max = step.duration.time; |
|
|
|
} else if (step.duration.calories && lastTransition.calories !== undefined && lastValue.calories !== undefined) { |
|
|
|
toNext.current = lastValue.calories - lastTransition.calories; |
|
|
|
toNext.max = step.duration.calories; |
|
|
|
} else if (step.duration.distance && lastTransition.distance !== undefined && lastValue.distance !== undefined) { |
|
|
|
toNext.current = lastValue.distance - lastTransition.distance; |
|
|
|
toNext.max = step.duration.distance; |
|
|
|
} |
|
|
|
toNext = calculateToNext(step, lastValue, lastTransition); |
|
|
|
|
|
|
|
if (toNext.current >= toNext.max) { |
|
|
|
steps[currentIndex].actualDuration = diffLinearValues(lastValue, lastTransition); |
|
|
|
currentIndex += 1; |
|
|
|
lastTransition = lastValue; |
|
|
|
|
|
|
|
if (currentIndex < steps.length) { |
|
|
|
toNext = calculateToNext(steps[currentIndex], lastValue, lastTransition); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|