diff --git a/lib/components/narrative/line-itin/realtime-time-column.js b/lib/components/narrative/line-itin/realtime-time-column.js index d5a123ce9..1208d1afc 100644 --- a/lib/components/narrative/line-itin/realtime-time-column.js +++ b/lib/components/narrative/line-itin/realtime-time-column.js @@ -8,21 +8,13 @@ import PropTypes from 'prop-types' import React from 'react' import styled from 'styled-components' -import { getTripStatus, TRIP_STATUS } from '../../../util/viewer' -import BaseStatusLabel, { DelayText } from '../../viewers/base-status-label' +import RealtimeStatusLabel, { DelayText, MainContent } from '../../viewers/realtime-status-label' -const TimeStruck = styled.div` - text-decoration: line-through; -` - -const TimeBlock = styled.div` - line-height: 1em; - margin-bottom: 4px; -` - -const StyledStatusLabel = styled(BaseStatusLabel)` - font-size: 80%; - line-height: 1em; +const StyledStatusLabel = styled(RealtimeStatusLabel)` + ${MainContent} { + font-size: 80%; + line-height: 1em; + } ${DelayText} { display: block; } @@ -51,25 +43,12 @@ function RealtimeTimeColumn ({ const originalFormattedTime = originalTimeMillis && formatTime(originalTimeMillis, timeOptions) - const status = getTripStatus(isRealtimeTransitLeg, delaySeconds) - const isEarlyOrLate = status === TRIP_STATUS.EARLY || status === TRIP_STATUS.LATE - - // If the transit vehicle is not on time, strike the original scheduled time - // and display the updated time underneath. - const renderedTime = isEarlyOrLate - ? ( - - {originalFormattedTime} -
{formattedTime}
-
- ) - :
{formattedTime}
- return ( -
- {renderedTime} - -
+ ) } diff --git a/lib/components/viewers/base-status-label.js b/lib/components/viewers/base-status-label.js deleted file mode 100644 index 9028cfe9f..000000000 --- a/lib/components/viewers/base-status-label.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react' -import styled from 'styled-components' - -// If shown, keep the '5 min' portion of the status string on the same line. -export const DelayText = styled.span` - white-space: nowrap; -` - -/** - * A simple label that renders a string such as '5 min late' or 'on time' - * while keeping the '5 min' portion on the same line. - */ -const BaseStatusLabel = ({ className, delay, style, tripStatus }) => { - const { getFormattedDuration, status } = tripStatus - let content - - if (typeof getFormattedDuration === 'function') { - content = ( - <> - {getFormattedDuration(delay)} {status} - - ) - } else { - content = status - } - - return ( -
{content}
- ) -} - -export default BaseStatusLabel diff --git a/lib/components/viewers/pattern-row.js b/lib/components/viewers/pattern-row.js index afb730201..583bd9014 100644 --- a/lib/components/viewers/pattern-row.js +++ b/lib/components/viewers/pattern-row.js @@ -2,8 +2,8 @@ import React, { Component } from 'react' import { VelocityTransitionGroup } from 'velocity-react' import Icon from '../narrative/icon' -import { getFormattedStopTime, getTripStatus } from '../../util/viewer' -import BaseStatusLabel from './base-status-label' +import { getFormattedStopTime } from '../../util/viewer' +import RealtimeStatusLabel from './realtime-status-label' /** * Represents a single pattern row for displaying arrival times in the stop @@ -91,6 +91,7 @@ export default class PatternRow extends Component { {/* list of upcoming trips */} {hasStopTimes && ( sortedStopTimes.map((stopTime, i) => { + const { departureDelay: delay, realtimeState } = stopTime return (
- +
) @@ -206,22 +212,3 @@ export default class PatternRow extends Component { ) } } - -/** - * Renders a colored label denoting a trip realtime status. - */ -const StatusLabel = ({ stopTime }) => { - const { departureDelay: delay, realtimeState } = stopTime - const status = getTripStatus(realtimeState === 'UPDATED', delay) - // Use a default background color if the status object doesn't set a color (e.g. for 'Scheduled' status). - const backgroundColor = status.color || '#bbb' - - return ( - - ) -} diff --git a/lib/components/viewers/realtime-status-label.js b/lib/components/viewers/realtime-status-label.js new file mode 100644 index 000000000..2e5a93462 --- /dev/null +++ b/lib/components/viewers/realtime-status-label.js @@ -0,0 +1,95 @@ +import { formatDuration } from '@opentripplanner/core-utils/lib/time' +import React from 'react' +import styled from 'styled-components' + +import { getTripStatus, REALTIME_STATUS } from '../../util/viewer' + +// If shown, keep the '5 min' portion of the status string on the same line. +export const DelayText = styled.span` + white-space: nowrap; +` + +export const MainContent = styled.div`` + +const Container = styled.div` +${props => props.withBackground + ? `background-color: ${props.color};` + : `color: ${props.color};` +} +` + +const TimeStruck = styled.div` + text-decoration: line-through; +` + +const TimeBlock = styled.div` + line-height: 1em; + margin-bottom: 4px; +` + +const STATUS = { + EARLY: { + color: '#337ab7', + label: 'early' + }, + LATE: { + color: '#d9534f', + label: 'late' + }, + ON_TIME: { + color: '#5cb85c', + label: 'on time' + }, + SCHEDULED: { + label: 'scheduled' + } +} + +/** + * This component renders a string such as '5 min late' or 'on time' + * while keeping the '5 min' portion on the same line. + * + * If the formatted time/original time values (e.g. 5:11 pm) are provided, they + * will be rendered above the status. Also, this can optionally be rendered with + * a background color for a label-like presentation. + */ +const RealtimeStatusLabel = ({ withBackground, className, delay, isRealtime, originalTime, time }) => { + const status = getTripStatus(isRealtime, delay) + const isEarlyOrLate = status === REALTIME_STATUS.EARLY || status === REALTIME_STATUS.LATE + // Use a default background color if the status object doesn't set a color + // (e.g. for 'Scheduled' status), but only in withBackground mode. + const color = STATUS[status].color || (withBackground && '#bbb') + // Render time if provided. + let renderedTime + if (time) { + // If transit vehicle is not on time, strike the original scheduled time + // and display the updated time underneath. + renderedTime = isEarlyOrLate + ? ( + + {originalTime} +
{time}
+
+ ) + :
{time}
+ } + return ( + + {renderedTime} + + {isEarlyOrLate && + + {formatDuration(Math.abs(delay))} + + } + {STATUS[status].label} + + + ) +} + +export default RealtimeStatusLabel diff --git a/lib/util/viewer.js b/lib/util/viewer.js index 0901f623e..bf3c0a4f4 100644 --- a/lib/util/viewer.js +++ b/lib/util/viewer.js @@ -159,45 +159,33 @@ export function getModeFromRoute (route) { } /** - * Preset strings and colors for transit trip realtime status. + * Enum to represent transit realtime status for trips/stop times. */ -export const TRIP_STATUS = { - EARLY: { - color: '#337ab7', - getFormattedDuration: delay => formatDuration(Math.abs(delay)), - status: 'early' - }, - LATE: { - color: '#d9534f', - getFormattedDuration: delay => formatDuration(delay), - status: 'late' - }, - ON_TIME: { - color: '#5cb85c', - status: 'on time' - }, - SCHEDULED: { - status: 'scheduled' - } +export const REALTIME_STATUS = { + EARLY: 'EARLY', + LATE: 'LATE', + ON_TIME: 'ON_TIME', + SCHEDULED: 'SCHEDULED' } /** - * Obtains one of the preset states above (on-time, late...) for the specified realtime status and delay. + * Get one of the realtime states (on-time, late...) if a leg/stoptime is + * registering realtime info and given a delay value in seconds. */ -export function getTripStatus (isRealtime, delay) { +export function getTripStatus (isRealtime, delaySeconds) { if (isRealtime) { - if (delay > 60) { + if (delaySeconds > 60) { // late departure - return TRIP_STATUS.LATE - } else if (delay < -60) { + return REALTIME_STATUS.LATE + } else if (delaySeconds < -60) { // early departure - return TRIP_STATUS.EARLY + return REALTIME_STATUS.EARLY } else { // on-time departure - return TRIP_STATUS.ON_TIME + return REALTIME_STATUS.ON_TIME } } else { // Schedule only - return TRIP_STATUS.SCHEDULED + return REALTIME_STATUS.SCHEDULED } }