import {PastWorkout, WorkoutState} from "../models/Workouts"; import {createContext, useCallback, useContext, useEffect, useState} from "react"; import {unimplemented} from "../helpers/misc"; import {WithChildren} from "../primitives/Shared"; import workoutRepo from "../actions/workouts"; interface WorkoutContextValue { workouts: PastWorkout[] loadingWorkouts: boolean expanded: boolean getWorkout(workoutId: string): PastWorkout | null fetchWorkout(workoutId: string): void getStates(workoutId: string): WorkoutState[] | null fetchStates(workoutId: string): void refreshWorkouts(): void showMoreWorkouts(): void } const WorkoutContext = createContext({ workouts: [], loadingWorkouts: false, expanded: false, getWorkout: unimplemented, fetchWorkout: unimplemented, getStates: unimplemented, fetchStates: unimplemented, refreshWorkouts: unimplemented, showMoreWorkouts: unimplemented, }); export function WorkoutContextProvider({children}: WithChildren) { const [workouts, setWorkouts] = useState([]); const [cache, setCache] = useState>({}); const [loadingWorkouts, setLoadingWorkouts] = useState(false); const [expanded, setExpanded] = useState(false); const [ver, setVer] = useState(0); const [stateMap, setStateMap] = useState>({}); const getWorkout = useCallback((workoutId: string) => { return cache[workoutId] || workouts.find(w => w.id === workoutId); }, [cache, workouts]); const fetchWorkout = useCallback((workoutId: string) => { workoutRepo().findById(workoutId) .then(result => { if (result) { setCache(prev => ({...prev, [workoutId]: result})); } }); }, []); const getStates = useCallback((workoutId: string) => { return stateMap[workoutId] || null; }, [stateMap]); const fetchStates = useCallback((workoutId: string) => { workoutRepo().fetchStates(workoutId) .then(result => setStateMap(prev => ({...prev, [workoutId]: result}))); }, []); const refreshWorkouts = useCallback(() => { setVer(prev => prev + 1); }, []); const showMoreWorkouts = useCallback(() => { setExpanded(true); }, []); useEffect(() => { if (ver === 0) { return; } setLoadingWorkouts(true); workoutRepo().fetchByFilter({daysBack: expanded ? undefined : 6, includeTest: false}) .then(setWorkouts) .finally(() => setLoadingWorkouts(false)); }, [expanded, ver]); return ( {children} ); } export default WorkoutContext;