expo-media-library 18.3.0-canary-20250919-7a31b96 → 18.3.0-canary-20250930-9dc59d3
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 +3 -0
- package/android/build.gradle +6 -6
- package/android/src/main/java/expo/modules/medialibrary/next/MediaLibraryNextModule.kt +27 -18
- package/android/src/main/java/expo/modules/medialibrary/next/extensions/resolver/CursorExtensions.kt +15 -5
- package/android/src/main/java/expo/modules/medialibrary/next/objects/album/Album.kt +16 -17
- package/android/src/main/java/expo/modules/medialibrary/next/objects/album/AlbumQuery.kt +3 -2
- package/android/src/main/java/expo/modules/medialibrary/next/objects/album/factories/AlbumFactory.kt +1 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/album/factories/AlbumLegacyFactory.kt +13 -4
- package/android/src/main/java/expo/modules/medialibrary/next/objects/album/factories/AlbumModernFactory.kt +13 -4
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/Asset.kt +2 -18
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/delegates/AssetLegacyDelegate.kt +9 -9
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/delegates/AssetModernDelegate.kt +10 -4
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/deleters/AssetDeleter.kt +8 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/deleters/AssetLegacyDeleter.kt +46 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/deleters/AssetModernDeleter.kt +21 -0
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/factories/AssetFactory.kt +2 -1
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/factories/AssetLegacyFactory.kt +25 -10
- package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/factories/AssetModernFactory.kt +22 -3
- package/android/src/main/java/expo/modules/medialibrary/next/objects/query/Query.kt +6 -2
- package/android/src/main/java/expo/modules/medialibrary/next/permissions/MediaStorePermissionsDelegate.kt +12 -6
- package/build/next/types/Asset.d.ts +4 -3
- package/build/next/types/Asset.d.ts.map +1 -1
- package/build/next/types/Asset.js.map +1 -1
- package/expo-module.config.json +1 -1
- package/ios/next/MediaLibraryNextModule.swift +7 -7
- package/ios/next/objects/Query/Query.swift +3 -3
- package/ios/next/objects/album/Album.swift +2 -2
- package/ios/next/objects/asset/Asset.swift +12 -5
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/{18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar → 18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3-sources.jar} +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-sources.jar.md5 +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-sources.jar.sha1 +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-sources.jar.sha256 +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-sources.jar.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.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 +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.aar.sha1 +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.aar.sha256 +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.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/{18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module → 18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.module} +27 -27
- 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 +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.sha1 +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.sha256 +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.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/{18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom → 18.3.0-canary-20250930-9dc59d3/expo.modules.medialibrary-18.3.0-canary-20250930-9dc59d3.pom} +4 -4
- 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 +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.sha1 +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.sha256 +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.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 +4 -3
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,11 +10,14 @@
|
|
|
10
10
|
|
|
11
11
|
### 🐛 Bug fixes
|
|
12
12
|
|
|
13
|
+
- [next][iOS] Convert `id` to URI format ([#39920](https://github.com/expo/expo/pull/39920) by [@Wenszel](https://github.com/Wenszel))
|
|
14
|
+
- [next][android] Fix `delete()` throwing security exception ([#39914](https://github.com/expo/expo/pull/39914) by [@Wenszel](https://github.com/Wenszel))
|
|
13
15
|
- [next][android] Change default root directory to Pictures ([#39716](https://github.com/expo/expo/pull/39716) by [@Wenszel](https://github.com/Wenszel))
|
|
14
16
|
- [next] Fix `asset.getModificationTime` to return milliseconds ([#39715](https://github.com/expo/expo/pull/39715) by [@Wenszel](https://github.com/Wenszel))
|
|
15
17
|
|
|
16
18
|
### 💡 Others
|
|
17
19
|
|
|
20
|
+
- [next] Add test screens ([#39951](https://github.com/expo/expo/pull/39951) by [@Wenszel](https://github.com/Wenszel))
|
|
18
21
|
- [next] Add documentation ([#39754](https://github.com/expo/expo/pull/39754) by [@Wenszel](https://github.com/Wenszel))
|
|
19
22
|
|
|
20
23
|
## 18.2.0 — 2025-09-16
|
package/android/build.gradle
CHANGED
|
@@ -4,23 +4,23 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'host.exp.exponent'
|
|
7
|
-
version = '18.3.0-canary-
|
|
7
|
+
version = '18.3.0-canary-20250930-9dc59d3'
|
|
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-20250930-9dc59d3"
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
dependencies {
|
|
18
|
-
implementation "androidx.annotation:annotation:1.
|
|
19
|
-
api "androidx.exifinterface:exifinterface:1.
|
|
20
|
-
implementation 'androidx.activity:activity-ktx:1.
|
|
18
|
+
implementation "androidx.annotation:annotation:1.9.1"
|
|
19
|
+
api "androidx.exifinterface:exifinterface:1.4.1"
|
|
20
|
+
implementation 'androidx.activity:activity-ktx:1.11.0'
|
|
21
21
|
|
|
22
22
|
if (project.findProject(':expo-modules-test-core')) {
|
|
23
23
|
testImplementation project(':expo-modules-test-core')
|
|
24
24
|
}
|
|
25
|
-
testImplementation "org.robolectric:robolectric:4.
|
|
25
|
+
testImplementation "org.robolectric:robolectric:4.16"
|
|
26
26
|
}
|
|
@@ -15,6 +15,8 @@ import expo.modules.medialibrary.next.objects.album.AlbumQuery
|
|
|
15
15
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
16
16
|
import expo.modules.medialibrary.next.objects.album.factories.AlbumModernFactory
|
|
17
17
|
import expo.modules.medialibrary.next.objects.album.factories.AlbumLegacyFactory
|
|
18
|
+
import expo.modules.medialibrary.next.objects.asset.deleters.AssetLegacyDeleter
|
|
19
|
+
import expo.modules.medialibrary.next.objects.asset.deleters.AssetModernDeleter
|
|
18
20
|
import expo.modules.medialibrary.next.objects.asset.factories.AssetModernFactory
|
|
19
21
|
import expo.modules.medialibrary.next.objects.asset.factories.AssetLegacyFactory
|
|
20
22
|
import expo.modules.medialibrary.next.objects.query.MediaStoreQueryFormatter
|
|
@@ -40,22 +42,30 @@ class MediaLibraryNextModule : Module() {
|
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
private val albumQuery by lazy {
|
|
43
|
-
AlbumQuery(context)
|
|
45
|
+
AlbumQuery(albumFactory, context)
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
private val albumFactory by lazy {
|
|
47
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.
|
|
48
|
-
AlbumModernFactory(assetFactory, context)
|
|
49
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
50
|
+
AlbumModernFactory(assetFactory, assetDeleter, context)
|
|
49
51
|
} else {
|
|
50
|
-
AlbumLegacyFactory(assetFactory, context)
|
|
52
|
+
AlbumLegacyFactory(assetFactory, assetDeleter, context)
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
private val assetFactory by lazy {
|
|
55
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.
|
|
56
|
-
AssetModernFactory(context)
|
|
57
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
58
|
+
AssetModernFactory(assetDeleter, context)
|
|
57
59
|
} else {
|
|
58
|
-
AssetLegacyFactory(context)
|
|
60
|
+
AssetLegacyFactory(assetDeleter, context)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private val assetDeleter by lazy {
|
|
65
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
66
|
+
AssetModernDeleter(mediaStorePermissionsDelegate)
|
|
67
|
+
} else {
|
|
68
|
+
AssetLegacyDeleter(context)
|
|
59
69
|
}
|
|
60
70
|
}
|
|
61
71
|
|
|
@@ -64,7 +74,7 @@ class MediaLibraryNextModule : Module() {
|
|
|
64
74
|
|
|
65
75
|
Class(Asset::class) {
|
|
66
76
|
Constructor { contentUri: Uri ->
|
|
67
|
-
|
|
77
|
+
assetFactory.create(contentUri)
|
|
68
78
|
}
|
|
69
79
|
|
|
70
80
|
Property("id") { self: Asset ->
|
|
@@ -114,14 +124,13 @@ class MediaLibraryNextModule : Module() {
|
|
|
114
124
|
|
|
115
125
|
AsyncFunction("delete") Coroutine { self: Asset ->
|
|
116
126
|
systemPermissionsDelegate.requireSystemPermissions(true)
|
|
117
|
-
mediaStorePermissionsDelegate.requestMediaLibraryActionPermission(listOf(self.contentUri), needsDeletePermission = true)
|
|
118
127
|
self.delete()
|
|
119
128
|
}
|
|
120
129
|
}
|
|
121
130
|
|
|
122
131
|
Class(Album::class) {
|
|
123
132
|
Constructor { id: String ->
|
|
124
|
-
Album(id, context)
|
|
133
|
+
Album(id, assetDeleter, assetFactory, context)
|
|
125
134
|
}
|
|
126
135
|
|
|
127
136
|
Property("id") { self: Album ->
|
|
@@ -140,21 +149,19 @@ class MediaLibraryNextModule : Module() {
|
|
|
140
149
|
|
|
141
150
|
AsyncFunction("add") Coroutine { self: Album, asset: Asset ->
|
|
142
151
|
systemPermissionsDelegate.requireSystemPermissions(true)
|
|
143
|
-
mediaStorePermissionsDelegate.
|
|
152
|
+
mediaStorePermissionsDelegate.requestMediaLibraryWritePermission(listOf(asset.contentUri))
|
|
144
153
|
self.add(asset)
|
|
145
154
|
}
|
|
146
155
|
|
|
147
156
|
AsyncFunction("delete") Coroutine { self: Album ->
|
|
148
157
|
systemPermissionsDelegate.requireSystemPermissions(true)
|
|
149
|
-
val assetIdsToDelete = self.getAssets().map { it.contentUri }
|
|
150
|
-
mediaStorePermissionsDelegate.requestMediaLibraryActionPermission(assetIdsToDelete, needsDeletePermission = true)
|
|
151
158
|
self.delete()
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
161
|
|
|
155
162
|
Class(Query::class) {
|
|
156
163
|
Constructor {
|
|
157
|
-
Query(context)
|
|
164
|
+
Query(assetFactory, context)
|
|
158
165
|
}
|
|
159
166
|
|
|
160
167
|
Function("limit") { self: Query, limit: Int ->
|
|
@@ -233,14 +240,16 @@ class MediaLibraryNextModule : Module() {
|
|
|
233
240
|
|
|
234
241
|
AsyncFunction("deleteAlbums") Coroutine { albums: List<Album> ->
|
|
235
242
|
systemPermissionsDelegate.requireSystemPermissions(true)
|
|
236
|
-
|
|
243
|
+
val contentUris = albums
|
|
244
|
+
.map { it.getAssets() }
|
|
245
|
+
.flatten()
|
|
246
|
+
.map { it.contentUri }
|
|
247
|
+
assetDeleter.delete(contentUris)
|
|
237
248
|
}
|
|
238
249
|
|
|
239
250
|
AsyncFunction("deleteAssets") Coroutine { assets: List<Asset> ->
|
|
240
251
|
systemPermissionsDelegate.requireSystemPermissions(true)
|
|
241
|
-
|
|
242
|
-
mediaStorePermissionsDelegate.requestMediaLibraryActionPermission(assetIdsToDelete, needsDeletePermission = true)
|
|
243
|
-
assets.forEach { asset -> asset.delete() }
|
|
252
|
+
assetDeleter.delete(assets.map { it.contentUri })
|
|
244
253
|
}
|
|
245
254
|
|
|
246
255
|
AsyncFunction("requestPermissionsAsync") { writeOnly: Boolean, permissions: List<GranularPermission>?, promise: Promise ->
|
package/android/src/main/java/expo/modules/medialibrary/next/extensions/resolver/CursorExtensions.kt
CHANGED
|
@@ -3,16 +3,26 @@ package expo.modules.medialibrary.next.extensions.resolver
|
|
|
3
3
|
import android.content.ContentUris
|
|
4
4
|
import android.database.Cursor
|
|
5
5
|
import android.net.Uri
|
|
6
|
+
import android.os.Build
|
|
6
7
|
import android.provider.MediaStore
|
|
7
8
|
|
|
8
9
|
fun Cursor.extractAssetContentUri(idColumn: Int, typeColumn: Int): Uri {
|
|
9
10
|
val id = getLong(idColumn)
|
|
10
11
|
val mediaType = getInt(typeColumn)
|
|
11
|
-
val baseUri =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
val baseUri = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
|
|
13
|
+
when (mediaType) {
|
|
14
|
+
MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE -> MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
|
15
|
+
MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO -> MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
|
16
|
+
MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO -> MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
|
17
|
+
else -> MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
when (mediaType) {
|
|
21
|
+
MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
|
22
|
+
MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
|
23
|
+
MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
|
24
|
+
else -> EXTERNAL_CONTENT_URI
|
|
25
|
+
}
|
|
16
26
|
}
|
|
17
27
|
return ContentUris.withAppendedId(baseUri, id)
|
|
18
28
|
}
|
|
@@ -12,14 +12,18 @@ import expo.modules.medialibrary.next.extensions.resolver.queryAlbumFilepath
|
|
|
12
12
|
import expo.modules.medialibrary.next.extensions.resolver.queryAlbumRelativePath
|
|
13
13
|
import expo.modules.medialibrary.next.extensions.resolver.queryAlbumTitle
|
|
14
14
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
15
|
+
import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
|
|
16
|
+
import expo.modules.medialibrary.next.objects.asset.factories.AssetFactory
|
|
15
17
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
16
|
-
import kotlinx.coroutines.async
|
|
17
|
-
import kotlinx.coroutines.awaitAll
|
|
18
|
-
import kotlinx.coroutines.coroutineScope
|
|
19
18
|
import java.io.File
|
|
20
19
|
import java.lang.ref.WeakReference
|
|
21
20
|
|
|
22
|
-
class Album(
|
|
21
|
+
class Album(
|
|
22
|
+
val id: String,
|
|
23
|
+
val assetDeleter: AssetDeleter,
|
|
24
|
+
val assetFactory: AssetFactory,
|
|
25
|
+
context: Context
|
|
26
|
+
) : SharedObject() {
|
|
23
27
|
private val contextRef = WeakReference(context)
|
|
24
28
|
|
|
25
29
|
private val contentResolver
|
|
@@ -51,21 +55,16 @@ class Album(val id: String, context: Context) : SharedObject() {
|
|
|
51
55
|
return RelativePath(relative)
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
suspend fun getAssets(): List<Asset>
|
|
55
|
-
|
|
58
|
+
suspend fun getAssets(): List<Asset> =
|
|
59
|
+
contentResolver
|
|
56
60
|
.queryAlbumAssetsContentUris(id)
|
|
57
|
-
.map {
|
|
58
|
-
}
|
|
61
|
+
.map { assetFactory.create(it) }
|
|
59
62
|
|
|
60
|
-
suspend fun delete() =
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
}.awaitAll()
|
|
66
|
-
}
|
|
63
|
+
suspend fun delete() =
|
|
64
|
+
assetDeleter.delete(
|
|
65
|
+
getAssets().map { it.contentUri }
|
|
66
|
+
)
|
|
67
67
|
|
|
68
|
-
suspend fun add(asset: Asset)
|
|
68
|
+
suspend fun add(asset: Asset) =
|
|
69
69
|
asset.move(getRelativePath())
|
|
70
|
-
}
|
|
71
70
|
}
|
|
@@ -4,9 +4,10 @@ import android.content.Context
|
|
|
4
4
|
import expo.modules.medialibrary.next.exceptions.ContentResolverNotObtainedException
|
|
5
5
|
import expo.modules.medialibrary.next.extensions.getOrThrow
|
|
6
6
|
import expo.modules.medialibrary.next.extensions.resolver.queryAlbumId
|
|
7
|
+
import expo.modules.medialibrary.next.objects.album.factories.AlbumFactory
|
|
7
8
|
import java.lang.ref.WeakReference
|
|
8
9
|
|
|
9
|
-
class AlbumQuery(context: Context) {
|
|
10
|
+
class AlbumQuery(val albumFactory: AlbumFactory, context: Context) {
|
|
10
11
|
private val contextRef = WeakReference(context)
|
|
11
12
|
|
|
12
13
|
private val contentResolver
|
|
@@ -17,6 +18,6 @@ class AlbumQuery(context: Context) {
|
|
|
17
18
|
suspend fun getAlbum(title: String): Album? {
|
|
18
19
|
val id = contentResolver.queryAlbumId(title)
|
|
19
20
|
?: return null
|
|
20
|
-
return
|
|
21
|
+
return albumFactory.create(id)
|
|
21
22
|
}
|
|
22
23
|
}
|
package/android/src/main/java/expo/modules/medialibrary/next/objects/album/factories/AlbumFactory.kt
CHANGED
|
@@ -5,6 +5,7 @@ import expo.modules.medialibrary.next.objects.album.Album
|
|
|
5
5
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
6
6
|
|
|
7
7
|
interface AlbumFactory {
|
|
8
|
+
fun create(id: String): Album
|
|
8
9
|
suspend fun createFromAssets(albumName: String, assets: List<Asset>, deleteOriginalAssets: Boolean): Album
|
|
9
10
|
suspend fun createFromFilePaths(albumName: String, filePaths: List<Uri>): Album
|
|
10
11
|
}
|
|
@@ -12,14 +12,19 @@ import expo.modules.medialibrary.next.extensions.resolver.queryAssetBucketId
|
|
|
12
12
|
import expo.modules.medialibrary.next.objects.album.Album
|
|
13
13
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
14
14
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
15
|
+
import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
|
|
15
16
|
import expo.modules.medialibrary.next.objects.wrappers.MimeType
|
|
16
17
|
import expo.modules.medialibrary.next.objects.asset.factories.AssetFactory
|
|
17
18
|
import java.io.File
|
|
18
19
|
import java.io.IOException
|
|
19
20
|
import java.lang.ref.WeakReference
|
|
20
21
|
|
|
21
|
-
@DeprecatedSinceApi(Build.VERSION_CODES.
|
|
22
|
-
class AlbumLegacyFactory(
|
|
22
|
+
@DeprecatedSinceApi(Build.VERSION_CODES.R)
|
|
23
|
+
class AlbumLegacyFactory(
|
|
24
|
+
private val assetFactory: AssetFactory,
|
|
25
|
+
private val assetDeleter: AssetDeleter,
|
|
26
|
+
context: Context
|
|
27
|
+
) : AlbumFactory {
|
|
23
28
|
private val contextRef = WeakReference(context)
|
|
24
29
|
|
|
25
30
|
private val contentResolver
|
|
@@ -27,6 +32,10 @@ class AlbumLegacyFactory(private val assetFactory: AssetFactory, context: Contex
|
|
|
27
32
|
.getOrThrow()
|
|
28
33
|
.contentResolver ?: throw AlbumCouldNotBeCreated("Failed to create album: ContentResolver is unavailable.")
|
|
29
34
|
|
|
35
|
+
override fun create(id: String): Album {
|
|
36
|
+
return Album(id, assetDeleter, assetFactory, contextRef.getOrThrow())
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
override suspend fun createFromAssets(albumName: String, assets: List<Asset>, deleteOriginalAssets: Boolean): Album {
|
|
31
40
|
try {
|
|
32
41
|
val firstAsset = assets.firstOrNull()
|
|
@@ -37,7 +46,7 @@ class AlbumLegacyFactory(private val assetFactory: AssetFactory, context: Contex
|
|
|
37
46
|
processAssetsLocation(assets, relativePath, true)
|
|
38
47
|
val albumId = contentResolver.queryAssetBucketId(assets[0].contentUri)
|
|
39
48
|
?: throw AlbumNotFoundException("Could not find album with filePath: ${relativePath.toFilePath()}")
|
|
40
|
-
return Album(albumId.toString(), contextRef.getOrThrow())
|
|
49
|
+
return Album(albumId.toString(), assetDeleter, assetFactory, contextRef.getOrThrow())
|
|
41
50
|
} catch (e: SecurityException) {
|
|
42
51
|
throw AlbumCouldNotBeCreated("Missing WRITE_EXTERNAL_STORAGE permission: ${e.message}", e)
|
|
43
52
|
} catch (e: IOException) {
|
|
@@ -55,7 +64,7 @@ class AlbumLegacyFactory(private val assetFactory: AssetFactory, context: Contex
|
|
|
55
64
|
}
|
|
56
65
|
val albumId = contentResolver.queryAssetBucketId(assets[0].contentUri)
|
|
57
66
|
?: throw AlbumCouldNotBeCreated("Could not find album with relativePath: $relativePath")
|
|
58
|
-
return Album(albumId.toString(), contextRef.getOrThrow())
|
|
67
|
+
return Album(albumId.toString(), assetDeleter, assetFactory, contextRef.getOrThrow())
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
private suspend fun processAssetsLocation(assets: List<Asset>, relativePath: RelativePath, deleteOriginalAssets: Boolean) {
|
|
@@ -11,13 +11,18 @@ import expo.modules.medialibrary.next.extensions.resolver.queryAlbumId
|
|
|
11
11
|
import expo.modules.medialibrary.next.objects.album.Album
|
|
12
12
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
13
13
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
14
|
+
import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
|
|
14
15
|
import expo.modules.medialibrary.next.objects.wrappers.MimeType
|
|
15
16
|
import expo.modules.medialibrary.next.objects.asset.factories.AssetFactory
|
|
16
17
|
import java.io.IOException
|
|
17
18
|
import java.lang.ref.WeakReference
|
|
18
19
|
|
|
19
|
-
@RequiresApi(Build.VERSION_CODES.
|
|
20
|
-
class AlbumModernFactory(
|
|
20
|
+
@RequiresApi(Build.VERSION_CODES.R)
|
|
21
|
+
class AlbumModernFactory(
|
|
22
|
+
private val assetFactory: AssetFactory,
|
|
23
|
+
private val assetDeleter: AssetDeleter,
|
|
24
|
+
context: Context
|
|
25
|
+
) : AlbumFactory {
|
|
21
26
|
private val contextRef = WeakReference(context)
|
|
22
27
|
|
|
23
28
|
private val contentResolver
|
|
@@ -25,6 +30,10 @@ class AlbumModernFactory(private val assetFactory: AssetFactory, context: Contex
|
|
|
25
30
|
.getOrThrow()
|
|
26
31
|
.contentResolver ?: throw AlbumCouldNotBeCreated("Failed to create album: ContentResolver is unavailable.")
|
|
27
32
|
|
|
33
|
+
override fun create(id: String): Album {
|
|
34
|
+
return Album(id, assetDeleter, assetFactory, contextRef.getOrThrow())
|
|
35
|
+
}
|
|
36
|
+
|
|
28
37
|
override suspend fun createFromAssets(albumName: String, assets: List<Asset>, deleteOriginalAssets: Boolean): Album =
|
|
29
38
|
try {
|
|
30
39
|
val mimeTypeOfFirstAsset = assets[0].getMimeType()
|
|
@@ -32,7 +41,7 @@ class AlbumModernFactory(private val assetFactory: AssetFactory, context: Contex
|
|
|
32
41
|
processAssetsLocation(assets, albumRelativePath, deleteOriginalAssets)
|
|
33
42
|
val albumId = contentResolver.queryAlbumId(albumRelativePath)
|
|
34
43
|
?: throw AlbumNotFoundException("Could not find album with relativePath: $albumRelativePath")
|
|
35
|
-
Album(albumId, contextRef.getOrThrow())
|
|
44
|
+
Album(albumId, assetDeleter, assetFactory, contextRef.getOrThrow())
|
|
36
45
|
} catch (e: SecurityException) {
|
|
37
46
|
throw AlbumCouldNotBeCreated("Security Exception: ${e.message}", e)
|
|
38
47
|
} catch (e: IOException) {
|
|
@@ -47,7 +56,7 @@ class AlbumModernFactory(private val assetFactory: AssetFactory, context: Contex
|
|
|
47
56
|
}
|
|
48
57
|
val albumId = contentResolver.queryAlbumId(relativePath)
|
|
49
58
|
?: throw AlbumCouldNotBeCreated("Failed to create album: newly created album was not found in the MediaStore.")
|
|
50
|
-
return Album(albumId, contextRef.getOrThrow())
|
|
59
|
+
return Album(albumId, assetDeleter, assetFactory, contextRef.getOrThrow())
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
private suspend fun processAssetsLocation(assets: List<Asset>, relativePath: RelativePath, deleteOriginalAssets: Boolean) {
|
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
package expo.modules.medialibrary.next.objects.asset
|
|
2
2
|
|
|
3
|
-
import android.content.Context
|
|
4
3
|
import android.net.Uri
|
|
5
|
-
import android.os.Build
|
|
6
4
|
import expo.modules.kotlin.sharedobjects.SharedObject
|
|
7
|
-
import expo.modules.medialibrary.next.
|
|
5
|
+
import expo.modules.medialibrary.next.objects.asset.delegates.AssetDelegate
|
|
8
6
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
9
|
-
import expo.modules.medialibrary.next.objects.asset.delegates.AssetLegacyDelegate
|
|
10
|
-
import expo.modules.medialibrary.next.objects.asset.delegates.AssetModernDelegate
|
|
11
7
|
import expo.modules.medialibrary.next.objects.wrappers.MediaType
|
|
12
8
|
import expo.modules.medialibrary.next.objects.wrappers.MimeType
|
|
13
9
|
import kotlinx.coroutines.Dispatchers
|
|
14
10
|
import kotlinx.coroutines.withContext
|
|
15
|
-
import java.lang.ref.WeakReference
|
|
16
|
-
import kotlin.getValue
|
|
17
|
-
|
|
18
|
-
class Asset(contentUri: Uri, context: Context) : SharedObject() {
|
|
19
|
-
private val contextRef = WeakReference(context)
|
|
20
|
-
|
|
21
|
-
val assetDelegate by lazy {
|
|
22
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
23
|
-
AssetModernDelegate(contentUri, contextRef.getOrThrow())
|
|
24
|
-
} else {
|
|
25
|
-
AssetLegacyDelegate(contentUri, contextRef.getOrThrow())
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
11
|
|
|
12
|
+
class Asset(val assetDelegate: AssetDelegate) : SharedObject() {
|
|
29
13
|
val contentUri: Uri get() = assetDelegate.contentUri
|
|
30
14
|
|
|
31
15
|
suspend fun getCreationTime(): Long? =
|
|
@@ -6,7 +6,6 @@ import android.net.Uri
|
|
|
6
6
|
import android.os.Build
|
|
7
7
|
import androidx.annotation.DeprecatedSinceApi
|
|
8
8
|
import androidx.core.net.toUri
|
|
9
|
-
import expo.modules.medialibrary.AssetFileException
|
|
10
9
|
import expo.modules.medialibrary.MediaLibraryUtils
|
|
11
10
|
import expo.modules.medialibrary.next.exceptions.AssetCouldNotBeCreated
|
|
12
11
|
import expo.modules.medialibrary.next.exceptions.AssetPropertyNotFoundException
|
|
@@ -24,6 +23,7 @@ import expo.modules.medialibrary.next.extensions.safeCopy
|
|
|
24
23
|
import expo.modules.medialibrary.next.extensions.safeMove
|
|
25
24
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
26
25
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
26
|
+
import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
|
|
27
27
|
import expo.modules.medialibrary.next.objects.wrappers.MediaType
|
|
28
28
|
import expo.modules.medialibrary.next.objects.wrappers.MimeType
|
|
29
29
|
import kotlinx.coroutines.Dispatchers
|
|
@@ -34,7 +34,11 @@ import kotlin.time.DurationUnit
|
|
|
34
34
|
import kotlin.time.toDuration
|
|
35
35
|
|
|
36
36
|
@DeprecatedSinceApi(Build.VERSION_CODES.Q)
|
|
37
|
-
class AssetLegacyDelegate(
|
|
37
|
+
class AssetLegacyDelegate(
|
|
38
|
+
contentUri: Uri,
|
|
39
|
+
val assetDeleter: AssetDeleter,
|
|
40
|
+
context: Context
|
|
41
|
+
) : AssetDelegate {
|
|
38
42
|
private val contextRef = WeakReference(context)
|
|
39
43
|
|
|
40
44
|
private val contentResolver
|
|
@@ -111,12 +115,7 @@ class AssetLegacyDelegate(contentUri: Uri, context: Context) : AssetDelegate {
|
|
|
111
115
|
}
|
|
112
116
|
|
|
113
117
|
override suspend fun delete(): Unit = withContext(Dispatchers.IO) {
|
|
114
|
-
|
|
115
|
-
?: throw AssetPropertyNotFoundException("Uri")
|
|
116
|
-
if (!File(path).delete()) {
|
|
117
|
-
throw AssetFileException("Could not delete file.")
|
|
118
|
-
}
|
|
119
|
-
contentResolver.delete(contentUri, null, null)
|
|
118
|
+
assetDeleter.delete(contentUri)
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
override suspend fun getUri(): Uri {
|
|
@@ -146,6 +145,7 @@ class AssetLegacyDelegate(contentUri: Uri, context: Context) : AssetDelegate {
|
|
|
146
145
|
if (uri == null) {
|
|
147
146
|
throw AssetCouldNotBeCreated("Could not create a new asset while copying the old one")
|
|
148
147
|
}
|
|
149
|
-
|
|
148
|
+
val newAssetDelegate = AssetLegacyDelegate(contentUri, assetDeleter, contextRef.getOrThrow())
|
|
149
|
+
return@withContext Asset(newAssetDelegate)
|
|
150
150
|
}
|
|
151
151
|
}
|
|
@@ -22,6 +22,7 @@ import expo.modules.medialibrary.next.extensions.resolver.queryAssetCreationTime
|
|
|
22
22
|
import expo.modules.medialibrary.next.extensions.resolver.updateRelativePath
|
|
23
23
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
24
24
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
25
|
+
import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
|
|
25
26
|
import expo.modules.medialibrary.next.objects.wrappers.MediaType
|
|
26
27
|
import expo.modules.medialibrary.next.objects.wrappers.MimeType
|
|
27
28
|
import kotlinx.coroutines.Dispatchers
|
|
@@ -32,7 +33,11 @@ import kotlin.time.DurationUnit
|
|
|
32
33
|
import kotlin.time.toDuration
|
|
33
34
|
|
|
34
35
|
@RequiresApi(Build.VERSION_CODES.Q)
|
|
35
|
-
class AssetModernDelegate(
|
|
36
|
+
class AssetModernDelegate(
|
|
37
|
+
override val contentUri: Uri,
|
|
38
|
+
val assetDeleter: AssetDeleter,
|
|
39
|
+
context: Context
|
|
40
|
+
) : AssetDelegate {
|
|
36
41
|
private val contextRef = WeakReference(context)
|
|
37
42
|
|
|
38
43
|
private val contentResolver
|
|
@@ -109,8 +114,8 @@ class AssetModernDelegate(override val contentUri: Uri, context: Context) : Asse
|
|
|
109
114
|
?: MimeType.from(getUri())
|
|
110
115
|
}
|
|
111
116
|
|
|
112
|
-
override suspend fun delete() {
|
|
113
|
-
|
|
117
|
+
override suspend fun delete() = withContext(Dispatchers.IO) {
|
|
118
|
+
assetDeleter.delete(contentUri)
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
override suspend fun move(relativePath: RelativePath) {
|
|
@@ -121,6 +126,7 @@ class AssetModernDelegate(override val contentUri: Uri, context: Context) : Asse
|
|
|
121
126
|
val newAssetUri = contentResolver.insertPendingAsset(getFilename(), getMimeType(), relativePath)
|
|
122
127
|
contentResolver.copyUriContent(contentUri, newAssetUri)
|
|
123
128
|
contentResolver.publishPendingAsset(newAssetUri)
|
|
124
|
-
|
|
129
|
+
val newAssetDelegate = AssetModernDelegate(newAssetUri, assetDeleter, contextRef.getOrThrow())
|
|
130
|
+
return@withContext Asset(newAssetDelegate)
|
|
125
131
|
}
|
|
126
132
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
package expo.modules.medialibrary.next.objects.asset.deleters
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.net.Uri
|
|
5
|
+
import android.os.Build
|
|
6
|
+
import androidx.annotation.DeprecatedSinceApi
|
|
7
|
+
import expo.modules.medialibrary.AssetFileException
|
|
8
|
+
import expo.modules.medialibrary.next.exceptions.AssetPropertyNotFoundException
|
|
9
|
+
import expo.modules.medialibrary.next.exceptions.ContentResolverNotObtainedException
|
|
10
|
+
import expo.modules.medialibrary.next.extensions.getOrThrow
|
|
11
|
+
import expo.modules.medialibrary.next.extensions.resolver.queryAssetPath
|
|
12
|
+
import kotlinx.coroutines.Dispatchers
|
|
13
|
+
import kotlinx.coroutines.async
|
|
14
|
+
import kotlinx.coroutines.awaitAll
|
|
15
|
+
import kotlinx.coroutines.withContext
|
|
16
|
+
import java.io.File
|
|
17
|
+
import java.lang.ref.WeakReference
|
|
18
|
+
|
|
19
|
+
@DeprecatedSinceApi(Build.VERSION_CODES.Q)
|
|
20
|
+
class AssetLegacyDeleter(context: Context) : AssetDeleter {
|
|
21
|
+
private val contextRef = WeakReference(context)
|
|
22
|
+
|
|
23
|
+
private val contentResolver
|
|
24
|
+
get() = contextRef
|
|
25
|
+
.getOrThrow()
|
|
26
|
+
.contentResolver ?: throw ContentResolverNotObtainedException()
|
|
27
|
+
|
|
28
|
+
override suspend fun delete(contentUri: Uri): Unit = withContext(Dispatchers.IO) {
|
|
29
|
+
val path = contentResolver.queryAssetPath(contentUri)
|
|
30
|
+
?: throw AssetPropertyNotFoundException("Uri")
|
|
31
|
+
if (!File(path).delete()) {
|
|
32
|
+
throw AssetFileException("Could not delete a file.")
|
|
33
|
+
}
|
|
34
|
+
contentResolver.delete(contentUri, null, null)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override suspend fun delete(contentUris: List<Uri>): Unit = withContext(Dispatchers.IO) {
|
|
38
|
+
contentUris.map { uri ->
|
|
39
|
+
async {
|
|
40
|
+
runCatching {
|
|
41
|
+
delete(uri)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}.awaitAll()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package expo.modules.medialibrary.next.objects.asset.deleters
|
|
2
|
+
|
|
3
|
+
import android.net.Uri
|
|
4
|
+
import android.os.Build
|
|
5
|
+
import androidx.annotation.RequiresApi
|
|
6
|
+
import expo.modules.medialibrary.next.permissions.MediaStorePermissionsDelegate
|
|
7
|
+
import kotlinx.coroutines.Dispatchers
|
|
8
|
+
import kotlinx.coroutines.withContext
|
|
9
|
+
|
|
10
|
+
@RequiresApi(Build.VERSION_CODES.R)
|
|
11
|
+
class AssetModernDeleter(
|
|
12
|
+
val mediaStorePermissionsDelegate: MediaStorePermissionsDelegate
|
|
13
|
+
) : AssetDeleter {
|
|
14
|
+
override suspend fun delete(contentUri: Uri) = withContext(Dispatchers.IO) {
|
|
15
|
+
mediaStorePermissionsDelegate.launchMediaStoreDeleteRequest(listOf(contentUri))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
override suspend fun delete(contentUris: List<Uri>) = withContext(Dispatchers.IO) {
|
|
19
|
+
mediaStorePermissionsDelegate.launchMediaStoreDeleteRequest(contentUris)
|
|
20
|
+
}
|
|
21
|
+
}
|
package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/factories/AssetFactory.kt
CHANGED
|
@@ -4,6 +4,7 @@ import android.net.Uri
|
|
|
4
4
|
import expo.modules.medialibrary.next.objects.wrappers.RelativePath
|
|
5
5
|
import expo.modules.medialibrary.next.objects.asset.Asset
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
interface AssetFactory {
|
|
8
|
+
fun create(contentUri: Uri): Asset
|
|
8
9
|
suspend fun create(filePath: Uri, relativePath: RelativePath?): Asset
|
|
9
10
|
}
|