From 7e7dc923b16c3f08da47e6a80fafb18a1208cd15 Mon Sep 17 00:00:00 2001 From: ArekChr Date: Mon, 27 Mar 2023 11:55:54 +0200 Subject: [PATCH 1/4] feat: use rnfs expensfy fork --- package-lock.json | 6 +- package.json | 2 +- patches/react-native-fast-image+8.6.3.patch | 300 -------------------- 3 files changed, 6 insertions(+), 302 deletions(-) delete mode 100644 patches/react-native-fast-image+8.6.3.patch diff --git a/package-lock.json b/package-lock.json index a4723a2eacba..741bf5afb7ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34577,6 +34577,8 @@ }, "node_modules/react-native-fast-image": { "version": "8.6.3", + "resolved": "git+ssh://git@github.com/Expensify/react-native-fast-image.git#bef666720ca00272c051a0165a056a2dc07e9deb", + "integrity": "sha512-JIyLRVzUgZq89jchYkNFMp/55MA/ZknFwdJur/CKopmWKfa3e2uYdwYeFp8mAMAkOnn74uupt+IWSORy5qZ5qQ==", "license": "(MIT AND Apache-2.0)", "peerDependencies": { "react": "^17 || ^18", @@ -64272,7 +64274,9 @@ } }, "react-native-fast-image": { - "version": "8.6.3", + "version": "git+ssh://git@github.com/Expensify/react-native-fast-image.git#bef666720ca00272c051a0165a056a2dc07e9deb", + "integrity": "sha512-JIyLRVzUgZq89jchYkNFMp/55MA/ZknFwdJur/CKopmWKfa3e2uYdwYeFp8mAMAkOnn74uupt+IWSORy5qZ5qQ==", + "from": "react-native-fast-image@^8.6.3", "requires": {} }, "react-native-flipper": { diff --git a/package.json b/package.json index 76e18e09de23..18c3e7647fda 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "react-native-config": "^1.4.5", "react-native-device-info": "^10.3.0", "react-native-document-picker": "^8.0.0", - "react-native-fast-image": "^8.6.3", + "react-native-fast-image": "git+https://github.com/Expensify/react-native-fast-image.git#bef666720ca00272c051a0165a056a2dc07e9deb", "react-native-gesture-handler": "2.9.0", "react-native-google-places-autocomplete": "git+https://github.com/Expensify/react-native-google-places-autocomplete.git#e12768f1542e7982d90f6449798f0d6b7f18f192", "react-native-haptic-feedback": "^1.13.0", diff --git a/patches/react-native-fast-image+8.6.3.patch b/patches/react-native-fast-image+8.6.3.patch deleted file mode 100644 index f01b87b7fd91..000000000000 --- a/patches/react-native-fast-image+8.6.3.patch +++ /dev/null @@ -1,300 +0,0 @@ -diff --git a/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/BitmapSizeDecoder.java b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/BitmapSizeDecoder.java -new file mode 100644 -index 0000000..2bd58b8 ---- /dev/null -+++ b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/BitmapSizeDecoder.java -@@ -0,0 +1,44 @@ -+package com.dylanvann.fastimage; -+ -+import android.graphics.BitmapFactory; -+ -+import androidx.annotation.NonNull; -+import androidx.annotation.Nullable; -+import androidx.exifinterface.media.ExifInterface; -+ -+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); -+ -+ // BitmapFactory#decodeStream leaves stream's position where ever it was after reading the encoded data -+ // https://developer.android.com/reference/android/graphics/BitmapFactory#decodeStream(java.io.InputStream) -+ // so we need to rewind the stream to be able to read image header with exif values -+ source.reset(); -+ -+ int orientation = new ExifInterface(source).getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); -+ if (orientation == ExifInterface.ORIENTATION_ROTATE_90 || orientation == ExifInterface.ORIENTATION_ROTATE_270) { -+ int tmpWidth = bitmapOptions.outWidth; -+ bitmapOptions.outWidth = bitmapOptions.outHeight; -+ bitmapOptions.outHeight = tmpWidth; -+ } -+ return new SimpleResource(bitmapOptions); -+ } -+} -\ No newline at end of file -diff --git a/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/BitmapSizeTranscoder.java b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/BitmapSizeTranscoder.java -new file mode 100644 -index 0000000..7d208d1 ---- /dev/null -+++ b/node_modules/react-native-fast-image/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); -+ } -+} -\ No newline at end of file -diff --git a/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java -index 811292a..f60b87c 100644 ---- a/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java -+++ b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java -@@ -2,6 +2,7 @@ package com.dylanvann.fastimage; - - import android.content.Context; - import androidx.annotation.NonNull; -+import android.graphics.BitmapFactory; - - import com.bumptech.glide.Glide; - import com.bumptech.glide.Registry; -@@ -47,6 +48,9 @@ public class FastImageOkHttpProgressGlideModule extends LibraryGlideModule { - .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/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageRequestListener.java b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageRequestListener.java -index dbeb813..bf8f21c 100644 ---- a/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageRequestListener.java -+++ b/node_modules/react-native-fast-image/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 class FastImageRequestListener implements RequestListener { - 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/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java -index 34fcf89..1339f5c 100644 ---- a/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java -+++ b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java -@@ -2,6 +2,7 @@ package com.dylanvann.fastimage; - - import static com.dylanvann.fastimage.FastImageRequestListener.REACT_ON_ERROR_EVENT; - -+import androidx.annotation.NonNull; - import android.annotation.SuppressLint; - import android.content.Context; - import android.graphics.drawable.Drawable; -@@ -9,16 +10,24 @@ import android.graphics.drawable.Drawable; - import androidx.annotation.Nullable; - import androidx.appcompat.widget.AppCompatImageView; - -+import com.bumptech.glide.Glide; - import com.bumptech.glide.RequestBuilder; - import com.bumptech.glide.RequestManager; -+import com.bumptech.glide.load.DataSource; -+import com.bumptech.glide.load.engine.GlideException; - import com.bumptech.glide.load.model.GlideUrl; - import com.bumptech.glide.request.Request; -+import com.bumptech.glide.request.RequestListener; -+import com.bumptech.glide.request.target.SimpleTarget; -+import com.bumptech.glide.request.target.Target; -+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; - import com.facebook.react.uimanager.ThemedReactContext; - import com.facebook.react.uimanager.events.RCTEventEmitter; - -+import java.io.File; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; -@@ -124,9 +133,34 @@ class FastImageViewWithUrl extends AppCompatImageView { - RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class); - int viewId = this.getId(); - -- eventEmitter.receiveEvent(viewId, -- FastImageViewManager.REACT_ON_LOAD_START_EVENT, -- new WritableNativeMap()); -+ // Request the URL from cache to see if it exists there and if so pass the cache -+ // path as an argument in the onLoadStart event -+ requestManager -+ .asFile() -+ .load(glideUrl) -+ .onlyRetrieveFromCache(true) -+ .listener(new RequestListener() { -+ @Override -+ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { -+ WritableNativeMap result = new WritableNativeMap(); -+ result.putNull("cachePath"); -+ eventEmitter.receiveEvent(viewId, -+ FastImageViewManager.REACT_ON_LOAD_START_EVENT, -+ result); -+ return false; -+ } -+ -+ @Override -+ public boolean onResourceReady(File resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { -+ WritableNativeMap result = new WritableNativeMap(); -+ result.putString("cachePath", resource.getAbsolutePath()); -+ eventEmitter.receiveEvent(viewId, -+ FastImageViewManager.REACT_ON_LOAD_START_EVENT, -+ result); -+ return false; -+ } -+ }) -+ .submit(); - } - - if (requestManager != null) { -@@ -148,6 +182,25 @@ class FastImageViewWithUrl extends AppCompatImageView { - 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 transition) { -+ WritableMap resourceData = new WritableNativeMap(); -+ resourceData.putInt("width", resource.width); -+ resourceData.putInt("height", resource.height); -+ eventEmitter.receiveEvent(viewId, -+ "onFastImageLoad", -+ resourceData -+ ); -+ } -+ }); - } - } - -diff --git a/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/Size.java b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/Size.java -new file mode 100644 -index 0000000..2fe8a47 ---- /dev/null -+++ b/node_modules/react-native-fast-image/android/src/main/java/com/dylanvann/fastimage/Size.java -@@ -0,0 +1,6 @@ -+package com.dylanvann.fastimage; -+ -+public class Size { -+ int width; -+ int height; -+} -\ No newline at end of file -diff --git a/node_modules/react-native-fast-image/dist/index.d.ts b/node_modules/react-native-fast-image/dist/index.d.ts -index 5abb7c9..a2672c6 100644 ---- a/node_modules/react-native-fast-image/dist/index.d.ts -+++ b/node_modules/react-native-fast-image/dist/index.d.ts -@@ -27,6 +27,11 @@ export declare type Source = { - priority?: Priority; - cache?: Cache; - }; -+export interface OnLoadStartEvent { -+ nativeEvent: { -+ cachePath: string | null; -+ }; -+} - export interface OnLoadEvent { - nativeEvent: { - width: number; -@@ -57,7 +62,7 @@ export interface FastImageProps extends AccessibilityProps, ViewProps { - defaultSource?: ImageRequireSource; - resizeMode?: ResizeMode; - fallback?: boolean; -- onLoadStart?(): void; -+ onLoadStart?(event: OnLoadStartEvent): void; - onProgress?(event: OnProgressEvent): void; - onLoad?(event: OnLoadEvent): void; - onError?(): void; -diff --git a/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m b/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m -index f710081..391ef92 100644 ---- a/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m -+++ b/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m -@@ -54,7 +54,6 @@ - (void) setOnFastImageError: (RCTDirectEventBlock)onFastImageError { - - (void) setOnFastImageLoadStart: (RCTDirectEventBlock)onFastImageLoadStart { - if (_source && !self.hasSentOnLoadStart) { - _onFastImageLoadStart = onFastImageLoadStart; -- onFastImageLoadStart(@{}); - self.hasSentOnLoadStart = YES; - } else { - _onFastImageLoadStart = onFastImageLoadStart; -@@ -188,7 +187,18 @@ - (void) reloadImage { - } - - if (self.onFastImageLoadStart) { -- self.onFastImageLoadStart(@{}); -+ NSString* cachePath = [[SDImageCache sharedImageCache] cachePathForKey:url]; -+ BOOL isCached = [[SDImageCache sharedImageCache] diskImageDataExistsWithKey:url]; -+ if (isCached) { -+ self.onFastImageLoadStart(@{ -+ @"cachePath": cachePath -+ }); -+ } -+ else { -+ self.onFastImageLoadStart(@{ -+ @"cachePath": [NSNull null] -+ }); -+ } - self.hasSentOnLoadStart = YES; - } else { - self.hasSentOnLoadStart = NO; From 2cffedf0f2154b3975b13d234e84ed5ce43bf82c Mon Sep 17 00:00:00 2001 From: ArekChr Date: Mon, 27 Mar 2023 11:56:25 +0200 Subject: [PATCH 2/4] feat: use disableTransformation prop, enable largeHeap --- android/app/src/main/AndroidManifest.xml | 2 ++ src/components/ImageView/index.native.js | 1 + 2 files changed, 3 insertions(+) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 514f471bf8e4..07214d27c471 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -10,6 +10,8 @@ Date: Mon, 27 Mar 2023 11:57:23 +0200 Subject: [PATCH 3/4] fix: disable transformation --- src/components/ImageView/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ImageView/index.native.js b/src/components/ImageView/index.native.js index 35829a12adb4..508187af2a8c 100644 --- a/src/components/ImageView/index.native.js +++ b/src/components/ImageView/index.native.js @@ -221,7 +221,7 @@ class ImageView extends PureComponent { // due to ImageZoom shouldShowLoadingIndicator ? styles.opacity0 : styles.opacity1, ]} - disableTransformation={false} + disableTransformation source={{uri: this.props.url}} isAuthTokenRequired={this.props.isAuthTokenRequired} resizeMode={Image.resizeMode.contain} From 55c3af29b5b8b5e73fda3fbe7160f5974b347400 Mon Sep 17 00:00:00 2001 From: ArekChr Date: Mon, 27 Mar 2023 13:20:42 +0200 Subject: [PATCH 4/4] fix: link latest working RNFS fork --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 741bf5afb7ce..3e39010462e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "react-native-config": "^1.4.5", "react-native-device-info": "^10.3.0", "react-native-document-picker": "^8.0.0", - "react-native-fast-image": "^8.6.3", + "react-native-fast-image": "git+https://github.com/Expensify/react-native-fast-image.git#afedf204bfc253d18f08fdcc5356a2bb82f6a87c", "react-native-gesture-handler": "2.9.0", "react-native-google-places-autocomplete": "git+https://github.com/Expensify/react-native-google-places-autocomplete.git#e12768f1542e7982d90f6449798f0d6b7f18f192", "react-native-haptic-feedback": "^1.13.0", @@ -34577,8 +34577,8 @@ }, "node_modules/react-native-fast-image": { "version": "8.6.3", - "resolved": "git+ssh://git@github.com/Expensify/react-native-fast-image.git#bef666720ca00272c051a0165a056a2dc07e9deb", - "integrity": "sha512-JIyLRVzUgZq89jchYkNFMp/55MA/ZknFwdJur/CKopmWKfa3e2uYdwYeFp8mAMAkOnn74uupt+IWSORy5qZ5qQ==", + "resolved": "git+ssh://git@github.com/Expensify/react-native-fast-image.git#afedf204bfc253d18f08fdcc5356a2bb82f6a87c", + "integrity": "sha512-jfARLcakkTtqh9jVkGWkJ+3zlpMmcoGH/6LHdnLuestM90Tn3cTPjWfWQloCYJmFwK/O2f4m1SHp1BOs0VR+cw==", "license": "(MIT AND Apache-2.0)", "peerDependencies": { "react": "^17 || ^18", @@ -64274,9 +64274,9 @@ } }, "react-native-fast-image": { - "version": "git+ssh://git@github.com/Expensify/react-native-fast-image.git#bef666720ca00272c051a0165a056a2dc07e9deb", - "integrity": "sha512-JIyLRVzUgZq89jchYkNFMp/55MA/ZknFwdJur/CKopmWKfa3e2uYdwYeFp8mAMAkOnn74uupt+IWSORy5qZ5qQ==", - "from": "react-native-fast-image@^8.6.3", + "version": "git+ssh://git@github.com/Expensify/react-native-fast-image.git#afedf204bfc253d18f08fdcc5356a2bb82f6a87c", + "integrity": "sha512-jfARLcakkTtqh9jVkGWkJ+3zlpMmcoGH/6LHdnLuestM90Tn3cTPjWfWQloCYJmFwK/O2f4m1SHp1BOs0VR+cw==", + "from": "react-native-fast-image@git+https://github.com/Expensify/react-native-fast-image.git#afedf204bfc253d18f08fdcc5356a2bb82f6a87c", "requires": {} }, "react-native-flipper": { diff --git a/package.json b/package.json index 18c3e7647fda..5867e5433d6c 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "react-native-config": "^1.4.5", "react-native-device-info": "^10.3.0", "react-native-document-picker": "^8.0.0", - "react-native-fast-image": "git+https://github.com/Expensify/react-native-fast-image.git#bef666720ca00272c051a0165a056a2dc07e9deb", + "react-native-fast-image": "git+https://github.com/Expensify/react-native-fast-image.git#afedf204bfc253d18f08fdcc5356a2bb82f6a87c", "react-native-gesture-handler": "2.9.0", "react-native-google-places-autocomplete": "git+https://github.com/Expensify/react-native-google-places-autocomplete.git#e12768f1542e7982d90f6449798f0d6b7f18f192", "react-native-haptic-feedback": "^1.13.0",