From 911f8f5731f2693e266724a639ba59b970347757 Mon Sep 17 00:00:00 2001 From: Adamantcheese Date: Sat, 10 Sep 2022 14:09:49 -0700 Subject: [PATCH] Attempt for #1348 I think that main thread runnables were still queued up despite the call being cancelled, so this should hopefully fix it? at least it seems to have from my looking --- .../chan/core/net/ImageLoadable.java | 187 +++++++++++------- .../adamantcheese/chan/core/net/NetUtils.java | 125 ++++++++---- .../embedders/QuickLatexEmbedder.java | 17 +- .../chan/ui/adapter/DrawerHistoryAdapter.java | 24 +-- .../chan/ui/adapter/DrawerPinAdapter.java | 24 +-- .../chan/ui/captcha/LegacyCaptchaLayout.java | 22 +-- .../chan/ui/cell/CardPostCell.java | 25 +-- .../adamantcheese/chan/ui/cell/PostCell.java | 23 +-- .../controller/AlbumDownloadController.java | 21 +- .../ui/controller/AlbumViewController.java | 24 +-- .../ui/controller/RemovedPostsController.java | 24 +-- .../chan/utils/BackgroundUtils.java | 4 + 12 files changed, 256 insertions(+), 264 deletions(-) diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/core/net/ImageLoadable.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/core/net/ImageLoadable.java index caff67cc6..6186a93ba 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/core/net/ImageLoadable.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/core/net/ImageLoadable.java @@ -13,11 +13,10 @@ import com.github.adamantcheese.chan.core.net.NetUtilsClasses.ResponseResult; import com.github.adamantcheese.chan.core.repository.BitmapRepository; import com.github.adamantcheese.chan.core.settings.ChanSettings; -import com.github.adamantcheese.chan.utils.Logger; -import com.github.adamantcheese.chan.utils.StringUtils; +import com.github.adamantcheese.chan.utils.*; -import okhttp3.Call; -import okhttp3.HttpUrl; +import kotlin.Triple; +import okhttp3.*; /** * A simple image loader that loads an image into an image view @@ -41,7 +40,12 @@ default void loadUrl( return; } - Call currentCall = getImageCall(); + if (getImageLoadableData() == null) { + setImageLoadableData(new ImageLoadableData()); + } + ImageLoadableData data = getImageLoadableData(); + + Call currentCall = data.getImageCall(); // in progress check, in case of a re-bind without recycling if (currentCall != null) { if (currentCall.request().url().equals(url)) { @@ -52,66 +56,73 @@ default void loadUrl( } // completed load check - if (url.equals(getLoadedUrl())) return; + if (url.equals(data.getLoadedUrl())) return; // request the image - Call imageCall = NetUtils.makeBitmapRequest(url, new NetUtilsClasses.BitmapResult() { - @Override - public void onBitmapFailure(@NonNull HttpUrl source, Exception e) { - setImageCall(null); - // for a chained load, this means that the last successful load will remain - if (getLoadedUrl() != null) return; - setLoadedUrl(null); // fail, nullify the last url - - // if this has an error code associated with it, draw it up all fancy-like - if (e instanceof NetUtilsClasses.HttpCodeException) { - if (((NetUtilsClasses.HttpCodeException) e).isServerErrorNotFound()) { - // for this case, never try and load again and treat it as though it loaded fully - setLoadedUrl(source); + Triple networkInfo = + NetUtils.makeBitmapRequest(url, new NetUtilsClasses.BitmapResult() { + @Override + public void onBitmapFailure(@NonNull HttpUrl source, Exception e) { + data.setImageCall(null); + data.setRunnable(null); + // for a chained load, this means that the last successful load will remain + if (data.getLoadedUrl() != null) return; + data.setLoadedUrl(null); // fail, nullify the last url + + // if this has an error code associated with it, draw it up all fancy-like + if (e instanceof NetUtilsClasses.HttpCodeException) { + if (((NetUtilsClasses.HttpCodeException) e).isServerErrorNotFound()) { + // for this case, never try and load again and treat it as though it loaded fully + data.setLoadedUrl(source); + } + } else { + Logger.d(this, "Failed to load image for " + StringUtils.maskImageUrl(source), e); + } + imageView.setImageBitmap(BitmapRepository.getHttpExceptionBitmap(imageView.getContext(), e)); + + if (callback != null) { + callback.onFailure(e); + } } - } else { - Logger.d(this, "Failed to load image for " + StringUtils.maskImageUrl(source), e); - } - imageView.setImageBitmap(BitmapRepository.getHttpExceptionBitmap(imageView.getContext(), e)); - - if (callback != null) { - callback.onFailure(e); - } - } - @Override - public void onBitmapSuccess(@NonNull HttpUrl source, @NonNull Bitmap bitmap, boolean fromCache) { - // success, save the last url as good - // for a chained load, this means that the last successful load will remain - setImageCall(null); - setLoadedUrl(source); - - // if not from cache, fade the view in; if set, fade out first - if (!fromCache) { - if (imageView.getDrawable() != null) { - imageView - .animate() - .setInterpolator(new AccelerateInterpolator(2f)) - .alpha(0f) - .withEndAction(() -> { - imageView.setImageBitmap(bitmap); - imageView.animate().alpha(1f).setInterpolator(new DecelerateInterpolator(2f)); - }); - } else { - imageView.setImageBitmap(bitmap); - imageView.animate().alpha(1f).setInterpolator(new DecelerateInterpolator(2f)); + @Override + public void onBitmapSuccess(@NonNull HttpUrl source, @NonNull Bitmap bitmap, boolean fromCache) { + // success, save the last url as good + // for a chained load, this means that the last successful load will remain + data.setImageCall(null); + data.setRunnable(null); + data.setLoadedUrl(source); + + // if not from cache, fade the view in; if set, fade out first + if (!fromCache) { + if (imageView.getDrawable() != null) { + imageView + .animate() + .setInterpolator(new AccelerateInterpolator(2f)) + .alpha(0f) + .withEndAction(() -> { + imageView.setImageBitmap(bitmap); + imageView + .animate() + .alpha(1f) + .setInterpolator(new DecelerateInterpolator(2f)); + }); + } else { + imageView.setImageBitmap(bitmap); + imageView.animate().alpha(1f).setInterpolator(new DecelerateInterpolator(2f)); + } + } else { + imageView.setImageBitmap(bitmap); + imageView.setAlpha(1f); + } + + if (callback != null) { + callback.onSuccess(null); + } } - } else { - imageView.setImageBitmap(bitmap); - imageView.setAlpha(1f); - } - - if (callback != null) { - callback.onSuccess(null); - } - } - }); - setImageCall(imageCall); + }, 0, 0, -1, null, true, true); + data.setImageCall(networkInfo == null ? null : networkInfo.getFirst()); + data.setRunnable(networkInfo == null ? null : networkInfo.getThird()); } /** @@ -154,19 +165,57 @@ default void cancelLoad(ImageView imageView) { imageView.animate().cancel(); imageView.setImageBitmap(null); imageView.setAlpha(0f); - setLoadedUrl(null); - Call currentCall = getImageCall(); - if (currentCall != null) { - currentCall.cancel(); + if (getImageLoadableData() == null) { + setImageLoadableData(new ImageLoadableData()); } - setImageCall(null); + getImageLoadableData().cancel(); } - HttpUrl getLoadedUrl(); + ImageLoadableData getImageLoadableData(); - void setLoadedUrl(HttpUrl url); + void setImageLoadableData(ImageLoadableData data); - Call getImageCall(); + class ImageLoadableData { + private HttpUrl loadedUrl = null; + private Call call = null; + private Runnable runnable = null; - void setImageCall(Call call); + public ImageLoadableData() { + } + + public void cancel() { + setLoadedUrl(null); + Call currentCall = getImageCall(); + if (currentCall != null) { + currentCall.cancel(); + } + setImageCall(null); + BackgroundUtils.cancel(runnable); + setRunnable(null); + } + + public HttpUrl getLoadedUrl() { + return loadedUrl; + } + + public void setLoadedUrl(HttpUrl loadedUrl) { + this.loadedUrl = loadedUrl; + } + + public Call getImageCall() { + return call; + } + + public void setImageCall(Call call) { + this.call = call; + } + + public Runnable getRunnable() { + return runnable; + } + + public void setRunnable(Runnable runnable) { + this.runnable = runnable; + } + } } diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/core/net/NetUtils.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/core/net/NetUtils.java index 54acfa6e1..4ebfb87ab 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/core/net/NetUtils.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/core/net/NetUtils.java @@ -220,8 +220,8 @@ public static Call makeBitmapRequest( public static Call makeBitmapRequest( final HttpUrl url, @NonNull final BitmapResult result, final int timeoutMs ) { - Pair ret = makeBitmapRequest(url, result, 0, 0, timeoutMs, null, true, true); - return ret == null ? null : ret.first; + Triple ret = makeBitmapRequest(url, result, 0, 0, timeoutMs, null, true, true); + return ret == null ? null : ret.getFirst(); } /** @@ -240,8 +240,9 @@ public static Call makeBitmapRequest( final int height, @Nullable ProgressResponseBody.ProgressListener progressListener ) { - Pair ret = makeBitmapRequest(url, result, width, height, -1, progressListener, true, true); - return ret == null ? null : ret.first; + Triple ret = + makeBitmapRequest(url, result, width, height, -1, progressListener, true, true); + return ret == null ? null : ret.getFirst(); } /** @@ -256,7 +257,7 @@ public static Call makeBitmapRequest( * @param mainThread Should this result be run on the main thread or not (most wrappers do) * @return An enqueued bitmap call. */ - public static Pair makeBitmapRequest( + public static Triple makeBitmapRequest( final HttpUrl url, final BitmapResult result, final int width, @@ -266,10 +267,13 @@ public static Pair makeBitmapRequest( boolean enqueue, boolean mainThread ) { + BitmapRunnable runnable = new BitmapRunnable(url, null, null, result); if (url == null || result == null) return null; Bitmap cachedBitmap = imageCache.get(new Triple<>(url, width, height)); if (cachedBitmap != null) { - performBitmapSuccess(url, cachedBitmap, result, true, mainThread); + runnable.setBitmap(cachedBitmap); + runnable.setFromCache(true); + runOrEnqueueOnMainThread(runnable, mainThread); return null; } OkHttpClient client = applicationClient.getHttpRedirectClient(); @@ -292,8 +296,9 @@ public static Pair makeBitmapRequest( @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { if (!isCancelledException(e)) { - Logger.e("NetUtils", "Error loading bitmap from " + url.toString()); - performBitmapFailure(url, e, result, mainThread); + Logger.e("NetUtils", "Error loading bitmap from " + url); + runnable.setException(e); + runOrEnqueueOnMainThread(runnable, mainThread); } } @@ -301,12 +306,14 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { public void onResponse(@NotNull Call call, @NotNull Response response) { try (ResponseBody body = response.body()) { if (body == null) { - performBitmapFailure(url, new NullPointerException("No response data"), result, mainThread); + runnable.setException(new NullPointerException("No response data")); + runOrEnqueueOnMainThread(runnable, mainThread); return; } if (!response.isSuccessful()) { - performBitmapFailure(url, new HttpCodeException(response), result, mainThread); + runnable.setException(new HttpCodeException(response)); + runOrEnqueueOnMainThread(runnable, mainThread); return; } @@ -314,85 +321,117 @@ public void onResponse(@NotNull Call call, @NotNull Response response) { File tempFile = new File(getCacheDir(), UUID.randomUUID().toString()); if (!tempFile.createNewFile()) { tempFile.delete(); - performBitmapFailure(url, - new IOException("Failed to create temp file for decode."), - result, - mainThread - ); + runnable.setException(new IOException("Failed to create temp file for decode.")); + runOrEnqueueOnMainThread(runnable, mainThread); } FilesKt.writeBytes(tempFile, body.bytes()); Bitmap b = BitmapUtils.decodeFilePreviewImage(tempFile, 0, 0, mainThread ? null : bitmap -> { //noinspection ResultOfMethodCallIgnored tempFile.delete(); - checkBitmap(url, width, height, bitmap, result, false); + checkBitmap(runnable, url, width, height, bitmap, false); }, false); if (b != null) { //noinspection ResultOfMethodCallIgnored tempFile.delete(); - checkBitmap(url, width, height, b, result, true); + checkBitmap(runnable, url, width, height, b, true); } } else { ExceptionCatchingInputStream wrappedStream = new ExceptionCatchingInputStream(body.byteStream()); Bitmap b = BitmapUtils.decode(wrappedStream, width, height); if (wrappedStream.getException() != null) { - performBitmapFailure(url, wrappedStream.getException(), result, mainThread); + runnable.setException(wrappedStream.getException()); + runOrEnqueueOnMainThread(runnable, mainThread); return; } - checkBitmap(url, width, height, b, result, mainThread); + checkBitmap(runnable, url, width, height, b, mainThread); } } catch (Exception e) { - performBitmapFailure(url, e, result, mainThread); + runnable.setException(e); + runOrEnqueueOnMainThread(runnable, mainThread); } catch (OutOfMemoryError e) { getRuntime().gc(); - performBitmapFailure(url, new IOException(e), result, mainThread); + runnable.setException(new IOException(e)); + runOrEnqueueOnMainThread(runnable, mainThread); } } }; if (enqueue) { call.enqueue(callback); } - return new Pair<>(call, callback); + return new Triple<>(call, callback, runnable); } private static void checkBitmap( + BitmapRunnable runnable, HttpUrl url, int requestWidth, int requestedHeight, Bitmap result, - BitmapResult bitmapResult, boolean mainThread ) { if (result == null) { - performBitmapFailure(url, new NullPointerException("Bitmap returned is null"), bitmapResult, mainThread); - return; + runnable.setException(new NullPointerException("Bitmap returned is null")); + runOrEnqueueOnMainThread(runnable, mainThread); } imageCache.put(new Triple<>(url, requestWidth, requestedHeight), result); - performBitmapSuccess(url, result, bitmapResult, false, mainThread); + runnable.setBitmap(result); + runOrEnqueueOnMainThread(runnable, mainThread); } - private static void performBitmapSuccess( - @NonNull final HttpUrl url, - @NonNull Bitmap bitmap, - BitmapResult result, - boolean fromCache, - boolean mainThread - ) { + private static void runOrEnqueueOnMainThread(BitmapRunnable runnable, boolean mainThread) { if (mainThread) { - BackgroundUtils.runOnMainThread(() -> result.onBitmapSuccess(url, bitmap, fromCache)); + BackgroundUtils.runOnMainThread(runnable); } else { - result.onBitmapSuccess(url, bitmap, fromCache); + runnable.run(); } } - private static void performBitmapFailure( - @NonNull final HttpUrl url, Exception e, BitmapResult result, boolean mainThread - ) { - if (isCancelledException(e)) return; - if (mainThread) { - BackgroundUtils.runOnMainThread(() -> result.onBitmapFailure(url, e)); - } else { - result.onBitmapFailure(url, e); + private static class BitmapRunnable + implements Runnable { + private final HttpUrl url; + private Exception exception; + private Bitmap bitmap; + private final BitmapResult result; + private boolean fromCache = false; + + public BitmapRunnable( + final HttpUrl url, Exception exception, Bitmap bitmap, BitmapResult result + ) { + this.url = url; + this.exception = exception; + this.bitmap = bitmap; + this.result = result; + } + + public Exception getException() { + return exception; + } + + public void setException(Exception e) { + this.exception = e; + } + + public Bitmap getBitmap() { + return bitmap; + } + + public void setBitmap(Bitmap bitmap) { + this.bitmap = bitmap; + } + + public void setFromCache(boolean fromCache) { + this.fromCache = fromCache; + } + + @Override + public void run() { + if (bitmap != null) { + result.onBitmapSuccess(url, bitmap, fromCache); + } else if (exception != null) { + if (isCancelledException(exception)) return; + result.onBitmapFailure(url, exception); + } } } diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/features/embedding/embedders/QuickLatexEmbedder.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/features/embedding/embedders/QuickLatexEmbedder.java index a3254ac76..b27bd3e7a 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/features/embedding/embedders/QuickLatexEmbedder.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/features/embedding/embedders/QuickLatexEmbedder.java @@ -32,6 +32,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import kotlin.Triple; import kotlin.random.Random; import okhttp3.*; @@ -96,10 +97,11 @@ public List> generateCallPairs( @Override public void onResponse(@NonNull Call call, @NonNull Response response) { BackgroundUtils.runOnBackgroundThread(() -> { - Pair ret = generateMathSpanCalls(commentCopy, imageUrl, math.first); - if (ret == null || ret.first == null || ret.second == null) return; + Triple ret = + generateMathSpanCalls(commentCopy, imageUrl, math.first); + if (ret == null || ret.getFirst() == null || ret.getSecond() == null) return; try { - ret.second.onResponse(ret.first, ret.first.execute()); + ret.getSecond().onResponse(ret.getFirst(), ret.getFirst().execute()); } catch (Exception ignored) { } }); @@ -125,10 +127,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) { String err = matcher.group(2); if (err == null) { mathCache.put(math.first, url); - Pair ret = + Triple ret = generateMathSpanCalls(commentCopy, url, math.first); - if (ret == null || ret.first == null || ret.second == null) return; - ret.second.onResponse(ret.first, ret.first.execute()); + if (ret == null || ret.getFirst() == null || ret.getSecond() == null) + return; + ret.getSecond().onResponse(ret.getFirst(), ret.getFirst().execute()); } } } catch (Exception ignored) { @@ -161,7 +164,7 @@ private Request setupMathImageUrlRequest(String formula) { .build(); } - private Pair generateMathSpanCalls( + private Triple generateMathSpanCalls( SpannableStringBuilder comment, @NonNull HttpUrl imageUrl, String rawMath ) { // execute immediately, so that the invalidate function is called when all embeds are done diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/adapter/DrawerHistoryAdapter.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/adapter/DrawerHistoryAdapter.java index da7c0912d..7dd70af47 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/adapter/DrawerHistoryAdapter.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/adapter/DrawerHistoryAdapter.java @@ -32,9 +32,6 @@ import java.util.ArrayList; import java.util.List; -import okhttp3.Call; -import okhttp3.HttpUrl; - public class DrawerHistoryAdapter extends RecyclerView.Adapter implements SearchLayout.SearchLayoutCallback { @@ -167,8 +164,7 @@ public class HistoryCell private final ImageView thumbnail; private final TextView text; private final TextView subtext; - private Call thumbnailCall; - private HttpUrl loadedUrl; + private ImageLoadableData data; public HistoryCell(View itemView) { super(itemView); @@ -201,23 +197,13 @@ public History getHistory() { } @Override - public HttpUrl getLoadedUrl() { - return loadedUrl; - } - - @Override - public void setLoadedUrl(HttpUrl url) { - loadedUrl = url; - } - - @Override - public Call getImageCall() { - return thumbnailCall; + public ImageLoadableData getImageLoadableData() { + return data; } @Override - public void setImageCall(Call call) { - thumbnailCall = call; + public void setImageLoadableData(ImageLoadableData data) { + this.data = data; } } diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/adapter/DrawerPinAdapter.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/adapter/DrawerPinAdapter.java index 9a6f1050a..a0ba86ddd 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/adapter/DrawerPinAdapter.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/adapter/DrawerPinAdapter.java @@ -53,9 +53,6 @@ import javax.inject.Inject; -import okhttp3.Call; -import okhttp3.HttpUrl; - public class DrawerPinAdapter extends RecyclerView.Adapter implements SearchLayout.SearchLayoutCallback { @@ -218,8 +215,7 @@ public class PinViewHolder private final TextView title; private final TextView threadInfo; private final TextView watchCountText; - private Call thumbnailCall; - private HttpUrl loadedUrl; + private ImageLoadableData data; private PinViewHolder(View itemView) { super(itemView); @@ -258,23 +254,13 @@ private PinViewHolder(View itemView) { } @Override - public HttpUrl getLoadedUrl() { - return loadedUrl; - } - - @Override - public void setLoadedUrl(HttpUrl url) { - loadedUrl = url; - } - - @Override - public Call getImageCall() { - return thumbnailCall; + public ImageLoadableData getImageLoadableData() { + return data; } @Override - public void setImageCall(Call call) { - thumbnailCall = call; + public void setImageLoadableData(ImageLoadableData data) { + this.data = data; } } diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/captcha/LegacyCaptchaLayout.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/captcha/LegacyCaptchaLayout.java index 36fb621f1..06c8f4552 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/captcha/LegacyCaptchaLayout.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/captcha/LegacyCaptchaLayout.java @@ -37,7 +37,6 @@ import java.io.InputStreamReader; import kotlin.io.TextStreamsKt; -import okhttp3.Call; import okhttp3.HttpUrl; public class LegacyCaptchaLayout @@ -47,8 +46,7 @@ public class LegacyCaptchaLayout private EditText input; private WebView internalWebView; - private Call captchaCall; - private HttpUrl loadedUrl; + private ImageLoadableData data; private SiteAuthentication authentication; private AuthenticationLayoutCallback callback; @@ -144,23 +142,13 @@ private void onCaptchaLoaded(final String imageUrl, final String challenge) { } @Override - public HttpUrl getLoadedUrl() { - return loadedUrl; + public ImageLoadableData getImageLoadableData() { + return data; } @Override - public void setLoadedUrl(HttpUrl url) { - loadedUrl = url; - } - - @Override - public Call getImageCall() { - return captchaCall; - } - - @Override - public void setImageCall(Call call) { - captchaCall = call; + public void setImageLoadableData(ImageLoadableData data) { + this.data = data; } public static class CaptchaInterface { diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/cell/CardPostCell.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/cell/CardPostCell.java index c4e70b053..7d04f2be7 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/cell/CardPostCell.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/cell/CardPostCell.java @@ -51,9 +51,6 @@ import java.util.ArrayList; import java.util.List; -import okhttp3.Call; -import okhttp3.HttpUrl; - public class CardPostCell extends CardView implements PostCellInterface, ImageLoadable { @@ -69,8 +66,7 @@ public class CardPostCell private PostIcons icons; private OneShotPreDrawListener maxLinesUpdater; - private Call thumbnailCall; - private HttpUrl loadedUrl; + private ImageLoadableData data; public CardPostCell(Context context) { super(context); @@ -110,6 +106,7 @@ protected void onFinishInflate() { .setUnixTimestampSeconds(System.currentTimeMillis()) .comment("") .build(), false); + thumbView.setImageResource(R.drawable.ic_stat_notify); } setOnClickListener((view) -> callback.onPostClicked(post)); @@ -286,22 +283,12 @@ private void setCompact(boolean compact) { } @Override - public HttpUrl getLoadedUrl() { - return loadedUrl; - } - - @Override - public void setLoadedUrl(HttpUrl url) { - loadedUrl = url; - } - - @Override - public Call getImageCall() { - return thumbnailCall; + public ImageLoadableData getImageLoadableData() { + return data; } @Override - public void setImageCall(Call call) { - this.thumbnailCall = call; + public void setImageLoadableData(ImageLoadableData data) { + this.data = data; } } diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/cell/PostCell.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/cell/PostCell.java index 1d8724f14..8b1faa7f0 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/cell/PostCell.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/cell/PostCell.java @@ -70,7 +70,6 @@ import java.util.ArrayList; import java.util.List; -import okhttp3.Call; import okhttp3.HttpUrl; public class PostCell @@ -569,6 +568,7 @@ public PostImagesAdapter.PostImageViewHolder onCreateViewHolder(@NonNull ViewGro ShapeablePostImageView thumbnailView = new ShapeablePostImageView(c); thumbnailView.setLayoutParams(new ViewGroup.MarginLayoutParams(getThumbnailSize(c), getThumbnailSize(c))); thumbnailView.setShapeAppearanceModel(ShapeAppearanceModel.builder().setAllCornerSizes(dp(c, 2)).build()); + thumbnailView.setImageResource(R.drawable.ic_fluent_image_off_24_filled); return new PostImageViewHolder(thumbnailView); } @@ -618,8 +618,7 @@ private class PostImageViewHolder extends RecyclerView.ViewHolder implements ImageLoadable { private final ShapeablePostImageView thumbnailView; - private Call imageCall; - private HttpUrl loadedUrl; + private ImageLoadableData data; public PostImageViewHolder(@NonNull ShapeablePostImageView itemView) { super(itemView); @@ -627,23 +626,13 @@ public PostImageViewHolder(@NonNull ShapeablePostImageView itemView) { } @Override - public HttpUrl getLoadedUrl() { - return loadedUrl; + public ImageLoadableData getImageLoadableData() { + return data; } @Override - public void setLoadedUrl(HttpUrl url) { - loadedUrl = url; - } - - @Override - public Call getImageCall() { - return imageCall; - } - - @Override - public void setImageCall(Call call) { - this.imageCall = call; + public void setImageLoadableData(ImageLoadableData data) { + this.data = data; } } } diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/AlbumDownloadController.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/AlbumDownloadController.java index e50581c2c..3a05f1522 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/AlbumDownloadController.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/AlbumDownloadController.java @@ -53,8 +53,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; -import okhttp3.Call; -import okhttp3.HttpUrl; public class AlbumDownloadController extends Controller { @@ -315,8 +313,7 @@ private class AlbumDownloadHolder implements ImageLoadable { private final ImageView checkbox; private final ShapeablePostImageView thumbnailView; - private Call thumbnailCall; - private HttpUrl loadedUrl; + private ImageLoadableData data; public AlbumDownloadHolder(View itemView) { super(itemView); @@ -333,21 +330,13 @@ public AlbumDownloadHolder(View itemView) { } @Override - public HttpUrl getLoadedUrl() { - return loadedUrl; + public ImageLoadableData getImageLoadableData() { + return data; } @Override - public void setLoadedUrl(HttpUrl url) { - loadedUrl = url; - } - - public Call getImageCall() { - return thumbnailCall; - } - - public void setImageCall(Call imageCall) { - this.thumbnailCall = imageCall; + public void setImageLoadableData(ImageLoadableData data) { + this.data = data; } } diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/AlbumViewController.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/AlbumViewController.java index b884bf5ed..725e4454f 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/AlbumViewController.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/AlbumViewController.java @@ -43,9 +43,6 @@ import java.util.List; -import okhttp3.Call; -import okhttp3.HttpUrl; - public class AlbumViewController extends Controller implements ImageViewerController.ImageViewerCallback, ImageViewerController.GoPostCallback, @@ -210,8 +207,7 @@ private class AlbumItemCellHolder implements ImageLoadable { private PostImage postImage; private final ShapeablePostImageView thumbnailView; - private Call thumbnailCall; - private HttpUrl loadedUrl; + private ImageLoadableData data; public AlbumItemCellHolder(View view) { super(view); @@ -242,23 +238,13 @@ public AlbumItemCellHolder(View view) { } @Override - public HttpUrl getLoadedUrl() { - return loadedUrl; - } - - @Override - public void setLoadedUrl(HttpUrl url) { - loadedUrl = url; - } - - @Override - public Call getImageCall() { - return thumbnailCall; + public ImageLoadableData getImageLoadableData() { + return data; } @Override - public void setImageCall(Call call) { - this.thumbnailCall = call; + public void setImageLoadableData(ImageLoadableData data) { + this.data = data; } } } diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/RemovedPostsController.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/RemovedPostsController.java index 70b0e20b9..aaf8c87a2 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/RemovedPostsController.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/ui/controller/RemovedPostsController.java @@ -22,9 +22,6 @@ import java.util.*; -import okhttp3.Call; -import okhttp3.HttpUrl; - public class RemovedPostsController extends BaseFloatingController { private final RemovedPostsHelper removedPostsHelper; @@ -177,8 +174,7 @@ private static class RemovedPostCell private final TextView postComment; private final CheckBox checkbox; private final ShapeablePostImageView postImage; - private Call thumbnailCall; - private HttpUrl loadedUrl; + private ImageLoadableData data; public RemovedPostCell(@NonNull View itemView) { super(itemView); @@ -189,23 +185,13 @@ public RemovedPostCell(@NonNull View itemView) { } @Override - public HttpUrl getLoadedUrl() { - return loadedUrl; - } - - @Override - public void setLoadedUrl(HttpUrl url) { - loadedUrl = url; - } - - @Override - public Call getImageCall() { - return thumbnailCall; + public ImageLoadableData getImageLoadableData() { + return data; } @Override - public void setImageCall(Call call) { - thumbnailCall = call; + public void setImageLoadableData(ImageLoadableData data) { + this.data = data; } } diff --git a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/utils/BackgroundUtils.java b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/utils/BackgroundUtils.java index fbdd1f125..52cfbb90f 100644 --- a/Kuroba/app/src/main/java/com/github/adamantcheese/chan/utils/BackgroundUtils.java +++ b/Kuroba/app/src/main/java/com/github/adamantcheese/chan/utils/BackgroundUtils.java @@ -63,6 +63,10 @@ public static void runOnMainThread(Runnable runnable, long delay) { mainHandler.postDelayed(runnable, delay); } + public static void cancel(Runnable runnable) { + mainHandler.removeCallbacks(runnable); + } + public static void cleanup() { mainHandler.removeCallbacksAndMessages(null); }