SmartStopAPK/src/infraestructure/hooks/useDevices.ts

225 lines
6.2 KiB
TypeScript
Raw Normal View History

import {useCallback, useEffect, useMemo, useState} from 'react';
2023-12-22 22:40:24 -03:00
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';
2023-12-22 22:40:24 -03:00
import RemoteConfigKeys from '../../utils/RemoteConfigKeys';
import {Line} from '../../presentation/components/Table';
import Status from '../../utils/Status';
interface State {
status: Status;
lines: LineDetail[];
displayedLines: Line[];
currentIndex: number;
stopMessage: string;
stopName: string;
}
const DEVICE_ID = 'TTM543870hyt';
const useDevices = () => {
const [state, setState] = useState<State>({
status: Status.LOADING,
currentIndex: 0,
stopMessage: '',
displayedLines: [],
lines: [],
stopName: 'Sin información - Sin información',
});
2023-12-22 22:40:24 -03:00
const baseURL = remoteConfig().getString(RemoteConfigKeys.BASE_URL);
const username = remoteConfig().getString(RemoteConfigKeys.USER);
const password = remoteConfig().getString(RemoteConfigKeys.PASS);
const changePageInterval = remoteConfig().getNumber(
RemoteConfigKeys.CHANGE_PAGE_INTERVAL,
);
const updateBusesListInterval = remoteConfig().getNumber(
RemoteConfigKeys.UPDATE_BUSES_LIST_INTERVAL,
2023-12-22 22:40:24 -03:00
);
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 {
busStopInfoService.getNextArraival(line.lineNumber);
return line;
} catch (error) {
return undefined;
}
})
.filter((line): line is LineDetail => line !== undefined);
busStopInfoService = new BusStopInfoService(linesWithArrivals);
const linesToDisplay: Line[] = busStopInfoService
2023-12-22 22:40:24 -03:00
.pruneBusList(state.currentIndex, 21) // result 7 rows * 3 columns
.map(line => {
try {
const nextArraival = busStopInfoService.getNextArraival(
line.lineNumber,
);
const estimatedArrivalTimeInMinutes =
busStopInfoService.checkArraivalTime(nextArraival);
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(() => {
const init = async () => {
try {
const token = await authRepository.auth({username, password});
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) {
setState((prevState: State) => ({
...prevState,
status: Status.ERROR,
}));
}
};
init();
const interval = setInterval(init, updateBusesListInterval);
return () => {
clearInterval(interval);
};
}, [
authRepository,
devicesRepository,
password,
username,
updateBusesListInterval,
]);
useEffect(() => {
setDisplayedLines(state.lines, state.stopMessage, state.stopName);
}, [setDisplayedLines, state.lines, state.stopMessage, state.stopName]);
useEffect(() => {
const interval = setInterval(() => {
setState(prevState => {
const isGreatherThanLinesLength =
(prevState.currentIndex || 1) + 21 >= state.lines.length;
return {
...prevState,
currentIndex: isGreatherThanLinesLength
? 0
: (prevState.currentIndex || 1 + 21) % state.lines.length,
};
});
}, changePageInterval);
return () => {
clearInterval(interval);
};
}, [state.lines, state.status, changePageInterval]);
return {state};
};
export default useDevices;