UNPKG

expo-running-kit

Version:

Expo native module for tracking running and walking workouts — GPS, pace, cadence, auto-pause, and laps.

106 lines 3.84 kB
import { useState, useRef } from "react"; import RunningKit from "../RunningKitModule"; import { toDisplayDistance, formatPace, useLocation } from "./useLocation"; import { useSession } from "./useSession"; import { useAutoPause } from "./useAutoPause"; const MIN_PACE_SPEED = 0.5; // m/s — below this pace is meaningless export function useRunningKit(config = {}) { const { units = "metric", autoPause = false, autoPauseDelay = 1, resumeThreshold = 30, speedSmoothingWindow = 5, } = config; const [laps, setLaps] = useState([]); const [summary, setSummary] = useState(null); const lapStartDistanceRef = useRef(0); const lapStartTimeRef = useRef(0); const { sessionState, sessionStateRef, duration, durationRef, resetSession } = useSession(); const { gpsQuality, distanceMeters, speedStats, paceStats, maxSpeedRef, bestPaceMsRef, resetLocation, steps, distanceRef, } = useLocation({ units, speedSmoothingWindow, durationRef, }); const { cancelAutoPause } = useAutoPause({ enabled: autoPause, cadence: steps.cadence, sessionState, sessionStateRef, delay: autoPauseDelay, resumeThreshold, }); // --- Actions --- async function requestPermissions() { return RunningKit.requestPermissions(); } async function startWorkout(type) { setSummary(null); setLaps([]); lapStartDistanceRef.current = 0; lapStartTimeRef.current = 0; resetSession(); resetLocation(); await RunningKit.startWorkout(type); } function pauseWorkout() { cancelAutoPause(); RunningKit.pauseWorkout(); } function resumeWorkout() { RunningKit.resumeWorkout(); } function recordLap() { const lapDistanceMeters = distanceMeters - lapStartDistanceRef.current; const lapDuration = duration - lapStartTimeRef.current; const lapAvgMs = lapDuration > 0 ? lapDistanceMeters / lapDuration : 0; const newLap = { number: laps.length + 1, duration: lapDuration, distance: toDisplayDistance(lapDistanceMeters, units), avgSpeed: lapAvgMs, avgPace: lapAvgMs > 0 ? formatPace(lapAvgMs, units) : null, }; setLaps((prev) => [...prev, newLap]); lapStartDistanceRef.current = distanceRef.current; lapStartTimeRef.current = duration; } async function stopWorkout() { cancelAutoPause(); const result = await RunningKit.stopWorkout(); const avgMs = result.duration > 0 ? result.distance / result.duration : 0; const finalSummary = { duration: Math.floor(result.duration), // ← floor here too distance: toDisplayDistance(result.distance, units), steps: result.steps, speed: { current: 0, avg: avgMs, max: maxSpeedRef.current, }, pace: { current: null, avg: avgMs >= MIN_PACE_SPEED ? formatPace(avgMs, units) : null, best: bestPaceMsRef.current >= MIN_PACE_SPEED ? formatPace(bestPaceMsRef.current, units) : null, }, calories: result.calories, laps, }; setSummary(finalSummary); return finalSummary; } return { sessionState, duration, summary, gpsQuality, distance: toDisplayDistance(distanceMeters, units), speed: speedStats, pace: paceStats, steps: steps, laps, recordLap, requestPermissions, startWorkout, pauseWorkout, resumeWorkout, stopWorkout, }; } //# sourceMappingURL=useRunningKit.js.map