Skip to content

Commit d763c95

Browse files
committed
Merge branch 'v3' into waltti
2 parents 40ba6bb + b11027b commit d763c95

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+780
-423
lines changed

app/action/PositionActions.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { getJson } from '../util/xhrPromise';
33
import geolocationMessages from '../util/geolocationMessages';
44
import { addAnalyticsEvent } from '../util/analyticsUtils';
55

6+
const MOCKPOS = false;
67
let geoWatchId;
78

89
function reverseGeocodeAddress(actionContext, coords) {
@@ -87,6 +88,20 @@ function dispatchGeolocationError(actionContext, error) {
8788
}
8889
}
8990

91+
function mockPositionChange(actionContext) {
92+
const pos = actionContext.getStore('PositionStore').getLocationState();
93+
if (pos.hasLocation) {
94+
const newPos = {
95+
coords: {
96+
latitude: pos.lat + (Math.random() - 0.5) * 0.001,
97+
longitude: pos.lon + (Math.random() - 0.5) * 0.001,
98+
heading: 0,
99+
},
100+
};
101+
geoCallback(actionContext, newPos);
102+
}
103+
}
104+
90105
// set watcher for geolocation
91106
function watchPosition(actionContext) {
92107
const quietTimeoutSeconds = 20;
@@ -96,6 +111,9 @@ function watchPosition(actionContext) {
96111
updateGeolocationMessage(actionContext, 'timeout');
97112
}, quietTimeoutSeconds * 1000);
98113
try {
114+
if (MOCKPOS) {
115+
setInterval(mockPositionChange, 5000, actionContext);
116+
}
99117
geoWatchId = navigator.geolocation.watchPosition(
100118
position => {
101119
updateGeolocationMessage(actionContext);
@@ -200,10 +218,20 @@ export function startLocationWatch(actionContext) {
200218
watchPosition(actionContext);
201219
break;
202220
}
221+
watchPending = false;
203222
});
204223
}
205224
}
206225

226+
/* stops location watch */
227+
export function stopLocationWatch() {
228+
if (typeof geoWatchId !== 'undefined') {
229+
navigator.geolocation.clearWatch(geoWatchId);
230+
geoWatchId = undefined;
231+
}
232+
watchPending = false;
233+
}
234+
207235
export function showGeolocationDeniedMessage(actionContext) {
208236
actionContext.dispatch('GeolocationDenied');
209237
updateGeolocationMessage(actionContext, 'denied');

app/component/DepartureListContainer.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ class DepartureListContainer extends Component {
8080
infiniteScroll: PropTypes.bool,
8181
className: PropTypes.string,
8282
isTerminal: PropTypes.bool,
83-
isStopPage: PropTypes.bool,
83+
showVehicles: PropTypes.bool,
8484
};
8585

8686
static defaultProps = {
8787
limit: undefined,
8888
infiniteScroll: false,
8989
className: undefined,
9090
isTerminal: false,
91-
isStopPage: false,
91+
showVehicles: false,
9292
mode: 'BUS',
9393
};
9494

@@ -114,27 +114,27 @@ class DepartureListContainer extends Component {
114114
}
115115
}, 100);
116116
}
117-
if (this.context.config.showVehiclesOnStopPage && this.props.isStopPage) {
117+
if (this.context.config.showVehiclesOnStopPage && this.props.showVehicles) {
118118
const departures = asDepartures(this.props.stoptimes)
119119
.filter(departure => !(this.props.isTerminal && departure.isArrival))
120-
.filter(departure => this.props.currentTime < departure.stoptime);
120+
.filter(departure => this.props.currentTime < departure.time);
121121
this.startClient(departures);
122122
}
123123
}
124124

125125
componentDidUpdate() {
126-
if (this.context.config.showVehiclesOnStopPage && this.props.isStopPage) {
126+
if (this.context.config.showVehiclesOnStopPage && this.props.showVehicles) {
127127
const departures = asDepartures(this.props.stoptimes)
128128
.filter(departure => !(this.props.isTerminal && departure.isArrival))
129-
.filter(departure => this.props.currentTime < departure.stoptime)
129+
.filter(departure => this.props.currentTime < departure.time)
130130
.filter(departure => departure.realtime);
131131

132132
this.updateClient(departures);
133133
}
134134
}
135135

136136
componentWillUnmount() {
137-
if (this.context.config.showVehiclesOnStopPage && this.props.isStopPage) {
137+
if (this.context.config.showVehiclesOnStopPage && this.props.showVehicles) {
138138
const { client } = this.context.getStore('RealTimeInformationStore');
139139
if (client) {
140140
this.context.executeAction(stopRealTimeClient, client);

app/component/IndexPage.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,6 @@ class IndexPage extends React.Component {
115115

116116
if (this.context.config.startSearchFromUserLocation && !origin.lat) {
117117
checkPositioningPermission().then(permission => {
118-
if (this.context.match.location?.query?.debug !== undefined) {
119-
alert(permission.state);
120-
}
121118
if (
122119
permission.state === 'granted' &&
123120
this.props.locationState.status === 'no-location'

app/component/itinerary/BicycleLeg.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,12 @@ export default function BicycleLeg(
276276
to={`/${PREFIX_STOPS}/${fromStop.gtfsId}`}
277277
>
278278
{origin}
279+
{leg.isViaPoint && (
280+
<Icon
281+
img="icon-icon_mapMarker-via"
282+
className="itinerary-mapmarker-icon"
283+
/>
284+
)}
279285
<Icon
280286
img="icon-icon_arrow-collapse--right"
281287
className="itinerary-arrow-icon"

app/component/itinerary/BikeParkLeg.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { displayDistance } from '../../util/geo-utils';
88
import { durationToString } from '../../util/timeUtils';
99
import ItineraryCircleLineWithIcon from './ItineraryCircleLineWithIcon';
1010
import ItineraryMapAction from './ItineraryMapAction';
11+
import Icon from '../Icon';
1112

1213
const BikeParkLeg = (
1314
{ leg, index, focusAction, bikePark },
@@ -55,6 +56,12 @@ const BikeParkLeg = (
5556
> */}
5657
<div className="address">
5758
<FormattedMessage id="bike-park" />
59+
{leg.isViaPoint && (
60+
<Icon
61+
img="icon-icon_mapMarker-via"
62+
className="itinerary-mapmarker-icon"
63+
/>
64+
)}
5865
{/* TODO */}
5966
{/* {bikePark && (
6067
<Icon

app/component/itinerary/CarLeg.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ export default function CarLeg(props, { config, intl }) {
6666
<div className="address-container">
6767
<div className="address">
6868
{address}
69+
{props.leg.isViaPoint && (
70+
<Icon
71+
img="icon-icon_mapMarker-via"
72+
className="itinerary-mapmarker-icon"
73+
/>
74+
)}
6975
{props.leg.from.stop && (
7076
<Icon
7177
img="icon-icon_arrow-collapse--right"

app/component/itinerary/CarParkLeg.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ function CarParkLeg(props, { config, intl }) {
7272
>
7373
<div className="address">
7474
<FormattedMessage id="car_park" defaultMessage="Park & Ride" />
75+
{props.leg.isViaPoint && (
76+
<Icon
77+
img="icon-icon_mapMarker-via"
78+
className="itinerary-mapmarker-icon"
79+
/>
80+
)}
7581
{props.carPark && (
7682
<Icon
7783
img="icon-icon_arrow-collapse--right"

app/component/itinerary/IntermediateLeg.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ function IntermediateLeg(
2323
previousZoneId,
2424
currentZoneId,
2525
nextZoneId,
26+
isViaPoint,
2627
isCanceled,
2728
isLastPlace,
2829
},
@@ -151,6 +152,12 @@ function IntermediateLeg(
151152
</span>
152153
{` ${name}`}
153154
</div>
155+
{isViaPoint && (
156+
<Icon
157+
img="icon-icon_mapMarker-via"
158+
className="itinerary-mapmarker-icon"
159+
/>
160+
)}
154161
<Icon
155162
img="icon-icon_arrow-collapse--right"
156163
className="itinerary-arrow-icon"
@@ -176,6 +183,7 @@ IntermediateLeg.propTypes = {
176183
previousZoneId: PropTypes.string,
177184
currentZoneId: PropTypes.string,
178185
nextZoneId: PropTypes.string,
186+
isViaPoint: PropTypes.bool,
179187
isLastPlace: PropTypes.bool,
180188
gtfsId: PropTypes.string,
181189
isCanceled: PropTypes.bool,
@@ -191,6 +199,7 @@ IntermediateLeg.defaultProps = {
191199
isCanceled: false,
192200
realTime: false,
193201
isLastPlace: false,
202+
isViaPoint: false,
194203
gtfsId: undefined,
195204
color: undefined,
196205
};

app/component/itinerary/Itinerary.js

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
getLegBadgeProps,
2222
isCallAgencyLeg,
2323
getInterliningLegs,
24+
isFirstInterliningLeg,
2425
getTotalDistance,
2526
getRouteText,
2627
legTime,
@@ -318,8 +319,8 @@ const Itinerary = (
318319
}
319320
nameLengthSum += 10; // every leg requires some minimum space
320321
if (
321-
leg.intermediatePlace ||
322-
connectsFromViaPoint(leg, intermediatePlaces)
322+
i > 0 &&
323+
(leg.intermediatePlace || connectsFromViaPoint(leg, intermediatePlaces))
323324
) {
324325
intermediateSlack +=
325326
legTime(leg.start) - legTime(compressedLegs[i - 1].end); // calculate time spent at each intermediate place
@@ -361,11 +362,9 @@ const Itinerary = (
361362
let waitLength;
362363
const startMs = legTime(leg.start);
363364
const endMs = legTime(leg.end);
364-
const isNextLegLast = i + 1 === compressedLegs.length - 1;
365-
const shouldRenderLastLeg =
366-
isNextLegLast && lastLegLength < renderBarThreshold;
367-
const previousLeg = compressedLegs[i - 1];
368-
const nextLeg = compressedLegs[i + 1];
365+
const previousLeg = i > 0 ? compressedLegs[i - 1] : null;
366+
const nextLeg =
367+
i < compressedLegs.length - 1 ? compressedLegs[i + 1] : null;
369368
let legLength = relativeLength(endMs - startMs);
370369
const longName = !leg?.route?.shortName || leg?.route?.shortName.length > 5;
371370

@@ -386,24 +385,37 @@ const Itinerary = (
386385
}
387386
}
388387

389-
const [interliningLines, interliningLegs] = getInterliningLegs(
390-
compressedLegs,
391-
i,
392-
);
393-
394-
const lastLegWithInterline = interliningLegs[interliningLegs.length - 1];
395-
if (lastLegWithInterline) {
388+
if (isFirstInterliningLeg(compressedLegs, i)) {
389+
const [interliningLines, interliningLegs] = getInterliningLegs(
390+
compressedLegs,
391+
i,
392+
);
396393
interliningWithRoute = interliningLines.join(' / ');
397-
legLength =
398-
((legTime(lastLegWithInterline.end) - startMs) / durationWithoutSlack) *
399-
100;
394+
const lastLegWithInterline = interliningLegs[interliningLegs.length - 1];
395+
legLength = relativeLength(legTime(lastLegWithInterline.end) - startMs);
396+
if (
397+
compressedLegs.length - 2 === i + interliningLegs.length &&
398+
lastLegLength < renderBarThreshold
399+
) {
400+
// If the last interlining leg is the next to last leg and
401+
// if the last leg is too short add its length to the interlining leg.
402+
legLength += lastLegLength;
403+
}
404+
} else if (leg.interlineWithPreviousLeg) {
405+
// Interlining legs after the first one should be skipped, this skips to the next index.
406+
return;
407+
} else if (
408+
compressedLegs.length - 2 === i &&
409+
lastLegLength < renderBarThreshold
410+
) {
411+
// Interlining legs handle this addition differently.
412+
// If this leg is the next to last leg and
413+
// if the last leg is too short add its length to the leg before it.
414+
legLength += lastLegLength;
400415
}
416+
401417
legLength += addition;
402418
addition = 0;
403-
404-
if (shouldRenderLastLeg) {
405-
legLength += lastLegLength; // if the last leg is too short add its length to the leg before it
406-
}
407419
if (legLength < renderBarThreshold && isLegOnFoot(leg)) {
408420
// don't render short legs that are on foot at all
409421
renderBar = false;
@@ -592,25 +604,23 @@ const Itinerary = (
592604
legLength > renderRouteNumberThreshold &&
593605
!longName &&
594606
transitLegCount < 7;
595-
if (!leg.interlineWithPreviousLeg) {
596-
legs.push(
597-
<RouteLeg
598-
key={`${leg.mode}_${startMs}`}
599-
leg={leg}
600-
fitRouteNumber={
601-
(fitAllRouteNumbers && !longName) || renderRouteNumberForALongLeg
602-
}
603-
interliningWithRoute={interliningWithRoute}
604-
intl={intl}
605-
legLength={legLength}
606-
large={breakpoint === 'large'}
607-
withBicycle={withBicycle}
608-
withCar={withCar}
609-
hasOneTransitLeg={hasOneTransitLeg(itinerary)}
610-
shortenLabels={shortenLabels}
611-
/>,
612-
);
613-
}
607+
legs.push(
608+
<RouteLeg
609+
key={`${leg.mode}_${startMs}`}
610+
leg={leg}
611+
fitRouteNumber={
612+
(fitAllRouteNumbers && !longName) || renderRouteNumberForALongLeg
613+
}
614+
interliningWithRoute={interliningWithRoute}
615+
intl={intl}
616+
legLength={legLength}
617+
large={breakpoint === 'large'}
618+
withBicycle={withBicycle}
619+
withCar={withCar}
620+
hasOneTransitLeg={hasOneTransitLeg(itinerary)}
621+
shortenLabels={shortenLabels}
622+
/>,
623+
);
614624
vehicleNames.push(
615625
formatMessage(
616626
{

app/component/itinerary/ItineraryPageUtils.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -472,15 +472,7 @@ export function mergeBikeTransitPlans(bikeParkPlan, bikeTransitPlan) {
472472
*/
473473
export function mergeCarDirectAndTransitPlans(carDirectPlan, carTransitPlan) {
474474
const carDirectPlanEdges = carDirectPlan?.edges || [];
475-
let carPublicEdges = carTransitPlan?.edges || [];
476-
477-
// If the car direct plan has a shorter duration than a transit plan, the transit plan is filtered out.
478-
if (carDirectPlanEdges.length === 1) {
479-
carPublicEdges = carPublicEdges.filter(
480-
itinerary =>
481-
itinerary.node.duration <= carDirectPlanEdges[0].node.duration,
482-
);
483-
}
475+
const carPublicEdges = carTransitPlan?.edges || [];
484476

485477
return {
486478
searchDateTime: carTransitPlan.searchDateTime,

0 commit comments

Comments
 (0)