UNPKG

@ledgerhq/live-common

Version:
67 lines (59 loc) 2.18 kB
import { useCallback, useEffect, useState } from "react"; import { updateFirmwareAction as defaultUpdateFirmwareAction, UpdateFirmwareActionState, initialState, } from "../actions/updateFirmware"; import { bufferTime, filter, map } from "rxjs/operators"; const STATE_UPDATE_THROTTLE = 500; export type UseUpdateFirmwareArgs = { deviceId: string; deviceName: string | null; updateFirmwareAction?: typeof defaultUpdateFirmwareAction; }; /** * Hook used to trigger the update of a firmware, it isn't triggered right away but rather returns * a function that triggers it. The function can be called multiple times in order to implement a * retry strategy * @param Args Object containing the arguments of the hook: a deviceId and an optional device action to used (useful for mocking) * @returns An object containing the current state of the update and the trigger update function */ export function useUpdateFirmware({ deviceId, deviceName, updateFirmwareAction = defaultUpdateFirmwareAction, }: UseUpdateFirmwareArgs): { updateState: UpdateFirmwareActionState; triggerUpdate: () => void; } { const [updateState, setUpdateState] = useState<UpdateFirmwareActionState>(initialState); const [nonce, setNonce] = useState(0); useEffect(() => { if (nonce > 0) { const sub = updateFirmwareAction({ deviceId, deviceName, }) .pipe( // in order to correctly throttle the events without losing any important events // we need to buffer them according to the throttle time and always return the latest event from the buffer bufferTime(STATE_UPDATE_THROTTLE), map(events => events[events.length - 1]), filter(e => e !== undefined), ) .subscribe({ next: (state: UpdateFirmwareActionState) => { setUpdateState(state); }, }); return () => { sub.unsubscribe(); }; } }, [deviceId, updateFirmwareAction, nonce, deviceName]); const triggerUpdate = useCallback(() => { setUpdateState(initialState); setNonce(nonce => nonce + 1); }, []); return { updateState, triggerUpdate }; }