Skip to content

Commit

Permalink
feat: handle geo orientation crash firefox & safari (#1381)
Browse files Browse the repository at this point in the history
* fix projectListMap: remove geolocation from homePage map

* refactor projectListMap: remove old vectorLayer code

* feat projectDetails: geolocationStatus add

* fix geoLocation: add & remove geoLocation layer conditionally

* fix mapControlComponent: change geolocation point to red if status on

* fix projectDetails: set generateMbtiles btn to bottom for mobile screen

* fix geolocation: zoom to current location on geolocation on

* fix geolocation: show error if browser is firefox or safari & show only blue dot for them
  • Loading branch information
NSUWAL123 authored Mar 22, 2024
1 parent aec9fb3 commit 4125867
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 38 deletions.
Binary file added src/frontend/src/assets/images/LocationDot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
99 changes: 62 additions & 37 deletions src/frontend/src/utilfunctions/Geolocation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pngbluedot from '@/assets/images/png bluedot.png';
import LocationDot from '@/assets/images/LocationDot.png';
import { Fill } from 'ol/style';
import VectorSource from 'ol/source/Vector';
import OLVectorLayer from 'ol/layer/Vector';
Expand All @@ -9,21 +10,34 @@ import { circular } from 'ol/geom/Polygon';
import { Style } from 'ol/style';
import { Icon } from 'ol/style';
import VectorLayer from 'ol/layer/Vector';
import { CommonActions } from '@/store/slices/CommonSlice';

const locationIconStyle = new Style({
fill: new Fill({
color: 'rgba(0, 0, 255, 0.2)',
}),
image: new Icon({
src: pngbluedot,
scale: 0.09,
imgSize: [27, 55],
rotateWithView: true,
}),
});

export const Geolocation = (map, geolocationStatus) => {
export const Geolocation = (map, geolocationStatus, dispatch) => {
if (!map) return;

// check firefox or safari browser as it doesnt support browser's Sensor API
// @ts-ignore
const isFirefox = typeof InstallTrigger !== 'undefined';
const isSafari =
// @ts-ignore
/constructor/i.test(window.HTMLElement) ||
(function (p) {
return p.toString() === '[object SafariRemoteNotification]';
// @ts-ignore
})(!window['safari'] || (typeof safari !== 'undefined' && window['safari'].pushNotification));

const locationIconStyle = new Style({
fill: new Fill({
color: 'rgba(0, 0, 255, 0.2)',
}),
image: new Icon({
src: isFirefox || isSafari ? LocationDot : pngbluedot,
scale: 0.09,
imgSize: [27, 55],
rotateWithView: true,
}),
});

const source = new VectorSource();
const layer = new OLVectorLayer({
source: source,
Expand Down Expand Up @@ -124,30 +138,41 @@ export const Geolocation = (map, geolocationStatus) => {
locationIconStyle.getImage().setRotation((Math.PI / 180) * heading);
}

// See the API specification at: https://w3c.github.io/orientation-sensor
// We use referenceFrame: 'screen' because the web page will rotate when
// the phone switches from portrait to landscape.
const sensor = new AbsoluteOrientationSensor({
frequency: 60,
referenceFrame: 'screen',
});
sensor.addEventListener('reading', (event) => {
layer.on('postrender', handleReading(sensor.quaternion));
});
// handleReading([0.509, -0.071, -0.19, 0.836]);

Promise.all([
navigator.permissions.query({ name: 'accelerometer' }),
navigator.permissions.query({ name: 'magnetometer' }),
navigator.permissions.query({ name: 'gyroscope' }),
]).then((results) => {
if (results.every((result) => result.state === 'granted')) {
sensor.start();
// stat.value = "Sensor started!";
} else {
// stat.value = "No permissions to use AbsoluteOrientationSensor.";
}
});
if (isFirefox || isSafari) {
dispatch(
CommonActions.SetSnackBar({
open: true,
message: "Unable to handle device orientation. Your browser doesn't support device orientation sensors.",
variant: 'error',
duration: 4000,
}),
);
} else {
// See the API specification at: https://w3c.github.io/orientation-sensor
// We use referenceFrame: 'screen' because the web page will rotate when
// the phone switches from portrait to landscape.
const sensor = new AbsoluteOrientationSensor({
frequency: 60,
referenceFrame: 'screen',
});
sensor.addEventListener('reading', (event) => {
layer.on('postrender', handleReading(sensor.quaternion));
});
// handleReading([0.509, -0.071, -0.19, 0.836]);

Promise.all([
navigator.permissions.query({ name: 'accelerometer' }),
navigator.permissions.query({ name: 'magnetometer' }),
navigator.permissions.query({ name: 'gyroscope' }),
]).then((results) => {
if (results.every((result) => result.state === 'granted')) {
sensor.start();
// stat.value = "Sensor started!";
} else {
// stat.value = "No permissions to use AbsoluteOrientationSensor.";
}
});
}
}

// remove the geolocation layer if geolocationStatus turned off
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/views/ProjectDetailsV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ const Home = () => {

useEffect(() => {
if (!map) return;
Geolocation(map, geolocationStatus);
Geolocation(map, geolocationStatus, dispatch);
}, [geolocationStatus]);

const { y } = OnScroll(map, windowSize.width);
Expand Down

0 comments on commit 4125867

Please sign in to comment.