Skip to content

Commit b2e43eb

Browse files
committed
fixup! Fix camera permissions race condition
Convert checkAndRequestPermission to ThunkAction that dispatches Redux updates, per swansontec comment: "We don't want to track state locally in the component - that's the job of the permission subsystem. The problem is that the permission subsystem is modifying things and then forgetting to update redux."
1 parent ac4c893 commit b2e43eb

2 files changed

Lines changed: 21 additions & 12 deletions

File tree

src/components/modals/ScanModal.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { sprintf } from 'sprintf-js'
1717
import { useLayout } from '../../hooks/useLayout'
1818
import { lstrings } from '../../locales/strings'
1919
import { config } from '../../theme/appConfig'
20-
import { useSelector } from '../../types/reactRedux'
20+
import { useDispatch, useSelector } from '../../types/reactRedux'
2121
import { triggerHaptic } from '../../util/haptic'
2222
import { logActivity } from '../../util/logger'
2323
import { ModalButtons } from '../buttons/ModalButtons'
@@ -62,6 +62,7 @@ export const ScanModal: React.FC<Props> = props => {
6262
scanModalTitle
6363
} = props
6464

65+
const dispatch = useDispatch()
6566
const theme = useTheme()
6667
const styles = getStyles(theme)
6768

@@ -90,7 +91,7 @@ export const ScanModal: React.FC<Props> = props => {
9091
// Mount effects
9192
React.useEffect(() => {
9293
setScanEnabled(true)
93-
checkAndRequestPermission('camera')
94+
dispatch(checkAndRequestPermission('camera'))
9495
.then(status => {
9596
setCameraPermission(status)
9697
})
@@ -100,7 +101,7 @@ export const ScanModal: React.FC<Props> = props => {
100101
return () => {
101102
setScanEnabled(false)
102103
}
103-
}, [])
104+
}, [dispatch])
104105

105106
const handleBarCodeRead = (codes: Code[]): void => {
106107
setScanEnabled(false)

src/components/services/PermissionsManager.tsx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,22 @@ export async function requestContactsPermission(
9090
* Checks permission and attempts to request permissions (only if checked
9191
* permission was 'denied')
9292
*/
93-
export async function checkAndRequestPermission(
94-
data: Permission
95-
): Promise<PermissionStatus> {
96-
const status: PermissionStatus = await check(permissionNames[data])
97-
98-
if (status === 'denied') return await request(permissionNames[data])
99-
else return status
100-
}
93+
export const checkAndRequestPermission =
94+
(permission: Permission): ThunkAction<Promise<PermissionStatus>> =>
95+
async dispatch => {
96+
const status: PermissionStatus = await check(permissionNames[permission])
97+
98+
if (status !== 'denied') return status
99+
100+
const newStatus = await request(permissionNames[permission])
101+
if (newStatus !== status) {
102+
dispatch({
103+
type: 'PERMISSIONS/UPDATE',
104+
data: { [permission]: newStatus }
105+
})
106+
}
107+
return newStatus
108+
}
101109

102110
export const checkIfDenied = (status: PermissionStatus) =>
103111
status === 'blocked' || status === 'denied' || status === 'unavailable'
@@ -126,7 +134,7 @@ export async function requestPermissionOnSettings(
126134

127135
// User first time check. If mandatory, it needs to be checked if denied or accepted
128136
if (status === 'denied') {
129-
const result = await checkAndRequestPermission(data)
137+
const result = await request(permissionNames[data])
130138
return mandatory && checkIfDenied(result)
131139
}
132140

0 commit comments

Comments
 (0)