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.
- package/README.md +87 -61
- package/RNFastImage.podspec +14 -9
- package/android/build.gradle +21 -47
- package/android/consumer-rules.pro +7 -7
- package/android/src/main/AndroidManifest.xml +1 -2
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimatable.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimated.java +2 -2
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageApng.java +2 -2
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageBlur.java +4 -6
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheControl.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheLimits.java +4 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheWrite.java +1 -1
- package/android/src/main/java/com/fastimage/FastImageCrop.java +92 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageEvent.java +2 -3
- package/android/src/main/java/com/fastimage/FastImageEvents.java +74 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGif.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlide.java +3 -3
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlideModule.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageKeyedGlideUrl.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageOkHttpProgressGlideModule.java +36 -9
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageRequestListener.java +6 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSharedDownloads.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSource.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSourceSize.java +12 -2
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvg.java +3 -3
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvgRenderer.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageUrl.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewConverter.java +7 -8
- package/android/src/main/java/com/fastimage/FastImageViewManager.java +591 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewModule.java +31 -28
- package/android/src/main/java/com/fastimage/FastImageViewPackage.java +51 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewWithUrl.java +362 -129
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageWebGlideUrl.java +1 -1
- package/app.plugin.js +2 -7
- package/dist/index.cjs.js +276 -157
- package/dist/index.cjs.js.flow +33 -17
- package/dist/index.cjs.web.js +211 -61
- package/dist/index.cjs.web.js.flow +33 -17
- package/dist/index.d.ts +83 -58
- package/dist/index.js +278 -159
- package/dist/index.js.flow +33 -17
- package/dist/index.web.js +212 -62
- package/dist/index.web.js.flow +33 -17
- package/dist/objectFit.d.ts +2 -2
- package/dist/objectPosition.d.ts +42 -0
- package/dist/specs/FastImageViewNativeComponent.d.ts +48 -0
- package/dist/specs/NativeFastImageModule.d.ts +11 -0
- package/dist/warnings.d.ts +3 -0
- package/ios/FastImage/FFFDownsampledImage.h +4 -8
- package/ios/FastImage/FFFDownsampledImage.m +0 -34
- package/ios/FastImage/FFFastImageModule.h +8 -0
- package/ios/FastImage/{FFFastImageViewManager.m → FFFastImageModule.mm} +70 -59
- package/ios/FastImage/FFFastImageView.h +36 -7
- package/ios/FastImage/FFFastImageView.m +201 -164
- package/ios/FastImage/FFFastImageViewComponentView.h +11 -0
- package/ios/FastImage/FFFastImageViewComponentView.mm +325 -0
- package/ios/FastImage/RCTConvert+FFFastImage.h +1 -1
- package/ios/FastImage/RCTConvert+FFFastImage.m +7 -10
- package/package.json +28 -9
- package/src/constants.ts +28 -0
- package/src/index.js.flow +179 -0
- package/src/index.tsx +1103 -0
- package/src/index.web.tsx +548 -0
- package/src/objectFit.ts +48 -0
- package/src/objectPosition.ts +243 -0
- package/src/specs/FastImageViewNativeComponent.ts +83 -0
- package/src/specs/NativeFastImageModule.ts +35 -0
- package/src/warnings.ts +37 -0
- package/android/src/main/AndroidManifestNew.xml +0 -3
- package/android/src/main/java/com/dylanvann/fastimage/FastImageCookieHandler.java +0 -63
- package/android/src/main/java/com/dylanvann/fastimage/FastImageEvents.java +0 -49
- package/android/src/main/java/com/dylanvann/fastimage/FastImageProgressListener.java +0 -18
- package/android/src/main/java/com/dylanvann/fastimage/FastImageShadowNode.java +0 -21
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java +0 -379
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewPackage.java +0 -27
- package/ios/FastImage/FFFastImageViewManager.h +0 -5
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
package com.fastimage;
|
|
2
|
+
|
|
3
|
+
import android.graphics.Bitmap;
|
|
4
|
+
import android.graphics.Canvas;
|
|
5
|
+
import android.graphics.Matrix;
|
|
6
|
+
import android.graphics.Paint;
|
|
7
|
+
|
|
8
|
+
import androidx.annotation.NonNull;
|
|
9
|
+
|
|
10
|
+
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
|
|
11
|
+
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
|
|
12
|
+
import com.bumptech.glide.load.resource.bitmap.TransformationUtils;
|
|
13
|
+
|
|
14
|
+
import java.nio.ByteBuffer;
|
|
15
|
+
import java.nio.charset.Charset;
|
|
16
|
+
import java.security.MessageDigest;
|
|
17
|
+
|
|
18
|
+
// objectFit cover with an objectPosition other than the center: Glide's
|
|
19
|
+
// CenterCrop at that position. The image is scaled to cover the view's size
|
|
20
|
+
// and the part the view shows is kept, so the bitmap is the view's size, as
|
|
21
|
+
// with CenterCrop. On each axis the image's left or top edge is at
|
|
22
|
+
// (view - image) * fraction + offset (CSS's object-position); an offset that
|
|
23
|
+
// moves it past an edge leaves that part transparent.
|
|
24
|
+
final class FastImageCrop extends BitmapTransformation {
|
|
25
|
+
private static final String ID = "com.fastimage.FastImageCrop";
|
|
26
|
+
private static final byte[] ID_BYTES = ID.getBytes(Charset.forName("UTF-8"));
|
|
27
|
+
private static final Paint PAINT = new Paint(Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
|
|
28
|
+
|
|
29
|
+
private final float x;
|
|
30
|
+
private final float xOffset;
|
|
31
|
+
private final float y;
|
|
32
|
+
private final float yOffset;
|
|
33
|
+
|
|
34
|
+
// Offsets in pixels.
|
|
35
|
+
FastImageCrop(float x, float xOffset, float y, float yOffset) {
|
|
36
|
+
this.x = x;
|
|
37
|
+
this.xOffset = xOffset;
|
|
38
|
+
this.y = y;
|
|
39
|
+
this.yOffset = yOffset;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Override
|
|
43
|
+
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
|
|
44
|
+
int width = toTransform.getWidth();
|
|
45
|
+
int height = toTransform.getHeight();
|
|
46
|
+
if (width <= 0 || height <= 0 || outWidth <= 0 || outHeight <= 0) return toTransform;
|
|
47
|
+
float scale = Math.max(outWidth / (float) width, outHeight / (float) height);
|
|
48
|
+
float shownWidth = width * scale;
|
|
49
|
+
float shownHeight = height * scale;
|
|
50
|
+
float left = Math.round((outWidth - shownWidth) * x + xOffset);
|
|
51
|
+
float top = Math.round((outHeight - shownHeight) * y + yOffset);
|
|
52
|
+
Bitmap.Config config = toTransform.getConfig() != null ? toTransform.getConfig() : Bitmap.Config.ARGB_8888;
|
|
53
|
+
// Past an edge, the view shows nothing there.
|
|
54
|
+
boolean uncovered = left > 0 || top > 0 || left + shownWidth < outWidth || top + shownHeight < outHeight;
|
|
55
|
+
if (uncovered && config == Bitmap.Config.RGB_565) config = Bitmap.Config.ARGB_8888;
|
|
56
|
+
Bitmap result = pool.get(outWidth, outHeight, config);
|
|
57
|
+
TransformationUtils.setAlpha(toTransform, result);
|
|
58
|
+
if (uncovered) {
|
|
59
|
+
result.setHasAlpha(true);
|
|
60
|
+
result.eraseColor(0);
|
|
61
|
+
}
|
|
62
|
+
Matrix matrix = new Matrix();
|
|
63
|
+
matrix.setScale(scale, scale);
|
|
64
|
+
matrix.postTranslate(left, top);
|
|
65
|
+
Canvas canvas = new Canvas(result);
|
|
66
|
+
canvas.drawBitmap(toTransform, matrix, PAINT);
|
|
67
|
+
canvas.setBitmap(null);
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@Override
|
|
72
|
+
public boolean equals(Object o) {
|
|
73
|
+
if (!(o instanceof FastImageCrop)) return false;
|
|
74
|
+
FastImageCrop other = (FastImageCrop) o;
|
|
75
|
+
return other.x == x && other.xOffset == xOffset && other.y == y && other.yOffset == yOffset;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@Override
|
|
79
|
+
public int hashCode() {
|
|
80
|
+
int hash = ID.hashCode();
|
|
81
|
+
hash = hash * 31 + Float.floatToIntBits(x);
|
|
82
|
+
hash = hash * 31 + Float.floatToIntBits(xOffset);
|
|
83
|
+
hash = hash * 31 + Float.floatToIntBits(y);
|
|
84
|
+
return hash * 31 + Float.floatToIntBits(yOffset);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Override
|
|
88
|
+
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
|
|
89
|
+
messageDigest.update(ID_BYTES);
|
|
90
|
+
messageDigest.update(ByteBuffer.allocate(16).putFloat(x).putFloat(xOffset).putFloat(y).putFloat(yOffset).array());
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.fastimage;
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.WritableMap;
|
|
4
4
|
import com.facebook.react.uimanager.events.Event;
|
|
5
5
|
|
|
6
6
|
// An event for a FastImage view, sent with the EventDispatcher (see
|
|
7
|
-
// FastImageEvents)
|
|
8
|
-
// Architecture warns about on every event.
|
|
7
|
+
// FastImageEvents).
|
|
9
8
|
class FastImageEvent extends Event<FastImageEvent> {
|
|
10
9
|
private final String name;
|
|
11
10
|
private final WritableMap data;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
package com.fastimage;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments;
|
|
4
|
+
import com.facebook.react.bridge.ReactContext;
|
|
5
|
+
import com.facebook.react.bridge.WritableMap;
|
|
6
|
+
import com.facebook.react.uimanager.UIManagerHelper;
|
|
7
|
+
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
8
|
+
|
|
9
|
+
// Sends FastImage view events through React Native's EventDispatcher.
|
|
10
|
+
final class FastImageEvents {
|
|
11
|
+
// The handledEvents prop's bits (see src/specs/FastImageViewNativeComponent.ts).
|
|
12
|
+
static final int LOAD_START = 1;
|
|
13
|
+
static final int PROGRESS = 1 << 1;
|
|
14
|
+
static final int LOAD = 1 << 2;
|
|
15
|
+
static final int ERROR = 1 << 3;
|
|
16
|
+
static final int LOAD_END = 1 << 4;
|
|
17
|
+
|
|
18
|
+
private FastImageEvents() {
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private static int bit(String name) {
|
|
22
|
+
switch (name) {
|
|
23
|
+
case FastImageViewManager.REACT_ON_LOAD_START_EVENT:
|
|
24
|
+
return LOAD_START;
|
|
25
|
+
case FastImageViewManager.REACT_ON_PROGRESS_EVENT:
|
|
26
|
+
return PROGRESS;
|
|
27
|
+
case FastImageRequestListener.REACT_ON_LOAD_EVENT:
|
|
28
|
+
return LOAD;
|
|
29
|
+
case FastImageRequestListener.REACT_ON_ERROR_EVENT:
|
|
30
|
+
return ERROR;
|
|
31
|
+
case FastImageRequestListener.REACT_ON_LOAD_END_EVENT:
|
|
32
|
+
return LOAD_END;
|
|
33
|
+
default:
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static void send(FastImageViewWithUrl view, String name) {
|
|
39
|
+
send(view, name, Arguments.createMap());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// onLoadEnd with the load's result: ok with the image's size, as onLoad
|
|
43
|
+
// sent it.
|
|
44
|
+
static void sendLoadEnd(FastImageViewWithUrl view, int width, int height) {
|
|
45
|
+
WritableMap event = Arguments.createMap();
|
|
46
|
+
event.putBoolean("ok", true);
|
|
47
|
+
event.putInt("width", width);
|
|
48
|
+
event.putInt("height", height);
|
|
49
|
+
send(view, FastImageRequestListener.REACT_ON_LOAD_END_EVENT, event);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// onLoadEnd with the load's result: not ok, with the error onError sent.
|
|
53
|
+
static void sendLoadEnd(FastImageViewWithUrl view, String error) {
|
|
54
|
+
WritableMap event = Arguments.createMap();
|
|
55
|
+
event.putBoolean("ok", false);
|
|
56
|
+
event.putString("error", error);
|
|
57
|
+
send(view, FastImageRequestListener.REACT_ON_LOAD_END_EVENT, event);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Only the events JS has a handler for: most images have none.
|
|
61
|
+
static void send(FastImageViewWithUrl view, String name, WritableMap data) {
|
|
62
|
+
if (!view.handles(bit(name))) return;
|
|
63
|
+
ReactContext context = FastImageViewManager.getReactContext(view.getContext());
|
|
64
|
+
if (context == null) return;
|
|
65
|
+
// The view's event dispatcher (Fabric, bridgeless). Deprecated from React
|
|
66
|
+
// Native 0.85; its replacement, getEventDispatcher(context), isn't in 0.83.
|
|
67
|
+
@SuppressWarnings("deprecation")
|
|
68
|
+
EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.getId());
|
|
69
|
+
if (dispatcher != null) {
|
|
70
|
+
dispatcher.dispatchEvent(new FastImageEvent(
|
|
71
|
+
UIManagerHelper.getSurfaceId(view), view.getId(), name, data));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.fastimage;
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
|
|
@@ -16,7 +16,7 @@ final class FastImageGlide {
|
|
|
16
16
|
// Set on FastImage's requests, so its decoders (animated WebP and AVIF,
|
|
17
17
|
// APNG, SVG) only take its own images: another library's images (e.g.
|
|
18
18
|
// expo-image's) keep that library's decoders.
|
|
19
|
-
static final Option<Boolean> REQUEST = Option.memory("com.
|
|
19
|
+
static final Option<Boolean> REQUEST = Option.memory("com.fastimage.Request", false);
|
|
20
20
|
|
|
21
21
|
static boolean isRequest(@NonNull Options options) {
|
|
22
22
|
return Boolean.TRUE.equals(options.get(REQUEST));
|
|
@@ -62,7 +62,7 @@ final class FastImageGlide {
|
|
|
62
62
|
synchronized (FastImageGlide.class) {
|
|
63
63
|
if (registered != glide) {
|
|
64
64
|
new FastImageOkHttpProgressGlideModule()
|
|
65
|
-
.
|
|
65
|
+
.register(context.getApplicationContext(), glide, registry, false);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.fastimage;
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import androidx.annotation.NonNull;
|
|
@@ -11,12 +11,14 @@ import com.bumptech.glide.load.ImageHeaderParser;
|
|
|
11
11
|
import com.bumptech.glide.load.ImageHeaderParserUtils;
|
|
12
12
|
import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool;
|
|
13
13
|
import com.bumptech.glide.load.Options;
|
|
14
|
+
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader;
|
|
14
15
|
import com.bumptech.glide.load.model.GlideUrl;
|
|
15
16
|
import com.bumptech.glide.load.model.ModelLoader;
|
|
16
17
|
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
|
17
18
|
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
|
|
18
19
|
import com.bumptech.glide.module.LibraryGlideModule;
|
|
19
20
|
import com.facebook.react.modules.network.CookieJarContainer;
|
|
21
|
+
import com.facebook.react.modules.network.ForwardingCookieHandler;
|
|
20
22
|
import com.facebook.react.modules.network.OkHttpClientProvider;
|
|
21
23
|
|
|
22
24
|
import java.io.File;
|
|
@@ -26,6 +28,7 @@ import java.util.Locale;
|
|
|
26
28
|
import java.util.concurrent.TimeUnit;
|
|
27
29
|
|
|
28
30
|
import okhttp3.Cache;
|
|
31
|
+
import okhttp3.Dispatcher;
|
|
29
32
|
import okhttp3.HttpUrl;
|
|
30
33
|
import okhttp3.Interceptor;
|
|
31
34
|
import okhttp3.JavaNetCookieJar;
|
|
@@ -95,18 +98,23 @@ public class FastImageOkHttpProgressGlideModule extends LibraryGlideModule {
|
|
|
95
98
|
@NonNull Glide glide,
|
|
96
99
|
@NonNull Registry registry
|
|
97
100
|
) {
|
|
101
|
+
register(context, glide, registry, true);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// `otherLoads`: as part of Glide's setup, where an app's own AppGlideModule
|
|
105
|
+
// runs after. Not when FastImageGlide.get registers FastImage's components
|
|
106
|
+
// itself, after the app's setup, which keeps what it registered for the
|
|
107
|
+
// app's other loads.
|
|
108
|
+
void register(Context context, Glide glide, Registry registry, boolean otherLoads) {
|
|
98
109
|
OkHttpClient sharedClient = OkHttpClientProvider.getOkHttpClient();
|
|
99
|
-
OkHttpClient.Builder builder = sharedClient
|
|
100
|
-
.newBuilder()
|
|
101
|
-
// A network interceptor, so it runs before the HTTP cache of
|
|
102
|
-
// `web` images stores the response (checking it reads it).
|
|
103
|
-
.addNetworkInterceptor(createNonImageInterceptor(registry, glide.getArrayPool()));
|
|
110
|
+
OkHttpClient.Builder builder = sharedClient.newBuilder();
|
|
104
111
|
// React Native's shared client comes with an empty cookie jar (React
|
|
105
112
|
// Native only fills it in for its networking and Image clients), so
|
|
106
113
|
// images were loaded without the app's cookies, unlike on iOS. Use the
|
|
107
|
-
// same cookie store
|
|
114
|
+
// same cookie store (Android's CookieManager, through React Native's
|
|
115
|
+
// ForwardingCookieHandler). A cookie jar the app set up itself is kept.
|
|
108
116
|
if (sharedClient.cookieJar() instanceof CookieJarContainer) {
|
|
109
|
-
builder.cookieJar(new JavaNetCookieJar(new
|
|
117
|
+
builder.cookieJar(new JavaNetCookieJar(new ForwardingCookieHandler()));
|
|
110
118
|
}
|
|
111
119
|
// React Native's shared client has no timeouts, so a download that
|
|
112
120
|
// stopped (e.g. on a connection that died) never ended, and every
|
|
@@ -117,7 +125,26 @@ public class FastImageOkHttpProgressGlideModule extends LibraryGlideModule {
|
|
|
117
125
|
// longer than any.
|
|
118
126
|
if (sharedClient.connectTimeoutMillis() == 0) builder.connectTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
|
119
127
|
if (sharedClient.readTimeoutMillis() == 0) builder.readTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
|
120
|
-
OkHttpClient
|
|
128
|
+
OkHttpClient appClient = builder.build();
|
|
129
|
+
// Images the app loads with Glide itself (a GlideUrl, from its own
|
|
130
|
+
// native code or another library) go through the same client, as
|
|
131
|
+
// expo-image does, instead of the default one Glide's OkHttp
|
|
132
|
+
// integration registers: the app's interceptors and cookies, these
|
|
133
|
+
// timeouts, and one connection pool. Not FastImage's check that a
|
|
134
|
+
// response is an image (below), which other loads, like a video's
|
|
135
|
+
// frame, can't pass. An app's own AppGlideModule runs after, and can
|
|
136
|
+
// register another.
|
|
137
|
+
// With a dispatcher of their own: FastImage's downloads count on
|
|
138
|
+
// having the client's requests per host to themselves
|
|
139
|
+
// (FastImageSharedDownloads), so the app's loads mustn't take them.
|
|
140
|
+
if (otherLoads) registry.replace(GlideUrl.class, InputStream.class,
|
|
141
|
+
new OkHttpUrlLoader.Factory(appClient.newBuilder().dispatcher(new Dispatcher()).build()));
|
|
142
|
+
OkHttpClient client = appClient
|
|
143
|
+
.newBuilder()
|
|
144
|
+
// A network interceptor, so it runs before the HTTP cache of
|
|
145
|
+
// `web` images stores the response (checking it reads it).
|
|
146
|
+
.addNetworkInterceptor(createNonImageInterceptor(registry, glide.getArrayPool()))
|
|
147
|
+
.build();
|
|
121
148
|
// `cache: 'web'` skips Glide's caches and relies on HTTP caching, so
|
|
122
149
|
// those urls get a client with an HTTP cache (#280): one of their own,
|
|
123
150
|
// not the app's (if it gave React Native's shared client one), so
|
package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageRequestListener.java
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.fastimage;
|
|
2
2
|
|
|
3
3
|
import android.graphics.drawable.Drawable;
|
|
4
4
|
|
|
@@ -84,6 +84,11 @@ public class FastImageRequestListener implements RequestListener<Drawable> {
|
|
|
84
84
|
dataSource == DataSource.RESOURCE_DISK_CACHE);
|
|
85
85
|
// Before the view shows it (the target does once this returns).
|
|
86
86
|
view.onImageSize(size);
|
|
87
|
+
// Only onLoad and onLoadEnd need a local image's size read from it:
|
|
88
|
+
// without them, don't (scale-down and none lay it out from the decoded
|
|
89
|
+
// image meanwhile). (After get, which also forgets a size that mustn't
|
|
90
|
+
// be reused.)
|
|
91
|
+
if (!view.handles(FastImageEvents.LOAD | FastImageEvents.LOAD_END)) return false;
|
|
87
92
|
if (size != null) {
|
|
88
93
|
sendLoad(view, size);
|
|
89
94
|
return false;
|
package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSourceSize.java
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.fastimage;
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.graphics.BitmapFactory;
|
|
@@ -110,13 +110,23 @@ final class FastImageSourceSize {
|
|
|
110
110
|
// downsample strategy it implies wrapped by capture, and then blur if it
|
|
111
111
|
// isn't null. Not downsampled (downsample false), the image isn't cropped
|
|
112
112
|
// or fitted to the view's size either: the view scales it as it draws it.
|
|
113
|
-
static RequestOptions scaleTypeOptions(
|
|
113
|
+
static RequestOptions scaleTypeOptions(
|
|
114
|
+
@Nullable ImageView.ScaleType scaleType,
|
|
115
|
+
Capture capture,
|
|
116
|
+
@Nullable FastImageCrop crop,
|
|
117
|
+
@Nullable FastImageBlur blur,
|
|
114
118
|
boolean downsample) {
|
|
115
119
|
RequestOptions options = new RequestOptions();
|
|
116
120
|
BitmapTransformation transformation = null;
|
|
117
121
|
if (scaleType != null && downsample) {
|
|
118
122
|
switch (scaleType) {
|
|
119
123
|
case CENTER_CROP:
|
|
124
|
+
if (crop != null) {
|
|
125
|
+
// At objectPosition, rather than the center.
|
|
126
|
+
options = options.optionalTransform(crop);
|
|
127
|
+
transformation = crop;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
120
130
|
options = options.optionalCenterCrop();
|
|
121
131
|
transformation = new CenterCrop();
|
|
122
132
|
break;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.fastimage;
|
|
2
2
|
|
|
3
3
|
import android.graphics.Bitmap;
|
|
4
4
|
|
|
@@ -45,7 +45,7 @@ final class FastImageSvg {
|
|
|
45
45
|
// the view. Part of the disk cache key, since the bitmap's size depends on
|
|
46
46
|
// them. Unset (0) for the other fits, which draw it for the view's size.
|
|
47
47
|
static final Option<Float> DENSITY = Option.disk(
|
|
48
|
-
"com.
|
|
48
|
+
"com.fastimage.FastImageSvg.Density", 0f,
|
|
49
49
|
new Option.CacheKeyUpdater<Float>() {
|
|
50
50
|
@Override
|
|
51
51
|
public void update(@NonNull byte[] keyBytes, @NonNull Float value, @NonNull MessageDigest messageDigest) {
|
|
@@ -54,7 +54,7 @@ final class FastImageSvg {
|
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
static final Option<Boolean> FITS = Option.disk(
|
|
57
|
-
"com.
|
|
57
|
+
"com.fastimage.FastImageSvg.Fits", false,
|
|
58
58
|
new Option.CacheKeyUpdater<Boolean>() {
|
|
59
59
|
@Override
|
|
60
60
|
public void update(@NonNull byte[] keyBytes, @NonNull Boolean value, @NonNull MessageDigest messageDigest) {
|
package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewConverter.java
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.
|
|
1
|
+
package com.fastimage;
|
|
2
2
|
|
|
3
3
|
import static com.bumptech.glide.request.RequestOptions.signatureOf;
|
|
4
4
|
|
|
@@ -43,16 +43,15 @@ class FastImageViewConverter {
|
|
|
43
43
|
put("high", Priority.HIGH);
|
|
44
44
|
}};
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
// objectFit's scale types. scale-down and none are laid out by the view
|
|
47
|
+
// itself, at the image's own size in dp (see
|
|
48
|
+
// FastImageViewWithUrl.updateImageMatrix).
|
|
49
|
+
private static final Map<String, ImageView.ScaleType> FAST_IMAGE_OBJECT_FIT_MAP =
|
|
47
50
|
new HashMap<String, ImageView.ScaleType>() {{
|
|
48
51
|
put("contain", ScaleType.FIT_CENTER);
|
|
49
52
|
put("cover", ScaleType.CENTER_CROP);
|
|
50
|
-
put("
|
|
51
|
-
put("center", ScaleType.CENTER_INSIDE);
|
|
52
|
-
// objectFit="scale-down": as center, laid out in dp (see
|
|
53
|
-
// FastImageViewWithUrl.setResizeMode).
|
|
53
|
+
put("fill", ScaleType.FIT_XY);
|
|
54
54
|
put("scale-down", ScaleType.CENTER_INSIDE);
|
|
55
|
-
// objectFit="none": the image at its own size, centered.
|
|
56
55
|
put("none", ScaleType.CENTER);
|
|
57
56
|
}};
|
|
58
57
|
|
|
@@ -163,7 +162,7 @@ class FastImageViewConverter {
|
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
static ScaleType getScaleType(String propValue) {
|
|
166
|
-
return getValue("
|
|
165
|
+
return getValue("objectFit", "cover", FAST_IMAGE_OBJECT_FIT_MAP, propValue);
|
|
167
166
|
}
|
|
168
167
|
|
|
169
168
|
private static <T> T getValue(String propName, String defaultPropValue, Map<String, T> map, String propValue) {
|