From af2375948de932dde1ac3e186ab40c60f86d531f Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 1 May 2023 23:11:48 +0200 Subject: [PATCH 01/13] Support obtaining multiple images from the extractor --- app/build.gradle | 2 +- .../org/schabi/newpipe/QueueItemMenuUtil.java | 2 +- .../database/playlist/PlaylistStreamEntry.kt | 3 +- .../playlist/model/PlaylistRemoteEntity.java | 7 +- .../database/stream/StreamStatisticsEntry.kt | 3 +- .../database/stream/model/StreamEntity.kt | 10 ++- .../subscription/SubscriptionEntity.java | 7 +- .../fragments/detail/DescriptionFragment.java | 3 +- .../fragments/detail/VideoDetailFragment.java | 25 +++--- .../list/channel/ChannelAboutFragment.java | 5 +- .../list/channel/ChannelFragment.java | 13 ++- .../list/playlist/PlaylistFragment.java | 5 +- .../dialog/StreamDialogDefaultEntry.java | 2 +- .../holder/ChannelMiniInfoItemHolder.java | 2 +- .../holder/CommentsMiniInfoItemHolder.java | 2 +- .../holder/PlaylistMiniInfoItemHolder.java | 2 +- .../holder/StreamMiniInfoItemHolder.java | 2 +- .../subscription/SubscriptionFragment.kt | 3 +- .../local/subscription/SubscriptionManager.kt | 10 ++- .../local/subscription/item/ChannelItem.kt | 2 +- .../org/schabi/newpipe/player/Player.java | 13 +-- .../player/mediaitem/ExceptionTag.java | 3 +- .../player/mediaitem/StreamInfoTag.java | 3 +- .../mediasession/PlayQueueNavigator.java | 4 +- .../player/playqueue/PlayQueueItem.java | 16 ++-- .../playqueue/PlayQueueItemBuilder.java | 2 +- .../newpipe/player/ui/MainPlayerUi.java | 2 +- .../newpipe/player/ui/VideoPlayerUi.java | 2 +- .../schabi/newpipe/util/PicassoHelper.java | 87 ++++++++++++++++--- .../external_communication/ShareUtils.java | 25 ++++++ 30 files changed, 190 insertions(+), 77 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 831b758b9..aa7ac8720 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:95a3cc0a173bba28c179f9f9503b1010ec6bff21' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:3be76a6406d59f1fd8eedf5fab6552e6c2a3da76' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java index 3255489b0..e6177f6a3 100644 --- a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java +++ b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java @@ -75,7 +75,7 @@ public final class QueueItemMenuUtil { return true; case R.id.menu_item_share: shareText(context, item.getTitle(), item.getUrl(), - item.getThumbnailUrl()); + item.getThumbnails()); return true; case R.id.menu_item_download: fetchStreamInfoAndSaveToDatabase(context, item.getServiceId(), item.getUrl(), diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt index d2543ae6d..3b6bc9593 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt @@ -7,6 +7,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity import org.schabi.newpipe.extractor.stream.StreamInfoItem +import org.schabi.newpipe.util.PicassoHelper data class PlaylistStreamEntry( @Embedded @@ -28,7 +29,7 @@ data class PlaylistStreamEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnailUrl = streamEntity.thumbnailUrl + item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) return item } 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 2e9a15d7d..640b6d1fa 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 @@ -11,6 +11,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.PicassoHelper; import static org.schabi.newpipe.database.LocalItem.LocalItemType.PLAYLIST_REMOTE_ITEM; import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME; @@ -69,8 +70,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { @Ignore public PlaylistRemoteEntity(final PlaylistInfo info) { this(info.getServiceId(), info.getName(), info.getUrl(), - info.getThumbnailUrl() == null - ? info.getUploaderAvatarUrl() : info.getThumbnailUrl(), + PicassoHelper.choosePreferredImage(info.getThumbnails()), info.getUploaderName(), info.getStreamCount()); } @@ -84,7 +84,8 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { && getStreamCount() == info.getStreamCount() && TextUtils.equals(getName(), info.getName()) && TextUtils.equals(getUrl(), info.getUrl()) - && TextUtils.equals(getThumbnailUrl(), info.getThumbnailUrl()) + && TextUtils.equals(getThumbnailUrl(), + PicassoHelper.choosePreferredImage(info.getThumbnails())) && TextUtils.equals(getUploader(), info.getUploaderName()); } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt index dc0db59d8..a268f8bbf 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt @@ -7,6 +7,7 @@ import org.schabi.newpipe.database.history.model.StreamHistoryEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS import org.schabi.newpipe.extractor.stream.StreamInfoItem +import org.schabi.newpipe.util.PicassoHelper import java.time.OffsetDateTime class StreamStatisticsEntry( @@ -30,7 +31,7 @@ class StreamStatisticsEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnailUrl = streamEntity.thumbnailUrl + item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) return item } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt index c56f91949..8b7639bbd 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt @@ -13,6 +13,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.player.playqueue.PlayQueueItem +import org.schabi.newpipe.util.PicassoHelper import java.io.Serializable import java.time.OffsetDateTime @@ -67,7 +68,7 @@ data class StreamEntity( constructor(item: StreamInfoItem) : this( serviceId = item.serviceId, url = item.url, title = item.name, streamType = item.streamType, duration = item.duration, uploader = item.uploaderName, - uploaderUrl = item.uploaderUrl, thumbnailUrl = item.thumbnailUrl, viewCount = item.viewCount, + uploaderUrl = item.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(), isUploadDateApproximation = item.uploadDate?.isApproximation ) @@ -76,7 +77,7 @@ data class StreamEntity( constructor(info: StreamInfo) : this( serviceId = info.serviceId, url = info.url, title = info.name, streamType = info.streamType, duration = info.duration, uploader = info.uploaderName, - uploaderUrl = info.uploaderUrl, thumbnailUrl = info.thumbnailUrl, viewCount = info.viewCount, + uploaderUrl = info.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(), isUploadDateApproximation = info.uploadDate?.isApproximation ) @@ -85,7 +86,8 @@ data class StreamEntity( constructor(item: PlayQueueItem) : this( serviceId = item.serviceId, url = item.url, title = item.title, streamType = item.streamType, duration = item.duration, uploader = item.uploader, - uploaderUrl = item.uploaderUrl, thumbnailUrl = item.thumbnailUrl + uploaderUrl = item.uploaderUrl, + thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails) ) fun toStreamInfoItem(): StreamInfoItem { @@ -93,7 +95,7 @@ data class StreamEntity( item.duration = duration item.uploaderName = uploader item.uploaderUrl = uploaderUrl - item.thumbnailUrl = thumbnailUrl + item.thumbnails = PicassoHelper.urlToImageList(thumbnailUrl) if (viewCount != null) item.viewCount = viewCount as Long item.textualUploadDate = textualUploadDate diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java index 0e4bda490..a455cf258 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java @@ -10,6 +10,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.PicassoHelper; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_SERVICE_ID; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE; @@ -57,8 +58,8 @@ public class SubscriptionEntity { final SubscriptionEntity result = new SubscriptionEntity(); result.setServiceId(info.getServiceId()); result.setUrl(info.getUrl()); - result.setData(info.getName(), info.getAvatarUrl(), info.getDescription(), - info.getSubscriberCount()); + result.setData(info.getName(), PicassoHelper.choosePreferredImage(info.getAvatars()), + info.getDescription(), info.getSubscriberCount()); return result; } @@ -138,7 +139,7 @@ public class SubscriptionEntity { @Ignore public ChannelInfoItem toChannelInfoItem() { final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName()); - item.setThumbnailUrl(getAvatarUrl()); + item.setThumbnails(PicassoHelper.urlToImageList(getAvatarUrl())); item.setSubscriberCount(getSubscriberCount()); item.setDescription(getDescription()); return item; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index 92219883b..e7f257665 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -17,6 +17,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.Localization; import java.util.List; +import org.schabi.newpipe.util.PicassoHelper; import icepick.State; @@ -113,7 +114,7 @@ public class DescriptionFragment extends BaseDescriptionFragment { addMetadataItem(inflater, layout, true, R.string.metadata_host, streamInfo.getHost()); addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url, - streamInfo.getThumbnailUrl()); + PicassoHelper.choosePreferredImage(streamInfo.getThumbnails())); } private void addPrivacyMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 686e102f1..2e6f493a3 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -71,6 +71,7 @@ import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.ReCaptchaActivity; import org.schabi.newpipe.error.UserAction; +import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; @@ -483,7 +484,7 @@ public final class VideoDetailFragment }); binding.detailControlsShare.setOnClickListener(makeOnClickListener(info -> ShareUtils.shareText(requireContext(), info.getName(), info.getUrl(), - info.getThumbnailUrl()))); + info.getThumbnails()))); binding.detailControlsOpenInBrowser.setOnClickListener(makeOnClickListener(info -> ShareUtils.openUrlInBrowser(requireContext(), info.getUrl()))); binding.detailControlsPlayWithKodi.setOnClickListener(makeOnClickListener(info -> @@ -723,7 +724,7 @@ public final class VideoDetailFragment final boolean isPlayerStopped = !isPlayerAvailable() || player.isStopped(); if (playQueueItem != null && isPlayerStopped) { updateOverlayData(playQueueItem.getTitle(), - playQueueItem.getUploader(), playQueueItem.getThumbnailUrl()); + playQueueItem.getUploader(), playQueueItem.getThumbnails()); } } @@ -1536,13 +1537,13 @@ public final class VideoDetailFragment binding.detailSecondaryControlPanel.setVisibility(View.GONE); checkUpdateProgressInfo(info); - PicassoHelper.loadDetailsThumbnail(info.getThumbnailUrl()).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadDetailsThumbnail(info.getThumbnails()).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.detailThumbnailImageView); showMetaInfoInTextView(info.getMetaInfo(), binding.detailMetaInfoTextView, binding.detailMetaInfoSeparator, disposables); if (!isPlayerAvailable() || player.isStopped()) { - updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnailUrl()); + updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnails()); } if (!info.getErrors().isEmpty()) { @@ -1587,7 +1588,7 @@ public final class VideoDetailFragment binding.detailUploaderTextView.setVisibility(View.GONE); } - PicassoHelper.loadAvatar(info.getUploaderAvatarUrl()).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.detailSubChannelThumbnailView); binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE); binding.detailUploaderThumbnailView.setVisibility(View.GONE); @@ -1619,10 +1620,10 @@ public final class VideoDetailFragment binding.detailUploaderTextView.setVisibility(View.GONE); } - PicassoHelper.loadAvatar(info.getSubChannelAvatarUrl()).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadAvatar(info.getSubChannelAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.detailSubChannelThumbnailView); binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE); - PicassoHelper.loadAvatar(info.getUploaderAvatarUrl()).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.detailUploaderThumbnailView); binding.detailUploaderThumbnailView.setVisibility(View.VISIBLE); } @@ -1797,7 +1798,7 @@ public final class VideoDetailFragment return; } - updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnailUrl()); + updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnails()); if (currentInfo != null && info.getUrl().equals(currentInfo.getUrl())) { return; } @@ -1826,7 +1827,7 @@ public final class VideoDetailFragment if (currentInfo != null) { updateOverlayData(currentInfo.getName(), currentInfo.getUploaderName(), - currentInfo.getThumbnailUrl()); + currentInfo.getThumbnails()); } updateOverlayPlayQueueButtonVisibility(); } @@ -2191,7 +2192,7 @@ public final class VideoDetailFragment playerHolder.stopService(); setInitialData(0, null, "", null); currentInfo = null; - updateOverlayData(null, null, null); + updateOverlayData(null, null, List.of()); } /*////////////////////////////////////////////////////////////////////////// @@ -2373,11 +2374,11 @@ public final class VideoDetailFragment private void updateOverlayData(@Nullable final String overlayTitle, @Nullable final String uploader, - @Nullable final String thumbnailUrl) { + @NonNull final List thumbnails) { binding.overlayTitleTextView.setText(isEmpty(overlayTitle) ? "" : overlayTitle); binding.overlayChannelTextView.setText(isEmpty(uploader) ? "" : uploader); binding.overlayThumbnail.setImageDrawable(null); - PicassoHelper.loadDetailsThumbnail(thumbnailUrl).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadDetailsThumbnail(thumbnails).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.overlayThumbnail); } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index 543fd80f3..eebd12d20 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -17,6 +17,7 @@ import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; +import org.schabi.newpipe.util.PicassoHelper; import java.util.List; @@ -100,8 +101,8 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { } addMetadataItem(inflater, layout, true, R.string.metadata_avatar_url, - channelInfo.getAvatarUrl()); + PicassoHelper.choosePreferredImage(channelInfo.getAvatars())); addMetadataItem(inflater, layout, true, R.string.metadata_banner_url, - channelInfo.getBannerUrl()); + PicassoHelper.choosePreferredImage(channelInfo.getBanners())); } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index c1345180b..6b2c71337 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -1,6 +1,5 @@ package org.schabi.newpipe.fragments.list.channel; -import static org.schabi.newpipe.extractor.utils.Utils.isBlank; import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor; import static org.schabi.newpipe.ktx.ViewUtils.animate; import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor; @@ -234,7 +233,7 @@ public class ChannelFragment extends BaseStateFragment case R.id.menu_item_share: if (currentInfo != null) { ShareUtils.shareText(requireContext(), name, currentInfo.getOriginalUrl(), - currentInfo.getAvatarUrl()); + currentInfo.getAvatars()); } break; default: @@ -355,7 +354,7 @@ public class ChannelFragment extends BaseStateFragment channel.setServiceId(info.getServiceId()); channel.setUrl(info.getUrl()); channel.setData(info.getName(), - info.getAvatarUrl(), + PicassoHelper.choosePreferredImage(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); channelSubscription = null; @@ -579,17 +578,17 @@ public class ChannelFragment extends BaseStateFragment currentInfo = result; setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); - if (PicassoHelper.getShouldLoadImages() && !isBlank(result.getBannerUrl())) { - PicassoHelper.loadBanner(result.getBannerUrl()).tag(PICASSO_CHANNEL_TAG) + if (PicassoHelper.getShouldLoadImages() && !result.getBanners().isEmpty()) { + PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG) .into(binding.channelBannerImage); } else { // do not waste space for the banner, if the user disabled images or there is not one binding.channelBannerImage.setImageDrawable(null); } - PicassoHelper.loadAvatar(result.getAvatarUrl()).tag(PICASSO_CHANNEL_TAG) + PicassoHelper.loadAvatar(result.getAvatars()).tag(PICASSO_CHANNEL_TAG) .into(binding.channelAvatarView); - PicassoHelper.loadAvatar(result.getParentChannelAvatarUrl()).tag(PICASSO_CHANNEL_TAG) + PicassoHelper.loadAvatar(result.getParentChannelAvatars()).tag(PICASSO_CHANNEL_TAG) .into(binding.subChannelAvatarView); binding.channelTitleView.setText(result.getName()); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 2b7cf9446..9b3f693e1 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -234,7 +234,7 @@ public class PlaylistFragment extends BaseListInfoFragment ShareUtils.shareText(fragment.requireContext(), item.getName(), item.getUrl(), - item.getThumbnailUrl())), + item.getThumbnails())), /** * Opens a {@link DownloadDialog} after fetching some stream info. diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java index 3b375d6eb..d971a6a6d 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java @@ -56,7 +56,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder { itemAdditionalDetailView.setText(getDetailLine(item)); } - PicassoHelper.loadAvatar(item.getThumbnailUrl()).into(itemThumbnailView); + PicassoHelper.loadAvatar(item.getThumbnails()).into(itemThumbnailView); itemView.setOnClickListener(view -> { if (itemBuilder.getOnChannelSelectedListener() != null) { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index 1c8db26d6..d69be077d 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -97,7 +97,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { } final CommentsInfoItem item = (CommentsInfoItem) infoItem; - PicassoHelper.loadAvatar(item.getUploaderAvatarUrl()).into(itemThumbnailView); + PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView); if (PicassoHelper.getShouldLoadImages()) { itemThumbnailView.setVisibility(View.VISIBLE); itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding, diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java index bf5f57db3..62c7c27eb 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java @@ -46,7 +46,7 @@ public class PlaylistMiniInfoItemHolder extends InfoItemHolder { .localizeStreamCountMini(itemStreamCountView.getContext(), item.getStreamCount())); itemUploaderView.setText(item.getUploaderName()); - PicassoHelper.loadPlaylistThumbnail(item.getThumbnailUrl()).into(itemThumbnailView); + PicassoHelper.loadPlaylistThumbnail(item.getThumbnails()).into(itemThumbnailView); itemView.setOnClickListener(view -> { if (itemBuilder.getOnPlaylistSelectedListener() != null) { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java index 6dd06e47f..796ea63b3 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java @@ -87,7 +87,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder { } // Default thumbnail is shown on error, while loading and if the url is empty - PicassoHelper.loadThumbnail(item.getThumbnailUrl()).into(itemThumbnailView); + PicassoHelper.loadThumbnail(item.getThumbnails()).into(itemThumbnailView); itemView.setOnClickListener(view -> { if (itemBuilder.getOnStreamSelectedListener() != null) { diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index dda4326e9..f428a7c1d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -58,6 +58,7 @@ import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard import org.schabi.newpipe.streams.io.StoredFileHelper import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.util.OnClickGesture +import org.schabi.newpipe.util.PicassoHelper import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels import org.schabi.newpipe.util.external_communication.ShareUtils @@ -342,7 +343,7 @@ class SubscriptionFragment : BaseStateFragment() { when (i) { 0 -> ShareUtils.shareText( requireContext(), selectedItem.name, selectedItem.url, - selectedItem.thumbnailUrl + PicassoHelper.choosePreferredImage(selectedItem.thumbnails) ) 1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url) 2 -> deleteChannel(selectedItem) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index 3c11ce152..a74ff305c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -19,6 +19,7 @@ import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.util.ExtractorHelper +import org.schabi.newpipe.util.PicassoHelper class SubscriptionManager(context: Context) { private val database = NewPipeDatabase.getInstance(context) @@ -71,7 +72,12 @@ class SubscriptionManager(context: Context) { subscriptionTable.getSubscription(info.serviceId, info.url) .flatMapCompletable { Completable.fromRunnable { - it.setData(info.name, info.avatarUrl, info.description, info.subscriberCount) + it.setData( + info.name, + PicassoHelper.choosePreferredImage(info.avatars), + info.description, + info.subscriberCount + ) subscriptionTable.update(it) } } @@ -99,7 +105,7 @@ class SubscriptionManager(context: Context) { } else if (info is ChannelInfo) { subscriptionEntity.setData( info.name, - info.avatarUrl, + PicassoHelper.choosePreferredImage(info.avatars), info.description, info.subscriberCount ) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt index bee2e910a..07a4f11ff 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt @@ -39,7 +39,7 @@ class ChannelItem( itemChannelDescriptionView.text = infoItem.description } - PicassoHelper.loadAvatar(infoItem.thumbnailUrl).into(itemThumbnailView) + PicassoHelper.loadAvatar(infoItem.thumbnails).into(itemThumbnailView) gesturesListener?.run { viewHolder.root.setOnClickListener { selected(infoItem) } diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 1a323176c..3ad03891e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -87,6 +87,7 @@ import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.stream.AudioStream; +import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; @@ -805,10 +806,10 @@ public final class Player implements PlaybackListener, Listener { }; } - private void loadCurrentThumbnail(final String url) { + private void loadCurrentThumbnail(final List thumbnails) { if (DEBUG) { - Log.d(TAG, "Thumbnail - loadCurrentThumbnail() called with url = [" - + (url == null ? "null" : url) + "]"); + Log.d(TAG, "Thumbnail - loadCurrentThumbnail() called with thumbnails = [" + + thumbnails.size() + "]"); } // first cancel any previous loading @@ -817,12 +818,12 @@ public final class Player implements PlaybackListener, Listener { // Unset currentThumbnail, since it is now outdated. This ensures it is not used in media // session metadata while the new thumbnail is being loaded by Picasso. onThumbnailLoaded(null); - if (isNullOrEmpty(url)) { + if (thumbnails.isEmpty()) { return; } // scale down the notification thumbnail for performance - PicassoHelper.loadScaledDownThumbnail(context, url) + PicassoHelper.loadScaledDownThumbnail(context, thumbnails) .tag(PICASSO_PLAYER_THUMBNAIL_TAG) .into(currentThumbnailTarget); } @@ -1792,7 +1793,7 @@ public final class Player implements PlaybackListener, Listener { maybeAutoQueueNextStream(info); - loadCurrentThumbnail(info.getThumbnailUrl()); + loadCurrentThumbnail(info.getThumbnails()); registerStreamViewed(); notifyMetadataUpdateToListeners(); diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java index ebedf8c71..5a5360b34 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java @@ -3,6 +3,7 @@ package org.schabi.newpipe.player.mediaitem; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.player.playqueue.PlayQueueItem; +import org.schabi.newpipe.util.PicassoHelper; import java.util.List; import java.util.Optional; @@ -74,7 +75,7 @@ public final class ExceptionTag implements MediaItemTag { @Override public String getThumbnailUrl() { - return item.getThumbnailUrl(); + return PicassoHelper.choosePreferredImage(item.getThumbnails()); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java index 689f5c72b..eb3abec1f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java @@ -6,6 +6,7 @@ import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; +import org.schabi.newpipe.util.PicassoHelper; import java.util.Collections; import java.util.List; @@ -95,7 +96,7 @@ public final class StreamInfoTag implements MediaItemTag { @Override public String getThumbnailUrl() { - return streamInfo.getThumbnailUrl(); + return PicassoHelper.choosePreferredImage(streamInfo.getThumbnails()); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java index 2e54b1129..327c2befe 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java @@ -20,6 +20,7 @@ import com.google.android.exoplayer2.util.Util; import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueueItem; +import org.schabi.newpipe.util.PicassoHelper; import java.util.ArrayList; import java.util.Collections; @@ -137,7 +138,8 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator .putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, player.getPlayQueue().size()); descBuilder.setExtras(additionalMetadata); - final Uri thumbnailUri = Uri.parse(item.getThumbnailUrl()); + final Uri thumbnailUri = Uri.parse( + PicassoHelper.choosePreferredImage(item.getThumbnails())); if (thumbnailUri != null) { descBuilder.setIconUri(thumbnailUri); } diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java index bf31ea9b1..759c51267 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java @@ -3,12 +3,14 @@ package org.schabi.newpipe.player.playqueue; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.util.ExtractorHelper; import java.io.Serializable; +import java.util.List; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.schedulers.Schedulers; @@ -24,7 +26,7 @@ public class PlayQueueItem implements Serializable { private final int serviceId; private final long duration; @NonNull - private final String thumbnailUrl; + private final List thumbnails; @NonNull private final String uploader; private final String uploaderUrl; @@ -38,7 +40,7 @@ public class PlayQueueItem implements Serializable { PlayQueueItem(@NonNull final StreamInfo info) { this(info.getName(), info.getUrl(), info.getServiceId(), info.getDuration(), - info.getThumbnailUrl(), info.getUploaderName(), + info.getThumbnails(), info.getUploaderName(), info.getUploaderUrl(), info.getStreamType()); if (info.getStartPosition() > 0) { @@ -48,20 +50,20 @@ public class PlayQueueItem implements Serializable { PlayQueueItem(@NonNull final StreamInfoItem item) { this(item.getName(), item.getUrl(), item.getServiceId(), item.getDuration(), - item.getThumbnailUrl(), item.getUploaderName(), + item.getThumbnails(), item.getUploaderName(), item.getUploaderUrl(), item.getStreamType()); } @SuppressWarnings("ParameterNumber") private PlayQueueItem(@Nullable final String name, @Nullable final String url, final int serviceId, final long duration, - @Nullable final String thumbnailUrl, @Nullable final String uploader, + final List thumbnails, @Nullable final String uploader, final String uploaderUrl, @NonNull final StreamType streamType) { this.title = name != null ? name : EMPTY_STRING; this.url = url != null ? url : EMPTY_STRING; this.serviceId = serviceId; this.duration = duration; - this.thumbnailUrl = thumbnailUrl != null ? thumbnailUrl : EMPTY_STRING; + this.thumbnails = thumbnails; this.uploader = uploader != null ? uploader : EMPTY_STRING; this.uploaderUrl = uploaderUrl; this.streamType = streamType; @@ -88,8 +90,8 @@ public class PlayQueueItem implements Serializable { } @NonNull - public String getThumbnailUrl() { - return thumbnailUrl; + public List getThumbnails() { + return thumbnails; } @NonNull diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java index e7aeb9638..19101a31d 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java @@ -33,7 +33,7 @@ public class PlayQueueItemBuilder { holder.itemDurationView.setVisibility(View.GONE); } - PicassoHelper.loadThumbnail(item.getThumbnailUrl()).into(holder.itemThumbnailView); + PicassoHelper.loadThumbnail(item.getThumbnails()).into(holder.itemThumbnailView); holder.itemRoot.setOnClickListener(view -> { if (onItemClickListener != null) { diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java index 92e38a6a2..03f90a344 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java @@ -740,7 +740,7 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh String videoUrl = player.getVideoUrl(); videoUrl += ("&t=" + seconds); ShareUtils.shareText(context, currentItem.getTitle(), - videoUrl, currentItem.getThumbnailUrl()); + videoUrl, currentItem.getThumbnails()); } } }; diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java index 119c43b95..b51aaa638 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java @@ -226,7 +226,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa final PlayQueueItem currentItem = player.getCurrentItem(); if (currentItem != null) { ShareUtils.shareText(context, currentItem.getTitle(), - player.getVideoUrlAtCurrentTime(), currentItem.getThumbnailUrl()); + player.getVideoUrlAtCurrentTime(), currentItem.getThumbnails()); } })); binding.share.setOnLongClickListener(v -> { diff --git a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java index ece0c7e87..5f3876d78 100644 --- a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java @@ -1,13 +1,14 @@ package org.schabi.newpipe.util; import static org.schabi.newpipe.MainActivity.DEBUG; -import static org.schabi.newpipe.extractor.utils.Utils.isBlank; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import android.annotation.SuppressLint; 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; @@ -19,9 +20,13 @@ import com.squareup.picasso.RequestCreator; import com.squareup.picasso.Transformation; import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.Image; +import org.schabi.newpipe.extractor.Image.ResolutionLevel; import java.io.File; import java.io.IOException; +import java.util.Comparator; +import java.util.List; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; @@ -42,6 +47,7 @@ public final class PicassoHelper { private static Picasso picassoInstance; private static boolean shouldLoadImages; + private static ResolutionLevel preferredResolutionLevel = ResolutionLevel.HIGH; public static void init(final Context context) { picassoCache = new LruCache(10 * 1024 * 1024); @@ -96,20 +102,33 @@ public final class PicassoHelper { } + public static RequestCreator loadAvatar(final List images) { + return loadImageDefault(images, R.drawable.placeholder_person); + } + public static RequestCreator loadAvatar(final String url) { return loadImageDefault(url, R.drawable.placeholder_person); } + public static RequestCreator loadThumbnail(final List images) { + return loadImageDefault(images, R.drawable.placeholder_thumbnail_video); + } + public static RequestCreator loadThumbnail(final String url) { return loadImageDefault(url, R.drawable.placeholder_thumbnail_video); } - public static RequestCreator loadDetailsThumbnail(final String url) { - return loadImageDefault(url, R.drawable.placeholder_thumbnail_video, false); + public static RequestCreator loadDetailsThumbnail(final List images) { + return loadImageDefault(choosePreferredImage(images), + R.drawable.placeholder_thumbnail_video, false); } - public static RequestCreator loadBanner(final String url) { - return loadImageDefault(url, R.drawable.placeholder_channel_banner); + public static RequestCreator loadBanner(final List images) { + return loadImageDefault(images, R.drawable.placeholder_channel_banner); + } + + public static RequestCreator loadPlaylistThumbnail(final List images) { + return loadImageDefault(images, R.drawable.placeholder_thumbnail_playlist); } public static RequestCreator loadPlaylistThumbnail(final String url) { @@ -125,9 +144,10 @@ public final class PicassoHelper { } - public static RequestCreator loadScaledDownThumbnail(final Context context, final String url) { + public static RequestCreator loadScaledDownThumbnail(final Context context, + final List images) { // scale down the notification thumbnail for performance - return PicassoHelper.loadThumbnail(url) + return PicassoHelper.loadThumbnail(images) .transform(new Transformation() { @Override public Bitmap transform(final Bitmap source) { @@ -180,13 +200,20 @@ public final class PicassoHelper { } - private static RequestCreator loadImageDefault(final String url, final int placeholderResId) { + private static RequestCreator loadImageDefault(final List images, + final int placeholderResId) { + return loadImageDefault(choosePreferredImage(images), placeholderResId); + } + + private static RequestCreator loadImageDefault(final String url, + final int placeholderResId) { return loadImageDefault(url, placeholderResId, true); } - private static RequestCreator loadImageDefault(final String url, final int placeholderResId, + private static RequestCreator loadImageDefault(@Nullable final String url, + final int placeholderResId, final boolean showPlaceholderWhileLoading) { - if (!shouldLoadImages || isBlank(url)) { + if (isNullOrEmpty(url)) { return picassoInstance .load((String) null) .placeholder(placeholderResId) // show placeholder when no image should load @@ -201,4 +228,44 @@ public final class PicassoHelper { return requestCreator; } } + + @Nullable + public static String choosePreferredImage(final List images) { + if (!shouldLoadImages) { + return null; + } + + final Comparator comparator; + switch (preferredResolutionLevel) { + case HIGH: + comparator = Comparator.comparingInt(Image::getHeight).reversed(); + break; + default: + case UNKNOWN: + case MEDIUM: + comparator = Comparator.comparingInt(image -> Math.abs(image.getHeight() - 450)); + break; + case LOW: + comparator = Comparator.comparingInt(Image::getHeight); + break; + } + + return images.stream() + .filter(image -> image.getEstimatedResolutionLevel() != ResolutionLevel.UNKNOWN) + .min(comparator) + .map(Image::getUrl) + .orElseGet(() -> images.stream() + .findAny() + .map(Image::getUrl) + .orElse(null)); + } + + @NonNull + public static List urlToImageList(@Nullable final String url) { + if (url == null) { + return List.of(); + } else { + return List.of(new Image(url, -1, -1, ResolutionLevel.UNKNOWN)); + } + } } 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 118b77026..f14f22069 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 @@ -23,10 +23,12 @@ import androidx.core.content.FileProvider; import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.util.PicassoHelper; import java.io.File; import java.io.FileOutputStream; +import java.util.List; public final class ShareUtils { private static final String TAG = ShareUtils.class.getSimpleName(); @@ -261,6 +263,29 @@ public final class ShareUtils { openAppChooser(context, shareIntent, false); } + /** + * Open the android share sheet to share a content. + * + *

+ * 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. + *

+ * + * @param context the context to use + * @param title the title of the content + * @param content the content to share + * @param images a set of possible {@link Image}s of the subject, among which to choose with + * {@link PicassoHelper#choosePreferredImage(List)} since that's likely to + * provide an image that is in Picasso's cache + */ + public static void shareText(@NonNull final Context context, + @NonNull final String title, + final String content, + final List images) { + shareText(context, title, content, PicassoHelper.choosePreferredImage(images)); + } + /** * Open the android share sheet to share a content. * From 0a8f28b1c6f804de22a1ee81fdc284e7725ef8cc Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 11:08:32 +0200 Subject: [PATCH 02/13] Add image quality preference --- app/src/main/java/org/schabi/newpipe/App.java | 8 ++++--- .../database/playlist/PlaylistStreamEntry.kt | 2 +- .../playlist/model/PlaylistRemoteEntity.java | 2 +- .../database/stream/StreamStatisticsEntry.kt | 2 +- .../database/stream/model/StreamEntity.kt | 2 +- .../subscription/SubscriptionEntity.java | 2 +- .../fragments/detail/DescriptionFragment.java | 2 +- .../fragments/detail/VideoDetailFragment.java | 2 +- .../list/channel/ChannelAboutFragment.java | 2 +- .../list/channel/ChannelFragment.java | 6 ++--- .../list/playlist/PlaylistFragment.java | 2 +- .../newpipe/info_list/StreamSegmentItem.kt | 2 +- .../holder/ChannelMiniInfoItemHolder.java | 2 +- .../holder/CommentsMiniInfoItemHolder.java | 4 ++-- .../holder/PlaylistMiniInfoItemHolder.java | 2 +- .../holder/StreamMiniInfoItemHolder.java | 2 +- .../newpipe/local/feed/item/StreamItem.kt | 2 +- .../feed/notifications/NotificationHelper.kt | 2 +- .../local/holder/LocalPlaylistItemHolder.java | 2 +- .../holder/LocalPlaylistStreamItemHolder.java | 2 +- .../LocalStatisticStreamItemHolder.java | 2 +- .../holder/RemotePlaylistItemHolder.java | 2 +- .../subscription/SubscriptionFragment.kt | 2 +- .../local/subscription/SubscriptionManager.kt | 2 +- .../local/subscription/item/ChannelItem.kt | 2 +- .../item/PickerSubscriptionItem.kt | 2 +- .../org/schabi/newpipe/player/Player.java | 2 +- .../player/mediaitem/ExceptionTag.java | 2 +- .../player/mediaitem/StreamInfoTag.java | 2 +- .../mediasession/PlayQueueNavigator.java | 2 +- .../playqueue/PlayQueueItemBuilder.java | 2 +- .../SeekbarPreviewThumbnailHolder.java | 2 +- .../settings/ContentSettingsFragment.java | 9 ++++--- .../settings/DebugSettingsFragment.java | 2 +- .../settings/SelectChannelFragment.java | 2 +- .../settings/SelectPlaylistFragment.java | 2 +- .../newpipe/settings/SettingMigrations.java | 17 ++++++++++++- .../external_communication/ShareUtils.java | 4 ++-- .../util/{ => image}/PicassoHelper.java | 22 +++++++---------- .../util/image/PreferredImageQuality.java | 24 +++++++++++++++++++ app/src/main/res/values-ar/strings.xml | 2 -- app/src/main/res/values-as/strings.xml | 2 -- app/src/main/res/values-az/strings.xml | 2 -- app/src/main/res/values-b+ast/strings.xml | 2 -- app/src/main/res/values-b+uz+Latn/strings.xml | 2 -- app/src/main/res/values-be/strings.xml | 2 -- app/src/main/res/values-bg/strings.xml | 2 -- app/src/main/res/values-bn-rBD/strings.xml | 2 -- app/src/main/res/values-bn-rIN/strings.xml | 2 -- app/src/main/res/values-bn/strings.xml | 2 -- app/src/main/res/values-bs/strings.xml | 2 -- app/src/main/res/values-ca/strings.xml | 2 -- app/src/main/res/values-ckb/strings.xml | 2 -- app/src/main/res/values-cs/strings.xml | 2 -- app/src/main/res/values-da/strings.xml | 2 -- app/src/main/res/values-de/strings.xml | 2 -- app/src/main/res/values-el/strings.xml | 2 -- app/src/main/res/values-en-rGB/strings.xml | 1 - app/src/main/res/values-eo/strings.xml | 2 -- app/src/main/res/values-es/strings.xml | 2 -- app/src/main/res/values-et/strings.xml | 2 -- app/src/main/res/values-eu/strings.xml | 2 -- app/src/main/res/values-fa/strings.xml | 2 -- app/src/main/res/values-fi/strings.xml | 2 -- app/src/main/res/values-fil/strings.xml | 2 -- app/src/main/res/values-fr/strings.xml | 2 -- app/src/main/res/values-gl/strings.xml | 2 -- app/src/main/res/values-he/strings.xml | 2 -- app/src/main/res/values-hi/strings.xml | 2 -- app/src/main/res/values-hr/strings.xml | 2 -- app/src/main/res/values-hu/strings.xml | 2 -- app/src/main/res/values-ia/strings.xml | 1 - app/src/main/res/values-in/strings.xml | 2 -- app/src/main/res/values-is/strings.xml | 2 -- app/src/main/res/values-it/strings.xml | 2 -- app/src/main/res/values-ja/strings.xml | 2 -- app/src/main/res/values-jv/strings.xml | 2 -- app/src/main/res/values-ka/strings.xml | 2 -- app/src/main/res/values-kmr/strings.xml | 2 -- app/src/main/res/values-ko/strings.xml | 2 -- app/src/main/res/values-ku/strings.xml | 3 --- app/src/main/res/values-lt/strings.xml | 2 -- app/src/main/res/values-lv/strings.xml | 2 -- app/src/main/res/values-mk/strings.xml | 2 -- app/src/main/res/values-ml/strings.xml | 2 -- app/src/main/res/values-ms/strings.xml | 2 -- app/src/main/res/values-nb-rNO/strings.xml | 2 -- app/src/main/res/values-ne/strings.xml | 2 -- app/src/main/res/values-nl-rBE/strings.xml | 2 -- app/src/main/res/values-nl/strings.xml | 2 -- app/src/main/res/values-oc/strings.xml | 1 - app/src/main/res/values-or/strings.xml | 2 -- app/src/main/res/values-pa-rPK/strings.xml | 1 - app/src/main/res/values-pa/strings.xml | 2 -- app/src/main/res/values-pl/strings.xml | 2 -- app/src/main/res/values-pt-rBR/strings.xml | 2 -- app/src/main/res/values-pt-rPT/strings.xml | 2 -- app/src/main/res/values-pt/strings.xml | 2 -- app/src/main/res/values-ro/strings.xml | 2 -- app/src/main/res/values-ru/strings.xml | 2 -- app/src/main/res/values-sc/strings.xml | 2 -- app/src/main/res/values-sk/strings.xml | 2 -- app/src/main/res/values-sl/strings.xml | 2 -- app/src/main/res/values-so/strings.xml | 2 -- app/src/main/res/values-sq/strings.xml | 2 -- app/src/main/res/values-sr/strings.xml | 2 -- app/src/main/res/values-sv/strings.xml | 2 -- app/src/main/res/values-ta/strings.xml | 2 -- app/src/main/res/values-te/strings.xml | 2 -- app/src/main/res/values-th/strings.xml | 2 -- app/src/main/res/values-tr/strings.xml | 2 -- app/src/main/res/values-uk/strings.xml | 2 -- app/src/main/res/values-und/strings.xml | 1 - app/src/main/res/values-ur/strings.xml | 2 -- app/src/main/res/values-vi/strings.xml | 2 -- app/src/main/res/values-zh-rCN/strings.xml | 2 -- app/src/main/res/values-zh-rHK/strings.xml | 2 -- app/src/main/res/values-zh-rTW/strings.xml | 2 -- app/src/main/res/values/settings_keys.xml | 22 +++++++++++++++-- app/src/main/res/values/strings.xml | 8 +++++-- app/src/main/res/xml/content_settings.xml | 12 ++++++---- 121 files changed, 132 insertions(+), 220 deletions(-) rename app/src/main/java/org/schabi/newpipe/util/{ => image}/PicassoHelper.java (94%) create mode 100644 app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index f4410a31b..b394c7039 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -20,9 +20,10 @@ import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.ktx.ExceptionUtils; import org.schabi.newpipe.settings.NewPipeSettings; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.StateSaver; +import org.schabi.newpipe.util.image.PreferredImageQuality; import java.io.IOException; import java.io.InterruptedIOException; @@ -99,8 +100,9 @@ public class App extends Application { // Initialize image loader final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); PicassoHelper.init(this); - PicassoHelper.setShouldLoadImages( - prefs.getBoolean(getString(R.string.download_thumbnail_key), true)); + PicassoHelper.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this, + prefs.getString(getString(R.string.image_quality_key), + getString(R.string.image_quality_default)))); PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG && prefs.getBoolean(getString(R.string.show_image_indicators_key), false)); diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt index 3b6bc9593..e7db1d603 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity import org.schabi.newpipe.extractor.stream.StreamInfoItem -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper data class PlaylistStreamEntry( @Embedded 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 640b6d1fa..569f6721c 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 @@ -11,7 +11,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.util.Constants; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import static org.schabi.newpipe.database.LocalItem.LocalItemType.PLAYLIST_REMOTE_ITEM; import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME; diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt index a268f8bbf..6d005351d 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.history.model.StreamHistoryEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS import org.schabi.newpipe.extractor.stream.StreamInfoItem -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper import java.time.OffsetDateTime class StreamStatisticsEntry( diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt index 8b7639bbd..bb2c0e0d7 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt @@ -13,7 +13,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.player.playqueue.PlayQueueItem -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper import java.io.Serializable import java.time.OffsetDateTime diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java index a455cf258..1f1722814 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java @@ -10,7 +10,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.util.Constants; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_SERVICE_ID; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index e7f257665..ff1a01466 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.Localization; import java.util.List; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import icepick.State; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 2e6f493a3..0314c2540 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -108,7 +108,7 @@ import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PermissionHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.StreamTypeUtil; import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.external_communication.KoreUtils; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index eebd12d20..5ea25bf15 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 6b2c71337..7436f50fd 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -48,8 +48,8 @@ import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.StateSaver; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; @@ -147,7 +147,7 @@ public class ChannelFragment extends BaseStateFragment setTitle(name); binding.channelTitleView.setText(name); - if (!PicassoHelper.getShouldLoadImages()) { + if (!PicassoHelper.shouldLoadImages()) { // do not waste space for the banner if it is not going to be loaded binding.channelBannerImage.setImageDrawable(null); } @@ -578,7 +578,7 @@ public class ChannelFragment extends BaseStateFragment currentInfo = result; setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); - if (PicassoHelper.getShouldLoadImages() && !result.getBanners().isEmpty()) { + if (PicassoHelper.shouldLoadImages() && !result.getBanners().isEmpty()) { PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG) .into(binding.channelBannerImage); } else { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 9b3f693e1..e82a984d5 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -48,7 +48,7 @@ import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.PlayButtonHelper; diff --git a/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt b/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt index 5fc8aa684..1e52d3168 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt +++ b/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt @@ -8,7 +8,7 @@ import com.xwray.groupie.Item import org.schabi.newpipe.R import org.schabi.newpipe.extractor.stream.StreamSegment import org.schabi.newpipe.util.Localization -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper class StreamSegmentItem( private val item: StreamSegment, diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java index d971a6a6d..7afc05c6c 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java @@ -13,7 +13,7 @@ import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.Localization; public class ChannelMiniInfoItemHolder extends InfoItemHolder { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index d69be077d..69e1bf5f6 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -31,7 +31,7 @@ import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.text.CommentTextOnTouchListener; import org.schabi.newpipe.util.text.TextLinkifier; @@ -98,7 +98,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { final CommentsInfoItem item = (CommentsInfoItem) infoItem; PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView); - if (PicassoHelper.getShouldLoadImages()) { + if (PicassoHelper.shouldLoadImages()) { itemThumbnailView.setVisibility(View.VISIBLE); itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding, commentVerticalPadding, commentVerticalPadding); diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java index 62c7c27eb..c9216d9a9 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java @@ -9,7 +9,7 @@ import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem; import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.Localization; public class PlaylistMiniInfoItemHolder extends InfoItemHolder { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java index 796ea63b3..01f3be6b3 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java @@ -16,7 +16,7 @@ import org.schabi.newpipe.ktx.ViewUtils; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DependentPreferenceHelper; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.StreamTypeUtil; import org.schabi.newpipe.views.AnimatedProgressBar; diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt index d795dcb08..4a071d6df 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt @@ -18,8 +18,8 @@ import org.schabi.newpipe.extractor.stream.StreamType.POST_LIVE_AUDIO_STREAM import org.schabi.newpipe.extractor.stream.StreamType.POST_LIVE_STREAM import org.schabi.newpipe.extractor.stream.StreamType.VIDEO_STREAM import org.schabi.newpipe.util.Localization -import org.schabi.newpipe.util.PicassoHelper import org.schabi.newpipe.util.StreamTypeUtil +import org.schabi.newpipe.util.image.PicassoHelper import java.util.concurrent.TimeUnit import java.util.function.Consumer diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt index 782f5ee47..9f7553e1f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt @@ -22,7 +22,7 @@ import org.schabi.newpipe.R import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.service.FeedUpdateInfo import org.schabi.newpipe.util.NavigationHelper -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper /** * Helper for everything related to show notifications about new streams to the user. diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java index 240ca0462..336f5cfe3 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java @@ -8,7 +8,7 @@ import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.Localization; import java.time.format.DateTimeFormatter; diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java index c98a8b60b..89a714fd7 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java @@ -16,7 +16,7 @@ import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DependentPreferenceHelper; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.views.AnimatedProgressBar; diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java index 41f2df1d0..150a35eb5 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java @@ -16,7 +16,7 @@ import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DependentPreferenceHelper; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.views.AnimatedProgressBar; diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java index 70987a6fc..d14c1a231 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java @@ -8,7 +8,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity; import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import java.time.format.DateTimeFormatter; diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index f428a7c1d..f84d9865f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -58,10 +58,10 @@ import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard import org.schabi.newpipe.streams.io.StoredFileHelper import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.util.OnClickGesture -import org.schabi.newpipe.util.PicassoHelper import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels import org.schabi.newpipe.util.external_communication.ShareUtils +import org.schabi.newpipe.util.image.PicassoHelper import java.text.SimpleDateFormat import java.util.Date import java.util.Locale diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index a74ff305c..70bac6168 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.util.ExtractorHelper -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper class SubscriptionManager(context: Context) { private val database = NewPipeDatabase.getInstance(context) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt index 07a4f11ff..bc39dafe6 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt @@ -9,7 +9,7 @@ import org.schabi.newpipe.R import org.schabi.newpipe.extractor.channel.ChannelInfoItem import org.schabi.newpipe.util.Localization import org.schabi.newpipe.util.OnClickGesture -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper class ChannelItem( private val infoItem: ChannelInfoItem, diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt index aadb2fc73..3a4c6e41b 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt @@ -10,7 +10,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.databinding.PickerSubscriptionItemBinding import org.schabi.newpipe.ktx.AnimationType import org.schabi.newpipe.ktx.animate -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper data class PickerSubscriptionItem( val subscriptionEntity: SubscriptionEntity, diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 3ad03891e..49e72328e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -118,7 +118,7 @@ import org.schabi.newpipe.player.ui.VideoPlayerUi; import org.schabi.newpipe.util.DependentPreferenceHelper; import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.SerializedCache; import org.schabi.newpipe.util.StreamTypeUtil; diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java index 5a5360b34..9ec6513dc 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java @@ -3,7 +3,7 @@ package org.schabi.newpipe.player.mediaitem; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.List; import java.util.Optional; diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java index eb3abec1f..a96f49f2f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java @@ -6,7 +6,7 @@ import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.Collections; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java index 327c2befe..3e0736f82 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java @@ -20,7 +20,7 @@ import com.google.android.exoplayer2.util.Util; import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.ArrayList; import java.util.Collections; diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java index 19101a31d..066f92c26 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java @@ -6,7 +6,7 @@ import android.view.MotionEvent; import android.view.View; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; public class PlayQueueItemBuilder { diff --git a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java index 50ffa2f2a..26065de15 100644 --- a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java @@ -14,7 +14,7 @@ import androidx.collection.SparseArrayCompat; import com.google.common.base.Stopwatch; import org.schabi.newpipe.extractor.stream.Frameset; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.Comparator; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index ee34f01dd..2297e3e93 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -31,8 +31,9 @@ import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; import org.schabi.newpipe.streams.io.StoredFileHelper; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ZipHelper; +import org.schabi.newpipe.util.image.PreferredImageQuality; import java.io.File; import java.io.IOException; @@ -105,9 +106,11 @@ public class ContentSettingsFragment extends BasePreferenceFragment { .getPreferredContentCountry(requireContext()); initialLanguage = defaultPreferences.getString(getString(R.string.app_language_key), "en"); - findPreference(getString(R.string.download_thumbnail_key)).setOnPreferenceChangeListener( + final Preference imageQualityPreference = requirePreference(R.string.image_quality_key); + imageQualityPreference.setOnPreferenceChangeListener( (preference, newValue) -> { - PicassoHelper.setShouldLoadImages((Boolean) newValue); + PicassoHelper.setPreferredImageQuality(PreferredImageQuality + .fromPreferenceKey(requireContext(), (String) newValue)); try { PicassoHelper.clearCache(preference.getContext()); Toast.makeText(preference.getContext(), diff --git a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java index 0f4c9765e..d78ade49d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java @@ -10,7 +10,7 @@ import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.feed.notifications.NotificationWorker; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.Optional; diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java index 0f25be630..37335421d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java @@ -19,7 +19,7 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.database.subscription.SubscriptionEntity; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.local.subscription.SubscriptionManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ThemeHelper; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java index e8491d52c..147d20a36 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java @@ -25,7 +25,7 @@ import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.playlist.LocalPlaylistManager; import org.schabi.newpipe.local.playlist.RemotePlaylistManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.List; import java.util.Vector; diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index 215caaa38..b7bafde75 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -128,6 +128,20 @@ public final class SettingMigrations { } }; + public static final Migration MIGRATION_5_6 = new Migration(5, 6) { + @Override + protected void migrate(@NonNull final Context context) { + final boolean loadImages = sp.getBoolean("download_thumbnail_key", true); + + sp.edit() + .putString(context.getString(R.string.image_quality_key), + context.getString(loadImages + ? R.string.image_quality_default + : R.string.image_quality_none_key)) + .apply(); + } + }; + /** * List of all implemented migrations. *

@@ -140,12 +154,13 @@ public final class SettingMigrations { MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, + MIGRATION_5_6, }; /** * Version number for preferences. Must be incremented every time a migration is necessary. */ - private static final int VERSION = 5; + private static final int VERSION = 6; public static void runMigrationsIfNeeded(@NonNull final Context context, 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 f14f22069..8150d4030 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 @@ -24,7 +24,7 @@ import androidx.core.content.FileProvider; import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.Image; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.io.File; import java.io.FileOutputStream; @@ -251,7 +251,7 @@ public final class ShareUtils { // If loading of images has been disabled, don't try to generate a content preview if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !TextUtils.isEmpty(imagePreviewUrl) - && PicassoHelper.getShouldLoadImages()) { + && PicassoHelper.shouldLoadImages()) { final ClipData clipData = generateClipDataForImagePreview(context, imagePreviewUrl); if (clipData != null) { diff --git a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java similarity index 94% rename from app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java rename to app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java index 5f3876d78..3177e83f4 100644 --- a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.util; +package org.schabi.newpipe.util.image; import static org.schabi.newpipe.MainActivity.DEBUG; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; @@ -46,8 +46,7 @@ public final class PicassoHelper { @SuppressLint("StaticFieldLeak") private static Picasso picassoInstance; - private static boolean shouldLoadImages; - private static ResolutionLevel preferredResolutionLevel = ResolutionLevel.HIGH; + private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; public static void init(final Context context) { picassoCache = new LruCache(10 * 1024 * 1024); @@ -93,12 +92,12 @@ public final class PicassoHelper { picassoInstance.setIndicatorsEnabled(enabled); // useful for debugging } - public static void setShouldLoadImages(final boolean shouldLoadImages) { - PicassoHelper.shouldLoadImages = shouldLoadImages; + public static void setPreferredImageQuality(final PreferredImageQuality preferredImageQuality) { + PicassoHelper.preferredImageQuality = preferredImageQuality; } - public static boolean getShouldLoadImages() { - return shouldLoadImages; + public static boolean shouldLoadImages() { + return preferredImageQuality != PreferredImageQuality.NONE; } @@ -231,17 +230,14 @@ public final class PicassoHelper { @Nullable public static String choosePreferredImage(final List images) { - if (!shouldLoadImages) { - return null; - } - final Comparator comparator; - switch (preferredResolutionLevel) { + switch (preferredImageQuality) { + case NONE: + return null; case HIGH: comparator = Comparator.comparingInt(Image::getHeight).reversed(); break; default: - case UNKNOWN: case MEDIUM: comparator = Comparator.comparingInt(image -> Math.abs(image.getHeight() - 450)); break; diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java b/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java new file mode 100644 index 000000000..9f17082ea --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java @@ -0,0 +1,24 @@ +package org.schabi.newpipe.util.image; + +import android.content.Context; + +import org.schabi.newpipe.R; + +public enum PreferredImageQuality { + NONE, + LOW, + MEDIUM, + HIGH; + + public static PreferredImageQuality fromPreferenceKey(final Context context, final String key) { + if (context.getString(R.string.image_quality_none_key).equals(key)) { + return NONE; + } else if (context.getString(R.string.image_quality_low_key).equals(key)) { + return LOW; + } else if (context.getString(R.string.image_quality_high_key).equals(key)) { + return HIGH; + } else { + return MEDIUM; // default to medium + } + } +} diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index d0cf90db4..0c9f2c74c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -243,7 +243,6 @@ الإشارات المرجعية استعمال التقديم السريع الغير دقيق خاصية التقديم الغير دقيق تسمح للمشغل بالقفز خلال الفديو بشكل أسرع مع دقة قفز أقل. خاصية القفز ل5، 15 او 25 لا تعمل مع القفز الغير دقيق - تحميل الصور المصغرة تم إفراغ مساحة ذاكرة التخزين المؤقتة الخاصة بالصور الملف لا يوجد مثل هذا المجلد @@ -260,7 +259,6 @@ عملية التصدير جارية … إستيراد ملف معرفك, soundcloud.com/هويتك - قم بإيقاف تشغيله لمنع تحميل الصور المصغرة وحفظ البيانات واستخدام الذاكرة. تمسح التغييرات كلاً من ذاكرة التخزين المؤقت للصورة الموجودة في الذاكرة والموجودة على القرص امسح البيانات الوصفيّة المخزّنة مؤقّتًا إزالة جميع بيانات صفحات الويب المخزنة مؤقّتًا تم محو ذاكرة التخزين المؤقتّة للبيانات الوصفيّة diff --git a/app/src/main/res/values-as/strings.xml b/app/src/main/res/values-as/strings.xml index 93e9e363e..fc9d5b2b6 100644 --- a/app/src/main/res/values-as/strings.xml +++ b/app/src/main/res/values-as/strings.xml @@ -62,7 +62,6 @@ লোড ব্যৱধানৰ আকাৰ সলনি কৰক (বৰ্তমানে %s) । এটা কম মানে প্ৰাৰম্ভিক ভিডিঅ\' লোডিং দ্ৰুত কৰিব পাৰে। পৰিৱৰ্তনৰ বাবে এটা খেলুৱৈ পুনৰাৰম্ভৰ প্ৰয়োজন থাম্বনেইলত থকা মূল ৰং অনুসৰি এণ্ড্ৰইডক জাননীৰ ৰং কাষ্টমাইজ কৰিবলৈ কওক (মন কৰিব যে এইটো সকলো ডিভাইচতে উপলব্ধ নহয়) সক্ৰিয় প্লেয়াৰৰ queue সলনি কৰা হ’ব - থাম্বনেইল লোড কৰক মন্তব্য দেখুৱাওক বিৱৰণ দেখুৱাওক মেটা তথ্য দেখুৱাওক @@ -96,6 +95,5 @@ ভিডিঅ\'ৰ বিৱৰণ আৰু অতিৰিক্ত তথ্য লুকুৱাবলৈ বন্ধ কৰক মন্তব্য লুকুৱাবলৈ বন্ধ কৰক \'পৰৱৰ্তী\' আৰু \'সাদৃশ্য থকা\' ভিডিঅ\' দেখুৱাওক - থাম্বনেইলসমূহ লোড কৰা, তথ্য আৰু মেমৰি ব্যৱহাৰ সংৰক্ষণ কৰা ৰোধ কৰিবলে বন্ধ কৰক। পৰিবৰ্তনসমূহে ইন-মেমৰি আৰু অন-ডিস্ক কেশ্ব দুয়োটা পৰিষ্কাৰ কৰে ষ্ট্ৰিমৰ সৃষ্টিকৰ্তা, ষ্ট্ৰিমৰ বিষয়বস্তু বা এটা সন্ধান অনুৰোধৰ বিষয়ে অতিৰিক্ত তথ্যৰ সৈতে মেটা তথ্যৰ বাকচসমূহ লুকুৱাবলৈ বন্ধ কৰক \ No newline at end of file diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index a238758af..06273f9cf 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -136,7 +136,6 @@ \nOnu görmək istəyirsinizsə, tənzimləmələrdə \"%1$s\" seçimini aktivləşdirin. YouTube potensial yetkin məzmunu gizlədən \"Məhdud Rejim\" təmin edir \"PeerTube\" nümunələri - Miniatürləri yüklə Yığcam bildirişdə göstərmək üçün ən çoxu üç fəaliyyət seçə bilərsiniz! Həmişə yenilə Axın @@ -287,7 +286,6 @@ Səs yayımı tapılmadı Digər tətbiqlərin üzərində göstərməyə icazə ver İlkin tənzimləmələri qaytarmaq istəyirsiniz\? - Miniatürləri yükləməyi, məlumata qənaət və yaddaş istifadəsin azaltmaq üçün söndür. Dəyişikliklər həm yaddaşdaxilində, həm də diskdə təsvir keşini təmizləyir Növbətini növbələ Təkrar Cəhd Et Cari oynatma yayımı bildirişini konfiqurasiya et diff --git a/app/src/main/res/values-b+ast/strings.xml b/app/src/main/res/values-b+ast/strings.xml index f9c6109e6..b9a57f1c2 100644 --- a/app/src/main/res/values-b+ast/strings.xml +++ b/app/src/main/res/values-b+ast/strings.xml @@ -206,8 +206,6 @@ \n3. Anicia sesión cuando se te pida \n4. Copia la URL del perfil al que te redirixeron. soundcloud.com/LaToID - Cargar les miniatures - Desactiva esta opción pa eviar la carga de miniatures y aforrar datos y usu de memoria. Los cambeos llimpien la caché d\'imáxenes temporal y permanente. Minimizar al cambiar d\'aplicación Minimizar al reproductor en segundu planu Minimizar al reproductor en ventanu diff --git a/app/src/main/res/values-b+uz+Latn/strings.xml b/app/src/main/res/values-b+uz+Latn/strings.xml index affa805e6..76924b0d4 100644 --- a/app/src/main/res/values-b+uz+Latn/strings.xml +++ b/app/src/main/res/values-b+uz+Latn/strings.xml @@ -24,10 +24,8 @@ Barcha keshlangan veb-sahifa ma\'lumotlarini olib tashlash Keshlangan metadatalarni o\'chirish Rasm keshi o\'chirildi - Eskizlarni yuklash, ma\'lumotlarni tejash va xotiradan foydalanishni oldini olish uchun o\'chirib qo\'ying. O\'zgarishlar xotiradagi va diskdagi rasm keshini tozalaydi. sharhlarni yashirishni o\'chirish Izohlarni ko\'rsatish - Eskizlarni yuklang Aktiv ijro etish navbati almashtiriladi Bir ijro etishdan boshqasiga o\'tish sizning navbatingizni almashtirishi mumkin Navbatni tozalashdan oldin tasdiqlashni so\'rash diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 979553372..e176d2bc9 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -55,8 +55,6 @@ Запамінаць памер і становішча ўсплываючага акна Хуткі пошук пазіцыі Недакладны пошук дазваляе плэеру знаходзіць пазіцыі хутчэй са зніжанай дакладнасцю. Пошук цягам 5, 15 ці 25 секунд пры гэтым немажлівы - Загружаць мініяцюры - Адключыце, каб не загружаць мініяцюры і зэканоміць трафік і памяць. Змена налады ачысьціць кэш малюнкаў Кэш малюнкаў ачышчаны Ачысціць кэш метададзеных Выдаліць усе загружаныя дадзеныя вэб-старонак diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 24bf7a764..59091553d 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -151,7 +151,6 @@ Добавяне към Използвай бързо, но неточно превъртане По-бързо превъртане с по-ниска прецизност. Превъртане с по 5, 15 или 25 секунди няма да работи с тази опция - Зареждай миниатюри Кеш-паметта с изображения е изтрита Изтрий кешираните метаданни Премахни всички метаданни за уебстраници от кеш-паметта @@ -205,7 +204,6 @@ Прочетете нашата политика за поверителност Лицензът на NewPipe Липсва стрийм плейър (можете да изтеглите VLC, за да пуснете стрийма). - Изключете, за да спрете зареждането на всички миниатюри, спестявайки трафик и памет. При промяна на тази настройка, текущата кеш-памет на изображенията ще бъде изтрита Показвай подсказка при избор на фоновия режим или режим в прозорец от екрана за „Детайли“ към видео Изтрива историята на възпроизвежданите стриймове и позицията на възпроизвеждането Не са намерени видео стриймове diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index 4e6655e45..e660cb7bd 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -140,8 +140,6 @@ দ্রুত-ফরওয়ার্ড/-পুনরায় সন্ধান সময়কাল মন্তব্যসমূহ লুকাতে বন্ধ করুন মন্তব্যসমূহ দেখাও - থাম্বনেইল লোড করো - থাম্বনেইল প্রদর্শন বন্ধ করার মাধ্যমে, ডাটা এবং মেমোরি সংরক্ষণ করুন। অপশনটি‌ পরিবর্তনে ইন-মেমোরি এবং অন-ডিস্ক ইমেজ ক্যাশ উভয়ই মুছে যাবে। ছবির ক্যাশ মোছা হয়েছে সব ক্যাশড ওয়েবপেজ ডেটা মুছে ফেলো ক্যাশ করা মেটাডেটা মোছ diff --git a/app/src/main/res/values-bn-rIN/strings.xml b/app/src/main/res/values-bn-rIN/strings.xml index 162dfde39..1f664ce26 100644 --- a/app/src/main/res/values-bn-rIN/strings.xml +++ b/app/src/main/res/values-bn-rIN/strings.xml @@ -79,10 +79,8 @@ সব ক্যাশড ওয়েবপেজ ডেটা মুছে ফেলো ক্যাশ করা মেটাডেটা মুছো ছবির ক্যাশ মুছে ফেলা হয়েছে - থাম্বনেইল প্রদর্শন বন্ধ করার মাধ্যমে, ডাটা এবং মেমোরি সংরক্ষণ করুন। অপশনটি‌ পরিবর্তনে ইন-মেমোরি এবং অন-ডিস্ক ইমেজ ক্যাশ উভয়ই মুছে যাবে মতামত প্রদর্শন বন্ধ করতে অপশনটি বন্ধ করুন মতামত প্রদর্শন করুন - থাম্বনেইল লোড করুন দ্রুত-ফরওয়ার্ড/-পুনরায় সন্ধান সময়কাল অনির্দিষ্ট সন্ধান প্লেয়ারকে আরো দ্রুত গতিতে সন্ধান করার সুবিধা দেয়, কিন্তু এটি সম্পূর্ণ নির্ভুল নাও হতে পারে ৷ ৫, ১৫ ও ২৫ সেকেন্ডের জন্য এটা কাজ করবে না ৷ দ্রুত টানা ব্যাবহার করুন diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 6c3cca7a1..d3f3a845b 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -225,10 +225,8 @@ সব ক্যাশড ওয়েবপেজ ডেটা মুছে ফেলো ক্যাশ করা মেটাডেটা মুছো ছবির ক্যাশ মুছে ফেলা হয়েছে - থাম্বনেইল প্রদর্শন বন্ধ করার মাধ্যমে, ডাটা এবং মেমোরি সংরক্ষণ করুন। অপশনটি‌ পরিবর্তনে ইন-মেমোরি এবং অন-ডিস্ক ইমেজ ক্যাশ উভয়ই মুছে যাবে মতামত প্রদর্শন বন্ধ করতে অপশনটি বন্ধ করুন মতামত প্রদর্শন করুন - থাম্বনেইল লোড করুন দ্রুত-ফরওয়ার্ড/-পুনরায় সন্ধান সময়কাল অনির্দিষ্ট সন্ধান, চালককে আরো দ্রুত গতিতে সন্ধান করার সুবিধা দেয়, কিন্তু এটি সম্পূর্ণ নির্ভুল নাও হতে পারে ৷ ৫, ১৫ ও ২৫ সেকেন্ডের জন্য এটা কাজ করবে না। দ্রুত টানা ব্যাবহার করুন diff --git a/app/src/main/res/values-bs/strings.xml b/app/src/main/res/values-bs/strings.xml index 50dcf839c..4921a6aa8 100644 --- a/app/src/main/res/values-bs/strings.xml +++ b/app/src/main/res/values-bs/strings.xml @@ -73,7 +73,6 @@ Prebacivanje sa jednog pokretača na drugi bi van moglo zamijeniti pokretni red Isključite da sakrijete komentare Pitajte za potvrdu prije isčišćavanja reda - Isključite kako bi ste spriječili učitavanje sličica, sto če vam spasiti korištenje podataka i memorije. Promjene čiste slike oboje u memoriji i predmešiju na disku Prikažite komentare Pokažite \'Sljedeće\' i \'Slične\' video zapise Prikažite opis @@ -115,5 +114,4 @@ Pokrenite s KODI-jem Vrijeme premotavanja naprijed/nazad Aktivni pokretni red će biti zamijenjen - Učitajte sličice \ No newline at end of file diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 010823e43..bd3a5c61b 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -121,7 +121,6 @@ Recorda la darrera mida i posició del reproductor emergent Cerca ràpida poc precisa La cerca poc precisa permet que el reproductor cerqui una posició més ràpidament amb menys precisió. Cerques de 5, 15 o 25 segons no funcionaran - Carrega les miniatures S\'ha eliminat la memòria cau d\'imatges Elimina les metadades de la memòria cau S\'ha esborrat la memòria cau de metadades @@ -217,7 +216,6 @@ Toca \"Cerca\" per començar. Elimina l\'àudio en algunes resolucions Reproductor d\'àudio extern - Desactiveu-ho per no guardar miniatures i estalviar dades i memòria. Canviant aquesta opció, s\'eliminarà la memòria cau d\'imatges tant de la memòria com de l\'emmagatzematge Emmagatzema les cerques localment Crea un historial de vídeos visualitzats Reprèn la reproducció diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml index f761323f9..bae9fb822 100644 --- a/app/src/main/res/values-ckb/strings.xml +++ b/app/src/main/res/values-ckb/strings.xml @@ -16,7 +16,6 @@ پڕۆژەی نیوپایپ زانیارییە تایبەتییەکانت بە وردی دەپارێزێت. هەروەها به‌رنامه‌كه‌ هیچ زانایارییەکت بەبێ ئاگاداری تۆ بەکارنابات. \n‫سیاسەتی تایبەتی نیوپایپ بە وردی ڕوونکردنەوەت دەداتێ لەسەر ئەو زانیاریانەی وەریاندەگرێت و بەکاریاندەبات. ناتوانرێت لە بیرگەی دەرەکیدا داببەزێنرێت . شوێنی فۆڵده‌ری دابه‌زاندنەکان ڕێکبخرێتەوە؟ - ناکارای بكه‌ بۆ وەستاندنی باركردنی وێنۆچكه‌كان، داتا دەپارێزێت و کەمتر بیرگە بەکاردەبات, گۆڕینی ئه‌مه‌ ده‌بێته‌ هۆی سڕینه‌وه‌یان له‌سه‌ر بیرگه‌ی مۆبایله‌كه‌ت ئایا مەبەستت ئه‌مه‌یه‌ \"%1$s\"؟ ماوەی نوێكردنه‌وه‌ی فیید هێڵەکی @@ -111,7 +110,6 @@ زمان دەگۆڕدرێت لەدوای داگیرساندنەوەی به‌رنامه‌كه‌ لادانی سەیرکراو پیشاندانی نیشانەکەری شوێنی کارپێکەر لە خشتەکاندا - باركردنی وێنۆچكه‌كان شوێنەکان لە خشتەکاندا به‌ژداریت بەهۆی گۆڕانکاری لە شێوەی ژێرنووسکردنەکە. پێویستە به‌رنامه‌كه‌ دابگیرسێنیته‌وه‌ diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 1eb38085c..dab312d3b 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -251,8 +251,6 @@ Vynutit hlášení nedoručitelných výjimek Rx mimo životnost fragmentu nebo aktivity po odstranění Použít rychlé nepřesné hledání Nepřesné hledání umožní přehrávači posouvat se rychleji, ale se sníženou přesností. Posouvání po 5, 15 nebo 25 vteřinách s tímto nefunguje - Načítat náhledy - Vypnutím zabráníte načítání miniatur, ukládání dat a spotřebě paměti. Změny vymažou mezipaměť obrázků v paměti i na disku Mezipaměť obrázků vymazána Vymazat metadata v mezipaměti Odstranit všechna data webových stránek v mezipaměti diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 0bd7e9875..ef6197414 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -57,8 +57,6 @@ Husk sidste størrelse og placering af pop op-afspiller Brug hurtig og upræcis søgning Upræcis søgning lader afspilleren finde placeringer hurtigere, men mindre præcist. Søgninger på 5, 15 eller 25 sekunder fungerer ikke med denne indstilling slået til - Indlæs miniaturebilleder - Slå fra for at undgå indlæsning af billeder, hvorved der spares data og hukommelse. Ændringer sletter billedcachen i både ram og lager Billedcache slettet Slet metadata-cachen Slet alle websidedata fra cachen diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 5283f1afa..e9b710c63 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -253,7 +253,6 @@ Beachte, dass diese Aktion das Netzwerk stark belasten kann. \n \nMöchtest du fortfahren\? - Vorschaubilder laden Bilder-Cache gelöscht Zwischengespeicherte (Metadaten) löschen Alle zwischengespeicherten Website-Daten entfernen @@ -270,7 +269,6 @@ Geschwindigkeit Tonhöhe Entkoppeln (kann zu Verzerrungen führen) - Ausschalten, um das Laden von Vorschaubildern zu verhindern, was Daten- und Speicherverbrauch spart. Änderungen löschen den Bildzwischenspeicher sowohl im Arbeitsspeicher als auch auf dem internen Speicher Nächsten Stream automatisch einreihen Wiedergabe durch Anhängen eines verwandten Streams an die Warteschlange (ohne Wiederholungsschleife) fortsetzen Wiedergabeliste mit Lesezeichen versehen diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 094ac0ccd..ced70b787 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -90,8 +90,6 @@ Ενθύμηση του τελευταίου μεγέθους και θέσης του παραθύρου Χρήση γρήγορης ανακριβούς αναζήτησης Η μην ακριβής αναζήτηση επιτρέπει στην εφαρμογή να αναζητεί θέσεις στο βίντεο γρηγορότερα με μειωμένη ακρίβεια. Δε λειτουργεί για διαστήματα των 5, 15 ή 25 δευτερολέπτων - Φόρτωση μικρογραφιών - Με την απενεργοποίηση δε φορτώνονται οι μικρογραφίες, εξοικονομώντας δεδομένα και μνήμη. Οι αλλαγές σβήνουν τις προσωρινά αποθηκευμένες εικόνες στη μνήμη και στον δίσκο Εκκαθαρίστηκε η προσωρινή μνήμη εικόνων Εκκαθάριση προσωρινά αποθηκευμένων μεταδεδομένων Αφαίρεση όλων των προσωρινά αποθηκευμένων δεδομένων ιστοσελίδων diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index c8cc728b5..808aa2573 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -76,7 +76,6 @@ Behaviour Select your favourite PeerTube instances Continue playing after interruptions (e.g. phone calls) - Turn off to prevent loading thumbnails, saving data and memory usage. Changes clear both in-memory and on-disc image cache. Published on %1$s Report this error via e-mail Select your favorite night theme – %s diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index a3a7a6af4..2d0951db4 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -80,7 +80,6 @@ Memori lastan grandon kaj pozicion de ŝprucfenestro Uzi rapidan malekzaktan serĉon Malekzakta serĉo permesas ke, la ludilo serĉi poziciojn pli rapide sed kun malpli ekzakto. Serĉi por 5, 15 aŭ 25 sekundoj ne funckias kun ĉi tio opcio - Ŝarĝi bildetojn Ne povis konstrui la dosierujon de elŝuto Enhavo limigita al aĝo Nuna @@ -181,7 +180,6 @@ \n2. Iru tien: %1$s \n3. Ensalutu kiam oni petas vin \n4. Kopiu la ligilon de profilo ke oni kondikis vin. - Malŝaltu por malebligi ŝarĝajn bildetojn por konservi datumuzadon kaj memoruzadon. Ŝanĝoj vakigi ambaŭ en memoran kaj en diskan bildkaŝmemoron Bildokaŝmemoro vakigis Vakigi kaŝmemorigitajn metadatumojn Vakigi tutajn kaŝmemorigitajn retpaĝajn datumojn diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index d1d7fdcd4..6ffadca81 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -288,8 +288,6 @@ Esta operación puede causar un uso intensivo de la red. \n \n¿Quieres continuar\? - Cargar miniaturas - Desactivar para evitar la carga de miniaturas y ahorrar datos y memoria. Se vaciará la caché de imágenes en la memoria volátil y en el disco Se vació la caché de imágenes Vaciar metadatos en memoria caché Quitar todos los datos guardados de páginas web diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index b55870c75..ab478ec11 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -55,8 +55,6 @@ Pea hüpikakna viimane suurus ja asukoht meeles Kasuta ebatäpset kerimist Ebatäpne kerimine lubab meediamängijal otsida asukohta kiiremini täpsuse arvel. Sellega ei tööta 5, 15 või 25 sekundi kaupa kerimine - Laadi pisipildid - Lülita välja, et keelata pisipiltide laadimist, andmete salvestamist ja mälukasutust. Muutmine puhastab vahemälu nii kettal kui ka mälus Pildid kustutati vahemälust Kustuta metaandmed vahemälust Kustuta veebilehtede andmed vahemälust diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index c8d16b698..6003de6fd 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -211,7 +211,6 @@ Gogoko erreprodukzio-zerrendak Gehitu hona Erabili bilaketa azkar ez zehatza - Kargatu iruditxoak Irudien cachea ezabatuta Ezabatu cacheko metadatuak Kendu cachetik webguneen datu guztiak @@ -307,7 +306,6 @@ Desaktibatu (distortsioa sor lezake) Ezarpenak ere inportatu nahi dituzu? Bilaketa ez zehatzak posizioak azkarrago baina prezisio gutxiagoz bilatzea ahalbidetzen du. 5, 15 edo 25 segundo bilatzea ez du honekin funtzionatzen - Desgaitu koadro txikiak ez kargatzeko, datuak eta memoria aurreztuz. Aldaketak memoria eta diskoko irudien cacheak garbituko ditu NewPipe Software Librea eta Copyleft da: Erabili, ikertu, partekatu eta hobetu dezakezu. Zehazki, elkarbanatzea eta aldatzea Free Software Foundation-ek argitaratutako GNU General Public License-ren 3. bertsioa edo berriagoren baten terminoen arabera egiteko baimena duzu. Behartu aktibitatearen bizitza ziklotik kanpo baztertu eta gero entregatu ezin diren Rx salbuespenen inguruko txostena NewPipe pribatutasun politika diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 3d8e8da9b..35db56515 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -96,7 +96,6 @@ تنها برخی دستگاه‌ها توانایی پخش ویدیوهای 2K و 4K را دارند قالب ویدیویی پیش‌گزیده سیاه - بار کردن بندانگشتی‌ها قرار دادن خودکار جریان بعدی در صف پیشنهادهای جستجو گزینش پیشنهادها برای نمایش هنگام جست‌وجو @@ -270,7 +269,6 @@ پخش ادامه یابد ذخیره محلی نتایج جستجو صف پخش در حال پایان (بدون تکرار) را با افزودن یک جریان مرتبط ادامه دهید - برای پیش‌گیری از بار کردن بندانگشتی‌ها و ذخیرهٔ داده و فضای ذخیره، خاموش کنید. تغییرات، انبارهٔ تصاویر روی حافظه و دیسک را پاک می‌کند ادامه پخش بازگرداندن آخرین موقعیت پخش موقعیت در فهرست‌ها diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 641e55b21..397f2fef0 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -196,8 +196,6 @@ Lisää soittolistaan Käytä nopeampaa epätarkkaa pikakelausta Epätarkka kelaus mahdollistaa videon kelauksen nopeammin huonommalla tarkkuudella. Kelaaminen 5, 15 tai 25 sekunnin hyppäyksin ei toimi tämän kanssa - Lataa esikatselukuvat - Poista käytöstä estääksesi esikatselukuvien lataus. Tämä säästää dataa ja vähentää muistin käyttöä. Asetuksen muuttaminen poistaa muistissa ja levyllä olevan kuvavälimuistin Kuvavälimuisti tyhjennetty Poista tallennettu metatieto Poista kaikki tallennettu sivutieto diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index 4cafaff85..0fb7a0a1d 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -48,7 +48,6 @@ Pangalawang action button Pangatlong action button Pinapayagan ng di-saktong seek ang player na mag-seek sa mga posisyon nang mabilis ngunit na may pinababang kasaktuhan. Di ito gagana sa pag-seek nang 5, 15, o 25 segundo. - Patayin para mapigilan ang pag-load sa mga thumbnail, para makatipid ng data at paggamit sa memory. Lilinisin ang parehong image cache na nasa memory at nasa disk Piliin ang mga mungkahing ipapakita habang naghahanap Patayin para itago ang paglalarawan ng video at karagdagang impormasyon I-edit ang bawat action sa abiso sa baba sa pamamagitan ng pagpindot sa mga ito. Pumili ng hanggang tatlong ipapakita sa siksik na abiso gamit ang mga checkbox sa kanan @@ -70,7 +69,6 @@ Kumpirmahin muna bago linisin ang pila Maaaring mapalitan ang pila mo kung magpapalit ka ng player Papalitan ang aktibong pila sa player - I-load ang mga thumbnail Ipakita ang paglalarawan Ipakita ang meta info Patayin para itago ang mga meta infobox na may karagdagang impormasyon tungkol sa creator ng stream, laman nito o ng hinanap diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b899ec7f8..51f258166 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -244,8 +244,6 @@ Zoomer Utiliser la recherche rapide approximative Permet au lecteur d’accéder plus rapidement à une position au détriment de la précision. Se déplacer de 5, 15 ou 25 secondes est impossible avec cette option - Charger les miniatures - Désactivez pour empêcher le chargement des miniatures afin de réduire l’utilisation de la bande passante et de la mémoire. La modification de cette option vide le cache en mémoire vive et sur le disque Images en cache effacées Effacer les métadonnées en cache Efface toutes les données des pages Web en cache diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 98d3d472b..8b5aaa497 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -55,8 +55,6 @@ Lembrar o tamaño e a posición anteriores do «popup» Usar un salto inexacto mais inexacto A busca inexacta permite ao reprodutor procurar posicións máis rápidas con precisión reducida. A busca de 5, 15 ou 25 segundos non funciona con isto - Carregar miniaturas - Desactíveo para evitar a carga de miniaturas e poupar datos e memoria. Modificar esta opción limpa a caché de imaxes da memoria e do disco A caché de imaxes foi limpada Os metadatos da caché foron eliminados Eliminar todos os datos de páxinas en caché diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 5c55d0bad..4dec4c819 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -268,8 +268,6 @@ קצב שימוש בחיפוש מהיר ולא מדויק חיפוש גס מאפשר לנגן לחפש נקודת זמן מהר יותר, ברמת דיוק נמוכה יותר. חיפוש של 5, 15 או 25 שניות לא עובד עם ההגדרה הזאת - טעינת תמונות ממוזערות - כיבוי האפשרות מונע את טעינת התמונות הממוזערות, חוסך בתקשורת נתונים ובניצולת הזיכרון. שינויים באפשרות זו מוחקים את המטמון בזיכרון ובכונן הסרת כל נתוני העמודים שבמטמון הוספת התזרים הבא לרשימת הנגינה אוטומטית להמשיך תור נגינה סופית (בלתי מחזורית) על ידי הוספת תזרים קשור diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index a2bbaf672..80ab6209c 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -245,10 +245,8 @@ ऑटो-जनरेटेड हीप डंप करने के दौरान मेमोरी लीक मॉनिटरिंग ऐप को अनुत्तरदायी बना सकता है Out-of-Lifecycle त्रुटियों की रिपोर्ट करें - थंमनेल लोड करें तेज और अनिश्चित तलाश का प्रयोग करें अनिश्चित खोज से प्लेयर में कम सटीकता से लेकिन तेजी से वीडियो पोजीशन्स की तलाश कर सकता हैं। 5, 15 या 25 सेकंड की तलाश में यह काम नहीं करता - डेटा खपत, मेमोरी उपयोग की बचत और थंमनेल लोड होने से रोकने के लिए बंद करें। इस बदलाव से इन-मेमोरी और ऑन-डिस्क छवि कैश दोनों मिट जाते हैं चित्र कैश मिटाया गया कैश मेटाडेटा मिटाएं कैश किए गए सभी वेबपेज का डेटा हटाएं diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 80b734fcd..c625955f7 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -218,7 +218,6 @@ Prikaži informacije Zabilježene playliste Dodaj u - Učitaj sličice Slikovna predmemorija obrisana Izbriši metapodatke iz predmemorije Kanali @@ -312,7 +311,6 @@ Dostupna je nova verzija za NewPipe! Preuzimanje nije uspjelo Prikaži pogrešku - Isključi za sprečavanje učitavanja sličica, čime se štedi korištenje podataka i memorije. Promjene čiste predmemoriju slika radne memorije i diska Izbriši sve podatke web-stranica iz predmemorije Metapodaci su izbrisani Automatski dodaj sljedeći stream u popisa izvođenja diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 9f3ddf9cf..26f4ee3cf 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -136,8 +136,6 @@ Hozzáadás ehhez Gyorsabb, de pontatlan tekerés használata A pontatlan tekerés lehetővé teszi, hogy gyorsabban ugorjon a pozíciókra, de kisebb pontossággal. Az 5, 15, vagy 25 másodperces tekerés nem működik ebben a módban - Bélyegképek betöltése - Kapcsolja ki, hogy a megelőzze a bélyegképek betöltését, így csökkentve az adat- és memóriahasználatot. A megváltoztatása törli a memóriában és a meghajtón lévő képgyorsítótárat A bélyegkép gyorsítótár törölve Gyorsítótárazott metaadatok törlése Minden gyorsítótárazott weboldaladat törlése diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml index d4ae5b455..512598eaa 100644 --- a/app/src/main/res/values-ia/strings.xml +++ b/app/src/main/res/values-ia/strings.xml @@ -227,7 +227,6 @@ Interne Aperir con Suggestiones de recerca remote - Cargar miniaturas Monstrante resultatos pro: %s Solmente alicun apparatos pote reproducer videos 2K/4K Initiar le reproductor principal in schermo plen diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 292430861..b68b36a47 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -132,8 +132,6 @@ Notifikasi NewPipe Riwayat Riwayat - Muat thumbnail - Matikan agar thumbnail tidak dimuat, menghemat penggunaan data dan memori. Perubahan menghapus cache gambar baik di memori dan disk Cache gambar dihapus Hapus cache metadata Hapus semua data cache halaman web diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index e27217971..98f73e294 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -177,7 +177,6 @@ Nota hraða en ónákvæma leit Lengd skrefs Biðja um staðfestingu áður en röð er hreinsuð - Sækja smámyndir Sýna ummæli Sjálfvirk biðröð Hreinsa gögn @@ -613,7 +612,6 @@ Stærð forhleðslu Breyta stærð forhleðslu (nú %s). Lægra gildi gæti flýtt fyrir upphaflegu hleðslu myndbands. Breytingar krefjast endurræsingar spilara Biðröð spilarans verður skipt út - Slökktu á til að hlaða ekki niður smámyndum til að spara bandbreidd og vinnsluminni. Breytingar eyða myndskyndiminni í bæði vinnsluminni og geymslu Slökktu á til að fela lýsigagnareiti með viðbótarupplýsingum um straumhöfund, straumefni eða leitarbeiðni Fjarlæga öll síðugögn úr skyndiminni Bæta svipuðum straumum við biðröðina þegar síðasta er spilað og endurspilun er ekki virkjuð diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 05604e998..48cc84328 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -287,8 +287,6 @@ Tieni presente che questa operazione può consumare una grande quantità di traffico dati. \n \nVuoi continuare? - Carica copertine - Disabilita per prevenire il caricamento delle copertine, risparmiando dati e memoria. La modifica di questa opzione cancellerà la cache delle immagini in memoria e sul disco Cache immagini svuotata Svuota la cache dei metadati Elimina i dati delle pagine web memorizzati nella cache diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 0eeeaf8dd..8fa73a002 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -196,7 +196,6 @@ 動画をダウンロード 情報を表示 ブックマークしたプレイリスト - サムネイルを読み込む 画像キャッシュを消去しました キャッシュを消去 アプリ内のキャッシュデータをすべて削除します @@ -254,7 +253,6 @@ プライバシーポリシーを確認 おおまかなシーク おおまかなシークを使用することで精度が下がる代わりに高速にシークができます。5 秒、15 秒または 25 秒間隔のシークはできません - サムネイルの読み込みと保存を無効化します。(このオプションを切り替えるとメモリとディスク上の画像キャッシュが消去されます) キューに関連動画を追加して再生を続ける (繰り返ししない場合) すべての再生履歴を削除しますか? すべての検索履歴を削除しますか? diff --git a/app/src/main/res/values-jv/strings.xml b/app/src/main/res/values-jv/strings.xml index 2f68f9bc9..7f71a2f41 100644 --- a/app/src/main/res/values-jv/strings.xml +++ b/app/src/main/res/values-jv/strings.xml @@ -10,11 +10,9 @@ Antri otomatis stream bare Sampah metadata wes dibusak Busak kabeh sampah ora kanggo - Pateni ben gambar cilik ora ketok, ora boros data lan memori. Iku bakal ngresiki sampah gambar. Sampah gambar wes resik Pateni gawe ngumpetke komentar Duduhke komentar - Duduhke gambar cilik Durasi cepet maju/mundure Eling-eling ukuran lan posisi ngambang terakhir Eling-eling ukuran lan posisi ngambang diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 89c2193da..47e105183 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -42,7 +42,6 @@ არაზუსტი ძიება საშუალებას აძლევს მოთამაშეს უფრო სწრაფად მოიძიოს პოზიციები შემცირებული სიზუსტით. 5, 15 ან 25 წამის ძიება ამით არ მუშაობს სწრაფი წინსვლა/-გადახვევა ძიების ხანგრძლივობა ერთი მოთამაშიდან მეორეზე გადართვამ შესაძლოა შეცვალოს თქვენი რიგი - გამორთეთ ესკიზების ჩატვირთვის თავიდან ასაცილებლად, მონაცემთა დაზოგვისა და მეხსიერების გამოყენების თავიდან ასაცილებლად. იცვლება როგორც მეხსიერებაში, ასევე დისკზე გამოსახულების ქეშის გასუფთავება ძიების შეთავაზებები წაშალეთ ყველა ქეშირებული ვებგვერდის მონაცემები შემდეგი ნაკადის ავტომატური შეყვანა @@ -107,7 +106,6 @@ შავი დამახსოვრება ამომხტარი ფანჯრის თვისებები აქტიური მოთამაშის რიგი შეიცვლება - ჩატვირთეთ ესკიზები კომენტარების ჩვენება გამორთეთ კომენტარების დასამალად \"შემდეგი\" და \"მსგავსი\" ვიდეოების ჩვენება diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index 41f2742ab..b7478aa58 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -242,8 +242,6 @@ Vîdyoyên \'Pêş\' û \'Bi vî rengî\' nîşan bidin Zivirandin da ku şîroveyan veşêrin Şîroveyan nîşan bide - Ji bo pêşîgirtina li barkirina nîgarkêşan, daneya daneyê û karanîna bîranînê xilas bibe vemirînin. Guherandinên kaşeya wêneyê hem di bîra û hem jî li ser dîskê paqij dikin. - Nîgarên barkêş Dê rêza lîstikvanê çalak were guhertin Guhertina ji lîstikvanek bi yeke din dibe ku dewsa dorê we bigire Berî paqijkirina dorê ji pejirandinê bipirsin diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 127db9bcb..30c381bcf 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -278,8 +278,6 @@ 경고: 데이터가 많이 소모될 수 있습니다. \n \n계속하시겠습니까\? - 썸네일 로드하기 - 동영상 썸네일을 로드하지 않으며, 데이터와 메모리 사용을 최대한 줄입니다. 이 옵션을 선택 시 모든 메모리 캐시와 저장소 캐시를 삭제합니다 이미지 캐시 지워짐 캐시된 메타데이터 지우기 캐시된 모든 웹페이지 데이터 지우기 diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml index 8d1ffbab8..fc7e85616 100644 --- a/app/src/main/res/values-ku/strings.xml +++ b/app/src/main/res/values-ku/strings.xml @@ -53,9 +53,6 @@ ڕه‌ش بیرهاتنه‌وه‌ی شوێن و قه‌باره‌ی په‌نجه‌ره‌ بیرهاتنه‌وه‌ی كۆتا قه‌باره‌ و شوێنی په‌نجه‌ره‌ی بچووك - باركردنی وێنۆچكه‌كان - ناچالاكی بكه‌ بۆ ڕاگرتنی وێنۆچكه‌كان له‌ باركردن و پاشه‌كه‌وتبوون له‌سه‌ر بیرگه‌ی ئامێره‌كه‌ت. -\nگۆڕینی ئه‌مه‌ ده‌بێته‌ هۆی سڕینه‌وه‌یان له‌سه‌ر بیرگه‌ی مۆبایله‌كه‌ت. پاشماوه‌ی وێنۆچكه‌كان سڕایه‌وه‌ بەکارهێنانی گەڕانی ناوردی خێرا خاوێنکردنەوەی پاشماوەی داتا diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 1c8ba59ae..58b25709b 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -374,8 +374,6 @@ Atstatyti paskutinį atkūrimo laiką Tęsti atkūrimą Rodyti aprašymą - Norėdami taupyti duomenų srautą, atminties naudojimą išjunkite. Pakeitimai išvalys duomenis atmintyje ir diske - Įkelti miniatiūras Aktyvaus grotuvo eilė bus pakeista Perjungimas iš vieno grotuvo į kitą gali pakeisti jūsų eilę Prieš išvalant eilę prašyti patvirtinimo diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index c8d3221eb..a613dd70a 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -517,8 +517,6 @@ Rādīt \'Nākošos\' un \'Līdzīgos\' videoklipus Izslēdziet, lai paslēptu komentārus Rādīt komentārus - Izslēdziet, ja vēlaties nelādēt video attēlus, ietaupot datus un atmiņu. Opcija notīra kešatmiņu, izdzēšot visus saglabātos video attēlus - Ielādēt video attēlus Tagadējā atskaņošanas rinda tiks aizvietota Mainoties vienam video uz citu, iespējams, notīrīsies jūsu atskaņošanas rinda Prasīt apstiprinājumu, pirms notīrīt atskaņošanas rindu diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index 524c82aef..e39172c72 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -55,8 +55,6 @@ Запамти ја последната големина и место на прозорчето Брзо, непрецизно премотување Со непрецизното премотување се пребарува побрзо, но со намалена презицност. - Прочитај мали видео-сликички - Оневозможете, за да не се читаат малите видео-сликички за штедење на меморија и интернет. Промената на оваа опцијата ќе ја избрише кеш-меморијата. Кешираните слики се избришани Избришете ги кешираните мета-податоци Избришете ги сите кеш-податоци од веб-страни diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 29769acae..d03ae0a38 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -331,10 +331,8 @@ കാഷെ ആയ ഡേറ്റ നീക്കംചെയ്യുക കാഷെ ആയ മെറ്റാഡേറ്റ തുടച്ചുനീക്കി ഇമേജ് കാചെ തുടച്ചുമാറ്റി - ലഘുചിങ്ങൾ ലോഡ് ചെയ്യാതിരിക്കാനും ഡേറ്റയും മെമ്മറിയും ലാഭിക്കാനുമായി ഓഫ്ചെയ്യുക. എസ് ഡീ കാർഡിലെയും മെമ്മറിയിലെയും കാച്ചേ ക്ലിയർ ചെയ്യും കമന്റുകൾ മറയ്ക്കാനായി ഓഫ് ചെയ്യുക കമന്റുകൾ കാണിക്കുക - ലഘുചിത്രങ്ങൾ ലോഡ്‌ ചെയ്യുക ഫാസ്റ്റ്-ഫോർവേർഡ്/റീവൈൻഡ് സമയദൈർഘ്യം Inexact seek ഉപയോഗിക്കുക കുറഞ്ഞ കൃത്യതയോടെ സീക് ചെയ്യാൻ ഇൻ എക്സക്ട് സഹായിക്കുന്നു. 5,15,25 സെക്കൻഡ് സീക്‌ ഈ മോഡിൽ പ്രവർത്തിക്കുകയില്ല diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index 648849205..d9e4f12ef 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -57,8 +57,6 @@ Mengingat saiz dan posisi popup terakhir Gunakan tinjau laju tidak tepat Membolehkan pemain untuk meninjau ke posisi lebih laju dengan kurang ketepatan. Mencari 5, 15 atau 25 saat tidak berfungsi dengan ini - Muatkan thumbnail - Matikan untuk mengelakkan pemuatan thumbnail, menjimat penggunaan data dan ingatan. Perubahan akan menghapus cache imej dari ingatan dan disk Cache imej dihapuskan Hapuskan cache metadata Hapuskan semua cache data halaman web diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index da6193e90..1637fe1f7 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -257,7 +257,6 @@ Eksporterer… Importer fil Forrige eksport - Last miniatyrbilder Bildehurtiglager tømt Tøm hurtiglagret metadata Fjern all hurtiglagret nettsidedata @@ -304,7 +303,6 @@ \n3. Logg inn når forespurt \n4. Kopier profil-nettadressen du ble videresendt til. Unøyaktig spoling lar spilleren søke posisjoner raskere med redusert presisjon. Å søke i 5, 15 eller 25 sekunder fungerer ikke med dette - Skru av for å stoppe innlasting av miniatyrbilder, noe som sparer data- og minnebruk. Endring av dette vil tømme både disk- og minne-hurtiglager Fortsett fullendt (ikke-repeterende) avspillingskø ved å legge til en relatert strøm Overvåkning av minnelekkasjer kan forårsake at appen ikke svarer under heap dumping Rapporter feil utenfor livssyklusen diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml index 05c82808e..d1d0d15b0 100644 --- a/app/src/main/res/values-ne/strings.xml +++ b/app/src/main/res/values-ne/strings.xml @@ -56,10 +56,8 @@ पछिल्लो आकार र पपअप को स्थिति सम्झना तेज \'inexact\' खोज्न प्रयोग गर्नुहोस \'Inexact\' प्लेयर कम सटीक छिटो स्थितिहरू गर्न खोज्न अनुमति दिन्छ खोज्छन्। 5, 15 वा 25 सेकेन्ड को लागि खोजी यो काम गर्दैन। - थम्बनेल लोड टिप्पणीहरू देखाऊ टिप्पणीहरू लुकाउन, बन्द गर्नुहोस - डाटा र स्मृति उपयोग सुरक्षित गर्न, थम्बनेलहरू लोड रोक्न, बन्द गर्नुहोस। परिवर्तनहरू दुवै मा-स्मृति र-डिस्क छवि क्यास खाली गर्छ। छवि क्यास सखाप क्यास मेटाडाटा हटाउ सबै क्यास वेबपेज डाटा हटाउ diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml index bf77f9da3..0d582f6de 100644 --- a/app/src/main/res/values-nl-rBE/strings.xml +++ b/app/src/main/res/values-nl-rBE/strings.xml @@ -55,8 +55,6 @@ Onthoud laatste grootte en positie van pop-up Snel, minder exact spoelen gebruiken Minder exact spoelen laat de speler sneller posities zoeken met verminderde precisie. 5, 15 en 25 seconden werken niet - Miniatuurvoorbeelden laden - Schakel dit uit voor het laden van miniatuurvoorbeelden te verhinderen; dit bespaart mobiele gegevens en geheugen. Het wijzigen van deze instelling wist het geheugen en de afbeeldingscache Afbeeldingscache gewist Gecachete metagegevens wissen Alle gecachete webpagina-gegevens wissen diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index b6622c210..e5b7f0f82 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -284,8 +284,6 @@ Let op: deze actie kan veel MB’s van je mobiele netwerk gebruiken. \n \nWil je doorgaan? - Miniatuurvoorbeelden laden - Schakel dit uit om het laden van miniatuurvoorbeelden te verhinderen; dit bespaart mobiele data en geheugen. Het wijzigen van deze instelling wist het geheugen en de afbeeldingscache Afbeeldingscache gewist Gecachete metagegevens wissen Alle gecachete webpagina-gegevens wissen diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index d440d8a89..6341e6700 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -58,7 +58,6 @@ Utilzar la recèrca rapida inexacta La recèrca inexacta permet a l\'utilizaire de recercar mai rapidament una posicion amb mens de precision Durada d\'avançada/reculada rapida - Cargar las miniaturas Afichar los comentaris Desactivar per afichar pas mai los comentaris Apondre la vidèo seguenta dins la coa de lectura diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index 084f21ca2..519a0f199 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -101,7 +101,6 @@ ଏକ ଧାଡି ସଫା କରିବା ପୂର୍ବରୁ ନିଶ୍ଚିତକରଣ ମାଗନ୍ତୁ ଗୋଟିଏ ଖେଳାଳୀରୁ ଅନ୍ୟ ଖେଳାଳୀକୁ ପରିବର୍ତ୍ତନ କରିବା ଆପଣଙ୍କ ଧାଡି ବଦଳାଇପାରେ ସକ୍ରିୟ ପ୍ଲେୟାର କ୍ୟୁ ବଦଳାଯିବ - ଥମ୍ୱନେଲ୍ ଲୋଡ୍ କରନ୍ତୁ \'ପରବର୍ତ୍ତୀ\' ଏବଂ \'ସମାନ\' ଭିଡିଓଗୁଡିକ ଦେଖାନ୍ତୁ ବର୍ଣ୍ଣନା ଦେଖାନ୍ତୁ ପ୍ରତିଛବି କ୍ୟାଚ୍ ପୋଛି ଦିଆଗଲା @@ -149,7 +148,6 @@ ଵିଡ଼ିଓ ଓ ଅଡ଼ିଓ ମିନି ପ୍ଲେୟାରରେ ଭିଡିଓ ଆରମ୍ଭ କରନ୍ତୁ ନାହିଁ, କିନ୍ତୁ ଅଟୋ ଘୂର୍ଣ୍ଣନ ବନ୍ଦ ହୋଇଗଲେ ସିଧାସଳଖ ଫୁଲ୍ ସ୍କ୍ରିନ୍ ମୋଡ୍ କୁ ଯାଆନ୍ତୁ। ଫୁଲ୍ ସ୍କ୍ରିନ୍ ଛାଡି ଆପଣ ଏପର୍ଯ୍ୟନ୍ତ ମିନି ପ୍ଲେୟାରକୁ ପ୍ରବେଶ କରିପାରିବେ ଏହା ଉପରେ ଟ୍ୟାପ୍ କରି ନିମ୍ନରେ ପ୍ରତ୍ୟେକ ବିଜ୍ଞପ୍ତି କାର୍ଯ୍ୟ ସଂପାଦନ କରନ୍ତୁ। ଡାହାଣରେ ଥିବା ଚେକ୍ ବକ୍ସ ବ୍ୟବହାର କରି କମ୍ପାକ୍ଟ ବିଜ୍ଞପ୍ତିରେ ଦେଖାଯିବାକୁ ସେମାନଙ୍କ ମଧ୍ୟରୁ ତିନୋଟି ପର୍ଯ୍ୟନ୍ତ ଚୟନ କରନ୍ତୁ - ଥମ୍ବନେଲ ଲୋଡିଂ, ଡାଟା ଏବଂ ମେମୋରୀ ବ୍ୟବହାରକୁ ରୋକିବା ପାଇଁ ବନ୍ଦ କରନ୍ତୁ । ପରିବର୍ତ୍ତନଗୁଡ଼ିକ ଉଭୟ ଇନ-ମେମୋରୀ ଏବଂ ଅନ୍-ଡିସ୍କ ଇମେଜ୍ କ୍ୟାଚ୍ ସଫା କରେ ଷ୍ଟ୍ରିମ୍ ସୃଷ୍ଟିକର୍ତ୍ତା, ଷ୍ଟ୍ରିମ୍ ବିଷୟବସ୍ତୁ କିମ୍ବା ଏକ ସନ୍ଧାନ ଅନୁରୋଧ ବିଷୟରେ ଅତିରିକ୍ତ ସୂଚନା ସହିତ ମେଟା ସୂଚନା ବାକ୍ସଗୁଡ଼ିକୁ ଲୁଚାଇବାକୁ ବନ୍ଦ କରନ୍ତୁ ପିଲାମାନଙ୍କ ପାଇଁ ସମ୍ଭବତ content ଅନୁପଯୁକ୍ତ ବିଷୟବସ୍ତୁ ଦେଖାନ୍ତୁ କାରଣ ଏହାର ବୟସ ସୀମା ଅଛି (ଯେପରିକି 18+) ଏହି ଭିଡିଓ ବୟସ-ସୀମିତ ଅଟେ । diff --git a/app/src/main/res/values-pa-rPK/strings.xml b/app/src/main/res/values-pa-rPK/strings.xml index 534ac790f..0233bbc8b 100644 --- a/app/src/main/res/values-pa-rPK/strings.xml +++ b/app/src/main/res/values-pa-rPK/strings.xml @@ -38,7 +38,6 @@ گوڑی اگے لنگھاؤݨ یا پچھے کرن دی سماں معد سرگرم پکیئر کتار جاوےگا - تھمنیل لوڈ کرو کتار نوں خالی کرن توں پہلاں تصویر کرن لئی پچھو ٹپݨیاں وکھاؤݨا روکݨ لئی ایسنوں بند کرو ٹپݨیاں دِکھاؤ diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index a10ddd125..253a87740 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -55,8 +55,6 @@ ਪੌਪ-ਅਪ ਦਾ ਆਖਰੀ ਅਕਾਰ ਅਤੇ ਸਥਿਤੀ ਯਾਦ ਰੱਖੋ ਤੇਜ਼ ਪਰ ਅਸਪੱਸ਼ਟ ਸੀਕ ਵਰਤੋ ਅਸਪੱਸ਼ਟ ਸੀਕ ਵੀਡੀਓ ਨੂੰ ਤੇਜ਼ ਪਰ ਅਣ-ਸਟੀਕ ਢੰਗ ਨਾਲ ਅੱਗੇ-ਪਿੱਛੇ ਲਿਜਾਂਦਾ ਹੈ । ਇਸ ਨਾਲ ਅੱਗੇ-ਪਿੱਛੇ 5,15 ਜਾਂ 25 ਸਕਿੰਟ ਜਾਣਾ ਕੰਮ ਨਹੀਂ ਕਰੇਗਾ - ਥੰਮਨੇਲ ਲੋਡ ਕਰੋ - ਡਾਟਾ ਤੇ ਮੈਮੋਰੀ ਖਪਤ ਦੀ ਬੱਚਤ ਅਤੇ ਥੰਮਨੇਲ ਲੋਡ ਹੋਣ ਤੋਂ ਰੋਕਣ ਲਈ ਬੰਦ ਕਰੋ। ਇਸ ਵਿਚ ਤਬਦੀਲੀ ਕਰਨ ਨਾਲ ਇਨ-ਮੈਮੋਰੀ ਅਤੇ ਆਨ-ਡਿਸਕ ਚਿੱਤਰ ਕੈਸ਼ੇ ਦੋਵੇਂ ਮਿਟ ਜਾਣਗੇ ਚਿੱਤਰ cache ਮਿਟਾ ਦਿੱਤੀ ਗਈ ਹੈ ਕੈਸ਼ ਕੀਤਾ ਮੈਟਾ-ਡਾਟਾ ਮਿਟਾਓ ਸਾਰੇ ਕੈਸ਼ ਕੀਤੇ ਵੈੱਬ-ਪੇਜਾਂ ਦਾ ਡਾਟਾ ਮਿਟਾਓ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 613433f5e..b250901ff 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -254,8 +254,6 @@ Wymuś raportowanie niedostarczonych wyjątków Rx poza cyklem życia fragmentu lub aktywności po usunięciu Używaj szybkiego, niedokładnego przewijania Niedokładne przewijanie umożliwia szybsze przewijanie ze zmniejszoną dokładnością. Przewijanie o 5, 15 lub 25 sekund nie działa w tym przypadku - Wczytuj miniatury - Wyłącz, aby nie wczytywać miniatur, oszczędzając dane i zużycie pamięci. Zmiana tej opcji czyści pamięć podręczną obrazów Wyczyszczono pamięć podręczną miniatur Wyczyść pamięć podręczną metadanych Usuwa całą pamięć podręczną stron diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 831adfe9e..c344fa826 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -284,14 +284,12 @@ Tenha em mente que esta operação poderá consumir muitos dados. \n \nVocê deseja continuar\? - Carregar miniaturas Cache de imagens limpo Limpar cache de metadados Remove todos os dados de páginas em cache Cache de metadados limpo Controles de velocidade de reprodução Velocidade - Desative para não carregar miniaturas e economizar no uso de dados e memória. A alteração limpa todo o cache de imagens em memória e em disco Afinação Desvincular (pode causar distorção) Ação de \'abrir\' preferida diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 24a8185db..dc3c8e48c 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -137,7 +137,6 @@ Mostrar resoluções mais altas Sem subscritores Utilizar reprodutor de áudio externo - Desative para parar o carregamento de miniaturas, poupar dados e utilização da memória. As alterações limpam a cache de imagens do disco e da memória Será que queria dizer \"%1$s\"\? Mostrar uma notificação para pedir a atualização da aplicação se existir uma nova versão Enfileirar @@ -442,7 +441,6 @@ Formato padrão de áudio O ficheiro não existe ou não tem permissões para ler e/ou escrever O nome do grupo está vazio - Carregar miniaturas Partilhar com Tempo após a última atualização antes de a subscrição ser considerada desatualizada - %s Pesquisar diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 87b475a8b..c3c981fad 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -204,8 +204,6 @@ Adicionar a Utilizar pesquisa rápida Este tipo de pesquisa e mais rápida mas reduz a precisão. Procurar por 5, 15 ou 25 segundos não funciona corretamente - Carregar miniaturas - Desative para parar o carregamento de miniaturas, poupar dados e utilização da memória. As alterações limpam a cache de imagens do disco e da memória Cache de imagens limpa País padrão para conteúdo Depuração diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index ad379c5ca..0a6920b6b 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -181,8 +181,6 @@ Salvare în Folosește parcurgerea rapidă inexactă Derularea inexactă permite player-ului să deruleze mai rapid, cu o precizie redusă. Derularea timp de 5, 15 sau 25 de secunde nu funcționează cu aceasta - Încarcă miniaturi - Dezactivați pentru a preveni încărcarea miniaturilor, economisirea datelor și utilizarea memoriei. Modificările șterg atât memoria cache a imaginilor în memorie, cât și pe disc Datele cache de imagini au fost șterse Șterge cache-ul pentru metadata Șterge cache-ul pentru datele de pagini web diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f033b6cf6..4b03f15c7 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -298,8 +298,6 @@ Это действие может вызвать большой расход трафика. \n \nПродолжить? - Загружать миниатюры - Отключите, чтобы не загружать миниатюры и сэкономить трафик и память. Изменение настройки очистит кэш изображений Кэш изображений очищен Очистить кэш метаданных Кэш метаданных очищен diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 2f44a8664..7846eb274 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -473,10 +473,8 @@ Boga totu sos datos de sa pàgina web in sa memòria temporànea Iscantzella sos metadatos in sa memòria temporànea Memòria temporànea de sas immàgines isboidada - Istuda pro prevènnere su carrigamentu de sas miniaduras, su sarvamentu de sos datos e s\'impreu de sa memòria. Sas modìficas ant a isbodiare siat sa memòria temporànea de sa memòria siat cussa de su discu Istuda pro cuare sos cummentos Ammustra sos cummentos - Càrriga sas miniaduras Longària de s\'avantzamentu e de sa torrada in segus lestros Su moimentu inesatu permitit a su riproduidore de si mòere cara a una positzione in manera prus lestra ma prus pagu pretzisa. Su de si mòere de 5, 15 o 25 segundos non funtzionat, cun custa optzione Imprea su moimentu inesatu lestru diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 6e218e16c..51f9eb490 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -246,8 +246,6 @@ Zväčšiť Používať rýchly posun Rýchly posun umožňuje prejsť na novú pozíciu rýchlejšie, ale s menšou presnosťou. Posun o 5, 15 alebo 25 sekúnd v tomto prípade nie je možný - Načítanie miniatúr - Vypnutím tejto funkcie sa nebudú vytvárať miniatúry a tým sa ušetrí miesto a pamäť. Zmena nastavení spôsobuje vyčistenie vyrovnávacej pamäte Vyrovnávacia pamäť obrázkov vymazaná Vymazať metadáta uložené vo vyrovnávacej pamäti Odstrániť všetky údaje webových stránok vo vyrovnávacej pamäti diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 7e89a1ed5..be6027620 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -198,7 +198,6 @@ Ustvari Opusti Preimenuj - Naloži sličice Jezik aplikacije Uporabi SAF Vprašaj kam shraniti @@ -309,7 +308,6 @@ Predpomnjeni metapodatki so bili odstranjeni Prikaži meta informacije Onemogoči da se ustavi prikazovanje komentarjev - Izklopite, če želite preprečiti nalaganje sličic, s tem bo varčeval na podatkih in uporabi spomina. Spremembe bodo izbrisale predpomnilnik v spominu in na disku Dejavna vrsta bo zamenjana Preklop na drugi predvajanik lahko zamenja vašo čakalno vrsto Vprašaj za potrditev pred čiščenjem vrste diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml index b2ec76d77..b3f4051c4 100644 --- a/app/src/main/res/values-so/strings.xml +++ b/app/src/main/res/values-so/strings.xml @@ -401,10 +401,8 @@ Tirtir waxyaabaha K/G ah ee boga website-ka Tirtir faahfaahinada yaryar kaydkii kumeelgaadhka ahaa ee sawirka waa la tirtiray - Xidh si aad u joojiso soo bandhiga galka muuqaalada, adigoo yaraynaya isticmalka khadka iyo maskaxda aalada. Wax ka baddalkan wuxuu nadiifin doonaa waxa kaydka hore iyo ka caadiga ah kumeelgaadh ahaan ugu jira Xidh si aad uqariso faallooyinka Tus faallooyinka - Soodhig galalka Hormada daareha hadda wax shidaya waa la baddali doonaa Kala baddalka daareha waxay badali kartaa hormada sidaas darteed waydii in la xaqiijiyo intaan hormada la tirtirin Xaqiijinta tirtirka hormada diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 41d9f22ad..5bfe72573 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -18,7 +18,6 @@ Luaj me Kodi Audio E zezë - Ngarko pamjet miniaturë Sugjerimet e kërkimit Të shikuarat Ruaji videot e shikuara @@ -487,7 +486,6 @@ Depoja e të dhënave meta u boshatis Boshatis depon e të gjitha të dhënave të faqeve të internetit Boshatis depon e të dhënave meta - Fikeni për të ndaluar shfaqjen e pamjeve statike, duke kursyer internet dhe memorje. Ndryshimet boshatisin depon e imazheve në memorje dhe në disk Depoja e imazheve u boshatis Fikeni për të fshehur komentet Shfaq komentet diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 208b7f6e9..b31ee604b 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -201,8 +201,6 @@ Задржи за стављање у ред Користи брзо, непрецизно премотавање Непрецизно премотавање омогућава плејеру да брже долази до позиције уз смањену прецизност. Премотавање за 5, 15 или 25 секунди са овом опцијом не ради - Учитај сличице - Искључите да спречите преузимање сличица, смањујући утрошак преноса података и меморије. Изменом ће се очистити и меморијски и диск кеш Очишћен кеш са сликама Уклони кеширане метаподатке Уклања све податке кешираних веб-страна diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 01b503d3f..02e472e4d 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -193,8 +193,6 @@ Bokmärkta Spellistor Lägg till i Använd snabb icke-exakt sökning - Läs in miniatyrbilder - Stäng av för att förhindra att miniatyrbilder läses in, vilket sparar data- och minnesanvändning. Ändringarna rensar både bildcacheminnet i minnet och på disken Cacheminnet för bilder rensat Debug Alltid diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 0a4f30670..0383d7197 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -50,7 +50,6 @@ கருமை திரைமேல் பண்புகளை நினைவுகொள் திரைமேல் நிலையின் கடைசி அளவையும் இடத்தையும் நினைவுகொள் - சிறுபடத்தைக் இறக்கு பட பதுக்ககம் அழிக்கப்பட்டது மேல்நிலைத்தரவின் பதுக்ககம் அழிக்கப்பட்டது பதுக்ககப்படுத்திய வலைப்பக்கத் தரவை நீக்கு @@ -264,7 +263,6 @@ ப.ல இயக்கியைச் சிதை - சிறுபடங்களேற்றுவதை தவிர்த்து தரவு மற்றும் நினைவகப் பயன்பாட்டைச் சேமிக்க அணை. மாற்றங்கள் நினைவகத்துள் மற்றும் வட்டின்மீதுள்ள பிடிதரவைத் துடைக்கும் பட்டியல்களில் இயக்கக குறியட நிலைகாட்டிகளைக் காட்டு துணையியக்கியில் காணொளிகளை துவக்காதே, ஆனால் தானாக சுழற்றல் பூட்டப்பட்டிருந்தால் நேரடியாக முழுதிரைக்குத் திரும்பு. முழுதிரையை வெளியேறி நீங்கள் இன்னும் துணையியக்கியை அணுகலாம் உரலியை அங்கீகரக்க முடியவில்லை. மற்றொரு செயலியில் திறக்கவா\? diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 2351be263..86f3e17c2 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -165,13 +165,11 @@ అధిక స్పష్టతను చూపుము నలుపు పాప్అప్ లక్షణాలను గుర్తుంచుకో - సూక్ష్మచిత్రాలను లోడ్ చేయండి వ్యాఖ్యలను చూపించు వ్యాఖ్యలను దాచడాన్ని ఆఫ్ చేయండి %sలో మీకు నచ్చిన సందర్భాలను కనుగొనండి పీర్‌ట్యూబ్ ఉదాహరణలు మూడవ చర్య బటన్ - థంబ్‌నెయిల్‌లను లోడ్ చేయడం, డేటాను సేవ్ చేయడం మరియు మెమరీ వినియోగాన్ని నిరోధించడానికి ఆఫ్ చేయండి. మార్పులు ఇన్-మెమరీ మరియు ఆన్-డిస్క్ ఇమేజ్ కాష్ రెండింటినీ క్లియర్ చేస్తాయి ఖచ్చితమైన శోధన తగ్గిన ఖచ్చితత్వంతో వేగంగా స్థానాలను పొందేందుకు ఆటగాడిని అనుమతిస్తుంది. 5, 15 లేదా 25 సెకన్ల పాటు కోరడం దీనితో పని చేయదు వేగవంతమైన ఖచ్చితమైన శోధనను ఉపయోగించండి జోడించండి diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 2b31bb988..17f20c1e4 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -56,10 +56,8 @@ จำขนาดและตำแหน่งสุดท้ายของป๊อปอัพ ใช้การข้ามที่ไม่แม่นยำ การข้ามช่วงที่ไม่แม่นยำจะทำให้เลื่อนไปยังตำแหน่งเวลาที่ต้องการได้เร็วขึ้น แต่จะลดความแม่นยำในการลากตำแหน่งลง - โหลดภาพขนาดย่อ แสดงความคิดเห็น ปิดใช้งานเพื่อซ่อนความคิดเห็น - ปิดเพื่อป้องกันการโหลดรูปขนาดย่อ ลดการใช้ข้อมูลและหน่วยความจำ การเปลี่ยนแปลงล้างแคชภาพในหน่วยความจำและบนดิสก์ ล้างแคชของรูปภาพแล้ว ลบข้อมูลเว็บเพจที่แคชไว้ทั้งหมด คิววีดีโอถัดไปโดยอัตโนมัติ diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 2400a8bd5..28bc92347 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -280,8 +280,6 @@ Bu sürecin ağa yük olabileceğini unutmayın. \n \nSürdürmek istiyor musunuz\? - Küçük resimleri yükle - Küçük resimlerin yüklenmesini önleyerek veri ve hafıza kullanımından tasarruf etmek için kapatın. Değişiklikler, hem bellek içi hem de diskteki resim önbelleğini temizler Resim önbelleği silindi Önbelleğe alınmış üstverileri temizle Önbelleğe alınmış tüm web sayfası verilerini kaldır diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 25b3a43d2..0b024c861 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -292,8 +292,6 @@ Майте на увазі: ця операція може потребувати багато трафіку. \n \nБажаєте продовжити\? - Завантажувати ескізи - Вимкніть для запобігання завантаженню ескізів, що заощадить трафік і внутрішню пам\'ять. Зміни призведуть до очищення кешу зображень Кеш зображень стерто Стерти кеш метаданих Видалити всі кешовані дані вебсторінок diff --git a/app/src/main/res/values-und/strings.xml b/app/src/main/res/values-und/strings.xml index f22a117c5..94e4f9dd6 100644 --- a/app/src/main/res/values-und/strings.xml +++ b/app/src/main/res/values-und/strings.xml @@ -118,7 +118,6 @@ کتار نوں خالی کرن توں پہلاں تصویر کرن لئی پچھو پلیئر بدلݨ نال تہاڈی بدل سکدی اے سرگرم پکیئر کتار جاوےگا - تھمنیل لوڈ کرو وہروا دِکھاؤ کھوج دا اتیت ڈیٹا پٹاؤ diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index c05fc095c..9632f5ff4 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -55,8 +55,6 @@ پچھلی جسامت اور پوپ اپ کا مقام یاد رکھیں بالواسطہ رسائی استعمال کریں بالواسطہ تلاش مشکلات کو کم کر کے پلیئر کو تیز رفتاری سے مقامات تک رسائی کرنے دیتی ہے۔ 5 ، 15 یا 25 سیکنڈ کی تلاش اس کے ساتھ کام نہیں کرتی ہے: - نظرِ انگشتی لوڈ کریں - ڈیٹا کی بچت اور میموری کے استعمال کو روکنے کیلئے تھمب نیل کو بند کریں۔ تبدیلیاں میموری اور آن ڈسک ایمیج کیشے کو صاف کریں گی تصویری کیشے کی صفائی ہوئی کیشے میٹا ڈیٹا کو صاف کریں ویب پیج کے سبھی کیشے ڈیٹا کو ہٹا دیں diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 871fb9c12..9609943ca 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -133,8 +133,6 @@ Thêm vào Sử dụng tìm kiếm nhanh không chính xác Tua không chính xác cho phép trình phát tua đến các vị trí nhanh hơn với độ chính xác bị giảm. Tua 5, 15 hay 25 giây không dùng được với chế độ này - Tải hình thu nhỏ - Tắt để ngăn chặn việc tải các hình thu nhỏ, việc này sẽ tiết kiệm lưu lượng mạng và bộ nhớ. Các thay đổi sẽ xóa bộ nhớ đệm hình ảnh cả trong RAM và trong bộ nhớ Đã xóa bộ nhớ cache hình ảnh Xóa siêu dữ liệu đã lưu vào bộ nhớ cache Xóa tất cả dữ liệu trang web được lưu trong bộ nhớ cache diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9a888c74d..d1d91dcd2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -46,7 +46,6 @@ 仅一次 添加至 文件 - 加载封面 清空播放历史 最小化至后台播放 @@ -310,7 +309,6 @@ 该操作消耗大量流量, \n \n你想继续吗? - 关闭可禁止加载封面,节省流量和内存使用。切换该选项将立即清除内存与存储中的图片缓存 清空图像缓存成功 清空已缓存的元数据 清空已缓存的网页数据 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index b465d887d..91f2f3fc8 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -159,7 +159,6 @@ 撳下面嘅掣去更改對應嘅通知動作。用右手邊嘅格仔剔選最多三個,擺喺精簡通知度 精簡通知最多淨係擺到三個動作! 循環播放 - 載入縮圖 顯示留言 關閉去隱藏留言 搜尋紀錄 @@ -168,7 +167,6 @@ 顯示描述 抹除咗影像快取 移除所有網頁嘅快取資料 - 關閉佢去避免載入條片嘅縮圖,慳返啲數據同埋用少啲 RAM。更改會抹走記憶體以及磁碟機上面嘅影像快取 粗略嘅快轉允許播放器比較籠統咁快轉去其他位置。快轉 5、15 或 25 秒就太仔細,做唔到 播放器 預設嘅國家內容 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 8eb964406..225e4562f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -278,8 +278,6 @@ \n2. 移至此網址: %1$s \n3. 當被提示時登入帳號 \n4. 複製您被重新導向到的個人設定檔網址。 - 載入縮圖 - 關閉以防止載入縮圖,減少數據和儲存空間的用量。改變時將清除記憶體和磁碟上的縮圖快取 已抹除圖片快取 抹除已快取的中介資料 移除所有已快取的網頁資料 diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 51abe14fb..19188bb6c 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -396,8 +396,6 @@ clear_cookie - download_thumbnail_key - cache_wipe_key clear_play_history clear_playback_states @@ -1433,4 +1431,24 @@ media_tunneling_device_blacklist_version use_exoplayer_decoder_fallback_key always_use_exoplayer_set_output_surface_workaround_key + + + image_quality_key + image_quality_none + image_quality_low + image_quality_medium + image_quality_high + @string/image_quality_medium_key + + @string/image_quality_none + @string/image_quality_low + @string/image_quality_medium + @string/image_quality_high + + + @string/image_quality_none_key + @string/image_quality_low_key + @string/image_quality_medium_key + @string/image_quality_high_key + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e5bbffaff..705a84aab 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,8 +85,6 @@ The active player queue will be replaced Ignore hardware media button events Useful, for instance, if you are using a headset with broken physical buttons - Load thumbnails - Turn off to prevent loading thumbnails, saving data and memory usage. Changes clear both in-memory and on-disk image cache Show comments Turn off to hide comments Show \'Next\' and \'Similar\' videos @@ -822,4 +820,10 @@ Duration Rewind Forward + Image quality + Choose the quality of images and whether to load images at all, to reduce data and memory usage. Changes clear both in-memory and on-disk image cache — %s + Do not load images + Low quality + Medium quality + High quality \ No newline at end of file diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index 73a849af7..45f187452 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -85,11 +85,13 @@ app:singleLineTitle="false" app:iconSpaceReserved="false" /> - From 35073c780d21cba874893b5f75d9e9d99236a1e8 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 12:30:27 +0200 Subject: [PATCH 03/13] Implement better image selection strategy --- app/src/main/java/org/schabi/newpipe/App.java | 3 +- .../database/playlist/PlaylistStreamEntry.kt | 4 +- .../playlist/model/PlaylistRemoteEntity.java | 6 +- .../database/stream/StreamStatisticsEntry.kt | 4 +- .../database/stream/model/StreamEntity.kt | 10 +- .../subscription/SubscriptionEntity.java | 6 +- .../fragments/detail/DescriptionFragment.java | 4 +- .../list/channel/ChannelAboutFragment.java | 6 +- .../list/channel/ChannelFragment.java | 7 +- .../holder/CommentsMiniInfoItemHolder.java | 3 +- .../subscription/SubscriptionFragment.kt | 4 +- .../local/subscription/SubscriptionManager.kt | 6 +- .../player/mediaitem/ExceptionTag.java | 4 +- .../player/mediaitem/StreamInfoTag.java | 4 +- .../mediasession/PlayQueueNavigator.java | 4 +- .../settings/ContentSettingsFragment.java | 3 +- .../external_communication/ShareUtils.java | 7 +- .../newpipe/util/image/ImageStrategy.java | 115 ++++++++++++++++++ .../newpipe/util/image/PicassoHelper.java | 50 +------- 19 files changed, 161 insertions(+), 89 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index b394c7039..ee352ae4a 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -20,6 +20,7 @@ import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.ktx.ExceptionUtils; import org.schabi.newpipe.settings.NewPipeSettings; import org.schabi.newpipe.util.Localization; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.StateSaver; @@ -100,7 +101,7 @@ public class App extends Application { // Initialize image loader final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); PicassoHelper.init(this); - PicassoHelper.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this, + ImageStrategy.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this, prefs.getString(getString(R.string.image_quality_key), getString(R.string.image_quality_default)))); PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt index e7db1d603..47dc1d06a 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity import org.schabi.newpipe.extractor.stream.StreamInfoItem -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy data class PlaylistStreamEntry( @Embedded @@ -29,7 +29,7 @@ data class PlaylistStreamEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) + item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) return item } 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 569f6721c..5e8977821 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 @@ -11,7 +11,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.util.Constants; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import static org.schabi.newpipe.database.LocalItem.LocalItemType.PLAYLIST_REMOTE_ITEM; import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME; @@ -70,7 +70,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { @Ignore public PlaylistRemoteEntity(final PlaylistInfo info) { this(info.getServiceId(), info.getName(), info.getUrl(), - PicassoHelper.choosePreferredImage(info.getThumbnails()), + ImageStrategy.choosePreferredImage(info.getThumbnails()), info.getUploaderName(), info.getStreamCount()); } @@ -85,7 +85,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { && TextUtils.equals(getName(), info.getName()) && TextUtils.equals(getUrl(), info.getUrl()) && TextUtils.equals(getThumbnailUrl(), - PicassoHelper.choosePreferredImage(info.getThumbnails())) + ImageStrategy.choosePreferredImage(info.getThumbnails())) && TextUtils.equals(getUploader(), info.getUploaderName()); } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt index 6d005351d..81e17b720 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.history.model.StreamHistoryEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS import org.schabi.newpipe.extractor.stream.StreamInfoItem -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy import java.time.OffsetDateTime class StreamStatisticsEntry( @@ -31,7 +31,7 @@ class StreamStatisticsEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) + item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) return item } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt index bb2c0e0d7..4eecc9373 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt @@ -13,7 +13,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.player.playqueue.PlayQueueItem -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy import java.io.Serializable import java.time.OffsetDateTime @@ -68,7 +68,7 @@ data class StreamEntity( constructor(item: StreamInfoItem) : this( serviceId = item.serviceId, url = item.url, title = item.name, streamType = item.streamType, duration = item.duration, uploader = item.uploaderName, - uploaderUrl = item.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, + uploaderUrl = item.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(), isUploadDateApproximation = item.uploadDate?.isApproximation ) @@ -77,7 +77,7 @@ data class StreamEntity( constructor(info: StreamInfo) : this( serviceId = info.serviceId, url = info.url, title = info.name, streamType = info.streamType, duration = info.duration, uploader = info.uploaderName, - uploaderUrl = info.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, + uploaderUrl = info.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(), isUploadDateApproximation = info.uploadDate?.isApproximation ) @@ -87,7 +87,7 @@ data class StreamEntity( serviceId = item.serviceId, url = item.url, title = item.title, streamType = item.streamType, duration = item.duration, uploader = item.uploader, uploaderUrl = item.uploaderUrl, - thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails) + thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails) ) fun toStreamInfoItem(): StreamInfoItem { @@ -95,7 +95,7 @@ data class StreamEntity( item.duration = duration item.uploaderName = uploader item.uploaderUrl = uploaderUrl - item.thumbnails = PicassoHelper.urlToImageList(thumbnailUrl) + item.thumbnails = ImageStrategy.urlToImageList(thumbnailUrl) if (viewCount != null) item.viewCount = viewCount as Long item.textualUploadDate = textualUploadDate diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java index 1f1722814..3fb474423 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java @@ -10,7 +10,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.util.Constants; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_SERVICE_ID; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE; @@ -58,7 +58,7 @@ public class SubscriptionEntity { final SubscriptionEntity result = new SubscriptionEntity(); result.setServiceId(info.getServiceId()); result.setUrl(info.getUrl()); - result.setData(info.getName(), PicassoHelper.choosePreferredImage(info.getAvatars()), + result.setData(info.getName(), ImageStrategy.choosePreferredImage(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); return result; } @@ -139,7 +139,7 @@ public class SubscriptionEntity { @Ignore public ChannelInfoItem toChannelInfoItem() { final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName()); - item.setThumbnails(PicassoHelper.urlToImageList(getAvatarUrl())); + item.setThumbnails(ImageStrategy.urlToImageList(getAvatarUrl())); item.setSubscriberCount(getSubscriberCount()); item.setDescription(getDescription()); return item; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index ff1a01466..60a2a2ed3 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.Localization; import java.util.List; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import icepick.State; @@ -114,7 +114,7 @@ public class DescriptionFragment extends BaseDescriptionFragment { addMetadataItem(inflater, layout, true, R.string.metadata_host, streamInfo.getHost()); addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url, - PicassoHelper.choosePreferredImage(streamInfo.getThumbnails())); + ImageStrategy.choosePreferredImage(streamInfo.getThumbnails())); } private void addPrivacyMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index 5ea25bf15..9a035d0ab 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import java.util.List; @@ -101,8 +101,8 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { } addMetadataItem(inflater, layout, true, R.string.metadata_avatar_url, - PicassoHelper.choosePreferredImage(channelInfo.getAvatars())); + ImageStrategy.choosePreferredImage(channelInfo.getAvatars())); addMetadataItem(inflater, layout, true, R.string.metadata_banner_url, - PicassoHelper.choosePreferredImage(channelInfo.getBanners())); + ImageStrategy.choosePreferredImage(channelInfo.getBanners())); } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 7436f50fd..3ece760ca 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -49,6 +49,7 @@ import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.StateSaver; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; @@ -147,7 +148,7 @@ public class ChannelFragment extends BaseStateFragment setTitle(name); binding.channelTitleView.setText(name); - if (!PicassoHelper.shouldLoadImages()) { + if (!ImageStrategy.shouldLoadImages()) { // do not waste space for the banner if it is not going to be loaded binding.channelBannerImage.setImageDrawable(null); } @@ -354,7 +355,7 @@ public class ChannelFragment extends BaseStateFragment channel.setServiceId(info.getServiceId()); channel.setUrl(info.getUrl()); channel.setData(info.getName(), - PicassoHelper.choosePreferredImage(info.getAvatars()), + ImageStrategy.choosePreferredImage(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); channelSubscription = null; @@ -578,7 +579,7 @@ public class ChannelFragment extends BaseStateFragment currentInfo = result; setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); - if (PicassoHelper.shouldLoadImages() && !result.getBanners().isEmpty()) { + if (ImageStrategy.shouldLoadImages() && !result.getBanners().isEmpty()) { PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG) .into(binding.channelBannerImage); } else { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index 69e1bf5f6..d6a08e6cb 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -31,6 +31,7 @@ import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.text.CommentTextOnTouchListener; @@ -98,7 +99,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { final CommentsInfoItem item = (CommentsInfoItem) infoItem; PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView); - if (PicassoHelper.shouldLoadImages()) { + if (ImageStrategy.shouldLoadImages()) { itemThumbnailView.setVisibility(View.VISIBLE); itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding, commentVerticalPadding, commentVerticalPadding); diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index f84d9865f..ac82d5c91 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -61,7 +61,7 @@ import org.schabi.newpipe.util.OnClickGesture import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels import org.schabi.newpipe.util.external_communication.ShareUtils -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -343,7 +343,7 @@ class SubscriptionFragment : BaseStateFragment() { when (i) { 0 -> ShareUtils.shareText( requireContext(), selectedItem.name, selectedItem.url, - PicassoHelper.choosePreferredImage(selectedItem.thumbnails) + ImageStrategy.choosePreferredImage(selectedItem.thumbnails) ) 1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url) 2 -> deleteChannel(selectedItem) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index 70bac6168..cfd5196be 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.util.ExtractorHelper -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy class SubscriptionManager(context: Context) { private val database = NewPipeDatabase.getInstance(context) @@ -74,7 +74,7 @@ class SubscriptionManager(context: Context) { Completable.fromRunnable { it.setData( info.name, - PicassoHelper.choosePreferredImage(info.avatars), + ImageStrategy.choosePreferredImage(info.avatars), info.description, info.subscriberCount ) @@ -105,7 +105,7 @@ class SubscriptionManager(context: Context) { } else if (info is ChannelInfo) { subscriptionEntity.setData( info.name, - PicassoHelper.choosePreferredImage(info.avatars), + ImageStrategy.choosePreferredImage(info.avatars), info.description, info.subscriberCount ) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java index 9ec6513dc..95a4f74af 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java @@ -3,7 +3,7 @@ package org.schabi.newpipe.player.mediaitem; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import java.util.List; import java.util.Optional; @@ -75,7 +75,7 @@ public final class ExceptionTag implements MediaItemTag { @Override public String getThumbnailUrl() { - return PicassoHelper.choosePreferredImage(item.getThumbnails()); + return ImageStrategy.choosePreferredImage(item.getThumbnails()); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java index a96f49f2f..e24a93615 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java @@ -6,7 +6,7 @@ import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import java.util.Collections; import java.util.List; @@ -96,7 +96,7 @@ public final class StreamInfoTag implements MediaItemTag { @Override public String getThumbnailUrl() { - return PicassoHelper.choosePreferredImage(streamInfo.getThumbnails()); + return ImageStrategy.choosePreferredImage(streamInfo.getThumbnails()); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java index 3e0736f82..f925bff16 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java @@ -20,7 +20,7 @@ import com.google.android.exoplayer2.util.Util; import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import java.util.ArrayList; import java.util.Collections; @@ -139,7 +139,7 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator descBuilder.setExtras(additionalMetadata); final Uri thumbnailUri = Uri.parse( - PicassoHelper.choosePreferredImage(item.getThumbnails())); + ImageStrategy.choosePreferredImage(item.getThumbnails())); if (thumbnailUri != null) { descBuilder.setIconUri(thumbnailUri); } diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 2297e3e93..c7d107acb 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -31,6 +31,7 @@ import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; import org.schabi.newpipe.streams.io.StoredFileHelper; import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ZipHelper; import org.schabi.newpipe.util.image.PreferredImageQuality; @@ -109,7 +110,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { final Preference imageQualityPreference = requirePreference(R.string.image_quality_key); imageQualityPreference.setOnPreferenceChangeListener( (preference, newValue) -> { - PicassoHelper.setPreferredImageQuality(PreferredImageQuality + ImageStrategy.setPreferredImageQuality(PreferredImageQuality .fromPreferenceKey(requireContext(), (String) newValue)); try { PicassoHelper.clearCache(preference.getContext()); 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 8150d4030..fc057de41 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 @@ -24,6 +24,7 @@ import androidx.core.content.FileProvider; import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.Image; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import java.io.File; @@ -251,7 +252,7 @@ public final class ShareUtils { // If loading of images has been disabled, don't try to generate a content preview if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !TextUtils.isEmpty(imagePreviewUrl) - && PicassoHelper.shouldLoadImages()) { + && ImageStrategy.shouldLoadImages()) { final ClipData clipData = generateClipDataForImagePreview(context, imagePreviewUrl); if (clipData != null) { @@ -276,14 +277,14 @@ public final class ShareUtils { * @param title the title of the content * @param content the content to share * @param images a set of possible {@link Image}s of the subject, among which to choose with - * {@link PicassoHelper#choosePreferredImage(List)} since that's likely to + * {@link ImageStrategy#choosePreferredImage(List)} since that's likely to * provide an image that is in Picasso's cache */ public static void shareText(@NonNull final Context context, @NonNull final String title, final String content, final List images) { - shareText(context, title, content, PicassoHelper.choosePreferredImage(images)); + shareText(context, title, content, ImageStrategy.choosePreferredImage(images)); } /** 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 new file mode 100644 index 000000000..5de0b52f4 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java @@ -0,0 +1,115 @@ +package org.schabi.newpipe.util.image; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.schabi.newpipe.extractor.Image; + +import java.util.Comparator; +import java.util.List; + +public final class ImageStrategy { + + // the height thresholds also used by the extractor (TODO move them to the extractor) + private static final int LOW_MEDIUM = 175; + private static final int MEDIUM_HIGH = 720; + + private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; + + private ImageStrategy() { + } + + public static void setPreferredImageQuality(final PreferredImageQuality preferredImageQuality) { + ImageStrategy.preferredImageQuality = preferredImageQuality; + } + + public static boolean shouldLoadImages() { + return preferredImageQuality != PreferredImageQuality.NONE; + } + + + private static double estimatePixelCount(final Image image, + final double widthOverHeight, + final boolean unknownsLast) { + if (image.getHeight() == Image.HEIGHT_UNKNOWN) { + if (image.getWidth() == Image.WIDTH_UNKNOWN) { + switch (image.getEstimatedResolutionLevel()) { + case LOW: + return unknownsLast + ? (LOW_MEDIUM - 1) * (LOW_MEDIUM - 1) * widthOverHeight + : 0; + case MEDIUM: + return unknownsLast + ? (MEDIUM_HIGH - 1) * (MEDIUM_HIGH - 1) * widthOverHeight + : LOW_MEDIUM * LOW_MEDIUM * widthOverHeight; + case HIGH: + return unknownsLast + ? 1e20 // less than 1e21 to prefer over fully unknown image sizes + : MEDIUM_HIGH * MEDIUM_HIGH * widthOverHeight; + default: + case UNKNOWN: + // images whose size is completely unknown will be avoided when possible + return unknownsLast ? 1e21 : -1; + } + + } else { + return image.getWidth() * image.getWidth() / widthOverHeight; + } + + } else if (image.getWidth() == Image.WIDTH_UNKNOWN) { + return image.getHeight() * image.getHeight() * widthOverHeight; + + } else { + return image.getHeight() * image.getWidth(); + } + } + + @Nullable + public static String choosePreferredImage(@NonNull final List images) { + if (preferredImageQuality == PreferredImageQuality.NONE) { + return null; // do not load images + } + + final double widthOverHeight = images.stream() + .filter(image -> image.getHeight() != Image.HEIGHT_UNKNOWN + && image.getWidth() != Image.WIDTH_UNKNOWN) + .mapToDouble(image -> ((double) image.getWidth()) / image.getHeight()) + .findFirst() + .orElse(1.0); + + final Comparator comparator; + switch (preferredImageQuality) { + case LOW: + comparator = Comparator.comparingDouble( + image -> estimatePixelCount(image, widthOverHeight, true)); + break; + default: + case MEDIUM: + comparator = Comparator.comparingDouble(image -> { + final double pixelCount = estimatePixelCount(image, widthOverHeight, true); + final double mediumHeight = (LOW_MEDIUM + MEDIUM_HIGH) / 2.0; + return Math.abs(pixelCount - mediumHeight * mediumHeight * widthOverHeight); + }); + break; + case HIGH: + comparator = Comparator.comparingDouble( + image -> estimatePixelCount(image, widthOverHeight, false)) + .reversed(); + break; + } + + return images.stream() + .min(comparator) + .map(Image::getUrl) + .orElse(null); + } + + @NonNull + public static List urlToImageList(@Nullable final String url) { + if (url == null) { + return List.of(); + } else { + return List.of(new Image(url, -1, -1, Image.ResolutionLevel.UNKNOWN)); + } + } +} 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 3177e83f4..ccf7c3737 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 @@ -2,13 +2,13 @@ package org.schabi.newpipe.util.image; import static org.schabi.newpipe.MainActivity.DEBUG; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; +import static org.schabi.newpipe.util.image.ImageStrategy.choosePreferredImage; import android.annotation.SuppressLint; 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; @@ -21,11 +21,9 @@ import com.squareup.picasso.Transformation; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.Image; -import org.schabi.newpipe.extractor.Image.ResolutionLevel; import java.io.File; import java.io.IOException; -import java.util.Comparator; import java.util.List; import java.util.concurrent.TimeUnit; @@ -46,7 +44,6 @@ public final class PicassoHelper { @SuppressLint("StaticFieldLeak") private static Picasso picassoInstance; - private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; public static void init(final Context context) { picassoCache = new LruCache(10 * 1024 * 1024); @@ -92,14 +89,6 @@ public final class PicassoHelper { picassoInstance.setIndicatorsEnabled(enabled); // useful for debugging } - public static void setPreferredImageQuality(final PreferredImageQuality preferredImageQuality) { - PicassoHelper.preferredImageQuality = preferredImageQuality; - } - - public static boolean shouldLoadImages() { - return preferredImageQuality != PreferredImageQuality.NONE; - } - public static RequestCreator loadAvatar(final List images) { return loadImageDefault(images, R.drawable.placeholder_person); @@ -227,41 +216,4 @@ public final class PicassoHelper { return requestCreator; } } - - @Nullable - public static String choosePreferredImage(final List images) { - final Comparator comparator; - switch (preferredImageQuality) { - case NONE: - return null; - case HIGH: - comparator = Comparator.comparingInt(Image::getHeight).reversed(); - break; - default: - case MEDIUM: - comparator = Comparator.comparingInt(image -> Math.abs(image.getHeight() - 450)); - break; - case LOW: - comparator = Comparator.comparingInt(Image::getHeight); - break; - } - - return images.stream() - .filter(image -> image.getEstimatedResolutionLevel() != ResolutionLevel.UNKNOWN) - .min(comparator) - .map(Image::getUrl) - .orElseGet(() -> images.stream() - .findAny() - .map(Image::getUrl) - .orElse(null)); - } - - @NonNull - public static List urlToImageList(@Nullable final String url) { - if (url == null) { - return List.of(); - } else { - return List.of(new Image(url, -1, -1, ResolutionLevel.UNKNOWN)); - } - } } From 4f7d2067368c058314a7b7cd176486b861a07134 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 18:56:02 +0200 Subject: [PATCH 04/13] Display all thumbnails in description tab --- .../detail/BaseDescriptionFragment.java | 75 +++++++++++++++++++ .../fragments/detail/DescriptionFragment.java | 10 ++- .../list/channel/ChannelAboutFragment.java | 9 +-- app/src/main/res/values-ar/strings.xml | 1 - app/src/main/res/values-az/strings.xml | 1 - app/src/main/res/values-be/strings.xml | 1 - app/src/main/res/values-bg/strings.xml | 1 - app/src/main/res/values-bn/strings.xml | 1 - app/src/main/res/values-ca/strings.xml | 1 - app/src/main/res/values-ckb/strings.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-da/strings.xml | 1 - app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-el/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-et/strings.xml | 1 - app/src/main/res/values-eu/strings.xml | 1 - app/src/main/res/values-fa/strings.xml | 1 - app/src/main/res/values-fi/strings.xml | 1 - app/src/main/res/values-fil/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-gl/strings.xml | 1 - app/src/main/res/values-he/strings.xml | 1 - app/src/main/res/values-hi/strings.xml | 1 - app/src/main/res/values-hr/strings.xml | 1 - app/src/main/res/values-hu/strings.xml | 1 - app/src/main/res/values-in/strings.xml | 1 - app/src/main/res/values-is/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-ka/strings.xml | 1 - app/src/main/res/values-ko/strings.xml | 1 - app/src/main/res/values-lt/strings.xml | 1 - app/src/main/res/values-lv/strings.xml | 1 - app/src/main/res/values-ml/strings.xml | 1 - app/src/main/res/values-nb-rNO/strings.xml | 1 - app/src/main/res/values-nl/strings.xml | 1 - app/src/main/res/values-or/strings.xml | 1 - app/src/main/res/values-pa/strings.xml | 1 - app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-pt-rPT/strings.xml | 1 - app/src/main/res/values-pt/strings.xml | 1 - app/src/main/res/values-ro/strings.xml | 1 - app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values-sc/strings.xml | 1 - app/src/main/res/values-sk/strings.xml | 1 - app/src/main/res/values-so/strings.xml | 1 - app/src/main/res/values-sq/strings.xml | 1 - app/src/main/res/values-sr/strings.xml | 1 - app/src/main/res/values-sv/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-uk/strings.xml | 1 - app/src/main/res/values-vi/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rHK/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 8 +- 58 files changed, 91 insertions(+), 65 deletions(-) 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 ae334b761..2bd5906bc 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 @@ -4,7 +4,13 @@ import static android.text.TextUtils.isEmpty; import static org.schabi.newpipe.extractor.utils.Utils.isBlank; import static org.schabi.newpipe.util.text.TextLinkifier.SET_LINK_MOVEMENT_METHOD; +import android.graphics.Typeface; import android.os.Bundle; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.text.style.StyleSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -23,10 +29,12 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.databinding.FragmentDescriptionBinding; import org.schabi.newpipe.databinding.ItemMetadataBinding; import org.schabi.newpipe.databinding.ItemMetadataTagsBinding; +import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.text.TextLinkifier; import java.util.List; @@ -176,6 +184,73 @@ public abstract class BaseDescriptionFragment extends BaseFragment { layout.addView(itemBinding.getRoot()); } + private String imageSizeToText(final int heightOrWidth) { + if (heightOrWidth < 0) { + return "?"; + } else { + return String.valueOf(heightOrWidth); + } + } + + protected void addImagesMetadataItem(final LayoutInflater inflater, + final LinearLayout layout, + @StringRes final int type, + final List images) { + final String preferredImageUrl = ImageStrategy.choosePreferredImage(images); + if (preferredImageUrl == null) { + return; // null will be returned in case there is no image + } + + final ItemMetadataBinding itemBinding = + ItemMetadataBinding.inflate(inflater, layout, false); + itemBinding.metadataTypeView.setText(type); + + final SpannableStringBuilder urls = new SpannableStringBuilder(); + for (final Image image : images) { + if (urls.length() != 0) { + urls.append(", "); + } + final int entryBegin = urls.length(); + + if (image.getHeight() != Image.HEIGHT_UNKNOWN + || image.getWidth() != Image.WIDTH_UNKNOWN + // if even the resolution level is unknown, ?x? will be shown + || image.getEstimatedResolutionLevel() == Image.ResolutionLevel.UNKNOWN) { + urls.append(imageSizeToText(image.getHeight())); + urls.append('x'); + urls.append(imageSizeToText(image.getWidth())); + } else { + switch (image.getEstimatedResolutionLevel()) { + case LOW: + urls.append(getString(R.string.image_quality_low)); + break; + case MEDIUM: + urls.append(getString(R.string.image_quality_medium)); + break; + case HIGH: + urls.append(getString(R.string.image_quality_high)); + break; + } + } + + urls.setSpan(new ClickableSpan() { + @Override + public void onClick(@NonNull final View widget) { + ShareUtils.openUrlInBrowser(requireContext(), image.getUrl()); + } + }, entryBegin, urls.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + if (preferredImageUrl.equals(image.getUrl())) { + urls.setSpan(new StyleSpan(Typeface.BOLD), entryBegin, urls.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + + itemBinding.metadataContentView.setText(urls); + itemBinding.metadataContentView.setMovementMethod(LinkMovementMethod.getInstance()); + layout.addView(itemBinding.getRoot()); + } + private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { final List tags = getTags(); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index 60a2a2ed3..ada12fc8e 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -17,7 +17,6 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.Localization; import java.util.List; -import org.schabi.newpipe.util.image.ImageStrategy; import icepick.State; @@ -113,8 +112,13 @@ public class DescriptionFragment extends BaseDescriptionFragment { streamInfo.getSupportInfo()); addMetadataItem(inflater, layout, true, R.string.metadata_host, streamInfo.getHost()); - addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url, - ImageStrategy.choosePreferredImage(streamInfo.getThumbnails())); + + addImagesMetadataItem(inflater, layout, R.string.metadata_thumbnails, + streamInfo.getThumbnails()); + addImagesMetadataItem(inflater, layout, R.string.metadata_uploader_avatars, + streamInfo.getUploaderAvatars()); + addImagesMetadataItem(inflater, layout, R.string.metadata_subchannel_avatars, + streamInfo.getSubChannelAvatars()); } private void addPrivacyMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index 9a035d0ab..56418800d 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -17,7 +17,6 @@ import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.image.ImageStrategy; import java.util.List; @@ -100,9 +99,9 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { Localization.localizeNumber(context, channelInfo.getSubscriberCount())); } - addMetadataItem(inflater, layout, true, R.string.metadata_avatar_url, - ImageStrategy.choosePreferredImage(channelInfo.getAvatars())); - addMetadataItem(inflater, layout, true, R.string.metadata_banner_url, - ImageStrategy.choosePreferredImage(channelInfo.getBanners())); + addImagesMetadataItem(inflater, layout, R.string.metadata_avatars, + channelInfo.getAvatars()); + addImagesMetadataItem(inflater, layout, R.string.metadata_banners, + channelInfo.getBanners()); } } diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 0c9f2c74c..78b59d4f9 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -642,7 +642,6 @@ خاص غير مدرج عامة - رابط الصورة المصغرة المضيف الدعم اللغة diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 06273f9cf..1b8109b41 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -629,7 +629,6 @@ Sahib Siyahıdan kənar Şəxsi - Miniatür URL Yaş həddi Dil İctimai diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index e176d2bc9..f79db16a8 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -698,7 +698,6 @@ Тэгі Ліцэнзія Хост - URL мініяцюры Не ў спісе Прыватная , diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 59091553d..56dfb9a9a 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -422,7 +422,6 @@ Поддръжка Сървър Публичен - Миниатюра линк Език на интерфейса Спри звука пост-обработката diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index d3f3a845b..24eed9eb0 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -548,7 +548,6 @@ প্রক্রিয়াকরণ ফিডে ত্রুটি ওয়েবসাইট খুলুন অ্যাকাউন্ট ধ্বংসকৃত - প্রতিচ্ছবি সংযোগ বয়সসীমা অভ্যন্তরীণ ব্যক্তিগত diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index bd3a5c61b..8ee3d6df4 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -600,7 +600,6 @@ Privat Descatalogat Públic - URL de la miniatura Amfitrió Suport Idioma diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml index bae9fb822..841edef63 100644 --- a/app/src/main/res/values-ckb/strings.xml +++ b/app/src/main/res/values-ckb/strings.xml @@ -588,7 +588,6 @@ تایبەتی خشتەنەکراو گشتی - بەستەری وێنۆچکە هۆست پشتگیری زمان diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index dab312d3b..1864f3c65 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -613,7 +613,6 @@ Soukromé Neuvedeno v seznamu Veřejné - URL miniatury Server Podpora Jazyk diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index ef6197414..59e112918 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -669,7 +669,6 @@ \nAktiver systemet mappevælger (SAF), hvis du vil downloade til et eksternt SD-kort Originaltekster fra tjenester vil være synlige i stream-emner Ingen videostreams er tilgængelige for eksterne afspillere - URL til miniaturebillede Fra Tablet-tilstand Denne video er kun tilgængelig for YouTube Music Premium-medlemmer, så den kan ikke streames eller downloades af NewPipe. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e9b710c63..01aa2de34 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -615,7 +615,6 @@ Schlagwörter Kategorie Nicht gelistet - Vorschaubild-URL Server Unterstützung Abonnenten diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index ced70b787..ddbc4c28b 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -602,7 +602,6 @@ Ιδιωτικό Εκτός λίστας Δημόσιο - URL εικονιδίου Υποστήριξη Γλώσσα Όριο ηλικίας diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6ffadca81..781325886 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -614,7 +614,6 @@ Privado No listado Público - URL de la miniatura Soporte Lenguaje Límite de edad diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index ab478ec11..de29df8d3 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -584,7 +584,6 @@ Sisemine Privaatne Avalik - Pisipildi URL Kasutajatugi Keel Vanusepiir diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 6003de6fd..fa2c885ed 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -624,7 +624,6 @@ Kontua ezabatu da Jario azkarrak ez du honi buruz informazio gehiagorik ematen. Adin muga - Miniaturaren URL-a Barnekoa Zerrendatu gabea Ostalaria diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 35db56515..341b34102 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -567,7 +567,6 @@ حالت رایانک گشودن پایگاه وب حساب از بین رفت - نشانی بندانگشتی کرانهٔ عمر موارد مرتبط نمایش شرح diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 397f2fef0..34a38ec33 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -595,7 +595,6 @@ Tämä video on ikärajoitettu. \nYouTuben uusien ikärajoitusperiaatteiden mukaisesti NewPipella ei ole pääsyä videoon eikä sitä voida toistaa. Yöteema - Pienoiskuvakkeen osoite Poista käytöstä tekstinvalinta kuvauskentän sisältä Voit nyt valita tekstin kuvauskentän sisältä. Huomioithan, että valintatilan aikana sivu voi vilkkua ja linkit eivät ehkä ole klikattavia. %s tuo tämän syyn: diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index 0fb7a0a1d..28b344af3 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -157,7 +157,6 @@ Lisensya Wika Pribado - URL ng Thumbnail Hindi nakalista Nakapatay Bago at patok diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 51f258166..bab3f6f47 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -616,7 +616,6 @@ Privé Non répertorié Public - URL de la miniature Hôte Support Langue diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 8b5aaa497..957415790 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -547,7 +547,6 @@ Interno Privado Público - URL da miniatura Apoio Idioma Límite de idade diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 4dec4c819..6d067e5e5 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -622,7 +622,6 @@ פרטי לא מופיע ברשימות ציבורי - כתובת תמונה ממוזערת אירוח תמיכה שפה diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 80ab6209c..5d2d3be10 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -616,7 +616,6 @@ ऐप को क्रैश करें श्रेणी आपसे पूछा जाएगा कि प्रत्येक डाउनलोड को कहां सहेजना है - थंमनेल यूआरएल ऑफ़ हमेशा अपडेट करें विवरण में पाठ का चयन अक्षम करें diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index c625955f7..cea08931d 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -616,7 +616,6 @@ Privatno Nenavedeno Javno - URL sličice Poslužitelj Podrška Jezik diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 26f4ee3cf..264eb2c86 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -605,7 +605,6 @@ Licenc Korhatár Kiszolgáló - Bélyegkép URL Nyilvános Nem listázott Ki diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index b68b36a47..9961a71c6 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -592,7 +592,6 @@ Privasi Tidak didaftar Publik - Alamat URL gambar mini/thumbnail Host Dukungan Bahasa diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 98f73e294..50d8b2220 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -485,7 +485,6 @@ Frá %s Reikningi lokað Aldurstakmark - Vefslóð smámyndar Fest ummæli Spjaldtölvuhamur Virkt diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 48cc84328..5408fe7ec 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -612,7 +612,6 @@ Privato Non in elenco Pubblico - URL copertina Host Supporto Lingua diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 8fa73a002..65280130d 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -600,7 +600,6 @@ 言語 サポート ホスト - サムネイルの URL ウェブサイトを開く ダウンロードのたびに保存する場所を尋ねます ダウンロードフォルダーがまだ設定されていません。今すぐデフォルトのフォルダーを選択してください diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 47e105183..0c663ac49 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -565,7 +565,6 @@ Ასაკობრივი შეზღუდვა Ენა მასპინძელი - მინიატურების URL საჯარო დამალული პირადი diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 30c381bcf..057118bef 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -625,7 +625,6 @@ 창작자의 마음 비공개 비공개 - 썸네일 URL 호스트 이제 이 채널을 구독했습니다 알림 받기 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 58b25709b..b6264fbf5 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -617,7 +617,6 @@ Viešas Privatus Neįtrauktas į sąrašą - Paveikslėlio URL Serveris Pagalba Kalba diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index a613dd70a..c312062b1 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -653,7 +653,6 @@ Zemas kvalitātes (mazāks) Privātums Sarakstā neiekļauts - Video attēla URL Uzņēmums Attālinātie meklēšanas ieteikumi Atzīmēt kā skatītu diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index d03ae0a38..3687a325e 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -609,7 +609,6 @@ സ്വകാര്യം ലിസ്റ്റ് ചെയ്യപ്പെടാത്തത് പൊതുവായത് - ചെറുചിത്രം URL ഹോസ്റ്റ് പിന്തുണ ഭാഷ diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 1637fe1f7..ae503b551 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -621,7 +621,6 @@ Privat Ulistet Offentlig - Miniatyrbilde-nettadresse Tjener Støtte Språk diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index e5b7f0f82..564ca873a 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -600,7 +600,6 @@ Privé Niet vermeld Openbaar - Miniatuur-URL Host Ondersteuning Taal diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index 519a0f199..fdbe665a5 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -419,7 +419,6 @@ ଟୋଗଲ୍ ସେବା, ବର୍ତ୍ତମାନ ମନୋନୀତ: ଫେରସ୍ତ କର ଓଭର୍ ରାଇଟ୍ କରନ୍ତୁ - ଥମ୍ବନେଲ୍ URL ହୋଷ୍ଟ ସାର୍ଵଜନୀନ ତାଲିକାଭୁକ୍ତ ନୁହେଁ diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 253a87740..521931aae 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -441,7 +441,6 @@ ਨਿੱਜੀ (ਪ੍ਰਾਈਵੇਟ) ਗੈਰ-ਸੂਚੀਬੱਧ ਜਨਤਕ - ਥੰਮਨੇਲ URL ਮੇਜ਼ਬਾਨ ਸਹਾਇਤਾ ਭਾਸ਼ਾ/ਬੋਲੀ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b250901ff..9df249f39 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -619,7 +619,6 @@ Wewnętrzny Prywatny Publiczny - Adres URL miniatury Host Wsparcie Język diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index c344fa826..7fec3d54c 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -613,7 +613,6 @@ Não Listado Público Limite de Idade - URL da Miniatura Hospedado em Suporte Idioma diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index dc3c8e48c..c7897a4a1 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -617,7 +617,6 @@ Privado Não listado Público - URL da miniatura Servidor Apoio Idioma diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index c3c981fad..efa6060d8 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -630,7 +630,6 @@ Privado Não listado Público - URL da miniatura Servidor Apoio Idioma diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 0a6920b6b..5d69144df 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -618,7 +618,6 @@ Privat Nelistat Public - URL miniatură Gazdă Sprijin Limbă diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 4b03f15c7..f54c0318e 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -629,7 +629,6 @@ Приватная Не в списке Публичная - URL миниатюры Сервер Доступность В быстром режиме обновления подробности об этом не предоставляются. diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 7846eb274..1e915a3c0 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -602,7 +602,6 @@ No elencadu Privadu Pùblicu - URL de sa miniadura Istrangiadore Suportu Limba diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 51f9eb490..9d6117bb9 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -611,7 +611,6 @@ Interné Súkromné Nezaradené - URL miniatúry Verejné Hostiteľ Podpora diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml index b3f4051c4..f36983526 100644 --- a/app/src/main/res/values-so/strings.xml +++ b/app/src/main/res/values-so/strings.xml @@ -602,7 +602,6 @@ Gaar ah Aan liistada kujirin Lawada arko - Tixraaca galka Martigaliye Taageero Luuqada diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 5bfe72573..ab5b914fe 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -587,7 +587,6 @@ Private E palistuar Publike - URL e pamjes statike Mundësuesi Mbështetje Gjuha diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index b31ee604b..ddb07544b 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -612,7 +612,6 @@ лично ненаведено јавно - УРЛ сличице Домаћин Подршка Језик diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 02e472e4d..939f5aa5c 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -628,7 +628,6 @@ Aktuellt Natt-tema Aviseringar för videohashningsframsteg - Miniatyrbild-webbadress Inaktivera medietunnel om du upplever en svart skärm eller att videouppspelningen hackar. Inaktivera medietunnel Hjärtmärkt av innehållsskaparen diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 28bc92347..52f4d7697 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -601,7 +601,6 @@ Gizli Listelenmemiş Herkese Açık - Küçük Resim URL\'si Konakçı Destek Dil diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 0b024c861..d65e1e435 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -618,7 +618,6 @@ Публічне Приватне Поза списком - URL мініатюри Власник Підтримка Мова diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 9609943ca..7f38d3c34 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -596,7 +596,6 @@ Riêng tư Chưa được liệt kê Công khai - URL hình thu nhỏ Nơi chứa Hỗ trợ Ngôn ngữ diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d1d91dcd2..b663b1953 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -593,7 +593,6 @@ 私享 未分类 公开 - 缩略图 URL 所在服务器 支持 语言 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 91f2f3fc8..01eb91a8c 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -508,7 +508,6 @@ 分類 標籤 公開設定 - 縮圖 URL 公開 憑網址瀏覽 置頂留言 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 225e4562f..18d67f34f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -592,7 +592,6 @@ 私人 未列出 公開 - 縮圖 URL 主機 支援 語言 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 705a84aab..2ccc6a412 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -753,9 +753,11 @@ Language Support Host - Thumbnail URL - Avatar URL - Banner URL + Thumbnails + Uploader avatars + Sub-channel avatars + Avatars + Banners Public Unlisted Private From 8d463b95777ecddca14ff16e5cf9a6a5fd6ae968 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 20:10:52 +0200 Subject: [PATCH 05/13] Further improve image resolution strategy Now using multiple comparison steps instead of magic values --- .../newpipe/util/image/ImageStrategy.java | 108 ++++++++++-------- .../util/image/PreferredImageQuality.java | 15 +++ 2 files changed, 73 insertions(+), 50 deletions(-) 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 5de0b52f4..89e63af3f 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 @@ -1,5 +1,8 @@ package org.schabi.newpipe.util.image; +import static org.schabi.newpipe.extractor.Image.HEIGHT_UNKNOWN; +import static org.schabi.newpipe.extractor.Image.WIDTH_UNKNOWN; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -10,9 +13,10 @@ import java.util.List; public final class ImageStrategy { - // the height thresholds also used by the extractor (TODO move them to the extractor) - private static final int LOW_MEDIUM = 175; - private static final int MEDIUM_HIGH = 720; + // when preferredImageQuality is LOW or MEDIUM, images are sorted by how close their preferred + // image quality is to these values (H stands for "Height") + private static final int BEST_LOW_H = 75; + private static final int BEST_MEDIUM_H = 250; private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; @@ -28,35 +32,18 @@ public final class ImageStrategy { } - private static double estimatePixelCount(final Image image, - final double widthOverHeight, - final boolean unknownsLast) { - if (image.getHeight() == Image.HEIGHT_UNKNOWN) { - if (image.getWidth() == Image.WIDTH_UNKNOWN) { - switch (image.getEstimatedResolutionLevel()) { - case LOW: - return unknownsLast - ? (LOW_MEDIUM - 1) * (LOW_MEDIUM - 1) * widthOverHeight - : 0; - case MEDIUM: - return unknownsLast - ? (MEDIUM_HIGH - 1) * (MEDIUM_HIGH - 1) * widthOverHeight - : LOW_MEDIUM * LOW_MEDIUM * widthOverHeight; - case HIGH: - return unknownsLast - ? 1e20 // less than 1e21 to prefer over fully unknown image sizes - : MEDIUM_HIGH * MEDIUM_HIGH * widthOverHeight; - default: - case UNKNOWN: - // images whose size is completely unknown will be avoided when possible - return unknownsLast ? 1e21 : -1; - } + static double estimatePixelCount(final Image image, final double widthOverHeight) { + if (image.getHeight() == HEIGHT_UNKNOWN) { + if (image.getWidth() == WIDTH_UNKNOWN) { + // 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() == Image.WIDTH_UNKNOWN) { + } else if (image.getWidth() == WIDTH_UNKNOWN) { return image.getHeight() * image.getHeight() * widthOverHeight; } else { @@ -70,36 +57,57 @@ public final class ImageStrategy { return null; // do not load images } + // this will be used to estimate the pixel count for images where only one of height or + // width are known final double widthOverHeight = images.stream() - .filter(image -> image.getHeight() != Image.HEIGHT_UNKNOWN - && image.getWidth() != Image.WIDTH_UNKNOWN) + .filter(image -> image.getHeight() != HEIGHT_UNKNOWN + && image.getWidth() != WIDTH_UNKNOWN) .mapToDouble(image -> ((double) image.getWidth()) / image.getHeight()) .findFirst() .orElse(1.0); - final Comparator comparator; - switch (preferredImageQuality) { - case LOW: - comparator = Comparator.comparingDouble( - image -> estimatePixelCount(image, widthOverHeight, true)); - break; - default: - case MEDIUM: - comparator = Comparator.comparingDouble(image -> { - final double pixelCount = estimatePixelCount(image, widthOverHeight, true); - final double mediumHeight = (LOW_MEDIUM + MEDIUM_HIGH) / 2.0; - return Math.abs(pixelCount - mediumHeight * mediumHeight * widthOverHeight); - }); - break; - case HIGH: - comparator = Comparator.comparingDouble( - image -> estimatePixelCount(image, widthOverHeight, false)) - .reversed(); - break; - } + final Image.ResolutionLevel preferredLevel = preferredImageQuality.toResolutionLevel(); + final Comparator initialComparator = Comparator + // the first step splits the images into groups of resolution levels + .comparingInt(i -> { + if (i.getEstimatedResolutionLevel() == Image.ResolutionLevel.UNKNOWN) { + return 3; // avoid unknowns as much as possible + } else if (i.getEstimatedResolutionLevel() == preferredLevel) { + return 0; // prefer a matching resolution level + } else if (i.getEstimatedResolutionLevel() == Image.ResolutionLevel.MEDIUM) { + return 1; // the preferredLevel is only 1 "step" away (either HIGH or LOW) + } else { + return 2; // the preferredLevel is the furthest away possible (2 "steps") + } + }) + // then each level's group is further split into two subgroups, one with known image + // size (which is also the preferred subgroup) and the other without + .thenComparing(image -> + image.getHeight() == HEIGHT_UNKNOWN && image.getWidth() == WIDTH_UNKNOWN); + + // The third step chooses, within each subgroup with known image size, the best image based + // on how close its size is to BEST_LOW_H or BEST_MEDIUM_H (with proper units). Subgroups + // without known image size will be left untouched since estimatePixelCount always returns + // the same number for those. + final Comparator finalComparator = switch (preferredImageQuality) { + case NONE -> initialComparator; // unreachable + case LOW -> initialComparator.thenComparingDouble(image -> { + final double pixelCount = estimatePixelCount(image, widthOverHeight); + return Math.abs(pixelCount - BEST_LOW_H * BEST_LOW_H * widthOverHeight); + }); + case MEDIUM -> initialComparator.thenComparingDouble(image -> { + final double pixelCount = estimatePixelCount(image, widthOverHeight); + return Math.abs(pixelCount - BEST_MEDIUM_H * BEST_MEDIUM_H * widthOverHeight); + }); + case HIGH -> initialComparator.thenComparingDouble( + // this is reversed with a - so that the highest resolution is chosen + i -> -estimatePixelCount(i, widthOverHeight)); + }; return images.stream() - .min(comparator) + // using "min" basically means "take the first group, then take the first subgroup, + // then choose the best image, while ignoring all other groups and subgroups" + .min(finalComparator) .map(Image::getUrl) .orElse(null); } diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java b/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java index 9f17082ea..7106359b3 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java @@ -3,6 +3,7 @@ package org.schabi.newpipe.util.image; import android.content.Context; import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.Image; public enum PreferredImageQuality { NONE, @@ -21,4 +22,18 @@ public enum PreferredImageQuality { return MEDIUM; // default to medium } } + + public Image.ResolutionLevel toResolutionLevel() { + switch (this) { + case LOW: + return Image.ResolutionLevel.LOW; + case MEDIUM: + return Image.ResolutionLevel.MEDIUM; + case HIGH: + return Image.ResolutionLevel.HIGH; + default: + case NONE: + return Image.ResolutionLevel.UNKNOWN; + } + } } From bf908f0b7dc44338f24c7a2b3d745070023a8704 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 21:06:12 +0200 Subject: [PATCH 06/13] 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); } From 37af2c87e8a275f8168e76a1dc38cb6a631202b7 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 21:12:32 +0200 Subject: [PATCH 07/13] Fix possible NPE in PlayQueueNavigator --- .../player/mediasession/PlayQueueNavigator.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java index f925bff16..3339869c1 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java @@ -138,10 +138,12 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator .putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, player.getPlayQueue().size()); descBuilder.setExtras(additionalMetadata); - final Uri thumbnailUri = Uri.parse( - ImageStrategy.choosePreferredImage(item.getThumbnails())); - if (thumbnailUri != null) { - descBuilder.setIconUri(thumbnailUri); + try { + descBuilder.setIconUri(Uri.parse( + ImageStrategy.choosePreferredImage(item.getThumbnails()))); + } catch (final Throwable e) { + // no thumbnail available at all, or the user disabled image loading, + // or the obtained url is not a valid `Uri` } return descBuilder.build(); From 87dca0f7ec6a22c8218489cb82454c4d6ed6beb6 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 21:36:11 +0200 Subject: [PATCH 08/13] Separate imageListToDbUrl from choosePreferredImage imageListToDbUrl should be used if the URL is going to be saved to the database, to avoid saving nothing in case at the moment of saving the user preference is to not show images. --- .../database/playlist/PlaylistStreamEntry.kt | 2 +- .../playlist/model/PlaylistRemoteEntity.java | 4 +- .../database/stream/StreamStatisticsEntry.kt | 2 +- .../database/stream/model/StreamEntity.kt | 10 +- .../subscription/SubscriptionEntity.java | 4 +- .../list/channel/ChannelFragment.java | 2 +- .../subscription/SubscriptionFragment.kt | 4 +- .../local/subscription/SubscriptionManager.kt | 4 +- .../newpipe/util/image/ImageStrategy.java | 104 ++++++++++++++---- 9 files changed, 96 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt index 47dc1d06a..1d74c6d31 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt @@ -29,7 +29,7 @@ data class PlaylistStreamEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) + item.thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl) return item } 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 a64f2952c..7c6b4a8b0 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 @@ -71,7 +71,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { public PlaylistRemoteEntity(final PlaylistInfo info) { this(info.getServiceId(), info.getName(), info.getUrl(), // use uploader avatar when no thumbnail is available - ImageStrategy.choosePreferredImage(info.getThumbnails().isEmpty() + ImageStrategy.imageListToDbUrl(info.getThumbnails().isEmpty() ? info.getUploaderAvatars() : info.getThumbnails()), info.getUploaderName(), info.getStreamCount()); } @@ -89,7 +89,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { // 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())) + ImageStrategy.imageListToDbUrl(info.getThumbnails())) && TextUtils.equals(getUploader(), info.getUploaderName()); } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt index 81e17b720..1f3654e7a 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt @@ -31,7 +31,7 @@ class StreamStatisticsEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) + item.thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl) return item } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt index 4eecc9373..d9c160b89 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt @@ -68,7 +68,8 @@ data class StreamEntity( constructor(item: StreamInfoItem) : this( serviceId = item.serviceId, url = item.url, title = item.name, streamType = item.streamType, duration = item.duration, uploader = item.uploaderName, - uploaderUrl = item.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, + uploaderUrl = item.uploaderUrl, + thumbnailUrl = ImageStrategy.imageListToDbUrl(item.thumbnails), viewCount = item.viewCount, textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(), isUploadDateApproximation = item.uploadDate?.isApproximation ) @@ -77,7 +78,8 @@ data class StreamEntity( constructor(info: StreamInfo) : this( serviceId = info.serviceId, url = info.url, title = info.name, streamType = info.streamType, duration = info.duration, uploader = info.uploaderName, - uploaderUrl = info.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, + uploaderUrl = info.uploaderUrl, + thumbnailUrl = ImageStrategy.imageListToDbUrl(info.thumbnails), viewCount = info.viewCount, textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(), isUploadDateApproximation = info.uploadDate?.isApproximation ) @@ -87,7 +89,7 @@ data class StreamEntity( serviceId = item.serviceId, url = item.url, title = item.title, streamType = item.streamType, duration = item.duration, uploader = item.uploader, uploaderUrl = item.uploaderUrl, - thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails) + thumbnailUrl = ImageStrategy.imageListToDbUrl(item.thumbnails) ) fun toStreamInfoItem(): StreamInfoItem { @@ -95,7 +97,7 @@ data class StreamEntity( item.duration = duration item.uploaderName = uploader item.uploaderUrl = uploaderUrl - item.thumbnails = ImageStrategy.urlToImageList(thumbnailUrl) + item.thumbnails = ImageStrategy.dbUrlToImageList(thumbnailUrl) if (viewCount != null) item.viewCount = viewCount as Long item.textualUploadDate = textualUploadDate diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java index 3fb474423..a61a22a84 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java @@ -58,7 +58,7 @@ public class SubscriptionEntity { final SubscriptionEntity result = new SubscriptionEntity(); result.setServiceId(info.getServiceId()); result.setUrl(info.getUrl()); - result.setData(info.getName(), ImageStrategy.choosePreferredImage(info.getAvatars()), + result.setData(info.getName(), ImageStrategy.imageListToDbUrl(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); return result; } @@ -139,7 +139,7 @@ public class SubscriptionEntity { @Ignore public ChannelInfoItem toChannelInfoItem() { final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName()); - item.setThumbnails(ImageStrategy.urlToImageList(getAvatarUrl())); + item.setThumbnails(ImageStrategy.dbUrlToImageList(getAvatarUrl())); item.setSubscriberCount(getSubscriberCount()); item.setDescription(getDescription()); return item; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 3ece760ca..b16f40a4a 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -355,7 +355,7 @@ public class ChannelFragment extends BaseStateFragment channel.setServiceId(info.getServiceId()); channel.setUrl(info.getUrl()); channel.setData(info.getName(), - ImageStrategy.choosePreferredImage(info.getAvatars()), + ImageStrategy.imageListToDbUrl(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); channelSubscription = null; diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index ac82d5c91..fe2321059 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -61,7 +61,6 @@ import org.schabi.newpipe.util.OnClickGesture import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels import org.schabi.newpipe.util.external_communication.ShareUtils -import org.schabi.newpipe.util.image.ImageStrategy import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -342,8 +341,7 @@ class SubscriptionFragment : BaseStateFragment() { val actions = DialogInterface.OnClickListener { _, i -> when (i) { 0 -> ShareUtils.shareText( - requireContext(), selectedItem.name, selectedItem.url, - ImageStrategy.choosePreferredImage(selectedItem.thumbnails) + requireContext(), selectedItem.name, selectedItem.url, selectedItem.thumbnails ) 1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url) 2 -> deleteChannel(selectedItem) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index cfd5196be..bd42bbe41 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -74,7 +74,7 @@ class SubscriptionManager(context: Context) { Completable.fromRunnable { it.setData( info.name, - ImageStrategy.choosePreferredImage(info.avatars), + ImageStrategy.imageListToDbUrl(info.avatars), info.description, info.subscriberCount ) @@ -105,7 +105,7 @@ class SubscriptionManager(context: Context) { } else if (info is ChannelInfo) { subscriptionEntity.setData( info.name, - ImageStrategy.choosePreferredImage(info.avatars), + ImageStrategy.imageListToDbUrl(info.avatars), info.description, info.subscriberCount ) 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 1583c0b09..da97179b6 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 @@ -49,30 +49,16 @@ public final class ImageStrategy { } /** - * 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. - *
+ * {@link #choosePreferredImage(List)} contains the description for this function's logic. * - * @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 + * @param images the images from which to choose + * @param nonNoneQuality the preferred quality (must NOT be {@link PreferredImageQuality#NONE}) + * @return the chosen preferred image, or {@link null} if the list is empty + * @see #choosePreferredImage(List) */ @Nullable - public static String choosePreferredImage(@NonNull final List images) { - if (preferredImageQuality == PreferredImageQuality.NONE) { - return null; // do not load images - } - + static String choosePreferredImage(@NonNull final List images, + final PreferredImageQuality nonNoneQuality) { // this will be used to estimate the pixel count for images where only one of height or // width are known final double widthOverHeight = images.stream() @@ -82,7 +68,7 @@ public final class ImageStrategy { .findFirst() .orElse(1.0); - final Image.ResolutionLevel preferredLevel = preferredImageQuality.toResolutionLevel(); + final Image.ResolutionLevel preferredLevel = nonNoneQuality.toResolutionLevel(); final Comparator initialComparator = Comparator // the first step splits the images into groups of resolution levels .comparingInt(i -> { @@ -105,7 +91,7 @@ public final class ImageStrategy { // on how close its size is to BEST_LOW_H or BEST_MEDIUM_H (with proper units). Subgroups // without known image size will be left untouched since estimatePixelCount always returns // the same number for those. - final Comparator finalComparator = switch (preferredImageQuality) { + final Comparator finalComparator = switch (nonNoneQuality) { case NONE -> initialComparator; // unreachable case LOW -> initialComparator.thenComparingDouble(image -> { final double pixelCount = estimatePixelCount(image, widthOverHeight); @@ -128,8 +114,78 @@ public final class ImageStrategy { .orElse(null); } + /** + * 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 height + * closest to {@link #BEST_LOW_H} or {@link #BEST_MEDIUM_H}
  6. + *
+ *
+ * Use {@link #imageListToDbUrl(List)} if the URL is going to be saved to the database, to avoid + * saving nothing in case at the moment of saving the user preference is to not show images. + * + * @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 + * @see #imageListToDbUrl(List) + */ + @Nullable + public static String choosePreferredImage(@NonNull final List images) { + if (preferredImageQuality == PreferredImageQuality.NONE) { + return null; // do not load images + } + + return choosePreferredImage(images, preferredImageQuality); + } + + /** + * Like {@link #choosePreferredImage(List)}, except that if {@link #preferredImageQuality} is + * {@link PreferredImageQuality#NONE} an image will be chosen anyway (with preferred quality + * {@link PreferredImageQuality#MEDIUM}. + *
+ * To go back to a list of images (obviously with just the one chosen image) from a URL saved in + * the database use {@link #dbUrlToImageList(String)}. + * + * @param images the images from which to choose + * @return the chosen preferred image, or {@link null} if the list is empty + * @see #choosePreferredImage(List) + * @see #dbUrlToImageList(String) + */ + @Nullable + public static String imageListToDbUrl(@NonNull final List images) { + final PreferredImageQuality quality; + if (preferredImageQuality == PreferredImageQuality.NONE) { + quality = PreferredImageQuality.MEDIUM; + } else { + quality = preferredImageQuality; + } + + return choosePreferredImage(images, quality); + } + + /** + * Wraps the URL (coming from the database) in a {@code List} so that it is usable + * seamlessly in all of the places where the extractor would return a list of images, including + * allowing to build info objects based on database objects. + *
+ * To obtain a url to save to the database from a list of images use {@link + * #imageListToDbUrl(List)}. + * + * @param url the URL to wrap coming from the database, or {@code null} to get an empty list + * @return a list containing just one {@link Image} wrapping the provided URL, with unknown + * image size fields, or an empty list if the URL is {@code null} + * @see #imageListToDbUrl(List) + */ @NonNull - public static List urlToImageList(@Nullable final String url) { + public static List dbUrlToImageList(@Nullable final String url) { if (url == null) { return List.of(); } else { From 0085ca64162a37104fc031677a8b59bf7a84090c Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 21:45:07 +0200 Subject: [PATCH 09/13] Fix loading images from db even if disabled --- .../java/org/schabi/newpipe/util/image/PicassoHelper.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 fb0c97fe1..904776580 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 @@ -202,7 +202,10 @@ public final class PicassoHelper { private static RequestCreator loadImageDefault(@Nullable final String url, final int placeholderResId, final boolean showPlaceholderWhileLoading) { - if (isNullOrEmpty(url)) { + // if the URL was chosen with `choosePreferredImage` it will be null, but check again + // `shouldLoadImages` in case the URL was chosen with `imageListToDbUrl` (which is the case + // for URLs stored in the database) + if (isNullOrEmpty(url) || !ImageStrategy.shouldLoadImages()) { return picassoInstance .load((String) null) .placeholder(placeholderResId) // show placeholder when no image should load From 1b485ddb5adf09a926d2c04857dd9f132f4ff006 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 13 Aug 2023 23:44:10 +0200 Subject: [PATCH 10/13] Allow using CHECKSTYLE:OFF comments --- checkstyle/checkstyle.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/checkstyle/checkstyle.xml b/checkstyle/checkstyle.xml index e8c9d94ca..3377e3b84 100644 --- a/checkstyle/checkstyle.xml +++ b/checkstyle/checkstyle.xml @@ -69,6 +69,8 @@ + + From 0a2d6d1d62040365cd6a54d45de2f26741a269f1 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 13 Aug 2023 23:44:51 +0200 Subject: [PATCH 11/13] Add test for ImageStrategy --- .../newpipe/util/image/ImageStrategyTest.java | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 app/src/test/java/org/schabi/newpipe/util/image/ImageStrategyTest.java diff --git a/app/src/test/java/org/schabi/newpipe/util/image/ImageStrategyTest.java b/app/src/test/java/org/schabi/newpipe/util/image/ImageStrategyTest.java new file mode 100644 index 000000000..8c8bf6937 --- /dev/null +++ b/app/src/test/java/org/schabi/newpipe/util/image/ImageStrategyTest.java @@ -0,0 +1,195 @@ +package org.schabi.newpipe.util.image; + +import static org.junit.Assert.assertEquals; +import static org.schabi.newpipe.extractor.Image.HEIGHT_UNKNOWN; +import static org.schabi.newpipe.extractor.Image.WIDTH_UNKNOWN; +import static org.schabi.newpipe.util.image.ImageStrategy.choosePreferredImage; +import static org.schabi.newpipe.util.image.ImageStrategy.estimatePixelCount; + +import org.junit.Test; +import org.schabi.newpipe.extractor.Image; +import org.schabi.newpipe.extractor.Image.ResolutionLevel; + +import java.util.List; + +public class ImageStrategyTest { + + private static final List RESOLUTION_LEVELS = List.of( + ResolutionLevel.LOW, ResolutionLevel.MEDIUM, ResolutionLevel.HIGH); + + private Image img(final int height, final int width) { + return new Image("", height, width, ResolutionLevel.UNKNOWN); + } + + private Image img(final String url, final ResolutionLevel resolutionLevel) { + return new Image(url, HEIGHT_UNKNOWN, WIDTH_UNKNOWN, resolutionLevel); + } + + private Image img(final String url, + final int height, + final int width, + final ResolutionLevel resolutionLevel) { + return new Image(url, height, width, resolutionLevel); + } + + private void assertChoosePreferredImage(final String low, + final String medium, + final String high, + final List images) { + assertEquals(low, choosePreferredImage(images, PreferredImageQuality.LOW)); + assertEquals(medium, choosePreferredImage(images, PreferredImageQuality.MEDIUM)); + assertEquals(high, choosePreferredImage(images, PreferredImageQuality.HIGH)); + } + + + // CHECKSTYLE:OFF + @Test + public void testEstimatePixelCountAllKnown() { + assertEquals(20000.0, estimatePixelCount(img(100, 200), 1.0), 0.0); + assertEquals(20000.0, estimatePixelCount(img(100, 200), 12.0), 0.0); + assertEquals( 100.0, estimatePixelCount(img(100, 1), 12.0), 0.0); + assertEquals( 100.0, estimatePixelCount(img( 1, 100), 0.5), 0.0); + } + + @Test + public void testEstimatePixelCountHeightUnknown() { + assertEquals( 10000.0, estimatePixelCount(img(HEIGHT_UNKNOWN, 100), 1.0 ), 0.0); + assertEquals( 20000.0, estimatePixelCount(img(HEIGHT_UNKNOWN, 200), 2.0 ), 0.0); + assertEquals( 10.0, estimatePixelCount(img(HEIGHT_UNKNOWN, 1), 0.1 ), 0.0); + assertEquals(230400.0, estimatePixelCount(img(HEIGHT_UNKNOWN, 640), 16.0/9.0), 0.0); + } + + @Test + public void testEstimatePixelCountWidthUnknown() { + assertEquals( 10000.0, estimatePixelCount(img(100, WIDTH_UNKNOWN), 1.0 ), 0.0); + assertEquals( 20000.0, estimatePixelCount(img(200, WIDTH_UNKNOWN), 0.5 ), 0.0); + assertEquals( 12.0, estimatePixelCount(img( 1, WIDTH_UNKNOWN), 12.0 ), 0.0); + assertEquals(230400.0, estimatePixelCount(img(360, WIDTH_UNKNOWN), 16.0/9.0), 0.0); + } + + @Test + public void testEstimatePixelCountAllUnknown() { + assertEquals(0.0, estimatePixelCount(img(HEIGHT_UNKNOWN, WIDTH_UNKNOWN), 1.0 ), 0.0); + assertEquals(0.0, estimatePixelCount(img(HEIGHT_UNKNOWN, WIDTH_UNKNOWN), 12.0 ), 0.0); + assertEquals(0.0, estimatePixelCount(img(HEIGHT_UNKNOWN, WIDTH_UNKNOWN), 0.1 ), 0.0); + assertEquals(0.0, estimatePixelCount(img(HEIGHT_UNKNOWN, WIDTH_UNKNOWN), 16.0/9.0), 0.0); + } + // CHECKSTYLE:ON + + + @Test + public void testChoosePreferredImageAllKnown() { + // the resolution level of the images is more important than the actual resolution + assertChoosePreferredImage("a", "b", "c", List.of( + img("a", 1, 1, ResolutionLevel.LOW), + img("b", 200, 200, ResolutionLevel.MEDIUM), + img("c", 10000, 10000, ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("a", "b", "c", List.of( + img("a", 10000, 10000, ResolutionLevel.LOW), + img("b", 200, 200, ResolutionLevel.MEDIUM), + img("c", 1, 1, ResolutionLevel.HIGH) + )); + + assertChoosePreferredImage("b", "c", "d", List.of( + img("a", 2, 1, ResolutionLevel.LOW), + img("b", 50, 25, ResolutionLevel.LOW), + img("c", 200, 100, ResolutionLevel.LOW), + img("d", 300, 150, ResolutionLevel.LOW) + )); + + assertChoosePreferredImage("c", "d", "d", List.of( + img("a", 2, 1, ResolutionLevel.MEDIUM), + img("b", 50, 25, ResolutionLevel.MEDIUM), + img("c", 60, 30, ResolutionLevel.MEDIUM), + img("d", 300, 150, ResolutionLevel.MEDIUM) + )); + } + + @Test + public void testChoosePreferredImageSomeKnown() { + // the resolution level of the images is more important than the actual resolution + assertChoosePreferredImage("a", "b", "c", List.of( + img("a", 1, WIDTH_UNKNOWN, ResolutionLevel.LOW), + img("b", HEIGHT_UNKNOWN, 200, ResolutionLevel.MEDIUM), + img("c", 10000, WIDTH_UNKNOWN, ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("a", "b", "c", List.of( + img("a", HEIGHT_UNKNOWN, 10000, ResolutionLevel.LOW), + img("b", 200, WIDTH_UNKNOWN, ResolutionLevel.MEDIUM), + img("c", HEIGHT_UNKNOWN, 1, ResolutionLevel.HIGH) + )); + + assertChoosePreferredImage("b", "c", "d", List.of( + img("a", HEIGHT_UNKNOWN, 1, ResolutionLevel.HIGH), + img("b", 50, WIDTH_UNKNOWN, ResolutionLevel.HIGH), + img("c", HEIGHT_UNKNOWN, 120, ResolutionLevel.HIGH), + img("d", 340, WIDTH_UNKNOWN, ResolutionLevel.HIGH) + )); + + assertChoosePreferredImage("c", "d", "d", List.of( + img("a", 2, WIDTH_UNKNOWN, ResolutionLevel.MEDIUM), + img("b", HEIGHT_UNKNOWN, 50, ResolutionLevel.MEDIUM), + img("c", 60, WIDTH_UNKNOWN, ResolutionLevel.MEDIUM), + img("d", HEIGHT_UNKNOWN, 340, ResolutionLevel.MEDIUM) + )); + } + + @Test + public void testChoosePreferredImageMixed() { + for (final ResolutionLevel resolutionLevel : RESOLUTION_LEVELS) { + assertChoosePreferredImage("d", "b", "c", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", 200, 100, resolutionLevel), + img("c", 400, WIDTH_UNKNOWN, resolutionLevel), + img("d", HEIGHT_UNKNOWN, 50, resolutionLevel), + img("e", resolutionLevel) + )); + } + for (final ResolutionLevel resolutionLevel : RESOLUTION_LEVELS) { + assertChoosePreferredImage("b", "b", "b", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", 200, 100, resolutionLevel), + img("e", resolutionLevel) + )); + } + assertChoosePreferredImage("b", "b", "e", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", 200, 100, ResolutionLevel.LOW), + img("e", ResolutionLevel.HIGH) + )); + } + + @Test + public void testChoosePreferredImageAllUnknown() { + assertChoosePreferredImage("b", "c", "d", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", ResolutionLevel.LOW), + img("c", ResolutionLevel.MEDIUM), + img("d", ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("c", "c", "d", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("c", ResolutionLevel.MEDIUM), + img("d", ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("b", "c", "c", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", ResolutionLevel.LOW), + img("c", ResolutionLevel.MEDIUM) + )); + + // UNKNOWN is avoided as much as possible + assertChoosePreferredImage("d", "d", "d", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("d", ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("b", "b", "b", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", ResolutionLevel.LOW) + )); + assertChoosePreferredImage("a", "a", "a", List.of( + img("a", ResolutionLevel.UNKNOWN) + )); + } +} From 027b829c384be26494b2d2867dd285a51388213b Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 19 Sep 2023 18:35:29 +0200 Subject: [PATCH 12/13] Use @DrawableRes in PicassoHelper --- .../java/org/schabi/newpipe/util/image/PicassoHelper.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 904776580..4b116bdf9 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.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.BitmapCompat; @@ -190,17 +191,17 @@ public final class PicassoHelper { private static RequestCreator loadImageDefault(@NonNull final List images, - final int placeholderResId) { + @DrawableRes final int placeholderResId) { return loadImageDefault(choosePreferredImage(images), placeholderResId); } private static RequestCreator loadImageDefault(@Nullable final String url, - final int placeholderResId) { + @DrawableRes final int placeholderResId) { return loadImageDefault(url, placeholderResId, true); } private static RequestCreator loadImageDefault(@Nullable final String url, - final int placeholderResId, + @DrawableRes final int placeholderResId, final boolean showPlaceholderWhileLoading) { // if the URL was chosen with `choosePreferredImage` it will be null, but check again // `shouldLoadImages` in case the URL was chosen with `imageListToDbUrl` (which is the case From f8b756c8bcaca8c45b41d7434db0b221ab3027d4 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 19 Sep 2023 18:40:14 +0200 Subject: [PATCH 13/13] Make question mark localizable --- .../newpipe/fragments/detail/BaseDescriptionFragment.java | 2 +- app/src/main/res/values/strings.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) 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 ffd10d827..e3bdc6592 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 @@ -186,7 +186,7 @@ public abstract class BaseDescriptionFragment extends BaseFragment { private String imageSizeToText(final int heightOrWidth) { if (heightOrWidth < 0) { - return "?"; + return getString(R.string.question_mark); } else { return String.valueOf(heightOrWidth); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2ccc6a412..9a533f6b8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -828,4 +828,5 @@ Low quality Medium quality High quality + \? \ No newline at end of file