expo-media-library 18.3.0-canary-20250930-9dc59d3 → 18.3.0-canary-20251003-7b9d7ff
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 +1 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/medialibrary/next/MediaLibraryNextModule.kt +10 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/Asset.kt +8 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/ExifTags.kt +135 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/delegates/AssetDelegate.kt +4 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/delegates/AssetLegacyDelegate.kt +35 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/delegates/AssetModernDelegate.kt +36 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/deleters/AssetModernDeleter.kt +3 -0
- package/android/src/main/java/expo/modules/medialibrary/next/records/Location.kt +9 -0
- package/build/next/types/Asset.d.ts +17 -0
- package/build/next/types/Asset.d.ts.map +1 -1
- package/build/next/types/Asset.js.map +1 -1
- package/build/next/types/Location.d.ts +5 -0
- package/build/next/types/Location.d.ts.map +1 -0
- package/build/next/types/Location.js +2 -0
- package/build/next/types/Location.js.map +1 -0
- package/expo-module.config.json +1 -1
- package/ios/next/MediaLibraryNextModule.swift +8 -0
- package/ios/next/exceptions/Exceptions.swift +6 -0
- package/ios/next/objects/asset/Asset.swift +24 -21
- package/ios/next/objects/asset/Location.swift +13 -0
- package/ios/next/objects/asset/UriExtractor.swift +86 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/{18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3-sources.jar → 18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar} +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/{18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.module → 18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module} +22 -22
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/{18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.pom → 18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml +4 -4
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.sha512 +1 -1
- package/package.json +3 -3
- package/src/next/types/Asset.ts +17 -0
- package/src/next/types/Location.ts +4 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3-sources.jar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3-sources.jar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3-sources.jar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3-sources.jar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
### 🎉 New features
|
|
8
8
|
|
|
9
|
+
- [next] Add exif support ([#39992](https://github.com/expo/expo/pull/39992) by [@Wenszel](https://github.com/Wenszel))
|
|
9
10
|
- [next] Add `Album.get(title)` ([#39717](https://github.com/expo/expo/pull/39717) by [@Wenszel](https://github.com/Wenszel))
|
|
10
11
|
|
|
11
12
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -4,13 +4,13 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'host.exp.exponent'
|
|
7
|
-
version = '18.3.0-canary-
|
|
7
|
+
version = '18.3.0-canary-20251003-7b9d7ff'
|
|
8
8
|
|
|
9
9
|
android {
|
|
10
10
|
namespace "expo.modules.medialibrary"
|
|
11
11
|
defaultConfig {
|
|
12
12
|
versionCode 37
|
|
13
|
-
versionName "18.3.0-canary-
|
|
13
|
+
versionName "18.3.0-canary-20251003-7b9d7ff"
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -92,6 +92,16 @@ class MediaLibraryNextModule : Module() {
|
|
|
92
92
|
self.getDuration()
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
AsyncFunction("getExif") Coroutine { self: Asset ->
|
|
96
|
+
systemPermissionsDelegate.requireSystemPermissions(false)
|
|
97
|
+
self.getExif()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
AsyncFunction("getLocation") Coroutine { self: Asset ->
|
|
101
|
+
systemPermissionsDelegate.requireSystemPermissions(false)
|
|
102
|
+
self.getLocation()
|
|
103
|
+
}
|
|
104
|
+
|
|
95
105
|
AsyncFunction("getFilename") Coroutine { self: Asset ->
|
|
96
106
|
systemPermissionsDelegate.requireSystemPermissions(false)
|
|
97
107
|
self.getFilename()
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
package expo.modules.medialibrary.next.objects.asset
|
|
2
2
|
|
|
3
3
|
import android.net.Uri
|
|
4
|
+
import android.os.Bundle
|
|
4
5
|
import expo.modules.kotlin.sharedobjects.SharedObject
|
|
5
6
|
import expo.modules.medialibrary.next.objects.asset.delegates.AssetDelegate
|
|
6
7
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
7
8
|
import expo.modules.medialibrary.next.objects.wrappers.MediaType
|
|
8
9
|
import expo.modules.medialibrary.next.objects.wrappers.MimeType
|
|
10
|
+
import expo.modules.medialibrary.next.records.Location
|
|
9
11
|
import kotlinx.coroutines.Dispatchers
|
|
10
12
|
import kotlinx.coroutines.withContext
|
|
11
13
|
|
|
@@ -39,6 +41,12 @@ class Asset(val assetDelegate: AssetDelegate) : SharedObject() {
|
|
|
39
41
|
suspend fun getMimeType(): MimeType =
|
|
40
42
|
assetDelegate.getMimeType()
|
|
41
43
|
|
|
44
|
+
suspend fun getLocation(): Location? =
|
|
45
|
+
assetDelegate.getLocation()
|
|
46
|
+
|
|
47
|
+
suspend fun getExif(): Bundle =
|
|
48
|
+
assetDelegate.getExif()
|
|
49
|
+
|
|
42
50
|
suspend fun move(relativePath: RelativePath) = withContext(Dispatchers.IO) {
|
|
43
51
|
assetDelegate.move(relativePath)
|
|
44
52
|
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
package expo.modules.medialibrary.next.objects.asset
|
|
2
|
+
|
|
3
|
+
import androidx.exifinterface.media.ExifInterface
|
|
4
|
+
|
|
5
|
+
val EXIF_TAGS = arrayOf(
|
|
6
|
+
arrayOf("string", ExifInterface.TAG_ARTIST),
|
|
7
|
+
arrayOf("int", ExifInterface.TAG_BITS_PER_SAMPLE),
|
|
8
|
+
arrayOf("int", ExifInterface.TAG_COMPRESSION),
|
|
9
|
+
arrayOf("string", ExifInterface.TAG_COPYRIGHT),
|
|
10
|
+
arrayOf("string", ExifInterface.TAG_DATETIME),
|
|
11
|
+
arrayOf("string", ExifInterface.TAG_IMAGE_DESCRIPTION),
|
|
12
|
+
arrayOf("int", ExifInterface.TAG_IMAGE_LENGTH),
|
|
13
|
+
arrayOf("int", ExifInterface.TAG_IMAGE_WIDTH),
|
|
14
|
+
arrayOf("int", ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT),
|
|
15
|
+
arrayOf("int", ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH),
|
|
16
|
+
arrayOf("string", ExifInterface.TAG_MAKE),
|
|
17
|
+
arrayOf("string", ExifInterface.TAG_MODEL),
|
|
18
|
+
arrayOf("int", ExifInterface.TAG_ORIENTATION),
|
|
19
|
+
arrayOf("int", ExifInterface.TAG_PHOTOMETRIC_INTERPRETATION),
|
|
20
|
+
arrayOf("int", ExifInterface.TAG_PLANAR_CONFIGURATION),
|
|
21
|
+
arrayOf("double", ExifInterface.TAG_PRIMARY_CHROMATICITIES),
|
|
22
|
+
arrayOf("double", ExifInterface.TAG_REFERENCE_BLACK_WHITE),
|
|
23
|
+
arrayOf("int", ExifInterface.TAG_RESOLUTION_UNIT),
|
|
24
|
+
arrayOf("int", ExifInterface.TAG_ROWS_PER_STRIP),
|
|
25
|
+
arrayOf("int", ExifInterface.TAG_SAMPLES_PER_PIXEL),
|
|
26
|
+
arrayOf("string", ExifInterface.TAG_SOFTWARE),
|
|
27
|
+
arrayOf("int", ExifInterface.TAG_STRIP_BYTE_COUNTS),
|
|
28
|
+
arrayOf("int", ExifInterface.TAG_STRIP_OFFSETS),
|
|
29
|
+
arrayOf("int", ExifInterface.TAG_TRANSFER_FUNCTION),
|
|
30
|
+
arrayOf("double", ExifInterface.TAG_WHITE_POINT),
|
|
31
|
+
arrayOf("double", ExifInterface.TAG_X_RESOLUTION),
|
|
32
|
+
arrayOf("double", ExifInterface.TAG_Y_CB_CR_COEFFICIENTS),
|
|
33
|
+
arrayOf("int", ExifInterface.TAG_Y_CB_CR_POSITIONING),
|
|
34
|
+
arrayOf("int", ExifInterface.TAG_Y_CB_CR_SUB_SAMPLING),
|
|
35
|
+
arrayOf("double", ExifInterface.TAG_Y_RESOLUTION),
|
|
36
|
+
arrayOf("double", ExifInterface.TAG_APERTURE_VALUE),
|
|
37
|
+
arrayOf("double", ExifInterface.TAG_BRIGHTNESS_VALUE),
|
|
38
|
+
arrayOf("string", ExifInterface.TAG_CFA_PATTERN),
|
|
39
|
+
arrayOf("int", ExifInterface.TAG_COLOR_SPACE),
|
|
40
|
+
arrayOf("string", ExifInterface.TAG_COMPONENTS_CONFIGURATION),
|
|
41
|
+
arrayOf("double", ExifInterface.TAG_COMPRESSED_BITS_PER_PIXEL),
|
|
42
|
+
arrayOf("int", ExifInterface.TAG_CONTRAST),
|
|
43
|
+
arrayOf("int", ExifInterface.TAG_CUSTOM_RENDERED),
|
|
44
|
+
arrayOf("string", ExifInterface.TAG_DATETIME_DIGITIZED),
|
|
45
|
+
arrayOf("string", ExifInterface.TAG_DATETIME_ORIGINAL),
|
|
46
|
+
arrayOf("string", ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION),
|
|
47
|
+
arrayOf("double", ExifInterface.TAG_DIGITAL_ZOOM_RATIO),
|
|
48
|
+
arrayOf("string", ExifInterface.TAG_EXIF_VERSION),
|
|
49
|
+
arrayOf("double", ExifInterface.TAG_EXPOSURE_BIAS_VALUE),
|
|
50
|
+
arrayOf("double", ExifInterface.TAG_EXPOSURE_INDEX),
|
|
51
|
+
arrayOf("int", ExifInterface.TAG_EXPOSURE_MODE),
|
|
52
|
+
arrayOf("int", ExifInterface.TAG_EXPOSURE_PROGRAM),
|
|
53
|
+
arrayOf("double", ExifInterface.TAG_EXPOSURE_TIME),
|
|
54
|
+
arrayOf("double", ExifInterface.TAG_F_NUMBER),
|
|
55
|
+
arrayOf("string", ExifInterface.TAG_FILE_SOURCE),
|
|
56
|
+
arrayOf("int", ExifInterface.TAG_FLASH),
|
|
57
|
+
arrayOf("double", ExifInterface.TAG_FLASH_ENERGY),
|
|
58
|
+
arrayOf("string", ExifInterface.TAG_FLASHPIX_VERSION),
|
|
59
|
+
arrayOf("double", ExifInterface.TAG_FOCAL_LENGTH),
|
|
60
|
+
arrayOf("int", ExifInterface.TAG_FOCAL_LENGTH_IN_35MM_FILM),
|
|
61
|
+
arrayOf("int", ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT),
|
|
62
|
+
arrayOf("double", ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION),
|
|
63
|
+
arrayOf("double", ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION),
|
|
64
|
+
arrayOf("int", ExifInterface.TAG_GAIN_CONTROL),
|
|
65
|
+
arrayOf("int", ExifInterface.TAG_ISO_SPEED_RATINGS),
|
|
66
|
+
arrayOf("string", ExifInterface.TAG_IMAGE_UNIQUE_ID),
|
|
67
|
+
arrayOf("int", ExifInterface.TAG_LIGHT_SOURCE),
|
|
68
|
+
arrayOf("string", ExifInterface.TAG_MAKER_NOTE),
|
|
69
|
+
arrayOf("double", ExifInterface.TAG_MAX_APERTURE_VALUE),
|
|
70
|
+
arrayOf("int", ExifInterface.TAG_METERING_MODE),
|
|
71
|
+
arrayOf("int", ExifInterface.TAG_NEW_SUBFILE_TYPE),
|
|
72
|
+
arrayOf("string", ExifInterface.TAG_OECF),
|
|
73
|
+
arrayOf("int", ExifInterface.TAG_PIXEL_X_DIMENSION),
|
|
74
|
+
arrayOf("int", ExifInterface.TAG_PIXEL_Y_DIMENSION),
|
|
75
|
+
arrayOf("string", ExifInterface.TAG_RELATED_SOUND_FILE),
|
|
76
|
+
arrayOf("int", ExifInterface.TAG_SATURATION),
|
|
77
|
+
arrayOf("int", ExifInterface.TAG_SCENE_CAPTURE_TYPE),
|
|
78
|
+
arrayOf("string", ExifInterface.TAG_SCENE_TYPE),
|
|
79
|
+
arrayOf("int", ExifInterface.TAG_SENSING_METHOD),
|
|
80
|
+
arrayOf("int", ExifInterface.TAG_SHARPNESS),
|
|
81
|
+
arrayOf("double", ExifInterface.TAG_SHUTTER_SPEED_VALUE),
|
|
82
|
+
arrayOf("string", ExifInterface.TAG_SPATIAL_FREQUENCY_RESPONSE),
|
|
83
|
+
arrayOf("string", ExifInterface.TAG_SPECTRAL_SENSITIVITY),
|
|
84
|
+
arrayOf("int", ExifInterface.TAG_SUBFILE_TYPE),
|
|
85
|
+
arrayOf("string", ExifInterface.TAG_SUBSEC_TIME),
|
|
86
|
+
arrayOf("string", ExifInterface.TAG_SUBSEC_TIME_DIGITIZED),
|
|
87
|
+
arrayOf("string", ExifInterface.TAG_SUBSEC_TIME_ORIGINAL),
|
|
88
|
+
arrayOf("int", ExifInterface.TAG_SUBJECT_AREA),
|
|
89
|
+
arrayOf("double", ExifInterface.TAG_SUBJECT_DISTANCE),
|
|
90
|
+
arrayOf("int", ExifInterface.TAG_SUBJECT_DISTANCE_RANGE),
|
|
91
|
+
arrayOf("int", ExifInterface.TAG_SUBJECT_LOCATION),
|
|
92
|
+
arrayOf("string", ExifInterface.TAG_USER_COMMENT),
|
|
93
|
+
arrayOf("int", ExifInterface.TAG_WHITE_BALANCE),
|
|
94
|
+
arrayOf("int", ExifInterface.TAG_GPS_ALTITUDE_REF),
|
|
95
|
+
arrayOf("string", ExifInterface.TAG_GPS_AREA_INFORMATION),
|
|
96
|
+
arrayOf("double", ExifInterface.TAG_GPS_DOP),
|
|
97
|
+
arrayOf("string", ExifInterface.TAG_GPS_DATESTAMP),
|
|
98
|
+
arrayOf("double", ExifInterface.TAG_GPS_DEST_BEARING),
|
|
99
|
+
arrayOf("string", ExifInterface.TAG_GPS_DEST_BEARING_REF),
|
|
100
|
+
arrayOf("double", ExifInterface.TAG_GPS_DEST_DISTANCE),
|
|
101
|
+
arrayOf("string", ExifInterface.TAG_GPS_DEST_DISTANCE_REF),
|
|
102
|
+
arrayOf("double", ExifInterface.TAG_GPS_DEST_LATITUDE),
|
|
103
|
+
arrayOf("string", ExifInterface.TAG_GPS_DEST_LATITUDE_REF),
|
|
104
|
+
arrayOf("double", ExifInterface.TAG_GPS_DEST_LONGITUDE),
|
|
105
|
+
arrayOf("string", ExifInterface.TAG_GPS_DEST_LONGITUDE_REF),
|
|
106
|
+
arrayOf("int", ExifInterface.TAG_GPS_DIFFERENTIAL),
|
|
107
|
+
arrayOf("double", ExifInterface.TAG_GPS_IMG_DIRECTION),
|
|
108
|
+
arrayOf("string", ExifInterface.TAG_GPS_IMG_DIRECTION_REF),
|
|
109
|
+
arrayOf("string", ExifInterface.TAG_GPS_LATITUDE_REF),
|
|
110
|
+
arrayOf("string", ExifInterface.TAG_GPS_LONGITUDE_REF),
|
|
111
|
+
arrayOf("string", ExifInterface.TAG_GPS_MAP_DATUM),
|
|
112
|
+
arrayOf("string", ExifInterface.TAG_GPS_MEASURE_MODE),
|
|
113
|
+
arrayOf("string", ExifInterface.TAG_GPS_PROCESSING_METHOD),
|
|
114
|
+
arrayOf("string", ExifInterface.TAG_GPS_SATELLITES),
|
|
115
|
+
arrayOf("double", ExifInterface.TAG_GPS_SPEED),
|
|
116
|
+
arrayOf("string", ExifInterface.TAG_GPS_SPEED_REF),
|
|
117
|
+
arrayOf("string", ExifInterface.TAG_GPS_STATUS),
|
|
118
|
+
arrayOf("string", ExifInterface.TAG_GPS_TIMESTAMP),
|
|
119
|
+
arrayOf("double", ExifInterface.TAG_GPS_TRACK),
|
|
120
|
+
arrayOf("string", ExifInterface.TAG_GPS_TRACK_REF),
|
|
121
|
+
arrayOf("string", ExifInterface.TAG_GPS_VERSION_ID),
|
|
122
|
+
arrayOf("string", ExifInterface.TAG_INTEROPERABILITY_INDEX),
|
|
123
|
+
arrayOf("int", ExifInterface.TAG_THUMBNAIL_IMAGE_LENGTH),
|
|
124
|
+
arrayOf("int", ExifInterface.TAG_THUMBNAIL_IMAGE_WIDTH),
|
|
125
|
+
arrayOf("int", ExifInterface.TAG_DNG_VERSION),
|
|
126
|
+
arrayOf("int", ExifInterface.TAG_DEFAULT_CROP_SIZE),
|
|
127
|
+
arrayOf("int", ExifInterface.TAG_ORF_PREVIEW_IMAGE_START),
|
|
128
|
+
arrayOf("int", ExifInterface.TAG_ORF_PREVIEW_IMAGE_LENGTH),
|
|
129
|
+
arrayOf("int", ExifInterface.TAG_ORF_ASPECT_FRAME),
|
|
130
|
+
arrayOf("int", ExifInterface.TAG_RW2_SENSOR_BOTTOM_BORDER),
|
|
131
|
+
arrayOf("int", ExifInterface.TAG_RW2_SENSOR_LEFT_BORDER),
|
|
132
|
+
arrayOf("int", ExifInterface.TAG_RW2_SENSOR_RIGHT_BORDER),
|
|
133
|
+
arrayOf("int", ExifInterface.TAG_RW2_SENSOR_TOP_BORDER),
|
|
134
|
+
arrayOf("int", ExifInterface.TAG_RW2_ISO)
|
|
135
|
+
)
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
package expo.modules.medialibrary.next.objects.asset.delegates
|
|
2
2
|
|
|
3
3
|
import android.net.Uri
|
|
4
|
+
import android.os.Bundle
|
|
4
5
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
5
6
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
6
7
|
import expo.modules.medialibrary.next.objects.wrappers.MediaType
|
|
7
8
|
import expo.modules.medialibrary.next.objects.wrappers.MimeType
|
|
9
|
+
import expo.modules.medialibrary.next.records.Location
|
|
8
10
|
|
|
9
11
|
interface AssetDelegate {
|
|
10
12
|
val contentUri: Uri
|
|
@@ -17,6 +19,8 @@ interface AssetDelegate {
|
|
|
17
19
|
suspend fun getModificationTime(): Long?
|
|
18
20
|
suspend fun getUri(): Uri
|
|
19
21
|
suspend fun getMimeType(): MimeType
|
|
22
|
+
suspend fun getLocation(): Location?
|
|
23
|
+
suspend fun getExif(): Bundle
|
|
20
24
|
suspend fun delete()
|
|
21
25
|
suspend fun move(relativePath: RelativePath)
|
|
22
26
|
suspend fun copy(relativePath: RelativePath): Asset
|
|
@@ -4,8 +4,10 @@ import android.content.Context
|
|
|
4
4
|
import android.graphics.BitmapFactory
|
|
5
5
|
import android.net.Uri
|
|
6
6
|
import android.os.Build
|
|
7
|
+
import android.os.Bundle
|
|
7
8
|
import androidx.annotation.DeprecatedSinceApi
|
|
8
9
|
import androidx.core.net.toUri
|
|
10
|
+
import androidx.exifinterface.media.ExifInterface
|
|
9
11
|
import expo.modules.medialibrary.MediaLibraryUtils
|
|
10
12
|
import expo.modules.medialibrary.next.exceptions.AssetCouldNotBeCreated
|
|
11
13
|
import expo.modules.medialibrary.next.exceptions.AssetPropertyNotFoundException
|
|
@@ -23,13 +25,18 @@ import expo.modules.medialibrary.next.extensions.safeCopy
|
|
|
23
25
|
import expo.modules.medialibrary.next.extensions.safeMove
|
|
24
26
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
25
27
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
28
|
+
import expo.modules.medialibrary.next.objects.asset.EXIF_TAGS
|
|
26
29
|
import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
|
|
27
30
|
import expo.modules.medialibrary.next.objects.wrappers.MediaType
|
|
28
31
|
import expo.modules.medialibrary.next.objects.wrappers.MimeType
|
|
32
|
+
import expo.modules.medialibrary.next.records.Location
|
|
29
33
|
import kotlinx.coroutines.Dispatchers
|
|
34
|
+
import kotlinx.coroutines.ensureActive
|
|
30
35
|
import kotlinx.coroutines.withContext
|
|
31
36
|
import java.io.File
|
|
32
37
|
import java.lang.ref.WeakReference
|
|
38
|
+
import kotlin.collections.component1
|
|
39
|
+
import kotlin.collections.component2
|
|
33
40
|
import kotlin.time.DurationUnit
|
|
34
41
|
import kotlin.time.toDuration
|
|
35
42
|
|
|
@@ -114,6 +121,34 @@ class AssetLegacyDelegate(
|
|
|
114
121
|
?: MimeType.from(getUri())
|
|
115
122
|
}
|
|
116
123
|
|
|
124
|
+
override suspend fun getLocation(): Location? =
|
|
125
|
+
contentResolver.openInputStream(contentUri)?.use { stream ->
|
|
126
|
+
ExifInterface(stream)
|
|
127
|
+
.latLong
|
|
128
|
+
?.let { (lat, long) -> Location(lat, long) }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
override suspend fun getExif(): Bundle = withContext(Dispatchers.IO) {
|
|
132
|
+
if (getMediaType() != MediaType.IMAGE) {
|
|
133
|
+
return@withContext Bundle()
|
|
134
|
+
}
|
|
135
|
+
val exifBundle = Bundle()
|
|
136
|
+
contentResolver.openInputStream(contentUri)?.use { stream ->
|
|
137
|
+
ensureActive()
|
|
138
|
+
val exifInterface = ExifInterface(stream)
|
|
139
|
+
for ((type, name) in EXIF_TAGS) {
|
|
140
|
+
if (exifInterface.getAttribute(name) != null) {
|
|
141
|
+
when (type) {
|
|
142
|
+
"string" -> exifBundle.putString(name, exifInterface.getAttribute(name))
|
|
143
|
+
"int" -> exifBundle.putInt(name, exifInterface.getAttributeInt(name, 0))
|
|
144
|
+
"double" -> exifBundle.putDouble(name, exifInterface.getAttributeDouble(name, 0.0))
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return@withContext exifBundle
|
|
150
|
+
}
|
|
151
|
+
|
|
117
152
|
override suspend fun delete(): Unit = withContext(Dispatchers.IO) {
|
|
118
153
|
assetDeleter.delete(contentUri)
|
|
119
154
|
}
|
|
@@ -2,8 +2,10 @@ package expo.modules.medialibrary.next.objects.asset.delegates
|
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
4
|
import android.graphics.BitmapFactory
|
|
5
|
+
import androidx.exifinterface.media.ExifInterface
|
|
5
6
|
import android.net.Uri
|
|
6
7
|
import android.os.Build
|
|
8
|
+
import android.os.Bundle
|
|
7
9
|
import androidx.annotation.RequiresApi
|
|
8
10
|
import androidx.core.net.toUri
|
|
9
11
|
import expo.modules.medialibrary.next.exceptions.AssetPropertyNotFoundException
|
|
@@ -22,13 +24,19 @@ import expo.modules.medialibrary.next.extensions.resolver.queryAssetCreationTime
|
|
|
22
24
|
import expo.modules.medialibrary.next.extensions.resolver.updateRelativePath
|
|
23
25
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
24
26
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
27
|
+
import expo.modules.medialibrary.next.objects.asset.EXIF_TAGS
|
|
25
28
|
import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
|
|
26
29
|
import expo.modules.medialibrary.next.objects.wrappers.MediaType
|
|
27
30
|
import expo.modules.medialibrary.next.objects.wrappers.MimeType
|
|
31
|
+
import expo.modules.medialibrary.next.records.Location
|
|
28
32
|
import kotlinx.coroutines.Dispatchers
|
|
33
|
+
import kotlinx.coroutines.ensureActive
|
|
29
34
|
import kotlinx.coroutines.withContext
|
|
30
35
|
import java.io.File
|
|
31
36
|
import java.lang.ref.WeakReference
|
|
37
|
+
import kotlin.collections.component1
|
|
38
|
+
import kotlin.collections.component2
|
|
39
|
+
import kotlin.let
|
|
32
40
|
import kotlin.time.DurationUnit
|
|
33
41
|
import kotlin.time.toDuration
|
|
34
42
|
|
|
@@ -114,6 +122,34 @@ class AssetModernDelegate(
|
|
|
114
122
|
?: MimeType.from(getUri())
|
|
115
123
|
}
|
|
116
124
|
|
|
125
|
+
override suspend fun getLocation(): Location? =
|
|
126
|
+
contentResolver.openInputStream(contentUri)?.use { stream ->
|
|
127
|
+
ExifInterface(stream)
|
|
128
|
+
.latLong
|
|
129
|
+
?.let { (lat, long) -> Location(lat, long) }
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
override suspend fun getExif(): Bundle = withContext(Dispatchers.IO) {
|
|
133
|
+
if (getMediaType() != MediaType.IMAGE) {
|
|
134
|
+
return@withContext Bundle()
|
|
135
|
+
}
|
|
136
|
+
val exifBundle = Bundle()
|
|
137
|
+
contentResolver.openInputStream(contentUri)?.use { stream ->
|
|
138
|
+
ensureActive()
|
|
139
|
+
val exifInterface = ExifInterface(stream)
|
|
140
|
+
for ((type, name) in EXIF_TAGS) {
|
|
141
|
+
if (exifInterface.getAttribute(name) != null) {
|
|
142
|
+
when (type) {
|
|
143
|
+
"string" -> exifBundle.putString(name, exifInterface.getAttribute(name))
|
|
144
|
+
"int" -> exifBundle.putInt(name, exifInterface.getAttributeInt(name, 0))
|
|
145
|
+
"double" -> exifBundle.putDouble(name, exifInterface.getAttributeDouble(name, 0.0))
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return@withContext exifBundle
|
|
151
|
+
}
|
|
152
|
+
|
|
117
153
|
override suspend fun delete() = withContext(Dispatchers.IO) {
|
|
118
154
|
assetDeleter.delete(contentUri)
|
|
119
155
|
}
|
|
@@ -16,6 +16,9 @@ class AssetModernDeleter(
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
override suspend fun delete(contentUris: List<Uri>) = withContext(Dispatchers.IO) {
|
|
19
|
+
if (contentUris.isEmpty()) {
|
|
20
|
+
return@withContext
|
|
21
|
+
}
|
|
19
22
|
mediaStorePermissionsDelegate.launchMediaStoreDeleteRequest(contentUris)
|
|
20
23
|
}
|
|
21
24
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Album } from './Album';
|
|
2
|
+
import { Location } from './Location';
|
|
2
3
|
import { MediaType } from './MediaType';
|
|
3
4
|
/**
|
|
4
5
|
* Represents a single media asset on the device (image, video, or audio).
|
|
@@ -73,6 +74,22 @@ export declare class Asset {
|
|
|
73
74
|
* @throws An exception if the asset could not be found.
|
|
74
75
|
*/
|
|
75
76
|
getWidth(): Promise<number>;
|
|
77
|
+
/**
|
|
78
|
+
* Gets the location of the asset.
|
|
79
|
+
* On Android, this method requires the `ACCESS_MEDIA_LOCATION` permission to access location metadata.
|
|
80
|
+
* @returns A promise resolving to the {@link Location} object or `null` if the location data is unavailable.
|
|
81
|
+
* @throws An exception if the asset could not be found, or if the permission is not granted on Android.
|
|
82
|
+
*/
|
|
83
|
+
getLocation(): Promise<Location | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Gets the exif data of the {@link MediaType.image} asset.
|
|
86
|
+
* On Android, this method requires the `ACCESS_MEDIA_LOCATION` permission to access location metadata.
|
|
87
|
+
* @returns A promise resolving to the exif data object or an empty object if the exif data is unavailable.
|
|
88
|
+
* @throws An exception if the asset could not be found.
|
|
89
|
+
*/
|
|
90
|
+
getExif(): Promise<{
|
|
91
|
+
[key: string]: any;
|
|
92
|
+
}>;
|
|
76
93
|
/**
|
|
77
94
|
* Deletes the asset from the device’s media store.
|
|
78
95
|
* @returns A promise that resolves once the deletion has completed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Asset.d.ts","sourceRoot":"","sources":["../../../src/next/types/Asset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,KAAK;IACxB;;;OAGG;gBACS,EAAE,EAAE,MAAM;IAEtB;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;;;OAIG;IACH,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAEzC;;;;;;OAMG;IACH,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAErC;;;;OAIG;IACH,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAE9B;;;;;OAKG;IACH,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAE5B;;;;OAIG;IACH,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IAElC;;;;OAIG;IACH,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAE7C;;;;;OAKG;IACH,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAEzB;;;;;OAKG;IACH,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAE3B;;;;;;;;OAQG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBvB,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;CAC/D"}
|
|
1
|
+
{"version":3,"file":"Asset.d.ts","sourceRoot":"","sources":["../../../src/next/types/Asset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,KAAK;IACxB;;;OAGG;gBACS,EAAE,EAAE,MAAM;IAEtB;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;;;OAIG;IACH,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAEzC;;;;;;OAMG;IACH,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAErC;;;;OAIG;IACH,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAE9B;;;;;OAKG;IACH,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAE5B;;;;OAIG;IACH,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IAElC;;;;OAIG;IACH,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAE7C;;;;;OAKG;IACH,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAEzB;;;;;OAKG;IACH,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAE3B;;;;;OAKG;IACH,WAAW,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAEvC;;;;;OAKG;IACH,OAAO,IAAI,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IAE1C;;;;;;;;OAQG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBvB,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;CAC/D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Asset.js","sourceRoot":"","sources":["../../../src/next/types/Asset.ts"],"names":[],"mappings":"","sourcesContent":["import { Album } from './Album';\nimport { MediaType } from './MediaType';\n\n/**\n * Represents a single media asset on the device (image, video, or audio).\n *\n * An {@link Asset} instance corresponds to an entry in the device's media store.\n * It exposes metadata (such as filename, dimensions, or creation time) and utility methods (like deleting).\n *\n * To create a new asset, use {@link Asset.create}, if you already have an asset ID, you can instantiate it directly using the constructor.\n */\nexport declare class Asset {\n /**\n * Reinitialize an instance of an asset with a given ID.\n * @param id - For Android, it is a `contentUri` (content://media/external/images/media/12345) and for iOS, it is `PHAsset` localIdentifier URI.\n */\n constructor(id: string);\n\n /**\n * ID of the asset.\n * Can be used to re-instantiate an {@link Asset} later.\n * For android it is a contentUri and PHAsset localIdentifier URI for iOS.\n */\n id: string;\n\n /**\n * Gets the creation time of the asset.\n * @returns A promise resolving to the UNIX timestamp in milliseconds, or `null` if unavailable.\n * @throws An exception if the asset could not be found.\n */\n getCreationTime(): Promise<number | null>;\n\n /**\n * Gets the duration of the asset.\n * Applies only to assets with media type {@link MediaType.audio} or {@link MediaType.video}.\n * For other media types, it returns `null`.\n * @returns A promise resolving to the duration in milliseconds, or `null` if not applicable.\n * @throws An exception if the asset could not be found.\n */\n getDuration(): Promise<number | null>;\n\n /**\n * Gets the filename of the asset, including its extension.\n * @returns A promise resolving to the filename string.\n * @throws An exception if the asset could not be found.\n */\n getFilename(): Promise<string>;\n\n /**\n * Gets the height of the asset in pixels.\n * Only applicable for image and video assets.\n * @returns A promise resolving to the height in pixels.\n * @throws An exception if the filename cannot be found.\n */\n getHeight(): Promise<number>;\n\n /**\n * Gets the media type of the asset (image, video, audio or unknown).\n * @returns A promise resolving to a {@link MediaType} enum value.\n * @throws An exception if the asset could not be found.\n */\n getMediaType(): Promise<MediaType>;\n\n /**\n * Gets the last modification time of the asset.\n * @returns A promise resolving to the UNIX timestamp in milliseconds, or `null` if unavailable.\n * @throws An exception if the asset could not be found.\n */\n getModificationTime(): Promise<number | null>;\n\n /**\n * Gets the URI pointing to the asset’s location in the system.\n * Example, for Android: `file:///storage/emulated/0/DCIM/Camera/IMG_20230915_123456.jpg`.\n * @returns A promise resolving to the string URI.\n * @throws An exception if the asset could not be found.\n */\n getUri(): Promise<string>;\n\n /**\n * Gets the width of the asset in pixels.\n * Only applicable for image and video assets.\n * @returns A promise resolving to the width in pixels.\n * @throws An exception if the asset could not be found.\n */\n getWidth(): Promise<number>;\n\n /**\n * Deletes the asset from the device’s media store.\n * @returns A promise that resolves once the deletion has completed.\n *\n * @example\n * ```ts\n * await asset.delete();\n * ```\n */\n delete(): Promise<void>;\n\n /*\n * A static function. Creates a new asset from a given file path.\n * Optionally associates the asset with an album. On Android, if not specified, the asset will be placed in the default \"Pictures\" directory.\n *\n * @param filePath - Local filesystem path (for example, `file:///...`) of the file to import.\n * @param album - Optional {@link Album} instance to place the asset in.\n * @returns A promise resolving to the created {@link Asset}.\n * @throws An exception if the asset could not be created, for example, if the file does not exist or permission is denied.\n *\n * @example\n * ```ts\n * const asset = await Asset.create(\"file:///storage/emulated/0/DCIM/Camera/IMG_20230915_123456.jpg\");\n * console.log(await asset.getFilename()); // \"IMG_20230915_123456.jpg\"\n * ```\n */\n static create(filePath: string, album?: Album): Promise<Asset>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Asset.js","sourceRoot":"","sources":["../../../src/next/types/Asset.ts"],"names":[],"mappings":"","sourcesContent":["import { Album } from './Album';\nimport { Location } from './Location';\nimport { MediaType } from './MediaType';\n\n/**\n * Represents a single media asset on the device (image, video, or audio).\n *\n * An {@link Asset} instance corresponds to an entry in the device's media store.\n * It exposes metadata (such as filename, dimensions, or creation time) and utility methods (like deleting).\n *\n * To create a new asset, use {@link Asset.create}, if you already have an asset ID, you can instantiate it directly using the constructor.\n */\nexport declare class Asset {\n /**\n * Reinitialize an instance of an asset with a given ID.\n * @param id - For Android, it is a `contentUri` (content://media/external/images/media/12345) and for iOS, it is `PHAsset` localIdentifier URI.\n */\n constructor(id: string);\n\n /**\n * ID of the asset.\n * Can be used to re-instantiate an {@link Asset} later.\n * For android it is a contentUri and PHAsset localIdentifier URI for iOS.\n */\n id: string;\n\n /**\n * Gets the creation time of the asset.\n * @returns A promise resolving to the UNIX timestamp in milliseconds, or `null` if unavailable.\n * @throws An exception if the asset could not be found.\n */\n getCreationTime(): Promise<number | null>;\n\n /**\n * Gets the duration of the asset.\n * Applies only to assets with media type {@link MediaType.audio} or {@link MediaType.video}.\n * For other media types, it returns `null`.\n * @returns A promise resolving to the duration in milliseconds, or `null` if not applicable.\n * @throws An exception if the asset could not be found.\n */\n getDuration(): Promise<number | null>;\n\n /**\n * Gets the filename of the asset, including its extension.\n * @returns A promise resolving to the filename string.\n * @throws An exception if the asset could not be found.\n */\n getFilename(): Promise<string>;\n\n /**\n * Gets the height of the asset in pixels.\n * Only applicable for image and video assets.\n * @returns A promise resolving to the height in pixels.\n * @throws An exception if the filename cannot be found.\n */\n getHeight(): Promise<number>;\n\n /**\n * Gets the media type of the asset (image, video, audio or unknown).\n * @returns A promise resolving to a {@link MediaType} enum value.\n * @throws An exception if the asset could not be found.\n */\n getMediaType(): Promise<MediaType>;\n\n /**\n * Gets the last modification time of the asset.\n * @returns A promise resolving to the UNIX timestamp in milliseconds, or `null` if unavailable.\n * @throws An exception if the asset could not be found.\n */\n getModificationTime(): Promise<number | null>;\n\n /**\n * Gets the URI pointing to the asset’s location in the system.\n * Example, for Android: `file:///storage/emulated/0/DCIM/Camera/IMG_20230915_123456.jpg`.\n * @returns A promise resolving to the string URI.\n * @throws An exception if the asset could not be found.\n */\n getUri(): Promise<string>;\n\n /**\n * Gets the width of the asset in pixels.\n * Only applicable for image and video assets.\n * @returns A promise resolving to the width in pixels.\n * @throws An exception if the asset could not be found.\n */\n getWidth(): Promise<number>;\n\n /**\n * Gets the location of the asset.\n * On Android, this method requires the `ACCESS_MEDIA_LOCATION` permission to access location metadata.\n * @returns A promise resolving to the {@link Location} object or `null` if the location data is unavailable.\n * @throws An exception if the asset could not be found, or if the permission is not granted on Android.\n */\n getLocation(): Promise<Location | null>;\n\n /**\n * Gets the exif data of the {@link MediaType.image} asset.\n * On Android, this method requires the `ACCESS_MEDIA_LOCATION` permission to access location metadata.\n * @returns A promise resolving to the exif data object or an empty object if the exif data is unavailable.\n * @throws An exception if the asset could not be found.\n */\n getExif(): Promise<{ [key: string]: any }>;\n\n /**\n * Deletes the asset from the device’s media store.\n * @returns A promise that resolves once the deletion has completed.\n *\n * @example\n * ```ts\n * await asset.delete();\n * ```\n */\n delete(): Promise<void>;\n\n /*\n * A static function. Creates a new asset from a given file path.\n * Optionally associates the asset with an album. On Android, if not specified, the asset will be placed in the default \"Pictures\" directory.\n *\n * @param filePath - Local filesystem path (for example, `file:///...`) of the file to import.\n * @param album - Optional {@link Album} instance to place the asset in.\n * @returns A promise resolving to the created {@link Asset}.\n * @throws An exception if the asset could not be created, for example, if the file does not exist or permission is denied.\n *\n * @example\n * ```ts\n * const asset = await Asset.create(\"file:///storage/emulated/0/DCIM/Camera/IMG_20230915_123456.jpg\");\n * console.log(await asset.getFilename()); // \"IMG_20230915_123456.jpg\"\n * ```\n */\n static create(filePath: string, album?: Album): Promise<Asset>;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Location.d.ts","sourceRoot":"","sources":["../../../src/next/types/Location.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Location.js","sourceRoot":"","sources":["../../../src/next/types/Location.ts"],"names":[],"mappings":"","sourcesContent":["export type Location = {\n latitude: number;\n longitude: number;\n};\n"]}
|
package/expo-module.config.json
CHANGED
|
@@ -22,6 +22,10 @@ public final class MediaLibraryNextModule: Module {
|
|
|
22
22
|
try await this.getDuration()
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
AsyncFunction("getExif") { (this: Asset) in
|
|
26
|
+
try await this.getExif()
|
|
27
|
+
}
|
|
28
|
+
|
|
25
29
|
AsyncFunction("getFilename") { (this: Asset) in
|
|
26
30
|
try await this.getFilename()
|
|
27
31
|
}
|
|
@@ -38,6 +42,10 @@ public final class MediaLibraryNextModule: Module {
|
|
|
38
42
|
try await this.getModificationTime()
|
|
39
43
|
}
|
|
40
44
|
|
|
45
|
+
AsyncFunction("getLocation") { (this: Asset) in
|
|
46
|
+
try await this.getLocation()
|
|
47
|
+
}
|
|
48
|
+
|
|
41
49
|
AsyncFunction("getUri") { (this: Asset) in
|
|
42
50
|
try await this.getUri()
|
|
43
51
|
}
|
|
@@ -77,3 +77,9 @@ internal final class PredicateBuilderException: GenericException<String> {
|
|
|
77
77
|
"Failed to build a predicate: \(param)"
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
internal final class FailedToExtractUri: GenericException<String> {
|
|
82
|
+
override var reason: String {
|
|
83
|
+
"Failed to extract an uri: \(param)"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -49,6 +49,17 @@ class Asset: SharedObject {
|
|
|
49
49
|
return date.millisecondsSince1970
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
func getLocation() async throws -> Location? {
|
|
53
|
+
let phAsset = try await requirePHAsset()
|
|
54
|
+
guard let clLocation = phAsset.location else {
|
|
55
|
+
return nil
|
|
56
|
+
}
|
|
57
|
+
return Location(
|
|
58
|
+
latitude: clLocation.coordinate.latitude,
|
|
59
|
+
longitude: clLocation.coordinate.longitude
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
52
63
|
func getModificationTime() async throws -> Int? {
|
|
53
64
|
let phAsset = try await requirePHAsset()
|
|
54
65
|
guard let date = phAsset.modificationDate else {
|
|
@@ -62,29 +73,21 @@ class Asset: SharedObject {
|
|
|
62
73
|
return MediaTypeNext.from(phAsset.mediaType)
|
|
63
74
|
}
|
|
64
75
|
|
|
65
|
-
func
|
|
76
|
+
func getExif() async throws -> [String: Any?] {
|
|
66
77
|
let phAsset = try await requirePHAsset()
|
|
78
|
+
guard try await getMediaType() == MediaTypeNext.IMAGE else {
|
|
79
|
+
return [:]
|
|
80
|
+
}
|
|
81
|
+
let uri = try await UriExtractor.extract(from: phAsset)
|
|
82
|
+
guard let ciImage = CIImage(contentsOf: uri) else {
|
|
83
|
+
return [:]
|
|
84
|
+
}
|
|
85
|
+
return ciImage.properties
|
|
86
|
+
}
|
|
67
87
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
guard let url = contentEditingInput.fullSizeImageURL else {
|
|
72
|
-
throw FailedToGetPropertyException("uri")
|
|
73
|
-
}
|
|
74
|
-
return url.absoluteString
|
|
75
|
-
|
|
76
|
-
case PHAssetMediaType.video:
|
|
77
|
-
let options = PHVideoRequestOptions()
|
|
78
|
-
options.version = .original
|
|
79
|
-
guard let avAsset = try await PHImageManager.default()
|
|
80
|
-
.requestAVAsset(forVideo: phAsset, options: options) as? AVURLAsset else {
|
|
81
|
-
throw FailedToGetPropertyException("uri")
|
|
82
|
-
}
|
|
83
|
-
return avAsset.url.absoluteString
|
|
84
|
-
|
|
85
|
-
default:
|
|
86
|
-
throw FailedToGetPropertyException("uri")
|
|
87
|
-
}
|
|
88
|
+
func getUri() async throws -> String {
|
|
89
|
+
let phAsset = try await requirePHAsset()
|
|
90
|
+
return try await UriExtractor.extract(from: phAsset).absoluteString
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
func delete() async throws {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import Photos
|
|
2
|
+
import AVFoundation
|
|
3
|
+
|
|
4
|
+
class UriExtractor {
|
|
5
|
+
static func extract(from phAsset: PHAsset) async throws -> URL {
|
|
6
|
+
switch phAsset.mediaType {
|
|
7
|
+
case .image:
|
|
8
|
+
return try await extract(fromImage: phAsset)
|
|
9
|
+
case .video:
|
|
10
|
+
return try await extract(fromVideo: phAsset)
|
|
11
|
+
default:
|
|
12
|
+
throw FailedToExtractUri("Unsupported media type")
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private static func extract(fromImage phAsset: PHAsset) async throws -> URL {
|
|
17
|
+
let contentEditingInput = try await phAsset.requestContentEditingInput()
|
|
18
|
+
guard let url = contentEditingInput.fullSizeImageURL else {
|
|
19
|
+
throw FailedToExtractUri("Missing fullSizeImageURL for image")
|
|
20
|
+
}
|
|
21
|
+
return url
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private static func extract(fromVideo phAsset: PHAsset) async throws -> URL {
|
|
25
|
+
let options = PHVideoRequestOptions()
|
|
26
|
+
options.version = .original
|
|
27
|
+
let avAsset = try await PHImageManager.default()
|
|
28
|
+
.requestAVAsset(forVideo: phAsset, options: options)
|
|
29
|
+
|
|
30
|
+
if let urlAsset = avAsset as? AVURLAsset {
|
|
31
|
+
return urlAsset.url
|
|
32
|
+
}
|
|
33
|
+
if let composition = avAsset as? AVComposition {
|
|
34
|
+
return try await handleSlowmotionVideo(composition: composition)
|
|
35
|
+
}
|
|
36
|
+
throw FailedToExtractUri("Unsupported AVAsset type")
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private static func handleSlowmotionVideo(composition: AVComposition) async throws -> URL {
|
|
40
|
+
let outputURL = try makeOutputURL()
|
|
41
|
+
let exporter = try makeExporter(for: composition, outputURL: outputURL)
|
|
42
|
+
try await exportVideo(exporter: exporter)
|
|
43
|
+
return outputURL
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private static func makeOutputURL() throws -> URL {
|
|
47
|
+
let directory = FileManager.default.temporaryDirectory
|
|
48
|
+
.appendingPathComponent("MediaLibraryUriExtractorDirectory", isDirectory: true)
|
|
49
|
+
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
|
50
|
+
|
|
51
|
+
let filename = "slowMoVideo-\(UUID().uuidString).mov"
|
|
52
|
+
return directory.appendingPathComponent(filename)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private static func makeExporter(for composition: AVComposition, outputURL: URL) throws -> AVAssetExportSession {
|
|
56
|
+
guard let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) else {
|
|
57
|
+
throw FailedToExtractUri("Failed to create AVAssetExportSession")
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
exporter.outputURL = outputURL
|
|
61
|
+
exporter.outputFileType = .mov
|
|
62
|
+
exporter.shouldOptimizeForNetworkUse = true
|
|
63
|
+
return exporter
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private struct ExporterBox: @unchecked Sendable {
|
|
67
|
+
let exporter: AVAssetExportSession
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private static func exportVideo(exporter: AVAssetExportSession) async throws {
|
|
71
|
+
let box = ExporterBox(exporter: exporter)
|
|
72
|
+
|
|
73
|
+
try await withCheckedThrowingContinuation { continuation in
|
|
74
|
+
box.exporter.exportAsynchronously {
|
|
75
|
+
switch box.exporter.status {
|
|
76
|
+
case .completed:
|
|
77
|
+
continuation.resume()
|
|
78
|
+
case .failed, .cancelled:
|
|
79
|
+
continuation.resume(throwing: box.exporter.error ?? FailedToExtractUri("Slowmotion Export failed"))
|
|
80
|
+
default:
|
|
81
|
+
continuation.resume(throwing: FailedToExtractUri("Unexpected export status: \(box.exporter.status.rawValue)"))
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9190c7184bc2cc0870be71699ef64471
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a3cec26e7891bee7431c766ef8ae4fc8639590f5
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e74b32a8014b50e6c67da261cc7451ac37c463c83ba2b4f7faa1f194be110721
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a96e8cdba38d07a56e757f9fd992faeda0134e7264c184bca2ba813f03af35138f55e33b0db974ee8b342a457f69c9f114c23c1bf3536904781c72b7e3719ca3
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fafd5b66cebedb47896cf16f908e30c6
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9d1e2c3fe0a44b21a707597b54855213a9efe8f5
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dfc16c8348c09598afb661682a9af8626fe5157cf51e75b6bdc615a713be9ecd
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c2783c2c43d94019acd8b10733c8377a22e893b06ab4e5a4c7b7c01ffb4ab8a7211ba1873b7e7aeda7c21fcd321f3432697a92996dfee317d588aa464437d260
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"component": {
|
|
4
4
|
"group": "host.exp.exponent",
|
|
5
5
|
"module": "expo.modules.medialibrary",
|
|
6
|
-
"version": "18.3.0-canary-
|
|
6
|
+
"version": "18.3.0-canary-20251003-7b9d7ff",
|
|
7
7
|
"attributes": {
|
|
8
8
|
"org.gradle.status": "release"
|
|
9
9
|
}
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
],
|
|
34
34
|
"files": [
|
|
35
35
|
{
|
|
36
|
-
"name": "expo.modules.medialibrary-18.3.0-canary-
|
|
37
|
-
"url": "expo.modules.medialibrary-18.3.0-canary-
|
|
38
|
-
"size":
|
|
39
|
-
"sha512": "
|
|
40
|
-
"sha256": "
|
|
41
|
-
"sha1": "
|
|
42
|
-
"md5": "
|
|
36
|
+
"name": "expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar",
|
|
37
|
+
"url": "expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar",
|
|
38
|
+
"size": 560052,
|
|
39
|
+
"sha512": "c2783c2c43d94019acd8b10733c8377a22e893b06ab4e5a4c7b7c01ffb4ab8a7211ba1873b7e7aeda7c21fcd321f3432697a92996dfee317d588aa464437d260",
|
|
40
|
+
"sha256": "dfc16c8348c09598afb661682a9af8626fe5157cf51e75b6bdc615a713be9ecd",
|
|
41
|
+
"sha1": "9d1e2c3fe0a44b21a707597b54855213a9efe8f5",
|
|
42
|
+
"md5": "fafd5b66cebedb47896cf16f908e30c6"
|
|
43
43
|
}
|
|
44
44
|
]
|
|
45
45
|
},
|
|
@@ -83,13 +83,13 @@
|
|
|
83
83
|
],
|
|
84
84
|
"files": [
|
|
85
85
|
{
|
|
86
|
-
"name": "expo.modules.medialibrary-18.3.0-canary-
|
|
87
|
-
"url": "expo.modules.medialibrary-18.3.0-canary-
|
|
88
|
-
"size":
|
|
89
|
-
"sha512": "
|
|
90
|
-
"sha256": "
|
|
91
|
-
"sha1": "
|
|
92
|
-
"md5": "
|
|
86
|
+
"name": "expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar",
|
|
87
|
+
"url": "expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar",
|
|
88
|
+
"size": 560052,
|
|
89
|
+
"sha512": "c2783c2c43d94019acd8b10733c8377a22e893b06ab4e5a4c7b7c01ffb4ab8a7211ba1873b7e7aeda7c21fcd321f3432697a92996dfee317d588aa464437d260",
|
|
90
|
+
"sha256": "dfc16c8348c09598afb661682a9af8626fe5157cf51e75b6bdc615a713be9ecd",
|
|
91
|
+
"sha1": "9d1e2c3fe0a44b21a707597b54855213a9efe8f5",
|
|
92
|
+
"md5": "fafd5b66cebedb47896cf16f908e30c6"
|
|
93
93
|
}
|
|
94
94
|
]
|
|
95
95
|
},
|
|
@@ -103,13 +103,13 @@
|
|
|
103
103
|
},
|
|
104
104
|
"files": [
|
|
105
105
|
{
|
|
106
|
-
"name": "expo.modules.medialibrary-18.3.0-canary-
|
|
107
|
-
"url": "expo.modules.medialibrary-18.3.0-canary-
|
|
108
|
-
"size":
|
|
109
|
-
"sha512": "
|
|
110
|
-
"sha256": "
|
|
111
|
-
"sha1": "
|
|
112
|
-
"md5": "
|
|
106
|
+
"name": "expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar",
|
|
107
|
+
"url": "expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar",
|
|
108
|
+
"size": 76414,
|
|
109
|
+
"sha512": "a96e8cdba38d07a56e757f9fd992faeda0134e7264c184bca2ba813f03af35138f55e33b0db974ee8b342a457f69c9f114c23c1bf3536904781c72b7e3719ca3",
|
|
110
|
+
"sha256": "e74b32a8014b50e6c67da261cc7451ac37c463c83ba2b4f7faa1f194be110721",
|
|
111
|
+
"sha1": "a3cec26e7891bee7431c766ef8ae4fc8639590f5",
|
|
112
|
+
"md5": "9190c7184bc2cc0870be71699ef64471"
|
|
113
113
|
}
|
|
114
114
|
]
|
|
115
115
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c29bbf7d68bc29473bf5fa7896cc6f26
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fa7295bd9faefc5df3a345f02c95697b7516789a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
5d43982c3a8cb50844dc75f9dbb49a0c2b243843f767128546f7472a51608092
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9a1d3594d3c2883e27d7a328becd749e406c16ca735778a1b6c0b3c922dba990b139959a0de980ad0dd16f19cc3802bbf2d4f1d7ea7e2d01d2192a178d04ac5f
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<modelVersion>4.0.0</modelVersion>
|
|
10
10
|
<groupId>host.exp.exponent</groupId>
|
|
11
11
|
<artifactId>expo.modules.medialibrary</artifactId>
|
|
12
|
-
<version>18.3.0-canary-
|
|
12
|
+
<version>18.3.0-canary-20251003-7b9d7ff</version>
|
|
13
13
|
<packaging>aar</packaging>
|
|
14
14
|
<name>expo.modules.medialibrary</name>
|
|
15
15
|
<url>https://github.com/expo/expo</url>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2042f6ee78cd81283e6e13af0c946791
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dc19c676a56e8c0a0e241f7eac40a28b02c23749
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1d0ba0aa1f090e25df1ff9ba093571993a367b6fcdde414dd83bc8cde80f0ed8
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
5535b463919eb77258a0ce8797ccd0d3dca50b58cf35e89b6d4a99bd8ff5318b37e6df8000a51787a658216d19e7be18c503f3ece7ae56658af0b169773c6b57
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<groupId>host.exp.exponent</groupId>
|
|
4
4
|
<artifactId>expo.modules.medialibrary</artifactId>
|
|
5
5
|
<versioning>
|
|
6
|
-
<latest>18.3.0-canary-
|
|
7
|
-
<release>18.3.0-canary-
|
|
6
|
+
<latest>18.3.0-canary-20251003-7b9d7ff</latest>
|
|
7
|
+
<release>18.3.0-canary-20251003-7b9d7ff</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>18.3.0-canary-
|
|
9
|
+
<version>18.3.0-canary-20251003-7b9d7ff</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20251003163125</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
edeb4e0a8650b3c962437aa26db06700
|
package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.sha1
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1969132e8bbd762ca4e1a23ce72465b6d2b74bdf
|
package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
714b65bf56dbf7069722765f42d4a9fc40602575a028380e20f259e6d8a75a46
|
package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.sha512
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
55ba283da3c42c8c4988cb1918f6f2de79e2c82707b666946d1af1253941aad011e3ab5da80ed8e653b02d071822af2afdc78b8f1a6cf47857c2752929ba8398
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-media-library",
|
|
3
|
-
"version": "18.3.0-canary-
|
|
3
|
+
"version": "18.3.0-canary-20251003-7b9d7ff",
|
|
4
4
|
"description": "Provides access to user's media library.",
|
|
5
5
|
"main": "build/MediaLibrary.js",
|
|
6
6
|
"types": "build/MediaLibrary.d.ts",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"preset": "expo-module-scripts"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"expo-module-scripts": "5.0.8-canary-
|
|
41
|
+
"expo-module-scripts": "5.0.8-canary-20251003-7b9d7ff"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"expo": "55.0.0-canary-
|
|
44
|
+
"expo": "55.0.0-canary-20251003-7b9d7ff",
|
|
45
45
|
"react-native": "*"
|
|
46
46
|
},
|
|
47
47
|
"codegenConfig": {
|
package/src/next/types/Asset.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Album } from './Album';
|
|
2
|
+
import { Location } from './Location';
|
|
2
3
|
import { MediaType } from './MediaType';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -84,6 +85,22 @@ export declare class Asset {
|
|
|
84
85
|
*/
|
|
85
86
|
getWidth(): Promise<number>;
|
|
86
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Gets the location of the asset.
|
|
90
|
+
* On Android, this method requires the `ACCESS_MEDIA_LOCATION` permission to access location metadata.
|
|
91
|
+
* @returns A promise resolving to the {@link Location} object or `null` if the location data is unavailable.
|
|
92
|
+
* @throws An exception if the asset could not be found, or if the permission is not granted on Android.
|
|
93
|
+
*/
|
|
94
|
+
getLocation(): Promise<Location | null>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Gets the exif data of the {@link MediaType.image} asset.
|
|
98
|
+
* On Android, this method requires the `ACCESS_MEDIA_LOCATION` permission to access location metadata.
|
|
99
|
+
* @returns A promise resolving to the exif data object or an empty object if the exif data is unavailable.
|
|
100
|
+
* @throws An exception if the asset could not be found.
|
|
101
|
+
*/
|
|
102
|
+
getExif(): Promise<{ [key: string]: any }>;
|
|
103
|
+
|
|
87
104
|
/**
|
|
88
105
|
* Deletes the asset from the device’s media store.
|
|
89
106
|
* @returns A promise that resolves once the deletion has completed.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
956cf3f11a22834fd45c099479659f34
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
bcccebe772325f21a9935321ae969920ab774547
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
745fd3718d10bdbf4207972eca04fb87abb808713ae84644ab08cffac403d0a2
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
934a566095d435efae5715900e23e99408e18221068dca4a32a81381473d4c0239a5cd2256645b14f514cb507e05861971ae7c4f2a086e4a92c17359095026c5
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
d3710df965d39584743b2e04ad0d1810
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
8d2e17f294b33a519aa407e492170dbe4945c9f8
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
39d65da4d8af4706749c26b961765ba04aaad6332bad3a7efcc2ed5a41935023
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
8f89acc1129594801ecfa079599d82cadba212cf1a82f639ca6a5725d1632db0004a91090e1169132304bb8db817942a1fee1ed1d457e00b3a829bc51c8071ff
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b082b799cbc0000683248fbbac691319
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
789464cb85272d02370af0abe931374899218394
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b843f9cd316503e484b7dde6a3acd9bea51df620a66fbbadd2c56ac55fa23c2e
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
65f52213563a4c3e7f0798a43768ce74a13fe1310e0267e6bd22671432e1fde347e43e119d0484726bde0e97862b1d985d0e6f8fe65e63b75d457ec31a582a4c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
5f2665a524f6d626b76e8d7d6233b32d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b458e951281a14482a86271a4a982bb4db121e4b
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
35133e3e93a4ecef1dc9f80583079319ab7de1ffce4ddc2cc158c8ae01d7dbe6
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
909ddf923e911d61392be5129b8b8db267761ae3e2fc3abd2ed19441bab8753907a084525fed4e1ea1e1d9d76ff87d0f7567f29964ba32d0118e8281c6d499b8
|