diff --git a/packages/react-native/Libraries/Image/ImageSource.d.ts b/packages/react-native/Libraries/Image/ImageSource.d.ts index 2d47b6ba194..406e89520e1 100644 --- a/packages/react-native/Libraries/Image/ImageSource.d.ts +++ b/packages/react-native/Libraries/Image/ImageSource.d.ts @@ -50,8 +50,6 @@ export interface ImageURISource { * its age or expiration date. If there is no existing data in the cache corresponding * to a URL load request, no attempt is made to load the data from the originating source, * and the load is considered to have failed. - * - * @platform ios (for `force-cache`) */ cache?: 'default' | 'reload' | 'force-cache' | 'only-if-cached' | undefined; /** diff --git a/packages/react-native/Libraries/Image/ImageSource.js b/packages/react-native/Libraries/Image/ImageSource.js index 1698c945b0b..71de1497ccc 100644 --- a/packages/react-native/Libraries/Image/ImageSource.js +++ b/packages/react-native/Libraries/Image/ImageSource.js @@ -65,8 +65,6 @@ export interface ImageURISource { * its age or expiration date. If there is no existing data in the cache corresponding * to a URL load request, no attempt is made to load the data from the originating source, * and the load is considered to have failed. - * - * @platform ios (for `force-cache`) */ +cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached'); diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 88ad2d0823a..bf197be2bc6 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3334,6 +3334,7 @@ public final class com/facebook/react/modules/fresco/FrescoModule$Companion { public final class com/facebook/react/modules/fresco/ImageCacheControl : java/lang/Enum { public static final field DEFAULT Lcom/facebook/react/modules/fresco/ImageCacheControl; + public static final field FORCE_CACHE Lcom/facebook/react/modules/fresco/ImageCacheControl; public static final field ONLY_IF_CACHED Lcom/facebook/react/modules/fresco/ImageCacheControl; public static final field RELOAD Lcom/facebook/react/modules/fresco/ImageCacheControl; public static fun getEntries ()Lkotlin/enums/EnumEntries; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ImageCacheControl.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ImageCacheControl.kt index acb04ea7beb..ca25c3fc4bb 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ImageCacheControl.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ImageCacheControl.kt @@ -15,6 +15,12 @@ public enum class ImageCacheControl { * be used to satisfy a URL load request. */ RELOAD, + /** + * The existing cache data will be used to satisfy a request, regardless of its age or expiration + * date. If there is no existing data in the cache corresponding to a URL load request, the data + * is loaded from the originating source. + */ + FORCE_CACHE, /** * The existing cache data will be used to satisfy a request, regardless of its age or expiration * date. If there is no existing data in the cache corresponding to a URL load request, no attempt diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ReactOkHttpNetworkFetcher.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ReactOkHttpNetworkFetcher.kt index 502f220a090..2e0bec6a119 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ReactOkHttpNetworkFetcher.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ReactOkHttpNetworkFetcher.kt @@ -12,6 +12,7 @@ import com.facebook.imagepipeline.backends.okhttp3.OkHttpNetworkFetcher import com.facebook.imagepipeline.producers.NetworkFetcher import com.facebook.react.bridge.ReadableMap import com.facebook.react.modules.network.OkHttpCompat +import java.util.concurrent.TimeUnit import okhttp3.CacheControl import okhttp3.OkHttpClient import okhttp3.Request @@ -35,21 +36,26 @@ internal class ReactOkHttpNetworkFetcher(private val okHttpClient: OkHttpClient) fetchState.submitTime = SystemClock.elapsedRealtime() val uri = fetchState.uri var requestHeaders: Map? = null - val cacheControlBuilder = CacheControl.Builder().noStore() + val cacheControlBuilder = CacheControl.Builder() if (fetchState.context.imageRequest is ReactNetworkImageRequest) { val networkImageRequest = fetchState.context.imageRequest as ReactNetworkImageRequest requestHeaders = getHeaders(networkImageRequest.headers) when (networkImageRequest.cacheControl) { ImageCacheControl.RELOAD -> { - cacheControlBuilder.noCache() + cacheControlBuilder.noStore().noCache() + } + ImageCacheControl.FORCE_CACHE -> { + cacheControlBuilder.maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS) } ImageCacheControl.ONLY_IF_CACHED -> { - cacheControlBuilder.onlyIfCached() + cacheControlBuilder.onlyIfCached().maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS) } ImageCacheControl.DEFAULT -> { - // No-op + cacheControlBuilder.noStore() } } + } else { + cacheControlBuilder.noStore() } val headers = OkHttpCompat.getHeadersFromMap(requestHeaders) val request = diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt index 5365d689f5f..fc10007e7a7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt @@ -312,6 +312,7 @@ public class ReactImageView( null, "default" -> ImageCacheControl.DEFAULT "reload" -> ImageCacheControl.RELOAD + "force-cache" -> ImageCacheControl.FORCE_CACHE "only-if-cached" -> ImageCacheControl.ONLY_IF_CACHED else -> ImageCacheControl.DEFAULT } diff --git a/packages/rn-tester/js/examples/Image/ImageExample.js b/packages/rn-tester/js/examples/Image/ImageExample.js index bbd0054bf78..f2f6adfdc09 100644 --- a/packages/rn-tester/js/examples/Image/ImageExample.js +++ b/packages/rn-tester/js/examples/Image/ImageExample.js @@ -666,6 +666,18 @@ function CacheControlAndroidExample(): React.Node { key={reload} /> + + Force-cache + console.log(e.nativeEvent.error)} + /> + Only-if-cached