Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 11 additions & 32 deletions lib/components/narrative/line-itin/realtime-time-column.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
? (
<TimeBlock>
<TimeStruck>{originalFormattedTime}</TimeStruck>
<div>{formattedTime}</div>
</TimeBlock>
)
: <div>{formattedTime}</div>

return (
<div style={{ color: status.color }}>
{renderedTime}
<StyledStatusLabel delay={delaySeconds} tripStatus={status} />
</div>
<StyledStatusLabel
delay={delaySeconds}
isRealtime={isRealtimeTransitLeg}
originalTime={originalFormattedTime}
time={formattedTime} />
)
}

Expand Down
32 changes: 0 additions & 32 deletions lib/components/viewers/base-status-label.js

This file was deleted.

31 changes: 9 additions & 22 deletions lib/components/viewers/pattern-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 (
<div
className='trip-row'
Expand All @@ -103,7 +104,12 @@ export default class PatternRow extends Component {
{getFormattedStopTime(stopTime, homeTimezone, stopViewerArriving, timeFormat)}
</div>
<div className='cell status-column'>
<StatusLabel stopTime={stopTime} />
<RealtimeStatusLabel
className='status-label'
delay={delay}
isRealtime={realtimeState === 'UPDATED'}
withBackground
/>
</div>
</div>
)
Expand Down Expand Up @@ -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 (
<BaseStatusLabel
className='status-label'
delay={delay}
style={{ backgroundColor }}
tripStatus={status}
/>
)
}
95 changes: 95 additions & 0 deletions lib/components/viewers/realtime-status-label.js
Original file line number Diff line number Diff line change
@@ -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;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Almost! I will add a spacer after this element so the rendering is correct in the stop viewer.

image

`

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
? (
<TimeBlock>
<TimeStruck>{originalTime}</TimeStruck>
<div>{time}</div>
</TimeBlock>
)
: <div>{time}</div>
}
return (
<Container
withBackground={withBackground}
className={className}
color={color}
>
{renderedTime}
<MainContent>
{isEarlyOrLate &&
<DelayText>
{formatDuration(Math.abs(delay))}
</DelayText>
}
{STATUS[status].label}
</MainContent>
</Container>
)
}

export default RealtimeStatusLabel
42 changes: 15 additions & 27 deletions lib/util/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}