1 | import { Platform } from '@unimodules/core';
|
2 | export function getRequestPermission() {
|
3 | if (typeof DeviceMotionEvent !== 'undefined' && !!DeviceMotionEvent?.requestPermission) {
|
4 | return DeviceMotionEvent.requestPermission;
|
5 | }
|
6 | else if (typeof DeviceOrientationEvent !== 'undefined' &&
|
7 | !!DeviceOrientationEvent?.requestPermission) {
|
8 | return DeviceOrientationEvent.requestPermission;
|
9 | }
|
10 | return null;
|
11 | }
|
12 | class PermissionError extends Error {
|
13 | constructor(eventName) {
|
14 | let errorMessage = `Cannot observe event: ${eventName}. How to fix:`;
|
15 | errorMessage += `\n- Ensure you've requested the \`MOTION\` permission via expo-permissions (this must be done in a touch event).`;
|
16 | if (location.protocol !== 'https:') {
|
17 | errorMessage +=
|
18 | '\n- Ensure that you are hosting with `https` as DeviceMotion and DeviceOrientation are now secure APIs.';
|
19 | }
|
20 |
|
21 | if (isIOS() && !getRequestPermission()) {
|
22 | errorMessage +=
|
23 | '\n- On iOS 12.2, you must manually enable device orientation in `Settings > Safari > Motion & Orientation Access`.';
|
24 | }
|
25 | super(errorMessage);
|
26 | }
|
27 | }
|
28 |
|
29 |
|
30 | export async function assertSensorEventEnabledAsync(eventName, timeout) {
|
31 | if (!Platform.isDOMAvailable) {
|
32 | return false;
|
33 | }
|
34 | if (getRequestPermission()) {
|
35 | if (await isSensorEnabledAsync(eventName, timeout)) {
|
36 | return true;
|
37 | }
|
38 | throw new PermissionError(eventName);
|
39 | }
|
40 | return true;
|
41 | }
|
42 |
|
43 | export async function isSensorEnabledAsync(eventName,
|
44 | // Initial interval tests found results on a median of
|
45 | // devicemotion:
|
46 | // - iPhone 7 Plus: 166.6666753590107ms
|
47 | // - iPhone X: 166.6666753590107ms
|
48 | // deviceorientation:
|
49 | // -
|
50 | //
|
51 | // The initial launch of iOS Safari onto a page calling this API seems to take a little longer than a regular call.
|
52 | // devicemotion:
|
53 | // - ~35ms
|
54 | // deviceorientation:
|
55 | // - ~45ms
|
56 | //
|
57 | timeout = 250) {
|
58 | if (!Platform.isDOMAvailable) {
|
59 | return false;
|
60 | }
|
61 |
|
62 |
|
63 | if (!isIOS && !getRequestPermission()) {
|
64 | return true;
|
65 | }
|
66 | return new Promise(resolve => {
|
67 | const id = setTimeout(() => {
|
68 | window.removeEventListener(eventName, listener);
|
69 | resolve(false);
|
70 | }, timeout);
|
71 | const listener = () => {
|
72 | clearTimeout(id);
|
73 | window.removeEventListener(eventName, listener);
|
74 | resolve(true);
|
75 | };
|
76 | window.addEventListener(eventName, listener);
|
77 | });
|
78 | }
|
79 |
|
80 | function isIOS() {
|
81 | const isIOSUA = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
|
82 | const isIE11 = !!window['MSStream'];
|
83 | return isIOSUA && !isIE11;
|
84 | }
|
85 |
|
\ | No newline at end of file |