react-native-fast-image 8.6.33 → 8.6.35

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.
@@ -0,0 +1,45 @@
1
+ package com.dylanvann.fastimage;
2
+
3
+ import com.facebook.react.bridge.WritableMap;
4
+ import com.facebook.react.uimanager.events.Event;
5
+ import com.facebook.react.uimanager.events.RCTEventEmitter;
6
+
7
+ // An event for a FastImage view, sent with the EventDispatcher (see
8
+ // FastImageEvents) instead of the RCTEventEmitter JS module, which the New
9
+ // Architecture warns about on every event.
10
+ class FastImageEvent extends Event<FastImageEvent> {
11
+ private final String name;
12
+ private final WritableMap data;
13
+
14
+ // Event(viewTag) works back to React Native 0.60. Without a surface id,
15
+ // Fabric finds the view by its tag.
16
+ @SuppressWarnings("deprecation")
17
+ FastImageEvent(int viewTag, String name, WritableMap data) {
18
+ super(viewTag);
19
+ this.name = name;
20
+ this.data = data;
21
+ }
22
+
23
+ @Override
24
+ public String getEventName() {
25
+ return name;
26
+ }
27
+
28
+ // Every event reaches JS, e.g. each progress update, as before.
29
+ @Override
30
+ public boolean canCoalesce() {
31
+ return false;
32
+ }
33
+
34
+ // Overrides Event.getEventData on React Native 0.65+ (not on older ones,
35
+ // hence no @Override).
36
+ protected WritableMap getEventData() {
37
+ return data;
38
+ }
39
+
40
+ @Override
41
+ @SuppressWarnings("deprecation")
42
+ public void dispatch(RCTEventEmitter rctEventEmitter) {
43
+ rctEventEmitter.receiveEvent(getViewTag(), name, data);
44
+ }
45
+ }
@@ -0,0 +1,60 @@
1
+ package com.dylanvann.fastimage;
2
+
3
+ import android.view.View;
4
+
5
+ import androidx.annotation.Nullable;
6
+
7
+ import com.facebook.react.bridge.Arguments;
8
+ import com.facebook.react.bridge.ReactContext;
9
+ import com.facebook.react.bridge.WritableMap;
10
+ import com.facebook.react.uimanager.UIManagerModule;
11
+ import com.facebook.react.uimanager.events.EventDispatcher;
12
+
13
+ import java.lang.reflect.Method;
14
+
15
+ // Sends FastImage view events through React Native's EventDispatcher.
16
+ final class FastImageEvents {
17
+ // UIManagerHelper.getEventDispatcherForReactTag (React Native 0.63+, also
18
+ // bridgeless). Looked up by reflection so older versions still compile.
19
+ @Nullable
20
+ private static final Method GET_EVENT_DISPATCHER = findGetEventDispatcher();
21
+
22
+ private FastImageEvents() {
23
+ }
24
+
25
+ static void send(View view, String name) {
26
+ send(view, name, Arguments.createMap());
27
+ }
28
+
29
+ static void send(View view, String name, WritableMap data) {
30
+ ReactContext context = FastImageViewManager.getReactContext(view.getContext());
31
+ if (context == null) return;
32
+ EventDispatcher dispatcher = eventDispatcher(context, view.getId());
33
+ if (dispatcher != null) {
34
+ dispatcher.dispatchEvent(new FastImageEvent(view.getId(), name, data));
35
+ }
36
+ }
37
+
38
+ @Nullable
39
+ private static EventDispatcher eventDispatcher(ReactContext context, int viewTag) {
40
+ if (GET_EVENT_DISPATCHER != null) {
41
+ try {
42
+ return (EventDispatcher) GET_EVENT_DISPATCHER.invoke(null, context, viewTag);
43
+ } catch (Exception ignored) {
44
+ // Fall back to the UIManagerModule's.
45
+ }
46
+ }
47
+ UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
48
+ return uiManager == null ? null : uiManager.getEventDispatcher();
49
+ }
50
+
51
+ @Nullable
52
+ private static Method findGetEventDispatcher() {
53
+ try {
54
+ return Class.forName("com.facebook.react.uimanager.UIManagerHelper")
55
+ .getMethod("getEventDispatcherForReactTag", ReactContext.class, int.class);
56
+ } catch (Exception e) {
57
+ return null;
58
+ }
59
+ }
60
+ }
@@ -11,8 +11,6 @@ import com.bumptech.glide.request.target.ImageViewTarget;
11
11
  import com.bumptech.glide.request.target.Target;
12
12
  import com.facebook.react.bridge.WritableMap;
13
13
  import com.facebook.react.bridge.WritableNativeMap;
14
- import com.facebook.react.bridge.ReactContext;
15
- import com.facebook.react.uimanager.events.RCTEventEmitter;
16
14
 
17
15
  public class FastImageRequestListener implements RequestListener<Drawable> {
18
16
  static final String REACT_ON_ERROR_EVENT = "onFastImageError";
@@ -33,14 +31,8 @@ public class FastImageRequestListener implements RequestListener<Drawable> {
33
31
  return false;
34
32
  }
35
33
  FastImageViewWithUrl view = (FastImageViewWithUrl) ((ImageViewTarget) target).getView();
36
- ReactContext context = FastImageViewManager.getReactContext(view.getContext());
37
- if (context == null) {
38
- return false;
39
- }
40
- RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class);
41
- int viewId = view.getId();
42
- eventEmitter.receiveEvent(viewId, REACT_ON_ERROR_EVENT, new WritableNativeMap());
43
- eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_END_EVENT, new WritableNativeMap());
34
+ FastImageEvents.send(view, REACT_ON_ERROR_EVENT);
35
+ FastImageEvents.send(view, REACT_ON_LOAD_END_EVENT);
44
36
  return false;
45
37
  }
46
38
 
@@ -70,16 +62,10 @@ public class FastImageRequestListener implements RequestListener<Drawable> {
70
62
  }
71
63
 
72
64
  private static void sendLoad(FastImageViewWithUrl view, int[] size) {
73
- ReactContext context = FastImageViewManager.getReactContext(view.getContext());
74
- if (context == null) {
75
- return;
76
- }
77
- RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class);
78
- int viewId = view.getId();
79
65
  WritableMap event = new WritableNativeMap();
80
66
  event.putInt("width", size[0]);
81
67
  event.putInt("height", size[1]);
82
- eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_EVENT, event);
83
- eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_END_EVENT, new WritableNativeMap());
68
+ FastImageEvents.send(view, REACT_ON_LOAD_EVENT, event);
69
+ FastImageEvents.send(view, REACT_ON_LOAD_END_EVENT);
84
70
  }
85
71
  }
@@ -23,7 +23,6 @@ import com.facebook.react.uimanager.SimpleViewManager;
23
23
  import com.facebook.react.bridge.ReactContext;
24
24
  import com.facebook.react.uimanager.ThemedReactContext;
25
25
  import com.facebook.react.uimanager.annotations.ReactProp;
26
- import com.facebook.react.uimanager.events.RCTEventEmitter;
27
26
  import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
28
27
 
29
28
  import java.util.List;
@@ -39,9 +38,6 @@ class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> imple
39
38
  static final String REACT_ON_PROGRESS_EVENT = "onFastImageProgress";
40
39
  private static final Map<String, List<FastImageViewWithUrl>> VIEWS_FOR_URLS = new WeakHashMap<>();
41
40
 
42
- @Nullable
43
- private RequestManager requestManager = null;
44
-
45
41
  @NonNull
46
42
  @Override
47
43
  public String getName() {
@@ -51,6 +47,10 @@ class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> imple
51
47
  @NonNull
52
48
  @Override
53
49
  protected FastImageViewWithUrl createViewInstance(@NonNull ThemedReactContext reactContext) {
50
+ // Each view keeps the RequestManager for its own Activity. A single one
51
+ // shared by all views kept the last view's Activity alive after it was
52
+ // destroyed, and gave views another Activity's manager (#492).
53
+ RequestManager requestManager = null;
54
54
  if (isValidContextForGlide(reactContext)) {
55
55
  requestManager = Glide.with(reactContext);
56
56
  } else if (getActivityFromContext(reactContext) == null) {
@@ -60,7 +60,7 @@ class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> imple
60
60
  requestManager = Glide.with(reactContext.getApplicationContext());
61
61
  }
62
62
 
63
- return new FastImageViewWithUrl(reactContext);
63
+ return new FastImageViewWithUrl(reactContext, requestManager);
64
64
  }
65
65
 
66
66
  @ReactProp(name = "source")
@@ -93,7 +93,7 @@ class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> imple
93
93
  @Override
94
94
  public void onDropViewInstance(@NonNull FastImageViewWithUrl view) {
95
95
  // This will cancel existing requests.
96
- view.clearView(requestManager);
96
+ view.clearView(view.requestManager);
97
97
 
98
98
  // Same key as when the view was tracked (toStringUrl, not toString,
99
99
  // which differ for urls that need escaping).
@@ -121,11 +121,7 @@ class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> imple
121
121
  WritableMap event = new WritableNativeMap();
122
122
  event.putInt("loaded", (int) bytesRead);
123
123
  event.putInt("total", (int) expectedLength);
124
- ReactContext context = getReactContext(view.getContext());
125
- if (context == null) continue;
126
- RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class);
127
- int viewId = view.getId();
128
- eventEmitter.receiveEvent(viewId, REACT_ON_PROGRESS_EVENT, event);
124
+ FastImageEvents.send(view, REACT_ON_PROGRESS_EVENT, event);
129
125
  }
130
126
  }
131
127
  }
@@ -206,6 +202,6 @@ class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> imple
206
202
  @Override
207
203
  protected void onAfterUpdateTransaction(@NonNull FastImageViewWithUrl view) {
208
204
  super.onAfterUpdateTransaction(view);
209
- view.onAfterUpdate(this, requestManager, VIEWS_FOR_URLS);
205
+ view.onAfterUpdate(this, view.requestManager, VIEWS_FOR_URLS);
210
206
  }
211
207
  }
@@ -18,8 +18,6 @@ import com.bumptech.glide.request.Request;
18
18
  import com.facebook.react.bridge.ReadableMap;
19
19
  import com.facebook.react.bridge.WritableMap;
20
20
  import com.facebook.react.bridge.WritableNativeMap;
21
- import com.facebook.react.bridge.ReactContext;
22
- import com.facebook.react.uimanager.events.RCTEventEmitter;
23
21
 
24
22
  import java.util.ArrayList;
25
23
  import java.util.Collections;
@@ -34,9 +32,13 @@ class FastImageViewWithUrl extends AppCompatImageView {
34
32
  private Drawable mDefaultSource = null;
35
33
 
36
34
  public GlideUrl glideUrl;
35
+ // Null when the view was created in a destroyed Activity (nothing loads).
36
+ @Nullable
37
+ final RequestManager requestManager;
37
38
 
38
- public FastImageViewWithUrl(Context context) {
39
+ public FastImageViewWithUrl(Context context, @Nullable RequestManager requestManager) {
39
40
  super(context);
41
+ this.requestManager = requestManager;
40
42
  }
41
43
 
42
44
  public void setSource(@Nullable ReadableMap source) {
@@ -97,15 +99,10 @@ class FastImageViewWithUrl extends AppCompatImageView {
97
99
  // resolved: fire onError and onLoadEnd and show defaultSource, as on iOS
98
100
  // (#1028, #945).
99
101
  if (mSource != null && (imageSource == null || imageSource.getUri().toString().length() == 0)) {
100
- ReactContext context = FastImageViewManager.getReactContext(getContext());
101
- if (context != null) {
102
- RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class);
103
- int viewId = getId();
104
- WritableMap event = new WritableNativeMap();
105
- event.putString("message", "Invalid source prop:" + mSource);
106
- eventEmitter.receiveEvent(viewId, REACT_ON_ERROR_EVENT, event);
107
- eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_END_EVENT, new WritableNativeMap());
108
- }
102
+ WritableMap event = new WritableNativeMap();
103
+ event.putString("message", "Invalid source prop:" + mSource);
104
+ FastImageEvents.send(this, REACT_ON_ERROR_EVENT, event);
105
+ FastImageEvents.send(this, REACT_ON_LOAD_END_EVENT);
109
106
 
110
107
  // Cancel existing requests.
111
108
  clearView(requestManager);
@@ -140,15 +137,9 @@ class FastImageViewWithUrl extends AppCompatImageView {
140
137
  }
141
138
  }
142
139
 
143
- ReactContext reactContext = FastImageViewManager.getReactContext(getContext());
144
- if (imageSource != null && reactContext != null) {
140
+ if (imageSource != null) {
145
141
  // This is an orphan even without a load/loadend when only loading a placeholder
146
- RCTEventEmitter eventEmitter = reactContext.getJSModule(RCTEventEmitter.class);
147
- int viewId = this.getId();
148
-
149
- eventEmitter.receiveEvent(viewId,
150
- FastImageViewManager.REACT_ON_LOAD_START_EVENT,
151
- new WritableNativeMap());
142
+ FastImageEvents.send(this, FastImageViewManager.REACT_ON_LOAD_START_EVENT);
152
143
  }
153
144
 
154
145
  if (requestManager != null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-fast-image",
3
- "version": "8.6.33",
3
+ "version": "8.6.35",
4
4
  "description": "🚩 FastImage, performant React Native image component.",
5
5
  "keywords": [
6
6
  "cache",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "https://github.com/DylanVann/react-native-fast-image.git"
18
+ "url": "git+https://github.com/DylanVann/react-native-fast-image.git"
19
19
  },
20
20
  "license": "(MIT AND Apache-2.0)",
21
21
  "author": "Dylan Vann <dylan@dylanvann.com> (https://dylanvann.com)",