From 4ee192f9e2876beffbc25c88f669c294b501d65c Mon Sep 17 00:00:00 2001
From: Thomas Coldwell <31568400+thomas-coldwell@users.noreply.github.com>
Date: Thu, 15 Dec 2022 13:40:37 +0000
Subject: [PATCH 1/3] fix: Build example app
---
ReactNativeFastImageExample/android/build.gradle | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/ReactNativeFastImageExample/android/build.gradle b/ReactNativeFastImageExample/android/build.gradle
index e64d31e5f..c20cd5fe6 100644
--- a/ReactNativeFastImageExample/android/build.gradle
+++ b/ReactNativeFastImageExample/android/build.gradle
@@ -1,5 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
+def REACT_NATIVE_VERSION = new File(['node', '--print',"JSON.parse(require('fs').readFileSync(require.resolve('react-native/package.json'), 'utf-8')).version"].execute(null, rootDir).text.trim())
+
buildscript {
ext {
buildToolsVersion = "30.0.2"
@@ -34,5 +36,13 @@ allprojects {
google()
maven { url 'https://www.jitpack.io' }
+
+ }
+
+ configurations.all {
+ resolutionStrategy {
+ // Remove this override in 0.65+, as a proper fix is included in react-native itself.
+ force "com.facebook.react:react-native:" + REACT_NATIVE_VERSION
+ }
}
}
From d8861219229c1527e8457d21e08e9f08085d5f99 Mon Sep 17 00:00:00 2001
From: Thomas Coldwell <31568400+thomas-coldwell@users.noreply.github.com>
Date: Thu, 15 Dec 2022 15:25:28 +0000
Subject: [PATCH 2/3] fix: Run example app
---
ReactNativeFastImageExample/metro.config.js | 50 +++++++++++++++++----
package.json | 4 +-
2 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/ReactNativeFastImageExample/metro.config.js b/ReactNativeFastImageExample/metro.config.js
index d65704821..2a0a8c597 100644
--- a/ReactNativeFastImageExample/metro.config.js
+++ b/ReactNativeFastImageExample/metro.config.js
@@ -5,13 +5,45 @@
* @format
*/
+
+
+const path = require('path')
+const escape = require('escape-string-regexp')
+const exclusionList = require('metro-config/src/defaults/exclusionList')
+const pak = require('../package.json')
+
+const root = path.resolve(__dirname, '..')
+
+const modules = Object.keys({
+ ...pak.peerDependencies,
+})
+
module.exports = {
- transformer: {
- getTransformOptions: async () => ({
- transform: {
- experimentalImportSupport: false,
- inlineRequires: true,
- },
- }),
- },
-}
+ projectRoot: __dirname,
+ watchFolders: [root],
+
+ // We need to make sure that only one version is loaded for peerDependencies
+ // So we block them at the root, and alias them to the versions in example's node_modules
+ resolver: {
+ blacklistRE: exclusionList(
+ modules.map(
+ (m) =>
+ new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`)
+ )
+ ),
+
+ extraNodeModules: modules.reduce((acc, name) => {
+ acc[name] = path.join(__dirname, 'node_modules', name)
+ return acc
+ }, {}),
+ },
+
+ transformer: {
+ getTransformOptions: async () => ({
+ transform: {
+ experimentalImportSupport: false,
+ inlineRequires: true,
+ },
+ }),
+ },
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index eaaa13c29..e3f4291a1 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,8 @@
"main": "dist/index.cjs.js",
"module": "dist/index.js",
"typings": "dist/index.d.ts",
+ "source": "src/index",
+ "react-native": "src/index",
"files": [
"android",
"!android/build",
@@ -79,4 +81,4 @@
"react": "^17 || ^18",
"react-native": ">=0.60.0"
}
-}
+}
\ No newline at end of file
From 176b6e395e94221ace85b5d463fac78633400813 Mon Sep 17 00:00:00 2001
From: Thomas Coldwell <31568400+thomas-coldwell@users.noreply.github.com>
Date: Thu, 15 Dec 2022 15:32:56 +0000
Subject: [PATCH 3/3] feat: Add additional `Size` target for Glide
---
.../src/AutoSizeExample.tsx | 1 +
.../fastimage/BitmapSizeDecoder.java | 31 +++++++++++++++++++
.../fastimage/BitmapSizeTranscoder.java | 23 ++++++++++++++
.../FastImageOkHttpProgressGlideModule.java | 6 ++++
.../fastimage/FastImageRequestListener.java | 8 -----
.../fastimage/FastImageViewWithUrl.java | 22 +++++++++++++
.../java/com/dylanvann/fastimage/Size.java | 6 ++++
7 files changed, 89 insertions(+), 8 deletions(-)
create mode 100644 android/src/main/java/com/dylanvann/fastimage/BitmapSizeDecoder.java
create mode 100644 android/src/main/java/com/dylanvann/fastimage/BitmapSizeTranscoder.java
create mode 100644 android/src/main/java/com/dylanvann/fastimage/Size.java
diff --git a/ReactNativeFastImageExample/src/AutoSizeExample.tsx b/ReactNativeFastImageExample/src/AutoSizeExample.tsx
index 75dfb8691..70f8db5ec 100644
--- a/ReactNativeFastImageExample/src/AutoSizeExample.tsx
+++ b/ReactNativeFastImageExample/src/AutoSizeExample.tsx
@@ -47,6 +47,7 @@ const AutoSizingImage = (props: AutoSizingImageProps) => {
)
diff --git a/android/src/main/java/com/dylanvann/fastimage/BitmapSizeDecoder.java b/android/src/main/java/com/dylanvann/fastimage/BitmapSizeDecoder.java
new file mode 100644
index 000000000..03ad01799
--- /dev/null
+++ b/android/src/main/java/com/dylanvann/fastimage/BitmapSizeDecoder.java
@@ -0,0 +1,31 @@
+package com.dylanvann.fastimage;
+
+import android.graphics.BitmapFactory;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.bumptech.glide.load.Options;
+import com.bumptech.glide.load.ResourceDecoder;
+import com.bumptech.glide.load.engine.Resource;
+import com.bumptech.glide.load.resource.SimpleResource;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BitmapSizeDecoder implements ResourceDecoder {
+
+ @Override
+ public boolean handles(@NonNull InputStream source, @NonNull Options options) throws IOException {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public Resource decode(@NonNull InputStream source, int width, int height, @NonNull Options options) throws IOException {
+ BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
+ bitmapOptions.inJustDecodeBounds = true;
+ BitmapFactory.decodeStream(source, null, bitmapOptions);
+ return new SimpleResource(bitmapOptions);
+ }
+}
\ No newline at end of file
diff --git a/android/src/main/java/com/dylanvann/fastimage/BitmapSizeTranscoder.java b/android/src/main/java/com/dylanvann/fastimage/BitmapSizeTranscoder.java
new file mode 100644
index 000000000..255cb0d26
--- /dev/null
+++ b/android/src/main/java/com/dylanvann/fastimage/BitmapSizeTranscoder.java
@@ -0,0 +1,23 @@
+package com.dylanvann.fastimage;
+
+import android.graphics.BitmapFactory;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.bumptech.glide.load.Options;
+import com.bumptech.glide.load.engine.Resource;
+import com.bumptech.glide.load.resource.SimpleResource;
+import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
+
+public class BitmapSizeTranscoder implements ResourceTranscoder {
+ @Nullable
+ @Override
+ public Resource transcode(@NonNull Resource toTranscode, @NonNull Options options) {
+ BitmapFactory.Options bitmap = toTranscode.get();
+ Size size = new Size();
+ size.width = bitmap.outWidth;
+ size.height = bitmap.outHeight;
+ return new SimpleResource(size);
+ }
+}
diff --git a/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java b/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java
index 811292aa7..b01df1930 100644
--- a/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java
+++ b/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java
@@ -1,6 +1,8 @@
package com.dylanvann.fastimage;
import android.content.Context;
+import android.graphics.BitmapFactory;
+
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
@@ -47,6 +49,10 @@ public void registerComponents(
.build();
OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory(client);
registry.replace(GlideUrl.class, InputStream.class, factory);
+
+ // Decoder + Transcoder pair for InputStream -> Size
+ registry.prepend(InputStream.class, BitmapFactory.Options.class, new BitmapSizeDecoder());
+ registry.register(BitmapFactory.Options.class, Size.class, new BitmapSizeTranscoder());
}
private static Interceptor createInterceptor(final ResponseProgressListener listener) {
diff --git a/android/src/main/java/com/dylanvann/fastimage/FastImageRequestListener.java b/android/src/main/java/com/dylanvann/fastimage/FastImageRequestListener.java
index dbeb81313..bf8f21cb8 100644
--- a/android/src/main/java/com/dylanvann/fastimage/FastImageRequestListener.java
+++ b/android/src/main/java/com/dylanvann/fastimage/FastImageRequestListener.java
@@ -22,13 +22,6 @@ public class FastImageRequestListener implements RequestListener {
this.key = key;
}
- private static WritableMap mapFromResource(Drawable resource) {
- WritableMap resourceData = new WritableNativeMap();
- resourceData.putInt("width", resource.getIntrinsicWidth());
- resourceData.putInt("height", resource.getIntrinsicHeight());
- return resourceData;
- }
-
@Override
public boolean onLoadFailed(@androidx.annotation.Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
FastImageOkHttpProgressGlideModule.forget(key);
@@ -53,7 +46,6 @@ public boolean onResourceReady(Drawable resource, Object model, Target
ThemedReactContext context = (ThemedReactContext) view.getContext();
RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class);
int viewId = view.getId();
- eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_EVENT, mapFromResource(resource));
eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_END_EVENT, new WritableNativeMap());
return false;
}
diff --git a/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java b/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java
index 34fcf898d..503f2ec88 100644
--- a/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java
+++ b/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java
@@ -6,6 +6,7 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
@@ -13,6 +14,8 @@
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.request.Request;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.bumptech.glide.request.transition.Transition;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
@@ -148,6 +151,25 @@ public void onAfterUpdate(
builder.listener(new FastImageRequestListener(key));
builder.into(this);
+
+ // Used specifically to handle the `onLoad` event for the image
+ RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class);
+ int viewId = this.getId();
+ requestManager
+ .as(Size.class)
+ .load(imageSource == null ? null : imageSource.getSourceForLoad())
+ .into(new SimpleTarget() {
+ @Override
+ public void onResourceReady(@NonNull Size resource, @Nullable Transition super Size> transition) {
+ WritableMap resourceData = new WritableNativeMap();
+ resourceData.putInt("width", resource.width);
+ resourceData.putInt("height", resource.height);
+ eventEmitter.receiveEvent(viewId,
+ "onFastImageLoad",
+ resourceData
+ );
+ }
+ });
}
}
diff --git a/android/src/main/java/com/dylanvann/fastimage/Size.java b/android/src/main/java/com/dylanvann/fastimage/Size.java
new file mode 100644
index 000000000..d3f33eb2b
--- /dev/null
+++ b/android/src/main/java/com/dylanvann/fastimage/Size.java
@@ -0,0 +1,6 @@
+package com.dylanvann.fastimage;
+
+public class Size {
+ int width;
+ int height;
+}