expo-image 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/android/build.gradle +13 -83
- package/android/src/main/java/expo/modules/image/CustomDownsampleStrategy.kt +19 -0
- package/android/src/main/java/expo/modules/image/Exceptions.kt +0 -3
- package/android/src/main/java/expo/modules/image/ExpoImageComponentCallbacks.kt +22 -0
- package/android/src/main/java/expo/modules/image/ExpoImageModule.kt +27 -30
- package/android/src/main/java/expo/modules/image/ExpoImageView.kt +11 -4
- package/android/src/main/java/expo/modules/image/ExpoImageViewWrapper.kt +20 -33
- package/android/src/main/java/expo/modules/image/GlideExtensions.kt +56 -0
- package/android/src/main/java/expo/modules/image/ImageUtils.kt +0 -8
- package/android/src/main/java/expo/modules/image/ImageViewWrapperTarget.kt +10 -0
- package/android/src/main/java/expo/modules/image/ResourceIdHelper.kt +1 -1
- package/android/src/main/java/expo/modules/image/enums/ImageCacheType.kt +1 -1
- package/android/src/main/java/expo/modules/image/records/SourceMap.kt +8 -8
- package/build/ExpoImage.d.ts.map +1 -1
- package/build/ExpoImage.js.map +1 -1
- package/build/ExpoImage.web.d.ts +1 -1
- package/build/ExpoImage.web.d.ts.map +1 -1
- package/build/ExpoImage.web.js +3 -2
- package/build/ExpoImage.web.js.map +1 -1
- package/build/Image.d.ts +15 -3
- package/build/Image.d.ts.map +1 -1
- package/build/Image.js +15 -14
- package/build/Image.js.map +1 -1
- package/build/Image.types.d.ts +11 -0
- package/build/Image.types.d.ts.map +1 -1
- package/build/Image.types.js.map +1 -1
- package/build/utils/AssetSourceResolver.web.js.map +1 -1
- package/build/utils/blurhash/base83.js.map +1 -1
- package/build/utils/blurhash/decode.js.map +1 -1
- package/build/utils/blurhash/useBlurhash.js.map +1 -1
- package/build/utils/blurhash/utils.js.map +1 -1
- package/build/utils/resolveAssetSource.web.js.map +1 -1
- package/build/utils/resolveSources.js +1 -1
- package/build/utils/resolveSources.js.map +1 -1
- package/build/utils/thumbhash/thumbhash.js.map +1 -1
- package/build/utils.js.map +1 -1
- package/build/web/AnimationManager.js.map +1 -1
- package/build/web/ColorTintFilter.js.map +1 -1
- package/build/web/ImageWrapper.js.map +1 -1
- package/build/web/getImageWrapperEventHandler.js.map +1 -1
- package/build/web/hooks.js.map +1 -1
- package/build/web/imageStyles.js +1 -1
- package/build/web/imageStyles.js.map +1 -1
- package/build/web/positioning.js.map +1 -1
- package/build/web/useSourceSelection.d.ts +2 -6
- package/build/web/useSourceSelection.d.ts.map +1 -1
- package/build/web/useSourceSelection.js +16 -27
- package/build/web/useSourceSelection.js.map +1 -1
- package/ios/ExpoImage.podspec +3 -3
- package/ios/ImageModule.swift +11 -3
- package/ios/ImageView.swift +39 -4
- package/package.json +3 -3
- package/src/ExpoImage.web.tsx +4 -2
- package/src/Image.tsx +34 -5
- package/src/Image.types.ts +13 -0
- package/src/utils/resolveSources.tsx +1 -1
- package/src/web/imageStyles.tsx +1 -1
- package/src/web/useSourceSelection.ts +27 -49
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,29 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 1.12.0 — 2024-04-18
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- On `iOS`, support loading assets in the native project. This already worked on android. ([#27251](https://github.com/expo/expo/pull/27251) by [@alanjhughes](https://github.com/alanjhughes))
|
|
18
|
+
- Support prefetching images with HTTP headers. ([#28133](https://github.com/expo/expo/pull/28133) by [@toy0605](https://github.com/toy0605))
|
|
19
|
+
|
|
20
|
+
### 🐛 Bug fixes
|
|
21
|
+
|
|
22
|
+
- Refactor web implementations of `useSourceSelection` to avoid unnecessary rerenders. ([#27569](https://github.com/expo/expo/pull/27569) by [@aleqsio](https://github.com/aleqsio))
|
|
23
|
+
- Fixed an issue where `isBlurhashString` always returned `true` .([#27251](https://github.com/expo/expo/pull/27251) by [@alanjhughes](https://github.com/alanjhughes))
|
|
24
|
+
- Fix #available check to account for tvOS. ([#27272](https://github.com/expo/expo/pull/27272) by [@alanjhughes](https://github.com/alanjhughes))
|
|
25
|
+
- Fixed jest may cause `RangeError: Invalid string length` error when generating a snapshot. ([#27354](https://github.com/expo/expo/pull/27354) by [@lukmccall](https://github.com/lukmccall))
|
|
26
|
+
- Fixed placeholders weren't correctly scaled down on the Android. ([#28255](https://github.com/expo/expo/pull/28255) by [@lukmccall](https://github.com/lukmccall))
|
|
27
|
+
|
|
28
|
+
### 💡 Others
|
|
29
|
+
|
|
30
|
+
- [iOS] Bump SDWebImage to `5.19.1` to include the 3rd-party privacy manifest. ([#27874](https://github.com/expo/expo/pull/27874) by [@aparedes](https://github.com/aparedes), []() by [@tsapeta](https://github.com/tsapeta))
|
|
31
|
+
- Use `typeof window` checks for removing server code. ([#27514](https://github.com/expo/expo/pull/27514) by [@EvanBacon](https://github.com/EvanBacon))
|
|
32
|
+
- Removed deprecated backward compatible Gradle settings. ([#28083](https://github.com/expo/expo/pull/28083) by [@kudo](https://github.com/kudo))
|
|
33
|
+
- [iOS] Bump SDWebImageWebPCoder to `0.14.6`. ([#28273](https://github.com/expo/expo/pull/28273) by [@alanjhughes](https://github.com/alanjhughes))
|
|
34
|
+
- Automatically clean blurhash cache when the app's memory is running low. ([#28276](https://github.com/expo/expo/pull/28276) by [@lukmccall](https://github.com/lukmccall))
|
|
35
|
+
|
|
13
36
|
## 1.11.0 — 2024-02-05
|
|
14
37
|
|
|
15
38
|
### 🎉 New features
|
package/android/build.gradle
CHANGED
|
@@ -1,113 +1,43 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
|
-
apply plugin: 'kotlin-android'
|
|
3
|
-
apply plugin: 'maven-publish'
|
|
4
2
|
apply plugin: 'kotlin-kapt'
|
|
5
3
|
|
|
6
4
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
12
|
-
useCoreDependencies()
|
|
13
|
-
}
|
|
14
|
-
}
|
|
5
|
+
apply from: expoModulesCorePlugin
|
|
6
|
+
applyKotlinExpoModulesCorePlugin()
|
|
7
|
+
useCoreDependencies()
|
|
8
|
+
useDefaultAndroidSdkVersions()
|
|
15
9
|
|
|
16
10
|
buildscript {
|
|
17
11
|
// Simple helper that allows the root project to override versions declared by this library.
|
|
18
12
|
ext.safeExtGet = { prop, fallback ->
|
|
19
13
|
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
20
14
|
}
|
|
21
|
-
|
|
22
|
-
// Ensures backward compatibility
|
|
23
|
-
ext.getKotlinVersion = {
|
|
24
|
-
if (ext.has("kotlinVersion")) {
|
|
25
|
-
ext.kotlinVersion()
|
|
26
|
-
} else {
|
|
27
|
-
ext.safeExtGet("kotlinVersion", "1.8.10")
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
repositories {
|
|
32
|
-
mavenCentral()
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
dependencies {
|
|
36
|
-
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
|
|
37
|
-
}
|
|
38
15
|
}
|
|
39
16
|
|
|
40
17
|
android {
|
|
41
|
-
// Remove this if and it's contents, when support for SDK49 is dropped
|
|
42
|
-
if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
43
|
-
compileSdkVersion safeExtGet("compileSdkVersion", 34)
|
|
44
|
-
|
|
45
|
-
defaultConfig {
|
|
46
|
-
minSdkVersion safeExtGet("minSdkVersion", 23)
|
|
47
|
-
targetSdkVersion safeExtGet("targetSdkVersion", 34)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
lintOptions {
|
|
51
|
-
abortOnError false
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
|
|
56
|
-
if (agpVersion.tokenize('.')[0].toInteger() < 8) {
|
|
57
|
-
compileOptions {
|
|
58
|
-
sourceCompatibility JavaVersion.VERSION_11
|
|
59
|
-
targetCompatibility JavaVersion.VERSION_11
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
kotlinOptions {
|
|
63
|
-
jvmTarget = JavaVersion.VERSION_11.majorVersion
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
18
|
namespace "expo.modules.image"
|
|
68
19
|
defaultConfig {
|
|
69
20
|
versionCode 1
|
|
70
|
-
versionName "1.
|
|
21
|
+
versionName "1.12.0"
|
|
71
22
|
consumerProguardFiles("proguard-rules.pro")
|
|
72
23
|
|
|
73
24
|
buildConfigField("boolean", "ALLOW_GLIDE_LOGS", project.properties.get("EXPO_ALLOW_GLIDE_LOGS", "false"))
|
|
74
25
|
}
|
|
75
|
-
publishing {
|
|
76
|
-
singleVariant("release") {
|
|
77
|
-
withSourcesJar()
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
26
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
mavenLocal()
|
|
91
|
-
maven {
|
|
92
|
-
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
|
93
|
-
url "$rootDir/../node_modules/react-native/android"
|
|
94
|
-
}
|
|
95
|
-
maven {
|
|
96
|
-
// Android JSC is installed from npm
|
|
97
|
-
url "$rootDir/../node_modules/jsc-android/dist"
|
|
27
|
+
sourceSets {
|
|
28
|
+
main {
|
|
29
|
+
java {
|
|
30
|
+
if (safeExtGet("excludeAppGlideModule", false)) {
|
|
31
|
+
exclude("**/ExpoImageAppGlideModule.kt")
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
98
35
|
}
|
|
99
|
-
google()
|
|
100
|
-
mavenCentral()
|
|
101
36
|
}
|
|
102
37
|
|
|
103
38
|
dependencies {
|
|
104
39
|
def GLIDE_VERSION = "4.13.2"
|
|
105
40
|
|
|
106
|
-
if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
107
|
-
implementation project(':expo-modules-core')
|
|
108
|
-
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
|
|
109
|
-
}
|
|
110
|
-
|
|
111
41
|
implementation 'com.facebook.react:react-android'
|
|
112
42
|
|
|
113
43
|
api "com.github.bumptech.glide:glide:${GLIDE_VERSION}"
|
|
@@ -44,6 +44,25 @@ object NoopDownsampleStrategy : DownsampleStrategy() {
|
|
|
44
44
|
): SampleSizeRounding = SampleSizeRounding.QUALITY
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
class PlaceholderDownsampleStrategy(
|
|
48
|
+
private val target: ImageViewWrapperTarget
|
|
49
|
+
) : CustomDownsampleStrategy() {
|
|
50
|
+
private var wasTriggered = false
|
|
51
|
+
|
|
52
|
+
override fun getScaleFactor(sourceWidth: Int, sourceHeight: Int, requestedWidth: Int, requestedHeight: Int): Float {
|
|
53
|
+
if (!wasTriggered) {
|
|
54
|
+
target.placeholderWidth = sourceWidth
|
|
55
|
+
target.placeholderHeight = sourceHeight
|
|
56
|
+
wasTriggered = true
|
|
57
|
+
}
|
|
58
|
+
return 1f
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override fun getSampleSizeRounding(sourceWidth: Int, sourceHeight: Int, requestedWidth: Int, requestedHeight: Int): SampleSizeRounding {
|
|
62
|
+
return SampleSizeRounding.QUALITY
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
47
66
|
class ContentFitDownsampleStrategy(
|
|
48
67
|
private val target: ImageViewWrapperTarget,
|
|
49
68
|
private val contentFit: ContentFit
|
|
@@ -2,8 +2,5 @@ package expo.modules.image
|
|
|
2
2
|
|
|
3
3
|
import expo.modules.kotlin.exception.CodedException
|
|
4
4
|
|
|
5
|
-
class ImagePrefetchFailure(message: String) :
|
|
6
|
-
CodedException(message = "Failed to prefetch the image: $message")
|
|
7
|
-
|
|
8
5
|
class MissingActivity :
|
|
9
6
|
CodedException(message = "The current activity is no longer available")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package expo.modules.image
|
|
2
|
+
|
|
3
|
+
import android.content.ComponentCallbacks2
|
|
4
|
+
import android.content.res.Configuration
|
|
5
|
+
import expo.modules.image.blurhash.BlurhashDecoder
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Clears the Blurhash cache when the memory is low.
|
|
9
|
+
*/
|
|
10
|
+
object ExpoImageComponentCallbacks : ComponentCallbacks2 {
|
|
11
|
+
override fun onConfigurationChanged(newConfig: Configuration) = Unit
|
|
12
|
+
|
|
13
|
+
override fun onLowMemory() {
|
|
14
|
+
BlurhashDecoder.clearCache()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override fun onTrimMemory(level: Int) {
|
|
18
|
+
if (level == ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {
|
|
19
|
+
onLowMemory()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
package expo.modules.image
|
|
2
2
|
|
|
3
3
|
import android.graphics.drawable.Drawable
|
|
4
|
-
import android.view.View
|
|
5
4
|
import androidx.core.view.doOnDetach
|
|
6
5
|
import com.bumptech.glide.Glide
|
|
7
6
|
import com.bumptech.glide.load.DataSource
|
|
8
7
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
|
9
8
|
import com.bumptech.glide.load.engine.GlideException
|
|
10
9
|
import com.bumptech.glide.load.model.GlideUrl
|
|
10
|
+
import com.bumptech.glide.load.model.Headers
|
|
11
|
+
import com.bumptech.glide.load.model.LazyHeaders
|
|
11
12
|
import com.bumptech.glide.request.RequestListener
|
|
12
13
|
import com.bumptech.glide.request.target.Target
|
|
13
14
|
import com.facebook.react.uimanager.PixelUtil
|
|
@@ -25,29 +26,42 @@ import expo.modules.kotlin.Promise
|
|
|
25
26
|
import expo.modules.kotlin.functions.Queues
|
|
26
27
|
import expo.modules.kotlin.modules.Module
|
|
27
28
|
import expo.modules.kotlin.modules.ModuleDefinition
|
|
28
|
-
import expo.modules.kotlin.views.ViewDefinitionBuilder
|
|
29
29
|
|
|
30
30
|
class ExpoImageModule : Module() {
|
|
31
31
|
override fun definition() = ModuleDefinition {
|
|
32
32
|
Name("ExpoImage")
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
OnCreate {
|
|
35
|
+
appContext.reactContext?.registerComponentCallbacks(ExpoImageComponentCallbacks)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
OnDestroy {
|
|
39
|
+
appContext.reactContext?.unregisterComponentCallbacks(ExpoImageComponentCallbacks)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
AsyncFunction("prefetch") { urls: List<String>, cachePolicy: CachePolicy, headersMap: Map<String, String>?, promise: Promise ->
|
|
35
43
|
val context = appContext.reactContext ?: return@AsyncFunction false
|
|
36
44
|
|
|
37
45
|
var imagesLoaded = 0
|
|
38
46
|
var failed = false
|
|
39
47
|
|
|
48
|
+
val headers = headersMap?.let {
|
|
49
|
+
LazyHeaders.Builder().apply {
|
|
50
|
+
it.forEach { (key, value) ->
|
|
51
|
+
addHeader(key, value)
|
|
52
|
+
}
|
|
53
|
+
}.build()
|
|
54
|
+
} ?: Headers.DEFAULT
|
|
55
|
+
|
|
40
56
|
urls.forEach {
|
|
41
57
|
Glide
|
|
42
58
|
.with(context)
|
|
43
|
-
.load(GlideUrl(it)) // Use `load` instead of `download` to store the asset in the memory cache
|
|
59
|
+
.load(GlideUrl(it, headers)) // Use `load` instead of `download` to store the asset in the memory cache
|
|
44
60
|
// We added `quality` and `downsample` to create the same cache key as in final image load.
|
|
45
61
|
.encodeQuality(100)
|
|
46
62
|
.downsample(NoopDownsampleStrategy)
|
|
47
|
-
.
|
|
48
|
-
|
|
49
|
-
diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
50
|
-
}
|
|
63
|
+
.customize(`when` = cachePolicy == CachePolicy.MEMORY) {
|
|
64
|
+
diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
51
65
|
}
|
|
52
66
|
.listener(object : RequestListener<Drawable> {
|
|
53
67
|
override fun onLoadFailed(
|
|
@@ -82,13 +96,13 @@ class ExpoImageModule : Module() {
|
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
98
|
|
|
85
|
-
AsyncFunction("clearMemoryCache") {
|
|
99
|
+
AsyncFunction<Boolean>("clearMemoryCache") {
|
|
86
100
|
val activity = appContext.currentActivity ?: return@AsyncFunction false
|
|
87
101
|
Glide.get(activity).clearMemory()
|
|
88
102
|
return@AsyncFunction true
|
|
89
103
|
}.runOnQueue(Queues.MAIN)
|
|
90
104
|
|
|
91
|
-
AsyncFunction("clearDiskCache") {
|
|
105
|
+
AsyncFunction<Boolean>("clearDiskCache") {
|
|
92
106
|
val activity = appContext.currentActivity ?: return@AsyncFunction false
|
|
93
107
|
activity.let {
|
|
94
108
|
Glide.get(activity).clearDiskCache()
|
|
@@ -103,18 +117,12 @@ class ExpoImageModule : Module() {
|
|
|
103
117
|
val glideUrl = GlideUrl(cacheKey)
|
|
104
118
|
val target = Glide.with(context).asFile().load(glideUrl).onlyRetrieveFromCache(true).submit()
|
|
105
119
|
|
|
106
|
-
try {
|
|
120
|
+
return@AsyncFunction try {
|
|
107
121
|
val file = target.get()
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (path != null) {
|
|
111
|
-
return@AsyncFunction path
|
|
112
|
-
}
|
|
122
|
+
file.absolutePath
|
|
113
123
|
} catch (e: Exception) {
|
|
114
|
-
|
|
124
|
+
null
|
|
115
125
|
}
|
|
116
|
-
|
|
117
|
-
return@AsyncFunction null
|
|
118
126
|
}
|
|
119
127
|
|
|
120
128
|
View(ExpoImageViewWrapper::class) {
|
|
@@ -264,14 +272,3 @@ class ExpoImageModule : Module() {
|
|
|
264
272
|
}
|
|
265
273
|
}
|
|
266
274
|
}
|
|
267
|
-
|
|
268
|
-
// TODO(@lukmccall): Remove when the same functionality will be defined by the expo-modules-core in SDK 48
|
|
269
|
-
@Suppress("FunctionName")
|
|
270
|
-
private inline fun <reified T : View, reified PropType, reified CustomValueType> ViewDefinitionBuilder<T>.PropGroup(
|
|
271
|
-
vararg props: Pair<String, CustomValueType>,
|
|
272
|
-
noinline body: (view: T, value: CustomValueType, prop: PropType) -> Unit
|
|
273
|
-
) {
|
|
274
|
-
for ((name, value) in props) {
|
|
275
|
-
Prop<T, PropType>(name) { view, prop -> body(view, value, prop) }
|
|
276
|
-
}
|
|
277
|
-
}
|
|
@@ -72,7 +72,12 @@ class ExpoImageView(
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
if (isPlaceholder) {
|
|
75
|
-
applyTransformationMatrix(
|
|
75
|
+
applyTransformationMatrix(
|
|
76
|
+
drawable,
|
|
77
|
+
placeholderContentFit,
|
|
78
|
+
sourceHeight = currentTarget?.placeholderHeight,
|
|
79
|
+
sourceWidth = currentTarget?.placeholderWidth
|
|
80
|
+
)
|
|
76
81
|
} else {
|
|
77
82
|
applyTransformationMatrix(drawable, contentFit, contentPosition)
|
|
78
83
|
}
|
|
@@ -81,7 +86,9 @@ class ExpoImageView(
|
|
|
81
86
|
private fun applyTransformationMatrix(
|
|
82
87
|
drawable: Drawable,
|
|
83
88
|
contentFit: ContentFit,
|
|
84
|
-
contentPosition: ContentPosition = ContentPosition.center
|
|
89
|
+
contentPosition: ContentPosition = ContentPosition.center,
|
|
90
|
+
sourceWidth: Int? = currentTarget?.sourceWidth,
|
|
91
|
+
sourceHeight: Int? = currentTarget?.sourceHeight
|
|
85
92
|
) {
|
|
86
93
|
val imageRect = RectF(0f, 0f, drawable.intrinsicWidth.toFloat(), drawable.intrinsicHeight.toFloat())
|
|
87
94
|
val viewRect = RectF(0f, 0f, width.toFloat(), height.toFloat())
|
|
@@ -89,8 +96,8 @@ class ExpoImageView(
|
|
|
89
96
|
val matrix = contentFit.toMatrix(
|
|
90
97
|
imageRect,
|
|
91
98
|
viewRect,
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
sourceWidth ?: -1,
|
|
100
|
+
sourceHeight ?: -1
|
|
94
101
|
)
|
|
95
102
|
val scaledImageRect = imageRect.transform(matrix)
|
|
96
103
|
|
|
@@ -440,19 +440,15 @@ class ExpoImageViewWrapper(context: Context, appContext: AppContext) : ExpoView(
|
|
|
440
440
|
|
|
441
441
|
private fun createPropOptions(): RequestOptions {
|
|
442
442
|
return RequestOptions()
|
|
443
|
-
.
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
blurRadius?.let {
|
|
454
|
-
transform(BlurTransformation(min(it, 25), 4))
|
|
455
|
-
}
|
|
443
|
+
.priority(this@ExpoImageViewWrapper.priority.toGlidePriority())
|
|
444
|
+
.customize(`when` = cachePolicy != CachePolicy.MEMORY_AND_DISK && cachePolicy != CachePolicy.MEMORY) {
|
|
445
|
+
skipMemoryCache(true)
|
|
446
|
+
}
|
|
447
|
+
.customize(`when` = cachePolicy == CachePolicy.NONE || cachePolicy == CachePolicy.MEMORY) {
|
|
448
|
+
diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
449
|
+
}
|
|
450
|
+
.customize(blurRadius) {
|
|
451
|
+
transform(BlurTransformation(min(it, 25), 4))
|
|
456
452
|
}
|
|
457
453
|
}
|
|
458
454
|
|
|
@@ -534,34 +530,25 @@ class ExpoImageViewWrapper(context: Context, appContext: AppContext) : ExpoView(
|
|
|
534
530
|
val request = requestManager
|
|
535
531
|
.asDrawable()
|
|
536
532
|
.load(model)
|
|
537
|
-
.
|
|
538
|
-
if (
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
} else {
|
|
543
|
-
placeholderContentFit
|
|
544
|
-
}
|
|
545
|
-
newTarget.placeholderContentFit = newPlaceholderContentFit
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
.apply {
|
|
549
|
-
options?.let {
|
|
550
|
-
apply(it)
|
|
533
|
+
.customize(placeholder) { newPlaceholder ->
|
|
534
|
+
val newPlaceholderContentFit = if (bestPlaceholder?.isBlurhash() == true || bestPlaceholder?.isThumbhash() == true) {
|
|
535
|
+
contentFit
|
|
536
|
+
} else {
|
|
537
|
+
placeholderContentFit
|
|
551
538
|
}
|
|
539
|
+
newTarget.placeholderContentFit = newPlaceholderContentFit
|
|
540
|
+
|
|
541
|
+
thumbnail(requestManager.load(newPlaceholder.glideData))
|
|
552
542
|
}
|
|
543
|
+
.apply(options)
|
|
553
544
|
.downsample(downsampleStrategy)
|
|
554
545
|
.addListener(GlideRequestListener(WeakReference(this)))
|
|
555
546
|
.encodeQuality(100)
|
|
556
547
|
.format(decodeFormat.toGlideFormat())
|
|
557
548
|
.apply(propOptions)
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
val tintColorOptions = RequestOptions().apply {
|
|
561
|
-
set(CustomOptions.tintColor, it)
|
|
549
|
+
.customize(tintColor) {
|
|
550
|
+
apply(RequestOptions().set(CustomOptions.tintColor, it))
|
|
562
551
|
}
|
|
563
|
-
request.apply(tintColorOptions)
|
|
564
|
-
}
|
|
565
552
|
|
|
566
553
|
val cookie = Trace.getNextCookieValue()
|
|
567
554
|
beginAsyncTraceBlock(Trace.tag, Trace.loadNewImageBlock, cookie)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
package expo.modules.image
|
|
2
|
+
|
|
3
|
+
import com.bumptech.glide.RequestBuilder
|
|
4
|
+
import com.bumptech.glide.request.RequestOptions
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Conditionally applies the block to the RequestBuilder if the condition is true.
|
|
8
|
+
*/
|
|
9
|
+
fun <T> RequestBuilder<T>.customize(`when`: Boolean, block: RequestBuilder<T>.() -> RequestBuilder<T>): RequestBuilder<T> {
|
|
10
|
+
if (!`when`) {
|
|
11
|
+
return this
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return block()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Conditionally applies the block to the RequestBuilder if the value is not null.
|
|
19
|
+
*/
|
|
20
|
+
inline fun <T, P> RequestBuilder<T>.customize(value: P?, block: RequestBuilder<T>.(P) -> RequestBuilder<T>): RequestBuilder<T> {
|
|
21
|
+
if (value == null) {
|
|
22
|
+
return this
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return block(value)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Conditionally applies the block to the RequestOptions if the condition is true.
|
|
30
|
+
*/
|
|
31
|
+
inline fun RequestOptions.customize(`when`: Boolean, block: RequestOptions.() -> RequestOptions): RequestOptions {
|
|
32
|
+
if (!`when`) {
|
|
33
|
+
return this
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return block()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Conditionally applies the block to the RequestOptions if the value is not null.
|
|
41
|
+
*/
|
|
42
|
+
inline fun <T> RequestOptions.customize(value: T?, block: RequestOptions.(T) -> RequestOptions): RequestOptions {
|
|
43
|
+
if (value == null) {
|
|
44
|
+
return this
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return block(value)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fun <T> RequestBuilder<T>.apply(options: RequestOptions?): RequestBuilder<T> {
|
|
51
|
+
if (options == null) {
|
|
52
|
+
return this
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return apply(options)
|
|
56
|
+
}
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
package expo.modules.image
|
|
2
2
|
|
|
3
3
|
import android.graphics.RectF
|
|
4
|
-
import com.bumptech.glide.request.FutureTarget
|
|
5
|
-
import kotlinx.coroutines.Dispatchers
|
|
6
|
-
import kotlinx.coroutines.runInterruptible
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Converts blocking [java.util.concurrent.Future] result into non-blocking suspend function.
|
|
10
|
-
*/
|
|
11
|
-
internal suspend fun <T> FutureTarget<T>.awaitGet(): T = runInterruptible(Dispatchers.IO) { get() }
|
|
12
4
|
|
|
13
5
|
fun calcXTranslation(
|
|
14
6
|
value: Float,
|
|
@@ -52,6 +52,16 @@ class ImageViewWrapperTarget(
|
|
|
52
52
|
*/
|
|
53
53
|
var sourceWidth = -1
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* The placeholder height where -1 means unknown
|
|
57
|
+
*/
|
|
58
|
+
var placeholderHeight = -1
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The placeholder width where -1 means unknown
|
|
62
|
+
*/
|
|
63
|
+
var placeholderWidth = -1
|
|
64
|
+
|
|
55
65
|
private var cookie = -1
|
|
56
66
|
|
|
57
67
|
fun setCookie(newValue: Int) {
|
|
@@ -33,7 +33,7 @@ object ResourceIdHelper {
|
|
|
33
33
|
|
|
34
34
|
fun getResourceUri(context: Context, name: String): Uri? {
|
|
35
35
|
val drawableUri = ResourceDrawableIdHelper.getInstance().getResourceDrawableUri(context, name)
|
|
36
|
-
if (drawableUri !=
|
|
36
|
+
if (drawableUri != Uri.EMPTY) {
|
|
37
37
|
return drawableUri
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -9,6 +9,6 @@ enum class ImageCacheType(private vararg val dataSources: DataSource) {
|
|
|
9
9
|
|
|
10
10
|
companion object {
|
|
11
11
|
fun fromNativeValue(value: DataSource): ImageCacheType =
|
|
12
|
-
|
|
12
|
+
entries.firstOrNull { it.dataSources.contains(value) } ?: NONE
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -42,15 +42,18 @@ data class SourceMap(
|
|
|
42
42
|
|
|
43
43
|
fun isThumbhash() = parsedUri?.scheme?.startsWith("thumbhash") ?: false
|
|
44
44
|
|
|
45
|
+
private fun parseUri(context: Context) {
|
|
46
|
+
if (parsedUri == null) {
|
|
47
|
+
parsedUri = computeUri(context)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
45
51
|
internal fun createGlideModel(context: Context): GlideModel? {
|
|
46
52
|
if (uri.isNullOrBlank()) {
|
|
47
53
|
return null
|
|
48
54
|
}
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
parsedUri = computeUri(context)
|
|
52
|
-
}
|
|
53
|
-
|
|
56
|
+
parseUri(context)
|
|
54
57
|
if (isContentUrl() || isDataUrl()) {
|
|
55
58
|
return GlideRawModel(uri)
|
|
56
59
|
}
|
|
@@ -94,12 +97,9 @@ data class SourceMap(
|
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
internal fun createOptions(context: Context): RequestOptions {
|
|
100
|
+
parseUri(context)
|
|
97
101
|
return RequestOptions()
|
|
98
102
|
.apply {
|
|
99
|
-
if (parsedUri == null) {
|
|
100
|
-
parsedUri = computeUri(context)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
103
|
// Override the size for local assets (apart from SVGs). This ensures that
|
|
104
104
|
// resizeMode "center" displays the image in the correct size.
|
|
105
105
|
if (width != 0 && height != 0) {
|
package/build/ExpoImage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoImage.d.ts","sourceRoot":"","sources":["../src/ExpoImage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAsC,MAAM,cAAc,CAAC;AAExF,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,eAAe,CAAC;AAIvB,QAAA,MAAM,eAAe,KAAmC,CAAC;AAgBzD,cAAM,SAAU,SAAQ,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC;IAC3D,WAAW,aAET;IAEF,MAAM,UAAW,
|
|
1
|
+
{"version":3,"file":"ExpoImage.d.ts","sourceRoot":"","sources":["../src/ExpoImage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAsC,MAAM,cAAc,CAAC;AAExF,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,eAAe,CAAC;AAIvB,QAAA,MAAM,eAAe,KAAmC,CAAC;AAgBzD,cAAM,SAAU,SAAQ,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC;IAC3D,WAAW,aAET;IAEF,MAAM,UAAW,oBAAoB,CAAC,kBAAkB,CAAC,UAGvD;IAEF,UAAU,UAAW,oBAAoB,CAAC,sBAAsB,CAAC,UAE/D;IAEF,OAAO,UAAW,oBAAoB,CAAC,mBAAmB,CAAC,UAGzD;IAEF,SAAS,aAEP;IAEF,MAAM;CAgEP;AAED,OAAO,EAAE,eAAe,EAAE,CAAC;AAC3B,eAAe,SAAS,CAAC"}
|
package/build/ExpoImage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoImage.js","sourceRoot":"","sources":["../src/ExpoImage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAwB,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AASxF,MAAM,eAAe,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;AAE9D,MAAM,eAAe,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;AAEzD,SAAS,yBAAyB,CAChC,KAAwC;IAExC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,WAAW,EAAE,aAAa,EAAE;QACtD,GAAG;YACD,OAAO,CAAC,IAAI,CACV,sHAAsH,CACvH,CAAC;YACF,OAAO,KAAK,CAAC,WAAW,CAAC;QAC3B,CAAC;KACF,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,WAAW,CAAC;AAC3B,CAAC;AAED,MAAM,SAAU,SAAQ,KAAK,CAAC,aAA+B;IAC3D,WAAW,GAAG,GAAG,EAAE;QACjB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;IAC7B,CAAC,CAAC;IAEF,MAAM,GAAG,CAAC,KAA+C,EAAE,EAAE;QAC3D,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC,CAAC;IAEF,UAAU,GAAG,CAAC,KAAmD,EAAE,EAAE;QACnE,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC;IAEF,OAAO,GAAG,CAAC,KAAgD,EAAE,EAAE;QAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC,CAAC;IAEF,SAAS,GAAG,GAAG,EAAE;QACf,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;IAC3B,CAAC,CAAC;IAEF,MAAM;QACJ,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAChE,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAEhD,kDAAkD;QAClD,iDAAiD;QACjD,6CAA6C;QAC7C,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE;
|
|
1
|
+
{"version":3,"file":"ExpoImage.js","sourceRoot":"","sources":["../src/ExpoImage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeViewManager, requireNativeModule } from 'expo-modules-core';\nimport React from 'react';\nimport { NativeSyntheticEvent, StyleSheet, Platform, processColor } from 'react-native';\n\nimport {\n ImageErrorEventData,\n ImageLoadEventData,\n ImageNativeProps,\n ImageProgressEventData,\n} from './Image.types';\n\nconst NativeExpoImage = requireNativeViewManager('ExpoImage');\n\nconst ExpoImageModule = requireNativeModule('ExpoImage');\n\nfunction withDeprecatedNativeEvent<NativeEvent>(\n event: NativeSyntheticEvent<NativeEvent>\n): NativeEvent {\n Object.defineProperty(event.nativeEvent, 'nativeEvent', {\n get() {\n console.warn(\n '[expo-image]: Accessing event payload through \"nativeEvent\" is deprecated, it is now part of the event object itself'\n );\n return event.nativeEvent;\n },\n });\n return event.nativeEvent;\n}\n\nclass ExpoImage extends React.PureComponent<ImageNativeProps> {\n onLoadStart = () => {\n this.props.onLoadStart?.();\n };\n\n onLoad = (event: NativeSyntheticEvent<ImageLoadEventData>) => {\n this.props.onLoad?.(withDeprecatedNativeEvent(event));\n this.onLoadEnd();\n };\n\n onProgress = (event: NativeSyntheticEvent<ImageProgressEventData>) => {\n this.props.onProgress?.(withDeprecatedNativeEvent(event));\n };\n\n onError = (event: NativeSyntheticEvent<ImageErrorEventData>) => {\n this.props.onError?.(withDeprecatedNativeEvent(event));\n this.onLoadEnd();\n };\n\n onLoadEnd = () => {\n this.props.onLoadEnd?.();\n };\n\n render() {\n const { style, accessibilityLabel, alt, ...props } = this.props;\n const resolvedStyle = StyleSheet.flatten(style);\n\n // Shadows behave different on iOS, Android & Web.\n // Android uses the `elevation` prop, whereas iOS\n // and web use the regular `shadow...` props.\n if (Platform.OS === 'android') {\n delete resolvedStyle.shadowColor;\n delete resolvedStyle.shadowOffset;\n delete resolvedStyle.shadowOpacity;\n delete resolvedStyle.shadowRadius;\n } else {\n // @ts-expect-error\n delete resolvedStyle.elevation;\n }\n\n // @ts-ignore\n const backgroundColor = processColor(resolvedStyle.backgroundColor);\n // On Android, we have to set the `backgroundColor` directly on the correct component.\n // So we have to remove it from styles. Otherwise, the background color won't take into consideration the border-radius.\n if (Platform.OS === 'android') {\n delete resolvedStyle.backgroundColor;\n }\n\n const tintColor = processColor(props.tintColor || resolvedStyle.tintColor);\n\n const borderColor = processColor(resolvedStyle.borderColor);\n // @ts-ignore\n const borderStartColor = processColor(resolvedStyle.borderStartColor);\n // @ts-ignore\n const borderEndColor = processColor(resolvedStyle.borderEndColor);\n // @ts-ignore\n const borderLeftColor = processColor(resolvedStyle.borderLeftColor);\n // @ts-ignore\n const borderRightColor = processColor(resolvedStyle.borderRightColor);\n // @ts-ignore\n const borderTopColor = processColor(resolvedStyle.borderTopColor);\n // @ts-ignore\n const borderBottomColor = processColor(resolvedStyle.borderBottomColor);\n\n return (\n <NativeExpoImage\n {...props}\n {...resolvedStyle}\n accessibilityLabel={accessibilityLabel ?? alt}\n style={resolvedStyle}\n onLoadStart={this.onLoadStart}\n onLoad={this.onLoad}\n onProgress={this.onProgress}\n onError={this.onError}\n tintColor={tintColor}\n borderColor={borderColor}\n borderLeftColor={borderLeftColor}\n borderRightColor={borderRightColor}\n borderTopColor={borderTopColor}\n borderBottomColor={borderBottomColor}\n borderStartColor={borderStartColor}\n borderEndColor={borderEndColor}\n backgroundColor={backgroundColor}\n ref={props.nativeViewRef}\n />\n );\n }\n}\n\nexport { ExpoImageModule };\nexport default ExpoImage;\n"]}
|
package/build/ExpoImage.web.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ImageNativeProps } from './Image.types';
|
|
2
2
|
export declare const ExpoImageModule: {
|
|
3
|
-
prefetch(urls: string | string[], _: any): Promise<boolean>;
|
|
3
|
+
prefetch(urls: string | string[], _: any, __: any): Promise<boolean>;
|
|
4
4
|
clearMemoryCache(): Promise<boolean>;
|
|
5
5
|
clearDiskCache(): Promise<boolean>;
|
|
6
6
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoImage.web.d.ts","sourceRoot":"","sources":["../src/ExpoImage.web.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAmC,MAAM,eAAe,CAAC;AAQlF,eAAO,MAAM,eAAe;mBACL,MAAM,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"ExpoImage.web.d.ts","sourceRoot":"","sources":["../src/ExpoImage.web.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAmC,MAAM,eAAe,CAAC;AAQlF,eAAO,MAAM,eAAe;mBACL,MAAM,GAAG,MAAM,EAAE,oBAAU,OAAO,CAAC,OAAO,CAAC;wBAqBtC,OAAO,CAAC,OAAO,CAAC;sBAIlB,OAAO,CAAC,OAAO,CAAC;CAGzC,CAAC;AAwCF,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,MAAM,EACN,WAAW,EACX,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,MAAM,EACN,UAAU,EACV,OAAO,EACP,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAK,EACL,aAAa,EACb,GAAG,KAAK,EACT,EAAE,gBAAgB,eAmFlB"}
|