Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various navigation bug fixes and improvements #5202

Merged
merged 9 commits into from
Dec 16, 2024
1 change: 1 addition & 0 deletions app/component/itinerary/PlanConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ const planConnection = graphql`
gtfsId
}
scheduledDeparture
serviceDay
}
stoptimes {
stop {
Expand Down
29 changes: 15 additions & 14 deletions app/component/itinerary/navigator/NaviCardContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ function NaviCardContainer(
const cardRef = useRef(null);

const handleRemove = index => {
const msg = messages.get(activeMessages[index].id);
msg.closed = true; // remember closing action
setActiveMessages(activeMessages.filter((_, i) => i !== index));
};

Expand Down Expand Up @@ -94,30 +96,29 @@ function NaviCardContainer(
),
);

if (currentLeg) {
if (nextLeg?.transitLeg) {
// Messages for NaviStack.
addMessages(incomingMessages, [
...getTransitLegState(nextLeg, intl, messages, time),
...getAdditionalMessages(nextLeg, time, intl, config, messages),
]);
}
if (legChanged) {
focusToLeg?.(currentLeg);
setCardExpanded(false);
}
if (nextLeg?.transitLeg) {
// Messages for NaviStack.
addMessages(incomingMessages, [
...getTransitLegState(nextLeg, intl, messages, time),
...getAdditionalMessages(nextLeg, time, intl, config, messages),
]);
}

if (currentLeg && legChanged) {
focusToLeg?.(currentLeg);
setCardExpanded(false);
}
if (incomingMessages.size || legChanged) {
// Handle messages when new messages arrives.

// Current active messages. Filter away expired messages.
const previousValidMessages = legChanged
? activeMessages.filter(m => m.expiresOn < time)
? activeMessages.filter(m => !m.expiresOn || m.expiresOn > time)
: activeMessages;

// handle messages that are updated.
const keptMessages = previousValidMessages.filter(
msg => !!incomingMessages.get(msg.id),
msg => !incomingMessages.get(msg.id),
partisaani marked this conversation as resolved.
Show resolved Hide resolved
);
const newMessages = Array.from(incomingMessages.values());
setActiveMessages([...keptMessages, ...newMessages]);
Expand Down
62 changes: 36 additions & 26 deletions app/component/itinerary/navigator/NaviUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,25 @@ function findTransferProblems(legs, time, position, origin) {
toLeg: next,
});
} else {
const transferDuration = legTime(leg.end) - legTime(leg.start);
const transferDuration = leg.duration * 1000; // this is original duration
// check if user is already at the next departure stop
const atStop =
position && distance(position, leg.to) <= DESTINATION_RADIUS;
const slack = t2 - t1 - transferDuration;
if (!atStop && slack < TRANSFER_SLACK) {
// original transfer not possible
let severity = 'WARNING';
const toGo = getRemainingTraversal(leg, position, origin, time);
const timeLeft = (t2 - time) / 1000;
let toGo;
let timeLeft;
// has transit walk already started ?
if (time > legTime(leg.start)) {
// compute how transit is proceeding
toGo = getRemainingTraversal(leg, position, origin, time);
timeLeft = (t2 - time) / 1000;
} else {
toGo = 1.0;
timeLeft = (t2 - t1) / 1000; // should we consider also transfer slack here?
}
if (toGo > 0 && timeLeft > 0) {
const originalSpeed = leg.distance / leg.duration;
const newSpeed = (toGo * leg.distance) / timeLeft;
Expand Down Expand Up @@ -172,8 +181,8 @@ export function getFirstLastLegs(legs) {
}
export const getAdditionalMessages = (leg, time, intl, config, messages) => {
const msgs = [];
const ticketMsg = messages.get('ticket');
if (!ticketMsg && legTime(leg.start) - time < DISPLAY_MESSAGE_THRESHOLD) {
const closed = messages.get('ticket')?.closed;
if (!closed && legTime(leg.start) - time < DISPLAY_MESSAGE_THRESHOLD) {
// Todo: multiple fares?
const fare = getFaresFromLegs([leg], config)[0];
msgs.push({
Expand All @@ -195,52 +204,56 @@ export const getAdditionalMessages = (leg, time, intl, config, messages) => {
export const getTransitLegState = (leg, intl, messages, time) => {
const { start, realtimeState, from, mode, legId, route } = leg;
const { scheduledTime, estimated } = start;
if (mode === 'WALK') {
return null;

if (messages.get(legId)?.closed) {
return [];
}
const previousMessage = messages.get(legId);
const prevSeverity = previousMessage ? previousMessage.severity : null;

const late =
const notInSchedule =
estimated?.delay > DISPLAY_MESSAGE_THRESHOLD ||
estimated?.delay < -DISPLAY_MESSAGE_THRESHOLD;
const localizedMode = getLocalizedMode(mode, intl);
let content;
let severity;
const isRealTime = realtimeState === 'UPDATED';
const shortName = route.shortName || '';

if (late && prevSeverity !== 'WARNING') {
if (notInSchedule) {
const lMode = getLocalizedMode(mode, intl);
const routeName = `${lMode} ${route.shortName}`;
const routeName = `${lMode} ${shortName}`;
const { delay } = estimated;

const id = `navigation-mode-${delay > 0 ? 'late' : 'early'}`;
const translationId = `navigation-mode-${delay > 0 ? 'late' : 'early'}`;

content = (
<div className="navi-alert-content">
<FormattedMessage id={id} values={{ mode: routeName }} />
<FormattedMessage id={translationId} values={{ mode: routeName }} />
</div>
);
severity = 'WARNING';
} else if (
!isRealTime &&
prevSeverity !== 'WARNING' &&
legTime(start) - time < DISPLAY_MESSAGE_THRESHOLD
) {
} else if (!isRealTime) {
const departure = leg.trip.stoptimesForDate[0];
const departed =
1000 * (departure.serviceDay + departure.scheduledDeparture);
if (time - departed < DISPLAY_MESSAGE_THRESHOLD) {
// vehicle just departed, maybe no realtime yet
return [];
}
severity = 'WARNING';
content = (
<div className="navi-info-content">
<FormattedMessage id="navileg-mode-schedule" />
<FormattedMessage
id="navileg-start-schedule"
values={{
route: shortName,
time: timeStr(scheduledTime),
mode: localizedMode,
}}
/>
</div>
);
} else if (isRealTime && prevSeverity !== 'INFO') {
} else {
const { parentStation, name } = from.stop;
const stopOrStation = parentStation
? intl.formatMessage({ id: 'from-station' })
Expand All @@ -249,12 +262,12 @@ export const getTransitLegState = (leg, intl, messages, time) => {
<div className="navi-info-content">
<FormattedMessage
id="navileg-mode-realtime"
values={{ mode: localizedMode }}
values={{ route: shortName, mode: localizedMode }}
/>
<FormattedMessage
id="navileg-start-realtime"
values={{
time: timeStr(estimated.time),
time: <span className="realtime">{timeStr(estimated.time)}</span>,
stopOrStation,
stopName: name,
}}
Expand All @@ -263,10 +276,7 @@ export const getTransitLegState = (leg, intl, messages, time) => {
);
severity = 'INFO';
}
const state = severity
? [{ severity, content, id: legId, expiresOn: legTime(start) }]
: [];
return state;
return [{ severity, content, id: legId, expiresOn: legTime(start) }];
};

export const getItineraryAlerts = (
Expand Down
12 changes: 6 additions & 6 deletions app/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -1329,14 +1329,14 @@ const translations = {
'navileg-leave-at':
'Jää pois {stopOrStation} {stop} {duration} min päästä klo {legTime}',
'navileg-mode-citybike': 'Kaupunkipyöriä on asemalla {available} kpl',
'navileg-mode-realtime': '{mode} on aikataulussa',
'navileg-mode-realtime': '{mode} {route} on aikataulussa',
'navileg-mode-schedule': 'The {mode} is on schedule',
'navileg-one-stop-remaining': 'TODO_{stopCount} pysähdys ennen poistumista',
'navileg-rent-cycle': 'Pick up citybike',
'navileg-rent-scooter': 'Pick up scooter',
'navileg-scooter': 'Travel by scooter to',
'navileg-start-realtime': 'Lähtee klo {time} {stop} {stopName}',
'navileg-start-schedule': '{mode}n aikataulun muk. lähtö {time}',
'navileg-start-schedule': '{mode}n {route} aikataulun muk. lähtö {time}',
'navileg-stops-remaining': 'TODO_{stopCount} pysähdystä ennen poistumista',
'navileg-walk': 'Walk to',
nearest: '{ mode } near you',
Expand Down Expand Up @@ -2596,14 +2596,14 @@ const translations = {
'navileg-leave-at':
'Jää pois {stopOrStation} {stop} {duration} min päästä klo {legTime}',
'navileg-mode-citybike': 'Kaupunkipyöriä on asemalla {available} kpl',
'navileg-mode-realtime': '{mode} on aikataulussa',
'navileg-mode-realtime': '{mode} {route} on aikataulussa',
'navileg-mode-schedule': 'Reaaliaikaista tietoa ei ole saatavilla',
'navileg-one-stop-remaining': '{stopCount} pysähdys ennen poistumista',
'navileg-rent-cycle': 'Nouda kapunkipyörä',
'navileg-rent-scooter': 'Nouda sähköpotkulauta',
'navileg-scooter': 'Potkulautaile',
'navileg-start-realtime': 'Lähtee klo {time} {stopOrStation} {stopName}',
'navileg-start-schedule': '{mode}n aikataulun muk. lähtö {time}',
'navileg-start-schedule': '{mode}n {route} aikataulun muk. lähtö {time}',
'navileg-stops-remaining': '{stopCount} pysähdystä ennen poistumista',
'navileg-walk': 'Kävele',
nearest: 'Lähimmät {mode}',
Expand Down Expand Up @@ -5514,14 +5514,14 @@ const translations = {
'navileg-leave-at':
'TODO_Jää pois {stopOrStation} {stop} {duration} min päästä klo {legTime}',
'navileg-mode-citybike': 'Kaupunkipyöriä on asemalla {available} kpl',
'navileg-mode-realtime': '{mode} on aikataulussa',
'navileg-mode-realtime': '{mode} {route} on aikataulussa',
'navileg-mode-schedule': 'Reaaliaikaista tietoa ei ole saatavilla',
'navileg-one-stop-remaining': 'TODO_{stopCount} pysähdys ennen poistumista',
'navileg-rent-cycle': 'Hämta stadscykel',
'navileg-rent-scooter': 'Hämta elsparkcykel',
'navileg-scooter': 'Åk elsparkcykel',
'navileg-start-realtime': 'Lähtee klo {time} {stop} {stopName}',
'navileg-start-schedule': '{mode}n aikataulun muk. lähtö {time}',
'navileg-start-schedule': '{mode}n {route} aikataulun muk. lähtö {time}',
'navileg-stops-remaining': 'TODO_{stopCount} pysähdystä ennen poistumista',
'navileg-walk': 'Gå till',
nearest: 'Närmaste { mode }',
Expand Down
Loading