Skip to content

Commit

Permalink
Merge pull request #26231 from tienifr/fix/24160-fail-to-request-came…
Browse files Browse the repository at this point in the history
…ra-permission-in-scan-receipt-screen

Fix: Fail to request camera permission in Scan receipt screen
  • Loading branch information
AndrewGable authored Sep 5, 2023
2 parents a33640c + 6c0320f commit 30076c5
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ const CONST = {
},
RECEIPT: {
ICON_SIZE: 164,
PERMISSION_AUTHORIZED: 'authorized',
PERMISSION_GRANTED: 'granted',
HAND_ICON_HEIGHT: 152,
HAND_ICON_WIDTH: 200,
SHUTTER_SIZE: 90,
Expand Down
12 changes: 12 additions & 0 deletions src/pages/iou/ReceiptSelector/CameraPermission/index.android.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {check, PERMISSIONS, request} from 'react-native-permissions';

function requestCameraPermission() {
return request(PERMISSIONS.ANDROID.CAMERA);
}

// Android will never return blocked after a check, you have to request the permission to get the info.
function getCameraPermissionStatus() {
return check(PERMISSIONS.ANDROID.CAMERA);
}

export {requestCameraPermission, getCameraPermissionStatus};
11 changes: 11 additions & 0 deletions src/pages/iou/ReceiptSelector/CameraPermission/index.ios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {check, PERMISSIONS, request} from 'react-native-permissions';

function requestCameraPermission() {
return request(PERMISSIONS.IOS.CAMERA);
}

function getCameraPermissionStatus() {
return check(PERMISSIONS.IOS.CAMERA);
}

export {requestCameraPermission, getCameraPermissionStatus};
5 changes: 5 additions & 0 deletions src/pages/iou/ReceiptSelector/CameraPermission/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function requestCameraPermission() {}

function getCameraPermissionStatus() {}

export {requestCameraPermission, getCameraPermissionStatus};
28 changes: 17 additions & 11 deletions src/pages/iou/ReceiptSelector/index.native.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {ActivityIndicator, Alert, AppState, Linking, Text, View} from 'react-native';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {Camera, useCameraDevices} from 'react-native-vision-camera';
import {useCameraDevices} from 'react-native-vision-camera';
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import {launchImageLibrary} from 'react-native-image-picker';
import {withOnyx} from 'react-native-onyx';
import {RESULTS} from 'react-native-permissions';
import PressableWithFeedback from '../../../components/Pressable/PressableWithFeedback';
import Icon from '../../../components/Icon';
import * as Expensicons from '../../../components/Icon/Expensicons';
Expand All @@ -19,6 +20,7 @@ import Button from '../../../components/Button';
import useLocalize from '../../../hooks/useLocalize';
import ONYXKEYS from '../../../ONYXKEYS';
import Log from '../../../libs/Log';
import * as CameraPermission from './CameraPermission';
import {iouPropTypes, iouDefaultProps} from '../propTypes';
import NavigationAwareCamera from './NavigationAwareCamera';

Expand Down Expand Up @@ -78,7 +80,8 @@ function ReceiptSelector(props) {

const camera = useRef(null);
const [flash, setFlash] = useState(false);
const [permissions, setPermissions] = useState('authorized');
const [permissions, setPermissions] = useState('granted');
const isAndroidBlockedPermissionRef = useRef(false);
const appState = useRef(AppState.currentState);

const iouType = lodashGet(props.route, 'params.iouType', '');
Expand All @@ -91,7 +94,7 @@ function ReceiptSelector(props) {
useEffect(() => {
const subscription = AppState.addEventListener('change', (nextAppState) => {
if (appState.current.match(/inactive|background/) && nextAppState === 'active') {
Camera.getCameraPermissionStatus().then((permissionStatus) => {
CameraPermission.getCameraPermissionStatus().then((permissionStatus) => {
setPermissions(permissionStatus);
});
}
Expand Down Expand Up @@ -134,12 +137,15 @@ function ReceiptSelector(props) {
};

const askForPermissions = () => {
if (permissions === 'not-determined') {
Camera.requestCameraPermission().then((permissionStatus) => {
// There's no way we can check for the BLOCKED status without requesting the permission first
// https://github.com/zoontek/react-native-permissions/blob/a836e114ce3a180b2b23916292c79841a267d828/README.md?plain=1#L670
if (permissions === RESULTS.BLOCKED || isAndroidBlockedPermissionRef.current) {
Linking.openSettings();
} else if (permissions === RESULTS.DENIED) {
CameraPermission.requestCameraPermission().then((permissionStatus) => {
setPermissions(permissionStatus);
isAndroidBlockedPermissionRef.current = permissionStatus === RESULTS.BLOCKED;
});
} else {
Linking.openSettings();
}
};

Expand Down Expand Up @@ -198,13 +204,13 @@ function ReceiptSelector(props) {
});
}, [flash, iouType, props.iou, props.report, reportID, translate]);

Camera.getCameraPermissionStatus().then((permissionStatus) => {
CameraPermission.getCameraPermissionStatus().then((permissionStatus) => {
setPermissions(permissionStatus);
});

return (
<View style={styles.flex1}>
{permissions !== CONST.RECEIPT.PERMISSION_AUTHORIZED && (
{permissions !== RESULTS.GRANTED && (
<View style={[styles.cameraView, styles.permissionView]}>
<Hand
width={CONST.RECEIPT.HAND_ICON_WIDTH}
Expand All @@ -227,7 +233,7 @@ function ReceiptSelector(props) {
</PressableWithFeedback>
</View>
)}
{permissions === CONST.RECEIPT.PERMISSION_AUTHORIZED && device == null && (
{permissions === RESULTS.GRANTED && device == null && (
<View style={[styles.cameraView]}>
<ActivityIndicator
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
Expand All @@ -236,7 +242,7 @@ function ReceiptSelector(props) {
/>
</View>
)}
{permissions === CONST.RECEIPT.PERMISSION_AUTHORIZED && device != null && (
{permissions === RESULTS.GRANTED && device != null && (
<NavigationAwareCamera
ref={camera}
device={device}
Expand Down

0 comments on commit 30076c5

Please sign in to comment.