mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 00:20:32 +00:00
Replace UniversalImageLoader with Picasso
This commit is contained in:
parent
9c5ac069d7
commit
fcef783bbb
@ -246,7 +246,8 @@ dependencies {
|
|||||||
// Circular ImageView
|
// Circular ImageView
|
||||||
implementation "de.hdodenhof:circleimageview:3.1.0"
|
implementation "de.hdodenhof:circleimageview:3.1.0"
|
||||||
// Image loading
|
// Image loading
|
||||||
implementation "com.nostra13.universalimageloader:universal-image-loader:1.9.5"
|
//noinspection GradleDependency --> 2.8 is the last version, not 2.71828!
|
||||||
|
implementation "com.squareup.picasso:picasso:2.8"
|
||||||
|
|
||||||
// Markdown library for Android
|
// Markdown library for Android
|
||||||
implementation "io.noties.markwon:core:${markwonVersion}"
|
implementation "io.noties.markwon:core:${markwonVersion}"
|
||||||
|
@ -11,10 +11,6 @@ import androidx.core.app.NotificationManagerCompat;
|
|||||||
import androidx.multidex.MultiDexApplication;
|
import androidx.multidex.MultiDexApplication;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache;
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
|
||||||
|
|
||||||
import org.acra.ACRA;
|
import org.acra.ACRA;
|
||||||
import org.acra.config.ACRAConfigurationException;
|
import org.acra.config.ACRAConfigurationException;
|
||||||
import org.acra.config.CoreConfiguration;
|
import org.acra.config.CoreConfiguration;
|
||||||
@ -28,6 +24,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.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;
|
||||||
|
|
||||||
@ -65,9 +62,9 @@ import io.reactivex.rxjava3.plugins.RxJavaPlugins;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class App extends MultiDexApplication {
|
public class App extends MultiDexApplication {
|
||||||
protected static final String TAG = App.class.toString();
|
|
||||||
private static App app;
|
|
||||||
public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
|
public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
|
||||||
|
private static final String TAG = App.class.toString();
|
||||||
|
private static App app;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Disposable disposable = null;
|
private Disposable disposable = null;
|
||||||
@ -103,7 +100,9 @@ public class App extends MultiDexApplication {
|
|||||||
ServiceHelper.initServices(this);
|
ServiceHelper.initServices(this);
|
||||||
|
|
||||||
// Initialize image loader
|
// Initialize image loader
|
||||||
ImageLoader.getInstance().init(getImageLoaderConfigurations(10, 50));
|
PicassoHelper.init(this);
|
||||||
|
PicassoHelper.setShouldLoadImages(PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
.getBoolean(getString(R.string.download_thumbnail_key), true));
|
||||||
|
|
||||||
configureRxJavaErrorHandler();
|
configureRxJavaErrorHandler();
|
||||||
|
|
||||||
@ -117,6 +116,7 @@ public class App extends MultiDexApplication {
|
|||||||
disposable.dispose();
|
disposable.dispose();
|
||||||
}
|
}
|
||||||
super.onTerminate();
|
super.onTerminate();
|
||||||
|
PicassoHelper.terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Downloader getDownloader() {
|
protected Downloader getDownloader() {
|
||||||
@ -201,15 +201,6 @@ public class App extends MultiDexApplication {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImageLoaderConfiguration getImageLoaderConfigurations(final int memoryCacheSizeMb,
|
|
||||||
final int diskCacheSizeMb) {
|
|
||||||
return new ImageLoaderConfiguration.Builder(this)
|
|
||||||
.memoryCache(new LRULimitedMemoryCache(memoryCacheSizeMb * 1024 * 1024))
|
|
||||||
.diskCacheSize(diskCacheSizeMb * 1024 * 1024)
|
|
||||||
.imageDownloader(new ImageDownloader(getApplicationContext()))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called in {@link #attachBaseContext(Context)} after calling the {@code super} method.
|
* Called in {@link #attachBaseContext(Context)} after calling the {@code super} method.
|
||||||
* Should be overridden if MultiDex is enabled, since it has to be initialized before ACRA.
|
* Should be overridden if MultiDex is enabled, since it has to be initialized before ACRA.
|
||||||
|
@ -10,14 +10,11 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import icepick.Icepick;
|
import icepick.Icepick;
|
||||||
import icepick.State;
|
import icepick.State;
|
||||||
import leakcanary.AppWatcher;
|
import leakcanary.AppWatcher;
|
||||||
|
|
||||||
public abstract class BaseFragment extends Fragment {
|
public abstract class BaseFragment extends Fragment {
|
||||||
public static final ImageLoader IMAGE_LOADER = ImageLoader.getInstance();
|
|
||||||
protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
|
protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
|
||||||
protected final boolean DEBUG = MainActivity.DEBUG;
|
protected final boolean DEBUG = MainActivity.DEBUG;
|
||||||
protected AppCompatActivity activity;
|
protected AppCompatActivity activity;
|
||||||
|
@ -17,7 +17,6 @@ import org.schabi.newpipe.util.InfoCache;
|
|||||||
import org.schabi.newpipe.util.TLSSocketFactoryCompat;
|
import org.schabi.newpipe.util.TLSSocketFactoryCompat;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
@ -194,36 +193,6 @@ public final class DownloaderImpl extends Downloader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream stream(final String siteUrl) throws IOException {
|
|
||||||
try {
|
|
||||||
final okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder()
|
|
||||||
.method("GET", null).url(siteUrl)
|
|
||||||
.addHeader("User-Agent", USER_AGENT);
|
|
||||||
|
|
||||||
final String cookies = getCookies(siteUrl);
|
|
||||||
if (!cookies.isEmpty()) {
|
|
||||||
requestBuilder.addHeader("Cookie", cookies);
|
|
||||||
}
|
|
||||||
|
|
||||||
final okhttp3.Request request = requestBuilder.build();
|
|
||||||
final okhttp3.Response response = client.newCall(request).execute();
|
|
||||||
final ResponseBody body = response.body();
|
|
||||||
|
|
||||||
if (response.code() == 429) {
|
|
||||||
throw new ReCaptchaException("reCaptcha Challenge requested", siteUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body == null) {
|
|
||||||
response.close();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return body.byteStream();
|
|
||||||
} catch (final ReCaptchaException e) {
|
|
||||||
throw new IOException(e.getMessage(), e.getCause());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response execute(@NonNull final Request request)
|
public Response execute(@NonNull final Request request)
|
||||||
throws IOException, ReCaptchaException {
|
throws IOException, ReCaptchaException {
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
package org.schabi.newpipe;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
public class ImageDownloader extends BaseImageDownloader {
|
|
||||||
private final Resources resources;
|
|
||||||
private final SharedPreferences preferences;
|
|
||||||
private final String downloadThumbnailKey;
|
|
||||||
|
|
||||||
public ImageDownloader(final Context context) {
|
|
||||||
super(context);
|
|
||||||
this.resources = context.getResources();
|
|
||||||
this.preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
this.downloadThumbnailKey = context.getString(R.string.download_thumbnail_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isDownloadingThumbnail() {
|
|
||||||
return preferences.getBoolean(downloadThumbnailKey, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("ResourceType")
|
|
||||||
@Override
|
|
||||||
public InputStream getStream(final String imageUri, final Object extra) throws IOException {
|
|
||||||
if (isDownloadingThumbnail()) {
|
|
||||||
return super.getStream(imageUri, extra);
|
|
||||||
} else {
|
|
||||||
return resources.openRawResource(R.drawable.dummy_thumbnail_dark);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected InputStream getStreamFromNetwork(final String imageUri, final Object extra)
|
|
||||||
throws IOException {
|
|
||||||
final DownloaderImpl downloader = (DownloaderImpl) NewPipe.getDownloader();
|
|
||||||
return downloader.stream(imageUri);
|
|
||||||
}
|
|
||||||
}
|
|
@ -48,9 +48,7 @@ import com.google.android.exoplayer2.PlaybackParameters;
|
|||||||
import com.google.android.material.appbar.AppBarLayout;
|
import com.google.android.material.appbar.AppBarLayout;
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||||
import com.google.android.material.tabs.TabLayout;
|
import com.google.android.material.tabs.TabLayout;
|
||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
import com.squareup.picasso.Callback;
|
||||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
|
||||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.App;
|
import org.schabi.newpipe.App;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
@ -90,14 +88,14 @@ import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
|
|||||||
import org.schabi.newpipe.util.Constants;
|
import org.schabi.newpipe.util.Constants;
|
||||||
import org.schabi.newpipe.util.DeviceUtils;
|
import org.schabi.newpipe.util.DeviceUtils;
|
||||||
import org.schabi.newpipe.util.ExtractorHelper;
|
import org.schabi.newpipe.util.ExtractorHelper;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
|
||||||
import org.schabi.newpipe.util.external_communication.KoreUtils;
|
|
||||||
import org.schabi.newpipe.util.ListHelper;
|
import org.schabi.newpipe.util.ListHelper;
|
||||||
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.PermissionHelper;
|
import org.schabi.newpipe.util.PermissionHelper;
|
||||||
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.ThemeHelper;
|
import org.schabi.newpipe.util.ThemeHelper;
|
||||||
|
import org.schabi.newpipe.util.external_communication.KoreUtils;
|
||||||
|
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -151,6 +149,8 @@ public final class VideoDetailFragment
|
|||||||
private static final String DESCRIPTION_TAB_TAG = "DESCRIPTION TAB";
|
private static final String DESCRIPTION_TAB_TAG = "DESCRIPTION TAB";
|
||||||
private static final String EMPTY_TAB_TAG = "EMPTY TAB";
|
private static final String EMPTY_TAB_TAG = "EMPTY TAB";
|
||||||
|
|
||||||
|
private static final String PICASSO_VIDEO_DETAILS_TAG = "PICASSO_VIDEO_DETAILS_TAG";
|
||||||
|
|
||||||
// tabs
|
// tabs
|
||||||
private boolean showComments;
|
private boolean showComments;
|
||||||
private boolean showRelatedItems;
|
private boolean showRelatedItems;
|
||||||
@ -686,33 +686,23 @@ public final class VideoDetailFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initThumbnailViews(@NonNull final StreamInfo info) {
|
private void initThumbnailViews(@NonNull final StreamInfo info) {
|
||||||
binding.detailThumbnailImageView.setImageResource(R.drawable.dummy_thumbnail_dark);
|
PicassoHelper.loadThumbnail(info.getThumbnailUrl()).tag(PICASSO_VIDEO_DETAILS_TAG)
|
||||||
|
.into(binding.detailThumbnailImageView, new Callback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
}
|
||||||
|
|
||||||
if (!isEmpty(info.getThumbnailUrl())) {
|
@Override
|
||||||
final ImageLoadingListener onFailListener = new SimpleImageLoadingListener() {
|
public void onError(final Exception e) {
|
||||||
@Override
|
showSnackBarError(new ErrorInfo(e, UserAction.LOAD_IMAGE,
|
||||||
public void onLoadingFailed(final String imageUri, final View view,
|
info.getThumbnailUrl(), info));
|
||||||
final FailReason failReason) {
|
}
|
||||||
showSnackBarError(new ErrorInfo(failReason.getCause(), UserAction.LOAD_IMAGE,
|
});
|
||||||
imageUri, info));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
IMAGE_LOADER.displayImage(info.getThumbnailUrl(), binding.detailThumbnailImageView,
|
PicassoHelper.loadAvatar(info.getSubChannelAvatarUrl()).tag(PICASSO_VIDEO_DETAILS_TAG)
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS, onFailListener);
|
.into(binding.detailSubChannelThumbnailView);
|
||||||
}
|
PicassoHelper.loadAvatar(info.getUploaderAvatarUrl()).tag(PICASSO_VIDEO_DETAILS_TAG)
|
||||||
|
.into(binding.detailUploaderThumbnailView);
|
||||||
if (!isEmpty(info.getSubChannelAvatarUrl())) {
|
|
||||||
IMAGE_LOADER.displayImage(info.getSubChannelAvatarUrl(),
|
|
||||||
binding.detailSubChannelThumbnailView,
|
|
||||||
ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isEmpty(info.getUploaderAvatarUrl())) {
|
|
||||||
IMAGE_LOADER.displayImage(info.getUploaderAvatarUrl(),
|
|
||||||
binding.detailUploaderThumbnailView,
|
|
||||||
ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
@ -1446,8 +1436,7 @@ public final class VideoDetailFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMAGE_LOADER.cancelDisplayTask(binding.detailThumbnailImageView);
|
PicassoHelper.cancelTag(PICASSO_VIDEO_DETAILS_TAG);
|
||||||
IMAGE_LOADER.cancelDisplayTask(binding.detailSubChannelThumbnailView);
|
|
||||||
binding.detailThumbnailImageView.setImageBitmap(null);
|
binding.detailThumbnailImageView.setImageBitmap(null);
|
||||||
binding.detailSubChannelThumbnailView.setImageBitmap(null);
|
binding.detailSubChannelThumbnailView.setImageBitmap(null);
|
||||||
}
|
}
|
||||||
@ -2278,10 +2267,8 @@ public final class VideoDetailFragment
|
|||||||
binding.overlayTitleTextView.setText(isEmpty(overlayTitle) ? "" : overlayTitle);
|
binding.overlayTitleTextView.setText(isEmpty(overlayTitle) ? "" : overlayTitle);
|
||||||
binding.overlayChannelTextView.setText(isEmpty(uploader) ? "" : uploader);
|
binding.overlayChannelTextView.setText(isEmpty(uploader) ? "" : uploader);
|
||||||
binding.overlayThumbnail.setImageResource(R.drawable.dummy_thumbnail_dark);
|
binding.overlayThumbnail.setImageResource(R.drawable.dummy_thumbnail_dark);
|
||||||
if (!isEmpty(thumbnailUrl)) {
|
PicassoHelper.loadThumbnail(thumbnailUrl).tag(PICASSO_VIDEO_DETAILS_TAG)
|
||||||
IMAGE_LOADER.displayImage(thumbnailUrl, binding.overlayThumbnail,
|
.into(binding.overlayThumbnail);
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOverlayPlayPauseImage(final boolean playerIsPlaying) {
|
private void setOverlayPlayPauseImage(final boolean playerIsPlaying) {
|
||||||
|
@ -40,10 +40,10 @@ import org.schabi.newpipe.local.subscription.SubscriptionManager;
|
|||||||
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
|
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||||
import org.schabi.newpipe.util.ExtractorHelper;
|
import org.schabi.newpipe.util.ExtractorHelper;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
|
||||||
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.external_communication.ShareUtils;
|
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||||
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.ThemeHelper;
|
import org.schabi.newpipe.util.ThemeHelper;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -66,7 +66,10 @@ import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor;
|
|||||||
|
|
||||||
public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
||||||
implements View.OnClickListener {
|
implements View.OnClickListener {
|
||||||
|
|
||||||
private static final int BUTTON_DEBOUNCE_INTERVAL = 100;
|
private static final int BUTTON_DEBOUNCE_INTERVAL = 100;
|
||||||
|
private static final String PICASSO_CHANNEL_TAG = "PICASSO_CHANNEL_TAG";
|
||||||
|
|
||||||
private final CompositeDisposable disposables = new CompositeDisposable();
|
private final CompositeDisposable disposables = new CompositeDisposable();
|
||||||
private Disposable subscribeButtonMonitor;
|
private Disposable subscribeButtonMonitor;
|
||||||
|
|
||||||
@ -421,10 +424,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
|||||||
@Override
|
@Override
|
||||||
public void showLoading() {
|
public void showLoading() {
|
||||||
super.showLoading();
|
super.showLoading();
|
||||||
|
PicassoHelper.cancelTag(PICASSO_CHANNEL_TAG);
|
||||||
IMAGE_LOADER.cancelDisplayTask(headerBinding.channelBannerImage);
|
|
||||||
IMAGE_LOADER.cancelDisplayTask(headerBinding.channelAvatarView);
|
|
||||||
IMAGE_LOADER.cancelDisplayTask(headerBinding.subChannelAvatarView);
|
|
||||||
animate(headerBinding.channelSubscribeButton, false, 100);
|
animate(headerBinding.channelSubscribeButton, false, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,13 +433,12 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
|||||||
super.handleResult(result);
|
super.handleResult(result);
|
||||||
|
|
||||||
headerBinding.getRoot().setVisibility(View.VISIBLE);
|
headerBinding.getRoot().setVisibility(View.VISIBLE);
|
||||||
IMAGE_LOADER.displayImage(result.getBannerUrl(), headerBinding.channelBannerImage,
|
PicassoHelper.loadBanner(result.getBannerUrl()).tag(PICASSO_CHANNEL_TAG)
|
||||||
ImageDisplayConstants.DISPLAY_BANNER_OPTIONS);
|
.into(headerBinding.channelBannerImage);
|
||||||
IMAGE_LOADER.displayImage(result.getAvatarUrl(), headerBinding.channelAvatarView,
|
PicassoHelper.loadAvatar(result.getAvatarUrl()).tag(PICASSO_CHANNEL_TAG)
|
||||||
ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS);
|
.into(headerBinding.channelAvatarView);
|
||||||
IMAGE_LOADER.displayImage(result.getParentChannelAvatarUrl(),
|
PicassoHelper.loadAvatar(result.getParentChannelAvatarUrl()).tag(PICASSO_CHANNEL_TAG)
|
||||||
headerBinding.subChannelAvatarView,
|
.into(headerBinding.subChannelAvatarView);
|
||||||
ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS);
|
|
||||||
|
|
||||||
headerBinding.channelSubscriberView.setVisibility(View.VISIBLE);
|
headerBinding.channelSubscriberView.setVisibility(View.VISIBLE);
|
||||||
if (result.getSubscriberCount() >= 0) {
|
if (result.getSubscriberCount() >= 0) {
|
||||||
|
@ -41,7 +41,7 @@ import org.schabi.newpipe.player.helper.PlayerHolder;
|
|||||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||||
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
|
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
|
||||||
import org.schabi.newpipe.util.ExtractorHelper;
|
import org.schabi.newpipe.util.ExtractorHelper;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.external_communication.KoreUtils;
|
import org.schabi.newpipe.util.external_communication.KoreUtils;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
import org.schabi.newpipe.util.NavigationHelper;
|
||||||
@ -64,12 +64,16 @@ import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
|||||||
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
|
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
|
||||||
|
|
||||||
public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
||||||
|
|
||||||
|
private static final String PICASSO_PLAYLIST_TAG = "PICASSO_PLAYLIST_TAG";
|
||||||
|
|
||||||
private CompositeDisposable disposables;
|
private CompositeDisposable disposables;
|
||||||
private Subscription bookmarkReactor;
|
private Subscription bookmarkReactor;
|
||||||
private AtomicBoolean isBookmarkButtonReady;
|
private AtomicBoolean isBookmarkButtonReady;
|
||||||
|
|
||||||
private RemotePlaylistManager remotePlaylistManager;
|
private RemotePlaylistManager remotePlaylistManager;
|
||||||
private PlaylistRemoteEntity playlistEntity;
|
private PlaylistRemoteEntity playlistEntity;
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Views
|
// Views
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
@ -274,7 +278,7 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
|||||||
animate(headerBinding.getRoot(), false, 200);
|
animate(headerBinding.getRoot(), false, 200);
|
||||||
animateHideRecyclerViewAllowingScrolling(itemsList);
|
animateHideRecyclerViewAllowingScrolling(itemsList);
|
||||||
|
|
||||||
IMAGE_LOADER.cancelDisplayTask(headerBinding.uploaderAvatarView);
|
PicassoHelper.cancelTag(PICASSO_PLAYLIST_TAG);
|
||||||
animate(headerBinding.uploaderLayout, false, 200);
|
animate(headerBinding.uploaderLayout, false, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,8 +321,8 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
|||||||
R.drawable.ic_radio)
|
R.drawable.ic_radio)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
IMAGE_LOADER.displayImage(avatarUrl, headerBinding.uploaderAvatarView,
|
PicassoHelper.loadAvatar(avatarUrl).tag(PICASSO_PLAYLIST_TAG)
|
||||||
ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS);
|
.into(headerBinding.uploaderAvatarView);
|
||||||
}
|
}
|
||||||
|
|
||||||
headerBinding.playlistStreamCount.setText(Localization
|
headerBinding.playlistStreamCount.setText(Localization
|
||||||
|
@ -6,8 +6,6 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||||
@ -51,7 +49,6 @@ import org.schabi.newpipe.util.OnClickGesture;
|
|||||||
|
|
||||||
public class InfoItemBuilder {
|
public class InfoItemBuilder {
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final ImageLoader imageLoader = ImageLoader.getInstance();
|
|
||||||
|
|
||||||
private OnClickGesture<StreamInfoItem> onStreamSelectedListener;
|
private OnClickGesture<StreamInfoItem> onStreamSelectedListener;
|
||||||
private OnClickGesture<ChannelInfoItem> onChannelSelectedListener;
|
private OnClickGesture<ChannelInfoItem> onChannelSelectedListener;
|
||||||
@ -101,10 +98,6 @@ public class InfoItemBuilder {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageLoader getImageLoader() {
|
|
||||||
return imageLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnClickGesture<StreamInfoItem> getOnStreamSelectedListener() {
|
public OnClickGesture<StreamInfoItem> getOnStreamSelectedListener() {
|
||||||
return onStreamSelectedListener;
|
return onStreamSelectedListener;
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,12 @@ package org.schabi.newpipe.info_list
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader
|
|
||||||
import com.xwray.groupie.GroupieViewHolder
|
import com.xwray.groupie.GroupieViewHolder
|
||||||
import com.xwray.groupie.Item
|
import com.xwray.groupie.Item
|
||||||
import org.schabi.newpipe.R
|
import org.schabi.newpipe.R
|
||||||
import org.schabi.newpipe.extractor.stream.StreamSegment
|
import org.schabi.newpipe.extractor.stream.StreamSegment
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants
|
|
||||||
import org.schabi.newpipe.util.Localization
|
import org.schabi.newpipe.util.Localization
|
||||||
|
import org.schabi.newpipe.util.PicassoHelper
|
||||||
|
|
||||||
class StreamSegmentItem(
|
class StreamSegmentItem(
|
||||||
private val item: StreamSegment,
|
private val item: StreamSegment,
|
||||||
@ -24,10 +23,8 @@ class StreamSegmentItem(
|
|||||||
|
|
||||||
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
|
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
|
||||||
item.previewUrl?.let {
|
item.previewUrl?.let {
|
||||||
ImageLoader.getInstance().displayImage(
|
PicassoHelper.loadThumbnail(it)
|
||||||
it, viewHolder.root.findViewById<ImageView>(R.id.previewImage),
|
.into(viewHolder.root.findViewById<ImageView>(R.id.previewImage))
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
viewHolder.root.findViewById<TextView>(R.id.textViewTitle).text = item.title
|
viewHolder.root.findViewById<TextView>(R.id.textViewTitle).text = item.title
|
||||||
if (item.channelName == null) {
|
if (item.channelName == null) {
|
||||||
|
@ -8,7 +8,7 @@ import org.schabi.newpipe.extractor.InfoItem;
|
|||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
|
|
||||||
import de.hdodenhof.circleimageview.CircleImageView;
|
import de.hdodenhof.circleimageview.CircleImageView;
|
||||||
@ -43,10 +43,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
itemTitleView.setText(item.getName());
|
itemTitleView.setText(item.getName());
|
||||||
itemAdditionalDetailView.setText(getDetailLine(item));
|
itemAdditionalDetailView.setText(getDetailLine(item));
|
||||||
|
|
||||||
itemBuilder.getImageLoader()
|
PicassoHelper.loadThumbnail(item.getThumbnailUrl()).into(itemThumbnailView);
|
||||||
.displayImage(item.getThumbnailUrl(),
|
|
||||||
itemThumbnailView,
|
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
|
|
||||||
|
|
||||||
itemView.setOnClickListener(view -> {
|
itemView.setOnClickListener(view -> {
|
||||||
if (itemBuilder.getOnChannelSelectedListener() != null) {
|
if (itemBuilder.getOnChannelSelectedListener() != null) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package org.schabi.newpipe.info_list.holder;
|
package org.schabi.newpipe.info_list.holder;
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.text.style.URLSpan;
|
import android.text.style.URLSpan;
|
||||||
@ -12,7 +11,6 @@ import android.widget.RelativeLayout;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.error.ErrorActivity;
|
import org.schabi.newpipe.error.ErrorActivity;
|
||||||
@ -22,11 +20,11 @@ import org.schabi.newpipe.info_list.InfoItemBuilder;
|
|||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.CommentTextOnTouchListener;
|
import org.schabi.newpipe.util.CommentTextOnTouchListener;
|
||||||
import org.schabi.newpipe.util.DeviceUtils;
|
import org.schabi.newpipe.util.DeviceUtils;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
|
||||||
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.external_communication.TimestampExtractor;
|
import org.schabi.newpipe.util.external_communication.TimestampExtractor;
|
||||||
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||||
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
@ -38,11 +36,9 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
private static final int COMMENT_DEFAULT_LINES = 2;
|
private static final int COMMENT_DEFAULT_LINES = 2;
|
||||||
private static final int COMMENT_EXPANDED_LINES = 1000;
|
private static final int COMMENT_EXPANDED_LINES = 1000;
|
||||||
|
|
||||||
private final String downloadThumbnailKey;
|
|
||||||
private final int commentHorizontalPadding;
|
private final int commentHorizontalPadding;
|
||||||
private final int commentVerticalPadding;
|
private final int commentVerticalPadding;
|
||||||
|
|
||||||
private SharedPreferences preferences = null;
|
|
||||||
private final RelativeLayout itemRoot;
|
private final RelativeLayout itemRoot;
|
||||||
public final CircleImageView itemThumbnailView;
|
public final CircleImageView itemThumbnailView;
|
||||||
private final TextView itemContentView;
|
private final TextView itemContentView;
|
||||||
@ -83,9 +79,6 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
itemPublishedTime = itemView.findViewById(R.id.itemPublishedTime);
|
itemPublishedTime = itemView.findViewById(R.id.itemPublishedTime);
|
||||||
itemContentView = itemView.findViewById(R.id.itemCommentContentView);
|
itemContentView = itemView.findViewById(R.id.itemCommentContentView);
|
||||||
|
|
||||||
downloadThumbnailKey = infoItemBuilder.getContext().
|
|
||||||
getString(R.string.download_thumbnail_key);
|
|
||||||
|
|
||||||
commentHorizontalPadding = (int) infoItemBuilder.getContext()
|
commentHorizontalPadding = (int) infoItemBuilder.getContext()
|
||||||
.getResources().getDimension(R.dimen.comments_horizontal_padding);
|
.getResources().getDimension(R.dimen.comments_horizontal_padding);
|
||||||
commentVerticalPadding = (int) infoItemBuilder.getContext()
|
commentVerticalPadding = (int) infoItemBuilder.getContext()
|
||||||
@ -105,14 +98,8 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
}
|
}
|
||||||
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
|
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
|
||||||
|
|
||||||
preferences = PreferenceManager.getDefaultSharedPreferences(itemBuilder.getContext());
|
PicassoHelper.loadAvatar(item.getUploaderAvatarUrl()).into(itemThumbnailView);
|
||||||
|
if (PicassoHelper.getShouldLoadImages()) {
|
||||||
itemBuilder.getImageLoader()
|
|
||||||
.displayImage(item.getUploaderAvatarUrl(),
|
|
||||||
itemThumbnailView,
|
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
|
|
||||||
|
|
||||||
if (preferences.getBoolean(downloadThumbnailKey, true)) {
|
|
||||||
itemThumbnailView.setVisibility(View.VISIBLE);
|
itemThumbnailView.setVisibility(View.VISIBLE);
|
||||||
itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding,
|
itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding,
|
||||||
commentVerticalPadding, commentVerticalPadding);
|
commentVerticalPadding, commentVerticalPadding);
|
||||||
|
@ -9,7 +9,7 @@ import org.schabi.newpipe.extractor.InfoItem;
|
|||||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
|
|
||||||
public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
|
public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
|
||||||
@ -46,9 +46,7 @@ public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
.localizeStreamCountMini(itemStreamCountView.getContext(), item.getStreamCount()));
|
.localizeStreamCountMini(itemStreamCountView.getContext(), item.getStreamCount()));
|
||||||
itemUploaderView.setText(item.getUploaderName());
|
itemUploaderView.setText(item.getUploaderName());
|
||||||
|
|
||||||
itemBuilder.getImageLoader()
|
PicassoHelper.loadPlaylistThumbnail(item.getThumbnailUrl()).into(itemThumbnailView);
|
||||||
.displayImage(item.getThumbnailUrl(), itemThumbnailView,
|
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
|
|
||||||
|
|
||||||
itemView.setOnClickListener(view -> {
|
itemView.setOnClickListener(view -> {
|
||||||
if (itemBuilder.getOnPlaylistSelectedListener() != null) {
|
if (itemBuilder.getOnPlaylistSelectedListener() != null) {
|
||||||
|
@ -15,7 +15,7 @@ import org.schabi.newpipe.extractor.stream.StreamType;
|
|||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.ktx.ViewUtils;
|
import org.schabi.newpipe.ktx.ViewUtils;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.views.AnimatedProgressBar;
|
import org.schabi.newpipe.views.AnimatedProgressBar;
|
||||||
|
|
||||||
@ -83,10 +83,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default thumbnail is shown on error, while loading and if the url is empty
|
// Default thumbnail is shown on error, while loading and if the url is empty
|
||||||
itemBuilder.getImageLoader()
|
PicassoHelper.loadThumbnail(item.getThumbnailUrl()).into(itemThumbnailView);
|
||||||
.displayImage(item.getThumbnailUrl(),
|
|
||||||
itemThumbnailView,
|
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
|
|
||||||
|
|
||||||
itemView.setOnClickListener(view -> {
|
itemView.setOnClickListener(view -> {
|
||||||
if (itemBuilder.getOnStreamSelectedListener() != null) {
|
if (itemBuilder.getOnStreamSelectedListener() != null) {
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
package org.schabi.newpipe.local;
|
package org.schabi.newpipe.local;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.widget.ImageView;
|
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.database.LocalItem;
|
import org.schabi.newpipe.database.LocalItem;
|
||||||
import org.schabi.newpipe.util.OnClickGesture;
|
import org.schabi.newpipe.util.OnClickGesture;
|
||||||
@ -31,7 +27,6 @@ import org.schabi.newpipe.util.OnClickGesture;
|
|||||||
|
|
||||||
public class LocalItemBuilder {
|
public class LocalItemBuilder {
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final ImageLoader imageLoader = ImageLoader.getInstance();
|
|
||||||
|
|
||||||
private OnClickGesture<LocalItem> onSelectedListener;
|
private OnClickGesture<LocalItem> onSelectedListener;
|
||||||
|
|
||||||
@ -43,11 +38,6 @@ public class LocalItemBuilder {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayImage(final String url, final ImageView view,
|
|
||||||
final DisplayImageOptions options) {
|
|
||||||
imageLoader.displayImage(url, view, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnClickGesture<LocalItem> getOnItemSelectedListener() {
|
public OnClickGesture<LocalItem> getOnItemSelectedListener() {
|
||||||
return onSelectedListener;
|
return onSelectedListener;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import android.text.TextUtils
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader
|
|
||||||
import com.xwray.groupie.viewbinding.BindableItem
|
import com.xwray.groupie.viewbinding.BindableItem
|
||||||
import org.schabi.newpipe.MainActivity
|
import org.schabi.newpipe.MainActivity
|
||||||
import org.schabi.newpipe.R
|
import org.schabi.newpipe.R
|
||||||
@ -16,8 +15,8 @@ import org.schabi.newpipe.extractor.stream.StreamType.AUDIO_LIVE_STREAM
|
|||||||
import org.schabi.newpipe.extractor.stream.StreamType.AUDIO_STREAM
|
import org.schabi.newpipe.extractor.stream.StreamType.AUDIO_STREAM
|
||||||
import org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM
|
import org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM
|
||||||
import org.schabi.newpipe.extractor.stream.StreamType.VIDEO_STREAM
|
import org.schabi.newpipe.extractor.stream.StreamType.VIDEO_STREAM
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants
|
|
||||||
import org.schabi.newpipe.util.Localization
|
import org.schabi.newpipe.util.Localization
|
||||||
|
import org.schabi.newpipe.util.PicassoHelper
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
data class StreamItem(
|
data class StreamItem(
|
||||||
@ -93,10 +92,7 @@ data class StreamItem(
|
|||||||
viewBinding.itemProgressView.visibility = View.GONE
|
viewBinding.itemProgressView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageLoader.getInstance().displayImage(
|
PicassoHelper.loadThumbnail(stream.thumbnailUrl).into(viewBinding.itemThumbnailView)
|
||||||
stream.thumbnailUrl, viewBinding.itemThumbnailView,
|
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS
|
|
||||||
)
|
|
||||||
|
|
||||||
if (itemVersion != ItemVersion.MINI) {
|
if (itemVersion != ItemVersion.MINI) {
|
||||||
viewBinding.itemAdditionalDetails.text =
|
viewBinding.itemAdditionalDetails.text =
|
||||||
|
@ -7,7 +7,7 @@ import org.schabi.newpipe.database.LocalItem;
|
|||||||
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
|
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
|
||||||
import org.schabi.newpipe.local.LocalItemBuilder;
|
import org.schabi.newpipe.local.LocalItemBuilder;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
|
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@ -36,8 +36,7 @@ public class LocalPlaylistItemHolder extends PlaylistItemHolder {
|
|||||||
itemStreamCountView.getContext(), item.streamCount));
|
itemStreamCountView.getContext(), item.streamCount));
|
||||||
itemUploaderView.setVisibility(View.INVISIBLE);
|
itemUploaderView.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView,
|
PicassoHelper.loadPlaylistThumbnail(item.thumbnailUrl).into(itemThumbnailView);
|
||||||
ImageDisplayConstants.DISPLAY_PLAYLIST_OPTIONS);
|
|
||||||
|
|
||||||
super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter);
|
super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import org.schabi.newpipe.extractor.NewPipe;
|
|||||||
import org.schabi.newpipe.ktx.ViewUtils;
|
import org.schabi.newpipe.ktx.ViewUtils;
|
||||||
import org.schabi.newpipe.local.LocalItemBuilder;
|
import org.schabi.newpipe.local.LocalItemBuilder;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.views.AnimatedProgressBar;
|
import org.schabi.newpipe.views.AnimatedProgressBar;
|
||||||
|
|
||||||
@ -81,8 +81,8 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default thumbnail is shown on error, while loading and if the url is empty
|
// Default thumbnail is shown on error, while loading and if the url is empty
|
||||||
itemBuilder.displayImage(item.getStreamEntity().getThumbnailUrl(), itemThumbnailView,
|
PicassoHelper.loadThumbnail(item.getStreamEntity().getThumbnailUrl())
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
|
.into(itemThumbnailView);
|
||||||
|
|
||||||
itemView.setOnClickListener(view -> {
|
itemView.setOnClickListener(view -> {
|
||||||
if (itemBuilder.getOnItemSelectedListener() != null) {
|
if (itemBuilder.getOnItemSelectedListener() != null) {
|
||||||
|
@ -15,7 +15,7 @@ import org.schabi.newpipe.extractor.NewPipe;
|
|||||||
import org.schabi.newpipe.ktx.ViewUtils;
|
import org.schabi.newpipe.ktx.ViewUtils;
|
||||||
import org.schabi.newpipe.local.LocalItemBuilder;
|
import org.schabi.newpipe.local.LocalItemBuilder;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.views.AnimatedProgressBar;
|
import org.schabi.newpipe.views.AnimatedProgressBar;
|
||||||
|
|
||||||
@ -114,8 +114,8 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default thumbnail is shown on error, while loading and if the url is empty
|
// Default thumbnail is shown on error, while loading and if the url is empty
|
||||||
itemBuilder.displayImage(item.getStreamEntity().getThumbnailUrl(), itemThumbnailView,
|
PicassoHelper.loadThumbnail(item.getStreamEntity().getThumbnailUrl())
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
|
.into(itemThumbnailView);
|
||||||
|
|
||||||
itemView.setOnClickListener(view -> {
|
itemView.setOnClickListener(view -> {
|
||||||
if (itemBuilder.getOnItemSelectedListener() != null) {
|
if (itemBuilder.getOnItemSelectedListener() != null) {
|
||||||
|
@ -8,7 +8,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
|
|||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.local.LocalItemBuilder;
|
import org.schabi.newpipe.local.LocalItemBuilder;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
|
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@ -44,9 +44,7 @@ public class RemotePlaylistItemHolder extends PlaylistItemHolder {
|
|||||||
itemUploaderView.setText(NewPipe.getNameOfService(item.getServiceId()));
|
itemUploaderView.setText(NewPipe.getNameOfService(item.getServiceId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PicassoHelper.loadPlaylistThumbnail(item.getThumbnailUrl()).into(itemThumbnailView);
|
||||||
itemBuilder.displayImage(item.getThumbnailUrl(), itemThumbnailView,
|
|
||||||
ImageDisplayConstants.DISPLAY_PLAYLIST_OPTIONS);
|
|
||||||
|
|
||||||
super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter);
|
super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter);
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,13 @@ package org.schabi.newpipe.local.subscription.item
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader
|
|
||||||
import com.xwray.groupie.GroupieViewHolder
|
import com.xwray.groupie.GroupieViewHolder
|
||||||
import com.xwray.groupie.Item
|
import com.xwray.groupie.Item
|
||||||
import org.schabi.newpipe.R
|
import org.schabi.newpipe.R
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants
|
|
||||||
import org.schabi.newpipe.util.Localization
|
import org.schabi.newpipe.util.Localization
|
||||||
import org.schabi.newpipe.util.OnClickGesture
|
import org.schabi.newpipe.util.OnClickGesture
|
||||||
|
import org.schabi.newpipe.util.PicassoHelper
|
||||||
|
|
||||||
class ChannelItem(
|
class ChannelItem(
|
||||||
private val infoItem: ChannelInfoItem,
|
private val infoItem: ChannelInfoItem,
|
||||||
@ -40,10 +39,7 @@ class ChannelItem(
|
|||||||
itemChannelDescriptionView.text = infoItem.description
|
itemChannelDescriptionView.text = infoItem.description
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageLoader.getInstance().displayImage(
|
PicassoHelper.loadThumbnail(infoItem.thumbnailUrl).into(itemThumbnailView)
|
||||||
infoItem.thumbnailUrl, itemThumbnailView,
|
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS
|
|
||||||
)
|
|
||||||
|
|
||||||
gesturesListener?.run {
|
gesturesListener?.run {
|
||||||
viewHolder.root.setOnClickListener { selected(infoItem) }
|
viewHolder.root.setOnClickListener { selected(infoItem) }
|
||||||
|
@ -3,7 +3,6 @@ package org.schabi.newpipe.local.subscription.item
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader
|
|
||||||
import com.xwray.groupie.viewbinding.BindableItem
|
import com.xwray.groupie.viewbinding.BindableItem
|
||||||
import com.xwray.groupie.viewbinding.GroupieViewHolder
|
import com.xwray.groupie.viewbinding.GroupieViewHolder
|
||||||
import org.schabi.newpipe.R
|
import org.schabi.newpipe.R
|
||||||
@ -11,7 +10,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
|
|||||||
import org.schabi.newpipe.databinding.PickerSubscriptionItemBinding
|
import org.schabi.newpipe.databinding.PickerSubscriptionItemBinding
|
||||||
import org.schabi.newpipe.ktx.AnimationType
|
import org.schabi.newpipe.ktx.AnimationType
|
||||||
import org.schabi.newpipe.ktx.animate
|
import org.schabi.newpipe.ktx.animate
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants
|
import org.schabi.newpipe.util.PicassoHelper
|
||||||
|
|
||||||
data class PickerSubscriptionItem(
|
data class PickerSubscriptionItem(
|
||||||
val subscriptionEntity: SubscriptionEntity,
|
val subscriptionEntity: SubscriptionEntity,
|
||||||
@ -22,11 +21,7 @@ data class PickerSubscriptionItem(
|
|||||||
override fun getSpanSize(spanCount: Int, position: Int): Int = 1
|
override fun getSpanSize(spanCount: Int, position: Int): Int = 1
|
||||||
|
|
||||||
override fun bind(viewBinding: PickerSubscriptionItemBinding, position: Int) {
|
override fun bind(viewBinding: PickerSubscriptionItemBinding, position: Int) {
|
||||||
ImageLoader.getInstance().displayImage(
|
PicassoHelper.loadAvatar(subscriptionEntity.avatarUrl).into(viewBinding.thumbnailView)
|
||||||
subscriptionEntity.avatarUrl,
|
|
||||||
viewBinding.thumbnailView, ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS
|
|
||||||
)
|
|
||||||
|
|
||||||
viewBinding.titleView.text = subscriptionEntity.name
|
viewBinding.titleView.text = subscriptionEntity.name
|
||||||
viewBinding.selectedHighlight.isVisible = isSelected
|
viewBinding.selectedHighlight.isVisible = isSelected
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import android.graphics.BitmapFactory;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.PorterDuffColorFilter;
|
import android.graphics.PorterDuffColorFilter;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -82,9 +83,9 @@ import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
|||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.exoplayer2.video.VideoListener;
|
import com.google.android.exoplayer2.video.VideoListener;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.squareup.picasso.Picasso;
|
||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
import com.squareup.picasso.Target;
|
||||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
import com.squareup.picasso.Transformation;
|
||||||
|
|
||||||
import org.schabi.newpipe.DownloaderImpl;
|
import org.schabi.newpipe.DownloaderImpl;
|
||||||
import org.schabi.newpipe.MainActivity;
|
import org.schabi.newpipe.MainActivity;
|
||||||
@ -128,11 +129,11 @@ import org.schabi.newpipe.player.resolver.VideoPlaybackResolver;
|
|||||||
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper;
|
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper;
|
||||||
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHolder;
|
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHolder;
|
||||||
import org.schabi.newpipe.util.DeviceUtils;
|
import org.schabi.newpipe.util.DeviceUtils;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.external_communication.KoreUtils;
|
||||||
import org.schabi.newpipe.util.ListHelper;
|
import org.schabi.newpipe.util.ListHelper;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
import org.schabi.newpipe.util.NavigationHelper;
|
||||||
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.SerializedCache;
|
import org.schabi.newpipe.util.SerializedCache;
|
||||||
import org.schabi.newpipe.util.external_communication.KoreUtils;
|
|
||||||
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||||
import org.schabi.newpipe.views.ExpandableSurfaceView;
|
import org.schabi.newpipe.views.ExpandableSurfaceView;
|
||||||
|
|
||||||
@ -196,7 +197,6 @@ import static org.schabi.newpipe.util.Localization.containsCaseInsensitive;
|
|||||||
public final class Player implements
|
public final class Player implements
|
||||||
EventListener,
|
EventListener,
|
||||||
PlaybackListener,
|
PlaybackListener,
|
||||||
ImageLoadingListener,
|
|
||||||
VideoListener,
|
VideoListener,
|
||||||
SeekBar.OnSeekBarChangeListener,
|
SeekBar.OnSeekBarChangeListener,
|
||||||
View.OnClickListener,
|
View.OnClickListener,
|
||||||
@ -250,6 +250,9 @@ public final class Player implements
|
|||||||
|
|
||||||
private static final int RENDERER_UNAVAILABLE = -1;
|
private static final int RENDERER_UNAVAILABLE = -1;
|
||||||
|
|
||||||
|
private static final String PICASSO_PLAYER_TAG = "PICASSO_PLAYER_TAG";
|
||||||
|
private static final String PICASSO_TRANSFORMATION_KEY = "PICASSO_TRANSFORMATION_KEY";
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Playback
|
// Playback
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
@ -820,7 +823,7 @@ public final class Player implements
|
|||||||
|
|
||||||
databaseUpdateDisposable.clear();
|
databaseUpdateDisposable.clear();
|
||||||
progressUpdateDisposable.set(null);
|
progressUpdateDisposable.set(null);
|
||||||
ImageLoader.getInstance().stop();
|
PicassoHelper.cancelTag(PICASSO_PLAYER_TAG);
|
||||||
|
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
binding.endScreen.setImageBitmap(null);
|
binding.endScreen.setImageBitmap(null);
|
||||||
@ -1215,14 +1218,71 @@ public final class Player implements
|
|||||||
|
|
||||||
private void initThumbnail(final String url) {
|
private void initThumbnail(final String url) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Thumbnail - initThumbnail() called");
|
Log.d(TAG, "Thumbnail - initThumbnail() called with url = ["
|
||||||
|
+ (url == null ? "null" : url) + "]");
|
||||||
}
|
}
|
||||||
if (url == null || url.isEmpty()) {
|
if (url == null || url.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ImageLoader.getInstance().resume();
|
|
||||||
ImageLoader.getInstance()
|
// scale down the notification thumbnail for performance
|
||||||
.loadImage(url, ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS, this);
|
PicassoHelper.loadThumbnail(url)
|
||||||
|
.tag(PICASSO_PLAYER_TAG)
|
||||||
|
.transform(new Transformation() {
|
||||||
|
@Override
|
||||||
|
public Bitmap transform(final Bitmap source) {
|
||||||
|
final float notificationThumbnailWidth = Math.min(
|
||||||
|
context.getResources()
|
||||||
|
.getDimension(R.dimen.player_notification_thumbnail_width),
|
||||||
|
source.getWidth());
|
||||||
|
return Bitmap.createScaledBitmap(
|
||||||
|
source,
|
||||||
|
(int) notificationThumbnailWidth,
|
||||||
|
(int) (source.getHeight()
|
||||||
|
/ (source.getWidth() / notificationThumbnailWidth)),
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String key() {
|
||||||
|
return PICASSO_TRANSFORMATION_KEY;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into(new Target() {
|
||||||
|
@Override
|
||||||
|
public void onBitmapLoaded(final Bitmap bitmap, final Picasso.LoadedFrom from) {
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Thumbnail - onLoadingComplete() called with: "
|
||||||
|
+ "url = [" + url + "], " + "loadedImage = [" + bitmap + " -> "
|
||||||
|
+ bitmap.getWidth() + "x" + bitmap.getHeight()
|
||||||
|
+ "], from = [" + from + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
currentThumbnail = bitmap;
|
||||||
|
NotificationUtil.getInstance()
|
||||||
|
.createNotificationIfNeededAndUpdate(Player.this, false);
|
||||||
|
// there is a new thumbnail, so changed the end screen thumbnail, too.
|
||||||
|
updateEndScreenThumbnail();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBitmapFailed(final Exception e, final Drawable errorDrawable) {
|
||||||
|
Log.e(TAG, "Thumbnail - onBitmapFailed() called with: url = ["
|
||||||
|
+ url + "]", e);
|
||||||
|
currentThumbnail = null;
|
||||||
|
NotificationUtil.getInstance()
|
||||||
|
.createNotificationIfNeededAndUpdate(Player.this, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrepareLoad(final Drawable placeHolderDrawable) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Thumbnail - onLoadingStarted() called with: url = ["
|
||||||
|
+ url + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1296,61 +1356,6 @@ public final class Player implements
|
|||||||
return Math.min(currentThumbnail.getHeight(), screenHeight);
|
return Math.min(currentThumbnail.getHeight(), screenHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingStarted(final String imageUri, final View view) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Thumbnail - onLoadingStarted() called on: "
|
|
||||||
+ "imageUri = [" + imageUri + "], view = [" + view + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingFailed(final String imageUri, final View view,
|
|
||||||
final FailReason failReason) {
|
|
||||||
Log.e(TAG, "Thumbnail - onLoadingFailed() called on imageUri = [" + imageUri + "]",
|
|
||||||
failReason.getCause());
|
|
||||||
currentThumbnail = null;
|
|
||||||
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingComplete(final String imageUri, final View view,
|
|
||||||
final Bitmap loadedImage) {
|
|
||||||
// scale down the notification thumbnail for performance
|
|
||||||
final float notificationThumbnailWidth = Math.min(
|
|
||||||
context.getResources().getDimension(R.dimen.player_notification_thumbnail_width),
|
|
||||||
loadedImage.getWidth());
|
|
||||||
currentThumbnail = Bitmap.createScaledBitmap(
|
|
||||||
loadedImage,
|
|
||||||
(int) notificationThumbnailWidth,
|
|
||||||
(int) (loadedImage.getHeight()
|
|
||||||
/ (loadedImage.getWidth() / notificationThumbnailWidth)),
|
|
||||||
true);
|
|
||||||
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Thumbnail - onLoadingComplete() called with: "
|
|
||||||
+ "imageUri = [" + imageUri + "], view = [" + view + "], "
|
|
||||||
+ "loadedImage = [" + loadedImage + "], "
|
|
||||||
+ loadedImage.getWidth() + "x" + loadedImage.getHeight()
|
|
||||||
+ ", scaled notification width = " + notificationThumbnailWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
|
|
||||||
|
|
||||||
// there is a new thumbnail, thus the end screen thumbnail needs to be changed, too.
|
|
||||||
updateEndScreenThumbnail();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingCancelled(final String imageUri, final View view) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Thumbnail - onLoadingCancelled() called with: "
|
|
||||||
+ "imageUri = [" + imageUri + "], view = [" + view + "]");
|
|
||||||
}
|
|
||||||
currentThumbnail = null;
|
|
||||||
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
|
|
||||||
}
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,11 +5,9 @@ import android.text.TextUtils;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
|
|
||||||
public class PlayQueueItemBuilder {
|
public class PlayQueueItemBuilder {
|
||||||
private static final String TAG = PlayQueueItemBuilder.class.toString();
|
private static final String TAG = PlayQueueItemBuilder.class.toString();
|
||||||
@ -35,8 +33,7 @@ public class PlayQueueItemBuilder {
|
|||||||
holder.itemDurationView.setVisibility(View.GONE);
|
holder.itemDurationView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageLoader.getInstance().displayImage(item.getThumbnailUrl(), holder.itemThumbnailView,
|
PicassoHelper.loadThumbnail(item.getThumbnailUrl()).into(holder.itemThumbnailView);
|
||||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
|
|
||||||
|
|
||||||
holder.itemRoot.setOnClickListener(view -> {
|
holder.itemRoot.setOnClickListener(view -> {
|
||||||
if (onItemClickListener != null) {
|
if (onItemClickListener != null) {
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
package org.schabi.newpipe.player.seekbarpreview;
|
package org.schabi.newpipe.player.seekbarpreview;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper.SeekbarPreviewThumbnailType;
|
||||||
|
|
||||||
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.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.stream.Frameset;
|
import org.schabi.newpipe.extractor.stream.Frameset;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -21,11 +23,8 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper.SeekbarPreviewThumbnailType;
|
|
||||||
|
|
||||||
public class SeekbarPreviewThumbnailHolder {
|
public class SeekbarPreviewThumbnailHolder {
|
||||||
|
|
||||||
// This has to be <= 23 chars on devices running Android 7 or lower (API <= 25)
|
// This has to be <= 23 chars on devices running Android 7 or lower (API <= 25)
|
||||||
@ -174,6 +173,7 @@ public class SeekbarPreviewThumbnailHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Bitmap getBitMapFrom(final String url) {
|
private Bitmap getBitMapFrom(final String url) {
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
Log.w(TAG, "url is null; This should never happen");
|
Log.w(TAG, "url is null; This should never happen");
|
||||||
@ -182,24 +182,11 @@ public class SeekbarPreviewThumbnailHolder {
|
|||||||
|
|
||||||
final Stopwatch sw = Log.isLoggable(TAG, Log.DEBUG) ? Stopwatch.createStarted() : null;
|
final Stopwatch sw = Log.isLoggable(TAG, Log.DEBUG) ? Stopwatch.createStarted() : null;
|
||||||
try {
|
try {
|
||||||
final SyncImageLoadingListener syncImageLoadingListener =
|
|
||||||
new SyncImageLoadingListener();
|
|
||||||
|
|
||||||
Log.d(TAG, "Downloading bitmap for seekbarPreview from '" + url + "'");
|
Log.d(TAG, "Downloading bitmap for seekbarPreview from '" + url + "'");
|
||||||
|
|
||||||
// Ensure that everything is running
|
// Gets the bitmap within the timeout of 15 seconds imposed by default by OkHttpClient
|
||||||
ImageLoader.getInstance().resume();
|
|
||||||
// Load the image
|
|
||||||
// Impl-Note:
|
|
||||||
// Ensure that your are not running on the main-Thread this will otherwise hang
|
// Ensure that your are not running on the main-Thread this will otherwise hang
|
||||||
ImageLoader.getInstance().loadImage(
|
final Bitmap bitmap = PicassoHelper.loadSeekbarThumbnailPreview(url).get();
|
||||||
url,
|
|
||||||
ImageDisplayConstants.DISPLAY_SEEKBAR_PREVIEW_OPTIONS,
|
|
||||||
syncImageLoadingListener);
|
|
||||||
|
|
||||||
// Get the bitmap within the timeout
|
|
||||||
final Bitmap bitmap =
|
|
||||||
syncImageLoadingListener.waitForBitmapOrThrow(30, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
if (sw != null) {
|
if (sw != null) {
|
||||||
Log.d(TAG,
|
Log.d(TAG,
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
package org.schabi.newpipe.player.seekbarpreview;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
|
||||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
|
||||||
|
|
||||||
import java.util.concurrent.CancellationException;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener for synchronously downloading of an image/bitmap.
|
|
||||||
*/
|
|
||||||
public class SyncImageLoadingListener extends SimpleImageLoadingListener {
|
|
||||||
|
|
||||||
private final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
private Bitmap bitmap;
|
|
||||||
private boolean cancelled = false;
|
|
||||||
private FailReason failReason = null;
|
|
||||||
|
|
||||||
@SuppressWarnings("checkstyle:HiddenField")
|
|
||||||
@Override
|
|
||||||
public void onLoadingFailed(
|
|
||||||
final String imageUri,
|
|
||||||
final View view,
|
|
||||||
final FailReason failReason) {
|
|
||||||
|
|
||||||
this.failReason = failReason;
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingComplete(
|
|
||||||
final String imageUri,
|
|
||||||
final View view,
|
|
||||||
final Bitmap loadedImage) {
|
|
||||||
|
|
||||||
bitmap = loadedImage;
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingCancelled(final String imageUri, final View view) {
|
|
||||||
cancelled = true;
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap waitForBitmapOrThrow(final long timeout, final TimeUnit timeUnit)
|
|
||||||
throws InterruptedException, TimeoutException {
|
|
||||||
|
|
||||||
// Wait for the download to finish
|
|
||||||
if (!countDownLatch.await(timeout, timeUnit)) {
|
|
||||||
throw new TimeoutException("Couldn't get the image in time");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isCancelled()) {
|
|
||||||
throw new CancellationException("Download of image was cancelled");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getFailReason() != null) {
|
|
||||||
throw new RuntimeException("Failed to download image" + getFailReason().getType(),
|
|
||||||
getFailReason().getCause());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getBitmap() == null) {
|
|
||||||
throw new NullPointerException("Bitmap is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
return getBitmap();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap getBitmap() {
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCancelled() {
|
|
||||||
return cancelled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FailReason getFailReason() {
|
|
||||||
return failReason;
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,8 +17,6 @@ import androidx.core.content.ContextCompat;
|
|||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.DownloaderImpl;
|
import org.schabi.newpipe.DownloaderImpl;
|
||||||
import org.schabi.newpipe.NewPipeDatabase;
|
import org.schabi.newpipe.NewPipeDatabase;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
@ -29,6 +27,7 @@ import org.schabi.newpipe.extractor.localization.ContentCountry;
|
|||||||
import org.schabi.newpipe.extractor.localization.Localization;
|
import org.schabi.newpipe.extractor.localization.Localization;
|
||||||
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.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.ZipHelper;
|
import org.schabi.newpipe.util.ZipHelper;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -50,7 +49,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||||||
private ContentSettingsManager manager;
|
private ContentSettingsManager manager;
|
||||||
|
|
||||||
private String importExportDataPathKey;
|
private String importExportDataPathKey;
|
||||||
private String thumbnailLoadToggleKey;
|
|
||||||
private String youtubeRestrictedModeEnabledKey;
|
private String youtubeRestrictedModeEnabledKey;
|
||||||
|
|
||||||
private Localization initialSelectedLocalization;
|
private Localization initialSelectedLocalization;
|
||||||
@ -69,7 +67,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||||||
manager.deleteSettingsFile();
|
manager.deleteSettingsFile();
|
||||||
|
|
||||||
importExportDataPathKey = getString(R.string.import_export_data_path);
|
importExportDataPathKey = getString(R.string.import_export_data_path);
|
||||||
thumbnailLoadToggleKey = getString(R.string.download_thumbnail_key);
|
|
||||||
youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled);
|
youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled);
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.content_settings);
|
addPreferencesFromResource(R.xml.content_settings);
|
||||||
@ -112,20 +109,24 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||||||
if (defaultPreferences.getString(getString(R.string.recaptcha_cookies_key), "").isEmpty()) {
|
if (defaultPreferences.getString(getString(R.string.recaptcha_cookies_key), "").isEmpty()) {
|
||||||
clearCookiePref.setVisible(false);
|
clearCookiePref.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findPreference(getString(R.string.download_thumbnail_key)).setOnPreferenceChangeListener(
|
||||||
|
(preference, newValue) -> {
|
||||||
|
PicassoHelper.setShouldLoadImages((Boolean) newValue);
|
||||||
|
try {
|
||||||
|
PicassoHelper.clearCache(preference.getContext());
|
||||||
|
Toast.makeText(preference.getContext(),
|
||||||
|
R.string.thumbnail_cache_wipe_complete_notice, Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
} catch (final IOException e) {
|
||||||
|
Log.e(TAG, "Unable to clear Picasso cache", e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceTreeClick(final Preference preference) {
|
public boolean onPreferenceTreeClick(final Preference preference) {
|
||||||
if (preference.getKey().equals(thumbnailLoadToggleKey)) {
|
|
||||||
final ImageLoader imageLoader = ImageLoader.getInstance();
|
|
||||||
imageLoader.stop();
|
|
||||||
imageLoader.clearDiskCache();
|
|
||||||
imageLoader.clearMemoryCache();
|
|
||||||
imageLoader.resume();
|
|
||||||
Toast.makeText(preference.getContext(), R.string.thumbnail_cache_wipe_complete_notice,
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preference.getKey().equals(youtubeRestrictedModeEnabledKey)) {
|
if (preference.getKey().equals(youtubeRestrictedModeEnabledKey)) {
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
|
@ -14,13 +14,11 @@ import androidx.fragment.app.DialogFragment;
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
|
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
|
||||||
import org.schabi.newpipe.error.ErrorActivity;
|
import org.schabi.newpipe.error.ErrorActivity;
|
||||||
import org.schabi.newpipe.local.subscription.SubscriptionManager;
|
import org.schabi.newpipe.local.subscription.SubscriptionManager;
|
||||||
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
import org.schabi.newpipe.util.ThemeHelper;
|
import org.schabi.newpipe.util.ThemeHelper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -54,13 +52,6 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class SelectChannelFragment extends DialogFragment {
|
public class SelectChannelFragment extends DialogFragment {
|
||||||
/**
|
|
||||||
* This contains the base display options for images.
|
|
||||||
*/
|
|
||||||
private static final DisplayImageOptions DISPLAY_IMAGE_OPTIONS
|
|
||||||
= new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
|
||||||
|
|
||||||
private final ImageLoader imageLoader = ImageLoader.getInstance();
|
|
||||||
|
|
||||||
private OnSelectedListener onSelectedListener = null;
|
private OnSelectedListener onSelectedListener = null;
|
||||||
private OnCancelListener onCancelListener = null;
|
private OnCancelListener onCancelListener = null;
|
||||||
@ -199,8 +190,7 @@ public class SelectChannelFragment extends DialogFragment {
|
|||||||
final SubscriptionEntity entry = subscriptions.get(position);
|
final SubscriptionEntity entry = subscriptions.get(position);
|
||||||
holder.titleView.setText(entry.getName());
|
holder.titleView.setText(entry.getName());
|
||||||
holder.view.setOnClickListener(view -> clickedItem(position));
|
holder.view.setOnClickListener(view -> clickedItem(position));
|
||||||
imageLoader.displayImage(entry.getAvatarUrl(), holder.thumbnailView,
|
PicassoHelper.loadAvatar(entry.getAvatarUrl()).into(holder.thumbnailView);
|
||||||
DISPLAY_IMAGE_OPTIONS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -14,9 +14,6 @@ import androidx.fragment.app.DialogFragment;
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.NewPipeDatabase;
|
import org.schabi.newpipe.NewPipeDatabase;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.database.AppDatabase;
|
import org.schabi.newpipe.database.AppDatabase;
|
||||||
@ -29,6 +26,7 @@ import org.schabi.newpipe.error.ErrorInfo;
|
|||||||
import org.schabi.newpipe.error.UserAction;
|
import org.schabi.newpipe.error.UserAction;
|
||||||
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
||||||
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
|
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
|
||||||
|
import org.schabi.newpipe.util.PicassoHelper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
@ -38,13 +36,6 @@ import io.reactivex.rxjava3.core.Flowable;
|
|||||||
import io.reactivex.rxjava3.disposables.Disposable;
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
|
||||||
public class SelectPlaylistFragment extends DialogFragment {
|
public class SelectPlaylistFragment extends DialogFragment {
|
||||||
/**
|
|
||||||
* This contains the base display options for images.
|
|
||||||
*/
|
|
||||||
private static final DisplayImageOptions DISPLAY_IMAGE_OPTIONS
|
|
||||||
= new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
|
||||||
|
|
||||||
private final ImageLoader imageLoader = ImageLoader.getInstance();
|
|
||||||
|
|
||||||
private OnSelectedListener onSelectedListener = null;
|
private OnSelectedListener onSelectedListener = null;
|
||||||
|
|
||||||
@ -170,16 +161,15 @@ public class SelectPlaylistFragment extends DialogFragment {
|
|||||||
|
|
||||||
holder.titleView.setText(entry.name);
|
holder.titleView.setText(entry.name);
|
||||||
holder.view.setOnClickListener(view -> clickedItem(position));
|
holder.view.setOnClickListener(view -> clickedItem(position));
|
||||||
imageLoader.displayImage(entry.thumbnailUrl, holder.thumbnailView,
|
PicassoHelper.loadPlaylistThumbnail(entry.thumbnailUrl).into(holder.thumbnailView);
|
||||||
DISPLAY_IMAGE_OPTIONS);
|
|
||||||
|
|
||||||
} else if (selectedItem instanceof PlaylistRemoteEntity) {
|
} else if (selectedItem instanceof PlaylistRemoteEntity) {
|
||||||
final PlaylistRemoteEntity entry = ((PlaylistRemoteEntity) selectedItem);
|
final PlaylistRemoteEntity entry = ((PlaylistRemoteEntity) selectedItem);
|
||||||
|
|
||||||
holder.titleView.setText(entry.getName());
|
holder.titleView.setText(entry.getName());
|
||||||
holder.view.setOnClickListener(view -> clickedItem(position));
|
holder.view.setOnClickListener(view -> clickedItem(position));
|
||||||
imageLoader.displayImage(entry.getThumbnailUrl(), holder.thumbnailView,
|
PicassoHelper.loadPlaylistThumbnail(entry.getThumbnailUrl())
|
||||||
DISPLAY_IMAGE_OPTIONS);
|
.into(holder.thumbnailView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
package org.schabi.newpipe.util;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
|
||||||
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
|
|
||||||
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
|
||||||
|
|
||||||
public final class ImageDisplayConstants {
|
|
||||||
private static final int BITMAP_FADE_IN_DURATION_MILLIS = 250;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant contains the base display options.
|
|
||||||
*/
|
|
||||||
private static final DisplayImageOptions BASE_DISPLAY_IMAGE_OPTIONS =
|
|
||||||
new DisplayImageOptions.Builder()
|
|
||||||
.cacheInMemory(true)
|
|
||||||
.cacheOnDisk(true)
|
|
||||||
.resetViewBeforeLoading(true)
|
|
||||||
.bitmapConfig(Bitmap.Config.RGB_565)
|
|
||||||
.imageScaleType(ImageScaleType.EXACTLY)
|
|
||||||
.displayer(new FadeInBitmapDisplayer(BITMAP_FADE_IN_DURATION_MILLIS))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
|
||||||
// DisplayImageOptions default configurations
|
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
|
||||||
|
|
||||||
public static final DisplayImageOptions DISPLAY_AVATAR_OPTIONS =
|
|
||||||
new DisplayImageOptions.Builder()
|
|
||||||
.cloneFrom(BASE_DISPLAY_IMAGE_OPTIONS)
|
|
||||||
.showImageForEmptyUri(R.drawable.buddy)
|
|
||||||
.showImageOnFail(R.drawable.buddy)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
public static final DisplayImageOptions DISPLAY_THUMBNAIL_OPTIONS =
|
|
||||||
new DisplayImageOptions.Builder()
|
|
||||||
.cloneFrom(BASE_DISPLAY_IMAGE_OPTIONS)
|
|
||||||
.showImageForEmptyUri(R.drawable.dummy_thumbnail)
|
|
||||||
.showImageOnFail(R.drawable.dummy_thumbnail)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
public static final DisplayImageOptions DISPLAY_BANNER_OPTIONS =
|
|
||||||
new DisplayImageOptions.Builder()
|
|
||||||
.cloneFrom(BASE_DISPLAY_IMAGE_OPTIONS)
|
|
||||||
.showImageForEmptyUri(R.drawable.channel_banner)
|
|
||||||
.showImageOnFail(R.drawable.channel_banner)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
public static final DisplayImageOptions DISPLAY_PLAYLIST_OPTIONS =
|
|
||||||
new DisplayImageOptions.Builder()
|
|
||||||
.cloneFrom(BASE_DISPLAY_IMAGE_OPTIONS)
|
|
||||||
.showImageForEmptyUri(R.drawable.dummy_thumbnail_playlist)
|
|
||||||
.showImageOnFail(R.drawable.dummy_thumbnail_playlist)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
public static final DisplayImageOptions DISPLAY_SEEKBAR_PREVIEW_OPTIONS =
|
|
||||||
new DisplayImageOptions.Builder()
|
|
||||||
.cloneFrom(BASE_DISPLAY_IMAGE_OPTIONS)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private ImageDisplayConstants() { }
|
|
||||||
}
|
|
@ -18,8 +18,6 @@ import androidx.fragment.app.Fragment;
|
|||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.MainActivity;
|
import org.schabi.newpipe.MainActivity;
|
||||||
import org.schabi.newpipe.NewPipeDatabase;
|
import org.schabi.newpipe.NewPipeDatabase;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
@ -259,10 +257,9 @@ public final class NavigationHelper {
|
|||||||
if (context instanceof Activity) {
|
if (context instanceof Activity) {
|
||||||
new AlertDialog.Builder(context)
|
new AlertDialog.Builder(context)
|
||||||
.setMessage(R.string.no_player_found)
|
.setMessage(R.string.no_player_found)
|
||||||
.setPositiveButton(R.string.install, (dialog, which) -> {
|
.setPositiveButton(R.string.install,
|
||||||
ShareUtils.openUrlInBrowser(context,
|
(dialog, which) -> ShareUtils.openUrlInBrowser(context,
|
||||||
context.getString(R.string.fdroid_vlc_url), false);
|
context.getString(R.string.fdroid_vlc_url), false))
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.cancel, (dialog, which)
|
.setNegativeButton(R.string.cancel, (dialog, which)
|
||||||
-> Log.i("NavigationHelper", "You unlocked a secret unicorn."))
|
-> Log.i("NavigationHelper", "You unlocked a secret unicorn."))
|
||||||
.show();
|
.show();
|
||||||
@ -284,8 +281,6 @@ public final class NavigationHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void gotoMainFragment(final FragmentManager fragmentManager) {
|
public static void gotoMainFragment(final FragmentManager fragmentManager) {
|
||||||
ImageLoader.getInstance().clearMemoryCache();
|
|
||||||
|
|
||||||
final boolean popped = fragmentManager.popBackStackImmediate(MAIN_FRAGMENT_TAG, 0);
|
final boolean popped = fragmentManager.popBackStackImmediate(MAIN_FRAGMENT_TAG, 0);
|
||||||
if (!popped) {
|
if (!popped) {
|
||||||
openMainFragment(fragmentManager);
|
openMainFragment(fragmentManager);
|
||||||
|
110
app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java
Normal file
110
app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package org.schabi.newpipe.util;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import com.squareup.picasso.Cache;
|
||||||
|
import com.squareup.picasso.LruCache;
|
||||||
|
import com.squareup.picasso.OkHttp3Downloader;
|
||||||
|
import com.squareup.picasso.Picasso;
|
||||||
|
import com.squareup.picasso.RequestCreator;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.R;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
|
||||||
|
|
||||||
|
public final class PicassoHelper {
|
||||||
|
|
||||||
|
private PicassoHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Cache picassoCache;
|
||||||
|
private static OkHttpClient picassoDownloaderClient;
|
||||||
|
|
||||||
|
// suppress because terminate() is called in App.onTerminate(), preventing leaks
|
||||||
|
@SuppressLint("StaticFieldLeak")
|
||||||
|
private static Picasso picassoInstance;
|
||||||
|
|
||||||
|
private static boolean shouldLoadImages;
|
||||||
|
|
||||||
|
public static void init(final Context context) {
|
||||||
|
picassoCache = new LruCache(10 * 1024 * 1024);
|
||||||
|
picassoDownloaderClient = new OkHttpClient.Builder()
|
||||||
|
.cache(new okhttp3.Cache(new File(context.getExternalCacheDir(), "picasso"),
|
||||||
|
50 * 1024 * 1024))
|
||||||
|
// this should already be the default timeout in OkHttp3, but just to be sure...
|
||||||
|
.callTimeout(15, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
picassoInstance = new Picasso.Builder(context)
|
||||||
|
.memoryCache(picassoCache) // memory cache
|
||||||
|
.downloader(new OkHttp3Downloader(picassoDownloaderClient)) // disk cache
|
||||||
|
.defaultBitmapConfig(Bitmap.Config.RGB_565)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void terminate() {
|
||||||
|
picassoCache = null;
|
||||||
|
picassoDownloaderClient = null;
|
||||||
|
|
||||||
|
if (picassoInstance != null) {
|
||||||
|
picassoInstance.shutdown();
|
||||||
|
picassoInstance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearCache(final Context context) throws IOException {
|
||||||
|
picassoInstance.shutdown();
|
||||||
|
picassoCache.clear(); // clear memory cache
|
||||||
|
picassoDownloaderClient.cache().delete(); // clear disk cache
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelTag(final Object tag) {
|
||||||
|
picassoInstance.cancelTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setShouldLoadImages(final boolean shouldLoadImages) {
|
||||||
|
PicassoHelper.shouldLoadImages = shouldLoadImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean getShouldLoadImages() {
|
||||||
|
return shouldLoadImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static RequestCreator loadAvatar(final String url) {
|
||||||
|
return loadImageDefault(url, R.drawable.buddy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestCreator loadThumbnail(final String url) {
|
||||||
|
return loadImageDefault(url, R.drawable.dummy_thumbnail);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestCreator loadBanner(final String url) {
|
||||||
|
return loadImageDefault(url, R.drawable.channel_banner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestCreator loadPlaylistThumbnail(final String url) {
|
||||||
|
return loadImageDefault(url, R.drawable.dummy_thumbnail_playlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestCreator loadSeekbarThumbnailPreview(final String url) {
|
||||||
|
return picassoInstance.load(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static RequestCreator loadImageDefault(final String url, final int placeholderResId) {
|
||||||
|
return picassoInstance
|
||||||
|
.load((!shouldLoadImages || isBlank(url)) ? null : url)
|
||||||
|
.placeholder(placeholderResId)
|
||||||
|
.error(placeholderResId);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user