react-native-fast-image 9.3.6 → 10.0.0

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.
Files changed (76) hide show
  1. package/README.md +87 -61
  2. package/RNFastImage.podspec +14 -9
  3. package/android/build.gradle +21 -47
  4. package/android/consumer-rules.pro +7 -7
  5. package/android/src/main/AndroidManifest.xml +1 -2
  6. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimatable.java +1 -1
  7. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimated.java +2 -2
  8. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageApng.java +2 -2
  9. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageBlur.java +4 -6
  10. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheControl.java +1 -1
  11. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheLimits.java +4 -1
  12. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheWrite.java +1 -1
  13. package/android/src/main/java/com/fastimage/FastImageCrop.java +92 -0
  14. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageEvent.java +2 -3
  15. package/android/src/main/java/com/fastimage/FastImageEvents.java +74 -0
  16. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGif.java +1 -1
  17. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlide.java +3 -3
  18. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlideModule.java +1 -1
  19. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageKeyedGlideUrl.java +1 -1
  20. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageOkHttpProgressGlideModule.java +36 -9
  21. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageRequestListener.java +6 -1
  22. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSharedDownloads.java +1 -1
  23. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSource.java +1 -1
  24. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSourceSize.java +12 -2
  25. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvg.java +3 -3
  26. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvgRenderer.java +1 -1
  27. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageUrl.java +1 -1
  28. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewConverter.java +7 -8
  29. package/android/src/main/java/com/fastimage/FastImageViewManager.java +591 -0
  30. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewModule.java +31 -28
  31. package/android/src/main/java/com/fastimage/FastImageViewPackage.java +51 -0
  32. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewWithUrl.java +362 -129
  33. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageWebGlideUrl.java +1 -1
  34. package/app.plugin.js +2 -7
  35. package/dist/index.cjs.js +276 -157
  36. package/dist/index.cjs.js.flow +33 -17
  37. package/dist/index.cjs.web.js +211 -61
  38. package/dist/index.cjs.web.js.flow +33 -17
  39. package/dist/index.d.ts +83 -58
  40. package/dist/index.js +278 -159
  41. package/dist/index.js.flow +33 -17
  42. package/dist/index.web.js +212 -62
  43. package/dist/index.web.js.flow +33 -17
  44. package/dist/objectFit.d.ts +2 -2
  45. package/dist/objectPosition.d.ts +42 -0
  46. package/dist/specs/FastImageViewNativeComponent.d.ts +48 -0
  47. package/dist/specs/NativeFastImageModule.d.ts +11 -0
  48. package/dist/warnings.d.ts +3 -0
  49. package/ios/FastImage/FFFDownsampledImage.h +4 -8
  50. package/ios/FastImage/FFFDownsampledImage.m +0 -34
  51. package/ios/FastImage/FFFastImageModule.h +8 -0
  52. package/ios/FastImage/{FFFastImageViewManager.m → FFFastImageModule.mm} +70 -59
  53. package/ios/FastImage/FFFastImageView.h +36 -7
  54. package/ios/FastImage/FFFastImageView.m +201 -164
  55. package/ios/FastImage/FFFastImageViewComponentView.h +11 -0
  56. package/ios/FastImage/FFFastImageViewComponentView.mm +325 -0
  57. package/ios/FastImage/RCTConvert+FFFastImage.h +1 -1
  58. package/ios/FastImage/RCTConvert+FFFastImage.m +7 -10
  59. package/package.json +28 -9
  60. package/src/constants.ts +28 -0
  61. package/src/index.js.flow +179 -0
  62. package/src/index.tsx +1103 -0
  63. package/src/index.web.tsx +548 -0
  64. package/src/objectFit.ts +48 -0
  65. package/src/objectPosition.ts +243 -0
  66. package/src/specs/FastImageViewNativeComponent.ts +83 -0
  67. package/src/specs/NativeFastImageModule.ts +35 -0
  68. package/src/warnings.ts +37 -0
  69. package/android/src/main/AndroidManifestNew.xml +0 -3
  70. package/android/src/main/java/com/dylanvann/fastimage/FastImageCookieHandler.java +0 -63
  71. package/android/src/main/java/com/dylanvann/fastimage/FastImageEvents.java +0 -49
  72. package/android/src/main/java/com/dylanvann/fastimage/FastImageProgressListener.java +0 -18
  73. package/android/src/main/java/com/dylanvann/fastimage/FastImageShadowNode.java +0 -21
  74. package/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java +0 -379
  75. package/android/src/main/java/com/dylanvann/fastimage/FastImageViewPackage.java +0 -27
  76. package/ios/FastImage/FFFastImageViewManager.h +0 -5
@@ -1,379 +0,0 @@
1
- package com.dylanvann.fastimage;
2
-
3
- import static com.dylanvann.fastimage.FastImageRequestListener.REACT_ON_ERROR_EVENT;
4
- import static com.dylanvann.fastimage.FastImageRequestListener.REACT_ON_LOAD_END_EVENT;
5
- import static com.dylanvann.fastimage.FastImageRequestListener.REACT_ON_LOAD_EVENT;
6
-
7
- import android.app.Activity;
8
- import android.content.Context;
9
- import android.content.ContextWrapper;
10
- import android.graphics.PorterDuff;
11
- import android.util.Log;
12
-
13
- import androidx.annotation.NonNull;
14
-
15
- import com.bumptech.glide.Glide;
16
- import com.bumptech.glide.RequestManager;
17
- import com.facebook.react.bridge.ReadableArray;
18
- import com.facebook.react.bridge.ReadableMap;
19
- import com.facebook.react.bridge.WritableMap;
20
- import com.facebook.react.bridge.WritableNativeMap;
21
- import com.facebook.react.common.MapBuilder;
22
- import com.facebook.react.uimanager.LayoutShadowNode;
23
- import com.facebook.react.uimanager.SimpleViewManager;
24
- import com.facebook.react.bridge.ReactContext;
25
- import com.facebook.react.bridge.UiThreadUtil;
26
- import com.facebook.react.uimanager.ThemedReactContext;
27
- import com.facebook.react.uimanager.PixelUtil;
28
- import com.facebook.react.uimanager.PointerEvents;
29
- import com.facebook.react.uimanager.annotations.ReactProp;
30
- import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
31
-
32
- import java.util.ArrayList;
33
- import java.util.HashMap;
34
- import java.util.LinkedHashSet;
35
- import java.util.List;
36
- import java.util.Locale;
37
- import java.util.Map;
38
- import java.util.Set;
39
- import java.util.concurrent.atomic.AtomicLong;
40
-
41
- import javax.annotation.Nullable;
42
-
43
- class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> {
44
-
45
- static final String REACT_CLASS = "FastImageView";
46
- static final String REACT_ON_LOAD_START_EVENT = "onFastImageLoadStart";
47
- static final String REACT_ON_PROGRESS_EVENT = "onFastImageProgress";
48
- static final String LOG_TAG = "FastImage";
49
- // Download progress, by the key downloads are shared by
50
- // (FastImageSharedDownloads.key): the views that get it, those with an onProgress from
51
- // their load's onLoadStart to its onLoad or onError, and the latest step a
52
- // download reported, until the UI thread sends it. The UI thread adds and
53
- // removes views, and downloads report steps on their own threads: only
54
- // used under its lock.
55
- private static final Map<String, Progress> PROGRESS = new HashMap<>();
56
- // Numbers the steps downloads report, so a view can tell those reported
57
- // before its load started (see FastImageViewWithUrl.takesProgress).
58
- private static final AtomicLong REPORTED_STEPS = new AtomicLong();
59
- // Whether any view gets progress (set under PROGRESS's lock), so downloads
60
- // can skip reporting without taking any lock.
61
- private static volatile boolean tracking = false;
62
-
63
- private static final class Progress {
64
- final Set<FastImageViewWithUrl> views = new LinkedHashSet<>();
65
- // A step waits to be sent: later ones replace it meanwhile, so a url
66
- // has at most one post to the UI thread at a time.
67
- boolean posted;
68
- long loaded;
69
- long total;
70
- long step;
71
- }
72
-
73
- @NonNull
74
- @Override
75
- public String getName() {
76
- return REACT_CLASS;
77
- }
78
-
79
- @NonNull
80
- @Override
81
- protected FastImageViewWithUrl createViewInstance(@NonNull ThemedReactContext reactContext) {
82
- // Each view keeps the RequestManager for its own Activity. A single one
83
- // shared by all views kept the last view's Activity alive after it was
84
- // destroyed, and gave views another Activity's manager (#492).
85
- RequestManager requestManager = null;
86
- FastImageGlide.get(reactContext);
87
- if (isValidContextForGlide(reactContext)) {
88
- requestManager = Glide.with(reactContext);
89
- } else if (getActivityFromContext(reactContext) == null) {
90
- // Not in an Activity (e.g. a root view created with the application
91
- // context): load with the application context, instead of leaving
92
- // requestManager null and never loading (#520).
93
- requestManager = Glide.with(reactContext.getApplicationContext());
94
- }
95
-
96
- return new FastImageViewWithUrl(reactContext, requestManager);
97
- }
98
-
99
- @ReactProp(name = "source")
100
- public void setSource(FastImageViewWithUrl view, @Nullable ReadableMap source) {
101
- view.setSource(source);
102
- }
103
-
104
- @ReactProp(name = "sources")
105
- public void setSources(FastImageViewWithUrl view, @Nullable ReadableArray sources) {
106
- view.setSources(sources);
107
- }
108
-
109
- @ReactProp(name = "defaultSource")
110
- public void setDefaultSource(FastImageViewWithUrl view, @Nullable String source) {
111
- view.setDefaultSource(
112
- ResourceDrawableIdHelper.getInstance()
113
- .getResourceDrawable(view.getContext(), source));
114
- }
115
-
116
- // React Native's View manager handles pointerEvents; a SimpleViewManager
117
- // doesn't. Parsed here: PointerEvents.parsePointerEvents isn't in every
118
- // supported React Native version.
119
- @ReactProp(name = "pointerEvents")
120
- public void setPointerEvents(FastImageViewWithUrl view, @Nullable String pointerEvents) {
121
- view.setPointerEvents(pointerEvents == null
122
- ? PointerEvents.AUTO
123
- : PointerEvents.valueOf(pointerEvents.toUpperCase(Locale.US).replace('-', '_')));
124
- }
125
-
126
- @ReactProp(name = "tintColor", customType = "Color")
127
- public void setTintColor(FastImageViewWithUrl view, @Nullable Integer color) {
128
- if (color == null) {
129
- view.clearColorFilter();
130
- } else {
131
- view.setColorFilter(color, PorterDuff.Mode.SRC_IN);
132
- }
133
- }
134
-
135
- @ReactProp(name = "recyclingKey")
136
- public void setRecyclingKey(FastImageViewWithUrl view, @Nullable String recyclingKey) {
137
- view.setRecyclingKey(recyclingKey);
138
- }
139
-
140
- @ReactProp(name = "loopCount", defaultInt = -1)
141
- public void setLoopCount(FastImageViewWithUrl view, int loopCount) {
142
- view.setLoopCount(loopCount);
143
- }
144
-
145
- @ReactProp(name = "imageRendering")
146
- public void setImageRendering(FastImageViewWithUrl view, @Nullable String imageRendering) {
147
- view.setImageRendering(imageRendering);
148
- }
149
-
150
- @ReactProp(name = "downsample", defaultBoolean = true)
151
- public void setDownsample(FastImageViewWithUrl view, boolean downsample) {
152
- view.setDownsample(downsample);
153
- }
154
-
155
- @ReactProp(name = "blurRadius")
156
- public void setBlurRadius(FastImageViewWithUrl view, float blurRadius) {
157
- view.setBlurRadius(PixelUtil.toPixelFromDIP(blurRadius));
158
- }
159
-
160
- @ReactProp(name = "transitionDuration")
161
- public void setTransitionDuration(FastImageViewWithUrl view, int transitionDuration) {
162
- view.setTransitionDuration(transitionDuration);
163
- }
164
-
165
- @ReactProp(name = "transitionBetweenImages")
166
- public void setTransitionBetweenImages(FastImageViewWithUrl view, boolean betweenImages) {
167
- view.setTransitionBetweenImages(betweenImages);
168
- }
169
-
170
- @ReactProp(name = "transitionSkipOnCacheHit")
171
- public void setTransitionSkipOnCacheHit(FastImageViewWithUrl view, @Nullable String skipOnCacheHit) {
172
- view.setTransitionSkipOnCacheHit(skipOnCacheHit);
173
- }
174
-
175
- @ReactProp(name = "paused")
176
- public void setPaused(FastImageViewWithUrl view, boolean paused) {
177
- view.setPaused(paused);
178
- }
179
-
180
- // Set when the image has an onProgress (see onDownloadProgress).
181
- @ReactProp(name = "trackProgress")
182
- public void setTrackProgress(FastImageViewWithUrl view, boolean trackProgress) {
183
- view.setTrackProgress(trackProgress);
184
- }
185
-
186
- @ReactProp(name = "resizeMode")
187
- public void setResizeMode(FastImageViewWithUrl view, String resizeMode) {
188
- // repeat fills the view with the tiled image (see setImageDrawable).
189
- boolean repeat = "repeat".equals(resizeMode);
190
- final FastImageViewWithUrl.ScaleType scaleType =
191
- repeat ? FastImageViewWithUrl.ScaleType.FIT_XY : FastImageViewConverter.getScaleType(resizeMode);
192
- view.setResizeMode(scaleType, repeat, "center".equals(resizeMode));
193
- }
194
-
195
- @Override
196
- public void onDropViewInstance(@NonNull FastImageViewWithUrl view) {
197
- // Cancels its request, and nothing loads or tracks progress for it
198
- // any more (the progress map doesn't keep it, or its Activity).
199
- view.drop();
200
-
201
- super.onDropViewInstance(view);
202
- }
203
-
204
- @Override
205
- public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
206
- return MapBuilder.<String, Object>builder()
207
- .put(REACT_ON_LOAD_START_EVENT, MapBuilder.of("registrationName", REACT_ON_LOAD_START_EVENT))
208
- .put(REACT_ON_PROGRESS_EVENT, MapBuilder.of("registrationName", REACT_ON_PROGRESS_EVENT))
209
- .put(REACT_ON_LOAD_EVENT, MapBuilder.of("registrationName", REACT_ON_LOAD_EVENT))
210
- .put(REACT_ON_ERROR_EVENT, MapBuilder.of("registrationName", REACT_ON_ERROR_EVENT))
211
- .put(REACT_ON_LOAD_END_EVENT, MapBuilder.of("registrationName", REACT_ON_LOAD_END_EVENT))
212
- .build();
213
- }
214
-
215
- // On the UI thread (FastImageViewWithUrl's updateProgressTracking).
216
- static void trackProgress(String key, FastImageViewWithUrl view) {
217
- synchronized (PROGRESS) {
218
- Progress progress = PROGRESS.get(key);
219
- if (progress == null) {
220
- progress = new Progress();
221
- PROGRESS.put(key, progress);
222
- }
223
- progress.views.add(view);
224
- tracking = true;
225
- }
226
- }
227
-
228
- // On the UI thread. A key's entry goes once it has no views.
229
- static void untrackProgress(String key, FastImageViewWithUrl view) {
230
- synchronized (PROGRESS) {
231
- Progress progress = PROGRESS.get(key);
232
- if (progress == null) return;
233
- progress.views.remove(view);
234
- if (progress.views.isEmpty()) PROGRESS.remove(key);
235
- tracking = !PROGRESS.isEmpty();
236
- }
237
- }
238
-
239
- // Whether any view gets progress now (a hint: a view can start loading
240
- // just after).
241
- static boolean wantsProgress() {
242
- return tracking;
243
- }
244
-
245
- // The latest step downloads reported (for a load that starts now).
246
- static long progressStep() {
247
- return REPORTED_STEPS.get();
248
- }
249
-
250
- // A download's progress (FastImageSharedDownloads), on its thread, which
251
- // only notes it if a view wants it (so downloads of images without an
252
- // onProgress post nothing). It's sent from the UI thread, where
253
- // views start and end their loads: a view only gets it during its own load,
254
- // not after its onLoad or once it loads again, and progress posted during
255
- // a download comes before the onLoad Glide posts after it.
256
- static void onDownloadProgress(final String key, long loaded, long total) {
257
- synchronized (PROGRESS) {
258
- Progress progress = PROGRESS.get(key);
259
- if (progress == null) return;
260
- // While a post is waiting, it keeps the furthest step: another
261
- // download of the key may report one behind it meanwhile. A step
262
- // kept keeps its number, so a load that started after it (e.g. a
263
- // reload, whose download reports behind it) doesn't take it.
264
- if (!progress.posted || (double) loaded / total >= (double) progress.loaded / progress.total) {
265
- progress.loaded = loaded;
266
- progress.total = total;
267
- progress.step = REPORTED_STEPS.incrementAndGet();
268
- }
269
- if (progress.posted) return;
270
- progress.posted = true;
271
- }
272
- UiThreadUtil.runOnUiThread(new Runnable() {
273
- @Override
274
- public void run() {
275
- sendProgress(key);
276
- }
277
- });
278
- }
279
-
280
- private static void sendProgress(String key) {
281
- List<FastImageViewWithUrl> views;
282
- long loaded;
283
- long total;
284
- long step;
285
- synchronized (PROGRESS) {
286
- Progress progress = PROGRESS.get(key);
287
- // Sent already, or no view wants it any more.
288
- if (progress == null || !progress.posted) return;
289
- progress.posted = false;
290
- loaded = progress.loaded;
291
- total = progress.total;
292
- step = progress.step;
293
- views = new ArrayList<>(progress.views);
294
- }
295
- for (FastImageViewWithUrl view : views) {
296
- if (!view.takesProgress(step, loaded, total)) continue;
297
- WritableMap event = new WritableNativeMap();
298
- event.putInt("loaded", (int) loaded);
299
- event.putInt("total", (int) total);
300
- try {
301
- FastImageEvents.send(view, REACT_ON_PROGRESS_EVENT, event);
302
- } catch (RuntimeException e) {
303
- // E.g. the view's React instance is gone: progress isn't worth
304
- // crashing the app for.
305
- // (Not the key: it has the request's headers.)
306
- Log.w(LOG_TAG, "Couldn't send onProgress", e);
307
- }
308
- }
309
- }
310
-
311
- private static boolean isValidContextForGlide(final Context context) {
312
- Activity activity = getActivityFromContext(context);
313
-
314
- if (activity == null) {
315
- return false;
316
- }
317
-
318
- return !isActivityDestroyed(activity);
319
- }
320
-
321
- // A view's context is the ThemedReactContext it was created with, but below
322
- // Android 5 (API 21) AppCompatImageView wraps it in a TintContextWrapper, so
323
- // it can't be cast directly (#840). Unwrap until the ReactContext.
324
- @Nullable
325
- static ReactContext getReactContext(Context context) {
326
- while (context instanceof ContextWrapper) {
327
- if (context instanceof ReactContext) {
328
- return (ReactContext) context;
329
- }
330
- context = ((ContextWrapper) context).getBaseContext();
331
- }
332
- return null;
333
- }
334
-
335
- private static Activity getActivityFromContext(final Context context) {
336
- if (context instanceof Activity) {
337
- return (Activity) context;
338
- }
339
-
340
- if (context instanceof ThemedReactContext) {
341
- final Context baseContext = ((ThemedReactContext) context).getBaseContext();
342
- if (baseContext instanceof Activity) {
343
- return (Activity) baseContext;
344
- }
345
-
346
- if (baseContext instanceof ContextWrapper) {
347
- final ContextWrapper contextWrapper = (ContextWrapper) baseContext;
348
- final Context wrapperBaseContext = contextWrapper.getBaseContext();
349
- if (wrapperBaseContext instanceof Activity) {
350
- return (Activity) wrapperBaseContext;
351
- }
352
- }
353
- }
354
-
355
- return null;
356
- }
357
-
358
- private static boolean isActivityDestroyed(Activity activity) {
359
- return activity.isDestroyed() || activity.isFinishing();
360
- }
361
-
362
- // Legacy architecture only; the New Architecture doesn't use shadow nodes.
363
- @NonNull
364
- @Override
365
- public LayoutShadowNode createShadowNodeInstance() {
366
- return new FastImageShadowNode();
367
- }
368
-
369
- @Override
370
- public void updateExtraData(@NonNull FastImageViewWithUrl view, Object extraData) {
371
- if (extraData == FastImageShadowNode.ZERO_LAYOUT) view.onZeroLayout();
372
- }
373
-
374
- @Override
375
- protected void onAfterUpdateTransaction(@NonNull FastImageViewWithUrl view) {
376
- super.onAfterUpdateTransaction(view);
377
- view.onAfterUpdate(this, view.requestManager);
378
- }
379
- }
@@ -1,27 +0,0 @@
1
- package com.dylanvann.fastimage;
2
-
3
- import androidx.annotation.NonNull;
4
-
5
- import com.facebook.react.ReactPackage;
6
- import com.facebook.react.bridge.NativeModule;
7
- import com.facebook.react.bridge.ReactApplicationContext;
8
- import com.facebook.react.uimanager.ViewManager;
9
-
10
- import java.util.Collections;
11
- import java.util.List;
12
-
13
- public class FastImageViewPackage implements ReactPackage {
14
- @NonNull
15
- @Override
16
- public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
17
- FastImageCacheLimits.loadInBackground(reactContext);
18
- return Collections.<NativeModule>singletonList(new FastImageViewModule(reactContext));
19
- }
20
-
21
- @NonNull
22
- @Override
23
- public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
24
- FastImageCacheLimits.loadInBackground(reactContext);
25
- return Collections.<ViewManager>singletonList(new FastImageViewManager());
26
- }
27
- }
@@ -1,5 +0,0 @@
1
- #import <React/RCTViewManager.h>
2
-
3
- @interface FFFastImageViewManager : RCTViewManager
4
-
5
- @end