expo-image-picker 14.0.3 → 14.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/android/build.gradle +4 -4
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt +22 -6
- package/build/ImagePicker.js +1 -1
- package/build/ImagePicker.js.map +1 -1
- package/package.json +2 -2
- package/src/ImagePicker.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 14.1.0 — 2023-01-26
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- Add support for [granular permissions](https://developer.android.com/about/versions/13/behavior-changes-13) on Android 13. ([#20908](https://github.com/expo/expo/pull/20908) by [@alanhughes](https://github.com/alanjhughes))
|
|
18
|
+
|
|
19
|
+
### 💡 Others
|
|
20
|
+
|
|
21
|
+
- On Android bump `compileSdkVersion` and `targetSdkVersion` to `33`. ([#20721](https://github.com/expo/expo/pull/20721) by [@lukmccall](https://github.com/lukmccall))
|
|
22
|
+
|
|
13
23
|
## 14.0.3 — 2022-12-30
|
|
14
24
|
|
|
15
25
|
### 💡 Others
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven-publish'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '14.0
|
|
6
|
+
version = '14.1.0'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -59,7 +59,7 @@ afterEvaluate {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
android {
|
|
62
|
-
compileSdkVersion safeExtGet("compileSdkVersion",
|
|
62
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 33)
|
|
63
63
|
|
|
64
64
|
compileOptions {
|
|
65
65
|
sourceCompatibility JavaVersion.VERSION_11
|
|
@@ -72,9 +72,9 @@ android {
|
|
|
72
72
|
|
|
73
73
|
defaultConfig {
|
|
74
74
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
75
|
-
targetSdkVersion safeExtGet("targetSdkVersion",
|
|
75
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
76
76
|
versionCode 22
|
|
77
|
-
versionName "14.0
|
|
77
|
+
versionName "14.1.0"
|
|
78
78
|
}
|
|
79
79
|
lintOptions {
|
|
80
80
|
abortOnError false
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
<!-- Required for picking images from camera roll -->
|
|
8
8
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
9
9
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
|
10
|
+
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
|
11
|
+
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
|
10
12
|
|
|
11
13
|
<application>
|
|
12
14
|
<activity
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
package expo.modules.imagepicker
|
|
2
2
|
|
|
3
3
|
import android.Manifest
|
|
4
|
+
import android.Manifest.permission.READ_MEDIA_IMAGES
|
|
5
|
+
import android.Manifest.permission.READ_MEDIA_VIDEO
|
|
4
6
|
import android.content.Context
|
|
5
7
|
import android.content.Intent
|
|
6
8
|
import android.net.Uri
|
|
9
|
+
import android.os.Build
|
|
7
10
|
import android.os.OperationCanceledException
|
|
8
11
|
import expo.modules.core.errors.ModuleNotFoundException
|
|
9
12
|
import expo.modules.imagepicker.contracts.CameraContract
|
|
@@ -109,7 +112,7 @@ class ImagePickerModule : Module() {
|
|
|
109
112
|
private lateinit var cropImageLauncher: AppContextActivityResultLauncher<CropImageContractOptions, ImagePickerContractResult>
|
|
110
113
|
|
|
111
114
|
private val cacheDirectory: File
|
|
112
|
-
get() = appContext.cacheDirectory
|
|
115
|
+
get() = appContext.cacheDirectory
|
|
113
116
|
|
|
114
117
|
/**
|
|
115
118
|
* Stores result for an operation that has been interrupted by the activity destruction.
|
|
@@ -171,10 +174,16 @@ class ImagePickerModule : Module() {
|
|
|
171
174
|
// region Utils
|
|
172
175
|
|
|
173
176
|
private fun getMediaLibraryPermissions(writeOnly: Boolean): Array<String> =
|
|
174
|
-
if (
|
|
175
|
-
|
|
177
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
178
|
+
listOfNotNull(
|
|
179
|
+
READ_MEDIA_IMAGES.takeIf { !writeOnly },
|
|
180
|
+
READ_MEDIA_VIDEO.takeIf { !writeOnly }
|
|
181
|
+
).toTypedArray()
|
|
176
182
|
} else {
|
|
177
|
-
|
|
183
|
+
listOfNotNull(
|
|
184
|
+
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
|
185
|
+
Manifest.permission.READ_EXTERNAL_STORAGE.takeIf { !writeOnly }
|
|
186
|
+
).toTypedArray()
|
|
178
187
|
}
|
|
179
188
|
|
|
180
189
|
private fun ensureTargetActivityIsAvailable(options: ImagePickerOptions) {
|
|
@@ -189,7 +198,13 @@ class ImagePickerModule : Module() {
|
|
|
189
198
|
|
|
190
199
|
permissions.askForPermissions(
|
|
191
200
|
{ permissionsResponse ->
|
|
192
|
-
if (
|
|
201
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
202
|
+
if (permissionsResponse[Manifest.permission.CAMERA]?.status == PermissionsStatus.GRANTED) {
|
|
203
|
+
continuation.resume(Unit)
|
|
204
|
+
} else {
|
|
205
|
+
continuation.resumeWithException(UserRejectedPermissionsException())
|
|
206
|
+
}
|
|
207
|
+
} else if (
|
|
193
208
|
permissionsResponse[Manifest.permission.WRITE_EXTERNAL_STORAGE]?.status == PermissionsStatus.GRANTED &&
|
|
194
209
|
permissionsResponse[Manifest.permission.CAMERA]?.status == PermissionsStatus.GRANTED
|
|
195
210
|
) {
|
|
@@ -198,7 +213,8 @@ class ImagePickerModule : Module() {
|
|
|
198
213
|
continuation.resumeWithException(UserRejectedPermissionsException())
|
|
199
214
|
}
|
|
200
215
|
},
|
|
201
|
-
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
|
216
|
+
Manifest.permission.WRITE_EXTERNAL_STORAGE.takeIf { Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU },
|
|
217
|
+
Manifest.permission.CAMERA
|
|
202
218
|
)
|
|
203
219
|
}
|
|
204
220
|
|
package/build/ImagePicker.js
CHANGED
package/build/ImagePicker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImagePicker.js","sourceRoot":"","sources":["../src/ImagePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n PermissionStatus,\n PermissionExpiration,\n PermissionHookOptions,\n PermissionResponse,\n createPermissionHook,\n UnavailabilityError,\n CodedError,\n} from 'expo-modules-core';\n\nimport ExponentImagePicker from './ExponentImagePicker';\nimport {\n CameraPermissionResponse,\n MediaLibraryPermissionResponse,\n ImagePickerResult,\n ImagePickerAsset,\n ImagePickerErrorResult,\n MediaTypeOptions,\n ImagePickerOptions,\n VideoExportPreset,\n ExpandImagePickerResult,\n ImageInfo,\n ImagePickerMultipleResult,\n ImagePickerCancelledResult,\n OpenFileBrowserOptions,\n UIImagePickerControllerQualityType,\n UIImagePickerPresentationStyle,\n} from './ImagePicker.types';\n\nfunction validateOptions(options: ImagePickerOptions) {\n const { aspect, quality, videoMaxDuration } = options;\n\n if (aspect != null) {\n const [x, y] = aspect;\n\n if (x <= 0 || y <= 0) {\n throw new CodedError(\n 'ERR_INVALID_ARGUMENT',\n `Invalid aspect ratio values ${x}:${y}. Provide positive numbers.`\n );\n }\n }\n\n if (quality && (quality < 0 || quality > 1)) {\n throw new CodedError(\n 'ERR_INVALID_ARGUMENT',\n `Invalid 'quality' value ${quality}. Provide a value between 0 and 1.`\n );\n }\n\n if (videoMaxDuration && videoMaxDuration < 0) {\n throw new CodedError(\n 'ERR_INVALID_ARGUMENT',\n `Invalid 'videoMaxDuration' value ${videoMaxDuration}. Provide a non-negative number.`\n );\n }\n\n return options;\n}\n\nconst DEPRECATED_RESULT_KEYS = [\n 'uri',\n 'assetId',\n 'width',\n 'height',\n 'type',\n 'exif',\n 'base64',\n 'duration',\n 'fileName',\n 'fileSize',\n];\nfunction mergeDeprecatedResult(result: ImagePickerResult): ImagePickerResult {\n const firstAsset = result.assets?.[0];\n const deprecatedResult = {\n ...result,\n get cancelled() {\n console.warn(\n 'Key \"cancelled\" in the image picker result is deprecated and will be removed in SDK 48, use \"canceled\" instead'\n );\n return this.canceled;\n },\n };\n for (const key of DEPRECATED_RESULT_KEYS) {\n Object.defineProperty(deprecatedResult, key, {\n get() {\n console.warn(\n `Key \"${key}\" in the image picker result is deprecated and will be removed in SDK 48, you can access selected assets through the \"assets\" array instead`\n );\n return firstAsset?.[key];\n },\n });\n }\n return deprecatedResult;\n}\n\n// @needsAudit\n/**\n * Checks user's permissions for accessing camera.\n * @return A promise that fulfills with an object of type [CameraPermissionResponse](#camerapermissionresponse).\n */\nexport async function getCameraPermissionsAsync(): Promise<CameraPermissionResponse> {\n return ExponentImagePicker.getCameraPermissionsAsync();\n}\n\n// @needsAudit\n/**\n * Checks user's permissions for accessing photos.\n * @param writeOnly Whether to request write or read and write permissions. Defaults to `false`\n * @return A promise that fulfills with an object of type [MediaLibraryPermissionResponse](#medialibrarypermissionresponse).\n */\nexport async function getMediaLibraryPermissionsAsync(\n writeOnly: boolean = false\n): Promise<MediaLibraryPermissionResponse> {\n return ExponentImagePicker.getMediaLibraryPermissionsAsync(writeOnly);\n}\n\n// @needsAudit\n/**\n * Asks the user to grant permissions for accessing camera. This does nothing on web because the\n * browser camera is not used.\n * @return A promise that fulfills with an object of type [CameraPermissionResponse](#camerarollpermissionresponse).\n */\nexport async function requestCameraPermissionsAsync(): Promise<CameraPermissionResponse> {\n return ExponentImagePicker.requestCameraPermissionsAsync();\n}\n\n// @needsAudit\n/**\n * Asks the user to grant permissions for accessing user's photo. This method does nothing on web.\n * @param writeOnly Whether to request write or read and write permissions. Defaults to `false`\n * @return A promise that fulfills with an object of type [MediaLibraryPermissionResponse](#medialibrarypermissionresponse).\n */\nexport async function requestMediaLibraryPermissionsAsync(\n writeOnly: boolean = false\n): Promise<MediaLibraryPermissionResponse> {\n const imagePickerMethod = ExponentImagePicker.requestMediaLibraryPermissionsAsync;\n return imagePickerMethod(writeOnly);\n}\n\n// @needsAudit\n/**\n * Check or request permissions to access the media library.\n * This uses both `requestMediaLibraryPermissionsAsync` and `getMediaLibraryPermissionsAsync` to interact with the permissions.\n *\n * @example\n * ```ts\n * const [status, requestPermission] = ImagePicker.useMediaLibraryPermissions();\n * ```\n */\nexport const useMediaLibraryPermissions = createPermissionHook<\n MediaLibraryPermissionResponse,\n { writeOnly?: boolean }\n>({\n // TODO(cedric): permission requesters should have an options param or a different requester\n getMethod: (options) => getMediaLibraryPermissionsAsync(options?.writeOnly),\n requestMethod: (options) => requestMediaLibraryPermissionsAsync(options?.writeOnly),\n});\n\n// @needsAudit\n/**\n * Check or request permissions to access the camera.\n * This uses both `requestCameraPermissionsAsync` and `getCameraPermissionsAsync` to interact with the permissions.\n *\n * @example\n * ```ts\n * const [status, requestPermission] = ImagePicker.useCameraPermissions();\n * ```\n */\nexport const useCameraPermissions = createPermissionHook({\n getMethod: getCameraPermissionsAsync,\n requestMethod: requestCameraPermissionsAsync,\n});\n\n// @needsAudit\n/**\n * Android system sometimes kills the `MainActivity` after the `ImagePicker` finishes. When this\n * happens, we lost the data selected from the `ImagePicker`. However, you can retrieve the lost\n * data by calling `getPendingResultAsync`. You can test this functionality by turning on\n * `Don't keep activities` in the developer options.\n * @return\n * - **On Android:** a promise that resolves to an array of objects of exactly same type as in\n * `ImagePicker.launchImageLibraryAsync` or `ImagePicker.launchCameraAsync` if the `ImagePicker`\n * finished successfully. Otherwise, to the array of [`ImagePickerErrorResult`](#imagepickerimagepickererrorresult).\n * - **On other platforms:** an empty array.\n */\nexport async function getPendingResultAsync(): Promise<\n (ImagePickerResult | ImagePickerErrorResult)[]\n> {\n if (ExponentImagePicker.getPendingResultAsync) {\n return ExponentImagePicker.getPendingResultAsync();\n }\n return [];\n}\n\n// @needsAudit\n/**\n * Display the system UI for taking a photo with the camera. Requires `Permissions.CAMERA`.\n * On Android and iOS 10 `Permissions.CAMERA_ROLL` is also required. On mobile web, this must be\n * called immediately in a user interaction like a button press, otherwise the browser will block\n * the request without a warning.\n * > **Note:** Make sure that you handle `MainActivity` destruction on **Android**. See [ImagePicker.getPendingResultAsync](#imagepickergetpendingresultasync).\n * > **Notes for Web:** The system UI can only be shown after user activation (e.g. a `Button` press).\n * Therefore, calling `launchCameraAsync` in `componentDidMount`, for example, will **not** work as\n * intended. The `cancelled` event will not be returned in the browser due to platform restrictions\n * and inconsistencies across browsers.\n * @param options An `ImagePickerOptions` object.\n * @return A promise that resolves to an object with `canceled` and `assets` fields.\n * When the user canceled the action the `assets` is always `null`, otherwise it's an array of\n * the selected media assets which have a form of [`ImagePickerAsset`](#imagepickerasset).\n */\nexport async function launchCameraAsync(\n options: ImagePickerOptions = {}\n): Promise<ImagePickerResult> {\n if (!ExponentImagePicker.launchCameraAsync) {\n throw new UnavailabilityError('ImagePicker', 'launchCameraAsync');\n }\n const result = await ExponentImagePicker.launchCameraAsync(validateOptions(options));\n return mergeDeprecatedResult(result);\n}\n\n// @needsAudit\n/**\n * Display the system UI for choosing an image or a video from the phone's library.\n * Requires `Permissions.MEDIA_LIBRARY` on iOS 10 only. On mobile web, this must be called\n * immediately in a user interaction like a button press, otherwise the browser will block the\n * request without a warning.\n *\n * **Animated GIFs support:** On Android, if the selected image is an animated GIF, the result image will be an\n * animated GIF too if and only if `quality` is explicitly set to `1.0` and `allowsEditing` is set to `false`.\n * Otherwise compression and/or cropper will pick the first frame of the GIF and return it as the\n * result (on Android the result will be a PNG). On iOS, both quality and cropping are supported.\n *\n * > **Notes for Web:** The system UI can only be shown after user activation (e.g. a `Button` press).\n * Therefore, calling `launchImageLibraryAsync` in `componentDidMount`, for example, will **not**\n * work as intended. The `cancelled` event will not be returned in the browser due to platform\n * restrictions and inconsistencies across browsers.\n * @param options An object extended by [`ImagePickerOptions`](#imagepickeroptions).\n * @return A promise that resolves to an object with `canceled` and `assets` fields.\n * When the user canceled the action the `assets` is always `null`, otherwise it's an array of\n * the selected media assets which have a form of [`ImagePickerAsset`](#imagepickerasset).\n */\nexport async function launchImageLibraryAsync(\n options?: ImagePickerOptions\n): Promise<ImagePickerResult> {\n if (!ExponentImagePicker.launchImageLibraryAsync) {\n throw new UnavailabilityError('ImagePicker', 'launchImageLibraryAsync');\n }\n if (options?.allowsEditing && options.allowsMultipleSelection) {\n console.warn(\n '[expo-image-picker] `allowsEditing` is not supported when `allowsMultipleSelection` is enabled and will be ignored.' +\n \"Disable either 'allowsEditing' or 'allowsMultipleSelection' in 'launchImageLibraryAsync' \" +\n 'to fix this warning.'\n );\n }\n const result = await ExponentImagePicker.launchImageLibraryAsync(options ?? {});\n return mergeDeprecatedResult(result);\n}\n\nexport {\n MediaTypeOptions,\n ImagePickerOptions,\n ImagePickerResult,\n ImagePickerErrorResult,\n ImagePickerAsset,\n VideoExportPreset,\n CameraPermissionResponse,\n MediaLibraryPermissionResponse,\n PermissionStatus,\n PermissionExpiration,\n PermissionHookOptions,\n PermissionResponse,\n ImageInfo, // deprecated\n ImagePickerMultipleResult, // deprecated\n ImagePickerCancelledResult, // deprecated\n OpenFileBrowserOptions,\n ExpandImagePickerResult, // deprecated\n UIImagePickerControllerQualityType,\n UIImagePickerPresentationStyle,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ImagePicker.js","sourceRoot":"","sources":["../src/ImagePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n PermissionStatus,\n PermissionExpiration,\n PermissionHookOptions,\n PermissionResponse,\n createPermissionHook,\n UnavailabilityError,\n CodedError,\n} from 'expo-modules-core';\n\nimport ExponentImagePicker from './ExponentImagePicker';\nimport {\n CameraPermissionResponse,\n MediaLibraryPermissionResponse,\n ImagePickerResult,\n ImagePickerAsset,\n ImagePickerErrorResult,\n MediaTypeOptions,\n ImagePickerOptions,\n VideoExportPreset,\n ExpandImagePickerResult,\n ImageInfo,\n ImagePickerMultipleResult,\n ImagePickerCancelledResult,\n OpenFileBrowserOptions,\n UIImagePickerControllerQualityType,\n UIImagePickerPresentationStyle,\n} from './ImagePicker.types';\n\nfunction validateOptions(options: ImagePickerOptions) {\n const { aspect, quality, videoMaxDuration } = options;\n\n if (aspect != null) {\n const [x, y] = aspect;\n\n if (x <= 0 || y <= 0) {\n throw new CodedError(\n 'ERR_INVALID_ARGUMENT',\n `Invalid aspect ratio values ${x}:${y}. Provide positive numbers.`\n );\n }\n }\n\n if (quality && (quality < 0 || quality > 1)) {\n throw new CodedError(\n 'ERR_INVALID_ARGUMENT',\n `Invalid 'quality' value ${quality}. Provide a value between 0 and 1.`\n );\n }\n\n if (videoMaxDuration && videoMaxDuration < 0) {\n throw new CodedError(\n 'ERR_INVALID_ARGUMENT',\n `Invalid 'videoMaxDuration' value ${videoMaxDuration}. Provide a non-negative number.`\n );\n }\n\n return options;\n}\n\nconst DEPRECATED_RESULT_KEYS = [\n 'uri',\n 'assetId',\n 'width',\n 'height',\n 'type',\n 'exif',\n 'base64',\n 'duration',\n 'fileName',\n 'fileSize',\n];\nfunction mergeDeprecatedResult(result: ImagePickerResult): ImagePickerResult {\n const firstAsset = result?.assets?.[0];\n const deprecatedResult = {\n ...result,\n get cancelled() {\n console.warn(\n 'Key \"cancelled\" in the image picker result is deprecated and will be removed in SDK 48, use \"canceled\" instead'\n );\n return this.canceled;\n },\n };\n for (const key of DEPRECATED_RESULT_KEYS) {\n Object.defineProperty(deprecatedResult, key, {\n get() {\n console.warn(\n `Key \"${key}\" in the image picker result is deprecated and will be removed in SDK 48, you can access selected assets through the \"assets\" array instead`\n );\n return firstAsset?.[key];\n },\n });\n }\n return deprecatedResult;\n}\n\n// @needsAudit\n/**\n * Checks user's permissions for accessing camera.\n * @return A promise that fulfills with an object of type [CameraPermissionResponse](#camerapermissionresponse).\n */\nexport async function getCameraPermissionsAsync(): Promise<CameraPermissionResponse> {\n return ExponentImagePicker.getCameraPermissionsAsync();\n}\n\n// @needsAudit\n/**\n * Checks user's permissions for accessing photos.\n * @param writeOnly Whether to request write or read and write permissions. Defaults to `false`\n * @return A promise that fulfills with an object of type [MediaLibraryPermissionResponse](#medialibrarypermissionresponse).\n */\nexport async function getMediaLibraryPermissionsAsync(\n writeOnly: boolean = false\n): Promise<MediaLibraryPermissionResponse> {\n return ExponentImagePicker.getMediaLibraryPermissionsAsync(writeOnly);\n}\n\n// @needsAudit\n/**\n * Asks the user to grant permissions for accessing camera. This does nothing on web because the\n * browser camera is not used.\n * @return A promise that fulfills with an object of type [CameraPermissionResponse](#camerarollpermissionresponse).\n */\nexport async function requestCameraPermissionsAsync(): Promise<CameraPermissionResponse> {\n return ExponentImagePicker.requestCameraPermissionsAsync();\n}\n\n// @needsAudit\n/**\n * Asks the user to grant permissions for accessing user's photo. This method does nothing on web.\n * @param writeOnly Whether to request write or read and write permissions. Defaults to `false`\n * @return A promise that fulfills with an object of type [MediaLibraryPermissionResponse](#medialibrarypermissionresponse).\n */\nexport async function requestMediaLibraryPermissionsAsync(\n writeOnly: boolean = false\n): Promise<MediaLibraryPermissionResponse> {\n const imagePickerMethod = ExponentImagePicker.requestMediaLibraryPermissionsAsync;\n return imagePickerMethod(writeOnly);\n}\n\n// @needsAudit\n/**\n * Check or request permissions to access the media library.\n * This uses both `requestMediaLibraryPermissionsAsync` and `getMediaLibraryPermissionsAsync` to interact with the permissions.\n *\n * @example\n * ```ts\n * const [status, requestPermission] = ImagePicker.useMediaLibraryPermissions();\n * ```\n */\nexport const useMediaLibraryPermissions = createPermissionHook<\n MediaLibraryPermissionResponse,\n { writeOnly?: boolean }\n>({\n // TODO(cedric): permission requesters should have an options param or a different requester\n getMethod: (options) => getMediaLibraryPermissionsAsync(options?.writeOnly),\n requestMethod: (options) => requestMediaLibraryPermissionsAsync(options?.writeOnly),\n});\n\n// @needsAudit\n/**\n * Check or request permissions to access the camera.\n * This uses both `requestCameraPermissionsAsync` and `getCameraPermissionsAsync` to interact with the permissions.\n *\n * @example\n * ```ts\n * const [status, requestPermission] = ImagePicker.useCameraPermissions();\n * ```\n */\nexport const useCameraPermissions = createPermissionHook({\n getMethod: getCameraPermissionsAsync,\n requestMethod: requestCameraPermissionsAsync,\n});\n\n// @needsAudit\n/**\n * Android system sometimes kills the `MainActivity` after the `ImagePicker` finishes. When this\n * happens, we lost the data selected from the `ImagePicker`. However, you can retrieve the lost\n * data by calling `getPendingResultAsync`. You can test this functionality by turning on\n * `Don't keep activities` in the developer options.\n * @return\n * - **On Android:** a promise that resolves to an array of objects of exactly same type as in\n * `ImagePicker.launchImageLibraryAsync` or `ImagePicker.launchCameraAsync` if the `ImagePicker`\n * finished successfully. Otherwise, to the array of [`ImagePickerErrorResult`](#imagepickerimagepickererrorresult).\n * - **On other platforms:** an empty array.\n */\nexport async function getPendingResultAsync(): Promise<\n (ImagePickerResult | ImagePickerErrorResult)[]\n> {\n if (ExponentImagePicker.getPendingResultAsync) {\n return ExponentImagePicker.getPendingResultAsync();\n }\n return [];\n}\n\n// @needsAudit\n/**\n * Display the system UI for taking a photo with the camera. Requires `Permissions.CAMERA`.\n * On Android and iOS 10 `Permissions.CAMERA_ROLL` is also required. On mobile web, this must be\n * called immediately in a user interaction like a button press, otherwise the browser will block\n * the request without a warning.\n * > **Note:** Make sure that you handle `MainActivity` destruction on **Android**. See [ImagePicker.getPendingResultAsync](#imagepickergetpendingresultasync).\n * > **Notes for Web:** The system UI can only be shown after user activation (e.g. a `Button` press).\n * Therefore, calling `launchCameraAsync` in `componentDidMount`, for example, will **not** work as\n * intended. The `cancelled` event will not be returned in the browser due to platform restrictions\n * and inconsistencies across browsers.\n * @param options An `ImagePickerOptions` object.\n * @return A promise that resolves to an object with `canceled` and `assets` fields.\n * When the user canceled the action the `assets` is always `null`, otherwise it's an array of\n * the selected media assets which have a form of [`ImagePickerAsset`](#imagepickerasset).\n */\nexport async function launchCameraAsync(\n options: ImagePickerOptions = {}\n): Promise<ImagePickerResult> {\n if (!ExponentImagePicker.launchCameraAsync) {\n throw new UnavailabilityError('ImagePicker', 'launchCameraAsync');\n }\n const result = await ExponentImagePicker.launchCameraAsync(validateOptions(options));\n return mergeDeprecatedResult(result);\n}\n\n// @needsAudit\n/**\n * Display the system UI for choosing an image or a video from the phone's library.\n * Requires `Permissions.MEDIA_LIBRARY` on iOS 10 only. On mobile web, this must be called\n * immediately in a user interaction like a button press, otherwise the browser will block the\n * request without a warning.\n *\n * **Animated GIFs support:** On Android, if the selected image is an animated GIF, the result image will be an\n * animated GIF too if and only if `quality` is explicitly set to `1.0` and `allowsEditing` is set to `false`.\n * Otherwise compression and/or cropper will pick the first frame of the GIF and return it as the\n * result (on Android the result will be a PNG). On iOS, both quality and cropping are supported.\n *\n * > **Notes for Web:** The system UI can only be shown after user activation (e.g. a `Button` press).\n * Therefore, calling `launchImageLibraryAsync` in `componentDidMount`, for example, will **not**\n * work as intended. The `cancelled` event will not be returned in the browser due to platform\n * restrictions and inconsistencies across browsers.\n * @param options An object extended by [`ImagePickerOptions`](#imagepickeroptions).\n * @return A promise that resolves to an object with `canceled` and `assets` fields.\n * When the user canceled the action the `assets` is always `null`, otherwise it's an array of\n * the selected media assets which have a form of [`ImagePickerAsset`](#imagepickerasset).\n */\nexport async function launchImageLibraryAsync(\n options?: ImagePickerOptions\n): Promise<ImagePickerResult> {\n if (!ExponentImagePicker.launchImageLibraryAsync) {\n throw new UnavailabilityError('ImagePicker', 'launchImageLibraryAsync');\n }\n if (options?.allowsEditing && options.allowsMultipleSelection) {\n console.warn(\n '[expo-image-picker] `allowsEditing` is not supported when `allowsMultipleSelection` is enabled and will be ignored.' +\n \"Disable either 'allowsEditing' or 'allowsMultipleSelection' in 'launchImageLibraryAsync' \" +\n 'to fix this warning.'\n );\n }\n const result = await ExponentImagePicker.launchImageLibraryAsync(options ?? {});\n return mergeDeprecatedResult(result);\n}\n\nexport {\n MediaTypeOptions,\n ImagePickerOptions,\n ImagePickerResult,\n ImagePickerErrorResult,\n ImagePickerAsset,\n VideoExportPreset,\n CameraPermissionResponse,\n MediaLibraryPermissionResponse,\n PermissionStatus,\n PermissionExpiration,\n PermissionHookOptions,\n PermissionResponse,\n ImageInfo, // deprecated\n ImagePickerMultipleResult, // deprecated\n ImagePickerCancelledResult, // deprecated\n OpenFileBrowserOptions,\n ExpandImagePickerResult, // deprecated\n UIImagePickerControllerQualityType,\n UIImagePickerPresentationStyle,\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-image-picker",
|
|
3
|
-
"version": "14.0
|
|
3
|
+
"version": "14.1.0",
|
|
4
4
|
"description": "Provides access to the system's UI for selecting images and videos from the phone's library or taking a photo with the camera.",
|
|
5
5
|
"main": "build/ImagePicker.js",
|
|
6
6
|
"types": "build/ImagePicker.d.ts",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"expo": "*"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "4fd9d5705d4e8bcab1d13c5be4a006a72d142953"
|
|
48
48
|
}
|
package/src/ImagePicker.ts
CHANGED
|
@@ -71,7 +71,7 @@ const DEPRECATED_RESULT_KEYS = [
|
|
|
71
71
|
'fileSize',
|
|
72
72
|
];
|
|
73
73
|
function mergeDeprecatedResult(result: ImagePickerResult): ImagePickerResult {
|
|
74
|
-
const firstAsset = result
|
|
74
|
+
const firstAsset = result?.assets?.[0];
|
|
75
75
|
const deprecatedResult = {
|
|
76
76
|
...result,
|
|
77
77
|
get cancelled() {
|