Skip to content

Commit 6256a2a

Browse files
authored
Merge pull request #82 from opentripplanner/dev
New release
2 parents 21f2e52 + 69aa4f0 commit 6256a2a

File tree

5 files changed

+72
-29
lines changed

5 files changed

+72
-29
lines changed

Diff for: example.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// import necessary React/Redux libraries
2+
import { createHashHistory } from 'history'
3+
import { connectRouter, routerMiddleware } from 'connected-react-router'
24
import React, { Component } from 'react'
35
import { render } from 'react-dom'
4-
import { createStore, combineReducers, applyMiddleware } from 'redux'
6+
import { createStore, combineReducers, applyMiddleware, compose } from 'redux'
57
import { Provider } from 'react-redux'
68
import thunk from 'redux-thunk'
79
import createLogger from 'redux-logger'
@@ -38,19 +40,29 @@ const initialQuery = {
3840
type: 'ITINERARY'
3941
}
4042

43+
const history = createHashHistory()
44+
const middleware = [
45+
thunk,
46+
routerMiddleware(history) // for dispatching history actions
47+
]
48+
49+
// check if app is being run in development mode. If so, enable redux-logger
50+
if (process.env.NODE_ENV === 'development') {
51+
middleware.push(createLogger())
52+
}
53+
4154
// set up the Redux store
4255
const store = createStore(
4356
combineReducers({
44-
otp: createOtpReducer(otpConfig) // add optional initial query here
45-
// add your own reducers if you want
57+
otp: createOtpReducer(otpConfig),
58+
router: connectRouter(history)
4659
}),
47-
applyMiddleware(thunk, createLogger())
60+
compose(applyMiddleware(...middleware))
4861
)
4962

5063
// define a simple responsive UI using Bootstrap and OTP-RR
5164
class OtpRRExample extends Component {
5265
render () {
53-
5466
/** desktop view **/
5567
const desktopView = (
5668
<div className='otp'>

Diff for: lib/actions/ui.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,15 @@ export function matchContentToUrl (location) {
6565
dispatch(setMainPanelContent(MainPanelContent.STOP_VIEWER))
6666
}
6767
break
68+
case 'start':
6869
case '@':
6970
// Parse comma separated params (ensuring numbers are parsed correctly).
70-
const [lat, lon, zoom, routerId] = id.split(',').map(s => isNaN(s) ? s : +s)
71+
let [lat, lon, zoom, routerId] = id ? idToParams(id) : []
72+
if (!lat || !lon) {
73+
// Attempt to parse path. (Legacy UI otp.js used slashes in the
74+
// pathname to specify lat, lon, etc.)
75+
[,, lat, lon, zoom, routerId] = idToParams(location.pathname, '/')
76+
}
7177
// Update map location/zoom and optionally override router ID.
7278
dispatch(setMapCenter({ lat, lon }))
7379
dispatch(setMapZoom({ zoom }))
@@ -82,6 +88,10 @@ export function matchContentToUrl (location) {
8288
}
8389
}
8490

91+
function idToParams (id, delimiter = ',') {
92+
return id.split(delimiter).map(s => isNaN(s) ? s : +s)
93+
}
94+
8595
/**
8696
* Event listener for responsive webapp that handles a back button press and
8797
* sets the active search and itinerary according to the URL query params.

Diff for: lib/components/app/responsive-webapp.js

+5
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class RouterWrapper extends Component {
181181
// to a quirk with react-router.
182182
// https://github.com/ReactTraining/react-router/issues/5870#issuecomment-394194338
183183
'/@/:latLonZoomRouter',
184+
'/start/:latLonZoomRouter',
184185
// Route viewer (and route ID).
185186
'/route',
186187
'/route/:id',
@@ -194,6 +195,10 @@ class RouterWrapper extends Component {
194195
path='/print'
195196
component={PrintLayout}
196197
/>
198+
{/* For any other route, simply return the web app. */}
199+
<Route
200+
render={() => <WebappWithRouter {...this.props} />}
201+
/>
197202
</Switch>
198203
</div>
199204
</ConnectedRouter>

Diff for: lib/components/narrative/line-itin/place-row.js

+37-21
Original file line numberDiff line numberDiff line change
@@ -156,42 +156,58 @@ class RentedVehicleLeg extends PureComponent {
156156
render () {
157157
const { config, leg } = this.props
158158
const configCompanies = config.companies || []
159+
160+
// Sometimes rented vehicles can be walked over things like stairs or other
161+
// ways that forbid the main mode of travel.
159162
if (leg.mode === 'WALK') {
160163
return (
161164
<div className='place-subheader'>
162165
Walk vehicle along {leg.from.name}
163166
</div>
164167
)
165168
}
166-
if (leg.rentedVehicle || leg.rentedBike || leg.rentedCar) {
167-
let pickUpString = 'Pick up'
168-
if (leg.rentedBike) {
169-
// TODO: Special case for TriMet may need to be refactored.
170-
pickUpString += ` shared bike`
171-
} else {
172-
// Add company and vehicle labels.
169+
170+
let rentalDescription = 'Pick up'
171+
if (leg.rentedBike) {
172+
// TODO: Special case for TriMet may need to be refactored.
173+
rentalDescription += ` shared bike`
174+
} else {
175+
// Add company and vehicle labels.
176+
let vehicleName = ''
177+
// TODO allow more flexibility in customizing these mode strings
178+
let modeString = leg.rentedVehicle
179+
? 'eScooter'
180+
: leg.rentedBike
181+
? 'bike'
182+
: 'car'
183+
184+
// The networks attribute of the from data will only appear at the very
185+
// beginning of the rental. It is possible that there will be some forced
186+
// walking that occurs in the middle of the rental, so once the main mode
187+
// resumes there won't be any network info. In that case we simply return
188+
// that the rental is continuing.
189+
if (leg.from.networks) {
173190
const companies = leg.from.networks.map(n => getCompanyForNetwork(n, configCompanies))
174191
const companyLabel = companies.map(co => co.label).join('/')
175-
pickUpString += ` ${companyLabel}`
176-
const modeString = getModeForPlace(leg.from)
192+
rentalDescription += ` ${companyLabel}`
177193
// Only show vehicle name for car rentals. For bikes and eScooters, these
178194
// IDs/names tend to be less relevant (or entirely useless) in this context.
179-
const vehicleName = leg.rentedCar ? ` ${leg.from.name}` : ''
180-
pickUpString += ` ${modeString}${vehicleName}`
195+
if (leg.rentedCar && leg.from.name) {
196+
vehicleName = leg.from.name
197+
}
198+
modeString = getModeForPlace(leg.from)
199+
} else {
200+
rentalDescription = 'Continue using rental'
181201
}
182-
// e.g., Pick up REACHNOW rented car XYZNDB OR
183-
// Pick up SPIN eScooter
184-
// Pick up shared bike
185-
return (
186-
<div className='place-subheader'>
187-
{pickUpString}
188-
</div>
189-
)
202+
203+
rentalDescription += ` ${modeString}${vehicleName}`
190204
}
191-
// FIXME: Under what conditions would this be returned?
205+
// e.g., Pick up REACHNOW rented car XYZNDB OR
206+
// Pick up SPIN eScooter
207+
// Pick up shared bike
192208
return (
193209
<div className='place-subheader'>
194-
Continue riding from {leg.from.name}
210+
{rentalDescription}
195211
</div>
196212
)
197213
}

Diff for: lib/util/itinerary.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -393,9 +393,9 @@ export function getLegIcon (leg, customIcons) {
393393
iconStr = leg.from.networks[0]
394394
} else if (iconStr === 'CAR' && leg.tncData) {
395395
iconStr = leg.tncData.company
396-
} else if (iconStr === 'BICYCLE' && leg.rentedBike) {
396+
} else if (iconStr === 'BICYCLE' && leg.rentedBike && leg.from.networks) {
397397
iconStr = leg.from.networks[0]
398-
} else if (iconStr === 'MICROMOBILITY' && leg.rentedVehicle) {
398+
} else if (iconStr === 'MICROMOBILITY' && leg.rentedVehicle && leg.from.networks) {
399399
iconStr = leg.from.networks[0]
400400
}
401401

0 commit comments

Comments
 (0)