Speedometer.tsx

mail@pastecode.io avatar
unknown
plain_text
6 months ago
3.6 kB
1
Indexable
Never
/* eslint-disable react-native/no-inline-styles */
import React, {useMemo} from 'react';
import {Text, View} from 'react-native';

// Redux
import {useSelector} from 'react-redux';
import {getCurrentSpeed} from '@Redux/train/selectors';
import {getTrackGroupData} from '@Redux/track/selectors';
import {
  getFinishedStatus,
  getRunningStatus,
  getTravelDistance,
} from '@Redux/common/selectors';
import {getCurrentTripKey} from '@Redux/trip/selectors';

// Components
import CircularProgress from '@Com/CircularProgress';

// Styles
import styles from './styles';

// Utils
import {getCurrentSpeedLimit} from '@Utils/getCurrentSpeedLimit';

const Speedometer: React.FC<{screen?: any}> = ({screen = null}) => {
  const currentTrainSpeedRedux = useSelector(state => getCurrentSpeed(state));
  const trackGroupData = useSelector(state => getTrackGroupData(state));
  const currentTripKey = useSelector(state => getCurrentTripKey(state));
  const speedLimitsData =
    trackGroupData[currentTripKey]?.data?.trackSpeedLimit || [];

  const absoluteStartTrackDistanceMiles =
    useMemo(() => {
      return trackGroupData[currentTripKey]?.data
        ?.absoluteStartTrackDistanceMiles;
    }, [currentTripKey]) || 0;

  const finishedStatus = useSelector(state => getFinishedStatus(state));
  const runningStatus = useSelector(state => getRunningStatus(state));
  const travelDistance = useSelector(state => getTravelDistance(state));
  const currentTrainSpeed =
    typeof currentTrainSpeedRedux === 'number' &&
    !Number.isNaN(currentTrainSpeedRedux)
      ? currentTrainSpeedRedux
      : 0;

  const currentLimitValue = useMemo<number | null>(() => {
    return getCurrentSpeedLimit(
      travelDistance + absoluteStartTrackDistanceMiles,
      speedLimitsData,
    );
  }, [travelDistance, speedLimitsData]);

  const fillSpeedMeter = useMemo<number>(() => {
    if (finishedStatus || !runningStatus) {
      return 0;
    }

    return (currentTrainSpeed / (currentLimitValue ?? 0)) * 100;
  }, [currentTrainSpeed, currentLimitValue, finishedStatus, runningStatus]);

  return (
    <>
      <View
        style={[
          styles.wrapOver,
          styles.flexColumn,
          styles.whiteBg,
          styles.speedLimit,
          {
            bottom: screen === 'BaseMode' ? 320 : 345,
          },
        ]}>
        <Text
          style={[styles.textBlack, styles.fontBold, styles.speedLimitLabel]}>
          LIMIT
        </Text>
        <Text
          testID="speed-limit"
          style={[styles.textGray2, styles.fontBold, styles.speedLimitValue]}>
          {currentLimitValue && screen !== 'BaseMode'
            ? `${currentLimitValue} mph`
            : '- -'}
        </Text>
        <View
          style={[
            {
              ...styles.btnMph,
              top: 70,
            },
            styles.wrapOver,
          ]}>
          <CircularProgress
            size={130}
            width={5}
            fill={fillSpeedMeter}
            maxFill={100}
            rotation={245}
            tintColor="#42ff55"
            limitColor="#FF4242"
            backgroundColor="transparent"
            style={undefined}
            childrenContainerStyle={undefined}>
            {() => (
              <Text
                testID="current-speed"
                style={[
                  styles.textWhite,
                  styles.fontBold,
                  styles.currentSpeed,
                ]}>
                {`${currentTrainSpeed} mph`}
              </Text>
            )}
          </CircularProgress>
        </View>
      </View>
    </>
  );
};

export default Speedometer;