@nativescript-community/ui-image 4.6.6 → 5.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 (55) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +4 -20
  3. package/index-common.d.ts +47 -18
  4. package/index-common.js +5 -69
  5. package/index-common.js.map +1 -1
  6. package/index.android.d.ts +33 -60
  7. package/index.android.js +597 -702
  8. package/index.android.js.map +1 -1
  9. package/index.d.ts +17 -92
  10. package/index.ios.d.ts +5 -10
  11. package/index.ios.js +72 -54
  12. package/index.ios.js.map +1 -1
  13. package/package.json +4 -4
  14. package/platforms/android/include.gradle +21 -16
  15. package/platforms/android/java/com/nativescript/image/CacheKeyStore.java +65 -0
  16. package/platforms/android/java/com/nativescript/image/CapturingEngineKeyFactory.java +43 -0
  17. package/platforms/android/java/com/nativescript/image/CompositeRequestListener.java +58 -0
  18. package/platforms/android/java/com/nativescript/image/ConditionalCrossFadeFactory.java +33 -0
  19. package/platforms/android/java/com/nativescript/image/CustomDataFetcher.java +124 -0
  20. package/platforms/android/java/com/nativescript/image/CustomGlideModule.java +220 -0
  21. package/platforms/android/java/com/nativescript/image/CustomGlideUrl.java +52 -0
  22. package/platforms/android/java/com/nativescript/image/CustomUrlLoader.java +74 -0
  23. package/platforms/android/java/com/nativescript/image/EvictionManager.java +735 -0
  24. package/platforms/android/java/com/nativescript/image/ExtractRequestOptions.java +109 -0
  25. package/platforms/android/java/com/nativescript/image/ImageLoadSourceCallback.java +5 -0
  26. package/platforms/android/java/com/nativescript/image/ImageProgressCallback.java +5 -0
  27. package/platforms/android/java/com/nativescript/image/LoadSourceInterceptor.java +28 -0
  28. package/platforms/android/java/com/nativescript/image/MatrixDrawable.java +200 -0
  29. package/platforms/android/java/com/nativescript/image/MatrixDrawableImageViewTarget.java +154 -0
  30. package/platforms/android/java/com/nativescript/image/MatrixImageView.java +696 -0
  31. package/platforms/android/java/com/nativescript/image/ProgressInterceptor.java +25 -0
  32. package/platforms/android/java/com/nativescript/image/ProgressResponseBody.java +70 -0
  33. package/platforms/android/java/com/nativescript/image/RecordingDigest.java +48 -0
  34. package/platforms/android/java/com/nativescript/image/RecreatedResourceKey.java +95 -0
  35. package/platforms/android/java/com/nativescript/image/SaveKeysRequestListener.java +145 -0
  36. package/platforms/android/java/com/nativescript/image/ScaleUtils.java +129 -0
  37. package/platforms/android/java/com/nativescript/image/SharedPrefCacheKeyStore.java +92 -0
  38. package/platforms/android/native-api-usage.json +39 -37
  39. package/platforms/ios/Podfile +1 -1
  40. package/references.d.ts +0 -1
  41. package/tsconfig.tsbuildinfo +1 -1
  42. package/typings/android.d.ts +4 -27
  43. package/typings/glide.android.d.ts +9395 -0
  44. package/typings/glide.okhttp.android.d.ts +104 -0
  45. package/typings/glide.transform.android.d.ts +540 -0
  46. package/typings/ui_image.android.d.ts +517 -0
  47. package/platforms/android/java/com/nativescript/image/BaseDataSubscriber.java +0 -22
  48. package/platforms/android/java/com/nativescript/image/BaseDataSubscriberListener.java +0 -9
  49. package/platforms/android/java/com/nativescript/image/DraweeView.java +0 -371
  50. package/platforms/android/java/com/nativescript/image/NetworkImageRequest.java +0 -55
  51. package/platforms/android/java/com/nativescript/image/OkHttpNetworkFetcher.java +0 -56
  52. package/platforms/android/java/com/nativescript/image/ScalingBlurPostprocessor.java +0 -64
  53. package/platforms/android/java/com/nativescript/image/ScalingUtils.java +0 -519
  54. package/typings/fresco-processors.d.ts +0 -53
  55. package/typings/fresco.d.ts +0 -12070
@@ -0,0 +1,25 @@
1
+ package com.nativescript.image;
2
+
3
+ import java.io.IOException;
4
+ import okhttp3.Interceptor;
5
+ import okhttp3.Response;
6
+
7
+ public class ProgressInterceptor implements Interceptor {
8
+ private final String url;
9
+ private final ImageProgressCallback callback;
10
+
11
+ public ProgressInterceptor(String url, ImageProgressCallback callback) {
12
+ this.url = url;
13
+ this.callback = callback;
14
+ }
15
+
16
+ @Override
17
+ public Response intercept(Chain chain) throws IOException {
18
+ Response originalResponse = chain.proceed(chain.request());
19
+
20
+ // Wrap response body with progress tracking
21
+ return originalResponse.newBuilder()
22
+ .body(new ProgressResponseBody(originalResponse.body(), url, callback))
23
+ .build();
24
+ }
25
+ }
@@ -0,0 +1,70 @@
1
+ package com.nativescript.image;
2
+
3
+ import java.io.IOException;
4
+ import okhttp3.MediaType;
5
+ import okhttp3.ResponseBody;
6
+ import okio.Buffer;
7
+ import okio.BufferedSource;
8
+ import okio.ForwardingSource;
9
+ import okio.Okio;
10
+ import okio.Source;
11
+
12
+ public class ProgressResponseBody extends ResponseBody {
13
+ private final ResponseBody responseBody;
14
+ private final String url;
15
+ private final ImageProgressCallback callback;
16
+ private BufferedSource bufferedSource;
17
+
18
+ public ProgressResponseBody(ResponseBody responseBody, String url, ImageProgressCallback callback) {
19
+ this.responseBody = responseBody;
20
+ this.url = url;
21
+ this.callback = callback;
22
+ }
23
+
24
+ @Override
25
+ public MediaType contentType() {
26
+ return responseBody.contentType();
27
+ }
28
+
29
+ @Override
30
+ public long contentLength() {
31
+ return responseBody.contentLength();
32
+ }
33
+
34
+ @Override
35
+ public BufferedSource source() {
36
+ if (bufferedSource == null) {
37
+ bufferedSource = Okio.buffer(source(responseBody.source()));
38
+ }
39
+ return bufferedSource;
40
+ }
41
+
42
+ private Source source(Source source) {
43
+ return new ForwardingSource(source) {
44
+ long totalBytesRead = 0L;
45
+ long lastNotified = 0L;
46
+ static final long NOTIFY_INTERVAL = 8192L; // 8KB
47
+
48
+ @Override
49
+ public long read(Buffer sink, long byteCount) throws IOException {
50
+ long bytesRead = super.read(sink, byteCount);
51
+
52
+ if (bytesRead != -1) {
53
+ totalBytesRead += bytesRead;
54
+
55
+ // Notify if we've read enough bytes or at completion
56
+ if (totalBytesRead - lastNotified >= NOTIFY_INTERVAL ||
57
+ totalBytesRead >= contentLength()) {
58
+
59
+ if (callback != null) {
60
+ callback.onProgress(url, totalBytesRead, contentLength());
61
+ }
62
+ lastNotified = totalBytesRead;
63
+ }
64
+ }
65
+
66
+ return bytesRead;
67
+ }
68
+ };
69
+ }
70
+ }
@@ -0,0 +1,48 @@
1
+ package com.nativescript.image;
2
+
3
+ import java.io.ByteArrayOutputStream;
4
+ import java.security.MessageDigest;
5
+
6
+ /**
7
+ * Small MessageDigest that records raw bytes passed to update(...).
8
+ * We don't compute a digest here: we simply capture the bytes that callers
9
+ * write by calling
10
+ * update(byte[]) so we can later replay them into another MessageDigest.
11
+ *
12
+ * Usage:
13
+ * RecordingDigest r = new RecordingDigest();
14
+ * transformation.updateDiskCacheKey(r);
15
+ * byte[] bytes = r.digest(); // returns the concatenated bytes that
16
+ * transformation wrote
17
+ */
18
+ public final class RecordingDigest extends MessageDigest {
19
+ private final ByteArrayOutputStream out = new ByteArrayOutputStream();
20
+
21
+ public RecordingDigest() {
22
+ // algorithm name is arbitrary here; we do not rely on MessageDigest's actual
23
+ // hashing.
24
+ super("NONE");
25
+ }
26
+
27
+ @Override
28
+ protected void engineUpdate(byte input) {
29
+ out.write(input);
30
+ }
31
+
32
+ @Override
33
+ protected void engineUpdate(byte[] input, int offset, int len) {
34
+ out.write(input, offset, len);
35
+ }
36
+
37
+ @Override
38
+ protected byte[] engineDigest() {
39
+ byte[] result = out.toByteArray();
40
+ out.reset();
41
+ return result;
42
+ }
43
+
44
+ @Override
45
+ protected void engineReset() {
46
+ out.reset();
47
+ }
48
+ }
@@ -0,0 +1,95 @@
1
+ package com.nativescript.image;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import com.bumptech.glide.load.Key;
5
+ import java.nio.ByteBuffer;
6
+ import java.security.MessageDigest;
7
+ import java.util.Objects;
8
+
9
+ /**
10
+ * Recreates ResourceCacheKey updateDiskCacheKey ordering but accepts
11
+ * precomputed transformation
12
+ * and options key bytes. This avoids the need to reconstruct
13
+ * Transformation/Options objects.
14
+ *
15
+ * Ordering mirrors Glide's ResourceCacheKey:
16
+ * signature.updateDiskCacheKey(md)
17
+ * sourceKey.updateDiskCacheKey(md)
18
+ * md.update(dimensions)
19
+ * md.update(transformationKeyBytes) -- if present
20
+ * md.update(optionsKeyBytes) -- if present
21
+ * md.update(decodedResourceClass.getName().getBytes(...))
22
+ */
23
+ public final class RecreatedResourceKey implements Key {
24
+ private final Key sourceKey;
25
+ private final Key signature;
26
+ private final int width;
27
+ private final int height;
28
+ private final byte[] transformationKeyBytes; // may be null
29
+ private final Class<?> decodedResourceClass;
30
+ private final byte[] optionsKeyBytes; // may be null
31
+
32
+ public RecreatedResourceKey(
33
+ Key sourceKey,
34
+ Key signature,
35
+ int width,
36
+ int height,
37
+ byte[] transformationKeyBytes,
38
+ Class<?> decodedResourceClass,
39
+ byte[] optionsKeyBytes) {
40
+ this.sourceKey = Objects.requireNonNull(sourceKey);
41
+ this.signature = Objects.requireNonNull(signature);
42
+ this.width = width;
43
+ this.height = height;
44
+ this.transformationKeyBytes = transformationKeyBytes;
45
+ this.decodedResourceClass = Objects.requireNonNull(decodedResourceClass);
46
+ this.optionsKeyBytes = optionsKeyBytes;
47
+ }
48
+
49
+ @Override
50
+ public boolean equals(Object o) {
51
+ if (this == o)
52
+ return true;
53
+ if (!(o instanceof RecreatedResourceKey))
54
+ return false;
55
+ RecreatedResourceKey that = (RecreatedResourceKey) o;
56
+ return width == that.width
57
+ && height == that.height
58
+ && sourceKey.equals(that.sourceKey)
59
+ && signature.equals(that.signature)
60
+ && java.util.Arrays.equals(transformationKeyBytes, that.transformationKeyBytes)
61
+ && decodedResourceClass.equals(that.decodedResourceClass)
62
+ && java.util.Arrays.equals(optionsKeyBytes, that.optionsKeyBytes);
63
+ }
64
+
65
+ @Override
66
+ public int hashCode() {
67
+ int result = sourceKey.hashCode();
68
+ result = 31 * result + signature.hashCode();
69
+ result = 31 * result + width;
70
+ result = 31 * result + height;
71
+ result = 31 * result + java.util.Arrays.hashCode(transformationKeyBytes);
72
+ result = 31 * result + decodedResourceClass.hashCode();
73
+ result = 31 * result + java.util.Arrays.hashCode(optionsKeyBytes);
74
+ return result;
75
+ }
76
+
77
+ @Override
78
+ public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
79
+ byte[] dimensions = ByteBuffer.allocate(8).putInt(width).putInt(height).array();
80
+
81
+ signature.updateDiskCacheKey(messageDigest);
82
+ sourceKey.updateDiskCacheKey(messageDigest);
83
+ messageDigest.update(dimensions);
84
+
85
+ if (transformationKeyBytes != null) {
86
+ messageDigest.update(transformationKeyBytes);
87
+ }
88
+
89
+ if (optionsKeyBytes != null) {
90
+ messageDigest.update(optionsKeyBytes);
91
+ }
92
+
93
+ messageDigest.update(decodedResourceClass.getName().getBytes(CHARSET));
94
+ }
95
+ }
@@ -0,0 +1,145 @@
1
+ package com.nativescript.image;
2
+
3
+ import android.graphics.drawable.Drawable;
4
+ import android.util.Log;
5
+
6
+ import androidx.annotation.Nullable;
7
+
8
+ import com.bumptech.glide.load.Key;
9
+ import com.bumptech.glide.load.Options;
10
+ import com.bumptech.glide.load.Transformation;
11
+ import com.bumptech.glide.request.RequestListener;
12
+ import com.bumptech.glide.request.RequestOptions;
13
+ import com.bumptech.glide.request.target.Target;
14
+ import com.bumptech.glide.load.engine.GlideException;
15
+
16
+ /**
17
+ * RequestListener that records the disk & transformation key bytes used for a
18
+ * request
19
+ * and persists them via EvictionManager so later evictions / presence checks
20
+ * can recreate
21
+ * the exact disk keys without needing to recreate Transformation objects.
22
+ *
23
+ * Usage:
24
+ * - Preferred: pass a RequestOptions instance; this listener will extract the
25
+ * internal Options
26
+ * via ExtractRequestOptions (cached reflection) so your existing RequestOptions
27
+ * usage continues to work.
28
+ * - Alternative: pass an Options instance directly if you already have it.
29
+ *
30
+ * The listener returns false from callbacks so it does not short-circuit other
31
+ * listeners or Glide's handling.
32
+ */
33
+ public final class SaveKeysRequestListener implements RequestListener<Drawable> {
34
+ private static final String TAG = "SaveKeysRequestListener";
35
+
36
+ private final String id; // canonical id you use to later evict (typically the URL string or normalized
37
+ // model id)
38
+ private final Object model; // the same model object you pass to Glide.load(...)
39
+ private final Key sourceKey;
40
+ private final Key signature;
41
+ private final int width;
42
+ private final int height;
43
+ @Nullable
44
+ private final Transformation<?> transformation;
45
+ private final Options options;
46
+ private final Class<?> decodedResourceClass;
47
+
48
+ /**
49
+ * Construct directly with an Options instance.
50
+ */
51
+ public SaveKeysRequestListener(
52
+ String id,
53
+ Object model,
54
+ Key sourceKey,
55
+ Key signature,
56
+ int width,
57
+ int height,
58
+ @Nullable Transformation<?> transformation,
59
+ RequestOptions options,
60
+ Class<?> decodedResourceClass) {
61
+ this.id = id;
62
+ this.model = model;
63
+ this.sourceKey = sourceKey;
64
+ this.signature = signature;
65
+ this.width = width;
66
+ this.height = height;
67
+ this.transformation = transformation;
68
+ this.options = (options == null) ? new Options() : ExtractRequestOptions.getFrom(options);
69
+ this.decodedResourceClass = (decodedResourceClass == null) ? Drawable.class : decodedResourceClass;
70
+ }
71
+
72
+ @Override
73
+ public boolean onLoadFailed(GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
74
+ // We don't persist anything on failure (could be added). Do not consume the
75
+ // event.
76
+ return false;
77
+ }
78
+
79
+ @Override
80
+ public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target,
81
+ com.bumptech.glide.load.DataSource dataSource, boolean isFirstResource) {
82
+ try {
83
+ byte[] transformationBytes = null;
84
+ byte[] optionsBytes = null;
85
+
86
+ // Record transformation key bytes if we have a transformation instance
87
+ if (transformation != null) {
88
+ try {
89
+ RecordingDigest rd = new RecordingDigest();
90
+ transformation.updateDiskCacheKey(rd);
91
+ transformationBytes = rd.digest();
92
+ } catch (Throwable t) {
93
+ Log.w(TAG, "Failed to record transformation key bytes for id=" + id, t);
94
+ }
95
+ }
96
+
97
+ // Record options key bytes (Options.updateDiskCacheKey)
98
+ try {
99
+ RecordingDigest rd2 = new RecordingDigest();
100
+ options.updateDiskCacheKey(rd2);
101
+ optionsBytes = rd2.digest();
102
+ } catch (Throwable t) {
103
+ Log.w(TAG, "Failed to record options key bytes for id=" + id, t);
104
+ }
105
+
106
+ // Attempt to preserve existing engineKey if present
107
+ com.bumptech.glide.load.Key engineKeyToKeep = null;
108
+
109
+ try {
110
+ CacheKeyStore.StoredKeys existing = null;
111
+ if (EvictionManager.get() != null) {
112
+ // use the public API to fetch current stored keys for this id (may be
113
+ // persistent or in-memory)
114
+ existing = EvictionManager.get().getKeyStore().get(id);
115
+ }
116
+ if (existing != null && existing.engineKey != null) {
117
+ engineKeyToKeep = existing.engineKey;
118
+ }
119
+ } catch (Throwable t) {
120
+ Log.w(TAG, "Failed to read existing stored keys to preserve engineKey for id=" + id, t);
121
+ }
122
+
123
+ // Build StoredKeys and persist via EvictionManager
124
+ CacheKeyStore.StoredKeys stored = new CacheKeyStore.StoredKeys(
125
+ sourceKey,
126
+ signature,
127
+ width,
128
+ height,
129
+ transformation, // may be null; kept for in-process fallback
130
+ transformationBytes, // recorded transformation bytes (preferred)
131
+ decodedResourceClass,
132
+ options,
133
+ optionsBytes,
134
+ engineKeyToKeep // preserve any engineKey we found
135
+ );
136
+
137
+ EvictionManager.get().saveKeys(id, stored);
138
+ } catch (Throwable t) {
139
+ Log.w(TAG, "Unexpected error in SaveKeysRequestListener.onResourceReady for id=" + id, t);
140
+ }
141
+ // Do not consume the event; allow other listeners and Glide to continue normal
142
+ // handling.
143
+ return false;
144
+ }
145
+ }
@@ -0,0 +1,129 @@
1
+ package com.nativescript.image;
2
+
3
+ import android.graphics.Matrix;
4
+ import android.graphics.RectF;
5
+ import android.graphics.drawable.Drawable;
6
+ import android.widget.ImageView;
7
+
8
+ /**
9
+ * Utilities to compute an image -> view matrix that respects an
10
+ * ImageView.ScaleType
11
+ * while also applying an image rotation (degrees).
12
+ *
13
+ * Notes:
14
+ * - Rotation is applied around the drawable's center before fitting/scaling.
15
+ * - The output matrix maps drawable coordinates to view coordinates.
16
+ *
17
+ * Usage:
18
+ * Matrix m = new Matrix();
19
+ * ScaleUtils.getImageMatrix(drawable, viewWidth, viewHeight, rotationDegrees,
20
+ * scaleType, m);
21
+ */
22
+ public final class ScaleUtils {
23
+
24
+ private ScaleUtils() {
25
+ }
26
+
27
+ /**
28
+ * Compute a matrix that maps the drawable (drawable-local coords:
29
+ * 0..intrinsicW/H)
30
+ * into view coordinates, applying rotation (degrees) about the drawable center
31
+ * first,
32
+ * then the scaleType fit.
33
+ *
34
+ * rotationDegrees is a float to allow smooth animated rotation.
35
+ */
36
+ public static void getImageMatrix(
37
+ Drawable d,
38
+ int viewWidth,
39
+ int viewHeight,
40
+ float rotationDegrees,
41
+ ImageView.ScaleType scaleType,
42
+ Matrix outMatrix) {
43
+ if (d == null) {
44
+ outMatrix.reset();
45
+ return;
46
+ }
47
+ float dW = d.getIntrinsicWidth();
48
+ float dH = d.getIntrinsicHeight();
49
+ if (dW <= 0 || dH <= 0 || viewWidth == 0 || viewHeight == 0) {
50
+ outMatrix.reset();
51
+ return;
52
+ }
53
+
54
+ RectF src = new RectF(0, 0, dW, dH);
55
+ Matrix m = new Matrix();
56
+
57
+ // 1) rotate around drawable center (drawable-local coords)
58
+ if ((rotationDegrees % 360f) != 0f) {
59
+ m.postRotate(rotationDegrees, dW / 2f, dH / 2f);
60
+ }
61
+
62
+ // 2) compute rotated drawable bounds in drawable-local coords
63
+ RectF rotated = new RectF();
64
+ m.mapRect(rotated, src);
65
+
66
+ float rW = rotated.width();
67
+ float rH = rotated.height();
68
+
69
+ float scaleX = (float) viewWidth / rW;
70
+ float scaleY = (float) viewHeight / rH;
71
+
72
+ switch (scaleType) {
73
+ case CENTER:
74
+ // no scaling, center only; rotation already applied
75
+ break;
76
+ case CENTER_CROP: {
77
+ float scale = Math.max(scaleX, scaleY);
78
+ m.postScale(scale, scale, dW / 2f, dH / 2f);
79
+ break;
80
+ }
81
+ case CENTER_INSIDE: {
82
+ float scale = Math.min(1f, Math.min(scaleX, scaleY));
83
+ m.postScale(scale, scale, dW / 2f, dH / 2f);
84
+ break;
85
+ }
86
+ case FIT_CENTER:
87
+ case FIT_START:
88
+ case FIT_END:
89
+ case FIT_XY: {
90
+ if (scaleType == ImageView.ScaleType.FIT_XY) {
91
+ m.postScale(scaleX, scaleY, dW / 2f, dH / 2f);
92
+ } else {
93
+ float scale = Math.min(scaleX, scaleY);
94
+ m.postScale(scale, scale, dW / 2f, dH / 2f);
95
+ }
96
+ break;
97
+ }
98
+ case MATRIX:
99
+ default:
100
+ // Let the caller manage the matrix in MATRIX mode; here treat like FIT_CENTER.
101
+ float scale = Math.min(scaleX, scaleY);
102
+ m.postScale(scale, scale, dW / 2f, dH / 2f);
103
+ break;
104
+ }
105
+
106
+ // 3) translate to position according to scaleType
107
+ RectF mapped = new RectF();
108
+ m.mapRect(mapped, src);
109
+
110
+ float dx = 0f;
111
+ float dy = 0f;
112
+
113
+ if (scaleType == ImageView.ScaleType.FIT_START) {
114
+ dx = 0f - mapped.left;
115
+ dy = 0f - mapped.top;
116
+ } else if (scaleType == ImageView.ScaleType.FIT_END) {
117
+ dx = viewWidth - mapped.right;
118
+ dy = viewHeight - mapped.bottom;
119
+ } else {
120
+ // center
121
+ dx = viewWidth * 0.5f - mapped.centerX();
122
+ dy = viewHeight * 0.5f - mapped.centerY();
123
+ }
124
+
125
+ m.postTranslate(dx, dy);
126
+
127
+ outMatrix.set(m);
128
+ }
129
+ }
@@ -0,0 +1,92 @@
1
+ package com.nativescript.image;
2
+
3
+ import android.content.Context;
4
+ import android.content.SharedPreferences;
5
+ import android.util.Base64;
6
+ import org.json.JSONException;
7
+ import org.json.JSONObject;
8
+ import com.bumptech.glide.load.Key;
9
+ import com.bumptech.glide.signature.ObjectKey;
10
+ import com.bumptech.glide.load.Options;
11
+ import com.bumptech.glide.load.Transformation;
12
+
13
+ /**
14
+ * SharedPreferences-backed minimal persistent store.
15
+ * Stores:
16
+ * - source (string)
17
+ * - signature (string)
18
+ * - width, height
19
+ * - decodedResourceClass (string)
20
+ * - transformationKeyBytes (base64)
21
+ * - optionsKeyBytes (base64)
22
+ *
23
+ * For transformations: we store recorded bytes (from RecordingDigest) rather
24
+ * than trying to
25
+ * re-create the Transformation object.
26
+ */
27
+ public class SharedPrefCacheKeyStore {
28
+ private static final String PREFS = "glide_cache_keys_v2";
29
+ private final SharedPreferences prefs;
30
+
31
+ public SharedPrefCacheKeyStore(Context context) {
32
+ this.prefs = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
33
+ }
34
+
35
+ public void put(String id, CacheKeyStore.StoredKeys keys) {
36
+ try {
37
+ JSONObject j = new JSONObject();
38
+ j.put("source", keys.sourceKey == null ? JSONObject.NULL : keys.sourceKey.toString());
39
+ j.put("signature", keys.signature == null ? JSONObject.NULL : keys.signature.toString());
40
+ j.put("width", keys.width);
41
+ j.put("height", keys.height);
42
+ j.put("decodedResourceClass",
43
+ keys.decodedResourceClass == null ? JSONObject.NULL : keys.decodedResourceClass.getName());
44
+ j.put("transformationBytes", keys.transformationKeyBytes == null ? JSONObject.NULL
45
+ : Base64.encodeToString(keys.transformationKeyBytes, Base64.NO_WRAP));
46
+ j.put("optionsBytes",
47
+ keys.optionsKeyBytes == null ? JSONObject.NULL : Base64.encodeToString(keys.optionsKeyBytes, Base64.NO_WRAP));
48
+ prefs.edit().putString(id, j.toString()).apply();
49
+ } catch (JSONException e) {
50
+ // log if you want
51
+ }
52
+ }
53
+
54
+ public CacheKeyStore.StoredKeys get(String id) {
55
+ String s = prefs.getString(id, null);
56
+ if (s == null)
57
+ return null;
58
+ try {
59
+ JSONObject j = new JSONObject(s);
60
+ String source = j.optString("source", null);
61
+ String signature = j.optString("signature", null);
62
+ int width = j.optInt("width", com.bumptech.glide.request.target.Target.SIZE_ORIGINAL);
63
+ int height = j.optInt("height", com.bumptech.glide.request.target.Target.SIZE_ORIGINAL);
64
+ String decodedName = j.optString("decodedResourceClass", android.graphics.Bitmap.class.getName());
65
+ String transformationBase64 = j.optString("transformationBytes", null);
66
+ String optionsBase64 = j.optString("optionsBytes", null);
67
+
68
+ Key sourceKey = source != null && !"null".equals(source) ? new ObjectKey(source) : new ObjectKey(id);
69
+ Key signatureKey = signature != null && !"null".equals(signature) ? new ObjectKey(signature)
70
+ : new ObjectKey("signature-none");
71
+ Class<?> decodedClass = Class.forName(decodedName);
72
+ byte[] transformationBytes = (transformationBase64 == null || "null".equals(transformationBase64)) ? null
73
+ : Base64.decode(transformationBase64, Base64.NO_WRAP);
74
+ byte[] optionsBytes = (optionsBase64 == null || "null".equals(optionsBase64)) ? null
75
+ : Base64.decode(optionsBase64, Base64.NO_WRAP);
76
+
77
+ // We cannot re-create a reliable Options instance from optionsBytes. We store
78
+ // optionsBytes and will replay them
79
+ // into the ResourceCacheKey digest when deleting. For in-memory Options pass an
80
+ // empty instance or the caller's instance.
81
+ Options options = new Options();
82
+ return new CacheKeyStore.StoredKeys(sourceKey, signatureKey, width, height, /* transformation */ null,
83
+ transformationBytes, decodedClass, options, optionsBytes, /* engineKey */ null);
84
+ } catch (Exception e) {
85
+ return null;
86
+ }
87
+ }
88
+
89
+ public void remove(String id) {
90
+ prefs.edit().remove(id).apply();
91
+ }
92
+ }
@@ -1,42 +1,44 @@
1
1
  {
2
2
  "uses": [
3
- "com.facebook.drawee.drawable:ScalingUtils",
4
- "com.facebook.drawee.drawable:ScalingUtils.ScaleType",
5
- "com.facebook.drawee.generic:RoundingParams",
6
- "com.facebook.drawee.drawable:ProgressBarDrawable",
7
- "com.facebook.drawee.view:DraweeView",
8
- "com.facebook.drawee.interfaces:DraweeHierarchy",
9
- "com.facebook.drawee.interfaces:SettableDraweeHierarchy",
10
- "com.facebook.drawee.interfaces:SimpleDraweeControllerBuilder",
11
- "com.facebook.drawee.interfaces:DraweeController",
12
- "com.facebook.drawee.generic:GenericDraweeHierarchyBuilder",
13
- "com.facebook.drawee.generic:GenericDraweeHierarchy",
14
- "com.facebook.imagepipeline.request:ImageRequestBuilder",
15
- "com.facebook.imagepipeline.request:ImageRequest",
16
- "com.facebook.imagepipeline.core:ImagePipelineConfig",
17
- "com.facebook.imagepipeline.core:ImagePipelineConfig.Builder",
18
- "com.facebook.imagepipeline.core:ImagePipeline",
19
- "com.facebook.imagepipeline.common:RotationOptions",
20
- "com.facebook.imagepipeline.common:ResizeOptions",
21
- "com.facebook.drawee.backends.pipeline:Fresco",
22
- "com.facebook.drawee.backends.pipeline:PipelineDraweeControllerBuilder",
23
- "com.facebook.drawee.backends.pipeline:PipelineDraweeController",
24
- "com.facebook.drawee.controller:AbstractDraweeControllerBuilder",
25
- "com.facebook.drawee.controller:AbstractDraweeController",
26
- "com.facebook.drawee.backends.pipeline.info:ImagePerfDataListener",
27
- "com.facebook.drawee.backends.pipeline.info:ImagePerfData",
28
- "com.facebook.drawee.controller:ControllerListener",
29
- "com.nativescript.image:ScalingUtils*",
30
- "com.nativescript.image:DraweeView",
31
- "com.nativescript.image:OkHttpNetworkFetcher",
32
- "com.nativescript.image:ScalingBlurPostprocessor",
33
- "com.facebook.imagepipeline.producers:NetworkFetcher",
34
- "com.facebook.imagepipeline.backends.okhttp3:OkHttpImagePipelineConfigFactory",
35
- "okhttp3:OkHttpClient",
36
- "android.graphics.drawable:Animatable",
37
- "com.facebook.imagepipeline.image:ImageInfo",
38
- "com.facebook.common.util:UriUtil",
39
3
  "android.net:Uri",
40
- "android.net:Uri.Builder"
4
+ "com.nativescript.image:SharedPrefCacheKeyStore",
5
+ "com.nativescript.image:CacheKeyStore",
6
+ "com.nativescript.image:EvictionManager",
7
+ "com.nativescript.image:EvictionManager.DiskPresenceCallback",
8
+ "com.nativescript.image:EvictionManager.EvictionCallback",
9
+ "com.nativescript.image:ImageProgressCallback",
10
+ "com.nativescript.image:ImageLoadSourceCallback",
11
+ "com.nativescript.image:CustomGlideUrl",
12
+ "com.nativescript.image:ConditionalCrossFadeFactory",
13
+ "com.nativescript.image:SaveKeysRequestListener",
14
+ "com.nativescript.image:CompositeRequestListener",
15
+ "com.nativescript.image:MatrixDrawableImageViewTarget",
16
+ "com.nativescript.image:MatrixImageView",
17
+ "com.bumptech.glide:Glide",
18
+ "com.bumptech.glide.signature:ObjectKey",
19
+ "com.bumptech.glide.request:RequestOptions",
20
+ "com.bumptech.glide.request:RequestBuilder",
21
+ "com.bumptech.glide.request:RequestListener",
22
+ "com.bumptech.glide.request.target:Target",
23
+ "com.bumptech.glide.request.target:ViewTarget",
24
+ "com.bumptech.glide:RequestManager",
25
+ "com.bumptech.glide.load:MultiTransformation",
26
+ "com.bumptech.glide.load:Transformation",
27
+ "com.bumptech.glide.load:DataSource",
28
+ "com.bumptech.glide.load:Key",
29
+ "com.bumptech.glide.load.resource.drawable:DrawableTransitionOptions",
30
+ "com.bumptech.glide.load.engine:DiskCacheStrategy",
31
+ "com.bumptech.glide.request.transition:Transition",
32
+ "com.bumptech.glide.request.transition:DrawableCrossFadeFactory",
33
+ "android.graphics.drawable:Drawable",
34
+ "android.graphics.drawable:BitmapDrawable",
35
+ "android.widget:ImageView:ScaleType",
36
+ "android.widget:ImageView",
37
+ "androidx.appcompat.widget:AppCompatImageView",
38
+ "android.graphics.PorterDuff:Mode",
39
+ "jp.wasabeef.glide.transformations:BlurTransformation",
40
+ "jp.wasabeef.glide.transformations:CropCircleTransformation",
41
+ "jp.wasabeef.glide.transformations:RoundedCornersTransformation",
42
+ "jp.wasabeef.glide.transformations:ColorFilterTransformation"
41
43
  ]
42
44
  }