UNPKG

@cometchat/chat-uikit-react-native

Version:

Ready-to-use Chat UI Components for React Native

145 lines (131 loc) 4.56 kB
import { Alert, Linking, NativeModules, PermissionsAndroid, Platform } from "react-native"; import { getCometChatTranslation } from "../resources/CometChatLocalizeNew/LocalizationManager"; const t = getCometChatTranslation(); const { FileManager } = NativeModules; let instance: PermissionUtilIOS; const permissionStatus = { "Not Determined": 0, Restricted: 1, Denied: 2, Authorized: 3, Unknown: -1, } as const; const permissionStatusAndroid = { granted: 3, denied: 2, never_ask_again: 2, } as any; const permissibleResources = ["camera", "mic"] as const; const permissionMapAndroid: any = { camera: PermissionsAndroid.PERMISSIONS.CAMERA, mic: PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, }; type TPermissibleResources = (typeof permissibleResources)[number]; type ValueOf<T> = T[keyof T]; type TPermissionStatus = ValueOf<typeof permissionStatus>; const permissionStore: any = { camera: permissionStatus.Unknown, mic: permissionStatus.Unknown, }; class PermissionUtilIOS { status = permissionStatus; constructor() { if (instance) { throw new Error("New instance cannot be created!!"); } instance = this; } async init() { try { if (Platform.OS === "ios") { const res: Record<TPermissibleResources, TPermissionStatus> = await FileManager.checkResourcesPermission(["mic", "camera"]); for (const resourceType in res) { permissionStore[resourceType as TPermissibleResources] = res[resourceType as TPermissibleResources]; } permissionStore.camera = res.camera; permissionStore.mic = res.mic; } else if (Platform.OS === "android") { for (const resourceType of permissibleResources) { const isGranted = await PermissionsAndroid.check(permissionMapAndroid[resourceType]); permissionStore[resourceType] = isGranted ? permissionStatus.Authorized : permissionStatus["Not Determined"]; } } return true; } catch (error: any) { return false; } } async get(resources: TPermissibleResources[]) { return resources.map((resource) => { if (!permissibleResources.includes(resource)) { throw new Error("Invalid resource type"); } return permissionStore[resource]; }); } async request(resources: TPermissibleResources[]) { for (const resource of resources) { if (!permissibleResources.includes(resource)) { throw new Error("Invalid resource type"); } } if (Platform.OS === "ios") { const res: Record<TPermissibleResources, TPermissionStatus> = await FileManager.requestResourcesPermission(resources); for (const resourceType in res) { permissionStore[resourceType as TPermissibleResources] = res[resourceType as TPermissibleResources]; } } else if (Platform.OS === "android") { const res: any = await PermissionsAndroid.requestMultiple( resources.map((item) => permissionMapAndroid[item]) ); const permissionMapAndroidRevert: any = {}; for (const resource in permissionMapAndroid) { permissionMapAndroidRevert[permissionMapAndroid[resource]] = resource; } for (const androidResource in res) { permissionStore[permissionMapAndroidRevert[androidResource]] = permissionStatusAndroid[res[androidResource]]; } } } async startResourceBasedTask(resources: TPermissibleResources[]) { const resourcePermStatuses = await this.get(resources); let allResourcesAllowed = true; for (let i = 0; i < resourcePermStatuses.length; i++) { const resourcePermStatus = resourcePermStatuses[i]; if ( resourcePermStatus === this.status["Not Determined"] || (Platform.OS === "android" && resourcePermStatuses[i] === this.status.Denied) ) { await this.request([resources[i]]); [resourcePermStatuses[i]] = await this.get([resources[i]]); } if (resourcePermStatuses[i] === this.status.Denied) { allResourcesAllowed = false; } } if (allResourcesAllowed === false) { Alert.alert("", t("CAMERA_PERMISSION"), [ { style: "cancel", text: t("CANCEL"), }, { style: "default", text: t("SETTINGS"), onPress: () => { Linking.openSettings(); }, }, ]); } return allResourcesAllowed; } } export const permissionUtil = Object.freeze(new PermissionUtilIOS());