Skip to content

Commit bad8098

Browse files
numsugtokman
authored andcommitted
feat: ignoreQueryParamsForCacheKey image option (iOS & Android)
Ignores URL query parameters for cache keys when the new option is set to true, defaults to false. This is needed for example when downloading images using S3 presigned URL's that include a signature that changes between requests preventing the images from being found in the cache. Also fixes the merge error in FasterImageViewManager.kt which came from commit 86a23fd
1 parent 5b2d114 commit bad8098

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

android/src/main/java/com/candlefinance/fasterimage/FasterImageViewManager.kt

+25-16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import android.graphics.RectF
1010
import android.graphics.Path
1111
import android.graphics.drawable.BitmapDrawable
1212
import android.graphics.drawable.Drawable
13+
import android.net.Uri
1314
import android.os.Build
1415
import android.util.Base64
1516
import android.view.View
@@ -18,6 +19,7 @@ import android.widget.ImageView.ScaleType
1819
import androidx.appcompat.widget.AppCompatImageView
1920
import coil.annotation.ExperimentalCoilApi
2021
import coil.imageLoader
22+
import coil.memory.MemoryCache
2123
import coil.request.CachePolicy
2224
import coil.request.ImageRequest
2325
import coil.size.Scale
@@ -93,9 +95,10 @@ import com.facebook.react.uimanager.events.RCTEventEmitter
9395
val failureImage = options.getString("failureImage")
9496
val grayscale = if (options.hasKey("grayscale")) options.getDouble("grayscale") else 0.0
9597
val allowHardware = if (options.hasKey("allowHardware")) options.getBoolean("allowHardware") else true
96-
val headers = options.getMap("headers")
98+
val headers = options.getMap("headers")
99+
val ignoreQueryParamsForCacheKey = if (options.hasKey("ignoreQueryParamsForCacheKey")) options.getBoolean("ignoreQueryParamsForCacheKey") else false
97100

98-
val borderRadii = BorderRadii(
101+
val borderRadii = BorderRadii(
99102
uniform = if (options.hasKey("borderRadius")) options.getDouble("borderRadius") else 0.0,
100103
topLeft = if (options.hasKey("borderTopLeftRadius")) options.getDouble("borderTopLeftRadius") else 0.0,
101104
topRight = if (options.hasKey("borderTopRightRadius")) options.getDouble("borderTopRightRadius") else 0.0,
@@ -128,6 +131,20 @@ import com.facebook.react.uimanager.events.RCTEventEmitter
128131
)
129132
} else {
130133
requestBuilder = requestBuilder.data(it)
134+
if (ignoreQueryParamsForCacheKey) {
135+
val uri = Uri.parse(it)
136+
val keyUri = uri.buildUpon().clearQuery().build()
137+
val cacheKey = keyUri.toString()
138+
val memoryCacheKey = MemoryCache.Key(cacheKey)
139+
if (cachePolicy.equals("memory")) {
140+
requestBuilder = requestBuilder
141+
.memoryCacheKey(memoryCacheKey)
142+
} else {
143+
requestBuilder = requestBuilder
144+
.memoryCacheKey(memoryCacheKey)
145+
.diskCacheKey(cacheKey)
146+
}
147+
}
131148
headers?.let {
132149
for (entry in it.entryIterator) {
133150
requestBuilder.setHeader(entry.key, entry.value as String)
@@ -233,20 +250,6 @@ import com.facebook.react.uimanager.events.RCTEventEmitter
233250

234251
private fun makeThumbHash(view: AppCompatImageView, hash: String): Drawable {
235252
val thumbHash = ThumbHash.thumbHashToRGBA(Base64.decode(hash, Base64.DEFAULT))
236-
val bitmap = Bitmap.createBitmap(thumbHash.width, thumbHash.height, Bitmap.Config.ARGB_8888)
237-
bitmap.setPixels(toIntArray(thumbHash.rgba), 0, thumbHash.width, 0, 0, thumbHash.width, thumbHash.height)
238-
return BitmapDrawable(view.context.resources, bitmap)
239-
}
240-
241-
private fun makeBlurHash(view: AppCompatImageView, hash: String): Drawable {
242-
val bitmap = BlurHashDecoder.decode(hash, 8, 8)
243-
return BitmapDrawable(view.context.resources, bitmap)
244-
}
245-
246-
private fun toIntArray(byteArray: ByteArray): IntArray {
247-
val intArray = IntArray(byteArray.size)
248-
for (i in byteArray.indices) {
249-
intArray[i] = byteArray[i].toInt() and 0xFF
250253
val intArray = IntArray(thumbHash.width * thumbHash.height)
251254
for (i in intArray.indices) {
252255
val r = thumbHash.rgba[i * 4].toInt() and 0xFF
@@ -260,6 +263,11 @@ import com.facebook.react.uimanager.events.RCTEventEmitter
260263
return BitmapDrawable(view.context.resources, bitmap)
261264
}
262265

266+
private fun makeBlurHash(view: AppCompatImageView, hash: String): Drawable {
267+
val bitmap = BlurHashDecoder.decode(hash, 8, 8)
268+
return BitmapDrawable(view.context.resources, bitmap)
269+
}
270+
263271
companion object {
264272
private val RESIZE_MODE = mapOf(
265273
"contain" to ScaleType.FIT_CENTER,
@@ -277,6 +285,7 @@ import com.facebook.react.uimanager.events.RCTEventEmitter
277285
}
278286
}
279287

288+
280289
object ThumbHash {
281290
/**
282291
* Encodes an RGBA image to a ThumbHash. RGB should not be premultiplied by A.

ios/FasterImageViewManager.swift

+11-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct ImageOptions: Decodable {
4343
let headers: [String: String]?
4444
let grayscale: Double?
4545
let priority: String?
46+
let ignoreQueryParamsForCacheKey: Bool?
4647
}
4748

4849
struct BorderRadii {
@@ -162,12 +163,19 @@ final class FasterImageView: UIView {
162163
}
163164
progressiveLoadingEnabled = options.progressiveLoadingEnabled ?? false
164165
grayscale = options.grayscale ?? 0.0
166+
ignoreQueryParamsForCacheKey = options.ignoreQueryParamsForCacheKey ?? false
165167

166168
if let url = URL(string: options.url) {
167169
var urlRequestFromOptions = URLRequest(url: url)
168170
urlRequestFromOptions.allHTTPHeaderFields = options.headers
169-
170171
urlRequest = urlRequestFromOptions
172+
173+
if ignoreQueryParamsForCacheKey {
174+
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
175+
components?.query = nil
176+
var url = components?.url?.absoluteString ?? url.absoluteString
177+
lazyImageView.request?.userInfo[.imageIdKey] = url
178+
}
171179
} else {
172180
onError?([
173181
"error": "Expected a valid url but got: \(options.url)",
@@ -304,6 +312,8 @@ final class FasterImageView: UIView {
304312
}
305313
}
306314

315+
var ignoreQueryParamsForCacheKey = false
316+
307317
// MARK: - Optional Properties
308318

309319
var base64Placeholder: String? {

src/index.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export type AndroidImageResizeMode =
4848
* @property {number} [grayscale] - Grayscale value of the image, 0-1
4949
* @property {boolean} [allowHardware] - Allow hardware rendering, defaults to true (Android only)
5050
* @property {'veryLow' | 'low' | 'normal' | 'high' | 'veryHigh'} [priority] - Set Image's loading priority, defaults to 'normal' (iOS only)
51+
* @property {boolean} [ignoreQueryParamsForCacheKey] - Ignore query params for cache key, defaults to false
5152
*/
5253
export type ImageOptions = {
5354
blurhash?: string;
@@ -72,6 +73,7 @@ export type ImageOptions = {
7273
grayscale?: number;
7374
allowHardware?: boolean;
7475
priority?: "veryLow" | "low" | "normal" | "high" | "veryHigh"
76+
ignoreQueryParamsForCacheKey?: boolean;
7577
};
7678

7779
/**

0 commit comments

Comments
 (0)