Skip to content

Commit c450d77

Browse files
author
Hanno Gödecke
committed
fix(android): support remote urls without etag
1 parent 80d2870 commit c450d77

File tree

3 files changed

+77
-68
lines changed

3 files changed

+77
-68
lines changed

android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java

Lines changed: 68 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
import android.content.Context;
55
import android.content.ContextWrapper;
66
import android.graphics.PorterDuff;
7+
import android.graphics.drawable.Drawable;
78
import android.os.Build;
89
import android.util.Log;
910

1011
import androidx.annotation.NonNull;
1112

1213
import com.bumptech.glide.Glide;
14+
import com.bumptech.glide.RequestBuilder;
1315
import com.bumptech.glide.RequestManager;
1416
import com.bumptech.glide.load.model.GlideUrl;
17+
import com.bumptech.glide.request.Request;
18+
import com.bumptech.glide.request.RequestOptions;
1519
import com.bumptech.glide.signature.ObjectKey;
1620
import com.dylanvann.fastimage.custom.EtagCallback;
1721
import com.dylanvann.fastimage.custom.EtagRequester;
@@ -49,12 +53,6 @@ class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> imple
4953

5054
private static final int FORCE_REFRESH_IMAGE = 1;
5155

52-
// private ReactApplicationContext reactContext;
53-
//
54-
// public FastImageViewManager(ReactApplicationContext reactContext) {
55-
// this.reactContext = reactContext;
56-
// }
57-
5856
@Nullable
5957
private RequestManager requestManager = null;
6058

@@ -136,33 +134,20 @@ private void load(final FastImageViewWithUrl view, @NonNull final ReadableMap so
136134
return;
137135
}
138136

139-
// TODO: what is your purpose? Why are you being called when you are also
140-
// called in #refresh ?
137+
final RequestOptions options = FastImageViewConverter.getOptions(context, imageSource, source);
138+
139+
// getEtag handles persistence of etag
141140
getEtag(url, new EtagCallback() {
142141
@Override
143142
public void onError(String error) {
144-
WritableNativeMap event = new WritableNativeMap();
145-
event.putString("error", error);
146-
eventEmitter.receiveEvent(viewId, REACT_ON_ERROR_EVENT, event);
143+
loadImage(view, url, null, options, key);
147144
}
148145

149146
@Override
150-
public void onEtag(final String etag) {
151-
getActivityFromContext(view.getContext()).runOnUiThread(new Runnable() {
152-
@Override
153-
public void run() {
154-
requestManager
155-
.load(url)
156-
.apply(FastImageViewConverter.getOptions(context, imageSource, source))
157-
.signature(new ObjectKey(etag))
158-
.listener(new FastImageRequestListener(key))
159-
.into(view);
160-
}
161-
});
162-
}
163-
}
164-
);
165-
refresh(view, url);
147+
public void onEtag(@Nullable final String etag) {
148+
loadImage(view, url, etag, options, key);
149+
}
150+
});
166151
}
167152
}
168153

@@ -173,54 +158,74 @@ public void run() {
173158
* @param url
174159
*/
175160
private void refresh(final FastImageViewWithUrl view, final String url) {
176-
final String prevEtag = ObjectBox.getEtagByUrl(url);
177-
if (prevEtag == null) {
178-
//can happen on the very first request. In this case a refresh is useless anyways.
179-
return;
180-
}
181-
182161
EtagRequester.requestEtag(url, new PersistEtagCallbackWrapper(url, new EtagCallback() {
183162
@Override
184163
public void onError(final String error) {
185-
final ThemedReactContext context = (ThemedReactContext) view.getContext();
186-
final RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class);
187-
final int viewId = view.getId();
188-
getActivityFromContext(view.getContext()).runOnUiThread(new Runnable() {
189-
@Override
190-
public void run() {
191-
WritableNativeMap event = new WritableNativeMap();
192-
event.putString("error", error);
193-
eventEmitter.receiveEvent(viewId, REACT_ON_ERROR_EVENT, event);
194-
}
195-
});
164+
loadImage(view, url, null, null, null);
196165
}
197166

198167
@Override
199168
public void onEtag(final String etag) {
200-
getActivityFromContext(view.getContext()).runOnUiThread(new Runnable() {
201-
@Override
202-
public void run() {
203-
if (requestManager == null) {
204-
Log.e(FastImageViewManager.class.getSimpleName(), "Can't refresh as requestManager was null!");
205-
return;
206-
}
207-
208-
requestManager
209-
.load(url)
210-
.thumbnail(
211-
requestManager.load(url)
212-
.signature(new ObjectKey(prevEtag))
213-
)
214-
.signature(new ObjectKey(etag))
215-
.skipMemoryCache(true)
216-
.into(view);
217-
}
218-
});
169+
loadImage(view, url, etag, null, null);
219170
}
220171
})
221172
);
222173
}
223174

175+
/**
176+
*
177+
* @param view
178+
* @param url
179+
* @param etag Optional
180+
* @param options Optional
181+
* @param key Optional, when set it will emit events
182+
*/
183+
private void loadImage(final FastImageViewWithUrl view, final String url, @Nullable final String etag, @Nullable final RequestOptions options, final @Nullable String key) {
184+
getActivityFromContext(view.getContext()).runOnUiThread(new Runnable() {
185+
@Override
186+
public void run() {
187+
if (requestManager == null) {
188+
Log.e(FastImageViewManager.class.getSimpleName(), "Can't refresh as requestManager was null!");
189+
return;
190+
}
191+
192+
193+
RequestBuilder<Drawable> thumbnailRequest = requestManager
194+
.load(url);
195+
196+
// add etag as signature when its set
197+
String prevEtag = ObjectBox.getEtagByUrl(url);
198+
if (prevEtag != null) {
199+
thumbnailRequest = thumbnailRequest.signature(new ObjectKey(prevEtag));
200+
}
201+
202+
RequestBuilder<Drawable> imageRequest = requestManager
203+
.load(url)
204+
.thumbnail(thumbnailRequest)
205+
.skipMemoryCache(true);
206+
207+
if (etag != null) {
208+
imageRequest = imageRequest.signature(new ObjectKey(etag));
209+
} else if (prevEtag != null) {
210+
// in case we received no etag (e.g. loading error due to no network)
211+
// we still want to consider getting cache with the prev etag.
212+
imageRequest = imageRequest.signature(new ObjectKey(prevEtag));
213+
}
214+
215+
if (options != null) {
216+
imageRequest = imageRequest.apply(options);
217+
}
218+
219+
if (key != null) {
220+
imageRequest = imageRequest.listener(new FastImageRequestListener(key));
221+
}
222+
223+
// finally, load the image
224+
imageRequest.into(view);
225+
}
226+
});
227+
}
228+
224229
/**
225230
* Returns the etag from cache. If there is no cached etag it will request
226231
* the server to get it, save it to the cache, and return it.

android/src/main/java/com/dylanvann/fastimage/custom/EtagRequester.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,20 @@ public void onFailure(Call call, IOException e) {
3636
// and the etag request failed
3737
if (prevEtag == null) {
3838
callback.onError("Failure when requesting etag: " + e.getMessage());
39+
} else {
40+
callback.onEtag(prevEtag);
3941
}
4042
}
4143

4244
@Override
4345
public void onResponse(Call call, Response response) {
4446
if (response.code() == 200) {
4547
String etag = response.header("etag");
46-
if (etag != null) {
47-
callback.onEtag(etag);
48-
}
48+
callback.onEtag(etag);
4949
} else if (response.code() > 308) {
5050
callback.onError("Unexpected http code: " + response.code());
51+
} else {
52+
callback.onEtag(prevEtag);
5153
}
5254
}
5355
});

android/src/main/java/com/dylanvann/fastimage/custom/PersistEtagCallbackWrapper.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.dylanvann.fastimage.custom.persistence.ObjectBox;
44

5+
import javax.annotation.Nullable;
6+
57
/**
68
* When an etag is returned this implementation will persist the received etag
79
* if it has changed.
@@ -21,9 +23,9 @@ public void onError(String error) {
2123
}
2224

2325
@Override
24-
public void onEtag(String etag) {
26+
public void onEtag(@Nullable String etag) {
2527
String prevEtag = ObjectBox.getEtagByUrl(this.url);
26-
if (!etag.equals(prevEtag)) {
28+
if (etag != null && !etag.equals(prevEtag)) {
2729
ObjectBox.putOrUpdateEtag(this.url, etag);
2830
}
2931
callback.onEtag(etag);

0 commit comments

Comments
 (0)