From bf908f0b7dc44338f24c7a2b3d745070023a8704 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 21:06:12 +0200 Subject: [PATCH] Add documentation and fix SonarCloud issue --- .../playlist/model/PlaylistRemoteEntity.java | 6 +++- .../detail/BaseDescriptionFragment.java | 1 + .../external_communication/ShareUtils.java | 4 +-- .../newpipe/util/image/ImageStrategy.java | 22 +++++++++++-- .../newpipe/util/image/PicassoHelper.java | 31 ++++++++++--------- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java index 5e8977821..a64f2952c 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java @@ -70,7 +70,9 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { @Ignore public PlaylistRemoteEntity(final PlaylistInfo info) { this(info.getServiceId(), info.getName(), info.getUrl(), - ImageStrategy.choosePreferredImage(info.getThumbnails()), + // use uploader avatar when no thumbnail is available + ImageStrategy.choosePreferredImage(info.getThumbnails().isEmpty() + ? info.getUploaderAvatars() : info.getThumbnails()), info.getUploaderName(), info.getStreamCount()); } @@ -84,6 +86,8 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { && getStreamCount() == info.getStreamCount() && TextUtils.equals(getName(), info.getName()) && TextUtils.equals(getUrl(), info.getUrl()) + // we want to update the local playlist data even when either the remote thumbnail + // URL changes, or the preferred image quality setting is changed by the user && TextUtils.equals(getThumbnailUrl(), ImageStrategy.choosePreferredImage(info.getThumbnails())) && TextUtils.equals(getUploader(), info.getUploaderName()); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java index 2bd5906bc..ffd10d827 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java @@ -224,6 +224,7 @@ public abstract class BaseDescriptionFragment extends BaseFragment { case LOW: urls.append(getString(R.string.image_quality_low)); break; + default: // unreachable, Image.ResolutionLevel.UNKNOWN is already filtered out case MEDIUM: urls.append(getString(R.string.image_quality_medium)); break; diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java index fc057de41..7524e5413 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java @@ -269,8 +269,8 @@ public final class ShareUtils { * *

* For Android 10+ users, a content preview is shown, which includes the title of the shared - * content and an image preview the content, if its URL is not null or empty and its - * corresponding image is in the image cache. + * content and an image preview the content, if the preferred image chosen by {@link + * ImageStrategy#choosePreferredImage(List)} is in the image cache. *

* * @param context the context to use diff --git a/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java index 89e63af3f..1583c0b09 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java @@ -38,19 +38,35 @@ public final class ImageStrategy { // images whose size is completely unknown will be in their own subgroups, so // any one of them will do, hence returning the same value for all of them return 0; - } else { return image.getWidth() * image.getWidth() / widthOverHeight; } - } else if (image.getWidth() == WIDTH_UNKNOWN) { return image.getHeight() * image.getHeight() * widthOverHeight; - } else { return image.getHeight() * image.getWidth(); } } + /** + * Chooses an image amongst the provided list based on the user preference previously set with + * {@link #setPreferredImageQuality(PreferredImageQuality)}. {@code null} will be returned in + * case the list is empty or the user preference is to not show images. + *
+ * These properties will be preferred, from most to least important: + *
    + *
  1. The image's {@link Image#getEstimatedResolutionLevel()} is not unknown and is close + * to {@link #preferredImageQuality}
  2. + *
  3. At least one of the image's width or height are known
  4. + *
  5. The highest resolution image is finally chosen if the user's preference is {@link + * PreferredImageQuality#HIGH}, otherwise the chosen image is the one that has the closest + * height to {@link #BEST_LOW_H} or {@link #BEST_MEDIUM_H}
  6. + *
+ * + * @param images the images from which to choose + * @return the chosen preferred image, or {@link null} if the list is empty or the user disabled + * images + */ @Nullable public static String choosePreferredImage(@NonNull final List images) { if (preferredImageQuality == PreferredImageQuality.NONE) { diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java index ccf7c3737..fb0c97fe1 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java @@ -9,6 +9,7 @@ import android.content.Context; import android.graphics.Bitmap; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.BitmapCompat; @@ -49,7 +50,7 @@ public final class PicassoHelper { picassoCache = new LruCache(10 * 1024 * 1024); picassoDownloaderClient = new OkHttpClient.Builder() .cache(new okhttp3.Cache(new File(context.getExternalCacheDir(), "picasso"), - 50 * 1024 * 1024)) + 50L * 1024L * 1024L)) // this should already be the default timeout in OkHttp3, but just to be sure... .callTimeout(15, TimeUnit.SECONDS) .build(); @@ -90,50 +91,50 @@ public final class PicassoHelper { } - public static RequestCreator loadAvatar(final List images) { + public static RequestCreator loadAvatar(@NonNull final List images) { return loadImageDefault(images, R.drawable.placeholder_person); } - public static RequestCreator loadAvatar(final String url) { + public static RequestCreator loadAvatar(@Nullable final String url) { return loadImageDefault(url, R.drawable.placeholder_person); } - public static RequestCreator loadThumbnail(final List images) { + public static RequestCreator loadThumbnail(@NonNull final List images) { return loadImageDefault(images, R.drawable.placeholder_thumbnail_video); } - public static RequestCreator loadThumbnail(final String url) { + public static RequestCreator loadThumbnail(@Nullable final String url) { return loadImageDefault(url, R.drawable.placeholder_thumbnail_video); } - public static RequestCreator loadDetailsThumbnail(final List images) { + public static RequestCreator loadDetailsThumbnail(@NonNull final List images) { return loadImageDefault(choosePreferredImage(images), R.drawable.placeholder_thumbnail_video, false); } - public static RequestCreator loadBanner(final List images) { + public static RequestCreator loadBanner(@NonNull final List images) { return loadImageDefault(images, R.drawable.placeholder_channel_banner); } - public static RequestCreator loadPlaylistThumbnail(final List images) { + public static RequestCreator loadPlaylistThumbnail(@NonNull final List images) { return loadImageDefault(images, R.drawable.placeholder_thumbnail_playlist); } - public static RequestCreator loadPlaylistThumbnail(final String url) { + public static RequestCreator loadPlaylistThumbnail(@Nullable final String url) { return loadImageDefault(url, R.drawable.placeholder_thumbnail_playlist); } - public static RequestCreator loadSeekbarThumbnailPreview(final String url) { + public static RequestCreator loadSeekbarThumbnailPreview(@Nullable final String url) { return picassoInstance.load(url); } - public static RequestCreator loadNotificationIcon(final String url) { + public static RequestCreator loadNotificationIcon(@Nullable final String url) { return loadImageDefault(url, R.drawable.ic_newpipe_triangle_white); } public static RequestCreator loadScaledDownThumbnail(final Context context, - final List images) { + @NonNull final List images) { // scale down the notification thumbnail for performance return PicassoHelper.loadThumbnail(images) .transform(new Transformation() { @@ -182,18 +183,18 @@ public final class PicassoHelper { } @Nullable - public static Bitmap getImageFromCacheIfPresent(final String imageUrl) { + public static Bitmap getImageFromCacheIfPresent(@NonNull final String imageUrl) { // URLs in the internal cache finish with \n so we need to add \n to image URLs return picassoCache.get(imageUrl + "\n"); } - private static RequestCreator loadImageDefault(final List images, + private static RequestCreator loadImageDefault(@NonNull final List images, final int placeholderResId) { return loadImageDefault(choosePreferredImage(images), placeholderResId); } - private static RequestCreator loadImageDefault(final String url, + private static RequestCreator loadImageDefault(@Nullable final String url, final int placeholderResId) { return loadImageDefault(url, placeholderResId, true); }