import {useCallback, useEffect, useMemo, useState} from 'react'; import remoteConfig from '@react-native-firebase/remote-config'; import DevicesRepositoryImpl from '../repositories/DevicesRepositoryImpl'; import DevicesAPI from '../api/clients/DevicesAPI'; import AuthRepositoryImpl from '../repositories/AuthRepositoryImpl'; import AuthAPI from '../api/clients/AuthAPI'; import LineDetail from '../../domain/repositories/LineDetail'; import BusStopInfoService from '../../domain/services/BusStopInfoService'; import RemoteConfigKeys from '../../utils/RemoteConfigKeys'; import {Line} from '../../presentation/components/Table'; import Status from '../../utils/Status'; import {BUSES_BY_PAGE} from '../../domain/const'; //import DeviceInfo from 'react-native-device-info'; export interface State { status: Status; lines: LineDetail[]; displayedLines: Line[]; currentIndex: number; stopMessage: string; stopName: string; } //const deviceId = DeviceInfo.getUniqueId(); const DEVICE_ID ='TTM543870hyt';// String(deviceId); const useDevices = () => { const [state, setState] = useState({ status: Status.LOADING, currentIndex: 0, stopMessage: '', displayedLines: [], lines: [], stopName: '', }); const baseURL = remoteConfig().getString(RemoteConfigKeys.BASE_URL); const username = remoteConfig().getString(RemoteConfigKeys.USER); const password = remoteConfig().getString(RemoteConfigKeys.PASSWORD); const rut = remoteConfig().getString(RemoteConfigKeys.RUT); const changePageInterval = remoteConfig().getNumber( RemoteConfigKeys.CHANGE_PAGE_INTERVAL, ); const updateBusesListInterval = remoteConfig().getNumber( RemoteConfigKeys.UPDATE_BUSES_LIST_INTERVAL, ); const deviceApi = useMemo(() => new DevicesAPI(baseURL), [baseURL]); const authApi = useMemo(() => new AuthAPI(baseURL), [baseURL]); const devicesRepository = useMemo( () => new DevicesRepositoryImpl(deviceApi), [deviceApi], ); const authRepository = useMemo( () => new AuthRepositoryImpl(authApi), [authApi], ); const setDisplayedLines = useCallback( (lineDetails: LineDetail[], stopMessage: string, stopName: string) => { if (!lineDetails || !stopName) { return; } try { let busStopInfoService = new BusStopInfoService(lineDetails); const linesWithArrivals = lineDetails .map(line => { try { if (line.arrivals && line.arrivals.length > 0) { busStopInfoService.getNextArraival(line.lineNumber); } return line; } catch (error) { return undefined; } }) .filter((line): line is LineDetail => line !== undefined); busStopInfoService = new BusStopInfoService(linesWithArrivals); var estimatedArrivalTimeInMinutes=""; const linesToDisplay: Line[] = busStopInfoService .pruneBusList(state.currentIndex, BUSES_BY_PAGE) .map(line => { try { if (line.arrivals && line.arrivals.length > 0) { const nextArraival = busStopInfoService.getNextArraival( line.lineNumber, ); estimatedArrivalTimeInMinutes =busStopInfoService.checkArraivalTime(nextArraival); } else { estimatedArrivalTimeInMinutes = "Sin información"; } const lineLetter = busStopInfoService.getLineLetterFromDescription( line.description, ); const lineNumber = busStopInfoService.getLineNumberFromDescription( line.description, ); const lineDescription = busStopInfoService.getLineDescription( line.description, line.lineNumber, ); return { backgroundColor: line.backgroundColor, estimatedArrivalTimeInMinutes, letterColor: line.letterColor, lineLetter, lineNumber, lineDescription, }; } catch (error) { return undefined; } }) .filter((line): line is Line => line !== undefined); setState(prevState => { const displayedLines = linesToDisplay.length === 0 ? prevState.displayedLines : linesToDisplay; return { ...prevState, displayedLines, stopMessage, stopName, lines: lineDetails, }; }); } catch (error: unknown) { setState(prevState => ({ ...prevState, status: Status.ERROR, })); } }, [state.currentIndex], ); useEffect(() => { let timeout: NodeJS.Timeout; const init = async () => { try { setState((prevState: State) => ({ ...prevState, status: Status.LOADING, })); const token = await authRepository.auth({username, password, rut}); const {lineDetails, stopMessage} = await devicesRepository.getDeviceInfo({ deviceId: DEVICE_ID, token, }); const {stopName} = await devicesRepository.whoAmI({ deviceId: DEVICE_ID, token, }); if (!lineDetails) { setState((prevState: State) => ({ ...prevState, status: Status.ERROR, })); return; } setState((prevState: State) => ({ ...prevState, ...{ lines: lineDetails, stopMessage, stopName, status: Status.SUCCESS, }, })); } catch (error: unknown) { setState((prevState: State) => ({ ...prevState, status: Status.ERROR, })); } timeout = setTimeout(init, updateBusesListInterval); }; init(); return () => { clearTimeout(timeout); }; }, [ authRepository, devicesRepository, password, updateBusesListInterval, username, rut, ]); useEffect(() => { setDisplayedLines(state.lines, state.stopMessage, state.stopName); }, [setDisplayedLines, state.lines, state.stopMessage, state.stopName]); useEffect(() => { let timeout: NodeJS.Timeout; const init = () => { setState(prevState => { const currentIndex = prevState.currentIndex || 1; const isGreatherThanLinesLength = currentIndex + BUSES_BY_PAGE >= state.lines.length; return { ...prevState, currentIndex: isGreatherThanLinesLength ? 0 : (prevState.currentIndex || 1 + BUSES_BY_PAGE) % state.lines.length, }; }); timeout = setTimeout(init, changePageInterval); }; init(); return () => { clearTimeout(timeout); }; }, [changePageInterval, state.lines.length]); return {state}; }; export default useDevices;