expo-permissions
Advanced tools
Comparing version 8.0.0-rc.0 to 8.0.0
import { PermissionExpiration, PermissionMap, PermissionStatus } from './Permissions.types'; | ||
export declare function coalesceStatuses(permissions: PermissionMap): PermissionStatus; | ||
export declare function coalesceExpirations(permissions: PermissionMap): PermissionExpiration; | ||
export declare function coalesceCanAskAgain(permissions: PermissionMap): boolean; | ||
export declare function coalesceGranted(permissions: PermissionMap): boolean; |
@@ -31,2 +31,8 @@ import { PermissionStatus } from './Permissions.types'; | ||
} | ||
export function coalesceCanAskAgain(permissions) { | ||
return Object.keys(permissions).reduce((canAskAgain, type) => canAskAgain && permissions[type].canAskAgain, true); | ||
} | ||
export function coalesceGranted(permissions) { | ||
return Object.keys(permissions).reduce((granted, type) => granted && permissions[type].granted, true); | ||
} | ||
//# sourceMappingURL=CoalescedPermissions.js.map |
@@ -32,3 +32,8 @@ import { PermissionStatus, } from './Permissions.types'; | ||
await _getUserMedia(options); | ||
return { status: PermissionStatus.GRANTED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.GRANTED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: true, | ||
}; | ||
} | ||
@@ -40,3 +45,8 @@ catch ({ message }) { | ||
// message: Permission dismissed | ||
return { status: PermissionStatus.UNDETERMINED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.UNDETERMINED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}; | ||
} | ||
@@ -47,3 +57,8 @@ else { | ||
// message: Permission denied | ||
return { status: PermissionStatus.DENIED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.DENIED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}; | ||
} | ||
@@ -60,9 +75,24 @@ } | ||
return new Promise(resolve => { | ||
navigator.geolocation.getCurrentPosition(() => resolve({ status: PermissionStatus.GRANTED, expires: 'never' }), ({ code }) => { | ||
navigator.geolocation.getCurrentPosition(() => resolve({ | ||
status: PermissionStatus.GRANTED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: true, | ||
}), ({ code }) => { | ||
// https://developer.mozilla.org/en-US/docs/Web/API/PositionError/code | ||
if (code === 1) { | ||
resolve({ status: PermissionStatus.DENIED, expires: 'never' }); | ||
resolve({ | ||
status: PermissionStatus.DENIED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}); | ||
} | ||
else { | ||
resolve({ status: PermissionStatus.UNDETERMINED, expires: 'never' }); | ||
resolve({ | ||
status: PermissionStatus.UNDETERMINED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}); | ||
} | ||
@@ -72,2 +102,39 @@ }); | ||
} | ||
async function getPermissionWithQueryAsync(name) { | ||
if (!navigator || !navigator.permissions || !navigator.permissions.query) | ||
return null; | ||
const { state } = await navigator.permissions.query({ name }); | ||
if (state === 'prompt') { | ||
return PermissionStatus.UNDETERMINED; | ||
} | ||
else if (state === 'granted') { | ||
return PermissionStatus.GRANTED; | ||
} | ||
else if (state === 'denied') { | ||
return PermissionStatus.DENIED; | ||
} | ||
return null; | ||
} | ||
async function enumerateDevices() { | ||
if (navigator && navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) { | ||
return await navigator.mediaDevices.enumerateDevices(); | ||
} | ||
// @ts-ignore: This is deprecated but we should still attempt to use it. | ||
if (window.MediaStreamTrack && typeof window.MediaStreamTrack.getSources === 'function') { | ||
// @ts-ignore | ||
return await MediaStreamTrack.getSources(); | ||
} | ||
return null; | ||
} | ||
async function getMediaMaybeGrantedAsync(targetKind) { | ||
const devices = await enumerateDevices(); | ||
if (!devices) { | ||
return false; | ||
} | ||
const result = await devices | ||
.filter(({ kind }) => kind === targetKind) | ||
.some(({ label }) => label !== ''); | ||
// Granted or denied or undetermined or no devices | ||
return result; | ||
} | ||
async function getPermissionAsync(permission, shouldAsk) { | ||
@@ -78,2 +145,13 @@ switch (permission) { | ||
{ | ||
if (!shouldAsk) { | ||
const status = await getPermissionWithQueryAsync('notifications'); | ||
if (status) { | ||
return { | ||
status, | ||
expires: 'never', | ||
granted: status === PermissionStatus.GRANTED, | ||
canAskAgain: true, | ||
}; | ||
} | ||
} | ||
const { Notification = {} } = window; | ||
@@ -86,5 +164,15 @@ if (Notification.requestPermission) { | ||
if (!status || status === 'default') { | ||
return { status: PermissionStatus.UNDETERMINED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.UNDETERMINED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}; | ||
} | ||
return { status, expires: 'never' }; | ||
return { | ||
status, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: status === PermissionStatus.GRANTED, | ||
}; | ||
} | ||
@@ -95,12 +183,13 @@ } | ||
{ | ||
const { navigator = {} } = window; | ||
if (navigator.permissions) { | ||
const { state } = await navigator.permissions.query({ name: 'geolocation' }); | ||
if (state !== PermissionStatus.GRANTED && state !== PermissionStatus.DENIED) { | ||
if (shouldAsk) { | ||
return await askForLocationPermissionAsync(); | ||
} | ||
return { status: PermissionStatus.UNDETERMINED, expires: 'never' }; | ||
const maybeStatus = await getPermissionWithQueryAsync('geolocation'); | ||
if (maybeStatus) { | ||
if (maybeStatus === PermissionStatus.UNDETERMINED && shouldAsk) { | ||
return await askForLocationPermissionAsync(); | ||
} | ||
return { status: state, expires: 'never' }; | ||
return { | ||
status: maybeStatus, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: maybeStatus === PermissionStatus.GRANTED, | ||
}; | ||
} | ||
@@ -114,16 +203,62 @@ else if (shouldAsk) { | ||
case 'audioRecording': | ||
if (shouldAsk) { | ||
return await askForMicrophonePermissionAsync(); | ||
{ | ||
const maybeStatus = await getPermissionWithQueryAsync('microphone'); | ||
if (maybeStatus) { | ||
if (maybeStatus === PermissionStatus.UNDETERMINED && shouldAsk) { | ||
return await askForMicrophonePermissionAsync(); | ||
} | ||
return { | ||
status: maybeStatus, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: maybeStatus === PermissionStatus.GRANTED, | ||
}; | ||
} | ||
else if (shouldAsk) { | ||
return await askForMicrophonePermissionAsync(); | ||
} | ||
else { | ||
const maybeGranted = await getMediaMaybeGrantedAsync('audioinput'); | ||
if (maybeGranted) { | ||
return { | ||
status: PermissionStatus.GRANTED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: true, | ||
}; | ||
} | ||
// TODO: Bacon: Get denied or undetermined... | ||
} | ||
} | ||
else { | ||
//TODO: Bacon: Is it possible to get this permission? | ||
} | ||
break; | ||
case 'camera': | ||
if (shouldAsk) { | ||
return await askForCameraPermissionAsync(); | ||
{ | ||
const maybeStatus = await getPermissionWithQueryAsync('camera'); | ||
if (maybeStatus) { | ||
if (maybeStatus === PermissionStatus.UNDETERMINED && shouldAsk) { | ||
return await askForCameraPermissionAsync(); | ||
} | ||
return { | ||
status: maybeStatus, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: maybeStatus === PermissionStatus.GRANTED, | ||
}; | ||
} | ||
else if (shouldAsk) { | ||
return await askForCameraPermissionAsync(); | ||
} | ||
else { | ||
const maybeGranted = await getMediaMaybeGrantedAsync('videoinput'); | ||
if (maybeGranted) { | ||
return { | ||
status: PermissionStatus.GRANTED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: true, | ||
}; | ||
} | ||
// TODO: Bacon: Get denied or undetermined... | ||
} | ||
} | ||
else { | ||
//TODO: Bacon: Is it possible to get this permission? | ||
} | ||
break; | ||
@@ -133,3 +268,8 @@ default: | ||
} | ||
return { status: PermissionStatus.UNDETERMINED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.UNDETERMINED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}; | ||
} | ||
@@ -136,0 +276,0 @@ export default { |
@@ -1,2 +0,3 @@ | ||
import { coalesceExpirations, coalesceStatuses } from './CoalescedPermissions'; | ||
import { Platform } from 'react-native'; | ||
import { coalesceExpirations, coalesceStatuses, coalesceCanAskAgain, coalesceGranted, } from './CoalescedPermissions'; | ||
import Permissions from './ExpoPermissions'; | ||
@@ -16,7 +17,32 @@ import { PermissionStatus, } from './Permissions.types'; | ||
export async function getAsync(...types) { | ||
if (Platform.OS === 'ios') { | ||
return await _handleMultiPermissionsRequestIOSAsync(types, Permissions.getAsync); | ||
} | ||
return await _handlePermissionsRequestAsync(types, Permissions.getAsync); | ||
} | ||
export async function askAsync(...types) { | ||
if (Platform.OS === 'ios') { | ||
return await _handleMultiPermissionsRequestIOSAsync(types, Permissions.askAsync); | ||
} | ||
return await _handlePermissionsRequestAsync(types, Permissions.askAsync); | ||
} | ||
async function _handleSinglePermissionRequestIOSAsync(type, handlePermission) { | ||
return await handlePermission(type); | ||
} | ||
async function _handleMultiPermissionsRequestIOSAsync(types, handlePermission) { | ||
if (!types.length) { | ||
throw new Error('At least one permission type must be specified'); | ||
} | ||
let permissions = {}; | ||
for (let type of types) { | ||
permissions[type] = await _handleSinglePermissionRequestIOSAsync(type, handlePermission); | ||
} | ||
return { | ||
status: coalesceStatuses(permissions), | ||
expires: coalesceExpirations(permissions), | ||
canAskAgain: coalesceCanAskAgain(permissions), | ||
granted: coalesceGranted(permissions), | ||
permissions, | ||
}; | ||
} | ||
async function _handlePermissionsRequestAsync(types, handlePermissions) { | ||
@@ -30,2 +56,4 @@ if (!types.length) { | ||
expires: coalesceExpirations(permissions), | ||
canAskAgain: coalesceCanAskAgain(permissions), | ||
granted: coalesceGranted(permissions), | ||
permissions, | ||
@@ -32,0 +60,0 @@ }; |
@@ -0,22 +1,15 @@ | ||
import { PermissionResponse as UMPermissionResponse, PermissionStatus, PermissionExpiration } from 'unimodules-permissions-interface'; | ||
export declare type PermissionType = 'camera' | 'cameraRoll' | 'audioRecording' | 'location' | 'userFacingNotifications' | 'notifications' | 'contacts' | 'calendar' | 'reminders' | 'systemBrightness'; | ||
export declare type PermissionResponse = { | ||
status: PermissionStatus; | ||
expires: PermissionExpiration; | ||
export interface PermissionResponse extends UMPermissionResponse { | ||
permissions: PermissionMap; | ||
}; | ||
export declare type PermissionMap = { | ||
} | ||
export interface PermissionMap { | ||
[permissionType: string]: PermissionInfo; | ||
}; | ||
export declare type PermissionInfo = { | ||
status: PermissionStatus; | ||
expires: PermissionExpiration; | ||
} | ||
export interface PermissionInfo extends UMPermissionResponse { | ||
ios?: PermissionDetailsLocationIOS; | ||
android?: PermissionDetailsLocationAndroid; | ||
}; | ||
export declare enum PermissionStatus { | ||
UNDETERMINED = "undetermined", | ||
GRANTED = "granted", | ||
DENIED = "denied" | ||
} | ||
export declare type PermissionExpiration = 'never' | number; | ||
export { PermissionStatus }; | ||
export { PermissionExpiration }; | ||
export declare type PermissionDetailsLocationIOS = { | ||
@@ -23,0 +16,0 @@ scope: 'whenInUse' | 'always'; |
@@ -1,7 +0,3 @@ | ||
export var PermissionStatus; | ||
(function (PermissionStatus) { | ||
PermissionStatus["UNDETERMINED"] = "undetermined"; | ||
PermissionStatus["GRANTED"] = "granted"; | ||
PermissionStatus["DENIED"] = "denied"; | ||
})(PermissionStatus || (PermissionStatus = {})); | ||
import { PermissionStatus, } from 'unimodules-permissions-interface'; | ||
export { PermissionStatus }; | ||
//# sourceMappingURL=Permissions.types.js.map |
{ | ||
"name": "expo-permissions", | ||
"version": "8.0.0-rc.0", | ||
"version": "8.0.0", | ||
"description": "Allows you prompt for various permissions to access device sensors, personal data, etc.", | ||
@@ -43,3 +43,3 @@ "main": "build/Permissions.js", | ||
}, | ||
"gitHead": "c93271fac3b0e9e8874be0f7a2cfc8f5a47562b9" | ||
"gitHead": "ec7878b9ce54f2537721218ae0fe4017e4004806" | ||
} |
@@ -37,1 +37,15 @@ import { PermissionExpiration, PermissionMap, PermissionStatus } from './Permissions.types'; | ||
} | ||
export function coalesceCanAskAgain(permissions: PermissionMap): boolean { | ||
return Object.keys(permissions).reduce<boolean>( | ||
(canAskAgain, type) => canAskAgain && permissions[type].canAskAgain, | ||
true | ||
); | ||
} | ||
export function coalesceGranted(permissions: PermissionMap): boolean { | ||
return Object.keys(permissions).reduce<boolean>( | ||
(granted, type) => granted && permissions[type].granted, | ||
true | ||
); | ||
} |
import { | ||
PermissionInfo, | ||
PermissionMap, | ||
PermissionType, | ||
PermissionStatus, | ||
PermissionType, | ||
PermissionInfo, | ||
} from './Permissions.types'; | ||
@@ -46,3 +46,8 @@ | ||
await _getUserMedia(options); | ||
return { status: PermissionStatus.GRANTED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.GRANTED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: true, | ||
}; | ||
} catch ({ message }) { | ||
@@ -53,3 +58,8 @@ // name: NotAllowedError | ||
// message: Permission dismissed | ||
return { status: PermissionStatus.UNDETERMINED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.UNDETERMINED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}; | ||
} else { | ||
@@ -59,3 +69,8 @@ // TODO: Bacon: [OSX] The system could deny access to chrome. | ||
// message: Permission denied | ||
return { status: PermissionStatus.DENIED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.DENIED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}; | ||
} | ||
@@ -76,9 +91,25 @@ } | ||
navigator.geolocation.getCurrentPosition( | ||
() => resolve({ status: PermissionStatus.GRANTED, expires: 'never' }), | ||
() => | ||
resolve({ | ||
status: PermissionStatus.GRANTED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: true, | ||
}), | ||
({ code }: PositionError) => { | ||
// https://developer.mozilla.org/en-US/docs/Web/API/PositionError/code | ||
if (code === 1) { | ||
resolve({ status: PermissionStatus.DENIED, expires: 'never' }); | ||
resolve({ | ||
status: PermissionStatus.DENIED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}); | ||
} else { | ||
resolve({ status: PermissionStatus.UNDETERMINED, expires: 'never' }); | ||
resolve({ | ||
status: PermissionStatus.UNDETERMINED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}); | ||
} | ||
@@ -90,2 +121,41 @@ } | ||
async function getPermissionWithQueryAsync(name: PermissionName): Promise<PermissionStatus | null> { | ||
if (!navigator || !navigator.permissions || !navigator.permissions.query) return null; | ||
const { state } = await navigator.permissions.query({ name }); | ||
if (state === 'prompt') { | ||
return PermissionStatus.UNDETERMINED; | ||
} else if (state === 'granted') { | ||
return PermissionStatus.GRANTED; | ||
} else if (state === 'denied') { | ||
return PermissionStatus.DENIED; | ||
} | ||
return null; | ||
} | ||
async function enumerateDevices(): Promise<MediaDeviceInfo[] | null> { | ||
if (navigator && navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) { | ||
return await navigator.mediaDevices.enumerateDevices(); | ||
} | ||
// @ts-ignore: This is deprecated but we should still attempt to use it. | ||
if (window.MediaStreamTrack && typeof window.MediaStreamTrack.getSources === 'function') { | ||
// @ts-ignore | ||
return await MediaStreamTrack.getSources(); | ||
} | ||
return null; | ||
} | ||
async function getMediaMaybeGrantedAsync(targetKind: MediaDeviceKind): Promise<boolean> { | ||
const devices = await enumerateDevices(); | ||
if (!devices) { | ||
return false; | ||
} | ||
const result = await devices | ||
.filter(({ kind }) => kind === targetKind) | ||
.some(({ label }) => label !== ''); | ||
// Granted or denied or undetermined or no devices | ||
return result; | ||
} | ||
async function getPermissionAsync( | ||
@@ -99,2 +169,14 @@ permission: PermissionType, | ||
{ | ||
if (!shouldAsk) { | ||
const status = await getPermissionWithQueryAsync('notifications'); | ||
if (status) { | ||
return { | ||
status, | ||
expires: 'never', | ||
granted: status === PermissionStatus.GRANTED, | ||
canAskAgain: true, | ||
}; | ||
} | ||
} | ||
const { Notification = {} } = window as any; | ||
@@ -107,5 +189,15 @@ if (Notification.requestPermission) { | ||
if (!status || status === 'default') { | ||
return { status: PermissionStatus.UNDETERMINED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.UNDETERMINED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}; | ||
} | ||
return { status, expires: 'never' }; | ||
return { | ||
status, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: status === PermissionStatus.GRANTED, | ||
}; | ||
} | ||
@@ -116,13 +208,13 @@ } | ||
{ | ||
const { navigator = {} } = window as any; | ||
if (navigator.permissions) { | ||
const { state } = await navigator.permissions.query({ name: 'geolocation' }); | ||
if (state !== PermissionStatus.GRANTED && state !== PermissionStatus.DENIED) { | ||
if (shouldAsk) { | ||
return await askForLocationPermissionAsync(); | ||
} | ||
return { status: PermissionStatus.UNDETERMINED, expires: 'never' }; | ||
const maybeStatus = await getPermissionWithQueryAsync('geolocation'); | ||
if (maybeStatus) { | ||
if (maybeStatus === PermissionStatus.UNDETERMINED && shouldAsk) { | ||
return await askForLocationPermissionAsync(); | ||
} | ||
return { status: state, expires: 'never' }; | ||
return { | ||
status: maybeStatus, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: maybeStatus === PermissionStatus.GRANTED, | ||
}; | ||
} else if (shouldAsk) { | ||
@@ -135,13 +227,57 @@ // TODO: Bacon: should this function as ask async when not in chrome? | ||
case 'audioRecording': | ||
if (shouldAsk) { | ||
return await askForMicrophonePermissionAsync(); | ||
} else { | ||
//TODO: Bacon: Is it possible to get this permission? | ||
{ | ||
const maybeStatus = await getPermissionWithQueryAsync('microphone'); | ||
if (maybeStatus) { | ||
if (maybeStatus === PermissionStatus.UNDETERMINED && shouldAsk) { | ||
return await askForMicrophonePermissionAsync(); | ||
} | ||
return { | ||
status: maybeStatus, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: maybeStatus === PermissionStatus.GRANTED, | ||
}; | ||
} else if (shouldAsk) { | ||
return await askForMicrophonePermissionAsync(); | ||
} else { | ||
const maybeGranted = await getMediaMaybeGrantedAsync('audioinput'); | ||
if (maybeGranted) { | ||
return { | ||
status: PermissionStatus.GRANTED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: true, | ||
}; | ||
} | ||
// TODO: Bacon: Get denied or undetermined... | ||
} | ||
} | ||
break; | ||
case 'camera': | ||
if (shouldAsk) { | ||
return await askForCameraPermissionAsync(); | ||
} else { | ||
//TODO: Bacon: Is it possible to get this permission? | ||
{ | ||
const maybeStatus = await getPermissionWithQueryAsync('camera'); | ||
if (maybeStatus) { | ||
if (maybeStatus === PermissionStatus.UNDETERMINED && shouldAsk) { | ||
return await askForCameraPermissionAsync(); | ||
} | ||
return { | ||
status: maybeStatus, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: maybeStatus === PermissionStatus.GRANTED, | ||
}; | ||
} else if (shouldAsk) { | ||
return await askForCameraPermissionAsync(); | ||
} else { | ||
const maybeGranted = await getMediaMaybeGrantedAsync('videoinput'); | ||
if (maybeGranted) { | ||
return { | ||
status: PermissionStatus.GRANTED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: true, | ||
}; | ||
} | ||
// TODO: Bacon: Get denied or undetermined... | ||
} | ||
} | ||
@@ -152,3 +288,8 @@ break; | ||
} | ||
return { status: PermissionStatus.UNDETERMINED, expires: 'never' }; | ||
return { | ||
status: PermissionStatus.UNDETERMINED, | ||
expires: 'never', | ||
canAskAgain: true, | ||
granted: false, | ||
}; | ||
} | ||
@@ -155,0 +296,0 @@ |
@@ -1,3 +0,10 @@ | ||
import { coalesceExpirations, coalesceStatuses } from './CoalescedPermissions'; | ||
import { Platform } from 'react-native'; | ||
import { | ||
coalesceExpirations, | ||
coalesceStatuses, | ||
coalesceCanAskAgain, | ||
coalesceGranted, | ||
} from './CoalescedPermissions'; | ||
import Permissions from './ExpoPermissions'; | ||
import { | ||
@@ -33,2 +40,5 @@ PermissionResponse, | ||
export async function getAsync(...types: PermissionType[]): Promise<PermissionResponse> { | ||
if (Platform.OS === 'ios') { | ||
return await _handleMultiPermissionsRequestIOSAsync(types, Permissions.getAsync); | ||
} | ||
return await _handlePermissionsRequestAsync(types, Permissions.getAsync); | ||
@@ -38,5 +48,37 @@ } | ||
export async function askAsync(...types: PermissionType[]): Promise<PermissionResponse> { | ||
if (Platform.OS === 'ios') { | ||
return await _handleMultiPermissionsRequestIOSAsync(types, Permissions.askAsync); | ||
} | ||
return await _handlePermissionsRequestAsync(types, Permissions.askAsync); | ||
} | ||
async function _handleSinglePermissionRequestIOSAsync( | ||
type: PermissionType, | ||
handlePermission: (type: PermissionType) => Promise<PermissionInfo> | ||
): Promise<PermissionInfo> { | ||
return await handlePermission(type); | ||
} | ||
async function _handleMultiPermissionsRequestIOSAsync( | ||
types: PermissionType[], | ||
handlePermission: (type: PermissionType) => Promise<PermissionInfo> | ||
): Promise<PermissionResponse> { | ||
if (!types.length) { | ||
throw new Error('At least one permission type must be specified'); | ||
} | ||
let permissions = {}; | ||
for (let type of types) { | ||
permissions[type] = await _handleSinglePermissionRequestIOSAsync(type, handlePermission); | ||
} | ||
return { | ||
status: coalesceStatuses(permissions), | ||
expires: coalesceExpirations(permissions), | ||
canAskAgain: coalesceCanAskAgain(permissions), | ||
granted: coalesceGranted(permissions), | ||
permissions, | ||
}; | ||
} | ||
async function _handlePermissionsRequestAsync( | ||
@@ -54,4 +96,6 @@ types: PermissionType[], | ||
expires: coalesceExpirations(permissions), | ||
canAskAgain: coalesceCanAskAgain(permissions), | ||
granted: coalesceGranted(permissions), | ||
permissions, | ||
}; | ||
} |
@@ -0,1 +1,7 @@ | ||
import { | ||
PermissionResponse as UMPermissionResponse, | ||
PermissionStatus, | ||
PermissionExpiration, | ||
} from 'unimodules-permissions-interface'; | ||
export type PermissionType = | ||
@@ -13,25 +19,19 @@ | 'camera' | ||
export type PermissionResponse = { | ||
status: PermissionStatus; | ||
expires: PermissionExpiration; | ||
export interface PermissionResponse extends UMPermissionResponse { | ||
permissions: PermissionMap; | ||
}; | ||
} | ||
export type PermissionMap = { [permissionType: string /* PermissionType */]: PermissionInfo }; | ||
export interface PermissionMap { | ||
[permissionType: string /* PermissionType */]: PermissionInfo; | ||
} | ||
export type PermissionInfo = { | ||
status: PermissionStatus; | ||
expires: PermissionExpiration; | ||
export interface PermissionInfo extends UMPermissionResponse { | ||
ios?: PermissionDetailsLocationIOS; | ||
android?: PermissionDetailsLocationAndroid; | ||
}; | ||
export enum PermissionStatus { | ||
UNDETERMINED = 'undetermined', | ||
GRANTED = 'granted', | ||
DENIED = 'denied', | ||
} | ||
export type PermissionExpiration = 'never' | number; | ||
export { PermissionStatus }; | ||
export { PermissionExpiration }; | ||
export type PermissionDetailsLocationIOS = { | ||
@@ -38,0 +38,0 @@ scope: 'whenInUse' | 'always'; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
922
0
109500
47