mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-01-03 14:00:32 +00:00
Implement better image selection strategy
This commit is contained in:
parent
0a8f28b1c6
commit
35073c780d
@ -20,6 +20,7 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
|
|||||||
import org.schabi.newpipe.ktx.ExceptionUtils;
|
import org.schabi.newpipe.ktx.ExceptionUtils;
|
||||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||||
import org.schabi.newpipe.util.Localization;
|
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.image.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.ServiceHelper;
|
import org.schabi.newpipe.util.ServiceHelper;
|
||||||
import org.schabi.newpipe.util.StateSaver;
|
import org.schabi.newpipe.util.StateSaver;
|
||||||
@ -100,7 +101,7 @@ public class App extends Application {
|
|||||||
// Initialize image loader
|
// Initialize image loader
|
||||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
PicassoHelper.init(this);
|
PicassoHelper.init(this);
|
||||||
PicassoHelper.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this,
|
ImageStrategy.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this,
|
||||||
prefs.getString(getString(R.string.image_quality_key),
|
prefs.getString(getString(R.string.image_quality_key),
|
||||||
getString(R.string.image_quality_default))));
|
getString(R.string.image_quality_default))));
|
||||||
PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG
|
PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG
|
||||||
|
@ -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.StreamEntity
|
||||||
import org.schabi.newpipe.database.stream.model.StreamStateEntity
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
||||||
import org.schabi.newpipe.util.image.PicassoHelper
|
import org.schabi.newpipe.util.image.ImageStrategy
|
||||||
|
|
||||||
data class PlaylistStreamEntry(
|
data class PlaylistStreamEntry(
|
||||||
@Embedded
|
@Embedded
|
||||||
@ -29,7 +29,7 @@ data class PlaylistStreamEntry(
|
|||||||
item.duration = streamEntity.duration
|
item.duration = streamEntity.duration
|
||||||
item.uploaderName = streamEntity.uploader
|
item.uploaderName = streamEntity.uploader
|
||||||
item.uploaderUrl = streamEntity.uploaderUrl
|
item.uploaderUrl = streamEntity.uploaderUrl
|
||||||
item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl)
|
item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl)
|
||||||
|
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import androidx.room.PrimaryKey;
|
|||||||
import org.schabi.newpipe.database.playlist.PlaylistLocalItem;
|
import org.schabi.newpipe.database.playlist.PlaylistLocalItem;
|
||||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
|
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
|
||||||
import org.schabi.newpipe.util.Constants;
|
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.LocalItem.LocalItemType.PLAYLIST_REMOTE_ITEM;
|
||||||
import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME;
|
import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME;
|
||||||
@ -70,7 +70,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem {
|
|||||||
@Ignore
|
@Ignore
|
||||||
public PlaylistRemoteEntity(final PlaylistInfo info) {
|
public PlaylistRemoteEntity(final PlaylistInfo info) {
|
||||||
this(info.getServiceId(), info.getName(), info.getUrl(),
|
this(info.getServiceId(), info.getName(), info.getUrl(),
|
||||||
PicassoHelper.choosePreferredImage(info.getThumbnails()),
|
ImageStrategy.choosePreferredImage(info.getThumbnails()),
|
||||||
info.getUploaderName(), info.getStreamCount());
|
info.getUploaderName(), info.getStreamCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem {
|
|||||||
&& TextUtils.equals(getName(), info.getName())
|
&& TextUtils.equals(getName(), info.getName())
|
||||||
&& TextUtils.equals(getUrl(), info.getUrl())
|
&& TextUtils.equals(getUrl(), info.getUrl())
|
||||||
&& TextUtils.equals(getThumbnailUrl(),
|
&& TextUtils.equals(getThumbnailUrl(),
|
||||||
PicassoHelper.choosePreferredImage(info.getThumbnails()))
|
ImageStrategy.choosePreferredImage(info.getThumbnails()))
|
||||||
&& TextUtils.equals(getUploader(), info.getUploaderName());
|
&& TextUtils.equals(getUploader(), info.getUploaderName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.StreamEntity
|
||||||
import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
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
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
class StreamStatisticsEntry(
|
class StreamStatisticsEntry(
|
||||||
@ -31,7 +31,7 @@ class StreamStatisticsEntry(
|
|||||||
item.duration = streamEntity.duration
|
item.duration = streamEntity.duration
|
||||||
item.uploaderName = streamEntity.uploader
|
item.uploaderName = streamEntity.uploader
|
||||||
item.uploaderUrl = streamEntity.uploaderUrl
|
item.uploaderUrl = streamEntity.uploaderUrl
|
||||||
item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl)
|
item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl)
|
||||||
|
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo
|
|||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
||||||
import org.schabi.newpipe.extractor.stream.StreamType
|
import org.schabi.newpipe.extractor.stream.StreamType
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem
|
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.io.Serializable
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ data class StreamEntity(
|
|||||||
constructor(item: StreamInfoItem) : this(
|
constructor(item: StreamInfoItem) : this(
|
||||||
serviceId = item.serviceId, url = item.url, title = item.name,
|
serviceId = item.serviceId, url = item.url, title = item.name,
|
||||||
streamType = item.streamType, duration = item.duration, uploader = item.uploaderName,
|
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(),
|
textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(),
|
||||||
isUploadDateApproximation = item.uploadDate?.isApproximation
|
isUploadDateApproximation = item.uploadDate?.isApproximation
|
||||||
)
|
)
|
||||||
@ -77,7 +77,7 @@ data class StreamEntity(
|
|||||||
constructor(info: StreamInfo) : this(
|
constructor(info: StreamInfo) : this(
|
||||||
serviceId = info.serviceId, url = info.url, title = info.name,
|
serviceId = info.serviceId, url = info.url, title = info.name,
|
||||||
streamType = info.streamType, duration = info.duration, uploader = info.uploaderName,
|
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(),
|
textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(),
|
||||||
isUploadDateApproximation = info.uploadDate?.isApproximation
|
isUploadDateApproximation = info.uploadDate?.isApproximation
|
||||||
)
|
)
|
||||||
@ -87,7 +87,7 @@ data class StreamEntity(
|
|||||||
serviceId = item.serviceId, url = item.url, title = item.title,
|
serviceId = item.serviceId, url = item.url, title = item.title,
|
||||||
streamType = item.streamType, duration = item.duration, uploader = item.uploader,
|
streamType = item.streamType, duration = item.duration, uploader = item.uploader,
|
||||||
uploaderUrl = item.uploaderUrl,
|
uploaderUrl = item.uploaderUrl,
|
||||||
thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails)
|
thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun toStreamInfoItem(): StreamInfoItem {
|
fun toStreamInfoItem(): StreamInfoItem {
|
||||||
@ -95,7 +95,7 @@ data class StreamEntity(
|
|||||||
item.duration = duration
|
item.duration = duration
|
||||||
item.uploaderName = uploader
|
item.uploaderName = uploader
|
||||||
item.uploaderUrl = uploaderUrl
|
item.uploaderUrl = uploaderUrl
|
||||||
item.thumbnails = PicassoHelper.urlToImageList(thumbnailUrl)
|
item.thumbnails = ImageStrategy.urlToImageList(thumbnailUrl)
|
||||||
|
|
||||||
if (viewCount != null) item.viewCount = viewCount as Long
|
if (viewCount != null) item.viewCount = viewCount as Long
|
||||||
item.textualUploadDate = textualUploadDate
|
item.textualUploadDate = textualUploadDate
|
||||||
|
@ -10,7 +10,7 @@ import androidx.room.PrimaryKey;
|
|||||||
import org.schabi.newpipe.extractor.channel.ChannelInfo;
|
import org.schabi.newpipe.extractor.channel.ChannelInfo;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
import org.schabi.newpipe.util.Constants;
|
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_SERVICE_ID;
|
||||||
import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE;
|
import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE;
|
||||||
@ -58,7 +58,7 @@ public class SubscriptionEntity {
|
|||||||
final SubscriptionEntity result = new SubscriptionEntity();
|
final SubscriptionEntity result = new SubscriptionEntity();
|
||||||
result.setServiceId(info.getServiceId());
|
result.setServiceId(info.getServiceId());
|
||||||
result.setUrl(info.getUrl());
|
result.setUrl(info.getUrl());
|
||||||
result.setData(info.getName(), PicassoHelper.choosePreferredImage(info.getAvatars()),
|
result.setData(info.getName(), ImageStrategy.choosePreferredImage(info.getAvatars()),
|
||||||
info.getDescription(), info.getSubscriberCount());
|
info.getDescription(), info.getSubscriberCount());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ public class SubscriptionEntity {
|
|||||||
@Ignore
|
@Ignore
|
||||||
public ChannelInfoItem toChannelInfoItem() {
|
public ChannelInfoItem toChannelInfoItem() {
|
||||||
final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName());
|
final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName());
|
||||||
item.setThumbnails(PicassoHelper.urlToImageList(getAvatarUrl()));
|
item.setThumbnails(ImageStrategy.urlToImageList(getAvatarUrl()));
|
||||||
item.setSubscriberCount(getSubscriberCount());
|
item.setSubscriberCount(getSubscriberCount());
|
||||||
item.setDescription(getDescription());
|
item.setDescription(getDescription());
|
||||||
return item;
|
return item;
|
||||||
|
@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo;
|
|||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.schabi.newpipe.util.image.PicassoHelper;
|
import org.schabi.newpipe.util.image.ImageStrategy;
|
||||||
|
|
||||||
import icepick.State;
|
import icepick.State;
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ public class DescriptionFragment extends BaseDescriptionFragment {
|
|||||||
addMetadataItem(inflater, layout, true, R.string.metadata_host,
|
addMetadataItem(inflater, layout, true, R.string.metadata_host,
|
||||||
streamInfo.getHost());
|
streamInfo.getHost());
|
||||||
addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url,
|
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) {
|
private void addPrivacyMetadataItem(final LayoutInflater inflater, final LinearLayout layout) {
|
||||||
|
@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.Description;
|
|||||||
import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment;
|
import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment;
|
||||||
import org.schabi.newpipe.util.DeviceUtils;
|
import org.schabi.newpipe.util.DeviceUtils;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.util.image.PicassoHelper;
|
import org.schabi.newpipe.util.image.ImageStrategy;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -101,8 +101,8 @@ public class ChannelAboutFragment extends BaseDescriptionFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addMetadataItem(inflater, layout, true, R.string.metadata_avatar_url,
|
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,
|
addMetadataItem(inflater, layout, true, R.string.metadata_banner_url,
|
||||||
PicassoHelper.choosePreferredImage(channelInfo.getBanners()));
|
ImageStrategy.choosePreferredImage(channelInfo.getBanners()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ import org.schabi.newpipe.util.ExtractorHelper;
|
|||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
import org.schabi.newpipe.util.NavigationHelper;
|
||||||
import org.schabi.newpipe.util.StateSaver;
|
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.image.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.ThemeHelper;
|
import org.schabi.newpipe.util.ThemeHelper;
|
||||||
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||||
@ -147,7 +148,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
|
|||||||
|
|
||||||
setTitle(name);
|
setTitle(name);
|
||||||
binding.channelTitleView.setText(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
|
// do not waste space for the banner if it is not going to be loaded
|
||||||
binding.channelBannerImage.setImageDrawable(null);
|
binding.channelBannerImage.setImageDrawable(null);
|
||||||
}
|
}
|
||||||
@ -354,7 +355,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
|
|||||||
channel.setServiceId(info.getServiceId());
|
channel.setServiceId(info.getServiceId());
|
||||||
channel.setUrl(info.getUrl());
|
channel.setUrl(info.getUrl());
|
||||||
channel.setData(info.getName(),
|
channel.setData(info.getName(),
|
||||||
PicassoHelper.choosePreferredImage(info.getAvatars()),
|
ImageStrategy.choosePreferredImage(info.getAvatars()),
|
||||||
info.getDescription(),
|
info.getDescription(),
|
||||||
info.getSubscriberCount());
|
info.getSubscriberCount());
|
||||||
channelSubscription = null;
|
channelSubscription = null;
|
||||||
@ -578,7 +579,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
|
|||||||
currentInfo = result;
|
currentInfo = result;
|
||||||
setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName());
|
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)
|
PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG)
|
||||||
.into(binding.channelBannerImage);
|
.into(binding.channelBannerImage);
|
||||||
} else {
|
} else {
|
||||||
|
@ -31,6 +31,7 @@ import org.schabi.newpipe.local.history.HistoryRecordManager;
|
|||||||
import org.schabi.newpipe.util.DeviceUtils;
|
import org.schabi.newpipe.util.DeviceUtils;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
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.image.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||||
import org.schabi.newpipe.util.text.CommentTextOnTouchListener;
|
import org.schabi.newpipe.util.text.CommentTextOnTouchListener;
|
||||||
@ -98,7 +99,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
|
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
|
||||||
|
|
||||||
PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView);
|
PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView);
|
||||||
if (PicassoHelper.shouldLoadImages()) {
|
if (ImageStrategy.shouldLoadImages()) {
|
||||||
itemThumbnailView.setVisibility(View.VISIBLE);
|
itemThumbnailView.setVisibility(View.VISIBLE);
|
||||||
itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding,
|
itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding,
|
||||||
commentVerticalPadding, commentVerticalPadding);
|
commentVerticalPadding, commentVerticalPadding);
|
||||||
|
@ -61,7 +61,7 @@ import org.schabi.newpipe.util.OnClickGesture
|
|||||||
import org.schabi.newpipe.util.ServiceHelper
|
import org.schabi.newpipe.util.ServiceHelper
|
||||||
import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels
|
import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels
|
||||||
import org.schabi.newpipe.util.external_communication.ShareUtils
|
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.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@ -343,7 +343,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
|||||||
when (i) {
|
when (i) {
|
||||||
0 -> ShareUtils.shareText(
|
0 -> ShareUtils.shareText(
|
||||||
requireContext(), selectedItem.name, selectedItem.url,
|
requireContext(), selectedItem.name, selectedItem.url,
|
||||||
PicassoHelper.choosePreferredImage(selectedItem.thumbnails)
|
ImageStrategy.choosePreferredImage(selectedItem.thumbnails)
|
||||||
)
|
)
|
||||||
1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url)
|
1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url)
|
||||||
2 -> deleteChannel(selectedItem)
|
2 -> deleteChannel(selectedItem)
|
||||||
|
@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.feed.FeedInfo
|
|||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
||||||
import org.schabi.newpipe.local.feed.FeedDatabaseManager
|
import org.schabi.newpipe.local.feed.FeedDatabaseManager
|
||||||
import org.schabi.newpipe.util.ExtractorHelper
|
import org.schabi.newpipe.util.ExtractorHelper
|
||||||
import org.schabi.newpipe.util.image.PicassoHelper
|
import org.schabi.newpipe.util.image.ImageStrategy
|
||||||
|
|
||||||
class SubscriptionManager(context: Context) {
|
class SubscriptionManager(context: Context) {
|
||||||
private val database = NewPipeDatabase.getInstance(context)
|
private val database = NewPipeDatabase.getInstance(context)
|
||||||
@ -74,7 +74,7 @@ class SubscriptionManager(context: Context) {
|
|||||||
Completable.fromRunnable {
|
Completable.fromRunnable {
|
||||||
it.setData(
|
it.setData(
|
||||||
info.name,
|
info.name,
|
||||||
PicassoHelper.choosePreferredImage(info.avatars),
|
ImageStrategy.choosePreferredImage(info.avatars),
|
||||||
info.description,
|
info.description,
|
||||||
info.subscriberCount
|
info.subscriberCount
|
||||||
)
|
)
|
||||||
@ -105,7 +105,7 @@ class SubscriptionManager(context: Context) {
|
|||||||
} else if (info is ChannelInfo) {
|
} else if (info is ChannelInfo) {
|
||||||
subscriptionEntity.setData(
|
subscriptionEntity.setData(
|
||||||
info.name,
|
info.name,
|
||||||
PicassoHelper.choosePreferredImage(info.avatars),
|
ImageStrategy.choosePreferredImage(info.avatars),
|
||||||
info.description,
|
info.description,
|
||||||
info.subscriberCount
|
info.subscriberCount
|
||||||
)
|
)
|
||||||
|
@ -3,7 +3,7 @@ package org.schabi.newpipe.player.mediaitem;
|
|||||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
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.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -75,7 +75,7 @@ public final class ExceptionTag implements MediaItemTag {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getThumbnailUrl() {
|
public String getThumbnailUrl() {
|
||||||
return PicassoHelper.choosePreferredImage(item.getThumbnails());
|
return ImageStrategy.choosePreferredImage(item.getThumbnails());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,7 +6,7 @@ import org.schabi.newpipe.extractor.stream.AudioStream;
|
|||||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -96,7 +96,7 @@ public final class StreamInfoTag implements MediaItemTag {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getThumbnailUrl() {
|
public String getThumbnailUrl() {
|
||||||
return PicassoHelper.choosePreferredImage(streamInfo.getThumbnails());
|
return ImageStrategy.choosePreferredImage(streamInfo.getThumbnails());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -20,7 +20,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
import org.schabi.newpipe.player.Player;
|
import org.schabi.newpipe.player.Player;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
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.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -139,7 +139,7 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator
|
|||||||
descBuilder.setExtras(additionalMetadata);
|
descBuilder.setExtras(additionalMetadata);
|
||||||
|
|
||||||
final Uri thumbnailUri = Uri.parse(
|
final Uri thumbnailUri = Uri.parse(
|
||||||
PicassoHelper.choosePreferredImage(item.getThumbnails()));
|
ImageStrategy.choosePreferredImage(item.getThumbnails()));
|
||||||
if (thumbnailUri != null) {
|
if (thumbnailUri != null) {
|
||||||
descBuilder.setIconUri(thumbnailUri);
|
descBuilder.setIconUri(thumbnailUri);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import org.schabi.newpipe.extractor.localization.Localization;
|
|||||||
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
|
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
|
||||||
import org.schabi.newpipe.streams.io.StoredFileHelper;
|
import org.schabi.newpipe.streams.io.StoredFileHelper;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
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.image.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.ZipHelper;
|
import org.schabi.newpipe.util.ZipHelper;
|
||||||
import org.schabi.newpipe.util.image.PreferredImageQuality;
|
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);
|
final Preference imageQualityPreference = requirePreference(R.string.image_quality_key);
|
||||||
imageQualityPreference.setOnPreferenceChangeListener(
|
imageQualityPreference.setOnPreferenceChangeListener(
|
||||||
(preference, newValue) -> {
|
(preference, newValue) -> {
|
||||||
PicassoHelper.setPreferredImageQuality(PreferredImageQuality
|
ImageStrategy.setPreferredImageQuality(PreferredImageQuality
|
||||||
.fromPreferenceKey(requireContext(), (String) newValue));
|
.fromPreferenceKey(requireContext(), (String) newValue));
|
||||||
try {
|
try {
|
||||||
PicassoHelper.clearCache(preference.getContext());
|
PicassoHelper.clearCache(preference.getContext());
|
||||||
|
@ -24,6 +24,7 @@ import androidx.core.content.FileProvider;
|
|||||||
import org.schabi.newpipe.BuildConfig;
|
import org.schabi.newpipe.BuildConfig;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.Image;
|
import org.schabi.newpipe.extractor.Image;
|
||||||
|
import org.schabi.newpipe.util.image.ImageStrategy;
|
||||||
import org.schabi.newpipe.util.image.PicassoHelper;
|
import org.schabi.newpipe.util.image.PicassoHelper;
|
||||||
|
|
||||||
import java.io.File;
|
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 loading of images has been disabled, don't try to generate a content preview
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||||
&& !TextUtils.isEmpty(imagePreviewUrl)
|
&& !TextUtils.isEmpty(imagePreviewUrl)
|
||||||
&& PicassoHelper.shouldLoadImages()) {
|
&& ImageStrategy.shouldLoadImages()) {
|
||||||
|
|
||||||
final ClipData clipData = generateClipDataForImagePreview(context, imagePreviewUrl);
|
final ClipData clipData = generateClipDataForImagePreview(context, imagePreviewUrl);
|
||||||
if (clipData != null) {
|
if (clipData != null) {
|
||||||
@ -276,14 +277,14 @@ public final class ShareUtils {
|
|||||||
* @param title the title of the content
|
* @param title the title of the content
|
||||||
* @param content the content to share
|
* @param content the content to share
|
||||||
* @param images a set of possible {@link Image}s of the subject, among which to choose with
|
* @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
|
* provide an image that is in Picasso's cache
|
||||||
*/
|
*/
|
||||||
public static void shareText(@NonNull final Context context,
|
public static void shareText(@NonNull final Context context,
|
||||||
@NonNull final String title,
|
@NonNull final String title,
|
||||||
final String content,
|
final String content,
|
||||||
final List<Image> images) {
|
final List<Image> images) {
|
||||||
shareText(context, title, content, PicassoHelper.choosePreferredImage(images));
|
shareText(context, title, content, ImageStrategy.choosePreferredImage(images));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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<Image> 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<Image> 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.<Image>comparingDouble(
|
||||||
|
image -> estimatePixelCount(image, widthOverHeight, false))
|
||||||
|
.reversed();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return images.stream()
|
||||||
|
.min(comparator)
|
||||||
|
.map(Image::getUrl)
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static List<Image> urlToImageList(@Nullable final String url) {
|
||||||
|
if (url == null) {
|
||||||
|
return List.of();
|
||||||
|
} else {
|
||||||
|
return List.of(new Image(url, -1, -1, Image.ResolutionLevel.UNKNOWN));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,13 +2,13 @@ package org.schabi.newpipe.util.image;
|
|||||||
|
|
||||||
import static org.schabi.newpipe.MainActivity.DEBUG;
|
import static org.schabi.newpipe.MainActivity.DEBUG;
|
||||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||||
|
import static org.schabi.newpipe.util.image.ImageStrategy.choosePreferredImage;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.graphics.BitmapCompat;
|
import androidx.core.graphics.BitmapCompat;
|
||||||
|
|
||||||
@ -21,11 +21,9 @@ import com.squareup.picasso.Transformation;
|
|||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.Image;
|
import org.schabi.newpipe.extractor.Image;
|
||||||
import org.schabi.newpipe.extractor.Image.ResolutionLevel;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -46,7 +44,6 @@ public final class PicassoHelper {
|
|||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private static Picasso picassoInstance;
|
private static Picasso picassoInstance;
|
||||||
|
|
||||||
private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM;
|
|
||||||
|
|
||||||
public static void init(final Context context) {
|
public static void init(final Context context) {
|
||||||
picassoCache = new LruCache(10 * 1024 * 1024);
|
picassoCache = new LruCache(10 * 1024 * 1024);
|
||||||
@ -92,14 +89,6 @@ public final class PicassoHelper {
|
|||||||
picassoInstance.setIndicatorsEnabled(enabled); // useful for debugging
|
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<Image> images) {
|
public static RequestCreator loadAvatar(final List<Image> images) {
|
||||||
return loadImageDefault(images, R.drawable.placeholder_person);
|
return loadImageDefault(images, R.drawable.placeholder_person);
|
||||||
@ -227,41 +216,4 @@ public final class PicassoHelper {
|
|||||||
return requestCreator;
|
return requestCreator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static String choosePreferredImage(final List<Image> images) {
|
|
||||||
final Comparator<Image> 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<Image> urlToImageList(@Nullable final String url) {
|
|
||||||
if (url == null) {
|
|
||||||
return List.of();
|
|
||||||
} else {
|
|
||||||
return List.of(new Image(url, -1, -1, ResolutionLevel.UNKNOWN));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user