import React, { useContext, useState } from "react"; import api from "../../services/vehiclesAPI"; import { LocalDateTimeString } from "../../utils/dates"; import { useInterval } from "usehooks-ts"; const CANSignalContext = React.createContext(); const BlankSignal = (msg) => ({ timestamp: "", signal: msg, value: "", }); const transformSignals = (signals) => signals .map((signal) => { const { timestamp, value, name } = signal; return { timestamp: LocalDateTimeString(timestamp), signal: name, value: value, }; }) .flat(); export const CANSignalProvider = ({ token, children }) => { // auto scale polling if not getting response const durations = [10000, 30000, 60000, 120000]; const delays = [500, 1500, 3000, 6000]; const [vin, setVIN] = useState(null); const [signals, setSignals] = useState([]); const [delayIndex, setDelayIndex] = useState(0); useInterval( () => { getCANSignals() }, vin ? delays[delayIndex] : null ) const getCANSignals = async () => { try { if (!vin) return; const date = new Date(); date.setUTCSeconds(date.getUTCSeconds() - durations[delayIndex]); const result = await api.getCANSignals(vin, { after_utc: date, }, token); if (result.error) throw new Error(`Get CAN signals error. ${result.message}`); const items = transformSignals(result.data); if (items.length > 0) { setDelayIndex((index) => { if (index === 0) { return 0; } return index -= 1; }); setSignals(items); } else { setDelayIndex((index) => { if (index < delays.length - 1) { return index += 1; } return index; }); setSignals([BlankSignal("No signals")]); } } catch (e) { setSignals([BlankSignal(e.message)]); } }; return ( {children} ); }; export const useCANSignalContext = () => useContext(CANSignalContext);