teamdigitale/italia-app

View on GitHub
ts/utils/permission.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { Platform } from "react-native";
import * as RNPermissions from "react-native-permissions";

/**
 * Wrapper function to check and request a permission
 * @param permission Permission to request
 * @param rationale Optional rationale displayed only on Android
 * @returns boolean that indicates wether the user has granted the permission or not
 */
export const requestIOPermission = async (
  permission: RNPermissions.Permission,
  rationale?: RNPermissions.Rationale
): Promise<boolean> => {
  const checkResult = await checkIOPermission(permission);
  if (checkResult) {
    return true;
  }

  const requestStatus = await RNPermissions.request(permission, rationale);
  return requestStatus === "granted";
};

/**
 * Wrapper function to check a permission
 * @param permission Permission to request
 * @returns boolean that indicates wether the user has granted the permission or not
 */
export const checkIOPermission = async (
  permission: RNPermissions.Permission
): Promise<boolean> => {
  // Be aware that some permissions may return "unavailable" event if the library
  // documents them as supported. One notorious case is the iOS PHOTO_LIBRARY_ADD_ONLY
  // permission. If such permission is automatically handled by the system upon request
  // (such as PHOTO_LIBRARY_ADD_ONLY is), then you should not use this function to
  // check nor to request such permission
  const checkResult = await RNPermissions.check(permission);
  return checkResult === "granted";
};

/**
 * Wrapper function to request the permission to create an event in the calendar
 * Note: currently unavailable on iOS17, use react-native-calendar-events instead
 * @returns boolean that indicates wether the user has granted the permission or not
 */
export const requestWriteCalendarPermission = async (
  rationale?: RNPermissions.Rationale
) =>
  Platform.select({
    android: requestIOPermission(
      RNPermissions.PERMISSIONS.ANDROID.WRITE_CALENDAR,
      rationale
    ),
    // react-native-permissions currently has problems on iOS 17.
    // Use react-native-calendar-events instead
    // https://github.com/vonovak/react-native-add-calendar-event/issues/180
    ios: Promise.resolve(true),
    default: Promise.resolve(true)
  });

/**
 * Wrapper function to request permission to read images from the gallery
 * @returns boolean that indicates wether the user has granted the permission or not
 */
export const requestMediaPermission = async () => {
  switch (Platform.OS) {
    case "android":
      return requestIOPermission(
        Platform.Version >= 33
          ? RNPermissions.PERMISSIONS.ANDROID.READ_MEDIA_IMAGES
          : RNPermissions.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE
      );
    case "ios":
      // On iOS, photo selection from the gallery is implicitly handled by the image picker.
      // The picker itself prompts the user for permission to access photos, allowing them to
      // select a photo that is then seamlessly passed back to the app.
      return true;
    default:
      return false;
  }
};

/**
 * Wrapper function to request permission to save an image to the library
 * @returns boolean that indicates wether the user has granted the permission or not
 */
export const requestSaveToGalleryPermission = async (
  rationale?: RNPermissions.Rationale
) =>
  Platform.select({
    android: requestIOPermission(
      RNPermissions.PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE,
      rationale
    ),
    // on iOS the permission is handled by adding NSPhotoLibraryAddUsageDescription and NSPhotoLibraryUsageDescription
    // into the Info.plist file and the permission request is automatically handled by the system when using the
    // Cameraroll.save method. Asking for the PHOTO_LIBRARY_ADD_ONLY permission results in an "unavailable" response
    // from the react-native-permissions library (even if the library documentation declares that it is supported) so
    // it cannot be used to determine the permission status.
    default: Promise.resolve(true)
  });