Map/InfoCar/index.tsx
unknown
plain_text
2 years ago
31 kB
10
Indexable
/* eslint-disable react-native/no-inline-styles */
import React, {useEffect, useRef, useState, useMemo} from 'react';
import {
Text,
View,
TouchableOpacity,
Animated,
useWindowDimensions,
} from 'react-native';
import GetLocation from 'react-native-get-location';
import isEmpty from 'lodash/isEmpty';
import dayjs from 'dayjs';
// Navigation
import {useNavigation} from '@react-navigation/native';
import ScreensName from '@Configs/navigator';
// Redux Selectors
import {useSelector, useDispatch} from 'react-redux';
import {
getRunningTrains,
getCurrentTripKey,
getTripId,
getStationHistory,
getSimpleTrainConsistSelector,
} from '@Redux/trip/selectors';
import {getLocationData, getPosition} from '@Redux/info/selectors';
import {getModels} from '@Redux/model/selectors';
import {
getWaitingStatus,
getRunningStatus,
getFinishedStatus,
getTravelDistance,
getOrientation,
getActiveEnv,
getOutOfTrack,
getUserInteractTime,
getShowTrackGradeView,
getCurrentMilepost,
getLastTimeFinishedChanged,
} from '@Redux/common/selectors';
import {getUserAuthorizationSelector, getUsername} from '@Redux/auth/selectors';
import {getInstructionGroup} from '@Redux/instruction/selectors';
import {getStopStations, getTrackGroupData} from '@Redux/track/selectors';
import {
getSelectedTrainId,
getTrainSelectionInfo,
} from '@Redux/train/selectors';
import {getMultipleSpeedProfileList} from '@Redux/speedProfile/selectors';
import {getConsistTrain, getCurrentSpeed} from '@Redux/train/selectors';
import {getStationActive} from '@Redux/station/selectors';
// Redux Actions
import {
setRunning,
setFinished,
setWaiting,
setTravelDistance,
} from '@Redux/common/actions';
import {
setGpsItem,
setCurrentTripKey,
cleanGpsList,
clearModelEventList,
setModelEventItem,
setStartStationHistory,
setEndStationHistory,
addStationHistoryItem,
addSpeedHistoryItem,
} from '@Redux/trip/actions';
import {clearInstructionGroup} from '@Redux/instruction/actions';
// Components
import Loader from './Loader';
import RightWidget from './RightWidget';
import ETA from './ETA';
import RecommendationItem from './RecommendationItem/RecommendationItem';
import Recenter from '@Com/Recenter';
import CloseTrip from './CloseTrip';
import ZoomInOut from '@Com/ZoomInOut';
import TrackGradeView from '@Com/TrackGradeView';
import ScaleBar from '@Com/ScaleBar';
import Speedometer from '@Com/Speedometer';
// Constants
import {
END_TRIP_ON_ARRIVE_AFTER_SECONDS,
TRAIN_IMAGE_WIDTH_BY_KM,
} from '@Constants';
// Types
import {UseStateTuple, Region} from '@Types';
import {ModelEventType} from '@Types';
// Utils
import {modelInterface} from '@Utils/modelInterface';
import {filterInterface} from '@Utils/filterInterface';
import {
getOffsetCoordinate,
getBearingAngle,
haversineDistance,
} from '@Utils/geometryHelper';
import {getSegmentIdFromCoord} from '@Utils/getCorridorSegmentDetails';
import {
createNewGPSFile,
generateGPSFileName,
generateGpsData,
} from '@Utils/gpsData';
import {
generateModelFileName,
createNewModelFile,
appendToModelFile,
} from '@Utils/modelData';
// Hooks
import useLogGPSLocation from '@Hooks/useLogGPSLocation';
// Styles
import styles from './styles';
const ModelInterface = new modelInterface();
export type MapProps = {
region?: Region;
};
const InfoCar: React.FC<{
mapRef: any;
regionRef: any;
isReady: boolean;
}> = ({mapRef, regionRef, isReady}) => {
const {width, height: screenHeight} = useWindowDimensions();
const dispatch = useDispatch();
const navigation = useNavigation();
const currentAngleRef = useRef();
const currentTravelDistance = useRef(0);
const [totalDistanceBase, setTotalDistanceBase]: UseStateTuple<number> =
useState(0);
const trains = useSelector(state => getRunningTrains(state));
const orientation = useSelector(state => getOrientation(state));
const envName = useSelector(state => getActiveEnv(state));
const height = envName === 'production' ? screenHeight : screenHeight - 25;
const models = useSelector(state => getModels(state));
const runningStatus = useSelector(state => getRunningStatus(state));
const waitingStatus = useSelector(state => getWaitingStatus(state));
const finishedStatus = useSelector(state => getFinishedStatus(state));
const lastTimeFinishedChanged = useSelector(state =>
getLastTimeFinishedChanged(state),
);
const isOutOfTrack = useSelector(state => getOutOfTrack(state));
const selectedTrainId = useSelector(state => getSelectedTrainId(state));
const currentMilePost = useSelector(getCurrentMilepost);
const position = useSelector(state => getPosition(state));
const location = useSelector(state => getLocationData(state));
const travelDistance = useSelector(state => getTravelDistance(state));
const instructionGroup = useSelector(state => getInstructionGroup(state));
const stopStations = useSelector(state => getStopStations(state));
const currentTripKey = useSelector(state => getCurrentTripKey(state));
const trackGroupData = useSelector(state => getTrackGroupData(state));
const tripId = useSelector(state => getTripId(state));
const username = useSelector(state => getUsername(state));
const userAuthorization = useSelector(state =>
getUserAuthorizationSelector(state),
);
const trainSelectionInfo = useSelector(state => getTrainSelectionInfo(state));
const simpleTrainConsist = useSelector(state =>
getSimpleTrainConsistSelector(state),
);
const stationHistory = useSelector(state => getStationHistory(state));
const multipleSpeedProfile = useSelector(state =>
getMultipleSpeedProfileList(state),
);
const userInteractTime = useSelector(state => getUserInteractTime(state));
const showTrackGradeView = useSelector(getShowTrackGradeView);
const activeStation = useSelector(getStationActive);
const consistTrain = useSelector(getConsistTrain);
const currentSpeed = useSelector(getCurrentSpeed);
let speedProfile = [];
if (currentTripKey && !isEmpty(multipleSpeedProfile)) {
if (typeof multipleSpeedProfile[currentTripKey] !== 'undefined') {
speedProfile = multipleSpeedProfile[currentTripKey]?.data || [];
}
}
const corridorList: any[] = useMemo(() => {
if (currentTripKey && !isEmpty(trackGroupData)) {
if (typeof trackGroupData[currentTripKey] !== 'undefined') {
return trackGroupData[currentTripKey]?.data?.corridors || [];
} else {
return [];
}
} else {
return [];
}
}, [trackGroupData, currentTripKey]);
let instructions = [];
if (currentTripKey && !isEmpty(instructionGroup)) {
if (typeof instructionGroup[currentTripKey] !== 'undefined') {
instructions = instructionGroup[currentTripKey]?.data || [];
}
}
const [count, setCount] = useState(0);
const [gpsJsonFileName, setGPSJsonFileName]: UseStateTuple<string | any> =
useState(null);
const [modelJsonFileName, setModelJsonFileName]: UseStateTuple<string | any> =
useState(null);
const [arriveTime, setArriveTime]: UseStateTuple<any> = useState(null);
const opacityRef = useRef(new Animated.Value(1)).current;
const trackingTrainId = isEmpty(selectedTrainId) ? 'none' : selectedTrainId;
const [zoomScale, setZoomScale]: UseStateTuple<number> = useState(0);
const [cameraCenter, setCameraCenter]: UseStateTuple<any> = useState(null);
const [prevZoomScale, setPrevZoomScale]: UseStateTuple<number> = useState(0);
const [loading, setLoading]: UseStateTuple<boolean> = useState(true);
const [startAngle, setStartAngle]: UseStateTuple<number> = useState(0);
const [startPos, setStartPos]: UseStateTuple<any> = useState();
const [timerCheck, setTimerCheck]: UseStateTuple<number> = useState(0);
const [confirmArrived, setConfirmArrived]: UseStateTuple<boolean> =
useState(false);
const [currentRecommendation, setCurrentRecommendation]: UseStateTuple<any> =
useState(null);
const [
incomingRecommendation,
setIncomingRecommendation,
]: UseStateTuple<any> = useState(null);
const corridorListFilter = useMemo(
() =>
corridorList.map((item: any) => {
return [
item.gpsCoordinates.lat,
item.gpsCoordinates.lng,
item.corridor,
item.station,
item.stn1x,
item.stn2x,
item.distanceToNext,
item.milepost,
];
}),
[corridorList],
);
const sortInstruction = instructions.sort((a: any, b: any) => {
return a.startMile - b.startMile;
});
const nextInstructionIndex = sortInstruction.findIndex((item: any) => {
return item.startMile > travelDistance;
});
const filterSpeedProfile = speedProfile.sort(
(a, b) => a?.distance - b?.distance,
);
const currentSpeedProfleValueIndex = filterSpeedProfile.findIndex(item => {
return item?.distance >= travelDistance;
});
const currentSpeedProfleValue =
currentSpeedProfleValueIndex >= 0
? filterSpeedProfile[currentSpeedProfleValueIndex]
: filterSpeedProfile[filterSpeedProfile.length - 1];
const estimatedTimeWithSpeedProfile = useMemo(() => {
let timeToArrival;
if (Number.isNaN(currentSpeedProfleValue?.estimatedDurationToArrival)) {
timeToArrival = dayjs();
} else {
timeToArrival = dayjs().add(
currentSpeedProfleValue?.estimatedDurationToArrival,
'minute',
);
}
return timeToArrival.format('h:mma');
}, [currentSpeedProfleValue, timerCheck]);
useEffect(() => {
ModelInterface.loadAllModels(models);
}, []);
useEffect(() => {
const timerInterval = setInterval(() => {
setTimerCheck(prev => (prev += 1));
}, 60000);
return () => {
clearInterval(timerInterval);
};
}, []);
useEffect(() => {
const trackGroupDataValues = Object.values(trackGroupData) || [];
const firstTrackData = trackGroupDataValues.find(item => item.order === 0);
if (firstTrackData) {
setStartPos([
firstTrackData?.data?.corridors[0]?.gpsCoordinates.lat,
firstTrackData?.data?.corridors[0]?.gpsCoordinates.lng,
]);
}
}, []);
useEffect(() => {
checkForZoomLevel(userInteractTime);
}, [userInteractTime]);
const checkForZoomLevel = async (numberCheck = 0) => {
try {
const camera = await mapRef.current?.getCamera();
if (numberCheck === 0 || !camera) {
setZoomScale(13.5);
} else {
setZoomScale(camera.zoom);
}
} catch (error) {
setZoomScale(13.5);
console.log('setZoomScale Error', error);
}
};
const opacity = opacityRef.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
});
const closeLoader = () => {
Animated.timing(opacityRef, {
toValue: 0,
duration: 500,
useNativeDriver: true,
}).start(() => {
setLoading(false);
});
};
const setCameraMap = async (
trainsSet: any,
latitude: number,
longitude: number,
isGettingReady: boolean = false,
) => {
let angleCarDefault = 90;
const camera = await mapRef.current?.getCamera();
setCameraCenter(camera.center);
if (!zoomScale) {
setZoomScale(camera.zoom);
}
// if (zoomScale !== prevZoomScale) {
// setPrevZoomScale(zoomScale);
// hideTrain();
// }
const offsetWithCorridor = getOffsetCoordinate(
[latitude, longitude],
TRAIN_IMAGE_WIDTH_BY_KM / 2,
angleCarDefault + trainsSet[0].angle + 90,
);
const offsetValue = (zoom: number) => {
const isLandScape = orientation === 'landscape' ? true : false;
if (zoom < 10.5) {
return isLandScape ? 6 : 16;
}
switch (Math.floor(zoom)) {
case 10:
return isLandScape ? 4 : 10;
case 11:
return isLandScape ? 2 : 6;
case 12:
return isLandScape ? 1 : 3;
case 13:
if (zoom > 13.5) {
return isLandScape ? 0.4 : 1.2;
}
return isLandScape ? 0.8 : 2;
case 14:
return isLandScape ? 0.25 : 0.6;
case 15:
return isLandScape ? 0.14 : 0.3;
case 16:
return isLandScape ? 0.07 : 0.2;
case 17:
return isLandScape ? 0.04 : 0.1;
default:
return 0;
}
};
let offsetWithCenter;
if (runningStatus) {
offsetWithCenter = getOffsetCoordinate(
[offsetWithCorridor.latitude, offsetWithCorridor.longitude],
isOutOfTrack ? 0 : offsetValue(zoomScale),
angleCarDefault + trainsSet[0].angle,
);
} else {
offsetWithCenter = getOffsetCoordinate(
[offsetWithCorridor.latitude, offsetWithCorridor.longitude],
isOutOfTrack && !isGettingReady ? 0 : offsetValue(zoomScale),
angleCarDefault + startAngle,
);
}
const autoCenterLocation = {
latitude: offsetWithCenter.latitude,
longitude: offsetWithCenter.longitude,
};
let autoHeading = angleCarDefault + startAngle;
if (runningStatus) {
if (isOutOfTrack) {
autoHeading = currentAngleRef.current
? currentAngleRef.current
: angleCarDefault + startAngle;
} else {
autoHeading = angleCarDefault + trainsSet[0].angle;
currentAngleRef.current = angleCarDefault + trainsSet[0].angle;
}
} else {
autoHeading = angleCarDefault + startAngle;
}
// autoCenter
// ? mapRef.current.animateCamera({
// ...camera,
// zoom: zoomScale ? zoomScale : camera.zoom,
// heading: autoCenter ? autoHeading : camera.heading,
// center: autoCenter ? autoCenterLocation : camera.center,
// })
// : null;
/**
* check Loading
*/
if (loading) {
setTimeout(() => {
closeLoader();
}, 3000);
}
};
useEffect(() => {
if (loading) {
setTimeout(() => {
closeLoader();
}, 3000);
}
}, []);
const processStopStations = useMemo(() => {
return Object.values(stopStations).sort(
(a: any, b: any) => a?.order - b?.order,
);
}, [stopStations]);
const setGpsDataToStore = () => {
GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 15000,
})
.then(location => {
const gpsData = generateGpsData(location);
if (runningStatus) {
// if (regionRef.current?.latitude !== location.latitude) {
dispatch(setGpsItem(gpsData));
// }
}
})
.catch(error => {
const {code, message} = error;
// console.warn(code, message);
});
};
useEffect(() => {
dispatch(
addSpeedHistoryItem({
distance: travelDistance + totalDistanceBase,
speed: currentSpeed,
}),
);
if (trackingTrainId === 'none') {
return;
}
setGpsDataToStore();
}, [position]);
// CHECK ARRIVED AT LAST STATION AND CLOSE THE TRIP
useEffect(() => {
const timeout = setTimeout(() => {
setCount(count + 1);
const currentTime = Math.floor(Date.now() / 1000);
if (
finishedStatus &&
lastTimeFinishedChanged + END_TRIP_ON_ARRIVE_AFTER_SECONDS < currentTime
) {
const stationPair = currentTripKey.split('-');
dispatch(
setEndStationHistory({
stationId: stationPair[1],
arrivedTimeStamp: new Date().toString(),
departedTimeStamp: null,
}),
);
dispatch(setFinished(false));
dispatch(setWaiting(false));
dispatch(setRunning(false));
dispatch(clearInstructionGroup());
navigation.navigate(ScreensName.TRIP_REVIEW);
}
}, 5000);
return () => clearTimeout(timeout);
}, [finishedStatus, lastTimeFinishedChanged, count]);
// CHECK ARRIVED_AT_STATION
useEffect(() => {
if (
!(corridorList && corridorList.length > 0 && position && stopStations)
) {
return;
}
const currentEndStation = corridorList[corridorList.length - 1];
// Calculate distance between current train position and current end station
const distTrainToCurrentEndStation = haversineDistance(position, [
currentEndStation.gpsCoordinates.lat,
currentEndStation.gpsCoordinates.lng,
]);
const ARRIVED_RADIUS = 0.5;
if (distTrainToCurrentEndStation < ARRIVED_RADIUS) {
const currentMovementOrder = stopStations[currentTripKey]?.order;
const numberOfMovements = Object.keys(stopStations).length;
const isLastMovement = currentMovementOrder === numberOfMovements - 1;
if (isLastMovement) {
dispatch(setFinished(true));
dispatch(setWaiting(false));
} else {
dispatch(setWaiting(true));
}
setCurrentRecommendation(null);
setIncomingRecommendation(null);
}
}, [position, corridorList]);
useEffect(() => {
const startingAngle = getBearingAngle(
[
corridorList[0]?.gpsCoordinates.lat,
corridorList[0]?.gpsCoordinates.lng,
],
[
corridorList[corridorList?.length - 1]?.gpsCoordinates.lat,
corridorList[corridorList?.length - 1]?.gpsCoordinates.lng,
],
);
setStartAngle(startingAngle);
}, [corridorList]);
// useEffect(() => {
// if (trackingTrainId !== 'none' && trains.length > 0) {
// const train = getCurrentTrain(trackingTrainId, trains);
// if (train.position) {
// const {latitude, longitude} = train.position;
// setGpsDataToStore();
// regionRef.current = {
// latitude,
// longitude,
// zoom: Math.floor(zoomScale),
// zoomDetail: zoomScale,
// };
// if (isReady) {
// if (runningStatus || waitingStatus || !startPos?.length) {
// setCameraMap(trains, latitude, longitude);
// } else {
// setCameraMap(trains, startPos[0], startPos[1], true);
// }
// }
// }
// }
// }, [
// trains,
// trackingTrainId,
// mapRef,
// zoomScale,
// runningStatus,
// waitingStatus,
// startPos,
// startAngle,
// autoCenter,
// loading,
// ]);
const startSetCameraCenter = async () => {
const camera = await mapRef.current?.getCamera();
if (camera) {
setCameraCenter(camera.center);
}
};
useEffect(() => {
startSetCameraCenter();
}, []);
const handleIncomingRecommendation = (
position: [number, number],
milepost: number,
speed: number,
currentSegmentId: number,
) => {
const recommendation = ModelInterface.getIncomingRecommendation(
milepost,
speed,
corridorList,
currentSegmentId,
travelDistance,
);
appendToModelFile(
modelJsonFileName,
ModelEventType.MODEL_RUN,
location,
recommendation,
);
const filteredResult = filterInterface.filterRecommendation(
recommendation,
speed,
);
if (filteredResult.filtered) {
appendToModelFile(
modelJsonFileName,
ModelEventType.MODEL_FILTERED_RECOMMENDATION,
location,
recommendation,
);
}
if (
!incomingRecommendation &&
!currentRecommendation &&
recommendation &&
!filteredResult.filtered
) {
setIncomingRecommendation({...recommendation, position: position});
appendToModelFile(
modelJsonFileName,
ModelEventType.MODEL_UI_INCOMING_RECOMMENDATIONS,
location,
recommendation,
);
}
};
const handleCurrentRecommendation = async (
position: [number, number],
milepost: number,
speed: number,
) => {
const recommendation = ModelInterface.getCurrentRecommendation(
milepost,
speed,
);
appendToModelFile(
modelJsonFileName,
ModelEventType.MODEL_RUN,
location,
recommendation,
);
const isFiltered = filterInterface.filterRecommendation(
recommendation,
speed,
);
if (isFiltered.filtered) {
appendToModelFile(
modelJsonFileName,
ModelEventType.MODEL_FILTERED_RECOMMENDATION,
location,
recommendation,
);
}
if (!currentRecommendation && recommendation && !isFiltered.filtered) {
setCurrentRecommendation({...recommendation, position: position});
appendToModelFile(
modelJsonFileName,
ModelEventType.MODEL_UI_ACTIVE_RECOMMENDATION_START,
location,
recommendation,
);
}
setIncomingRecommendation(null);
};
// Check for incoming recommendation
useEffect(() => {
const currentSegmentId = getSegmentIdFromCoord(
position,
corridorListFilter,
);
if (!currentTravelDistance.current) {
currentTravelDistance.current = travelDistance;
}
if (Math.abs(travelDistance - currentTravelDistance.current) > 0.1) {
currentTravelDistance.current = travelDistance;
if (!incomingRecommendation && !currentRecommendation) {
handleIncomingRecommendation(
travelDistance,
currentMilePost,
currentSpeed,
currentSegmentId,
);
} else if (
incomingRecommendation &&
!currentRecommendation &&
travelDistance >= incomingRecommendation.targetDistance
) {
handleCurrentRecommendation(
travelDistance,
currentMilePost,
currentSpeed,
);
}
}
}, [travelDistance, currentSpeed]);
// Check to clear recommendation
useEffect(() => {
if (currentRecommendation) {
if (
travelDistance - currentRecommendation.position >
currentRecommendation.distance
) {
appendToModelFile(
modelJsonFileName,
ModelEventType.MODEL_UI_ACTIVE_RECOMMENDATION_END,
location,
currentRecommendation,
);
setCurrentRecommendation(null);
}
}
}, [travelDistance, currentRecommendation]);
useLogGPSLocation(gpsJsonFileName);
return (
<>
{loading && <Loader opacity={opacity} />}
{/* Display or hide arrived/start buttons */}
{finishedStatus ? (
<TouchableOpacity
style={[
styles.btnStartStop,
styles.wrapOver,
{
left: orientation === 'landscape' ? 260 : 145,
},
]}
onPress={() => {
const stationPair = currentTripKey.split('-');
dispatch(
setEndStationHistory({
stationId: stationPair[1],
arrivedTimeStamp: new Date().toString(),
departedTimeStamp: null,
}),
);
dispatch(setFinished(false));
dispatch(setWaiting(false));
dispatch(setRunning(false));
dispatch(clearInstructionGroup());
navigation.navigate(ScreensName.TRIP_REVIEW);
}}>
<Text style={styles.btnArrivedAtStationText}>End Trip</Text>
</TouchableOpacity>
) : waitingStatus && !confirmArrived ? (
<TouchableOpacity
style={[
styles.btnStartStop,
styles.wrapOver,
{
left: orientation === 'landscape' ? 260 : 145,
},
]}
onPress={() => {
if (waitingStatus) {
const currentOrder = Object.values(stopStations).find(
item => item.key === currentTripKey,
)?.order;
const nextRoute = Object.values(stopStations).find(
item => item.order === currentOrder + 1,
);
dispatch(setCurrentTripKey(nextRoute?.key || currentTripKey));
}
dispatch(setRunning(false));
dispatch(cleanGpsList());
dispatch(clearModelEventList());
setTotalDistanceBase(travelDistance + totalDistanceBase);
dispatch(setTravelDistance(0));
setConfirmArrived(true);
setArriveTime(new Date().toString());
}}>
<Text style={styles.btnArrivedAtStationText}>End Trip Section</Text>
</TouchableOpacity>
) : waitingStatus ? (
<TouchableOpacity
style={[
styles.btnStartStop,
styles.wrapOver,
{
left: orientation === 'landscape' ? 260 : 145,
},
]}
onPress={async () => {
if (!gpsJsonFileName) {
const fileName = generateGPSFileName(
String(userAuthorization?.railroadId),
String(simpleTrainConsist?.simpleTrainConsistId),
);
setGPSJsonFileName(fileName);
await createNewGPSFile(
String(userAuthorization?.railroadId),
String(simpleTrainConsist?.tripId),
String(userAuthorization?.userId),
fileName,
location,
String(simpleTrainConsist?.simpleTrainConsistId),
String(consistTrain?.locomotiveModel),
);
}
const [currentStartStationId, currentEndStationId] =
currentTripKey.split('-');
if (stationHistory?.startStationHistory) {
dispatch(
addStationHistoryItem({
stationId: currentStartStationId,
arrivedTimeStamp: arriveTime,
departedTimeStamp: new Date().toString(),
}),
);
} else {
dispatch(
setStartStationHistory({
stationId: currentStartStationId,
arrivedTimeStamp: null,
departedTimeStamp: new Date().toString(),
}),
);
}
const loadModel = ModelInterface.selectModel(
currentStartStationId,
currentEndStationId,
);
if (!modelJsonFileName) {
const fileName = generateModelFileName(
String(userAuthorization?.railroadId),
String(simpleTrainConsist?.simpleTrainConsistId),
);
setModelJsonFileName(fileName);
await createNewModelFile(
String(userAuthorization?.railroadId),
String(simpleTrainConsist?.tripId),
String(userAuthorization?.userId),
fileName,
location,
String(simpleTrainConsist?.simpleTrainConsistId),
String(consistTrain?.locomotiveModel),
loadModel
? ModelEventType.MODEL_LOADED
: ModelEventType.MODEL_LOAD_FAILED,
);
}
dispatch(setRunning(true));
setConfirmArrived(false);
dispatch(setWaiting(false));
}}>
<Text style={styles.btnStartText} testID="start-button">
Start Trip Section
</Text>
</TouchableOpacity>
) : runningStatus ? (
currentRecommendation ? (
<RecommendationItem
instruction={currentRecommendation}
travelValue={
currentRecommendation?.position +
currentRecommendation?.distance -
travelDistance
}
/>
) : null
) : (
<TouchableOpacity
style={[
styles.btnStartStop,
styles.wrapOver,
{
left: orientation === 'landscape' ? 260 : 145,
},
]}
onPress={async () => {
if (!gpsJsonFileName) {
const fileName = generateGPSFileName(
String(userAuthorization?.railroadId),
String(simpleTrainConsist?.simpleTrainConsistId),
);
setGPSJsonFileName(fileName);
await createNewGPSFile(
String(userAuthorization?.railroadId),
String(simpleTrainConsist?.tripId),
String(userAuthorization?.userId),
fileName,
location,
String(simpleTrainConsist?.simpleTrainConsistId),
String(consistTrain?.locomotiveModel),
);
}
const [currentStartStationId, currentEndStationId] =
currentTripKey.split('-');
if (stationHistory?.startStationHistory) {
dispatch(
addStationHistoryItem({
stationId: currentStartStationId,
arrivedTimeStamp: arriveTime,
departedTimeStamp: new Date().toString(),
}),
);
} else {
dispatch(
setStartStationHistory({
stationId: currentStartStationId,
arrivedTimeStamp: null,
departedTimeStamp: new Date().toString(),
}),
);
}
const loadModel = ModelInterface.selectModel(
currentStartStationId,
currentEndStationId,
);
if (!modelJsonFileName) {
const fileName = generateModelFileName(
String(userAuthorization?.railroadId),
String(simpleTrainConsist?.simpleTrainConsistId),
);
setModelJsonFileName(fileName);
await createNewModelFile(
String(userAuthorization?.railroadId),
String(simpleTrainConsist?.tripId),
String(userAuthorization?.userId),
fileName,
location,
String(simpleTrainConsist?.simpleTrainConsistId),
String(consistTrain?.locomotiveModel),
loadModel
? ModelEventType.MODEL_LOADED
: ModelEventType.MODEL_LOAD_FAILED,
);
}
dispatch(setRunning(true));
}}>
<Text style={styles.btnStartText} testID="start-button">
Start Trip
</Text>
</TouchableOpacity>
)}
<CloseTrip />
<ETA estimatedTime={estimatedTimeWithSpeedProfile} />
<View style={styles.wrapControlButtons}>
<ZoomInOut
mapRef={mapRef}
zoomScale={zoomScale}
setZoomScale={setZoomScale}
/>
<Recenter mapRef={mapRef} zoomScale={zoomScale} />
</View>
<Speedometer />
<TrackGradeView track={corridorList} />
<RightWidget
zoomScale={zoomScale}
incomingRecommendation={incomingRecommendation}
/>
<ScaleBar
zoomLevel={zoomScale || null}
latitude={cameraCenter?.latitude || null}
overridenStyles={{bottom: showTrackGradeView ? 270 : 70}}
/>
</>
);
};
export default InfoCar;
Editor is loading...