Skip to content

Commit

Permalink
Fix and tidy JourneyStop time parsing logic
Browse files Browse the repository at this point in the history
  • Loading branch information
JeeZeh committed Jun 3, 2022
1 parent fcdac5c commit 60e2314
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 92 deletions.
4 changes: 2 additions & 2 deletions src/components/JourneyMap.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react"
import React from "react";
import { useEffect, useState, useRef } from "react";
import styled from "styled-components";
import moment from "moment";
Expand Down Expand Up @@ -180,7 +180,7 @@ export const JourneyMap = (props: JoruneyMapProps) => {
const renderStops = (journey: IJourney) => {
return journey.stops.map((stop, i) => (
<JourneyStop
station={stop}
movement={stop}
stopNumber={i}
trainPosition={journey.trainPosition}
journeyLength={journey.stops.length}
Expand Down
208 changes: 118 additions & 90 deletions src/components/JourneyStop.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import React from "react"
import React from "react";
import styled from "styled-components";
import { IMovement, ITrain } from "../api/IrishRailApi";
import "moment/locale/en-ie";
import { useWindowSize } from "../hooks/useWindowSize";
import moment from "moment";
moment.locale("en-ie");

interface JourneyStopProps {
station: IMovement;
stopNumber: number;
trainPosition: number;
journeyLength: number;
train: ITrain;
forceShowTime?: boolean;
}

export const Dot = styled.div<{ isPortable?: boolean }>`
height: 10px;
width: 10px;
Expand Down Expand Up @@ -145,107 +136,144 @@ export const smallify = (name: string, lite?: boolean): string => {
return name;
};

export const JourneyStop = (props: JourneyStopProps) => {
const {
station,
/**
* Retrieve the time to be displayed with the station on the journey map, formatted HH:MM.
* Time returned depenends on the status of the train, i.e. if arrived show scheduled departure, etc.
*/
const getTime = ({
movement,
stopNumber,
trainPosition,
}: Pick<
JourneyStopProps,
"movement" | "stopNumber" | "trainPosition"
>): string => {
if (!movement.ExpectedArrival) {
console.log(movement.LocationFullName, movement);
}

// Train left
if (movement.Departure) {
return movement.Departure.format("HH:mm");
}

// Train arrived at the station. If it's the destination, return the arrival time... it's not going anywhere
if (movement.Arrival && movement.LocationType === "D") {
return movement.Arrival.format("HH:mm");
}

// If we're stopped at a station, or if it's the origin (O or index 1) station, show the expected departure
if (
stopNumber === trainPosition ||
movement.LocationType === "O" ||
movement.LocationOrder == 1
) {
return movement.ExpectedDeparture.format("HH:mm");
}

// Otherwise we haven't yet arrived at this station, return the expected arrival time
if (movement.ExpectedArrival) {
return movement.ExpectedArrival.format("HH:mm");
}

// Base case if all else fails
return "??:??";
};

/**
* Generates the classes needed to style a the current JourneyStop on the train map.
*/
const getStationStyleClasses = (
{
movement,
stopNumber,
journeyLength,
trainPosition,
forceShowTime,
train,
} = props;

const isPortable = useWindowSize().width <= 1000;

let time: string | React.ReactElement = "";
let classes = "";

const getTime = (): string => {
if (station.Departure) {
return station.Departure.format("HH:mm");
}
if (station.Arrival) {
if (station.LocationType === "D") {
return station.Arrival.format("HH:mm");
} else if (stopNumber === trainPosition) {
return station.ExpectedDeparture.format("HH:mm");
}
}
}: JourneyStopProps,
time: string
) => {
const classNames =
[
0,
journeyLength - 1,
trainPosition - 1,
trainPosition + 1,
trainPosition,
].includes(stopNumber) || forceShowTime
? ["show-time"]
: [];

if (stopNumber < trainPosition) {
classNames.push("departed");
} else if (stopNumber == trainPosition) {
classNames.push(movement.Arrival ? "arrived" : "approaching");
} else {
classNames.push("future");
}

if (station.LocationType === "O") {
return station.ExpectedDeparture.format("HH:mm");
if (
!movement.Arrival &&
movement.LocationFullName == train.Stationfullname &&
movement.ScheduledArrival &&
movement.ExpectedArrival
) {
classNames.push("relevant");
classNames.push("show-time");
const diff = movement.ExpectedArrival.diff(
movement.ScheduledArrival,
"minutes"
);

let unaccountedDelay = 0;

// Only check the unaccounted delay if it's the next station
if (trainPosition !== -1 && trainPosition + 1 == movement.LocationOrder) {
unaccountedDelay = moment(train.Querytime, "HH:mm:SS").diff(
movement.ExpectedArrival,
"minutes"
);
}

return station.ExpectedArrival.format("HH:mm");
};

const getClasses = () => {
const classNames =
[
0,
journeyLength - 1,
trainPosition - 1,
trainPosition + 1,
trainPosition,
].includes(stopNumber) || forceShowTime
? ["show-time"]
: [];

if (stopNumber < trainPosition) {
classNames.push("departed");
} else if (stopNumber == trainPosition) {
classNames.push(station.Arrival ? "arrived" : "approaching");
} else {
classNames.push("future");
if (movement.ScheduledArrival && (diff > 2 || unaccountedDelay > 2)) {
classNames.push("delayed");
time = `${time} (${movement.ScheduledArrival.format("HH:mm")})`;
} else if (diff < -2) {
classNames.push("early");
time = `${time} (${movement.ScheduledArrival.format("HH:mm")})`;
}
}

if (
!station.Arrival &&
station.LocationFullName == train.Stationfullname &&
station.ScheduledArrival &&
station.ExpectedArrival
) {
classNames.push("relevant");
classNames.push("show-time");
const diff = station.ExpectedArrival.diff(
station.ScheduledArrival,
"minutes"
);
return classNames.join(" ");
};

let unaccountedDelay = 0;

// Only check the unaccounted delay if it's the next station
if (trainPosition !== -1 && trainPosition + 1 == station.LocationOrder) {
unaccountedDelay = moment(train.Querytime, "HH:mm:SS").diff(
station.ExpectedArrival,
"minutes"
);
}

if (station.ScheduledArrival && (diff > 2 || unaccountedDelay > 2)) {
classNames.push("delayed");
time = `${time} (${station.ScheduledArrival.format("HH:mm")})`;
} else if (diff < -2) {
classNames.push("early");
time = `${time} (${station.ScheduledArrival.format("HH:mm")})`;
}
}
interface JourneyStopProps {
movement: IMovement;
stopNumber: number;
trainPosition: number;
journeyLength: number;
train: ITrain;
forceShowTime?: boolean;
}

return classNames.join(" ");
};
export const JourneyStop = (props: JourneyStopProps) => {
const { movement } = props;
const isPortable = useWindowSize().width <= 1000;

time = getTime();
classes = getClasses();
let time: string | React.ReactElement = "";
let classes = "";

console.log(station);
time = getTime(props);
classes = getStationStyleClasses(props, time);

return (
<StationDiv className={classes} isPortable={isPortable}>
<Dot className={classes} isPortable={isPortable}>
{classes.includes("early") || classes.includes("delayed") ? "!" : null}
</Dot>
<Name className={classes} isPortable={isPortable}>
{smallify(station.LocationFullName)}
{smallify(movement.LocationFullName)}
</Name>
<Time className={classes} isPortable={isPortable}>
{time}
Expand Down

1 comment on commit 60e2314

@JeeZeh
Copy link
Owner Author

@JeeZeh JeeZeh commented on 60e2314 Jun 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contributes to #16

Please sign in to comment.