Skip to content

Commit

Permalink
Merge pull request #82 from opentripplanner/dev
Browse files Browse the repository at this point in the history
New release
  • Loading branch information
landonreed authored Jul 18, 2019
2 parents 21f2e52 + 69aa4f0 commit 6256a2a
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 29 deletions.
22 changes: 17 additions & 5 deletions example.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// import necessary React/Redux libraries
import { createHashHistory } from 'history'
import { connectRouter, routerMiddleware } from 'connected-react-router'
import React, { Component } from 'react'
import { render } from 'react-dom'
import { createStore, combineReducers, applyMiddleware } from 'redux'
import { createStore, combineReducers, applyMiddleware, compose } from 'redux'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
Expand Down Expand Up @@ -38,19 +40,29 @@ const initialQuery = {
type: 'ITINERARY'
}

const history = createHashHistory()
const middleware = [
thunk,
routerMiddleware(history) // for dispatching history actions
]

// check if app is being run in development mode. If so, enable redux-logger
if (process.env.NODE_ENV === 'development') {
middleware.push(createLogger())
}

// set up the Redux store
const store = createStore(
combineReducers({
otp: createOtpReducer(otpConfig) // add optional initial query here
// add your own reducers if you want
otp: createOtpReducer(otpConfig),
router: connectRouter(history)
}),
applyMiddleware(thunk, createLogger())
compose(applyMiddleware(...middleware))
)

// define a simple responsive UI using Bootstrap and OTP-RR
class OtpRRExample extends Component {
render () {

/** desktop view **/
const desktopView = (
<div className='otp'>
Expand Down
12 changes: 11 additions & 1 deletion lib/actions/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,15 @@ export function matchContentToUrl (location) {
dispatch(setMainPanelContent(MainPanelContent.STOP_VIEWER))
}
break
case 'start':
case '@':
// Parse comma separated params (ensuring numbers are parsed correctly).
const [lat, lon, zoom, routerId] = id.split(',').map(s => isNaN(s) ? s : +s)
let [lat, lon, zoom, routerId] = id ? idToParams(id) : []
if (!lat || !lon) {
// Attempt to parse path. (Legacy UI otp.js used slashes in the
// pathname to specify lat, lon, etc.)
[,, lat, lon, zoom, routerId] = idToParams(location.pathname, '/')
}
// Update map location/zoom and optionally override router ID.
dispatch(setMapCenter({ lat, lon }))
dispatch(setMapZoom({ zoom }))
Expand All @@ -82,6 +88,10 @@ export function matchContentToUrl (location) {
}
}

function idToParams (id, delimiter = ',') {
return id.split(delimiter).map(s => isNaN(s) ? s : +s)
}

/**
* Event listener for responsive webapp that handles a back button press and
* sets the active search and itinerary according to the URL query params.
Expand Down
5 changes: 5 additions & 0 deletions lib/components/app/responsive-webapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class RouterWrapper extends Component {
// to a quirk with react-router.
// https://github.com/ReactTraining/react-router/issues/5870#issuecomment-394194338
'/@/:latLonZoomRouter',
'/start/:latLonZoomRouter',
// Route viewer (and route ID).
'/route',
'/route/:id',
Expand All @@ -194,6 +195,10 @@ class RouterWrapper extends Component {
path='/print'
component={PrintLayout}
/>
{/* For any other route, simply return the web app. */}
<Route
render={() => <WebappWithRouter {...this.props} />}
/>
</Switch>
</div>
</ConnectedRouter>
Expand Down
58 changes: 37 additions & 21 deletions lib/components/narrative/line-itin/place-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,42 +156,58 @@ class RentedVehicleLeg extends PureComponent {
render () {
const { config, leg } = this.props
const configCompanies = config.companies || []

// Sometimes rented vehicles can be walked over things like stairs or other
// ways that forbid the main mode of travel.
if (leg.mode === 'WALK') {
return (
<div className='place-subheader'>
Walk vehicle along {leg.from.name}
</div>
)
}
if (leg.rentedVehicle || leg.rentedBike || leg.rentedCar) {
let pickUpString = 'Pick up'
if (leg.rentedBike) {
// TODO: Special case for TriMet may need to be refactored.
pickUpString += ` shared bike`
} else {
// Add company and vehicle labels.

let rentalDescription = 'Pick up'
if (leg.rentedBike) {
// TODO: Special case for TriMet may need to be refactored.
rentalDescription += ` shared bike`
} else {
// Add company and vehicle labels.
let vehicleName = ''
// TODO allow more flexibility in customizing these mode strings
let modeString = leg.rentedVehicle
? 'eScooter'
: leg.rentedBike
? 'bike'
: 'car'

// The networks attribute of the from data will only appear at the very
// beginning of the rental. It is possible that there will be some forced
// walking that occurs in the middle of the rental, so once the main mode
// resumes there won't be any network info. In that case we simply return
// that the rental is continuing.
if (leg.from.networks) {
const companies = leg.from.networks.map(n => getCompanyForNetwork(n, configCompanies))
const companyLabel = companies.map(co => co.label).join('/')
pickUpString += ` ${companyLabel}`
const modeString = getModeForPlace(leg.from)
rentalDescription += ` ${companyLabel}`
// Only show vehicle name for car rentals. For bikes and eScooters, these
// IDs/names tend to be less relevant (or entirely useless) in this context.
const vehicleName = leg.rentedCar ? ` ${leg.from.name}` : ''
pickUpString += ` ${modeString}${vehicleName}`
if (leg.rentedCar && leg.from.name) {
vehicleName = leg.from.name
}
modeString = getModeForPlace(leg.from)
} else {
rentalDescription = 'Continue using rental'
}
// e.g., Pick up REACHNOW rented car XYZNDB OR
// Pick up SPIN eScooter
// Pick up shared bike
return (
<div className='place-subheader'>
{pickUpString}
</div>
)

rentalDescription += ` ${modeString}${vehicleName}`
}
// FIXME: Under what conditions would this be returned?
// e.g., Pick up REACHNOW rented car XYZNDB OR
// Pick up SPIN eScooter
// Pick up shared bike
return (
<div className='place-subheader'>
Continue riding from {leg.from.name}
{rentalDescription}
</div>
)
}
Expand Down
4 changes: 2 additions & 2 deletions lib/util/itinerary.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,9 @@ export function getLegIcon (leg, customIcons) {
iconStr = leg.from.networks[0]
} else if (iconStr === 'CAR' && leg.tncData) {
iconStr = leg.tncData.company
} else if (iconStr === 'BICYCLE' && leg.rentedBike) {
} else if (iconStr === 'BICYCLE' && leg.rentedBike && leg.from.networks) {
iconStr = leg.from.networks[0]
} else if (iconStr === 'MICROMOBILITY' && leg.rentedVehicle) {
} else if (iconStr === 'MICROMOBILITY' && leg.rentedVehicle && leg.from.networks) {
iconStr = leg.from.networks[0]
}

Expand Down

0 comments on commit 6256a2a

Please sign in to comment.