UNPKG

@ledgerhq/live-common

Version:
182 lines • 6.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAction = void 0; const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const react_1 = require("react"); const logs_1 = require("@ledgerhq/logs"); const observable_1 = require("../../observable"); const app_1 = require("./app"); const implementations_1 = require("./implementations"); const getLatestFirmwareForDeviceUseCase_1 = require("../../device/use-cases/getLatestFirmwareForDeviceUseCase"); const mapResult = ({ deviceInfo, device, result }) => deviceInfo && device ? { device, deviceInfo, result, } : null; const getInitialState = (device) => ({ isLoading: device === undefined || !!device, requestQuitApp: false, unresponsive: false, isLocked: false, allowManagerRequested: false, allowManagerGranted: false, device, deviceInfo: null, deviceId: null, result: null, error: null, }); const reducer = (state, e) => { switch (e.type) { case "unresponsiveDevice": return { ...state, unresponsive: true }; case "lockedDevice": return { ...state, isLocked: true }; case "deviceChange": return getInitialState(e.device); case "error": return { ...getInitialState(state.device), error: e.error, isLoading: false, isLocked: false, }; case "appDetected": return { ...state, unresponsive: false, isLocked: false, requestQuitApp: true, }; case "osu": case "bootloader": return { ...state, isLoading: false, unresponsive: false, isLocked: false, requestQuitApp: false, deviceInfo: e.deviceInfo, }; case "listingApps": return { ...state, isLoading: true, requestQuitApp: false, unresponsive: false, isLocked: false, deviceInfo: e.deviceInfo, }; case "device-permission-requested": return { ...state, unresponsive: false, isLocked: false, allowManagerRequested: true, }; case "device-permission-granted": return { ...state, unresponsive: false, isLocked: false, allowManagerRequested: false, allowManagerGranted: true, }; case "device-id": return { ...state, deviceId: e.deviceId, }; case "result": return { ...state, isLoading: false, unresponsive: false, isLocked: false, result: e.result, }; } return state; }; const createAction = (task) => { const useHook = (device, request = {}) => { const [state, setState] = (0, react_1.useState)(() => getInitialState()); const [resetIndex, setResetIndex] = (0, react_1.useState)(0); const deviceSubject = (0, observable_1.useReplaySubject)(device); // repair modal will interrupt everything and be rendered instead of the background content const [repairModalOpened, setRepairModalOpened] = (0, react_1.useState)(null); (0, react_1.useEffect)(() => { if (request?.cancelExecution) return; const impl = (0, implementations_1.getImplementation)(app_1.currentMode)({ deviceSubject, task, request, retryableWithDelayDisconnectedErrors: [], }); if (repairModalOpened) return; const sub = impl .pipe((0, operators_1.tap)((e) => (0, logs_1.log)("actions-manager-event", e.type, e)), (0, operators_1.debounce)((e) => ("replaceable" in e && e.replaceable ? (0, rxjs_1.interval)(100) : (0, rxjs_1.of)(null))), (0, operators_1.scan)(reducer, getInitialState())) .subscribe(setState); return () => { sub.unsubscribe(); }; }, [deviceSubject, resetIndex, repairModalOpened, request]); const { deviceInfo } = state; (0, react_1.useEffect)(() => { if (!deviceInfo) return; // Preload latest firmware in parallel (0, getLatestFirmwareForDeviceUseCase_1.getLatestFirmwareForDeviceUseCase)(deviceInfo).catch((e) => { (0, logs_1.log)("warn", e.message); }); }, [deviceInfo]); const onRepairModal = (0, react_1.useCallback)(open => { setRepairModalOpened(open ? { auto: false, } : null); }, []); const closeRepairModal = (0, react_1.useCallback)(() => { // Sets isBootloader to true to avoid having the renderBootloaderStep rendered, // on which the user could re-trigger a bootloader repairing scenario that is not needed setState(prevState => { return { ...prevState, deviceInfo: prevState.deviceInfo ? { ...prevState.deviceInfo, isBootloader: false } : null, }; }); setRepairModalOpened(null); }, []); const onRetry = (0, react_1.useCallback)(() => { setResetIndex(currIndex => currIndex + 1); setState(s => getInitialState(s.device)); }, []); const onAutoRepair = (0, react_1.useCallback)(() => { setRepairModalOpened({ auto: true, }); }, []); return { ...state, repairModalOpened, onRetry, onAutoRepair, closeRepairModal, onRepairModal, }; }; return { useHook, mapResult, }; }; exports.createAction = createAction; //# sourceMappingURL=manager.js.map