Skip to content

Commit cc7ca17

Browse files
committed
Fix isAvailable Camera bug for web app on iOS devices
1 parent 7cb92ce commit cc7ca17

File tree

3 files changed

+42
-12
lines changed

3 files changed

+42
-12
lines changed

packages/react-native/src/components/Camera/index.jsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useCallback, useMemo, useState } from 'react';
22
import PropTypes from 'prop-types';
33
import noop from 'lodash.noop';
44

5-
import { StyleSheet } from 'react-native';
5+
import { View, Platform, StyleSheet } from 'react-native';
66
import { Camera as ExpoCamera } from 'expo-camera';
77

88
import utils from '../utils';
@@ -25,7 +25,7 @@ function Camera({
2525
}) {
2626
// STATE
2727
const [camera, setCamera] = useState();
28-
useCameraAsync();
28+
const [cameraCanMount] = useCameraAsync();
2929

3030
const cameraStyle = useMemo(() => {
3131
// eslint-disable-next-line import/no-named-as-default-member
@@ -44,9 +44,9 @@ function Camera({
4444
}, [camera, onCameraReady]);
4545

4646
// RENDERERS
47-
// if (!cameraCanMount) {
48-
// return <View />;
49-
// }
47+
if (Platform.OS === 'web' && utils.getOS() === 'iOS' && !cameraCanMount) {
48+
return <View />;
49+
}
5050

5151
return (
5252
<ExpoCamera

packages/react-native/src/components/utils.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,33 @@ function getContainedSizes(ratio) {
3333
};
3434
}
3535

36+
function getOS() {
37+
const userAgent = window.navigator.userAgent;
38+
const platform = window.navigator.platform;
39+
const macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'];
40+
const windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'];
41+
const iosPlatforms = ['iPhone', 'iPad', 'iPod'];
42+
let os = null;
43+
44+
if (macosPlatforms.indexOf(platform) !== -1) {
45+
os = 'Mac OS';
46+
} else if (iosPlatforms.indexOf(platform) !== -1) {
47+
os = 'iOS';
48+
} else if (windowsPlatforms.indexOf(platform) !== -1) {
49+
os = 'Windows';
50+
} else if (/Android/.test(userAgent)) {
51+
os = 'Android';
52+
} else if (/Linux/.test(platform)) {
53+
os = 'Linux';
54+
}
55+
56+
return os;
57+
}
58+
3659
export default {
3760
styles: {
3861
flex,
3962
getContainedSizes,
4063
},
64+
getOS,
4165
};

packages/react-native/src/hooks/useCameraAsync/index.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { Platform } from 'react-native';
33
import { Camera } from 'expo-camera';
44
import * as ScreenOrientation from 'expo-screen-orientation';
55

6+
import utils from '../../components/utils';
7+
68
/**
79
* @returns {[unknown, {isAvailable: null, hasPermission: null, isLockInLandscape: null}]}
810
*/
@@ -12,34 +14,38 @@ export default function useCameraAsync() {
1214
[],
1315
);
1416

17+
const isAlwaysAvailable = useMemo(
18+
() => Platform.OS !== 'web' && utils.getOS() !== 'iOS',
19+
[],
20+
);
21+
1522
const [cameraAsync, setCameraAsync] = useState({
1623
hasPermission: null,
17-
// isAvailable: null, // isAvailable was causing issues on Android web apps
24+
isAvailable: isAlwaysAvailable,
1825
isLockInLandscape: null,
1926
});
2027

2128
const cameraCanMount = useMemo(() => {
2229
const {
2330
hasPermission,
24-
// isAvailable,
31+
isAvailable,
2532
isLockInLandscape,
2633
} = cameraAsync;
2734

28-
// return hasPermission && isAvailable && isLockInLandscape;
29-
return hasPermission && isLockInLandscape;
35+
return hasPermission && isAvailable && isLockInLandscape;
3036
}, [cameraAsync]);
3137

3238
useEffect(() => {
3339
(async () => {
3440
const { status } = await Camera.requestPermissionsAsync();
35-
// const isAvailable = isNative || await Camera.isAvailableAsync();
41+
const isAvailable = isAlwaysAvailable || await Camera.isAvailableAsync();
3642
const isLockInLandscape = !isNative || await ScreenOrientation.lockAsync(
3743
ScreenOrientation.OrientationLock.LANDSCAPE_RIGHT,
3844
);
3945

4046
setCameraAsync({
4147
hasPermission: status === 'granted',
42-
// isAvailable,
48+
isAvailable,
4349
isLockInLandscape,
4450
});
4551
})();
@@ -51,7 +57,7 @@ export default function useCameraAsync() {
5157
);
5258
}
5359
};
54-
}, [isNative]);
60+
}, [isAlwaysAvailable, isNative]);
5561

5662
return [cameraCanMount, cameraAsync];
5763
}

0 commit comments

Comments
 (0)