Stian Fredrik Aune
1 year ago
3 changed files with 60 additions and 1 deletions
-
52webui-react/src/hooks/kpm.ts
-
3webui-react/src/pages/PlayPage.tsx
-
6webui-react/src/primitives/misc/Misc.tsx
@ -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; |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue