Skip to content

Commit

Permalink
Merge branch 'v3' into navifixes5
Browse files Browse the repository at this point in the history
  • Loading branch information
vesameskanen committed Jan 7, 2025
2 parents 64f6b59 + 0e1d7e6 commit 40e1056
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 269 deletions.
104 changes: 0 additions & 104 deletions app/action/MockGeolocationApi.js

This file was deleted.

116 changes: 39 additions & 77 deletions app/action/PositionActions.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import debounce from 'lodash/debounce';
import d from 'debug';
import { getJson } from '../util/xhrPromise';
import geolocationMessages from '../util/geolocationMessages';
import { addAnalyticsEvent } from '../util/analyticsUtils';

const debug = d('PositionActions.js');

let geoWatchId;

function reverseGeocodeAddress(actionContext, location) {
function reverseGeocodeAddress(actionContext, coords) {
const language = actionContext.getStore('PreferencesStore').getLanguage();

const searchParams = {
'point.lat': location.lat,
'point.lon': location.lon,
'point.lat': coords.latitude,
'point.lon': coords.longitude,
lang: language,
size: 1,
layers: 'address',
Expand All @@ -23,6 +20,7 @@ function reverseGeocodeAddress(actionContext, location) {
searchParams['boundary.country'] =
actionContext.config.searchParams['boundary.country'];
}
actionContext.dispatch('StartReverseGeocoding');

return getJson(
actionContext.config.URL.PELIAS_REVERSE_GEOCODER,
Expand All @@ -43,41 +41,17 @@ function reverseGeocodeAddress(actionContext, location) {
});
}

const runReverseGeocodingAction = (actionContext, lat, lon) =>
actionContext.executeAction(reverseGeocodeAddress, {
lat,
lon,
});

const debouncedRunReverseGeocodingAction = debounce(
runReverseGeocodingAction,
10000,
{
leading: true,
},
);
const debouncedReverseGeocoding = debounce(reverseGeocodeAddress, 10000, {
leading: true,
});

function geoCallback(actionContext, { pos, disableDebounce }) {
actionContext.dispatch('StartReverseGeocoding');
function geoCallback(actionContext, pos) {
actionContext.dispatch('GeolocationFound', {
lat: pos.coords.latitude,
lon: pos.coords.longitude,
heading: pos.coords.heading,
disableFiltering: disableDebounce,
});
if (disableDebounce) {
runReverseGeocodingAction(
actionContext,
pos.coords.latitude,
pos.coords.longitude,
);
} else {
debouncedRunReverseGeocodingAction(
actionContext,
pos.coords.latitude,
pos.coords.longitude,
);
}
debouncedReverseGeocoding(actionContext, pos.coords);
}

function updateGeolocationMessage(actionContext, newId) {
Expand Down Expand Up @@ -115,16 +89,15 @@ function dispatchGeolocationError(actionContext, error) {

// set watcher for geolocation
function watchPosition(actionContext) {
debug('watchPosition');
const quietTimeoutSeconds = 20;

let timeout = setTimeout(() => {
actionContext.dispatch('GeolocationWatchTimeout');
updateGeolocationMessage(actionContext, 'timeout');
}, quietTimeoutSeconds * 1000);
try {
geoWatchId = navigator.geoapi.watchPosition(
(position, disableDebounce) => {
geoWatchId = navigator.geolocation.watchPosition(
position => {
updateGeolocationMessage(actionContext);
if (timeout !== null) {
clearTimeout(timeout);
Expand All @@ -138,7 +111,7 @@ function watchPosition(actionContext) {
lon !== undefined &&
!Number.isNaN(lon)
) {
geoCallback(actionContext, { pos: position, disableDebounce });
geoCallback(actionContext, position);
}
},
error => {
Expand All @@ -152,6 +125,7 @@ function watchPosition(actionContext) {
},
{ enableHighAccuracy: true, timeout: 60000, maximumAge: 60000 },
);
actionContext.dispatch('storeWatchId', geoWatchId);
} catch (error) {
if (timeout !== null) {
clearTimeout(timeout);
Expand All @@ -168,15 +142,9 @@ function watchPosition(actionContext) {
/**
* Small wrapper around permission api.
* Returns a promise of checking positioning permission.
* resolving to null means there's no permission api.
*/
export function checkPositioningPermission() {
const p = new Promise(resolve => {
if (typeof window !== 'undefined' && window.mock !== undefined) {
debug('mock permission');
resolve({ state: window.mock.permission });
return;
}
if (!navigator.permissions) {
resolve({ state: 'error' });
} else {
Expand All @@ -201,44 +169,38 @@ export function checkPositioningPermission() {
});
}
});

return p;
}

function startPositioning(actionContext) {
checkPositioningPermission().then(status => {
debug('Examining permission', status);
switch (status.state) {
case 'granted':
actionContext.dispatch('GeolocationSearch');
updateGeolocationMessage(actionContext);
watchPosition(actionContext);
break;
case 'denied':
actionContext.dispatch('GeolocationDenied');
updateGeolocationMessage(actionContext, 'denied');
break;
case 'prompt':
updateGeolocationMessage(actionContext, 'prompt');
actionContext.dispatch('GeolocationSearch');
watchPosition(actionContext);
break;
default:
// browsers not supporting permission api
actionContext.dispatch('GeolocationSearch');
watchPosition(actionContext);
break;
}
});
}
let watchPending;

/* starts location watch */
export function startLocationWatch(actionContext) {
if (typeof geoWatchId === 'undefined') {
debug('starting...');
startPositioning(actionContext); // from geolocation.js
} else {
debug('already started...');
if (typeof geoWatchId === 'undefined' && !watchPending) {
watchPending = true;
checkPositioningPermission().then(status => {
switch (status.state) {
case 'granted':
actionContext.dispatch('GeolocationSearch');
updateGeolocationMessage(actionContext);
watchPosition(actionContext);
break;
case 'denied':
actionContext.dispatch('GeolocationDenied');
updateGeolocationMessage(actionContext, 'denied');
break;
case 'prompt':
updateGeolocationMessage(actionContext, 'prompt');
actionContext.dispatch('GeolocationSearch');
watchPosition(actionContext);
break;
default:
// browsers not supporting permission api
actionContext.dispatch('GeolocationSearch');
watchPosition(actionContext);
break;
}
});
}
}

Expand Down
2 changes: 1 addition & 1 deletion app/component/IndexPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class IndexPage extends React.Component {
this.context.executeAction(storeDestination, destination);
}

if (this.context.config.startSearchFromUserLocation) {
if (this.context.config.startSearchFromUserLocation && !origin.lat) {
checkPositioningPermission().then(permission => {
if (
permission.state === 'granted' &&
Expand Down
63 changes: 38 additions & 25 deletions app/component/itinerary/navigator/NaviBottom.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import cx from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import React, { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import { configShape } from '../../../util/shapes';
import { epochToTime } from '../../../util/timeUtils';
Expand All @@ -8,34 +9,46 @@ export default function NaviBottom(
{ setNavigation, arrival, time },
{ config },
) {
const handleClose = useCallback(() => setNavigation(false), [setNavigation]);
const handleTicketButtonClick = useCallback(e => e.stopPropagation(), []);

const isTicketSaleActive = !!config?.ticketLink;
const remainingDuration = Math.ceil((arrival - time) / 60000); // ms to minutes

const sheetClasses = cx('navi-bottom-sheet', {
'ticket-link': isTicketSaleActive,
});

const closeButton = (
<button type="button" onClick={handleClose} className="navi-close-button">
<FormattedMessage id="navigation-quit" />
</button>
);

const durationDiv = remainingDuration >= 0 && (
<div className="navi-time">
<span>
<FormattedMessage
id="travel-time"
values={{ min: remainingDuration }}
/>
</span>
<span className="navi-daytime">{epochToTime(arrival, config)}</span>
</div>
);

const [FirstElement, SecondElement] = isTicketSaleActive
? [closeButton, durationDiv]
: [durationDiv, closeButton];

return (
<div className="navi-bottom-controls">
<button
type="button"
onClick={() => setNavigation(false)}
className="navi-close-button"
>
<FormattedMessage id="navigation-quit" />
</button>

{remainingDuration >= 0 && (
<div className="navi-time">
<span>
<FormattedMessage
id="travel-time"
values={{ min: remainingDuration }}
/>
</span>
<span className="navi-daytime">{epochToTime(arrival, config)}</span>
</div>
)}
{config.ticketLink && (
<div className={sheetClasses}>
{FirstElement}
{SecondElement}
{isTicketSaleActive && (
<button type="button" className="navi-ticket-button">
<a
onClick={e => {
e.stopPropagation();
}}
onClick={handleTicketButtonClick}
href={config.ticketLink}
target="_blank"
rel="noopener noreferrer"
Expand Down
Loading

0 comments on commit 40e1056

Please sign in to comment.