+
{renderedTime}
-
+
)
}
-export default RealtimeTimeColumn
-
RealtimeTimeColumn.propTypes = {
isDestination: PropTypes.bool.isRequired,
leg: legType.isRequired,
@@ -84,3 +82,5 @@ RealtimeTimeColumn.propTypes = {
RealtimeTimeColumn.defaultProps = {
timeOptions: null
}
+
+export default RealtimeTimeColumn
diff --git a/lib/components/viewers/base-status-label.js b/lib/components/viewers/base-status-label.js
new file mode 100644
index 000000000..9028cfe9f
--- /dev/null
+++ b/lib/components/viewers/base-status-label.js
@@ -0,0 +1,32 @@
+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 0bb926fd6..afb730201 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 } from '../../util/viewer'
-import StatusLabel from './status-label'
+import { getFormattedStopTime, getTripStatus } from '../../util/viewer'
+import BaseStatusLabel from './base-status-label'
/**
* Represents a single pattern row for displaying arrival times in the stop
@@ -206,3 +206,22 @@ 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/status-label.js b/lib/components/viewers/status-label.js
deleted file mode 100644
index 06e63194d..000000000
--- a/lib/components/viewers/status-label.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react'
-import styled from 'styled-components'
-
-import { getTripStatus } from '../../util/viewer'
-
-/**
- * Renders a colored label denoting a trip realtime status.
- */
-const StatusLabel = ({ stopTime }) => {
- const { departureDelay: delay, realtimeState } = stopTime
- const preset = getTripStatus(realtimeState === 'UPDATED', delay)
-
- return (
-
-
-
- )
-}
-
-// Keep the '5 min' 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.
- */
-export const BaseStatusLabel = ({ delay, preset }) => {
- const { getFormattedDuration, status } = preset
-
- if (getFormattedDuration) {
- return (
- <>
-
{getFormattedDuration(delay)} {status}
- >
- )
- }
-
- return <>{status}>
-}
-
-export default StatusLabel
diff --git a/lib/util/viewer.js b/lib/util/viewer.js
index c6735706e..0901f623e 100644
--- a/lib/util/viewer.js
+++ b/lib/util/viewer.js
@@ -161,7 +161,7 @@ export function getModeFromRoute (route) {
/**
* Preset strings and colors for transit trip realtime status.
*/
-export const STATUS_PRESETS = {
+export const TRIP_STATUS = {
EARLY: {
color: '#337ab7',
getFormattedDuration: delay => formatDuration(Math.abs(delay)),
@@ -177,28 +177,27 @@ export const STATUS_PRESETS = {
status: 'on time'
},
SCHEDULED: {
- color: '#bbb',
status: 'scheduled'
}
}
/**
- * Obtains the preset status above (on-time, late...) for the specified realtime status and delay.
+ * Obtains one of the preset states above (on-time, late...) for the specified realtime status and delay.
*/
export function getTripStatus (isRealtime, delay) {
if (isRealtime) {
if (delay > 60) {
// late departure
- return STATUS_PRESETS.LATE
+ return TRIP_STATUS.LATE
} else if (delay < -60) {
// early departure
- return STATUS_PRESETS.EARLY
+ return TRIP_STATUS.EARLY
} else {
// on-time departure
- return STATUS_PRESETS.ON_TIME
+ return TRIP_STATUS.ON_TIME
}
} else {
// Schedule only
- return STATUS_PRESETS.SCHEDULED
+ return TRIP_STATUS.SCHEDULED
}
}
From 38630f24e44ee43a1f294b6971094f72261519b2 Mon Sep 17 00:00:00 2001
From: Landon Reed
Date: Mon, 4 Jan 2021 16:37:21 -0500
Subject: [PATCH 3/4] refactor(realtime-status-label): encapsulate more of the
status label logic in component
---
.../line-itin/realtime-time-column.js | 43 +++------
lib/components/viewers/base-status-label.js | 32 -------
lib/components/viewers/pattern-row.js | 31 ++----
.../viewers/realtime-status-label.js | 95 +++++++++++++++++++
lib/util/viewer.js | 42 +++-----
5 files changed, 130 insertions(+), 113 deletions(-)
delete mode 100644 lib/components/viewers/base-status-label.js
create mode 100644 lib/components/viewers/realtime-status-label.js
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
}
}
From 508bc80e47cf4716845973fae5d97f2470f4b4e3 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Tue, 5 Jan 2021 07:30:03 -0800
Subject: [PATCH 4/4] fix(RealtimeStatusLabel): Add spacer between delay text
and status text.
---
lib/components/viewers/realtime-status-label.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/components/viewers/realtime-status-label.js b/lib/components/viewers/realtime-status-label.js
index 2e5a93462..5c169bfb5 100644
--- a/lib/components/viewers/realtime-status-label.js
+++ b/lib/components/viewers/realtime-status-label.js
@@ -84,6 +84,8 @@ const RealtimeStatusLabel = ({ withBackground, className, delay, isRealtime, ori
{isEarlyOrLate &&
{formatDuration(Math.abs(delay))}
+ {/* A spacer is needed between '5 min' and 'early/late'. */}
+ {' '}
}
{STATUS[status].label}