Browse Source

KPM

main
Stian Fredrik Aune 1 year ago
parent
commit
7ed13f49af
  1. 52
      webui-react/src/hooks/kpm.ts
  2. 3
      webui-react/src/pages/PlayPage.tsx
  3. 6
      webui-react/src/primitives/misc/Misc.tsx

52
webui-react/src/hooks/kpm.ts

@ -0,0 +1,52 @@
import {useContext, useEffect, useReducer} from "react";
import RuntimeContext from "../contexts/RuntimeContext";
import {Values} from "../models/Shared";
import {WorkoutState} from "../models/Workouts";
interface UseKpmReducerState {
lastStates: WorkoutState[]
kpm: number
}
export function useKpm() {
const {lastEvent} = useContext(RuntimeContext);
const [state, dispatch] = useReducer((state: UseKpmReducerState, newState: WorkoutState) => {
if (newState.time === 0) {
return {
lastStates: [],
kpm: 0,
};
}
const lastSeconds = Math.max(0, ...state.lastStates.map(s => s.time));
if (newState.time > lastSeconds) {
const sixtySecondsAgo = Math.max(0, newState.time - 60);
const inRange = state.lastStates.filter(s => s.time >= sixtySecondsAgo);
const first = inRange[0] || { time: 0, calories: 0 };
const duration = newState.time - first.time;
return {
lastStates: [...inRange, newState],
kpm: inRange.length > 30
? Math.round(((newState.calories || 0) - (first.calories || 0)) * 60 / duration)
: 0,
}
}
return state;
}, {
lastStates: [],
kpm: 0,
});
useEffect(() => {
if (lastEvent?.workoutStates) {
for (const state of lastEvent.workoutStates) {
dispatch(state);
}
}
}, [lastEvent]);
return state.kpm;
}

3
webui-react/src/pages/PlayPage.tsx

@ -19,6 +19,7 @@ import {ControlsBoi} from "./runtime/ControlsBoi";
import MessageBoi from "./runtime/MessageBoi";
import ProgramBoi from "./runtime/ProgramBoi";
import MilestoneBoi from "./runtime/MilestoneBoi";
import {useKpm} from "../hooks/kpm";
function PlayPage(): JSX.Element {
const {active, ready, ended, workout, reset, resume} = useContext(RuntimeContext);
@ -176,6 +177,7 @@ function CreatePlayPage(): JSX.Element {
function RunPlayPage(): JSX.Element {
const {workout} = useContext(RuntimeContext);
const lastState = useLastState();
const kpm = useKpm();
if (!workout || workout.status === WorkoutStatus.Created) {
return <LoadingPage minimal/>;
@ -193,6 +195,7 @@ function RunPlayPage(): JSX.Element {
<FluffyValue raw={lastState} valueKey="distance"/>
<FluffyValue raw={lastState} valueKey="level"/>
<FluffyValue raw={lastState} valueKey="rpmSpeed"/>
{kpm > 0 && <FluffyValue raw={kpm} valueKey="kpm"/>}
<FluffyValue raw={lastState} valueKey="pulse"/>
</Boi>
)}

6
webui-react/src/primitives/misc/Misc.tsx

@ -11,7 +11,7 @@ export function TitleLine({children}: WithChildren) {
interface ValueProps {
raw: Values | number
valueKey: keyof Values
valueKey: keyof Values | "kpm"
}
export function FluffyValue({raw, valueKey}: ValueProps): JSX.Element | null {
@ -61,6 +61,10 @@ export function Value({raw, valueKey}: ValueProps): JSX.Element | null {
return <><strong>{actual}</strong> rpm</>
}
if (valueKey === "kpm") {
return <><strong>{actual}</strong> kpm</>
}
if (valueKey === "pulse") {
return (
<>

Loading…
Cancel
Save