diff options
Diffstat (limited to 'org.fox.ttrss/src/main')
8 files changed, 423 insertions, 56 deletions
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java index eaa997f4..ced956c2 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java @@ -131,7 +131,7 @@ public class GalleryActivity extends CommonActivity { Log.d(TAG, "observed items to check=" + itemsToCheck); m_checkProgress.setMax(itemsToCheck); - m_checkProgress.setVisibility(View.VISIBLE); + m_checkProgress.setVisibility(itemsToCheck > 0 ? View.VISIBLE : View.GONE); m_checkProgress.setProgress(0); }); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java index d5206518..db141427 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java @@ -61,7 +61,7 @@ public class GalleryImageFragment extends GalleryBaseFragment { // final GlideDrawableImageViewTarget glideImage = new GlideDrawableImageViewTarget(imgView); - Glide.with(m_activity) + Glide.with(this) .load(m_url) .diskCacheStrategy(DiskCacheStrategy.ALL) .skipMemoryCache(false) @@ -71,7 +71,7 @@ public class GalleryImageFragment extends GalleryBaseFragment { progressBar.setVisibility(View.GONE); errorMessage.setVisibility(View.VISIBLE); - ActivityCompat.startPostponedEnterTransition(m_activity); + // ActivityCompat.startPostponedEnterTransition(m_activity); return false; } @@ -81,7 +81,7 @@ public class GalleryImageFragment extends GalleryBaseFragment { progressBar.setVisibility(View.GONE); errorMessage.setVisibility(View.GONE); - ActivityCompat.startPostponedEnterTransition(m_activity); + // ActivityCompat.startPostponedEnterTransition(m_activity); return false; } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryModel.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryModel.java index 8458fc33..2f0451fb 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryModel.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryModel.java @@ -79,6 +79,7 @@ public class GalleryModel extends AndroidViewModel { m_itemsToCheck.postValue(elems.size()); int currentItem = 0; + boolean firstFound = false; for (Element elem : elems) { ++currentItem; @@ -95,6 +96,8 @@ public class GalleryModel extends AndroidViewModel { if (src != null && src.equals(srcFirst)) { Log.d(TAG, "first item found, vid=" + src); + firstFound = true; + GalleryEntry item = new GalleryEntry(src, GalleryEntry.GalleryEntryType.TYPE_VIDEO, poster); checkList.add(item); @@ -115,6 +118,8 @@ public class GalleryModel extends AndroidViewModel { if (src != null && src.equals(srcFirst)) { Log.d(TAG, "first item found, img=" + src); + firstFound = true; + GalleryEntry item = new GalleryEntry(src, GalleryEntry.GalleryEntryType.TYPE_IMAGE, null); checkList.add(item); @@ -148,6 +153,13 @@ public class GalleryModel extends AndroidViewModel { m_checkProgress.postValue(currentItem); } + + // if we didn't find it in the document, let's add insert to the list anyway so shared transition + // would hopefully work + if (!firstFound) { + checkList.add(0, new GalleryEntry(srcFirst, GalleryEntry.GalleryEntryType.TYPE_IMAGE, null)); + m_items.postValue(checkList); + } }); } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java index 18d08e4f..a171fb5b 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java @@ -56,7 +56,7 @@ public class GalleryVideoFragment extends GalleryBaseFragment { registerForContextMenu(imgView); - ActivityCompat.startPostponedEnterTransition(m_activity); + // ActivityCompat.startPostponedEnterTransition(m_activity); view.findViewById(R.id.flavor_image_progress).setVisibility(View.VISIBLE); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java index 96cd245c..d5da9d6e 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java @@ -64,14 +64,17 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy; import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.DrawableImageViewTarget; import com.bumptech.glide.request.target.Target; import com.google.android.material.button.MaterialButton; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; +import org.fox.ttrss.glide.ProgressTarget; import org.fox.ttrss.types.Article; import org.fox.ttrss.types.ArticleList; import org.fox.ttrss.types.Attachment; @@ -87,8 +90,6 @@ import java.util.HashMap; import java.util.TimeZone; import java.util.stream.Collectors; -import jp.wasabeef.glide.transformations.CropCircleTransformation; - public class HeadlinesFragment extends androidx.fragment.app.Fragment { private boolean m_isLazyLoading; @@ -617,7 +618,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { public View flavorImageOverflow; public TextureView flavorVideoView; public MaterialButton attachmentsView; - //public ProgressTarget<String, GlideDrawable> flavorProgressTarget; + public ProgressTarget<String, Drawable> flavorProgressTarget; int articleId; public TextView linkHost; @@ -659,9 +660,10 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { attachmentsView = v.findViewById(R.id.attachments); linkHost = v.findViewById(R.id.link_host); - /* if (flavorImageView != null && flavorImageLoadingBar != null) { - flavorProgressTarget = new FlavorProgressTarget<>(new GlideDrawableImageViewTarget(flavorImageView), flavorImageLoadingBar); - } */ + if (flavorImageView != null && flavorImageLoadingBar != null) { + flavorProgressTarget = new FlavorProgressTarget<>(new DrawableImageViewTarget(flavorImageView), + flavorImageLoadingBar); + } } public void clearAnimation() { @@ -669,7 +671,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { } } - /* private static class FlavorProgressTarget<Z> extends ProgressTarget<String, Z> { + private static class FlavorProgressTarget<Z> extends ProgressTarget<String, Z> { private final ProgressBar progress; public FlavorProgressTarget(Target<Z> target, ProgressBar progress) { super(target); @@ -694,7 +696,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { @Override protected void onDelivered() { progress.setVisibility(View.INVISIBLE); } - } */ + } private class ArticleListAdapter extends ListAdapter<Article, ArticleViewHolder> { public static final int VIEW_NORMAL = 0; @@ -711,8 +713,8 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { private final TextDrawable.IBuilder m_drawableBuilder = TextDrawable.builder().round(); boolean flavorImageEnabled; + private final int m_screenWidth; private final int m_screenHeight; - private int m_lastAddedPosition; private final ConnectivityManager m_cmgr; @@ -740,6 +742,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { Point size = new Point(); display.getSize(size); m_screenHeight = size.y; + m_screenWidth = size.x; String headlineMode = m_prefs.getString("headline_mode", "HL_DEFAULT"); flavorImageEnabled = "HL_DEFAULT".equals(headlineMode) || "HL_COMPACT".equals(headlineMode); @@ -1015,7 +1018,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { holder.flavorVideoView.setVisibility(View.GONE); holder.flavorImageHolder.setVisibility(View.GONE); - Glide.with(m_activity).clear(holder.flavorImageView); + Glide.with(HeadlinesFragment.this).clear(holder.flavorImageView); // this is needed if our flavor image goes behind base listview element holder.headlineHeader.setOnClickListener(v -> { @@ -1069,66 +1072,66 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { } holder.flavorImageView.setVisibility(View.VISIBLE); - holder.flavorImageView.setMaxHeight((int)(m_screenHeight * 0.6f)); + + int maxImageSize = (int) (m_screenHeight * 0.5f); + + // we also downsample below using glide to save RAM + // holder.flavorImageView.setMaxHeight(maxImageSize); // only show holder if we're about to display a picture holder.flavorImageHolder.setVisibility(View.VISIBLE); // prevent lower listiew entries from jumping around if this row is modified - if (m_flavorHeightsCache.containsKey(article.id)) { + /* if (m_flavorHeightsCache.containsKey(article.id)) { int cachedHeight = m_flavorHeightsCache.get(article.id); if (cachedHeight > 0) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) holder.flavorImageView.getLayoutParams(); lp.height = cachedHeight; } - } + } */ - // holder.flavorProgressTarget.setModel(article.flavorImageUri); - - try { + holder.flavorProgressTarget.setModel(article.flavorImageUri); - Glide.with(m_activity) - .load(article.flavorImageUri) - .transition(DrawableTransitionOptions.withCrossFade()) - .diskCacheStrategy(DiskCacheStrategy.ALL) - .skipMemoryCache(false) - .listener(new RequestListener<Drawable>() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + Glide.with(HeadlinesFragment.this) + .load(article.flavorImageUri) + .transition(DrawableTransitionOptions.withCrossFade()) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .skipMemoryCache(false) + .listener(new RequestListener<Drawable>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { - holder.flavorImageLoadingBar.setVisibility(View.GONE); - holder.flavorImageView.setVisibility(View.GONE); + holder.flavorImageLoadingBar.setVisibility(View.GONE); + holder.flavorImageView.setVisibility(View.GONE); - return false; - } + return false; + } - @Override - public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { - holder.flavorImageLoadingBar.setVisibility(View.GONE); + holder.flavorImageLoadingBar.setVisibility(View.GONE); - if (resource.getIntrinsicWidth() > FLAVOR_IMG_MIN_SIZE && resource.getIntrinsicHeight() > FLAVOR_IMG_MIN_SIZE) { + if (resource.getIntrinsicWidth() > FLAVOR_IMG_MIN_SIZE && resource.getIntrinsicHeight() > FLAVOR_IMG_MIN_SIZE) { - holder.flavorImageView.setVisibility(View.VISIBLE); - holder.flavorImageOverflow.setVisibility(View.VISIBLE); + holder.flavorImageView.setVisibility(View.VISIBLE); + holder.flavorImageOverflow.setVisibility(View.VISIBLE); - adjustVideoKindView(holder, article); + adjustVideoKindView(holder, article); - return false; - } else { + return false; + } else { - holder.flavorImageOverflow.setVisibility(View.GONE); - holder.flavorImageView.setVisibility(View.GONE); + holder.flavorImageOverflow.setVisibility(View.GONE); + holder.flavorImageView.setVisibility(View.GONE); - return true; - } + return true; } - }) - .into(new DrawableImageViewTarget(holder.flavorImageView)); - } catch (OutOfMemoryError e) { - e.printStackTrace(); - } + } + }) + .into(holder.flavorProgressTarget); + } if (m_prefs.getBoolean("inline_video_player", false) && article.flavorImage != null && @@ -1339,12 +1342,12 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { holder.textImage.setImageDrawable(textDrawable); } else { - Glide.with(m_activity) + Glide.with(HeadlinesFragment.this) .load(article.flavorImageUri) .transition(DrawableTransitionOptions.withCrossFade()) .placeholder(textDrawable) .thumbnail(0.5f) - .transform(new CropCircleTransformation()) + .apply(RequestOptions.circleCropTransform()) .diskCacheStrategy(DiskCacheStrategy.ALL) .skipMemoryCache(false) .listener(new RequestListener<Drawable>() { @@ -1400,12 +1403,14 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { intent.putExtra("content", tempContent); - ActivityOptionsCompat options = + /* ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(m_activity, transitionView != null ? transitionView : holder.flavorImageView, - "gallery:" + (article.flavorStreamUri != null ? article.flavorStreamUri : article.flavorImageUri)); + "gallery:" + (article.flavorStreamUri != null ? article.flavorStreamUri : article.flavorImageUri)); */ + + // ActivityCompat.startActivity(m_activity, intent, options.toBundle()) - ActivityCompat.startActivity(m_activity, intent, options.toBundle()); + startActivity(intent); } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OkHttpProgressGlideModule.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OkHttpProgressGlideModule.java new file mode 100644 index 00000000..561f9a86 --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OkHttpProgressGlideModule.java @@ -0,0 +1,172 @@ +package org.fox.ttrss.glide; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.GlideBuilder; +import com.bumptech.glide.Registry; +import com.bumptech.glide.annotation.GlideModule; +import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; +import com.bumptech.glide.load.model.GlideUrl; +import com.bumptech.glide.module.AppGlideModule; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import okhttp3.HttpUrl; +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okio.Buffer; +import okio.BufferedSource; +import okio.ForwardingSource; +import okio.Okio; +import okio.Source; + +@GlideModule +public class OkHttpProgressGlideModule extends AppGlideModule { + @Override public void registerComponents(Context context, Glide glide, Registry registry) { + OkHttpClient client = new OkHttpClient.Builder() + .addNetworkInterceptor(createInterceptor(new DispatchingProgressListener())) + .build(); + + // registry.append() doesn't work... + registry.prepend(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(client)); + } + + public static Interceptor createInterceptor(final ResponseProgressListener listener) { + return chain -> { + Request request = chain.request(); + Response response = chain.proceed(request); + + return response.newBuilder() + .body(new OkHttpProgressResponseBody(request.url(), response.body(), listener)) + .build(); + }; + } + + public interface UIProgressListener { + void onProgress(long bytesRead, long expectedLength); + /** + * Control how often the listener needs an update. 0% and 100% will always be dispatched. + * @return in percentage (0.2 = call {@link #onProgress} around every 0.2 percent of progress) + */ + float getGranualityPercentage(); + } + + public static void forget(String url) { + DispatchingProgressListener.forget(url); + } + public static void expect(String url, UIProgressListener listener) { + DispatchingProgressListener.expect(url, listener); + } + + public interface ResponseProgressListener { + void update(HttpUrl url, long bytesRead, long contentLength); + } + + private static class DispatchingProgressListener implements ResponseProgressListener { + private static final Map<String, UIProgressListener> LISTENERS = new HashMap<>(); + private static final Map<String, Long> PROGRESSES = new HashMap<>(); + + private final Handler handler; + DispatchingProgressListener() { + this.handler = new Handler(Looper.getMainLooper()); + } + + static void forget(String url) { + LISTENERS.remove(url); + PROGRESSES.remove(url); + } + static void expect(String url, UIProgressListener listener) { + LISTENERS.put(url, listener); + } + + @Override public void update(HttpUrl url, final long bytesRead, final long contentLength) { + //System.out.printf("%s: %d/%d = %.2f%%%n", url, bytesRead, contentLength, (100f * bytesRead) / contentLength); + + String key = url.toString(); + final UIProgressListener listener = LISTENERS.get(key); + + if (listener == null) { + return; + } + if (contentLength <= bytesRead) { + forget(key); + } + if (needsDispatch(key, bytesRead, contentLength, listener.getGranualityPercentage())) { + handler.post(() -> listener.onProgress(bytesRead, contentLength)); + } + } + + private boolean needsDispatch(String key, long current, long total, float granularity) { + if (granularity == 0 || current == 0 || total == current) { + return true; + } + float percent = 100f * current / total; + long currentProgress = (long)(percent / granularity); + Long lastProgress = PROGRESSES.get(key); + if (lastProgress == null || currentProgress != lastProgress) { + PROGRESSES.put(key, currentProgress); + return true; + } else { + return false; + } + } + } + + public static class OkHttpProgressResponseBody extends ResponseBody { + private final HttpUrl url; + private final ResponseBody responseBody; + private final ResponseProgressListener progressListener; + private BufferedSource bufferedSource; + + public OkHttpProgressResponseBody(HttpUrl url, ResponseBody responseBody, + ResponseProgressListener progressListener) { + + this.url = url; + this.responseBody = responseBody; + this.progressListener = progressListener; + } + + @Override public MediaType contentType() { + return responseBody.contentType(); + } + + @Override public long contentLength() { + return responseBody.contentLength(); + } + + @Override public BufferedSource source() { + if (bufferedSource == null) { + bufferedSource = Okio.buffer(source(responseBody.source())); + } + return bufferedSource; + } + + private Source source(Source source) { + return new ForwardingSource(source) { + long totalBytesRead = 0L; + @Override public long read(Buffer sink, long byteCount) throws IOException { + long bytesRead = super.read(sink, byteCount); + long fullLength = responseBody.contentLength(); + if (bytesRead == -1) { // this source is exhausted + totalBytesRead = fullLength; + } else { + totalBytesRead += bytesRead; + } + progressListener.update(url, totalBytesRead, fullLength); + return bytesRead; + } + }; + } + } +}
\ No newline at end of file diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/ProgressTarget.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/ProgressTarget.java new file mode 100644 index 00000000..172dd28a --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/ProgressTarget.java @@ -0,0 +1,115 @@ +package org.fox.ttrss.glide; + + +import android.graphics.drawable.Drawable; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.Resource; +import com.bumptech.glide.request.target.Target; +import com.bumptech.glide.request.transition.Transition; + +public abstract class ProgressTarget<T, Z> extends WrappingTarget<Z> implements OkHttpProgressGlideModule.UIProgressListener { + private T model; + private boolean ignoreProgress = true; + public ProgressTarget(Target<Z> target) { + this(null, target); + } + public ProgressTarget(T model, Target<Z> target) { + super(target); + this.model = model; + } + + public final T getModel() { + return model; + } + public final void setModel(T model) { + this.model = model; + } + /** + * Convert a model into an Url string that is used to match up the OkHttp requests. For explicit + * {@link com.bumptech.glide.load.model.GlideUrl GlideUrl} loads this needs to return + * {@link com.bumptech.glide.load.model.GlideUrl#toStringUrl toStringUrl}. For custom models do the same as your + * {@link com.bumptech.glide.load.model.stream.BaseGlideUrlLoader BaseGlideUrlLoader} does. + * @param model return the representation of the given model, DO NOT use {@link #getModel()} inside this method. + * @return a stable Url representation of the model, otherwise the progress reporting won't work + */ + protected String toUrlString(T model) { + return String.valueOf(model); + } + + @Override public float getGranualityPercentage() { + return 1.0f; + } + + @Override public void onProgress(long bytesRead, long expectedLength) { + if (ignoreProgress) { + return; + } + if (expectedLength == Long.MAX_VALUE) { + onConnecting(); + } else if (bytesRead == expectedLength) { + onDownloaded(); + } else { + onDownloading(bytesRead, expectedLength); + } + } + + /** + * Called when the Glide load has started. + * At this time it is not known if the Glide will even go and use the network to fetch the image. + */ + protected abstract void onConnecting(); + /** + * Called when there's any progress on the download; not called when loading from cache. + * At this time we know how many bytes have been transferred through the wire. + */ + protected abstract void onDownloading(long bytesRead, long expectedLength); + /** + * Called when the bytes downloaded reach the length reported by the server; not called when loading from cache. + * At this time it is fairly certain, that Glide either finished reading the stream. + * This means that the image was either already decoded or saved the network stream to cache. + * In the latter case there's more work to do: decode the image from cache and transform. + * These cannot be listened to for progress so it's unsure how fast they'll be, best to show indeterminate progress. + */ + protected abstract void onDownloaded(); + /** + * Called when the Glide load has finished either by successfully loading the image or failing to load or cancelled. + * In any case the best is to hide/reset any progress displays. + */ + protected abstract void onDelivered(); + + private void start() { + OkHttpProgressGlideModule.expect(toUrlString(model), this); + ignoreProgress = false; + onProgress(0, Long.MAX_VALUE); + } + private void cleanup() { + ignoreProgress = true; + T model = this.model; // save in case it gets modified + onDelivered(); + OkHttpProgressGlideModule.forget(toUrlString(model)); + this.model = null; + } + + @Override public void onLoadStarted(Drawable placeholder) { + super.onLoadStarted(placeholder); + start(); + } + /** @noinspection unchecked*/ + public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) { + cleanup(); + super.onResourceReady(resource, (Transition)transition); + } + @Override public void onLoadFailed(Drawable errorDrawable) { + cleanup(); + super.onLoadFailed(errorDrawable); + } + @Override public void onLoadCleared(Drawable placeholder) { + cleanup(); + super.onLoadCleared(placeholder); + } +}
\ No newline at end of file diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/WrappingTarget.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/WrappingTarget.java new file mode 100755 index 00000000..314800d9 --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/WrappingTarget.java @@ -0,0 +1,63 @@ +package org.fox.ttrss.glide; + +import android.graphics.drawable.Drawable; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bumptech.glide.request.Request; +import com.bumptech.glide.request.target.SizeReadyCallback; +import com.bumptech.glide.request.target.Target; +import com.bumptech.glide.request.transition.Transition; + +public class WrappingTarget<Z> implements Target<Z> { + protected final @NonNull Target<? super Z> target; + public WrappingTarget(@NonNull Target<? super Z> target) { + this.target = target; + } + public @NonNull Target<? super Z> getWrappedTarget() { + return target; + } + @Override public void getSize(SizeReadyCallback cb) { + target.getSize(cb); + } + + @Override + public void removeCallback(@NonNull SizeReadyCallback cb) { + + } + + @Override public void onLoadStarted(Drawable placeholder) { + target.onLoadStarted(placeholder); + } + @Override public void onLoadFailed(Drawable errorDrawable) { + target.onLoadFailed(errorDrawable); + } + + /** @noinspection unchecked*/ + @Override + public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) { + target.onResourceReady(resource, (Transition)transition); + } + + @Override public void onLoadCleared(Drawable placeholder) { + target.onLoadCleared(placeholder); + } + + @Override public Request getRequest() { + return target.getRequest(); + } + @Override public void setRequest(Request request) { + target.setRequest(request); + } + + @Override public void onStart() { + target.onStart(); + } + @Override public void onStop() { + target.onStop(); + } + @Override public void onDestroy() { + target.onDestroy(); + } +}
\ No newline at end of file |