From 2ac0d1f13a808a377fd9b8ebaa4e416d0059809c Mon Sep 17 00:00:00 2001
From: Christian Schabesberger
Date: Tue, 2 Jul 2024 09:31:34 +0200
Subject: [PATCH 001/134] add NP icon for Android Studio's NewUI
---
.idea/icon.svg | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 .idea/icon.svg
diff --git a/.idea/icon.svg b/.idea/icon.svg
new file mode 100644
index 000000000..51fdf95de
--- /dev/null
+++ b/.idea/icon.svg
@@ -0,0 +1,21 @@
+
+
+
From 73e3a69aaf78a1d7a7f2f4c54e22d718b7c3093a Mon Sep 17 00:00:00 2001
From: Isira Seneviratne <31027858+Isira-Seneviratne@users.noreply.github.com>
Date: Wed, 3 Jul 2024 18:53:04 +0530
Subject: [PATCH 002/134] Migrate image loading from Picasso to Coil (#11201)
* Load notification icons using Coil
* Migrate to Coil from Picasso
* Clean up Picasso leftovers
* Enable RGB-565 for low-end devices
* Added Coil helper method
* Add annotation
* Simplify newImageLoader implementation
* Use Coil's default disk and memory cache config
* Enable crossfade animation
* Correct method name
* Fix thumbnail not being displayed in media notification
---
app/build.gradle | 3 +-
app/src/main/java/org/schabi/newpipe/App.java | 24 +-
.../org/schabi/newpipe/about/AboutActivity.kt | 4 +-
.../fragments/detail/VideoDetailFragment.java | 29 +--
.../list/channel/ChannelFragment.java | 20 +-
.../list/comments/CommentRepliesFragment.java | 4 +-
.../list/playlist/PlaylistFragment.java | 11 +-
.../newpipe/info_list/StreamSegmentItem.kt | 44 ++--
.../holder/ChannelMiniInfoItemHolder.java | 4 +-
.../holder/CommentInfoItemHolder.java | 8 +-
.../holder/PlaylistMiniInfoItemHolder.java | 4 +-
.../holder/StreamMiniInfoItemHolder.java | 4 +-
.../java/org/schabi/newpipe/ktx/Bitmap.kt | 13 +
.../newpipe/local/feed/item/StreamItem.kt | 4 +-
.../feed/notifications/NotificationHelper.kt | 58 +----
.../local/holder/LocalPlaylistItemHolder.java | 7 +-
.../holder/LocalPlaylistStreamItemHolder.java | 6 +-
.../LocalStatisticStreamItemHolder.java | 6 +-
.../holder/RemotePlaylistItemHolder.java | 7 +-
.../local/subscription/item/ChannelItem.kt | 4 +-
.../item/PickerSubscriptionItem.kt | 4 +-
.../org/schabi/newpipe/player/Player.java | 87 +++----
.../playqueue/PlayQueueItemBuilder.java | 4 +-
.../SeekbarPreviewThumbnailHolder.java | 7 +-
.../settings/ContentSettingsFragment.java | 20 +-
.../settings/DebugSettingsFragment.java | 9 -
.../settings/SelectChannelFragment.java | 4 +-
.../settings/SelectPlaylistFragment.java | 17 +-
.../external_communication/ShareUtils.java | 21 +-
.../schabi/newpipe/util/image/CoilHelper.kt | 142 +++++++++++
.../newpipe/util/image/PicassoHelper.java | 224 ------------------
app/src/main/res/values-ar-rLY/strings.xml | 2 -
app/src/main/res/values-ar/strings.xml | 2 -
app/src/main/res/values-az/strings.xml | 2 -
app/src/main/res/values-be/strings.xml | 2 -
app/src/main/res/values-bg/strings.xml | 1 -
app/src/main/res/values-bn/strings.xml | 1 -
app/src/main/res/values-ca/strings.xml | 2 -
app/src/main/res/values-ckb/strings.xml | 2 -
app/src/main/res/values-cs/strings.xml | 2 -
app/src/main/res/values-da/strings.xml | 2 -
app/src/main/res/values-de/strings.xml | 2 -
app/src/main/res/values-el/strings.xml | 2 -
app/src/main/res/values-es/strings.xml | 2 -
app/src/main/res/values-et/strings.xml | 2 -
app/src/main/res/values-eu/strings.xml | 2 -
app/src/main/res/values-fa/strings.xml | 2 -
app/src/main/res/values-fi/strings.xml | 2 -
app/src/main/res/values-fr/strings.xml | 2 -
app/src/main/res/values-gl/strings.xml | 2 -
app/src/main/res/values-he/strings.xml | 2 -
app/src/main/res/values-hi/strings.xml | 2 -
app/src/main/res/values-hr/strings.xml | 2 -
app/src/main/res/values-hu/strings.xml | 2 -
app/src/main/res/values-in/strings.xml | 2 -
app/src/main/res/values-is/strings.xml | 2 -
app/src/main/res/values-it/strings.xml | 2 -
app/src/main/res/values-ja/strings.xml | 2 -
app/src/main/res/values-ka/strings.xml | 2 -
app/src/main/res/values-ko/strings.xml | 2 -
app/src/main/res/values-lt/strings.xml | 2 -
app/src/main/res/values-lv/strings.xml | 2 -
app/src/main/res/values-ml/strings.xml | 2 -
app/src/main/res/values-nb-rNO/strings.xml | 2 -
app/src/main/res/values-nl-rBE/strings.xml | 1 -
app/src/main/res/values-nl/strings.xml | 2 -
app/src/main/res/values-nqo/strings.xml | 2 -
app/src/main/res/values-or/strings.xml | 2 -
app/src/main/res/values-pa/strings.xml | 2 -
app/src/main/res/values-pl/strings.xml | 2 -
app/src/main/res/values-pt-rBR/strings.xml | 2 -
app/src/main/res/values-pt-rPT/strings.xml | 2 -
app/src/main/res/values-pt/strings.xml | 2 -
app/src/main/res/values-ro/strings.xml | 2 -
app/src/main/res/values-ru/strings.xml | 2 -
app/src/main/res/values-ryu/strings.xml | 2 -
app/src/main/res/values-sat/strings.xml | 2 -
app/src/main/res/values-sc/strings.xml | 2 -
app/src/main/res/values-sk/strings.xml | 2 -
app/src/main/res/values-so/strings.xml | 2 -
app/src/main/res/values-sr/strings.xml | 2 -
app/src/main/res/values-sv/strings.xml | 2 -
app/src/main/res/values-te/strings.xml | 2 -
app/src/main/res/values-tr/strings.xml | 2 -
app/src/main/res/values-uk/strings.xml | 2 -
app/src/main/res/values-vi/strings.xml | 2 -
app/src/main/res/values-zh-rCN/strings.xml | 2 -
app/src/main/res/values-zh-rHK/strings.xml | 2 -
app/src/main/res/values-zh-rTW/strings.xml | 2 -
app/src/main/res/values/settings_keys.xml | 1 -
app/src/main/res/values/strings.xml | 2 -
app/src/main/res/xml/debug_settings.xml | 7 -
92 files changed, 330 insertions(+), 596 deletions(-)
create mode 100644 app/src/main/java/org/schabi/newpipe/ktx/Bitmap.kt
create mode 100644 app/src/main/java/org/schabi/newpipe/util/image/CoilHelper.kt
delete mode 100644 app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java
diff --git a/app/build.gradle b/app/build.gradle
index 4652cf6e5..1ba5aca38 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -267,8 +267,7 @@ dependencies {
implementation "com.github.lisawray.groupie:groupie-viewbinding:${groupieVersion}"
// Image loading
- //noinspection GradleDependency --> 2.8 is the last version, not 2.71828!
- implementation "com.squareup.picasso:picasso:2.8"
+ implementation 'io.coil-kt:coil:2.6.0'
// Markdown library for Android
implementation "io.noties.markwon:core:${markwonVersion}"
diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java
index d92425d20..a47e0f2fd 100644
--- a/app/src/main/java/org/schabi/newpipe/App.java
+++ b/app/src/main/java/org/schabi/newpipe/App.java
@@ -1,5 +1,6 @@
package org.schabi.newpipe;
+import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
@@ -8,6 +9,7 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationChannelCompat;
import androidx.core.app.NotificationManagerCompat;
+import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import com.jakewharton.processphoenix.ProcessPhoenix;
@@ -20,10 +22,9 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.settings.NewPipeSettings;
import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.image.ImageStrategy;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.StateSaver;
+import org.schabi.newpipe.util.image.ImageStrategy;
import org.schabi.newpipe.util.image.PreferredImageQuality;
import java.io.IOException;
@@ -32,6 +33,9 @@ import java.net.SocketException;
import java.util.List;
import java.util.Objects;
+import coil.ImageLoader;
+import coil.ImageLoaderFactory;
+import coil.util.DebugLogger;
import io.reactivex.rxjava3.exceptions.CompositeException;
import io.reactivex.rxjava3.exceptions.MissingBackpressureException;
import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException;
@@ -57,7 +61,7 @@ import io.reactivex.rxjava3.plugins.RxJavaPlugins;
* along with NewPipe. If not, see .
*/
-public class App extends Application {
+public class App extends Application implements ImageLoaderFactory {
public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
private static final String TAG = App.class.toString();
@@ -108,20 +112,22 @@ public class App extends Application {
// Initialize image loader
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- PicassoHelper.init(this);
ImageStrategy.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this,
prefs.getString(getString(R.string.image_quality_key),
getString(R.string.image_quality_default))));
- PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG
- && prefs.getBoolean(getString(R.string.show_image_indicators_key), false));
configureRxJavaErrorHandler();
}
+ @NonNull
@Override
- public void onTerminate() {
- super.onTerminate();
- PicassoHelper.terminate();
+ public ImageLoader newImageLoader() {
+ return new ImageLoader.Builder(this)
+ .allowRgb565(ContextCompat.getSystemService(this, ActivityManager.class)
+ .isLowRamDevice())
+ .logger(BuildConfig.DEBUG ? new DebugLogger() : null)
+ .crossfade(true)
+ .build();
}
protected Downloader getDownloader() {
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
index 7f148e9b5..0d0d0d48d 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
@@ -167,8 +167,8 @@ class AboutActivity : AppCompatActivity() {
"https://square.github.io/okhttp/", StandardLicenses.APACHE2
),
SoftwareComponent(
- "Picasso", "2013", "Square, Inc.",
- "https://square.github.io/picasso/", StandardLicenses.APACHE2
+ "Coil", "2023", "Coil Contributors",
+ "https://coil-kt.github.io/coil/", StandardLicenses.APACHE2
),
SoftwareComponent(
"PrettyTime", "2012 - 2020", "Lincoln Baxter, III",
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
index 95b54f65a..96523321b 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
@@ -116,7 +116,7 @@ import org.schabi.newpipe.util.StreamTypeUtil;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.external_communication.KoreUtils;
import org.schabi.newpipe.util.external_communication.ShareUtils;
-import org.schabi.newpipe.util.image.PicassoHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
import java.util.ArrayList;
import java.util.Iterator;
@@ -127,6 +127,7 @@ import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
+import coil.util.CoilUtils;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
@@ -159,8 +160,6 @@ public final class VideoDetailFragment
private static final String DESCRIPTION_TAB_TAG = "DESCRIPTION TAB";
private static final String EMPTY_TAB_TAG = "EMPTY TAB";
- private static final String PICASSO_VIDEO_DETAILS_TAG = "PICASSO_VIDEO_DETAILS_TAG";
-
// tabs
private boolean showComments;
private boolean showRelatedItems;
@@ -1471,7 +1470,10 @@ public final class VideoDetailFragment
}
}
- PicassoHelper.cancelTag(PICASSO_VIDEO_DETAILS_TAG);
+ CoilUtils.dispose(binding.detailThumbnailImageView);
+ CoilUtils.dispose(binding.detailSubChannelThumbnailView);
+ CoilUtils.dispose(binding.overlayThumbnail);
+
binding.detailThumbnailImageView.setImageBitmap(null);
binding.detailSubChannelThumbnailView.setImageBitmap(null);
}
@@ -1562,8 +1564,8 @@ public final class VideoDetailFragment
binding.detailSecondaryControlPanel.setVisibility(View.GONE);
checkUpdateProgressInfo(info);
- PicassoHelper.loadDetailsThumbnail(info.getThumbnails()).tag(PICASSO_VIDEO_DETAILS_TAG)
- .into(binding.detailThumbnailImageView);
+ CoilHelper.INSTANCE.loadDetailsThumbnail(binding.detailThumbnailImageView,
+ info.getThumbnails());
showMetaInfoInTextView(info.getMetaInfo(), binding.detailMetaInfoTextView,
binding.detailMetaInfoSeparator, disposables);
@@ -1613,8 +1615,8 @@ public final class VideoDetailFragment
binding.detailUploaderTextView.setVisibility(View.GONE);
}
- PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG)
- .into(binding.detailSubChannelThumbnailView);
+ CoilHelper.INSTANCE.loadAvatar(binding.detailSubChannelThumbnailView,
+ info.getUploaderAvatars());
binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE);
binding.detailUploaderThumbnailView.setVisibility(View.GONE);
}
@@ -1645,11 +1647,11 @@ public final class VideoDetailFragment
binding.detailUploaderTextView.setVisibility(View.GONE);
}
- PicassoHelper.loadAvatar(info.getSubChannelAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG)
- .into(binding.detailSubChannelThumbnailView);
+ CoilHelper.INSTANCE.loadAvatar(binding.detailSubChannelThumbnailView,
+ info.getSubChannelAvatars());
binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE);
- PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG)
- .into(binding.detailUploaderThumbnailView);
+ CoilHelper.INSTANCE.loadAvatar(binding.detailUploaderThumbnailView,
+ info.getUploaderAvatars());
binding.detailUploaderThumbnailView.setVisibility(View.VISIBLE);
}
@@ -2403,8 +2405,7 @@ public final class VideoDetailFragment
binding.overlayTitleTextView.setText(isEmpty(overlayTitle) ? "" : overlayTitle);
binding.overlayChannelTextView.setText(isEmpty(uploader) ? "" : uploader);
binding.overlayThumbnail.setImageDrawable(null);
- PicassoHelper.loadDetailsThumbnail(thumbnails).tag(PICASSO_VIDEO_DETAILS_TAG)
- .into(binding.overlayThumbnail);
+ CoilHelper.INSTANCE.loadDetailsThumbnail(binding.overlayThumbnail, thumbnails);
}
private void setOverlayPlayPauseImage(final boolean playerIsPlaying) {
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
index fd382adbf..3890e4865 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
@@ -50,15 +50,16 @@ import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.StateSaver;
-import org.schabi.newpipe.util.image.ImageStrategy;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
+import org.schabi.newpipe.util.image.CoilHelper;
+import org.schabi.newpipe.util.image.ImageStrategy;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
+import coil.util.CoilUtils;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
@@ -73,7 +74,6 @@ public class ChannelFragment extends BaseStateFragment
implements StateSaver.WriteRead {
private static final int BUTTON_DEBOUNCE_INTERVAL = 100;
- private static final String PICASSO_CHANNEL_TAG = "PICASSO_CHANNEL_TAG";
@State
protected int serviceId = Constants.NO_SERVICE_ID;
@@ -576,7 +576,9 @@ public class ChannelFragment extends BaseStateFragment
@Override
public void showLoading() {
super.showLoading();
- PicassoHelper.cancelTag(PICASSO_CHANNEL_TAG);
+ CoilUtils.dispose(binding.channelAvatarView);
+ CoilUtils.dispose(binding.channelBannerImage);
+ CoilUtils.dispose(binding.subChannelAvatarView);
animate(binding.channelSubscribeButton, false, 100);
}
@@ -587,17 +589,15 @@ public class ChannelFragment extends BaseStateFragment
setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName());
if (ImageStrategy.shouldLoadImages() && !result.getBanners().isEmpty()) {
- PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG)
- .into(binding.channelBannerImage);
+ CoilHelper.INSTANCE.loadBanner(binding.channelBannerImage, result.getBanners());
} else {
// do not waste space for the banner, if the user disabled images or there is not one
binding.channelBannerImage.setImageDrawable(null);
}
- PicassoHelper.loadAvatar(result.getAvatars()).tag(PICASSO_CHANNEL_TAG)
- .into(binding.channelAvatarView);
- PicassoHelper.loadAvatar(result.getParentChannelAvatars()).tag(PICASSO_CHANNEL_TAG)
- .into(binding.subChannelAvatarView);
+ CoilHelper.INSTANCE.loadAvatar(binding.channelAvatarView, result.getAvatars());
+ CoilHelper.INSTANCE.loadAvatar(binding.subChannelAvatarView,
+ result.getParentChannelAvatars());
binding.channelTitleView.setText(result.getName());
binding.channelSubscriberView.setVisibility(View.VISIBLE);
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java
index 304eaf55a..4eb73520f 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java
@@ -23,8 +23,8 @@ import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.util.image.ImageStrategy;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.text.TextLinkifier;
import java.util.Queue;
@@ -82,7 +82,7 @@ public final class CommentRepliesFragment
final CommentsInfoItem item = commentsInfoItem;
// load the author avatar
- PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(binding.authorAvatar);
+ CoilHelper.INSTANCE.loadAvatar(binding.authorAvatar, item.getUploaderAvatars());
binding.authorAvatar.setVisibility(ImageStrategy.shouldLoadImages()
? View.VISIBLE : View.GONE);
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
index 6410fb9ee..d4607a9ff 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
@@ -53,7 +53,7 @@ import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PlayButtonHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
-import org.schabi.newpipe.util.image.PicassoHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.util.text.TextEllipsizer;
import java.util.ArrayList;
@@ -62,6 +62,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.stream.Collectors;
+import coil.util.CoilUtils;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Single;
@@ -71,8 +72,6 @@ import io.reactivex.rxjava3.disposables.Disposable;
public class PlaylistFragment extends BaseListInfoFragment
implements PlaylistControlViewHolder {
- private static final String PICASSO_PLAYLIST_TAG = "PICASSO_PLAYLIST_TAG";
-
private CompositeDisposable disposables;
private Subscription bookmarkReactor;
private AtomicBoolean isBookmarkButtonReady;
@@ -276,7 +275,7 @@ public class PlaylistFragment extends BaseListInfoFragment() {
+) : BindableItem() {
companion object {
const val PAYLOAD_SELECT = 1
@@ -21,31 +20,32 @@ class StreamSegmentItem(
var isSelected = false
- override fun bind(viewHolder: GroupieViewHolder, position: Int) {
- item.previewUrl?.let {
- PicassoHelper.loadThumbnail(it)
- .into(viewHolder.root.findViewById(R.id.previewImage))
- }
- viewHolder.root.findViewById(R.id.textViewTitle).text = item.title
+ override fun bind(viewBinding: ItemStreamSegmentBinding, position: Int) {
+ CoilHelper.loadThumbnail(viewBinding.previewImage, item.previewUrl)
+ viewBinding.textViewTitle.text = item.title
if (item.channelName == null) {
- viewHolder.root.findViewById(R.id.textViewChannel).visibility = View.GONE
+ viewBinding.textViewChannel.visibility = View.GONE
// When the channel name is displayed there is less space
// and thus the segment title needs to be only one line height.
// But when there is no channel name displayed, the title can be two lines long.
// The default maxLines value is set to 1 to display all elements in the AS preview,
- viewHolder.root.findViewById(R.id.textViewTitle).maxLines = 2
+ viewBinding.textViewTitle.maxLines = 2
} else {
- viewHolder.root.findViewById(R.id.textViewChannel).text = item.channelName
- viewHolder.root.findViewById(R.id.textViewChannel).visibility = View.VISIBLE
+ viewBinding.textViewChannel.text = item.channelName
+ viewBinding.textViewChannel.visibility = View.VISIBLE
}
- viewHolder.root.findViewById(R.id.textViewStartSeconds).text =
+ viewBinding.textViewStartSeconds.text =
Localization.getDurationString(item.startTimeSeconds.toLong())
- viewHolder.root.setOnClickListener { onClick.onItemClick(this, item.startTimeSeconds) }
- viewHolder.root.setOnLongClickListener { onClick.onItemLongClick(this, item.startTimeSeconds); true }
- viewHolder.root.isSelected = isSelected
+ viewBinding.root.setOnClickListener { onClick.onItemClick(this, item.startTimeSeconds) }
+ viewBinding.root.setOnLongClickListener { onClick.onItemLongClick(this, item.startTimeSeconds); true }
+ viewBinding.root.isSelected = isSelected
}
- override fun bind(viewHolder: GroupieViewHolder, position: Int, payloads: MutableList) {
+ override fun bind(
+ viewHolder: GroupieViewHolder,
+ position: Int,
+ payloads: MutableList
+ ) {
if (payloads.contains(PAYLOAD_SELECT)) {
viewHolder.root.isSelected = isSelected
return
@@ -54,4 +54,6 @@ class StreamSegmentItem(
}
override fun getLayout() = R.layout.item_stream_segment
+
+ override fun initializeViewBinding(view: View) = ItemStreamSegmentBinding.bind(view)
}
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java
index 7afc05c6c..92a5054e1 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java
@@ -13,8 +13,8 @@ import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.utils.Utils;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.image.CoilHelper;
public class ChannelMiniInfoItemHolder extends InfoItemHolder {
private final ImageView itemThumbnailView;
@@ -56,7 +56,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder {
itemAdditionalDetailView.setText(getDetailLine(item));
}
- PicassoHelper.loadAvatar(item.getThumbnails()).into(itemThumbnailView);
+ CoilHelper.INSTANCE.loadAvatar(itemThumbnailView, item.getThumbnails());
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnChannelSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java
index 839aa1813..a3316d3fe 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java
@@ -27,8 +27,8 @@ import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
+import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.util.image.ImageStrategy;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.text.TextEllipsizer;
public class CommentInfoItemHolder extends InfoItemHolder {
@@ -82,14 +82,12 @@ public class CommentInfoItemHolder extends InfoItemHolder {
@Override
public void updateFromItem(final InfoItem infoItem,
final HistoryRecordManager historyRecordManager) {
- if (!(infoItem instanceof CommentsInfoItem)) {
+ if (!(infoItem instanceof CommentsInfoItem item)) {
return;
}
- final CommentsInfoItem item = (CommentsInfoItem) infoItem;
-
// load the author avatar
- PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView);
+ CoilHelper.INSTANCE.loadAvatar(itemThumbnailView, item.getUploaderAvatars());
if (ImageStrategy.shouldLoadImages()) {
itemThumbnailView.setVisibility(View.VISIBLE);
itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding,
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java
index c9216d9a9..b7949318d 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java
@@ -9,8 +9,8 @@ import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.image.CoilHelper;
public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
public final ImageView itemThumbnailView;
@@ -46,7 +46,7 @@ public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
.localizeStreamCountMini(itemStreamCountView.getContext(), item.getStreamCount()));
itemUploaderView.setText(item.getUploaderName());
- PicassoHelper.loadPlaylistThumbnail(item.getThumbnails()).into(itemThumbnailView);
+ CoilHelper.INSTANCE.loadPlaylistThumbnail(itemThumbnailView, item.getThumbnails());
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnPlaylistSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java
index 01f3be6b3..32fa8bf60 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java
@@ -16,8 +16,8 @@ import org.schabi.newpipe.ktx.ViewUtils;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.StreamTypeUtil;
+import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.views.AnimatedProgressBar;
import java.util.concurrent.TimeUnit;
@@ -87,7 +87,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
}
// Default thumbnail is shown on error, while loading and if the url is empty
- PicassoHelper.loadThumbnail(item.getThumbnails()).into(itemThumbnailView);
+ CoilHelper.INSTANCE.loadThumbnail(itemThumbnailView, item.getThumbnails());
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnStreamSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/ktx/Bitmap.kt b/app/src/main/java/org/schabi/newpipe/ktx/Bitmap.kt
new file mode 100644
index 000000000..4a3c3e071
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/ktx/Bitmap.kt
@@ -0,0 +1,13 @@
+package org.schabi.newpipe.ktx
+
+import android.graphics.Bitmap
+import android.graphics.Rect
+import androidx.core.graphics.BitmapCompat
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun Bitmap.scale(
+ width: Int,
+ height: Int,
+ srcRect: Rect? = null,
+ scaleInLinearSpace: Boolean = true,
+) = BitmapCompat.createScaledBitmap(this, width, height, srcRect, scaleInLinearSpace)
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt
index 4a071d6df..030bb7a76 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt
@@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.stream.StreamType.POST_LIVE_STREAM
import org.schabi.newpipe.extractor.stream.StreamType.VIDEO_STREAM
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.StreamTypeUtil
-import org.schabi.newpipe.util.image.PicassoHelper
+import org.schabi.newpipe.util.image.CoilHelper
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
@@ -101,7 +101,7 @@ data class StreamItem(
viewBinding.itemProgressView.visibility = View.GONE
}
- PicassoHelper.loadThumbnail(stream.thumbnailUrl).into(viewBinding.itemThumbnailView)
+ CoilHelper.loadThumbnail(viewBinding.itemThumbnailView, stream.thumbnailUrl)
if (itemVersion != ItemVersion.MINI) {
viewBinding.itemAdditionalDetails.text =
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt
index 8ea89368d..659088ef2 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt
@@ -6,7 +6,6 @@ import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
-import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.provider.Settings
@@ -16,20 +15,17 @@ import androidx.core.app.PendingIntentCompat
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import androidx.preference.PreferenceManager
-import com.squareup.picasso.Picasso
-import com.squareup.picasso.Target
import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.local.feed.service.FeedUpdateInfo
import org.schabi.newpipe.util.NavigationHelper
-import org.schabi.newpipe.util.image.PicassoHelper
+import org.schabi.newpipe.util.image.CoilHelper
/**
* Helper for everything related to show notifications about new streams to the user.
*/
class NotificationHelper(val context: Context) {
private val manager = NotificationManagerCompat.from(context)
- private val iconLoadingTargets = ArrayList()
/**
* Show notifications for new streams from a single channel. The individual notifications are
@@ -68,51 +64,23 @@ class NotificationHelper(val context: Context) {
summaryBuilder.setStyle(style)
// open the channel page when clicking on the summary notification
+ val intent = NavigationHelper
+ .getChannelIntent(context, data.serviceId, data.url)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
summaryBuilder.setContentIntent(
- PendingIntentCompat.getActivity(
- context,
- data.pseudoId,
- NavigationHelper
- .getChannelIntent(context, data.serviceId, data.url)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
- 0,
- false
- )
+ PendingIntentCompat.getActivity(context, data.pseudoId, intent, 0, false)
)
- // a Target is like a listener for image loading events
- val target = object : Target {
- override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) {
- // set channel icon only if there is actually one (for Android versions < 7.0)
- summaryBuilder.setLargeIcon(bitmap)
+ val avatarIcon =
+ CoilHelper.loadBitmapBlocking(context, data.avatarUrl, R.drawable.ic_newpipe_triangle_white)
- // Show individual stream notifications, set channel icon only if there is actually
- // one
- showStreamNotifications(newStreams, data.serviceId, bitmap)
- // Show summary notification
- manager.notify(data.pseudoId, summaryBuilder.build())
+ summaryBuilder.setLargeIcon(avatarIcon)
- iconLoadingTargets.remove(this) // allow it to be garbage-collected
- }
-
- override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) {
- // Show individual stream notifications
- showStreamNotifications(newStreams, data.serviceId, null)
- // Show summary notification
- manager.notify(data.pseudoId, summaryBuilder.build())
- iconLoadingTargets.remove(this) // allow it to be garbage-collected
- }
-
- override fun onPrepareLoad(placeHolderDrawable: Drawable) {
- // Nothing to do
- }
- }
-
- // add the target to the list to hold a strong reference and prevent it from being garbage
- // collected, since Picasso only holds weak references to targets
- iconLoadingTargets.add(target)
-
- PicassoHelper.loadNotificationIcon(data.avatarUrl).into(target)
+ // Show individual stream notifications, set channel icon only if there is actually
+ // one
+ showStreamNotifications(newStreams, data.serviceId, avatarIcon)
+ // Show summary notification
+ manager.notify(data.pseudoId, summaryBuilder.build())
}
private fun showStreamNotifications(
diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java
index 336f5cfe3..a11438374 100644
--- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java
@@ -8,8 +8,8 @@ import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry;
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.image.CoilHelper;
import java.time.format.DateTimeFormatter;
@@ -30,17 +30,16 @@ public class LocalPlaylistItemHolder extends PlaylistItemHolder {
public void updateFromItem(final LocalItem localItem,
final HistoryRecordManager historyRecordManager,
final DateTimeFormatter dateTimeFormatter) {
- if (!(localItem instanceof PlaylistMetadataEntry)) {
+ if (!(localItem instanceof PlaylistMetadataEntry item)) {
return;
}
- final PlaylistMetadataEntry item = (PlaylistMetadataEntry) localItem;
itemTitleView.setText(item.name);
itemStreamCountView.setText(Localization.localizeStreamCountMini(
itemStreamCountView.getContext(), item.streamCount));
itemUploaderView.setVisibility(View.INVISIBLE);
- PicassoHelper.loadPlaylistThumbnail(item.thumbnailUrl).into(itemThumbnailView);
+ CoilHelper.INSTANCE.loadPlaylistThumbnail(itemThumbnailView, item.thumbnailUrl);
if (item instanceof PlaylistDuplicatesEntry
&& ((PlaylistDuplicatesEntry) item).timesStreamIsContained > 0) {
diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java
index 89a714fd7..7dc71bfb4 100644
--- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java
@@ -16,8 +16,8 @@ import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.views.AnimatedProgressBar;
import java.time.format.DateTimeFormatter;
@@ -83,8 +83,8 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
}
// Default thumbnail is shown on error, while loading and if the url is empty
- PicassoHelper.loadThumbnail(item.getStreamEntity().getThumbnailUrl())
- .into(itemThumbnailView);
+ CoilHelper.INSTANCE.loadThumbnail(itemThumbnailView,
+ item.getStreamEntity().getThumbnailUrl());
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnItemSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java
index 150a35eb5..f26a76ad9 100644
--- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java
@@ -16,8 +16,8 @@ import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.views.AnimatedProgressBar;
import java.time.format.DateTimeFormatter;
@@ -117,8 +117,8 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
}
// Default thumbnail is shown on error, while loading and if the url is empty
- PicassoHelper.loadThumbnail(item.getStreamEntity().getThumbnailUrl())
- .into(itemThumbnailView);
+ CoilHelper.INSTANCE.loadThumbnail(itemThumbnailView,
+ item.getStreamEntity().getThumbnailUrl());
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnItemSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java
index 765732063..f79f3c785 100644
--- a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java
@@ -8,8 +8,8 @@ import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
import java.time.format.DateTimeFormatter;
@@ -29,10 +29,9 @@ public class RemotePlaylistItemHolder extends PlaylistItemHolder {
public void updateFromItem(final LocalItem localItem,
final HistoryRecordManager historyRecordManager,
final DateTimeFormatter dateTimeFormatter) {
- if (!(localItem instanceof PlaylistRemoteEntity)) {
+ if (!(localItem instanceof PlaylistRemoteEntity item)) {
return;
}
- final PlaylistRemoteEntity item = (PlaylistRemoteEntity) localItem;
itemTitleView.setText(item.getName());
itemStreamCountView.setText(Localization.localizeStreamCountMini(
@@ -45,7 +44,7 @@ public class RemotePlaylistItemHolder extends PlaylistItemHolder {
itemUploaderView.setText(ServiceHelper.getNameOfServiceById(item.getServiceId()));
}
- PicassoHelper.loadPlaylistThumbnail(item.getThumbnailUrl()).into(itemThumbnailView);
+ CoilHelper.INSTANCE.loadPlaylistThumbnail(itemThumbnailView, item.getThumbnailUrl());
super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter);
}
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt
index bc39dafe6..ca626e704 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt
@@ -9,7 +9,7 @@ import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.channel.ChannelInfoItem
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.OnClickGesture
-import org.schabi.newpipe.util.image.PicassoHelper
+import org.schabi.newpipe.util.image.CoilHelper
class ChannelItem(
private val infoItem: ChannelInfoItem,
@@ -39,7 +39,7 @@ class ChannelItem(
itemChannelDescriptionView.text = infoItem.description
}
- PicassoHelper.loadAvatar(infoItem.thumbnails).into(itemThumbnailView)
+ CoilHelper.loadAvatar(itemThumbnailView, infoItem.thumbnails)
gesturesListener?.run {
viewHolder.root.setOnClickListener { selected(infoItem) }
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt
index 3a4c6e41b..da35447e3 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt
@@ -10,7 +10,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
import org.schabi.newpipe.databinding.PickerSubscriptionItemBinding
import org.schabi.newpipe.ktx.AnimationType
import org.schabi.newpipe.ktx.animate
-import org.schabi.newpipe.util.image.PicassoHelper
+import org.schabi.newpipe.util.image.CoilHelper
data class PickerSubscriptionItem(
val subscriptionEntity: SubscriptionEntity,
@@ -21,7 +21,7 @@ data class PickerSubscriptionItem(
override fun getSpanSize(spanCount: Int, position: Int): Int = 1
override fun bind(viewBinding: PickerSubscriptionItemBinding, position: Int) {
- PicassoHelper.loadAvatar(subscriptionEntity.avatarUrl).into(viewBinding.thumbnailView)
+ CoilHelper.loadAvatar(viewBinding.thumbnailView, subscriptionEntity.avatarUrl)
viewBinding.titleView.text = subscriptionEntity.name
viewBinding.selectedHighlight.isVisible = isSelected
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java
index 49e72328e..40da9139d 100644
--- a/app/src/main/java/org/schabi/newpipe/player/Player.java
+++ b/app/src/main/java/org/schabi/newpipe/player/Player.java
@@ -60,6 +60,7 @@ import android.view.LayoutInflater;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.graphics.drawable.DrawableKt;
import androidx.core.math.MathUtils;
import androidx.preference.PreferenceManager;
@@ -77,8 +78,6 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.video.VideoSize;
-import com.squareup.picasso.Picasso;
-import com.squareup.picasso.Target;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
@@ -86,8 +85,8 @@ import org.schabi.newpipe.databinding.PlayerBinding;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
-import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.Image;
+import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.stream.VideoStream;
@@ -118,14 +117,15 @@ import org.schabi.newpipe.player.ui.VideoPlayerUi;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.SerializedCache;
import org.schabi.newpipe.util.StreamTypeUtil;
+import org.schabi.newpipe.util.image.CoilHelper;
import java.util.List;
import java.util.Optional;
import java.util.stream.IntStream;
+import coil.target.Target;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
@@ -174,7 +174,6 @@ public final class Player implements PlaybackListener, Listener {
//////////////////////////////////////////////////////////////////////////*/
public static final int RENDERER_UNAVAILABLE = -1;
- private static final String PICASSO_PLAYER_THUMBNAIL_TAG = "PICASSO_PLAYER_THUMBNAIL_TAG";
/*//////////////////////////////////////////////////////////////////////////
// Playback
@@ -246,12 +245,6 @@ public final class Player implements PlaybackListener, Listener {
@NonNull
private final CompositeDisposable databaseUpdateDisposable = new CompositeDisposable();
- // This is the only listener we need for thumbnail loading, since there is always at most only
- // one thumbnail being loaded at a time. This field is also here to maintain a strong reference,
- // which would otherwise be garbage collected since Picasso holds weak references to targets.
- @NonNull
- private final Target currentThumbnailTarget;
-
/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/
@@ -295,8 +288,6 @@ public final class Player implements PlaybackListener, Listener {
videoResolver = new VideoPlaybackResolver(context, dataSource, getQualityResolver());
audioResolver = new AudioPlaybackResolver(context, dataSource);
- currentThumbnailTarget = getCurrentThumbnailTarget();
-
// The UIs added here should always be present. They will be initialized when the player
// reaches the initialization step. Make sure the media session ui is before the
// notification ui in the UIs list, since the notification depends on the media session in
@@ -602,7 +593,6 @@ public final class Player implements PlaybackListener, Listener {
databaseUpdateDisposable.clear();
progressUpdateDisposable.set(null);
- cancelLoadingCurrentThumbnail();
UIs.destroyAll(Object.class); // destroy every UI: obviously every UI extends Object
}
@@ -776,67 +766,52 @@ public final class Player implements PlaybackListener, Listener {
//////////////////////////////////////////////////////////////////////////*/
//region Thumbnail loading
- private Target getCurrentThumbnailTarget() {
- // a Picasso target is just a listener for thumbnail loading events
- return new Target() {
- @Override
- public void onBitmapLoaded(final Bitmap bitmap, final Picasso.LoadedFrom from) {
- if (DEBUG) {
- Log.d(TAG, "Thumbnail - onBitmapLoaded() called with: bitmap = [" + bitmap
- + " -> " + bitmap.getWidth() + "x" + bitmap.getHeight() + "], from = ["
- + from + "]");
- }
- // there is a new thumbnail, so e.g. the end screen thumbnail needs to change, too.
- onThumbnailLoaded(bitmap);
- }
-
- @Override
- public void onBitmapFailed(final Exception e, final Drawable errorDrawable) {
- Log.e(TAG, "Thumbnail - onBitmapFailed() called", e);
- // there is a new thumbnail, so e.g. the end screen thumbnail needs to change, too.
- onThumbnailLoaded(null);
- }
-
- @Override
- public void onPrepareLoad(final Drawable placeHolderDrawable) {
- if (DEBUG) {
- Log.d(TAG, "Thumbnail - onPrepareLoad() called");
- }
- }
- };
- }
-
private void loadCurrentThumbnail(final List thumbnails) {
if (DEBUG) {
Log.d(TAG, "Thumbnail - loadCurrentThumbnail() called with thumbnails = ["
+ thumbnails.size() + "]");
}
- // first cancel any previous loading
- cancelLoadingCurrentThumbnail();
-
// Unset currentThumbnail, since it is now outdated. This ensures it is not used in media
- // session metadata while the new thumbnail is being loaded by Picasso.
+ // session metadata while the new thumbnail is being loaded by Coil.
onThumbnailLoaded(null);
if (thumbnails.isEmpty()) {
return;
}
// scale down the notification thumbnail for performance
- PicassoHelper.loadScaledDownThumbnail(context, thumbnails)
- .tag(PICASSO_PLAYER_THUMBNAIL_TAG)
- .into(currentThumbnailTarget);
- }
+ final var target = new Target() {
+ @Override
+ public void onError(@Nullable final Drawable error) {
+ Log.e(TAG, "Thumbnail - onError() called");
+ // there is a new thumbnail, so e.g. the end screen thumbnail needs to change, too.
+ onThumbnailLoaded(null);
+ }
- private void cancelLoadingCurrentThumbnail() {
- // cancel the Picasso job associated with the player thumbnail, if any
- PicassoHelper.cancelTag(PICASSO_PLAYER_THUMBNAIL_TAG);
+ @Override
+ public void onStart(@Nullable final Drawable placeholder) {
+ if (DEBUG) {
+ Log.d(TAG, "Thumbnail - onStart() called");
+ }
+ }
+
+ @Override
+ public void onSuccess(@NonNull final Drawable result) {
+ if (DEBUG) {
+ Log.d(TAG, "Thumbnail - onSuccess() called with: drawable = [" + result + "]");
+ }
+ // there is a new thumbnail, so e.g. the end screen thumbnail needs to change, too.
+ onThumbnailLoaded(DrawableKt.toBitmapOrNull(result, result.getIntrinsicWidth(),
+ result.getIntrinsicHeight(), null));
+ }
+ };
+ CoilHelper.INSTANCE.loadScaledDownThumbnail(context, thumbnails, target);
}
private void onThumbnailLoaded(@Nullable final Bitmap bitmap) {
// Avoid useless thumbnail updates, if the thumbnail has not actually changed. Based on the
// thumbnail loading code, this if would be skipped only when both bitmaps are `null`, since
- // onThumbnailLoaded won't be called twice with the same nonnull bitmap by Picasso's target.
+ // onThumbnailLoaded won't be called twice with the same nonnull bitmap by Coil's target.
if (currentThumbnail != bitmap) {
currentThumbnail = bitmap;
UIs.call(playerUi -> playerUi.onThumbnailLoaded(bitmap));
diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java
index 066f92c26..8994aef79 100644
--- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java
@@ -6,8 +6,8 @@ import android.view.MotionEvent;
import android.view.View;
import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
public class PlayQueueItemBuilder {
private static final String TAG = PlayQueueItemBuilder.class.toString();
@@ -33,7 +33,7 @@ public class PlayQueueItemBuilder {
holder.itemDurationView.setVisibility(View.GONE);
}
- PicassoHelper.loadThumbnail(item.getThumbnails()).into(holder.itemThumbnailView);
+ CoilHelper.INSTANCE.loadThumbnail(holder.itemThumbnailView, item.getThumbnails());
holder.itemRoot.setOnClickListener(view -> {
if (onItemClickListener != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java
index 26065de15..d09664aeb 100644
--- a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java
@@ -13,8 +13,9 @@ import androidx.collection.SparseArrayCompat;
import com.google.common.base.Stopwatch;
+import org.schabi.newpipe.App;
import org.schabi.newpipe.extractor.stream.Frameset;
-import org.schabi.newpipe.util.image.PicassoHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
import java.util.Comparator;
import java.util.List;
@@ -177,8 +178,8 @@ public class SeekbarPreviewThumbnailHolder {
Log.d(TAG, "Downloading bitmap for seekbarPreview from '" + url + "'");
// Gets the bitmap within the timeout of 15 seconds imposed by default by OkHttpClient
- // Ensure that your are not running on the main-Thread this will otherwise hang
- final Bitmap bitmap = PicassoHelper.loadSeekbarThumbnailPreview(url).get();
+ // Ensure that you are not running on the main thread, otherwise this will hang
+ final var bitmap = CoilHelper.INSTANCE.loadBitmapBlocking(App.getApp(), url);
if (sw != null) {
Log.d(TAG, "Download of bitmap for seekbarPreview from '" + url + "' took "
diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
index ec2bed67a..2cda1b4ea 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
@@ -13,10 +13,9 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.extractor.localization.Localization;
import org.schabi.newpipe.util.image.ImageStrategy;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.image.PreferredImageQuality;
-import java.io.IOException;
+import coil.Coil;
public class ContentSettingsFragment extends BasePreferenceFragment {
private String youtubeRestrictedModeEnabledKey;
@@ -42,14 +41,17 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
(preference, newValue) -> {
ImageStrategy.setPreferredImageQuality(PreferredImageQuality
.fromPreferenceKey(requireContext(), (String) 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);
+ final var loader = Coil.imageLoader(preference.getContext());
+ if (loader.getMemoryCache() != null) {
+ loader.getMemoryCache().clear();
}
+ if (loader.getDiskCache() != null) {
+ loader.getDiskCache().clear();
+ }
+ Toast.makeText(preference.getContext(),
+ R.string.thumbnail_cache_wipe_complete_notice, Toast.LENGTH_SHORT)
+ .show();
+
return true;
});
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java
index d78ade49d..c6abb5405 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java
@@ -10,7 +10,6 @@ import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.local.feed.notifications.NotificationWorker;
-import org.schabi.newpipe.util.image.PicassoHelper;
import java.util.Optional;
@@ -25,8 +24,6 @@ public class DebugSettingsFragment extends BasePreferenceFragment {
findPreference(getString(R.string.allow_heap_dumping_key));
final Preference showMemoryLeaksPreference =
findPreference(getString(R.string.show_memory_leaks_key));
- final Preference showImageIndicatorsPreference =
- findPreference(getString(R.string.show_image_indicators_key));
final Preference checkNewStreamsPreference =
findPreference(getString(R.string.check_new_streams_key));
final Preference crashTheAppPreference =
@@ -38,7 +35,6 @@ public class DebugSettingsFragment extends BasePreferenceFragment {
assert allowHeapDumpingPreference != null;
assert showMemoryLeaksPreference != null;
- assert showImageIndicatorsPreference != null;
assert checkNewStreamsPreference != null;
assert crashTheAppPreference != null;
assert showErrorSnackbarPreference != null;
@@ -61,11 +57,6 @@ public class DebugSettingsFragment extends BasePreferenceFragment {
showMemoryLeaksPreference.setSummary(R.string.leak_canary_not_available);
}
- showImageIndicatorsPreference.setOnPreferenceChangeListener((preference, newValue) -> {
- PicassoHelper.setIndicatorsEnabled((Boolean) newValue);
- return true;
- });
-
checkNewStreamsPreference.setOnPreferenceClickListener(preference -> {
NotificationWorker.runNow(preference.getContext());
return true;
diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
index 37335421d..c566313e3 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
@@ -19,8 +19,8 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.local.subscription.SubscriptionManager;
-import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ThemeHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
import java.util.List;
import java.util.Vector;
@@ -190,7 +190,7 @@ public class SelectChannelFragment extends DialogFragment {
final SubscriptionEntity entry = subscriptions.get(position);
holder.titleView.setText(entry.getName());
holder.view.setOnClickListener(view -> clickedItem(position));
- PicassoHelper.loadAvatar(entry.getAvatarUrl()).into(holder.thumbnailView);
+ CoilHelper.INSTANCE.loadAvatar(holder.thumbnailView, entry.getAvatarUrl());
}
@Override
diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java
index 36abef9e5..c340dca22 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java
@@ -27,7 +27,7 @@ import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
-import org.schabi.newpipe.util.image.PicassoHelper;
+import org.schabi.newpipe.util.image.CoilHelper;
import java.util.List;
import java.util.Vector;
@@ -154,20 +154,15 @@ public class SelectPlaylistFragment extends DialogFragment {
final int position) {
final PlaylistLocalItem selectedItem = playlists.get(position);
- if (selectedItem instanceof PlaylistMetadataEntry) {
- final PlaylistMetadataEntry entry = ((PlaylistMetadataEntry) selectedItem);
-
+ if (selectedItem instanceof PlaylistMetadataEntry entry) {
holder.titleView.setText(entry.name);
holder.view.setOnClickListener(view -> clickedItem(position));
- PicassoHelper.loadPlaylistThumbnail(entry.thumbnailUrl).into(holder.thumbnailView);
-
- } else if (selectedItem instanceof PlaylistRemoteEntity) {
- final PlaylistRemoteEntity entry = ((PlaylistRemoteEntity) selectedItem);
-
+ CoilHelper.INSTANCE.loadPlaylistThumbnail(holder.thumbnailView, entry.thumbnailUrl);
+ } else if (selectedItem instanceof PlaylistRemoteEntity entry) {
holder.titleView.setText(entry.getName());
holder.view.setOnClickListener(view -> clickedItem(position));
- PicassoHelper.loadPlaylistThumbnail(entry.getThumbnailUrl())
- .into(holder.thumbnailView);
+ CoilHelper.INSTANCE.loadPlaylistThumbnail(holder.thumbnailView,
+ entry.getThumbnailUrl());
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java
index 7524e5413..21a4b1175 100644
--- a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java
+++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java
@@ -24,8 +24,8 @@ import androidx.core.content.FileProvider;
import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.Image;
+import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.util.image.ImageStrategy;
-import org.schabi.newpipe.util.image.PicassoHelper;
import java.io.File;
import java.io.FileOutputStream;
@@ -278,7 +278,7 @@ public final class ShareUtils {
* @param content the content to share
* @param images a set of possible {@link Image}s of the subject, among which to choose with
* {@link ImageStrategy#choosePreferredImage(List)} since that's likely to
- * provide an image that is in Picasso's cache
+ * provide an image that is in Coil's cache
*/
public static void shareText(@NonNull final Context context,
@NonNull final String title,
@@ -335,15 +335,7 @@ public final class ShareUtils {
}
/**
- * Generate a {@link ClipData} with the image of the content shared, if it's in the app cache.
- *
- *
- * In order not to worry about network issues (timeouts, DNS issues, low connection speed, ...)
- * when sharing a content, only images in the {@link com.squareup.picasso.LruCache LruCache}
- * used by the Picasso library inside {@link PicassoHelper} are used as preview images. If the
- * thumbnail image is not in the cache, no {@link ClipData} will be generated and {@code null}
- * will be returned.
- *
+ * Generate a {@link ClipData} with the image of the content shared.
*
*
* In order to display the image in the content preview of the Android share sheet, an URI of
@@ -359,9 +351,8 @@ public final class ShareUtils {
*
*
*
- * This method will call {@link PicassoHelper#getImageFromCacheIfPresent(String)} to get the
- * thumbnail of the content in the {@link com.squareup.picasso.LruCache LruCache} used by
- * the Picasso library inside {@link PicassoHelper}.
+ * This method will call {@link CoilHelper#loadBitmapBlocking(Context, String)} to get the
+ * thumbnail of the content.
*
*
*
@@ -378,7 +369,7 @@ public final class ShareUtils {
@NonNull final Context context,
@NonNull final String thumbnailUrl) {
try {
- final Bitmap bitmap = PicassoHelper.getImageFromCacheIfPresent(thumbnailUrl);
+ final var bitmap = CoilHelper.INSTANCE.loadBitmapBlocking(context, thumbnailUrl);
if (bitmap == null) {
return null;
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/image/CoilHelper.kt b/app/src/main/java/org/schabi/newpipe/util/image/CoilHelper.kt
new file mode 100644
index 000000000..ab7cd79a8
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/util/image/CoilHelper.kt
@@ -0,0 +1,142 @@
+package org.schabi.newpipe.util.image
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.util.Log
+import android.widget.ImageView
+import androidx.annotation.DrawableRes
+import androidx.core.graphics.drawable.toBitmapOrNull
+import coil.executeBlocking
+import coil.imageLoader
+import coil.request.ImageRequest
+import coil.size.Size
+import coil.target.Target
+import coil.transform.Transformation
+import org.schabi.newpipe.MainActivity
+import org.schabi.newpipe.R
+import org.schabi.newpipe.extractor.Image
+import org.schabi.newpipe.ktx.scale
+import kotlin.math.min
+
+object CoilHelper {
+ private val TAG = CoilHelper::class.java.simpleName
+
+ @JvmOverloads
+ fun loadBitmapBlocking(
+ context: Context,
+ url: String?,
+ @DrawableRes placeholderResId: Int = 0
+ ): Bitmap? {
+ val request = getImageRequest(context, url, placeholderResId).build()
+ return context.imageLoader.executeBlocking(request).drawable?.toBitmapOrNull()
+ }
+
+ fun loadAvatar(target: ImageView, images: List) {
+ loadImageDefault(target, images, R.drawable.placeholder_person)
+ }
+
+ fun loadAvatar(target: ImageView, url: String?) {
+ loadImageDefault(target, url, R.drawable.placeholder_person)
+ }
+
+ fun loadThumbnail(target: ImageView, images: List) {
+ loadImageDefault(target, images, R.drawable.placeholder_thumbnail_video)
+ }
+
+ fun loadThumbnail(target: ImageView, url: String?) {
+ loadImageDefault(target, url, R.drawable.placeholder_thumbnail_video)
+ }
+
+ fun loadScaledDownThumbnail(context: Context, images: List, target: Target) {
+ val url = ImageStrategy.choosePreferredImage(images)
+ val request = getImageRequest(context, url, R.drawable.placeholder_thumbnail_video)
+ .target(target)
+ .transformations(object : Transformation {
+ override val cacheKey = "COIL_PLAYER_THUMBNAIL_TRANSFORMATION_KEY"
+
+ override suspend fun transform(input: Bitmap, size: Size): Bitmap {
+ if (MainActivity.DEBUG) {
+ Log.d(TAG, "Thumbnail - transform() called")
+ }
+
+ val notificationThumbnailWidth = min(
+ context.resources.getDimension(R.dimen.player_notification_thumbnail_width),
+ input.width.toFloat()
+ ).toInt()
+
+ var newHeight = input.height / (input.width / notificationThumbnailWidth)
+ val result = input.scale(notificationThumbnailWidth, newHeight)
+
+ return if (result == input || !result.isMutable) {
+ // create a new mutable bitmap to prevent strange crashes on some
+ // devices (see #4638)
+ newHeight = input.height / (input.width / (notificationThumbnailWidth - 1))
+ input.scale(notificationThumbnailWidth, newHeight)
+ } else {
+ result
+ }
+ }
+ })
+ .build()
+
+ context.imageLoader.enqueue(request)
+ }
+
+ fun loadDetailsThumbnail(target: ImageView, images: List) {
+ val url = ImageStrategy.choosePreferredImage(images)
+ loadImageDefault(target, url, R.drawable.placeholder_thumbnail_video, false)
+ }
+
+ fun loadBanner(target: ImageView, images: List) {
+ loadImageDefault(target, images, R.drawable.placeholder_channel_banner)
+ }
+
+ fun loadPlaylistThumbnail(target: ImageView, images: List) {
+ loadImageDefault(target, images, R.drawable.placeholder_thumbnail_playlist)
+ }
+
+ fun loadPlaylistThumbnail(target: ImageView, url: String?) {
+ loadImageDefault(target, url, R.drawable.placeholder_thumbnail_playlist)
+ }
+
+ private fun loadImageDefault(
+ target: ImageView,
+ images: List,
+ @DrawableRes placeholderResId: Int
+ ) {
+ loadImageDefault(target, ImageStrategy.choosePreferredImage(images), placeholderResId)
+ }
+
+ private fun loadImageDefault(
+ target: ImageView,
+ url: String?,
+ @DrawableRes placeholderResId: Int,
+ showPlaceholder: Boolean = true
+ ) {
+ val request = getImageRequest(target.context, url, placeholderResId, showPlaceholder)
+ .target(target)
+ .build()
+ target.context.imageLoader.enqueue(request)
+ }
+
+ private fun getImageRequest(
+ context: Context,
+ url: String?,
+ @DrawableRes placeholderResId: Int,
+ showPlaceholderWhileLoading: Boolean = true
+ ): ImageRequest.Builder {
+ // if the URL was chosen with `choosePreferredImage` it will be null, but check again
+ // `shouldLoadImages` in case the URL was chosen with `imageListToDbUrl` (which is the case
+ // for URLs stored in the database)
+ val takenUrl = url?.takeIf { it.isNotEmpty() && ImageStrategy.shouldLoadImages() }
+
+ return ImageRequest.Builder(context)
+ .data(takenUrl)
+ .error(placeholderResId)
+ .apply {
+ if (takenUrl != null || showPlaceholderWhileLoading) {
+ placeholder(placeholderResId)
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java
deleted file mode 100644
index 4b116bdf9..000000000
--- a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package org.schabi.newpipe.util.image;
-
-import static org.schabi.newpipe.MainActivity.DEBUG;
-import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
-import static org.schabi.newpipe.util.image.ImageStrategy.choosePreferredImage;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.util.Log;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.graphics.BitmapCompat;
-
-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 com.squareup.picasso.Transformation;
-
-import org.schabi.newpipe.R;
-import org.schabi.newpipe.extractor.Image;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import okhttp3.OkHttpClient;
-
-public final class PicassoHelper {
- private static final String TAG = PicassoHelper.class.getSimpleName();
- private static final String PLAYER_THUMBNAIL_TRANSFORMATION_KEY =
- "PICASSO_PLAYER_THUMBNAIL_TRANSFORMATION_KEY";
-
- 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;
-
-
- 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"),
- 50L * 1024L * 1024L))
- // 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
- final okhttp3.Cache diskCache = picassoDownloaderClient.cache();
- if (diskCache != null) {
- diskCache.delete(); // clear disk cache
- }
- init(context);
- }
-
- public static void cancelTag(final Object tag) {
- picassoInstance.cancelTag(tag);
- }
-
- public static void setIndicatorsEnabled(final boolean enabled) {
- picassoInstance.setIndicatorsEnabled(enabled); // useful for debugging
- }
-
-
- public static RequestCreator loadAvatar(@NonNull final List images) {
- return loadImageDefault(images, R.drawable.placeholder_person);
- }
-
- public static RequestCreator loadAvatar(@Nullable final String url) {
- return loadImageDefault(url, R.drawable.placeholder_person);
- }
-
- public static RequestCreator loadThumbnail(@NonNull final List images) {
- return loadImageDefault(images, R.drawable.placeholder_thumbnail_video);
- }
-
- public static RequestCreator loadThumbnail(@Nullable final String url) {
- return loadImageDefault(url, R.drawable.placeholder_thumbnail_video);
- }
-
- public static RequestCreator loadDetailsThumbnail(@NonNull final List images) {
- return loadImageDefault(choosePreferredImage(images),
- R.drawable.placeholder_thumbnail_video, false);
- }
-
- public static RequestCreator loadBanner(@NonNull final List images) {
- return loadImageDefault(images, R.drawable.placeholder_channel_banner);
- }
-
- public static RequestCreator loadPlaylistThumbnail(@NonNull final List images) {
- return loadImageDefault(images, R.drawable.placeholder_thumbnail_playlist);
- }
-
- public static RequestCreator loadPlaylistThumbnail(@Nullable final String url) {
- return loadImageDefault(url, R.drawable.placeholder_thumbnail_playlist);
- }
-
- public static RequestCreator loadSeekbarThumbnailPreview(@Nullable final String url) {
- return picassoInstance.load(url);
- }
-
- public static RequestCreator loadNotificationIcon(@Nullable final String url) {
- return loadImageDefault(url, R.drawable.ic_newpipe_triangle_white);
- }
-
-
- public static RequestCreator loadScaledDownThumbnail(final Context context,
- @NonNull final List images) {
- // scale down the notification thumbnail for performance
- return PicassoHelper.loadThumbnail(images)
- .transform(new Transformation() {
- @Override
- public Bitmap transform(final Bitmap source) {
- if (DEBUG) {
- Log.d(TAG, "Thumbnail - transform() called");
- }
-
- final float notificationThumbnailWidth = Math.min(
- context.getResources()
- .getDimension(R.dimen.player_notification_thumbnail_width),
- source.getWidth());
-
- final Bitmap result = BitmapCompat.createScaledBitmap(
- source,
- (int) notificationThumbnailWidth,
- (int) (source.getHeight()
- / (source.getWidth() / notificationThumbnailWidth)),
- null,
- true);
-
- if (result == source || !result.isMutable()) {
- // create a new mutable bitmap to prevent strange crashes on some
- // devices (see #4638)
- final Bitmap copied = BitmapCompat.createScaledBitmap(
- source,
- (int) notificationThumbnailWidth - 1,
- (int) (source.getHeight() / (source.getWidth()
- / (notificationThumbnailWidth - 1))),
- null,
- true);
- source.recycle();
- return copied;
- } else {
- source.recycle();
- return result;
- }
- }
-
- @Override
- public String key() {
- return PLAYER_THUMBNAIL_TRANSFORMATION_KEY;
- }
- });
- }
-
- @Nullable
- public static Bitmap getImageFromCacheIfPresent(@NonNull final String imageUrl) {
- // URLs in the internal cache finish with \n so we need to add \n to image URLs
- return picassoCache.get(imageUrl + "\n");
- }
-
-
- private static RequestCreator loadImageDefault(@NonNull final List images,
- @DrawableRes final int placeholderResId) {
- return loadImageDefault(choosePreferredImage(images), placeholderResId);
- }
-
- private static RequestCreator loadImageDefault(@Nullable final String url,
- @DrawableRes final int placeholderResId) {
- return loadImageDefault(url, placeholderResId, true);
- }
-
- private static RequestCreator loadImageDefault(@Nullable final String url,
- @DrawableRes final int placeholderResId,
- final boolean showPlaceholderWhileLoading) {
- // if the URL was chosen with `choosePreferredImage` it will be null, but check again
- // `shouldLoadImages` in case the URL was chosen with `imageListToDbUrl` (which is the case
- // for URLs stored in the database)
- if (isNullOrEmpty(url) || !ImageStrategy.shouldLoadImages()) {
- return picassoInstance
- .load((String) null)
- .placeholder(placeholderResId) // show placeholder when no image should load
- .error(placeholderResId);
- } else {
- final RequestCreator requestCreator = picassoInstance
- .load(url)
- .error(placeholderResId);
- if (showPlaceholderWhileLoading) {
- requestCreator.placeholder(placeholderResId);
- }
- return requestCreator;
- }
- }
-}
diff --git a/app/src/main/res/values-ar-rLY/strings.xml b/app/src/main/res/values-ar-rLY/strings.xml
index 077cf1106..290d9f6ab 100644
--- a/app/src/main/res/values-ar-rLY/strings.xml
+++ b/app/src/main/res/values-ar-rLY/strings.xml
@@ -302,7 +302,6 @@
%s مشاركجلب البيانات الوصفية…
- إظهار مؤشرات الصورانقر للتنزيل %sتعطيل الوضع السريع,
@@ -830,7 +829,6 @@
لقد اشتركت الآن في هذه القناةبدءًا من Android 10، يتم دعم \"Storage Access Framework\" فقطإنشاء اسم فريد
- أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرةفشل الاتصال الآمنيتوفر هذا الفيديو فقط لأعضاء YouTube Music Premium، لذلك لا يمكن بثه أو تنزيله من قبل NewPipe.البث السابق
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 82173d758..902fe8c3a 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -674,8 +674,6 @@
معاينة مصغرة على شريط التمريروضع علامة على تمت مشاهدتهأُعجب بها منشئ المحتوى
- أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرة
- إظهار مؤشرات الصوراقتراحات البحث عن بعداقتراحات البحث المحليةاسحب العناصر لإزالتها
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index 66bfe75de..9c9c15c96 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -505,8 +505,6 @@
Məlumat əldə edilir…Elementlərdə orijinal əvvəlki vaxtı göstərYaşam dövrəsi xaricindəki xətaları bildir
- Şəkil göstəricilərini göstər
- Şəkillərin üzərində mənbəsini göstərən Picasso rəngli lentləri göstər: şəbəkə üçün qırmızı, disk üçün mavi və yaddaş üçün yaşılBəzi endirmələri dayandırmaq mümkün olmasa da, mobil dataya keçərkən faydalıdırBağlaFayl silindiyi üçün irəliləyiş itirildi
diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml
index dceaaf6c5..5ddf30c2a 100644
--- a/app/src/main/res/values-be/strings.xml
+++ b/app/src/main/res/values-be/strings.xml
@@ -630,8 +630,6 @@
Перайсці на вэбсайтПравядзіце пальцам па элементах, каб выдаліць іхАдмяніць пастаянную мініяцюру
- Паказаць індыкатары выявы
- Паказваць каляровыя стужкі Пікаса на выявах, якія пазначаюць іх крыніцу: чырвоная для сеткі, сіняя для дыска і зялёная для памяціАпрацоўка стужкі…Вам будзе прапанавана, дзе захоўваць кожную спампоўкуЗагрузка стужкі…
diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml
index bc235446c..9b8c06bc5 100644
--- a/app/src/main/res/values-bg/strings.xml
+++ b/app/src/main/res/values-bg/strings.xml
@@ -539,7 +539,6 @@
Това видео е с възрастова граница.
\n
\nВключете „%1$s“ в настройките ако искате да го пуснете.
- Показвай цветни Picasso-панделки в горната част на изображенията като индикатор за техния произход (червен – от мрежата, син – от диска и червен – от паметта)Автоматична (тази на устройството)Мащабиране на миниатюрата в известието от 16:9 към 1:1 формат (възможни са изкривявания)Избете плейлист
diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml
index 853b04b64..8fe38988a 100644
--- a/app/src/main/res/values-bn/strings.xml
+++ b/app/src/main/res/values-bn/strings.xml
@@ -589,7 +589,6 @@
নতুন ধারাকম্পাঙ্ক দেখোপূর্বদর্শন রেখার মাধ্যমে প্রাকদর্শন
- ছবিরূপ সূচক দেখাওদেখিও নাযেকোনো নেটওয়ার্কপরেরটা ক্রমে রাখা হয়েছে
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 871af187b..dd08e3526 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -625,7 +625,6 @@
No mostrisBaixa qualitat (més petit)Alta qualitat (més gran)
- Mostra indicadors de la imatgeDesactiva l\'entunelament del contingut si en els videos hi ha una pantalla negre o tartamudegenMostra detalls del canalNo s\'ha establert una carpeta de descàrregues, selecciona la carpeta per defecte ara
@@ -669,7 +668,6 @@
Comentari fixatMostra \"Força el tancament del reproductor\"Mostra una opció de fallada quan s\'utilitza el reproductor
- Mostra les cintes de color Picasso a la part superior de les imatges que indiquen la seva font: vermell per a la xarxa, blau per al disc i verd per a la memòriaEl LeakCanary no està disponibleComprovant freqüènciaEs necesita una conexió a Internet
diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml
index e6e375a4c..d14449cf1 100644
--- a/app/src/main/res/values-ckb/strings.xml
+++ b/app/src/main/res/values-ckb/strings.xml
@@ -631,8 +631,6 @@
پیشان نەدرێتکواڵێتی نزم (بچووکتر)کواڵێتی بەرز (گەورەتر)
- پیشاندانی شریتە ڕەنگکراوەکانی پیکاسۆ لەسەرووی وێنەکانەوە بۆ بەدیار خستنی سەرچاوەکانیان : سوور بۆ تۆڕ ، شین بۆ دیسک و سەوز بۆ بیرگە
- پیشاندانی دیارخەرەکانی وێنەپێشنیازکراوەکانی گەڕانی ڕیمۆتپێشنیازکراوەکانی گەڕانی نێوخۆییدیارکردن وەک بینراو
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 34537446c..e6263f6e0 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -654,8 +654,6 @@
%s stahování dokončena%s stahováních dokončeno
- Zobrazit barevné pásky Picasso na obrázcích označujících jejich zdroj: červená pro síť, modrá pro disk a zelená pro paměť
- Zobrazit indikátory obrázkůVzdálené návrhy vyhledáváníLokální návrhy vyhledáváníPokud je vypnuté automatické otáčení, nespouštět video v mini přehrávači, ale přepnout se přímo do režimu celé obrazovky. Do mini přehrávače se lze i nadále dostat ukončením režimu celé obrazovky
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index 601bc3752..cbb59d591 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -516,7 +516,6 @@
Behandler… Det kan tage et øjeblikVis hukommelseslækagerDeaktivér medietunneling
- Vis billedindikatorerNetværkskravAlle netværkKontrolfrekvens
@@ -695,7 +694,6 @@
Ofte stillede spørgsmålHvis du har problemer med at bruge appen, bør du tjekke disse svar på almindelige spørgsmål!Se på webside
- Vis Picasso-farvede bånd oven på billeder, der angiver deres kilde: rød for netværk, blå for disk og grøn for hukommelseDu kører den nyeste version af NewPipePga. ExoPlayer-begrænsninger blev søgevarigheden sat til %d sekunderVis kun ikke-grupperede abonnementer
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index fcc38bf0b..028ff86ca 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -637,8 +637,6 @@
AusAls gesehen markierenVom Ersteller mit Herz versehen
- Farbige Picasso-Bänder über den Bildern anzeigen, die deren Quelle angeben: rot für Netzwerk, blau für Festplatte und grün für Speicher
- Bildindikatoren anzeigenEntfernte SuchvorschlägeLokale Suchvorschläge
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 6e9525459..58a70c270 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -634,8 +634,6 @@
Προεπισκόπηση στην μπάρα αναζήτησηςΣήμανση ως αναπαραχθένΕπισημάνθηκε από τον δημιουργό
- Εμφάνιση χρωματιστής κορδέλας πάνω στις εικόνες, που δείχνει την πηγή τους: κόκκινη για δίκτυο, μπλε για δίσκο και πράσινο για μνήμη
- Εμφάνιση δεικτών εικόνωνΠροτάσεις απομακρυσμένης αναζήτησηςΠροτάσεις τοπικής αναζήτησης
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index c7b780a1f..a44c72937 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -647,8 +647,6 @@
Los comentarios están deshabilitadosDe corazón por el creadorMarcar como visto
- Mostrar cintas de colores Picasso encima de las imágenes indicando su origen: rojo para la red, azul para el disco y verde para la memoria
- Mostrar indicadores de imagenSugerencias de búsqueda remotaSugerencias de búsqueda local
diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml
index 1d3fcdcb8..0e6e082c9 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -634,8 +634,6 @@
\n
\nNii et valik taandub sellele, mida eelistad: kiirus või täpne teave.
Märgi vaadatuks
- Näita piltide kohal Picasso värvides riba, mis märgib pildi allikat: punane tähistab võrku, sinine kohalikku andmekandjat ja roheline kohalikku mälu
- Näita piltide allikatKaugotsingu soovitusedKohaliku otsingu soovitusedÜksuse eemaldamiseks viipa
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 6f94a8f62..076b50d10 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -641,8 +641,6 @@
Deskarga amaituta%s Deskarga amaituta
- Irudien gainean Picasso koloretako zintak erakutsi, jatorria adieraziz: gorria sarerako, urdina diskorako eta berdea memoriarako
- Erakutsi irudi-adierazleakUrruneko bilaketaren iradokizunakTokiko bilaketa-iradokizunakIkusi gisa markatu
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index 2afeaf286..02ac369d7 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -597,7 +597,6 @@
رنگی کردن آگاهیگشودن بانشانه به عنوان دیده شده
- نمایش روبانهای رنگی پیکاسو در بالای تصویرها کهنشانگر منبعشان است: قرمز برای شبکه ، آبی برای دیسک و سبز برای حافظهدرخواست از اندروید برای سفارشیسازی رنگ آگاهی براساس رنگ اصلی در بندانگشتی (توجّه داشته باشید که روی همهٔ افزارهها در دسترس نیست)این ویدیو محدود به سن است.
\n
@@ -635,7 +634,6 @@
قلبشده به دست ایجادگرپیشنهادهای جستوجوی محلّیپیشنهادهای جستوجوی دوردست
- نمایش نشانگرهای تصویربارگیری پایان یافت%s بارگیری پایان یافتند
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 67350d7ba..d72402e77 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -634,8 +634,6 @@
Latauskansiota ei vielä asetettu, valitse ensin oletuslatauskansioKommentit poistettu käytöstäMerkitse katsotuksi
- Näytä Picasso-värjätyt nauhat kuvien päällä osoittaakseen lähteen: punainen tarkoittaa verkkoa, sininen tarkoittaa levytilaa ja vihreä tarkoittaa muistia
- Näytä kuvailmaisimetEtähakuehdotuksetPaikalliset hakuehdotuksetLisää seuraavaksi
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 66418e7cf..f6a3d6285 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -646,10 +646,8 @@
Prévisualisation de la barre de progression sur la miniatureMarquer comme visionnéApprécié par le créateur
- Afficher les indicateurs d’imageSuggestions de recherche distanteSuggestions de recherche locale
- Affiche les rubans colorés de Picasso au-dessus des images indiquant leur source : rouge pour le réseau, bleu pour le disque et vert pour la mémoire%1$s téléchargement supprimé%1$s téléchargements supprimés
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index efe1b7f5e..4b087a882 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -627,7 +627,6 @@
%s descargas finalizadasMiniatura na barra de busca
- Mostrar indicadores de imaxeDesactive o túnel multimedia se experimentar unha pantalla en negro ou interrupcións na reprodución.Desactivar túnel multimediaEngadido á cola
@@ -664,7 +663,6 @@
A partir do Android 10, só o \'Sistema de Acceso ao Almacenamento\' está soportadoProcesando... Pode devagar un momentoCrear unha notificación de erro
- Amosar fitas coloridas de Picasso na cima das imaxes que indican a súa fonte: vermello para a rede, azul para o disco e verde para a memoriaNovos elementosPredefinido do ExoPlayerAmosar \"Travar o reprodutor\"
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index befde2d53..1da62fc75 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -654,8 +654,6 @@
תמונה מוקטנת בסרגל הנגינהסומן בלב על ידי היוצרסימון כנצפה
- הצגת סרטים בסגנון פיקאסו בראש התמונות לציון המקור שלהם: אדום זה מהרשת, כחול מהכונן וירוק מהזיכרון
- הצגת מחווני תמונותהצעות חיפוש מרוחקותהצעות חיפוש מקומיות
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index 51455fafb..6e185156d 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -570,7 +570,6 @@
कतारबद्ध हुआस्ट्रीम विवरण लोड हो रहे हैं…प्रोसेस हो रहा है… कुछ समय लग सकता है
- छवि संकेतक दिखाएंप्लेयर का उपयोग करते समय क्रैश विकल्प दिखाता हैनई स्ट्रीमों के लिए जांच चलाएंएक त्रुटि स्नैकबार दिखाएं
@@ -668,7 +667,6 @@
लीक-कैनरी उपलब्ध नहीं हैएक त्रुटी हुई है, नोटीफिकेशन देखेंयदि वीडियो प्लेबैक पर आप काली स्क्रीन या रुक-रुक कर वीडियो चलने का अनुभव करते हैं तो मीडिया टनलिंग को अक्षम करें।
- छवियों के शीर्ष पर पिकासो रंगीन रिबन दिखाएँ जो उनके स्रोत को दर्शाता है: नेटवर्क के लिए लाल, डिस्क के लिए नीला और मेमोरी के लिए हरात्रुटी की नोटीफिकेशन बनाएंइस डाउनलोड को पुनर्प्राप्त नहीं किया जा सकताअभी तक कोई डाउनलोड फ़ोल्डर सेट नहीं किया गया है, अब डिफ़ॉल्ट डाउनलोड फ़ोल्डर चुनें
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 419f4619e..3a945bba0 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -646,7 +646,6 @@
%s pruža ovaj razlog:Obrada u tijeku … Može malo potrajatiZa ukljanjanje stavki povuci ih
- Prikaži indikatore slikePreuzimanje je gotovo%s preuzimanja su gotova
@@ -655,7 +654,6 @@
Pokreni glavni player u cjeloekranskom prikazuDodaj u popis kao sljedećiDodano u popis kao sljedeći
- Prikaži Picassove vrpce u boji na slikama koje označavaju njihov izvor: crvena za mrežu, plava za disk i zelena za memorijuIzbrisano %1$s preuzimanjeIzbrisana %1$s preuzimanja
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 5a402c94c..f86704148 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -570,7 +570,6 @@
Az eltávolítás utáni, fragment vagy activity életcikluson kívüli, nem kézbesíthető Rx kivételek jelentésének kényszerítéseEredeti „ennyi ideje” megjelenítése az elemekenTiltsa le a médiacsatornázást, ha fekete képernyőt vagy akadozást tapasztal videólejátszáskor.
- Picasso színes szalagok megjelenítése a képek fölött, megjelölve a forrásukat: piros a hálózathoz, kék a lemezhez, zöld a memóriáhozMinden letöltésnél meg fogja kérdezni, hogy hova mentse elVálasszon egy példánytLista legutóbbi frissítése: %s
@@ -657,7 +656,6 @@
\nBiztos benne\? Ez nem vonható vissza!A szolgáltatásokból származó eredeti szövegek láthatók lesznek a közvetítési elemekenLejátszó összeomlasztása
- Képjelölők megjelenítéseA „lejátszó összeomlasztása” lehetőség megjelenítéseMegjeleníti az összeomlasztási lehetőséget a lejátszó használatakorHangmagasság megtartása (torzítást okozhat)
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index 71900400e..9a6472692 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -631,13 +631,11 @@
Disukai oleh kreatorSaran pencarian lokalSaran pencarian remote
- Tampilkan indikator gambarMenghapus %1$s unduhantambahkan ke selanjutnyatelah ditambahkan ke selanjutnya
- Tampilkan Ribon bewarna Picasso di atas gambar yang mengindikasikan asalnya: merah untuk jaringan, biru untuk disk dan hijau untuk memoriJangan memulai memutar video di mini player, tapi nyalakan langsung di mode layar penuh, jika rotasi otomatis terkunci. Anda tetap dapat mengakses mini player dengan keluar dari layar penuhMemproses… Mungkin butuh waktu sebentarPeriksa Pembaruan
diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml
index ed5ebe99b..d921cfac0 100644
--- a/app/src/main/res/values-is/strings.xml
+++ b/app/src/main/res/values-is/strings.xml
@@ -657,8 +657,6 @@
Upprunalegir textar frá þjónustu verða sýnilegir í atriðumSlökkva á fjölmiðlagöngumSlökktu á fjölmiðlagöngum ef þú finnur fyrir svörtum skjá eða stami við spilun myndbandar
- Sýna myndvísa
- Sýna Picasso litaða borða ofan á myndum sem gefa til kynna uppruna þeirra: rauðan fyrir netið, bláan fyrir disk og grænan fyrir minniSýna „Hrynja spilara“Sýna valkost til að hrynja spilaraHrynja forrit
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 2a5ac16d3..9d1c4bc0b 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -644,8 +644,6 @@
Commenti disattivatiApprezzato dall\'autoreSegna come visto
- Mostra gli indicatori colorati Picasso sopra le immagini, per indicare la loro fonte: rosso per la rete, blu per il disco e verde per la memoria
- Mostra indicatori immagineSuggerimenti di ricerca remotiSuggerimenti di ricerca locali
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 74924125a..7e7cf83a2 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -634,8 +634,6 @@
%s つのダウンロードが完了しました
- ピカソは、画像の上に、画像の出所を識別する色彩記章を表示します: 赤はネットワーク、青はディスク、緑はメモリ
- 画像に標識を表示処理中… 少し時間がかかるかもしれません新しいバージョンを手動で確認しますアップデートを確認中…
diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml
index ecb2a8495..4344c245d 100644
--- a/app/src/main/res/values-ka/strings.xml
+++ b/app/src/main/res/values-ka/strings.xml
@@ -384,7 +384,6 @@
ორიგინალური ტექსტები სერვისებიდან ხილული იქნება ნაკადის ერთეულებშიმედია გვირაბის გათიშვაგამორთეთ მედია გვირაბი, თუ ვიდეოს დაკვრისას შავი ეკრანი ან ჭუჭყი გაქვთ
- გამოსახულების ინდიკატორების ჩვენებააჩვენე \"დამკვრელის დამსხვრევა\"აჩვენებს ავარიის ვარიანტს დამკვრელის გამოყენებისასგაუშვით შემოწმება ახალი ნაკადებისთვის
@@ -683,7 +682,6 @@
გამოწერების იმპორტი ვერ მოხერხდაშეატყობინეთ სასიცოცხლო ციკლის შეცდომებსიძულებითი მოხსენება შეუსაბამო Rx გამონაკლისების შესახებ ფრაგმენტის ან აქტივობის სასიცოცხლო ციკლის გარეთ განკარგვის შემდეგ
- აჩვენეთ პიკასოს ფერადი ლენტები სურათების თავზე, სადაც მითითებულია მათი წყარო: წითელი ქსელისთვის, ლურჯი დისკისთვის და მწვანე მეხსიერებისთვისსწრაფი კვების რეჟიმი ამაზე მეტ ინფორმაციას არ იძლევა.„%s“-ის არხის ჩატვირთვა ვერ მოხერხდა.ხელმისაწვდომია ზოგიერთ სერვისში, როგორც წესი, ბევრად უფრო სწრაფია, მაგრამ შეიძლება დააბრუნოს შეზღუდული რაოდენობის ელემენტი და ხშირად არასრული ინფორმაცია (მაგ. ხანგრძლივობის გარეშე, ელემენტის ტიპი, არ არის ლაივის სტატუსი)
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 939d97441..5d5dfa023 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -545,8 +545,6 @@
미디어 터널링 비활성화서비스의 원본 텍스트가 스트림 항목에 표시됩니다동영상 재생 시 검은 화면이 나타나거나 끊김 현상이 발생하면 미디어 터널링을 비활성화하세요.
- 이미지 표시기 표시
- 원본을 나타내는 이미지 위에 피카소 컬러 리본 표시: 네트워크는 빨간색, 디스크는 파란색, 메모리는 녹색\"플레이어 충돌\" 표시플레이어를 사용할 때 충돌 옵션을 표시합니다새로운 스트림 확인 실행
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index c68e49bdd..2294a357d 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -644,8 +644,6 @@
NerodytiŠirdelė nuo kurėjoPažymėti kaip peržiūrėtą
- Rodyti „Picasso“ spalvotas juosteles ant vaizdų, nurodančių jų šaltinį: raudona tinklui, mėlyna diskui ir žalia atmintis
- Rodyti vaizdo indikatoriusNuotolinės paieškos pasiūlymaiVietinės paieškos pasiūlymai
diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml
index 58b9a9d76..a28d3e607 100644
--- a/app/src/main/res/values-lv/strings.xml
+++ b/app/src/main/res/values-lv/strings.xml
@@ -625,12 +625,10 @@
Nesākt video atskaņošanu samazinātā režīmā, bet pilnekrāna režīmā, ja automātiskā rotācija ir izslēgtaIzslēgt multivides tuneļošanuIzslēdziet multivides tuneļošanu, ja jums video atskaņošanas laikā parādās melns ekrāns vai aizķeršanās
- Rādīt krāsainas lentes virs attēliem, norādot to avotu: sarkana - tīkls, zila - disks, zaļa - atmiņaIeslēgt teksta atlasīšanu video aprakstāLejupielādes mape vēl nav iestatīta, izvēlieties noklusējuma lejupielādes mapiPārvelciet objektus, lai tos noņemtuLokālie meklēšanas ieteikumi
- Rādīt attēlu indikatorusAugstas kvalitātes (lielāks)Pārbaudīt atjauninājumusManuāli pārbaudīt, vai ir atjauninājumi
diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml
index c439593f7..ee4b88a41 100644
--- a/app/src/main/res/values-ml/strings.xml
+++ b/app/src/main/res/values-ml/strings.xml
@@ -595,7 +595,6 @@
രണ്ടാം പ്രവർത്തന ബട്ടൺആദ്യ പ്രവർത്തന ബട്ടൺവീഡിയോ കാണുമ്പോൾ കറുത്ത സ്ക്രീൻ, അവ്യക്തത അനുഭവിക്കുന്നു എങ്കിൽ മീഡിയ ട്യൂൺലിങ് പ്രവർത്തനരഹിതമാക്കുക
- ഉറവിടം തിരിച്ചറിയാൻ പിക്കാസോ കളർഡ് റിബൺ ചിത്രങ്ങളുടെ മുകളിൽ കാണിക്കുക: നെറ്റ്വർക്കിന് ചുവപ്പ്, ഡിസ്കിനു നീല, മെമ്മറിയിക്ക് പച്ചസീക്ബാർ ചെറുചിത്രം പ്രദർശനംസ്നേഹത്തോടെ സൃഷ്ടാവ്ഡിസ്ക്രിപ്ഷനിലെ ടെക്സ്റ്റ് സെലക്ട് ചെയ്യുവാൻ അനുവദിക്കാതെ ഇരിക്കുക
@@ -630,7 +629,6 @@
കാണിക്കരുത്കുറഞ്ഞ നിലവാരം (ചെറുത് )ഉയർന്ന നിലവാരം (വലിയത് )
- ഇമേജ് ഇൻഡിക്കേറ്ററുകൾ കാണിക്കുകമീഡിയ ട്യൂൺലിങ് പ്രവർത്തനരഹിതമാക്കുകഡൌൺലോഡ് ഫോൾഡർ ഇത് വരെയും സെറ്റ് ചെയ്തിട്ടില്ല, സ്ഥിര ഡൌൺലോഡ് ഫോൾഡർ ഇപ്പോൾ തിരഞ്ഞെക്കുകഅഭിപ്രായങ്ങൾ പ്രവർത്തനരഹിതമായിരിക്കുന്നു
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index 416ebfd02..7acf7f4cd 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -644,9 +644,7 @@
Lokale søkeforslagMarker som settIkke start videoer i minispilleren, men bytt til fullskjermsmodus direkte dersom auto-rotering er låst. Du har fremdeles tilgang til minispilleren ved å avslutte fullskjermsvisningen
- Vis Picasso-fargede bånd på toppen av bilder for å indikere kilde: Rød for nettverk, blå for disk, og grønn for minneHjertemerket av skaperen
- Vis bildeindikatorerDra elementer for å fjerne demStart hovedspiller i fullskjermStill i kø neste
diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml
index 637eb1751..c744de62c 100644
--- a/app/src/main/res/values-nl-rBE/strings.xml
+++ b/app/src/main/res/values-nl-rBE/strings.xml
@@ -611,7 +611,6 @@
Geen download map ingesteld, kies nu de standaard download mapNiet tonenReacties zijn uitgeschakeld
- Toon afbeeldingsindicatorenSpeler meldingConfigureer actieve stream meldingMeldingen
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index b4629a03f..26e328ed4 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -632,8 +632,6 @@
Lage kwaliteit (kleiner)Hoge kwaliteit (groter)Zoekbalk miniatuurafbeelding voorbeeld
- Toon Picasso-gekleurde linten bovenop afbeeldingen die hun bron aangeven: rood voor netwerk, blauw voor schijf en groen voor geheugen
- Afbeeldingsindicatoren tonenReacties zijn uitgeschakeldZoeksuggesties op afstandLokale zoeksuggesties
diff --git a/app/src/main/res/values-nqo/strings.xml b/app/src/main/res/values-nqo/strings.xml
index 94e7ae2f4..f1960b980 100644
--- a/app/src/main/res/values-nqo/strings.xml
+++ b/app/src/main/res/values-nqo/strings.xml
@@ -440,8 +440,6 @@
ߗߋߢߊߟߌ ߟߎ߬ ߞߟߏߜߍ߫ ߓߐߛߎ߲ߡߊ ߟߎ߬ ߦߌ߬ߘߊ߬ߕߐ߫ ߟߋ߬ ߟߊ߬ߖߍ߲߬ߛߍ߲߬ߠߌ߲ ߘߐ߫ߞߋߟߋߞߋߟߋ ߟߊ߫ ߝߊߟߊ߲ߓߍߦߊ ߟߊߛߊ߬ߞߋߟߋߞߋߟߋ ߟߊ߫ ߝߊߟߊ߲ߓߍߦߊ ߟߊߛߊ߬ ߣߴߌ ߞߊ߬ ߥߊ߲߬ߊߥߊ߲߬ ߝߌ߲ ߦߋ߫ ߥߟߊ߫ ߜߊߘߊ߲ߜߊߘߊ߲ߠߌ߲ ߦߋߡߍ߲ߕߊ ߘߏ߫ ߘߐߛߊߙߌ߫ ߕߎߡߊ
- ߞߊ߬ ߖߌ߬ߦߊ߬ߓߍ߫ ߦߌ߬ߘߊ߬ߟߊ߲ ߠߎ߫ ߝߍ߲߬ߛߍ߲߫
- ߏ߬ ߦߋ߫ ߔߌߛߊߞߏ߫ ߟߊ߫ ߡߙߎߝߋ߫ ߞߟߐ߬ߡߊ ߟߎ߫ ߟߋ߬ ߝߍ߲߬ߛߍ߲߬ ߠߊ߫ ߖߌ߬ߦߊ߬ߓߍ ߟߎ߫ ߞߎ߲߬ߘߐ߫ ߞߵߊ߬ߟߎ߬ ߓߐߛߎ߲ ߦߌ߬ߘߊ߬: ߥߎߟߋ߲߬ߡߊ߲ ߦߋ߫ ߞߙߏ߬ߝߏ ߕߊ ߘߌ߫߸ ߓߊ߯ߡߊ ߦߋ߫ ߝߘߍ߬ ߜߍߟߍ߲ ߕߊ ߘߌ߫ ߊ߬ߣߌ߫ ߝߙߌߛߌߡߊ ߦߋ߫ ߦߟߌߕߏߟߊ߲ ߕߊ ߘߌ߫ߟߊ߬ߓߐ߬ߟߌ ߦߴߌߘߐ߫…ߞߵߊ߬ ߘߊߡߌ߬ߣߊ߬ߞߊ߲߬ߞߎߡߊ ߟߎ߬ ߟߊߛߊ߬ߣߍ߲ ߠߋ߬
diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml
index f9faa8324..59a6a739a 100644
--- a/app/src/main/res/values-or/strings.xml
+++ b/app/src/main/res/values-or/strings.xml
@@ -342,7 +342,6 @@
ସେବାଗୁଡିକରୁ ମୂଳ ଲେଖା ଷ୍ଟ୍ରିମ୍ ଆଇଟମ୍ ଗୁଡିକରେ ଦୃଶ୍ୟମାନ ହେବମିଡିଆ ଟନେଲିଂକୁ ଅକ୍ଷମ କରନ୍ତୁଯଦି ଆପଣ ଏକ କଳା ପରଦା ଅନୁଭବ କରନ୍ତି କିମ୍ବା ଭିଡିଓ ପ୍ଲେବେକ୍ ଉପରେ ଝୁଣ୍ଟି ପଡ଼ନ୍ତି ତେବେ ମିଡିଆ ଟନେଲିଂକୁ ଅକ୍ଷମ କରନ୍ତୁ ।
- ଚିତ୍ରଗୁଡ଼ିକର ଉପରେ ପିକାସୋ ରଙ୍ଗୀନ ଫିତା ଦେଖାନ୍ତୁ: ସେମାନଙ୍କର ଉତ୍ସକୁ ସୂଚାଇଥାଏ: ନେଟୱାର୍କ ପାଇଁ ନାଲି, ଡିସ୍କ ପାଇଁ ନୀଳ ଏବଂ ସ୍ମୃତି ପାଇଁ ସବୁଜଆମଦାନି କରନ୍ତୁଠାରୁ ଆମଦାନୀ କରନ୍ତୁଆମଦାନି…
@@ -657,7 +656,6 @@
ଅଟୋ-ଜେନେରେଟ୍ (କୌଣସି ଅପଲୋଡର୍ ମିଳିଲା ନାହିଁ)ପୁରଣ କରନ୍ତୁକ୍ୟାପସନ୍
- ପ୍ରତିଛବି ସୂଚକ ଦେଖାନ୍ତୁପ୍ଲେୟାର ବ୍ୟବହାର କରିବା ସମୟରେ ଏକ କ୍ରାସ୍ ବିକଳ୍ପ ଦେଖାଏନୂତନ ଷ୍ଟ୍ରିମ୍ ପାଇଁ ଯାଞ୍ଚ ଚଲାନ୍ତୁଆପ୍ କ୍ରାସ୍ କରନ୍ତୁ
diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml
index 814cdb885..d612ff75b 100644
--- a/app/src/main/res/values-pa/strings.xml
+++ b/app/src/main/res/values-pa/strings.xml
@@ -626,8 +626,6 @@
ਨਿਊਪਾਈਪ ਖਾਮੀ ਤੋਂ ਪ੍ਰਭਾਵਤ ਹੋਈ ਹੈ, ਇੱਥੇ ਨੱਪ ਕੇ ਰਿਪੋਰਟ ਕਰੋਇੱਕ ਖਾਮੀ ਪ੍ਰਭਾਵੀ ਹੋਈ ਹੈ, ਨੋਟੀਫੀਕੇਸ਼ਨ ਵੇਖੋਆਈਟਮਾਂ ਨੂੰ ਇੱਕ ਪਾਸੇ ਖਿੱਚ ਕੇ ਹਟਾਓ
- ਦ੍ਰਿਸ਼ ਸੂਚਕ ਵਿਖਾਓ
- ਦ੍ਰਿਸ਼ਾਂ ਦੇ ਉੱਪਰ ਉਹਨਾਂ ਦੀ ਸਰੋਤ-ਪਛਾਣ ਲਈ ਪਿਕਾਸੋ ਦੇ ਰੰਗਦਾਰ ਰਿਬਨ ਵਿਖਾਓ : ਨੈੱਟਵਰਕ ਲਈ ਲਾਲ, ਡਿਸਕ ਲਈ ਨੀਲੇ ਤੇ ਮੈਮਰੀ ਲਈ ਹਰੇਨਵੀਂ ਸਟ੍ਰੀਮ ਦੇ ਨੋਟੀਫਿਕੇਸ਼ਨਪਿੰਨ ਕੀਤੀ ਟਿੱਪਣੀਅੱਪਡੇਟ ਦੀ ਉਪਲੱਬਧਤਾ ਪਰਖੀ ਜਾ ਰਹੀ…
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 01f242cd9..b7c517ffc 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -649,8 +649,6 @@
Nie pokazujSerduszko od twórcyOznacz jako obejrzane
- Pokazuj kolorowe wstążki Picasso nad obrazami wskazujące ich źródło: czerwone dla sieci, niebieskie dla dysku i zielone dla pamięci
- Pokazuj wskaźniki obrazuZdalne podpowiedzi wyszukiwaniaLokalne podpowiedzi wyszukiwania
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 5a203e0f2..3d4b57621 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -644,7 +644,6 @@
Os comentários estão desabilitadosMarcar como assistidoCurtido pelo criador
- Exibir fitas coloridas no topo das imagens indicando sua fonte: vermelho para rede, azul para disco e verde para memória%1$s download excluído%1$s downloads excluídos
@@ -655,7 +654,6 @@
%s downloads concluídos%s downloads concluídos
- Mostrar indicadores de imagemAdicionado na próxima posição da filaEnfileira a próximaDeslize os itens para remove-los
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index 498a49a53..23310adec 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -644,8 +644,6 @@
Ainda não foi definida uma pasta de descarregamento, escolha agora a pasta de descarregamento padrãoComentários estão desativadosMarcar como visto
- Mostrar fitas coloridas de Picasso em cima das imagens que indicam a sua fonte: vermelho para rede, azul para disco e verde para memória
- Mostrar indicadores de imagemSugestões de pesquisa remotasSugestões de pesquisa locais
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 5534dbf0b..99e5cbd04 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -644,8 +644,6 @@
Baixa qualidade (menor)Alta qualidade (maior)Os comentários estão desativados
- Mostrar fitas coloridas de Picasso em cima das imagens que indicam a sua fonte: vermelho para rede, azul para disco e verde para memória
- Mostrar indicadores de imagemSugestões de pesquisa remotasSugestões de pesquisa locais
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index bcef4d952..a5eb21143 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -660,8 +660,6 @@
Calitate scăzută (mai mică)Calitate înaltă (mai mare)Miniatură de previzualizare în bara de derulare
- Afișați panglici colorate de Picasso deasupra imaginilor, indicând sursa acestora: roșu pentru rețea, albastru pentru disc și verde pentru memorie
- Afișați indicatorii de imagineDezactivați tunelarea media dacă întâmpinați un ecran negru sau blocaje la redarea video.Procesarea.. Poate dura un momentVerifică dacă există actualizări
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 9e79b165f..667e5413d 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -652,8 +652,6 @@
Миниатюра над полосой прокруткиАвтору видео понравилось этоПометить проигранным
- Picasso: указать цветом источник изображений (красный — сеть, синий — диск, зелёный — память)
- Цветные метки на изображенияхСерверные предложения поискаЛокальные предложения поиска
diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml
index 5a4f35de5..e970950e0 100644
--- a/app/src/main/res/values-ryu/strings.xml
+++ b/app/src/main/res/values-ryu/strings.xml
@@ -646,8 +646,6 @@
%sちぬダウンロードぬかんりょうさびたん%sちぬダウンロードぬかんりょうさびたん
- ピカソー、がぞうぬういに、がぞうくとぅどぅくるしーきびちするしきさいきしーょうひょうじさびーん: あかーネットワーク、あおーディスク、みどぅれーメモリ
- やしがぞうんかいふぃいょうしきひょうじしーょりちゅう… くーてーんじがんがかかいんかむしりやびらんみーさるバージョンしーゅどうでぃかくにんさびーんアップデートかくにんちゅう…
diff --git a/app/src/main/res/values-sat/strings.xml b/app/src/main/res/values-sat/strings.xml
index a5959086e..9ede53a76 100644
--- a/app/src/main/res/values-sat/strings.xml
+++ b/app/src/main/res/values-sat/strings.xml
@@ -270,7 +270,6 @@
LeakCanary ᱵᱟᱭ ᱧᱟᱢᱚᱜ ᱠᱟᱱᱟᱢᱮᱢᱚᱨᱤ ᱞᱤᱠᱟᱞ ᱢᱚᱱᱤᱴᱚᱨᱤᱝ ᱦᱤᱯ ᱰᱟᱢᱯᱤᱝ ᱚᱠᱛᱚ ᱨᱮ ᱮᱯᱞᱤᱠᱮᱥᱚᱱ ᱨᱟᱥᱴᱨᱤᱭ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜ-ᱟᱡᱤᱭᱚᱱ ᱪᱤᱠᱤ ᱠᱷᱚᱱ ᱵᱟᱦᱨᱮ ᱨᱮ ᱵᱷᱮᱜᱟᱨ ᱠᱚ ᱚᱱᱚᱞ ᱢᱮ
- ᱱᱮᱴᱣᱟᱨᱠ ᱞᱟᱹᱜᱤᱫ red, ᱰᱤᱥᱠ ᱞᱟᱹᱜᱤᱫ blue ᱟᱨ ᱢᱮᱢᱚᱨᱤ ᱞᱟᱹᱜᱤᱫ greenᱯᱞᱮᱭᱟᱨ ᱵᱮᱵᱷᱟᱨ ᱚᱠᱛᱮ ᱨᱮ ᱠᱨᱟᱥ ᱚᱯᱥᱚᱱ ᱧᱮᱞᱚᱜ ᱠᱟᱱᱟᱤᱢᱯᱳᱨᱴᱤᱢᱯᱚᱨᱴ
@@ -540,7 +539,6 @@
ᱡᱤᱱᱤᱥ ᱠᱚᱨᱮᱱᱟᱜ ᱢᱩᱞ ᱚᱠᱛᱚ ᱧᱮᱞ ᱢᱮᱥᱮᱵᱟ ᱠᱷᱚᱱ ᱚᱨᱡᱤᱱᱤᱭᱟᱞ ᱴᱮᱠᱥᱴ ᱠᱚ ᱥᱴᱨᱤᱢ ᱤᱴᱮᱢ ᱨᱮ ᱧᱮᱞᱚᱜᱼᱟᱡᱩᱫᱤ ᱟᱢ ᱵᱷᱤᱰᱤᱭᱳ ᱯᱞᱮᱭᱚᱯ ᱨᱮ ᱵᱞᱮᱠ ᱥᱠᱨᱤᱱ ᱟᱨᱵᱟᱝ ᱠᱷᱟᱹᱞᱤ ᱥᱴᱮᱴᱞᱤᱝ ᱮᱢ ᱧᱟᱢᱟ ᱮᱱᱠᱷᱟᱱ ᱢᱤᱰᱤᱭᱟ ᱴᱩᱱᱮᱞᱤᱝ ᱵᱚᱫᱚᱞ ᱢᱮ ᱾
- ᱪᱤᱛᱟᱹᱨ ᱪᱤᱱᱦᱟᱹ ᱠᱚ ᱧᱮᱞ ᱢᱮᱱᱟᱣᱟ ᱥᱴᱨᱤᱢ ᱞᱟᱹᱜᱤᱫ ᱪᱟᱪᱞᱟᱣ ᱢᱮᱢᱤᱫ error notification ᱛᱮᱭᱟᱨ ᱢᱮᱥᱮᱞᱮᱫ ᱮᱠᱥᱯᱳᱨᱴ ᱵᱟᱝ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜ ᱠᱟᱱᱟ
diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml
index 6b89b32c3..fce5280e1 100644
--- a/app/src/main/res/values-sc/strings.xml
+++ b/app/src/main/res/values-sc/strings.xml
@@ -634,8 +634,6 @@
Sos cummentos sunt disabilitadosSu creadore b\'at postu unu coroMarca comente pompiadu
- Ammustra sos listrones colorados de Picasso in subra de sas immàgines chi indicant sa fonte issoro: ruja pro sa retze, biaita pro su discu e birde pro sa memòria
- Ammustra sos indicadores de immàginesImpòsitos de chirca remotaImpòsitos de chirca locales
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index e3aa5b6bc..5c4210b71 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -653,8 +653,6 @@
Nízka kvalita (menšie)Vysoká kvalita (väčšie)Náhľad miniatúry pri vyhľadávaní
- Zobrazí farebné pásiky Picasso na obrázkoch podľa ich zdroja: červený pre sieť, modrý pre disk a zelený pre pamäť
- Zobraziť indikátory obrázkaPotiahnutím vymazaťKomentáre sú zakázanéAk je automatické otáčanie zablokované, nespustí videá v miniprehrávači, ale prepne sa do celoobrazovkového režimu. Do miniprehrávača sa dostanete po ukončení režimu celej obrazovky
diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml
index e37c3a36d..72e661a1b 100644
--- a/app/src/main/res/values-so/strings.xml
+++ b/app/src/main/res/values-so/strings.xml
@@ -633,8 +633,6 @@
Fallooyinka waa laxidhayKahelay soosaarahaWaan daawaday
- Soo bandhig shaambado midabka Picasso leh sawirrada dushooda oo tilmaamaya isha laga keenay: guduud waa khadka, buluug waa kaydka gudaha, cagaar waa kaydka K/G
- Tus tilmaamayaasha sawirkaSoojeedinada raadinta banaankaSoojeedinada raadinta gudahaCabirka soodaarida udhexeeya
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 5f14a0e51..2300cd929 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -644,7 +644,6 @@
Означи као одгледаноКоментари су онемогућениОбрађивање… Може потрајати пар тренутака
- Прикажи индикаторе сликеНе покрећите видео снимке у мини-плејеру, већ директно пређите на режим целог екрана, ако је аутоматска ротација закључана. И даље можете приступити мини-плејеру тако што ћете изаћи из целог екранаПокрени главни плејер преко целог екранаСрушите плејер
@@ -740,7 +739,6 @@
Обавештења за пријаву грешакаУвезите или извезите праћења из менија са 3 тачкеАудио снимак
- Прикажите Picasso обојене траке на врху слика које указују на њихов извор: црвена за мрежу, плава за диск и зелена за меморијуНаправите обавештење о грешциПроценатКористите најновију верзију NewPipe-а
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 8cf57f605..50948fd57 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -633,7 +633,6 @@
Du kan välja det natt-tema du föredrar nedanVälj det natt-tema du föredrar — %sSökradens förhandsvisningsminiatyr
- Visa bildindikatorerLokala sökningsförslagTog bort %1$s nedladdning
@@ -651,7 +650,6 @@
Svep objekt för att ta bort demFörslag via fjärrsökningStarta inte videor i minispelaren, utan byt till helskärmsläge direkt, om automatisk rotation är låst. Du kan fortfarande komma åt minispelaren genom att gå ut ur helskärmsläge
- Visa Picasso färgade band ovanpå bilderna som anger deras källa: rött för nätverk, blått för disk och grönt för minneSök efter uppdateringarKolla manuellt efter nya versionerSöker efter uppdateringar…
diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml
index b2846823c..90708580a 100644
--- a/app/src/main/res/values-te/strings.xml
+++ b/app/src/main/res/values-te/strings.xml
@@ -442,7 +442,6 @@
ప్లేబ్యాక్ స్పీడ్ నియంత్రణలుఏమిలేదుమీరు బ్లాక్ స్క్రీన్ లేదా చలనచిత్రం ప్లేబ్యాక్లో అంతరాయాన్ని అనుభవిస్తే మీడియా టన్నెలింగ్ను నిలిపివేయండి
- చిత్రాల మూలాన్ని సూచించే విధంగా వాటి పైభాగంలో పికాసో రంగు రిబ్బన్లను చూపండి: నెట్వర్క్ కోసం ఎరుపు, డిస్క్ కోసం నీలం మరియు మెమరీ కోసం ఆకుపచ్చలోపం స్నాక్బార్ని చూపండిమీరు NewPipe యొక్క తాజా సంస్కరణను అమలు చేస్తున్నారుNewPipe నవీకరణ అందుబాటులో ఉంది!
@@ -455,7 +454,6 @@
తక్కువ నాణ్యత (చిన్నది)చూపించవద్దుమీడియా టన్నెలింగ్ని నిలిపివేయండి
- చిత్ర సూచికలను చూపుకొత్త స్ట్రీమ్ల కోసం తనిఖీని అమలు చేయండిఎర్రర్ నోటిఫికేషన్ను సృష్టించండిదిగుమతి
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index adecbf3ff..29933bdc6 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -633,8 +633,6 @@
Yorumlar devre dışıYaratıcısınca kalplendiİzlendi olarak işaretle
- Resimlerin üzerinde kaynaklarını gösteren Picasso renkli şeritler göster: ağ için kırmızı, disk için mavi ve bellek için yeşil
- Resim göstergelerini gösterUzak arama önerileriYerel arama önerileri
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index c34708609..86350d40e 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -646,8 +646,6 @@
Мініатюра з попереднім переглядом на повзунку поступуВподобано авторомПозначити переглянутим
- Показувати кольорові стрічки Пікассо поверх зображень із зазначенням їх джерела: червоний для мережі, синій для диска та зелений для пам’яті
- Показати індикатори зображеньВіддалені пропозиції пошукуЛокальні пошукові пропозиції
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index 0d71173af..15f5a86d4 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -624,8 +624,6 @@
Bình luận đã bị tắtĐã được chủ kênh thả \"thính\"Đánh dấu là đã xem
- Hiển thị các dải băng màu Picasso trên đầu các hình ảnh cho biết nguồn của chúng: màu đỏ cho mạng, màu lam cho đĩa và màu lục cho bộ nhớ
- Hiện dấu chỉ hình ảnhĐề xuất tìm kiếm trên mạngĐề xuất tìm kiếm cục bộ
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index fa8d31022..7b303621b 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -624,8 +624,6 @@
高品质(较大)被创作者喜爱标记为已观看
- 在图像顶部显示毕加索彩带,指示其来源:红色代表网络,蓝色代表磁盘,绿色代表内存
- 显示图像指示器远程搜索建议本地搜索建议
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 518a1290f..9f581b43f 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -668,9 +668,7 @@
新你係咪要刪除呢個谷?淨係顯示未成谷嘅訂閱
- 啲圖都要騷 Picasso 三色碼顯示源頭:紅碼係網絡上高落嚟,藍碼係儲存喺磁碟本地,綠碼係潛伏喺記憶體中服務原本嘅字會騷返喺串流項目上面
- 影像要推三色碼若果播片嘅時候窒下窒下或者黑畫面,就停用多媒體隧道啦。點樣用 Google 匯出嚟匯入 YouTube 訂閱:
\n
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index c404edeca..a4ad3578f 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -624,8 +624,6 @@
拖動列縮圖預覽被創作者加心號標記為已觀看
- 在圖片頂部顯示畢卡索彩色絲帶,指示其來源:紅色代表網路、藍色代表磁碟、綠色代表記憶體
- 顯示圖片指示器遠端搜尋建議本機搜尋建議
diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml
index fb68a464d..e31cebb92 100644
--- a/app/src/main/res/values/settings_keys.xml
+++ b/app/src/main/res/values/settings_keys.xml
@@ -241,7 +241,6 @@
show_memory_leaks_keyallow_disposed_exceptions_keyshow_original_time_ago_key
- show_image_indicators_keyshow_crash_the_player_keycheck_new_streamscrash_the_app_key
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 56140441c..bff35e5d9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -486,8 +486,6 @@
Disable media tunnelingDisable media tunneling if you experience a black screen or stuttering on video playback.Media tunneling was disabled by default on your device because your device model is known to not support it.
- Show image indicators
- Show Picasso colored ribbons on top of images indicating their source: red for network, blue for disk and green for memoryShow \"Crash the player\"Shows a crash option when using the playerRun check for new streams
diff --git a/app/src/main/res/xml/debug_settings.xml b/app/src/main/res/xml/debug_settings.xml
index 84bb281f3..d97c5aa1a 100644
--- a/app/src/main/res/xml/debug_settings.xml
+++ b/app/src/main/res/xml/debug_settings.xml
@@ -34,13 +34,6 @@
app:singleLineTitle="false"
app:iconSpaceReserved="false" />
-
-
Date: Fri, 5 Jul 2024 08:29:21 +0530
Subject: [PATCH 003/134] Revert "Migrate image loading from Picasso to Coil
(#11201)"
This reverts commit 73e3a69aaf78a1d7a7f2f4c54e22d718b7c3093a.
---
app/build.gradle | 3 +-
app/src/main/java/org/schabi/newpipe/App.java | 24 +-
.../org/schabi/newpipe/about/AboutActivity.kt | 4 +-
.../fragments/detail/VideoDetailFragment.java | 29 ++-
.../list/channel/ChannelFragment.java | 20 +-
.../list/comments/CommentRepliesFragment.java | 4 +-
.../list/playlist/PlaylistFragment.java | 11 +-
.../newpipe/info_list/StreamSegmentItem.kt | 44 ++--
.../holder/ChannelMiniInfoItemHolder.java | 4 +-
.../holder/CommentInfoItemHolder.java | 8 +-
.../holder/PlaylistMiniInfoItemHolder.java | 4 +-
.../holder/StreamMiniInfoItemHolder.java | 4 +-
.../java/org/schabi/newpipe/ktx/Bitmap.kt | 13 -
.../newpipe/local/feed/item/StreamItem.kt | 4 +-
.../feed/notifications/NotificationHelper.kt | 58 ++++-
.../local/holder/LocalPlaylistItemHolder.java | 7 +-
.../holder/LocalPlaylistStreamItemHolder.java | 6 +-
.../LocalStatisticStreamItemHolder.java | 6 +-
.../holder/RemotePlaylistItemHolder.java | 7 +-
.../local/subscription/item/ChannelItem.kt | 4 +-
.../item/PickerSubscriptionItem.kt | 4 +-
.../org/schabi/newpipe/player/Player.java | 87 ++++---
.../playqueue/PlayQueueItemBuilder.java | 4 +-
.../SeekbarPreviewThumbnailHolder.java | 7 +-
.../settings/ContentSettingsFragment.java | 20 +-
.../settings/DebugSettingsFragment.java | 9 +
.../settings/SelectChannelFragment.java | 4 +-
.../settings/SelectPlaylistFragment.java | 17 +-
.../external_communication/ShareUtils.java | 21 +-
.../schabi/newpipe/util/image/CoilHelper.kt | 142 -----------
.../newpipe/util/image/PicassoHelper.java | 224 ++++++++++++++++++
app/src/main/res/values-ar-rLY/strings.xml | 2 +
app/src/main/res/values-ar/strings.xml | 2 +
app/src/main/res/values-az/strings.xml | 2 +
app/src/main/res/values-be/strings.xml | 2 +
app/src/main/res/values-bg/strings.xml | 1 +
app/src/main/res/values-bn/strings.xml | 1 +
app/src/main/res/values-ca/strings.xml | 2 +
app/src/main/res/values-ckb/strings.xml | 2 +
app/src/main/res/values-cs/strings.xml | 2 +
app/src/main/res/values-da/strings.xml | 2 +
app/src/main/res/values-de/strings.xml | 2 +
app/src/main/res/values-el/strings.xml | 2 +
app/src/main/res/values-es/strings.xml | 2 +
app/src/main/res/values-et/strings.xml | 2 +
app/src/main/res/values-eu/strings.xml | 2 +
app/src/main/res/values-fa/strings.xml | 2 +
app/src/main/res/values-fi/strings.xml | 2 +
app/src/main/res/values-fr/strings.xml | 2 +
app/src/main/res/values-gl/strings.xml | 2 +
app/src/main/res/values-he/strings.xml | 2 +
app/src/main/res/values-hi/strings.xml | 2 +
app/src/main/res/values-hr/strings.xml | 2 +
app/src/main/res/values-hu/strings.xml | 2 +
app/src/main/res/values-in/strings.xml | 2 +
app/src/main/res/values-is/strings.xml | 2 +
app/src/main/res/values-it/strings.xml | 2 +
app/src/main/res/values-ja/strings.xml | 2 +
app/src/main/res/values-ka/strings.xml | 2 +
app/src/main/res/values-ko/strings.xml | 2 +
app/src/main/res/values-lt/strings.xml | 2 +
app/src/main/res/values-lv/strings.xml | 2 +
app/src/main/res/values-ml/strings.xml | 2 +
app/src/main/res/values-nb-rNO/strings.xml | 2 +
app/src/main/res/values-nl-rBE/strings.xml | 1 +
app/src/main/res/values-nl/strings.xml | 2 +
app/src/main/res/values-nqo/strings.xml | 2 +
app/src/main/res/values-or/strings.xml | 2 +
app/src/main/res/values-pa/strings.xml | 2 +
app/src/main/res/values-pl/strings.xml | 2 +
app/src/main/res/values-pt-rBR/strings.xml | 2 +
app/src/main/res/values-pt-rPT/strings.xml | 2 +
app/src/main/res/values-pt/strings.xml | 2 +
app/src/main/res/values-ro/strings.xml | 2 +
app/src/main/res/values-ru/strings.xml | 2 +
app/src/main/res/values-ryu/strings.xml | 2 +
app/src/main/res/values-sat/strings.xml | 2 +
app/src/main/res/values-sc/strings.xml | 2 +
app/src/main/res/values-sk/strings.xml | 2 +
app/src/main/res/values-so/strings.xml | 2 +
app/src/main/res/values-sr/strings.xml | 2 +
app/src/main/res/values-sv/strings.xml | 2 +
app/src/main/res/values-te/strings.xml | 2 +
app/src/main/res/values-tr/strings.xml | 2 +
app/src/main/res/values-uk/strings.xml | 2 +
app/src/main/res/values-vi/strings.xml | 2 +
app/src/main/res/values-zh-rCN/strings.xml | 2 +
app/src/main/res/values-zh-rHK/strings.xml | 2 +
app/src/main/res/values-zh-rTW/strings.xml | 2 +
app/src/main/res/values/settings_keys.xml | 1 +
app/src/main/res/values/strings.xml | 2 +
app/src/main/res/xml/debug_settings.xml | 7 +
92 files changed, 596 insertions(+), 330 deletions(-)
delete mode 100644 app/src/main/java/org/schabi/newpipe/ktx/Bitmap.kt
delete mode 100644 app/src/main/java/org/schabi/newpipe/util/image/CoilHelper.kt
create mode 100644 app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java
diff --git a/app/build.gradle b/app/build.gradle
index 1ba5aca38..4652cf6e5 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -267,7 +267,8 @@ dependencies {
implementation "com.github.lisawray.groupie:groupie-viewbinding:${groupieVersion}"
// Image loading
- implementation 'io.coil-kt:coil:2.6.0'
+ //noinspection GradleDependency --> 2.8 is the last version, not 2.71828!
+ implementation "com.squareup.picasso:picasso:2.8"
// Markdown library for Android
implementation "io.noties.markwon:core:${markwonVersion}"
diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java
index a47e0f2fd..d92425d20 100644
--- a/app/src/main/java/org/schabi/newpipe/App.java
+++ b/app/src/main/java/org/schabi/newpipe/App.java
@@ -1,6 +1,5 @@
package org.schabi.newpipe;
-import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
@@ -9,7 +8,6 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationChannelCompat;
import androidx.core.app.NotificationManagerCompat;
-import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import com.jakewharton.processphoenix.ProcessPhoenix;
@@ -22,9 +20,10 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.settings.NewPipeSettings;
import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.image.ImageStrategy;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.StateSaver;
-import org.schabi.newpipe.util.image.ImageStrategy;
import org.schabi.newpipe.util.image.PreferredImageQuality;
import java.io.IOException;
@@ -33,9 +32,6 @@ import java.net.SocketException;
import java.util.List;
import java.util.Objects;
-import coil.ImageLoader;
-import coil.ImageLoaderFactory;
-import coil.util.DebugLogger;
import io.reactivex.rxjava3.exceptions.CompositeException;
import io.reactivex.rxjava3.exceptions.MissingBackpressureException;
import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException;
@@ -61,7 +57,7 @@ import io.reactivex.rxjava3.plugins.RxJavaPlugins;
* along with NewPipe. If not, see .
*/
-public class App extends Application implements ImageLoaderFactory {
+public class App extends Application {
public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
private static final String TAG = App.class.toString();
@@ -112,22 +108,20 @@ public class App extends Application implements ImageLoaderFactory {
// Initialize image loader
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ PicassoHelper.init(this);
ImageStrategy.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this,
prefs.getString(getString(R.string.image_quality_key),
getString(R.string.image_quality_default))));
+ PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG
+ && prefs.getBoolean(getString(R.string.show_image_indicators_key), false));
configureRxJavaErrorHandler();
}
- @NonNull
@Override
- public ImageLoader newImageLoader() {
- return new ImageLoader.Builder(this)
- .allowRgb565(ContextCompat.getSystemService(this, ActivityManager.class)
- .isLowRamDevice())
- .logger(BuildConfig.DEBUG ? new DebugLogger() : null)
- .crossfade(true)
- .build();
+ public void onTerminate() {
+ super.onTerminate();
+ PicassoHelper.terminate();
}
protected Downloader getDownloader() {
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
index 0d0d0d48d..7f148e9b5 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
@@ -167,8 +167,8 @@ class AboutActivity : AppCompatActivity() {
"https://square.github.io/okhttp/", StandardLicenses.APACHE2
),
SoftwareComponent(
- "Coil", "2023", "Coil Contributors",
- "https://coil-kt.github.io/coil/", StandardLicenses.APACHE2
+ "Picasso", "2013", "Square, Inc.",
+ "https://square.github.io/picasso/", StandardLicenses.APACHE2
),
SoftwareComponent(
"PrettyTime", "2012 - 2020", "Lincoln Baxter, III",
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
index 96523321b..95b54f65a 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
@@ -116,7 +116,7 @@ import org.schabi.newpipe.util.StreamTypeUtil;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.external_communication.KoreUtils;
import org.schabi.newpipe.util.external_communication.ShareUtils;
-import org.schabi.newpipe.util.image.CoilHelper;
+import org.schabi.newpipe.util.image.PicassoHelper;
import java.util.ArrayList;
import java.util.Iterator;
@@ -127,7 +127,6 @@ import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
-import coil.util.CoilUtils;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
@@ -160,6 +159,8 @@ public final class VideoDetailFragment
private static final String DESCRIPTION_TAB_TAG = "DESCRIPTION TAB";
private static final String EMPTY_TAB_TAG = "EMPTY TAB";
+ private static final String PICASSO_VIDEO_DETAILS_TAG = "PICASSO_VIDEO_DETAILS_TAG";
+
// tabs
private boolean showComments;
private boolean showRelatedItems;
@@ -1470,10 +1471,7 @@ public final class VideoDetailFragment
}
}
- CoilUtils.dispose(binding.detailThumbnailImageView);
- CoilUtils.dispose(binding.detailSubChannelThumbnailView);
- CoilUtils.dispose(binding.overlayThumbnail);
-
+ PicassoHelper.cancelTag(PICASSO_VIDEO_DETAILS_TAG);
binding.detailThumbnailImageView.setImageBitmap(null);
binding.detailSubChannelThumbnailView.setImageBitmap(null);
}
@@ -1564,8 +1562,8 @@ public final class VideoDetailFragment
binding.detailSecondaryControlPanel.setVisibility(View.GONE);
checkUpdateProgressInfo(info);
- CoilHelper.INSTANCE.loadDetailsThumbnail(binding.detailThumbnailImageView,
- info.getThumbnails());
+ PicassoHelper.loadDetailsThumbnail(info.getThumbnails()).tag(PICASSO_VIDEO_DETAILS_TAG)
+ .into(binding.detailThumbnailImageView);
showMetaInfoInTextView(info.getMetaInfo(), binding.detailMetaInfoTextView,
binding.detailMetaInfoSeparator, disposables);
@@ -1615,8 +1613,8 @@ public final class VideoDetailFragment
binding.detailUploaderTextView.setVisibility(View.GONE);
}
- CoilHelper.INSTANCE.loadAvatar(binding.detailSubChannelThumbnailView,
- info.getUploaderAvatars());
+ PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG)
+ .into(binding.detailSubChannelThumbnailView);
binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE);
binding.detailUploaderThumbnailView.setVisibility(View.GONE);
}
@@ -1647,11 +1645,11 @@ public final class VideoDetailFragment
binding.detailUploaderTextView.setVisibility(View.GONE);
}
- CoilHelper.INSTANCE.loadAvatar(binding.detailSubChannelThumbnailView,
- info.getSubChannelAvatars());
+ PicassoHelper.loadAvatar(info.getSubChannelAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG)
+ .into(binding.detailSubChannelThumbnailView);
binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE);
- CoilHelper.INSTANCE.loadAvatar(binding.detailUploaderThumbnailView,
- info.getUploaderAvatars());
+ PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG)
+ .into(binding.detailUploaderThumbnailView);
binding.detailUploaderThumbnailView.setVisibility(View.VISIBLE);
}
@@ -2405,7 +2403,8 @@ public final class VideoDetailFragment
binding.overlayTitleTextView.setText(isEmpty(overlayTitle) ? "" : overlayTitle);
binding.overlayChannelTextView.setText(isEmpty(uploader) ? "" : uploader);
binding.overlayThumbnail.setImageDrawable(null);
- CoilHelper.INSTANCE.loadDetailsThumbnail(binding.overlayThumbnail, thumbnails);
+ PicassoHelper.loadDetailsThumbnail(thumbnails).tag(PICASSO_VIDEO_DETAILS_TAG)
+ .into(binding.overlayThumbnail);
}
private void setOverlayPlayPauseImage(final boolean playerIsPlaying) {
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
index 3890e4865..fd382adbf 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
@@ -50,16 +50,15 @@ import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.StateSaver;
+import org.schabi.newpipe.util.image.ImageStrategy;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
-import org.schabi.newpipe.util.image.CoilHelper;
-import org.schabi.newpipe.util.image.ImageStrategy;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
-import coil.util.CoilUtils;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
@@ -74,6 +73,7 @@ public class ChannelFragment extends BaseStateFragment
implements StateSaver.WriteRead {
private static final int BUTTON_DEBOUNCE_INTERVAL = 100;
+ private static final String PICASSO_CHANNEL_TAG = "PICASSO_CHANNEL_TAG";
@State
protected int serviceId = Constants.NO_SERVICE_ID;
@@ -576,9 +576,7 @@ public class ChannelFragment extends BaseStateFragment
@Override
public void showLoading() {
super.showLoading();
- CoilUtils.dispose(binding.channelAvatarView);
- CoilUtils.dispose(binding.channelBannerImage);
- CoilUtils.dispose(binding.subChannelAvatarView);
+ PicassoHelper.cancelTag(PICASSO_CHANNEL_TAG);
animate(binding.channelSubscribeButton, false, 100);
}
@@ -589,15 +587,17 @@ public class ChannelFragment extends BaseStateFragment
setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName());
if (ImageStrategy.shouldLoadImages() && !result.getBanners().isEmpty()) {
- CoilHelper.INSTANCE.loadBanner(binding.channelBannerImage, result.getBanners());
+ PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG)
+ .into(binding.channelBannerImage);
} else {
// do not waste space for the banner, if the user disabled images or there is not one
binding.channelBannerImage.setImageDrawable(null);
}
- CoilHelper.INSTANCE.loadAvatar(binding.channelAvatarView, result.getAvatars());
- CoilHelper.INSTANCE.loadAvatar(binding.subChannelAvatarView,
- result.getParentChannelAvatars());
+ PicassoHelper.loadAvatar(result.getAvatars()).tag(PICASSO_CHANNEL_TAG)
+ .into(binding.channelAvatarView);
+ PicassoHelper.loadAvatar(result.getParentChannelAvatars()).tag(PICASSO_CHANNEL_TAG)
+ .into(binding.subChannelAvatarView);
binding.channelTitleView.setText(result.getName());
binding.channelSubscriberView.setVisibility(View.VISIBLE);
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java
index 4eb73520f..304eaf55a 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java
@@ -23,8 +23,8 @@ import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
-import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.util.image.ImageStrategy;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.text.TextLinkifier;
import java.util.Queue;
@@ -82,7 +82,7 @@ public final class CommentRepliesFragment
final CommentsInfoItem item = commentsInfoItem;
// load the author avatar
- CoilHelper.INSTANCE.loadAvatar(binding.authorAvatar, item.getUploaderAvatars());
+ PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(binding.authorAvatar);
binding.authorAvatar.setVisibility(ImageStrategy.shouldLoadImages()
? View.VISIBLE : View.GONE);
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
index d4607a9ff..6410fb9ee 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
@@ -53,7 +53,7 @@ import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PlayButtonHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
-import org.schabi.newpipe.util.image.CoilHelper;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.text.TextEllipsizer;
import java.util.ArrayList;
@@ -62,7 +62,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.stream.Collectors;
-import coil.util.CoilUtils;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Single;
@@ -72,6 +71,8 @@ import io.reactivex.rxjava3.disposables.Disposable;
public class PlaylistFragment extends BaseListInfoFragment
implements PlaylistControlViewHolder {
+ private static final String PICASSO_PLAYLIST_TAG = "PICASSO_PLAYLIST_TAG";
+
private CompositeDisposable disposables;
private Subscription bookmarkReactor;
private AtomicBoolean isBookmarkButtonReady;
@@ -275,7 +276,7 @@ public class PlaylistFragment extends BaseListInfoFragment() {
+) : Item() {
companion object {
const val PAYLOAD_SELECT = 1
@@ -20,32 +21,31 @@ class StreamSegmentItem(
var isSelected = false
- override fun bind(viewBinding: ItemStreamSegmentBinding, position: Int) {
- CoilHelper.loadThumbnail(viewBinding.previewImage, item.previewUrl)
- viewBinding.textViewTitle.text = item.title
+ override fun bind(viewHolder: GroupieViewHolder, position: Int) {
+ item.previewUrl?.let {
+ PicassoHelper.loadThumbnail(it)
+ .into(viewHolder.root.findViewById(R.id.previewImage))
+ }
+ viewHolder.root.findViewById(R.id.textViewTitle).text = item.title
if (item.channelName == null) {
- viewBinding.textViewChannel.visibility = View.GONE
+ viewHolder.root.findViewById(R.id.textViewChannel).visibility = View.GONE
// When the channel name is displayed there is less space
// and thus the segment title needs to be only one line height.
// But when there is no channel name displayed, the title can be two lines long.
// The default maxLines value is set to 1 to display all elements in the AS preview,
- viewBinding.textViewTitle.maxLines = 2
+ viewHolder.root.findViewById(R.id.textViewTitle).maxLines = 2
} else {
- viewBinding.textViewChannel.text = item.channelName
- viewBinding.textViewChannel.visibility = View.VISIBLE
+ viewHolder.root.findViewById(R.id.textViewChannel).text = item.channelName
+ viewHolder.root.findViewById(R.id.textViewChannel).visibility = View.VISIBLE
}
- viewBinding.textViewStartSeconds.text =
+ viewHolder.root.findViewById(R.id.textViewStartSeconds).text =
Localization.getDurationString(item.startTimeSeconds.toLong())
- viewBinding.root.setOnClickListener { onClick.onItemClick(this, item.startTimeSeconds) }
- viewBinding.root.setOnLongClickListener { onClick.onItemLongClick(this, item.startTimeSeconds); true }
- viewBinding.root.isSelected = isSelected
+ viewHolder.root.setOnClickListener { onClick.onItemClick(this, item.startTimeSeconds) }
+ viewHolder.root.setOnLongClickListener { onClick.onItemLongClick(this, item.startTimeSeconds); true }
+ viewHolder.root.isSelected = isSelected
}
- override fun bind(
- viewHolder: GroupieViewHolder,
- position: Int,
- payloads: MutableList
- ) {
+ override fun bind(viewHolder: GroupieViewHolder, position: Int, payloads: MutableList) {
if (payloads.contains(PAYLOAD_SELECT)) {
viewHolder.root.isSelected = isSelected
return
@@ -54,6 +54,4 @@ class StreamSegmentItem(
}
override fun getLayout() = R.layout.item_stream_segment
-
- override fun initializeViewBinding(view: View) = ItemStreamSegmentBinding.bind(view)
}
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java
index 92a5054e1..7afc05c6c 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java
@@ -13,8 +13,8 @@ import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.utils.Utils;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.image.CoilHelper;
public class ChannelMiniInfoItemHolder extends InfoItemHolder {
private final ImageView itemThumbnailView;
@@ -56,7 +56,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder {
itemAdditionalDetailView.setText(getDetailLine(item));
}
- CoilHelper.INSTANCE.loadAvatar(itemThumbnailView, item.getThumbnails());
+ PicassoHelper.loadAvatar(item.getThumbnails()).into(itemThumbnailView);
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnChannelSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java
index a3316d3fe..839aa1813 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java
@@ -27,8 +27,8 @@ import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
-import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.util.image.ImageStrategy;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.text.TextEllipsizer;
public class CommentInfoItemHolder extends InfoItemHolder {
@@ -82,12 +82,14 @@ public class CommentInfoItemHolder extends InfoItemHolder {
@Override
public void updateFromItem(final InfoItem infoItem,
final HistoryRecordManager historyRecordManager) {
- if (!(infoItem instanceof CommentsInfoItem item)) {
+ if (!(infoItem instanceof CommentsInfoItem)) {
return;
}
+ final CommentsInfoItem item = (CommentsInfoItem) infoItem;
+
// load the author avatar
- CoilHelper.INSTANCE.loadAvatar(itemThumbnailView, item.getUploaderAvatars());
+ PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView);
if (ImageStrategy.shouldLoadImages()) {
itemThumbnailView.setVisibility(View.VISIBLE);
itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding,
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java
index b7949318d..c9216d9a9 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java
@@ -9,8 +9,8 @@ import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.image.CoilHelper;
public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
public final ImageView itemThumbnailView;
@@ -46,7 +46,7 @@ public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
.localizeStreamCountMini(itemStreamCountView.getContext(), item.getStreamCount()));
itemUploaderView.setText(item.getUploaderName());
- CoilHelper.INSTANCE.loadPlaylistThumbnail(itemThumbnailView, item.getThumbnails());
+ PicassoHelper.loadPlaylistThumbnail(item.getThumbnails()).into(itemThumbnailView);
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnPlaylistSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java
index 32fa8bf60..01f3be6b3 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java
@@ -16,8 +16,8 @@ import org.schabi.newpipe.ktx.ViewUtils;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.StreamTypeUtil;
-import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.views.AnimatedProgressBar;
import java.util.concurrent.TimeUnit;
@@ -87,7 +87,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
}
// Default thumbnail is shown on error, while loading and if the url is empty
- CoilHelper.INSTANCE.loadThumbnail(itemThumbnailView, item.getThumbnails());
+ PicassoHelper.loadThumbnail(item.getThumbnails()).into(itemThumbnailView);
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnStreamSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/ktx/Bitmap.kt b/app/src/main/java/org/schabi/newpipe/ktx/Bitmap.kt
deleted file mode 100644
index 4a3c3e071..000000000
--- a/app/src/main/java/org/schabi/newpipe/ktx/Bitmap.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.schabi.newpipe.ktx
-
-import android.graphics.Bitmap
-import android.graphics.Rect
-import androidx.core.graphics.BitmapCompat
-
-@Suppress("NOTHING_TO_INLINE")
-inline fun Bitmap.scale(
- width: Int,
- height: Int,
- srcRect: Rect? = null,
- scaleInLinearSpace: Boolean = true,
-) = BitmapCompat.createScaledBitmap(this, width, height, srcRect, scaleInLinearSpace)
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt
index 030bb7a76..4a071d6df 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt
@@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.stream.StreamType.POST_LIVE_STREAM
import org.schabi.newpipe.extractor.stream.StreamType.VIDEO_STREAM
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.StreamTypeUtil
-import org.schabi.newpipe.util.image.CoilHelper
+import org.schabi.newpipe.util.image.PicassoHelper
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
@@ -101,7 +101,7 @@ data class StreamItem(
viewBinding.itemProgressView.visibility = View.GONE
}
- CoilHelper.loadThumbnail(viewBinding.itemThumbnailView, stream.thumbnailUrl)
+ PicassoHelper.loadThumbnail(stream.thumbnailUrl).into(viewBinding.itemThumbnailView)
if (itemVersion != ItemVersion.MINI) {
viewBinding.itemAdditionalDetails.text =
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt
index 659088ef2..8ea89368d 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt
@@ -6,6 +6,7 @@ import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
+import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.provider.Settings
@@ -15,17 +16,20 @@ import androidx.core.app.PendingIntentCompat
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import androidx.preference.PreferenceManager
+import com.squareup.picasso.Picasso
+import com.squareup.picasso.Target
import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.local.feed.service.FeedUpdateInfo
import org.schabi.newpipe.util.NavigationHelper
-import org.schabi.newpipe.util.image.CoilHelper
+import org.schabi.newpipe.util.image.PicassoHelper
/**
* Helper for everything related to show notifications about new streams to the user.
*/
class NotificationHelper(val context: Context) {
private val manager = NotificationManagerCompat.from(context)
+ private val iconLoadingTargets = ArrayList()
/**
* Show notifications for new streams from a single channel. The individual notifications are
@@ -64,23 +68,51 @@ class NotificationHelper(val context: Context) {
summaryBuilder.setStyle(style)
// open the channel page when clicking on the summary notification
- val intent = NavigationHelper
- .getChannelIntent(context, data.serviceId, data.url)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
summaryBuilder.setContentIntent(
- PendingIntentCompat.getActivity(context, data.pseudoId, intent, 0, false)
+ PendingIntentCompat.getActivity(
+ context,
+ data.pseudoId,
+ NavigationHelper
+ .getChannelIntent(context, data.serviceId, data.url)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
+ 0,
+ false
+ )
)
- val avatarIcon =
- CoilHelper.loadBitmapBlocking(context, data.avatarUrl, R.drawable.ic_newpipe_triangle_white)
+ // a Target is like a listener for image loading events
+ val target = object : Target {
+ override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) {
+ // set channel icon only if there is actually one (for Android versions < 7.0)
+ summaryBuilder.setLargeIcon(bitmap)
- summaryBuilder.setLargeIcon(avatarIcon)
+ // Show individual stream notifications, set channel icon only if there is actually
+ // one
+ showStreamNotifications(newStreams, data.serviceId, bitmap)
+ // Show summary notification
+ manager.notify(data.pseudoId, summaryBuilder.build())
- // Show individual stream notifications, set channel icon only if there is actually
- // one
- showStreamNotifications(newStreams, data.serviceId, avatarIcon)
- // Show summary notification
- manager.notify(data.pseudoId, summaryBuilder.build())
+ iconLoadingTargets.remove(this) // allow it to be garbage-collected
+ }
+
+ override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) {
+ // Show individual stream notifications
+ showStreamNotifications(newStreams, data.serviceId, null)
+ // Show summary notification
+ manager.notify(data.pseudoId, summaryBuilder.build())
+ iconLoadingTargets.remove(this) // allow it to be garbage-collected
+ }
+
+ override fun onPrepareLoad(placeHolderDrawable: Drawable) {
+ // Nothing to do
+ }
+ }
+
+ // add the target to the list to hold a strong reference and prevent it from being garbage
+ // collected, since Picasso only holds weak references to targets
+ iconLoadingTargets.add(target)
+
+ PicassoHelper.loadNotificationIcon(data.avatarUrl).into(target)
}
private fun showStreamNotifications(
diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java
index a11438374..336f5cfe3 100644
--- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java
@@ -8,8 +8,8 @@ import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry;
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.image.CoilHelper;
import java.time.format.DateTimeFormatter;
@@ -30,16 +30,17 @@ public class LocalPlaylistItemHolder extends PlaylistItemHolder {
public void updateFromItem(final LocalItem localItem,
final HistoryRecordManager historyRecordManager,
final DateTimeFormatter dateTimeFormatter) {
- if (!(localItem instanceof PlaylistMetadataEntry item)) {
+ if (!(localItem instanceof PlaylistMetadataEntry)) {
return;
}
+ final PlaylistMetadataEntry item = (PlaylistMetadataEntry) localItem;
itemTitleView.setText(item.name);
itemStreamCountView.setText(Localization.localizeStreamCountMini(
itemStreamCountView.getContext(), item.streamCount));
itemUploaderView.setVisibility(View.INVISIBLE);
- CoilHelper.INSTANCE.loadPlaylistThumbnail(itemThumbnailView, item.thumbnailUrl);
+ PicassoHelper.loadPlaylistThumbnail(item.thumbnailUrl).into(itemThumbnailView);
if (item instanceof PlaylistDuplicatesEntry
&& ((PlaylistDuplicatesEntry) item).timesStreamIsContained > 0) {
diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java
index 7dc71bfb4..89a714fd7 100644
--- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java
@@ -16,8 +16,8 @@ import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
-import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.views.AnimatedProgressBar;
import java.time.format.DateTimeFormatter;
@@ -83,8 +83,8 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
}
// Default thumbnail is shown on error, while loading and if the url is empty
- CoilHelper.INSTANCE.loadThumbnail(itemThumbnailView,
- item.getStreamEntity().getThumbnailUrl());
+ PicassoHelper.loadThumbnail(item.getStreamEntity().getThumbnailUrl())
+ .into(itemThumbnailView);
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnItemSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java
index f26a76ad9..150a35eb5 100644
--- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java
@@ -16,8 +16,8 @@ import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
-import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.views.AnimatedProgressBar;
import java.time.format.DateTimeFormatter;
@@ -117,8 +117,8 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
}
// Default thumbnail is shown on error, while loading and if the url is empty
- CoilHelper.INSTANCE.loadThumbnail(itemThumbnailView,
- item.getStreamEntity().getThumbnailUrl());
+ PicassoHelper.loadThumbnail(item.getStreamEntity().getThumbnailUrl())
+ .into(itemThumbnailView);
itemView.setOnClickListener(view -> {
if (itemBuilder.getOnItemSelectedListener() != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java
index f79f3c785..765732063 100644
--- a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java
@@ -8,8 +8,8 @@ import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
-import org.schabi.newpipe.util.image.CoilHelper;
import java.time.format.DateTimeFormatter;
@@ -29,9 +29,10 @@ public class RemotePlaylistItemHolder extends PlaylistItemHolder {
public void updateFromItem(final LocalItem localItem,
final HistoryRecordManager historyRecordManager,
final DateTimeFormatter dateTimeFormatter) {
- if (!(localItem instanceof PlaylistRemoteEntity item)) {
+ if (!(localItem instanceof PlaylistRemoteEntity)) {
return;
}
+ final PlaylistRemoteEntity item = (PlaylistRemoteEntity) localItem;
itemTitleView.setText(item.getName());
itemStreamCountView.setText(Localization.localizeStreamCountMini(
@@ -44,7 +45,7 @@ public class RemotePlaylistItemHolder extends PlaylistItemHolder {
itemUploaderView.setText(ServiceHelper.getNameOfServiceById(item.getServiceId()));
}
- CoilHelper.INSTANCE.loadPlaylistThumbnail(itemThumbnailView, item.getThumbnailUrl());
+ PicassoHelper.loadPlaylistThumbnail(item.getThumbnailUrl()).into(itemThumbnailView);
super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter);
}
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt
index ca626e704..bc39dafe6 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt
@@ -9,7 +9,7 @@ import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.channel.ChannelInfoItem
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.OnClickGesture
-import org.schabi.newpipe.util.image.CoilHelper
+import org.schabi.newpipe.util.image.PicassoHelper
class ChannelItem(
private val infoItem: ChannelInfoItem,
@@ -39,7 +39,7 @@ class ChannelItem(
itemChannelDescriptionView.text = infoItem.description
}
- CoilHelper.loadAvatar(itemThumbnailView, infoItem.thumbnails)
+ PicassoHelper.loadAvatar(infoItem.thumbnails).into(itemThumbnailView)
gesturesListener?.run {
viewHolder.root.setOnClickListener { selected(infoItem) }
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt
index da35447e3..3a4c6e41b 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt
@@ -10,7 +10,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
import org.schabi.newpipe.databinding.PickerSubscriptionItemBinding
import org.schabi.newpipe.ktx.AnimationType
import org.schabi.newpipe.ktx.animate
-import org.schabi.newpipe.util.image.CoilHelper
+import org.schabi.newpipe.util.image.PicassoHelper
data class PickerSubscriptionItem(
val subscriptionEntity: SubscriptionEntity,
@@ -21,7 +21,7 @@ data class PickerSubscriptionItem(
override fun getSpanSize(spanCount: Int, position: Int): Int = 1
override fun bind(viewBinding: PickerSubscriptionItemBinding, position: Int) {
- CoilHelper.loadAvatar(viewBinding.thumbnailView, subscriptionEntity.avatarUrl)
+ PicassoHelper.loadAvatar(subscriptionEntity.avatarUrl).into(viewBinding.thumbnailView)
viewBinding.titleView.text = subscriptionEntity.name
viewBinding.selectedHighlight.isVisible = isSelected
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java
index 40da9139d..49e72328e 100644
--- a/app/src/main/java/org/schabi/newpipe/player/Player.java
+++ b/app/src/main/java/org/schabi/newpipe/player/Player.java
@@ -60,7 +60,6 @@ import android.view.LayoutInflater;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.core.graphics.drawable.DrawableKt;
import androidx.core.math.MathUtils;
import androidx.preference.PreferenceManager;
@@ -78,6 +77,8 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.video.VideoSize;
+import com.squareup.picasso.Picasso;
+import com.squareup.picasso.Target;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
@@ -85,8 +86,8 @@ import org.schabi.newpipe.databinding.PlayerBinding;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
-import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.stream.AudioStream;
+import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.stream.VideoStream;
@@ -117,15 +118,14 @@ import org.schabi.newpipe.player.ui.VideoPlayerUi;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.SerializedCache;
import org.schabi.newpipe.util.StreamTypeUtil;
-import org.schabi.newpipe.util.image.CoilHelper;
import java.util.List;
import java.util.Optional;
import java.util.stream.IntStream;
-import coil.target.Target;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
@@ -174,6 +174,7 @@ public final class Player implements PlaybackListener, Listener {
//////////////////////////////////////////////////////////////////////////*/
public static final int RENDERER_UNAVAILABLE = -1;
+ private static final String PICASSO_PLAYER_THUMBNAIL_TAG = "PICASSO_PLAYER_THUMBNAIL_TAG";
/*//////////////////////////////////////////////////////////////////////////
// Playback
@@ -245,6 +246,12 @@ public final class Player implements PlaybackListener, Listener {
@NonNull
private final CompositeDisposable databaseUpdateDisposable = new CompositeDisposable();
+ // This is the only listener we need for thumbnail loading, since there is always at most only
+ // one thumbnail being loaded at a time. This field is also here to maintain a strong reference,
+ // which would otherwise be garbage collected since Picasso holds weak references to targets.
+ @NonNull
+ private final Target currentThumbnailTarget;
+
/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/
@@ -288,6 +295,8 @@ public final class Player implements PlaybackListener, Listener {
videoResolver = new VideoPlaybackResolver(context, dataSource, getQualityResolver());
audioResolver = new AudioPlaybackResolver(context, dataSource);
+ currentThumbnailTarget = getCurrentThumbnailTarget();
+
// The UIs added here should always be present. They will be initialized when the player
// reaches the initialization step. Make sure the media session ui is before the
// notification ui in the UIs list, since the notification depends on the media session in
@@ -593,6 +602,7 @@ public final class Player implements PlaybackListener, Listener {
databaseUpdateDisposable.clear();
progressUpdateDisposable.set(null);
+ cancelLoadingCurrentThumbnail();
UIs.destroyAll(Object.class); // destroy every UI: obviously every UI extends Object
}
@@ -766,52 +776,67 @@ public final class Player implements PlaybackListener, Listener {
//////////////////////////////////////////////////////////////////////////*/
//region Thumbnail loading
+ private Target getCurrentThumbnailTarget() {
+ // a Picasso target is just a listener for thumbnail loading events
+ return new Target() {
+ @Override
+ public void onBitmapLoaded(final Bitmap bitmap, final Picasso.LoadedFrom from) {
+ if (DEBUG) {
+ Log.d(TAG, "Thumbnail - onBitmapLoaded() called with: bitmap = [" + bitmap
+ + " -> " + bitmap.getWidth() + "x" + bitmap.getHeight() + "], from = ["
+ + from + "]");
+ }
+ // there is a new thumbnail, so e.g. the end screen thumbnail needs to change, too.
+ onThumbnailLoaded(bitmap);
+ }
+
+ @Override
+ public void onBitmapFailed(final Exception e, final Drawable errorDrawable) {
+ Log.e(TAG, "Thumbnail - onBitmapFailed() called", e);
+ // there is a new thumbnail, so e.g. the end screen thumbnail needs to change, too.
+ onThumbnailLoaded(null);
+ }
+
+ @Override
+ public void onPrepareLoad(final Drawable placeHolderDrawable) {
+ if (DEBUG) {
+ Log.d(TAG, "Thumbnail - onPrepareLoad() called");
+ }
+ }
+ };
+ }
+
private void loadCurrentThumbnail(final List thumbnails) {
if (DEBUG) {
Log.d(TAG, "Thumbnail - loadCurrentThumbnail() called with thumbnails = ["
+ thumbnails.size() + "]");
}
+ // first cancel any previous loading
+ cancelLoadingCurrentThumbnail();
+
// Unset currentThumbnail, since it is now outdated. This ensures it is not used in media
- // session metadata while the new thumbnail is being loaded by Coil.
+ // session metadata while the new thumbnail is being loaded by Picasso.
onThumbnailLoaded(null);
if (thumbnails.isEmpty()) {
return;
}
// scale down the notification thumbnail for performance
- final var target = new Target() {
- @Override
- public void onError(@Nullable final Drawable error) {
- Log.e(TAG, "Thumbnail - onError() called");
- // there is a new thumbnail, so e.g. the end screen thumbnail needs to change, too.
- onThumbnailLoaded(null);
- }
+ PicassoHelper.loadScaledDownThumbnail(context, thumbnails)
+ .tag(PICASSO_PLAYER_THUMBNAIL_TAG)
+ .into(currentThumbnailTarget);
+ }
- @Override
- public void onStart(@Nullable final Drawable placeholder) {
- if (DEBUG) {
- Log.d(TAG, "Thumbnail - onStart() called");
- }
- }
-
- @Override
- public void onSuccess(@NonNull final Drawable result) {
- if (DEBUG) {
- Log.d(TAG, "Thumbnail - onSuccess() called with: drawable = [" + result + "]");
- }
- // there is a new thumbnail, so e.g. the end screen thumbnail needs to change, too.
- onThumbnailLoaded(DrawableKt.toBitmapOrNull(result, result.getIntrinsicWidth(),
- result.getIntrinsicHeight(), null));
- }
- };
- CoilHelper.INSTANCE.loadScaledDownThumbnail(context, thumbnails, target);
+ private void cancelLoadingCurrentThumbnail() {
+ // cancel the Picasso job associated with the player thumbnail, if any
+ PicassoHelper.cancelTag(PICASSO_PLAYER_THUMBNAIL_TAG);
}
private void onThumbnailLoaded(@Nullable final Bitmap bitmap) {
// Avoid useless thumbnail updates, if the thumbnail has not actually changed. Based on the
// thumbnail loading code, this if would be skipped only when both bitmaps are `null`, since
- // onThumbnailLoaded won't be called twice with the same nonnull bitmap by Coil's target.
+ // onThumbnailLoaded won't be called twice with the same nonnull bitmap by Picasso's target.
if (currentThumbnail != bitmap) {
currentThumbnail = bitmap;
UIs.call(playerUi -> playerUi.onThumbnailLoaded(bitmap));
diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java
index 8994aef79..066f92c26 100644
--- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java
@@ -6,8 +6,8 @@ import android.view.MotionEvent;
import android.view.View;
import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
-import org.schabi.newpipe.util.image.CoilHelper;
public class PlayQueueItemBuilder {
private static final String TAG = PlayQueueItemBuilder.class.toString();
@@ -33,7 +33,7 @@ public class PlayQueueItemBuilder {
holder.itemDurationView.setVisibility(View.GONE);
}
- CoilHelper.INSTANCE.loadThumbnail(holder.itemThumbnailView, item.getThumbnails());
+ PicassoHelper.loadThumbnail(item.getThumbnails()).into(holder.itemThumbnailView);
holder.itemRoot.setOnClickListener(view -> {
if (onItemClickListener != null) {
diff --git a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java
index d09664aeb..26065de15 100644
--- a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java
@@ -13,9 +13,8 @@ import androidx.collection.SparseArrayCompat;
import com.google.common.base.Stopwatch;
-import org.schabi.newpipe.App;
import org.schabi.newpipe.extractor.stream.Frameset;
-import org.schabi.newpipe.util.image.CoilHelper;
+import org.schabi.newpipe.util.image.PicassoHelper;
import java.util.Comparator;
import java.util.List;
@@ -178,8 +177,8 @@ public class SeekbarPreviewThumbnailHolder {
Log.d(TAG, "Downloading bitmap for seekbarPreview from '" + url + "'");
// Gets the bitmap within the timeout of 15 seconds imposed by default by OkHttpClient
- // Ensure that you are not running on the main thread, otherwise this will hang
- final var bitmap = CoilHelper.INSTANCE.loadBitmapBlocking(App.getApp(), url);
+ // Ensure that your are not running on the main-Thread this will otherwise hang
+ final Bitmap bitmap = PicassoHelper.loadSeekbarThumbnailPreview(url).get();
if (sw != null) {
Log.d(TAG, "Download of bitmap for seekbarPreview from '" + url + "' took "
diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
index 2cda1b4ea..ec2bed67a 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
@@ -13,9 +13,10 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.extractor.localization.Localization;
import org.schabi.newpipe.util.image.ImageStrategy;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.image.PreferredImageQuality;
-import coil.Coil;
+import java.io.IOException;
public class ContentSettingsFragment extends BasePreferenceFragment {
private String youtubeRestrictedModeEnabledKey;
@@ -41,17 +42,14 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
(preference, newValue) -> {
ImageStrategy.setPreferredImageQuality(PreferredImageQuality
.fromPreferenceKey(requireContext(), (String) newValue));
- final var loader = Coil.imageLoader(preference.getContext());
- if (loader.getMemoryCache() != null) {
- loader.getMemoryCache().clear();
+ 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);
}
- if (loader.getDiskCache() != null) {
- loader.getDiskCache().clear();
- }
- Toast.makeText(preference.getContext(),
- R.string.thumbnail_cache_wipe_complete_notice, Toast.LENGTH_SHORT)
- .show();
-
return true;
});
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java
index c6abb5405..d78ade49d 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java
@@ -10,6 +10,7 @@ import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.local.feed.notifications.NotificationWorker;
+import org.schabi.newpipe.util.image.PicassoHelper;
import java.util.Optional;
@@ -24,6 +25,8 @@ public class DebugSettingsFragment extends BasePreferenceFragment {
findPreference(getString(R.string.allow_heap_dumping_key));
final Preference showMemoryLeaksPreference =
findPreference(getString(R.string.show_memory_leaks_key));
+ final Preference showImageIndicatorsPreference =
+ findPreference(getString(R.string.show_image_indicators_key));
final Preference checkNewStreamsPreference =
findPreference(getString(R.string.check_new_streams_key));
final Preference crashTheAppPreference =
@@ -35,6 +38,7 @@ public class DebugSettingsFragment extends BasePreferenceFragment {
assert allowHeapDumpingPreference != null;
assert showMemoryLeaksPreference != null;
+ assert showImageIndicatorsPreference != null;
assert checkNewStreamsPreference != null;
assert crashTheAppPreference != null;
assert showErrorSnackbarPreference != null;
@@ -57,6 +61,11 @@ public class DebugSettingsFragment extends BasePreferenceFragment {
showMemoryLeaksPreference.setSummary(R.string.leak_canary_not_available);
}
+ showImageIndicatorsPreference.setOnPreferenceChangeListener((preference, newValue) -> {
+ PicassoHelper.setIndicatorsEnabled((Boolean) newValue);
+ return true;
+ });
+
checkNewStreamsPreference.setOnPreferenceClickListener(preference -> {
NotificationWorker.runNow(preference.getContext());
return true;
diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
index c566313e3..37335421d 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
@@ -19,8 +19,8 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.local.subscription.SubscriptionManager;
+import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ThemeHelper;
-import org.schabi.newpipe.util.image.CoilHelper;
import java.util.List;
import java.util.Vector;
@@ -190,7 +190,7 @@ public class SelectChannelFragment extends DialogFragment {
final SubscriptionEntity entry = subscriptions.get(position);
holder.titleView.setText(entry.getName());
holder.view.setOnClickListener(view -> clickedItem(position));
- CoilHelper.INSTANCE.loadAvatar(holder.thumbnailView, entry.getAvatarUrl());
+ PicassoHelper.loadAvatar(entry.getAvatarUrl()).into(holder.thumbnailView);
}
@Override
diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java
index c340dca22..36abef9e5 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java
@@ -27,7 +27,7 @@ import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
-import org.schabi.newpipe.util.image.CoilHelper;
+import org.schabi.newpipe.util.image.PicassoHelper;
import java.util.List;
import java.util.Vector;
@@ -154,15 +154,20 @@ public class SelectPlaylistFragment extends DialogFragment {
final int position) {
final PlaylistLocalItem selectedItem = playlists.get(position);
- if (selectedItem instanceof PlaylistMetadataEntry entry) {
+ if (selectedItem instanceof PlaylistMetadataEntry) {
+ final PlaylistMetadataEntry entry = ((PlaylistMetadataEntry) selectedItem);
+
holder.titleView.setText(entry.name);
holder.view.setOnClickListener(view -> clickedItem(position));
- CoilHelper.INSTANCE.loadPlaylistThumbnail(holder.thumbnailView, entry.thumbnailUrl);
- } else if (selectedItem instanceof PlaylistRemoteEntity entry) {
+ PicassoHelper.loadPlaylistThumbnail(entry.thumbnailUrl).into(holder.thumbnailView);
+
+ } else if (selectedItem instanceof PlaylistRemoteEntity) {
+ final PlaylistRemoteEntity entry = ((PlaylistRemoteEntity) selectedItem);
+
holder.titleView.setText(entry.getName());
holder.view.setOnClickListener(view -> clickedItem(position));
- CoilHelper.INSTANCE.loadPlaylistThumbnail(holder.thumbnailView,
- entry.getThumbnailUrl());
+ PicassoHelper.loadPlaylistThumbnail(entry.getThumbnailUrl())
+ .into(holder.thumbnailView);
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java
index 21a4b1175..7524e5413 100644
--- a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java
+++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java
@@ -24,8 +24,8 @@ import androidx.core.content.FileProvider;
import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.Image;
-import org.schabi.newpipe.util.image.CoilHelper;
import org.schabi.newpipe.util.image.ImageStrategy;
+import org.schabi.newpipe.util.image.PicassoHelper;
import java.io.File;
import java.io.FileOutputStream;
@@ -278,7 +278,7 @@ public final class ShareUtils {
* @param content the content to share
* @param images a set of possible {@link Image}s of the subject, among which to choose with
* {@link ImageStrategy#choosePreferredImage(List)} since that's likely to
- * provide an image that is in Coil's cache
+ * provide an image that is in Picasso's cache
*/
public static void shareText(@NonNull final Context context,
@NonNull final String title,
@@ -335,7 +335,15 @@ public final class ShareUtils {
}
/**
- * Generate a {@link ClipData} with the image of the content shared.
+ * Generate a {@link ClipData} with the image of the content shared, if it's in the app cache.
+ *
+ *
+ * In order not to worry about network issues (timeouts, DNS issues, low connection speed, ...)
+ * when sharing a content, only images in the {@link com.squareup.picasso.LruCache LruCache}
+ * used by the Picasso library inside {@link PicassoHelper} are used as preview images. If the
+ * thumbnail image is not in the cache, no {@link ClipData} will be generated and {@code null}
+ * will be returned.
+ *
*
*
* In order to display the image in the content preview of the Android share sheet, an URI of
@@ -351,8 +359,9 @@ public final class ShareUtils {
*
*
*
- * This method will call {@link CoilHelper#loadBitmapBlocking(Context, String)} to get the
- * thumbnail of the content.
+ * This method will call {@link PicassoHelper#getImageFromCacheIfPresent(String)} to get the
+ * thumbnail of the content in the {@link com.squareup.picasso.LruCache LruCache} used by
+ * the Picasso library inside {@link PicassoHelper}.
*
*
*
@@ -369,7 +378,7 @@ public final class ShareUtils {
@NonNull final Context context,
@NonNull final String thumbnailUrl) {
try {
- final var bitmap = CoilHelper.INSTANCE.loadBitmapBlocking(context, thumbnailUrl);
+ final Bitmap bitmap = PicassoHelper.getImageFromCacheIfPresent(thumbnailUrl);
if (bitmap == null) {
return null;
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/image/CoilHelper.kt b/app/src/main/java/org/schabi/newpipe/util/image/CoilHelper.kt
deleted file mode 100644
index ab7cd79a8..000000000
--- a/app/src/main/java/org/schabi/newpipe/util/image/CoilHelper.kt
+++ /dev/null
@@ -1,142 +0,0 @@
-package org.schabi.newpipe.util.image
-
-import android.content.Context
-import android.graphics.Bitmap
-import android.util.Log
-import android.widget.ImageView
-import androidx.annotation.DrawableRes
-import androidx.core.graphics.drawable.toBitmapOrNull
-import coil.executeBlocking
-import coil.imageLoader
-import coil.request.ImageRequest
-import coil.size.Size
-import coil.target.Target
-import coil.transform.Transformation
-import org.schabi.newpipe.MainActivity
-import org.schabi.newpipe.R
-import org.schabi.newpipe.extractor.Image
-import org.schabi.newpipe.ktx.scale
-import kotlin.math.min
-
-object CoilHelper {
- private val TAG = CoilHelper::class.java.simpleName
-
- @JvmOverloads
- fun loadBitmapBlocking(
- context: Context,
- url: String?,
- @DrawableRes placeholderResId: Int = 0
- ): Bitmap? {
- val request = getImageRequest(context, url, placeholderResId).build()
- return context.imageLoader.executeBlocking(request).drawable?.toBitmapOrNull()
- }
-
- fun loadAvatar(target: ImageView, images: List) {
- loadImageDefault(target, images, R.drawable.placeholder_person)
- }
-
- fun loadAvatar(target: ImageView, url: String?) {
- loadImageDefault(target, url, R.drawable.placeholder_person)
- }
-
- fun loadThumbnail(target: ImageView, images: List) {
- loadImageDefault(target, images, R.drawable.placeholder_thumbnail_video)
- }
-
- fun loadThumbnail(target: ImageView, url: String?) {
- loadImageDefault(target, url, R.drawable.placeholder_thumbnail_video)
- }
-
- fun loadScaledDownThumbnail(context: Context, images: List, target: Target) {
- val url = ImageStrategy.choosePreferredImage(images)
- val request = getImageRequest(context, url, R.drawable.placeholder_thumbnail_video)
- .target(target)
- .transformations(object : Transformation {
- override val cacheKey = "COIL_PLAYER_THUMBNAIL_TRANSFORMATION_KEY"
-
- override suspend fun transform(input: Bitmap, size: Size): Bitmap {
- if (MainActivity.DEBUG) {
- Log.d(TAG, "Thumbnail - transform() called")
- }
-
- val notificationThumbnailWidth = min(
- context.resources.getDimension(R.dimen.player_notification_thumbnail_width),
- input.width.toFloat()
- ).toInt()
-
- var newHeight = input.height / (input.width / notificationThumbnailWidth)
- val result = input.scale(notificationThumbnailWidth, newHeight)
-
- return if (result == input || !result.isMutable) {
- // create a new mutable bitmap to prevent strange crashes on some
- // devices (see #4638)
- newHeight = input.height / (input.width / (notificationThumbnailWidth - 1))
- input.scale(notificationThumbnailWidth, newHeight)
- } else {
- result
- }
- }
- })
- .build()
-
- context.imageLoader.enqueue(request)
- }
-
- fun loadDetailsThumbnail(target: ImageView, images: List) {
- val url = ImageStrategy.choosePreferredImage(images)
- loadImageDefault(target, url, R.drawable.placeholder_thumbnail_video, false)
- }
-
- fun loadBanner(target: ImageView, images: List) {
- loadImageDefault(target, images, R.drawable.placeholder_channel_banner)
- }
-
- fun loadPlaylistThumbnail(target: ImageView, images: List) {
- loadImageDefault(target, images, R.drawable.placeholder_thumbnail_playlist)
- }
-
- fun loadPlaylistThumbnail(target: ImageView, url: String?) {
- loadImageDefault(target, url, R.drawable.placeholder_thumbnail_playlist)
- }
-
- private fun loadImageDefault(
- target: ImageView,
- images: List,
- @DrawableRes placeholderResId: Int
- ) {
- loadImageDefault(target, ImageStrategy.choosePreferredImage(images), placeholderResId)
- }
-
- private fun loadImageDefault(
- target: ImageView,
- url: String?,
- @DrawableRes placeholderResId: Int,
- showPlaceholder: Boolean = true
- ) {
- val request = getImageRequest(target.context, url, placeholderResId, showPlaceholder)
- .target(target)
- .build()
- target.context.imageLoader.enqueue(request)
- }
-
- private fun getImageRequest(
- context: Context,
- url: String?,
- @DrawableRes placeholderResId: Int,
- showPlaceholderWhileLoading: Boolean = true
- ): ImageRequest.Builder {
- // if the URL was chosen with `choosePreferredImage` it will be null, but check again
- // `shouldLoadImages` in case the URL was chosen with `imageListToDbUrl` (which is the case
- // for URLs stored in the database)
- val takenUrl = url?.takeIf { it.isNotEmpty() && ImageStrategy.shouldLoadImages() }
-
- return ImageRequest.Builder(context)
- .data(takenUrl)
- .error(placeholderResId)
- .apply {
- if (takenUrl != null || showPlaceholderWhileLoading) {
- placeholder(placeholderResId)
- }
- }
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java
new file mode 100644
index 000000000..4b116bdf9
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java
@@ -0,0 +1,224 @@
+package org.schabi.newpipe.util.image;
+
+import static org.schabi.newpipe.MainActivity.DEBUG;
+import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
+import static org.schabi.newpipe.util.image.ImageStrategy.choosePreferredImage;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.util.Log;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.graphics.BitmapCompat;
+
+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 com.squareup.picasso.Transformation;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.extractor.Image;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.OkHttpClient;
+
+public final class PicassoHelper {
+ private static final String TAG = PicassoHelper.class.getSimpleName();
+ private static final String PLAYER_THUMBNAIL_TRANSFORMATION_KEY =
+ "PICASSO_PLAYER_THUMBNAIL_TRANSFORMATION_KEY";
+
+ 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;
+
+
+ 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"),
+ 50L * 1024L * 1024L))
+ // 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
+ final okhttp3.Cache diskCache = picassoDownloaderClient.cache();
+ if (diskCache != null) {
+ diskCache.delete(); // clear disk cache
+ }
+ init(context);
+ }
+
+ public static void cancelTag(final Object tag) {
+ picassoInstance.cancelTag(tag);
+ }
+
+ public static void setIndicatorsEnabled(final boolean enabled) {
+ picassoInstance.setIndicatorsEnabled(enabled); // useful for debugging
+ }
+
+
+ public static RequestCreator loadAvatar(@NonNull final List images) {
+ return loadImageDefault(images, R.drawable.placeholder_person);
+ }
+
+ public static RequestCreator loadAvatar(@Nullable final String url) {
+ return loadImageDefault(url, R.drawable.placeholder_person);
+ }
+
+ public static RequestCreator loadThumbnail(@NonNull final List images) {
+ return loadImageDefault(images, R.drawable.placeholder_thumbnail_video);
+ }
+
+ public static RequestCreator loadThumbnail(@Nullable final String url) {
+ return loadImageDefault(url, R.drawable.placeholder_thumbnail_video);
+ }
+
+ public static RequestCreator loadDetailsThumbnail(@NonNull final List images) {
+ return loadImageDefault(choosePreferredImage(images),
+ R.drawable.placeholder_thumbnail_video, false);
+ }
+
+ public static RequestCreator loadBanner(@NonNull final List images) {
+ return loadImageDefault(images, R.drawable.placeholder_channel_banner);
+ }
+
+ public static RequestCreator loadPlaylistThumbnail(@NonNull final List images) {
+ return loadImageDefault(images, R.drawable.placeholder_thumbnail_playlist);
+ }
+
+ public static RequestCreator loadPlaylistThumbnail(@Nullable final String url) {
+ return loadImageDefault(url, R.drawable.placeholder_thumbnail_playlist);
+ }
+
+ public static RequestCreator loadSeekbarThumbnailPreview(@Nullable final String url) {
+ return picassoInstance.load(url);
+ }
+
+ public static RequestCreator loadNotificationIcon(@Nullable final String url) {
+ return loadImageDefault(url, R.drawable.ic_newpipe_triangle_white);
+ }
+
+
+ public static RequestCreator loadScaledDownThumbnail(final Context context,
+ @NonNull final List images) {
+ // scale down the notification thumbnail for performance
+ return PicassoHelper.loadThumbnail(images)
+ .transform(new Transformation() {
+ @Override
+ public Bitmap transform(final Bitmap source) {
+ if (DEBUG) {
+ Log.d(TAG, "Thumbnail - transform() called");
+ }
+
+ final float notificationThumbnailWidth = Math.min(
+ context.getResources()
+ .getDimension(R.dimen.player_notification_thumbnail_width),
+ source.getWidth());
+
+ final Bitmap result = BitmapCompat.createScaledBitmap(
+ source,
+ (int) notificationThumbnailWidth,
+ (int) (source.getHeight()
+ / (source.getWidth() / notificationThumbnailWidth)),
+ null,
+ true);
+
+ if (result == source || !result.isMutable()) {
+ // create a new mutable bitmap to prevent strange crashes on some
+ // devices (see #4638)
+ final Bitmap copied = BitmapCompat.createScaledBitmap(
+ source,
+ (int) notificationThumbnailWidth - 1,
+ (int) (source.getHeight() / (source.getWidth()
+ / (notificationThumbnailWidth - 1))),
+ null,
+ true);
+ source.recycle();
+ return copied;
+ } else {
+ source.recycle();
+ return result;
+ }
+ }
+
+ @Override
+ public String key() {
+ return PLAYER_THUMBNAIL_TRANSFORMATION_KEY;
+ }
+ });
+ }
+
+ @Nullable
+ public static Bitmap getImageFromCacheIfPresent(@NonNull final String imageUrl) {
+ // URLs in the internal cache finish with \n so we need to add \n to image URLs
+ return picassoCache.get(imageUrl + "\n");
+ }
+
+
+ private static RequestCreator loadImageDefault(@NonNull final List images,
+ @DrawableRes final int placeholderResId) {
+ return loadImageDefault(choosePreferredImage(images), placeholderResId);
+ }
+
+ private static RequestCreator loadImageDefault(@Nullable final String url,
+ @DrawableRes final int placeholderResId) {
+ return loadImageDefault(url, placeholderResId, true);
+ }
+
+ private static RequestCreator loadImageDefault(@Nullable final String url,
+ @DrawableRes final int placeholderResId,
+ final boolean showPlaceholderWhileLoading) {
+ // if the URL was chosen with `choosePreferredImage` it will be null, but check again
+ // `shouldLoadImages` in case the URL was chosen with `imageListToDbUrl` (which is the case
+ // for URLs stored in the database)
+ if (isNullOrEmpty(url) || !ImageStrategy.shouldLoadImages()) {
+ return picassoInstance
+ .load((String) null)
+ .placeholder(placeholderResId) // show placeholder when no image should load
+ .error(placeholderResId);
+ } else {
+ final RequestCreator requestCreator = picassoInstance
+ .load(url)
+ .error(placeholderResId);
+ if (showPlaceholderWhileLoading) {
+ requestCreator.placeholder(placeholderResId);
+ }
+ return requestCreator;
+ }
+ }
+}
diff --git a/app/src/main/res/values-ar-rLY/strings.xml b/app/src/main/res/values-ar-rLY/strings.xml
index 290d9f6ab..077cf1106 100644
--- a/app/src/main/res/values-ar-rLY/strings.xml
+++ b/app/src/main/res/values-ar-rLY/strings.xml
@@ -302,6 +302,7 @@
%s مشارك
جلب البيانات الوصفية…
+ إظهار مؤشرات الصورانقر للتنزيل %sتعطيل الوضع السريع,
@@ -829,6 +830,7 @@
لقد اشتركت الآن في هذه القناةبدءًا من Android 10، يتم دعم \"Storage Access Framework\" فقطإنشاء اسم فريد
+ أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرةفشل الاتصال الآمنيتوفر هذا الفيديو فقط لأعضاء YouTube Music Premium، لذلك لا يمكن بثه أو تنزيله من قبل NewPipe.البث السابق
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 902fe8c3a..82173d758 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -674,6 +674,8 @@
معاينة مصغرة على شريط التمريروضع علامة على تمت مشاهدتهأُعجب بها منشئ المحتوى
+ أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرة
+ إظهار مؤشرات الصوراقتراحات البحث عن بعداقتراحات البحث المحليةاسحب العناصر لإزالتها
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index 9c9c15c96..66bfe75de 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -505,6 +505,8 @@
Məlumat əldə edilir…Elementlərdə orijinal əvvəlki vaxtı göstərYaşam dövrəsi xaricindəki xətaları bildir
+ Şəkil göstəricilərini göstər
+ Şəkillərin üzərində mənbəsini göstərən Picasso rəngli lentləri göstər: şəbəkə üçün qırmızı, disk üçün mavi və yaddaş üçün yaşılBəzi endirmələri dayandırmaq mümkün olmasa da, mobil dataya keçərkən faydalıdırBağlaFayl silindiyi üçün irəliləyiş itirildi
diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml
index 5ddf30c2a..dceaaf6c5 100644
--- a/app/src/main/res/values-be/strings.xml
+++ b/app/src/main/res/values-be/strings.xml
@@ -630,6 +630,8 @@
Перайсці на вэбсайтПравядзіце пальцам па элементах, каб выдаліць іхАдмяніць пастаянную мініяцюру
+ Паказаць індыкатары выявы
+ Паказваць каляровыя стужкі Пікаса на выявах, якія пазначаюць іх крыніцу: чырвоная для сеткі, сіняя для дыска і зялёная для памяціАпрацоўка стужкі…Вам будзе прапанавана, дзе захоўваць кожную спампоўкуЗагрузка стужкі…
diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml
index 9b8c06bc5..bc235446c 100644
--- a/app/src/main/res/values-bg/strings.xml
+++ b/app/src/main/res/values-bg/strings.xml
@@ -539,6 +539,7 @@
Това видео е с възрастова граница.
\n
\nВключете „%1$s“ в настройките ако искате да го пуснете.
+ Показвай цветни Picasso-панделки в горната част на изображенията като индикатор за техния произход (червен – от мрежата, син – от диска и червен – от паметта)Автоматична (тази на устройството)Мащабиране на миниатюрата в известието от 16:9 към 1:1 формат (възможни са изкривявания)Избете плейлист
diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml
index 8fe38988a..853b04b64 100644
--- a/app/src/main/res/values-bn/strings.xml
+++ b/app/src/main/res/values-bn/strings.xml
@@ -589,6 +589,7 @@
নতুন ধারাকম্পাঙ্ক দেখোপূর্বদর্শন রেখার মাধ্যমে প্রাকদর্শন
+ ছবিরূপ সূচক দেখাওদেখিও নাযেকোনো নেটওয়ার্কপরেরটা ক্রমে রাখা হয়েছে
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index dd08e3526..871af187b 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -625,6 +625,7 @@
No mostrisBaixa qualitat (més petit)Alta qualitat (més gran)
+ Mostra indicadors de la imatgeDesactiva l\'entunelament del contingut si en els videos hi ha una pantalla negre o tartamudegenMostra detalls del canalNo s\'ha establert una carpeta de descàrregues, selecciona la carpeta per defecte ara
@@ -668,6 +669,7 @@
Comentari fixatMostra \"Força el tancament del reproductor\"Mostra una opció de fallada quan s\'utilitza el reproductor
+ Mostra les cintes de color Picasso a la part superior de les imatges que indiquen la seva font: vermell per a la xarxa, blau per al disc i verd per a la memòriaEl LeakCanary no està disponibleComprovant freqüènciaEs necesita una conexió a Internet
diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml
index d14449cf1..e6e375a4c 100644
--- a/app/src/main/res/values-ckb/strings.xml
+++ b/app/src/main/res/values-ckb/strings.xml
@@ -631,6 +631,8 @@
پیشان نەدرێتکواڵێتی نزم (بچووکتر)کواڵێتی بەرز (گەورەتر)
+ پیشاندانی شریتە ڕەنگکراوەکانی پیکاسۆ لەسەرووی وێنەکانەوە بۆ بەدیار خستنی سەرچاوەکانیان : سوور بۆ تۆڕ ، شین بۆ دیسک و سەوز بۆ بیرگە
+ پیشاندانی دیارخەرەکانی وێنەپێشنیازکراوەکانی گەڕانی ڕیمۆتپێشنیازکراوەکانی گەڕانی نێوخۆییدیارکردن وەک بینراو
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index e6263f6e0..34537446c 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -654,6 +654,8 @@
%s stahování dokončena%s stahováních dokončeno
+ Zobrazit barevné pásky Picasso na obrázcích označujících jejich zdroj: červená pro síť, modrá pro disk a zelená pro paměť
+ Zobrazit indikátory obrázkůVzdálené návrhy vyhledáváníLokální návrhy vyhledáváníPokud je vypnuté automatické otáčení, nespouštět video v mini přehrávači, ale přepnout se přímo do režimu celé obrazovky. Do mini přehrávače se lze i nadále dostat ukončením režimu celé obrazovky
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index cbb59d591..601bc3752 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -516,6 +516,7 @@
Behandler… Det kan tage et øjeblikVis hukommelseslækagerDeaktivér medietunneling
+ Vis billedindikatorerNetværkskravAlle netværkKontrolfrekvens
@@ -694,6 +695,7 @@
Ofte stillede spørgsmålHvis du har problemer med at bruge appen, bør du tjekke disse svar på almindelige spørgsmål!Se på webside
+ Vis Picasso-farvede bånd oven på billeder, der angiver deres kilde: rød for netværk, blå for disk og grøn for hukommelseDu kører den nyeste version af NewPipePga. ExoPlayer-begrænsninger blev søgevarigheden sat til %d sekunderVis kun ikke-grupperede abonnementer
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 028ff86ca..fcc38bf0b 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -637,6 +637,8 @@
AusAls gesehen markierenVom Ersteller mit Herz versehen
+ Farbige Picasso-Bänder über den Bildern anzeigen, die deren Quelle angeben: rot für Netzwerk, blau für Festplatte und grün für Speicher
+ Bildindikatoren anzeigenEntfernte SuchvorschlägeLokale Suchvorschläge
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 58a70c270..6e9525459 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -634,6 +634,8 @@
Προεπισκόπηση στην μπάρα αναζήτησηςΣήμανση ως αναπαραχθένΕπισημάνθηκε από τον δημιουργό
+ Εμφάνιση χρωματιστής κορδέλας πάνω στις εικόνες, που δείχνει την πηγή τους: κόκκινη για δίκτυο, μπλε για δίσκο και πράσινο για μνήμη
+ Εμφάνιση δεικτών εικόνωνΠροτάσεις απομακρυσμένης αναζήτησηςΠροτάσεις τοπικής αναζήτησης
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index a44c72937..c7b780a1f 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -647,6 +647,8 @@
Los comentarios están deshabilitadosDe corazón por el creadorMarcar como visto
+ Mostrar cintas de colores Picasso encima de las imágenes indicando su origen: rojo para la red, azul para el disco y verde para la memoria
+ Mostrar indicadores de imagenSugerencias de búsqueda remotaSugerencias de búsqueda local
diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml
index 0e6e082c9..1d3fcdcb8 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -634,6 +634,8 @@
\n
\nNii et valik taandub sellele, mida eelistad: kiirus või täpne teave.
Märgi vaadatuks
+ Näita piltide kohal Picasso värvides riba, mis märgib pildi allikat: punane tähistab võrku, sinine kohalikku andmekandjat ja roheline kohalikku mälu
+ Näita piltide allikatKaugotsingu soovitusedKohaliku otsingu soovitusedÜksuse eemaldamiseks viipa
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 076b50d10..6f94a8f62 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -641,6 +641,8 @@
Deskarga amaituta%s Deskarga amaituta
+ Irudien gainean Picasso koloretako zintak erakutsi, jatorria adieraziz: gorria sarerako, urdina diskorako eta berdea memoriarako
+ Erakutsi irudi-adierazleakUrruneko bilaketaren iradokizunakTokiko bilaketa-iradokizunakIkusi gisa markatu
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index 02ac369d7..2afeaf286 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -597,6 +597,7 @@
رنگی کردن آگاهیگشودن بانشانه به عنوان دیده شده
+ نمایش روبانهای رنگی پیکاسو در بالای تصویرها کهنشانگر منبعشان است: قرمز برای شبکه ، آبی برای دیسک و سبز برای حافظهدرخواست از اندروید برای سفارشیسازی رنگ آگاهی براساس رنگ اصلی در بندانگشتی (توجّه داشته باشید که روی همهٔ افزارهها در دسترس نیست)این ویدیو محدود به سن است.
\n
@@ -634,6 +635,7 @@
قلبشده به دست ایجادگرپیشنهادهای جستوجوی محلّیپیشنهادهای جستوجوی دوردست
+ نمایش نشانگرهای تصویربارگیری پایان یافت%s بارگیری پایان یافتند
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index d72402e77..67350d7ba 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -634,6 +634,8 @@
Latauskansiota ei vielä asetettu, valitse ensin oletuslatauskansioKommentit poistettu käytöstäMerkitse katsotuksi
+ Näytä Picasso-värjätyt nauhat kuvien päällä osoittaakseen lähteen: punainen tarkoittaa verkkoa, sininen tarkoittaa levytilaa ja vihreä tarkoittaa muistia
+ Näytä kuvailmaisimetEtähakuehdotuksetPaikalliset hakuehdotuksetLisää seuraavaksi
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index f6a3d6285..66418e7cf 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -646,8 +646,10 @@
Prévisualisation de la barre de progression sur la miniatureMarquer comme visionnéApprécié par le créateur
+ Afficher les indicateurs d’imageSuggestions de recherche distanteSuggestions de recherche locale
+ Affiche les rubans colorés de Picasso au-dessus des images indiquant leur source : rouge pour le réseau, bleu pour le disque et vert pour la mémoire%1$s téléchargement supprimé%1$s téléchargements supprimés
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index 4b087a882..efe1b7f5e 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -627,6 +627,7 @@
%s descargas finalizadasMiniatura na barra de busca
+ Mostrar indicadores de imaxeDesactive o túnel multimedia se experimentar unha pantalla en negro ou interrupcións na reprodución.Desactivar túnel multimediaEngadido á cola
@@ -663,6 +664,7 @@
A partir do Android 10, só o \'Sistema de Acceso ao Almacenamento\' está soportadoProcesando... Pode devagar un momentoCrear unha notificación de erro
+ Amosar fitas coloridas de Picasso na cima das imaxes que indican a súa fonte: vermello para a rede, azul para o disco e verde para a memoriaNovos elementosPredefinido do ExoPlayerAmosar \"Travar o reprodutor\"
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index 1da62fc75..befde2d53 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -654,6 +654,8 @@
תמונה מוקטנת בסרגל הנגינהסומן בלב על ידי היוצרסימון כנצפה
+ הצגת סרטים בסגנון פיקאסו בראש התמונות לציון המקור שלהם: אדום זה מהרשת, כחול מהכונן וירוק מהזיכרון
+ הצגת מחווני תמונותהצעות חיפוש מרוחקותהצעות חיפוש מקומיות
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index 6e185156d..51455fafb 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -570,6 +570,7 @@
कतारबद्ध हुआस्ट्रीम विवरण लोड हो रहे हैं…प्रोसेस हो रहा है… कुछ समय लग सकता है
+ छवि संकेतक दिखाएंप्लेयर का उपयोग करते समय क्रैश विकल्प दिखाता हैनई स्ट्रीमों के लिए जांच चलाएंएक त्रुटि स्नैकबार दिखाएं
@@ -667,6 +668,7 @@
लीक-कैनरी उपलब्ध नहीं हैएक त्रुटी हुई है, नोटीफिकेशन देखेंयदि वीडियो प्लेबैक पर आप काली स्क्रीन या रुक-रुक कर वीडियो चलने का अनुभव करते हैं तो मीडिया टनलिंग को अक्षम करें।
+ छवियों के शीर्ष पर पिकासो रंगीन रिबन दिखाएँ जो उनके स्रोत को दर्शाता है: नेटवर्क के लिए लाल, डिस्क के लिए नीला और मेमोरी के लिए हरात्रुटी की नोटीफिकेशन बनाएंइस डाउनलोड को पुनर्प्राप्त नहीं किया जा सकताअभी तक कोई डाउनलोड फ़ोल्डर सेट नहीं किया गया है, अब डिफ़ॉल्ट डाउनलोड फ़ोल्डर चुनें
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 3a945bba0..419f4619e 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -646,6 +646,7 @@
%s pruža ovaj razlog:Obrada u tijeku … Može malo potrajatiZa ukljanjanje stavki povuci ih
+ Prikaži indikatore slikePreuzimanje je gotovo%s preuzimanja su gotova
@@ -654,6 +655,7 @@
Pokreni glavni player u cjeloekranskom prikazuDodaj u popis kao sljedećiDodano u popis kao sljedeći
+ Prikaži Picassove vrpce u boji na slikama koje označavaju njihov izvor: crvena za mrežu, plava za disk i zelena za memorijuIzbrisano %1$s preuzimanjeIzbrisana %1$s preuzimanja
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index f86704148..5a402c94c 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -570,6 +570,7 @@
Az eltávolítás utáni, fragment vagy activity életcikluson kívüli, nem kézbesíthető Rx kivételek jelentésének kényszerítéseEredeti „ennyi ideje” megjelenítése az elemekenTiltsa le a médiacsatornázást, ha fekete képernyőt vagy akadozást tapasztal videólejátszáskor.
+ Picasso színes szalagok megjelenítése a képek fölött, megjelölve a forrásukat: piros a hálózathoz, kék a lemezhez, zöld a memóriáhozMinden letöltésnél meg fogja kérdezni, hogy hova mentse elVálasszon egy példánytLista legutóbbi frissítése: %s
@@ -656,6 +657,7 @@
\nBiztos benne\? Ez nem vonható vissza!A szolgáltatásokból származó eredeti szövegek láthatók lesznek a közvetítési elemekenLejátszó összeomlasztása
+ Képjelölők megjelenítéseA „lejátszó összeomlasztása” lehetőség megjelenítéseMegjeleníti az összeomlasztási lehetőséget a lejátszó használatakorHangmagasság megtartása (torzítást okozhat)
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index 9a6472692..71900400e 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -631,11 +631,13 @@
Disukai oleh kreatorSaran pencarian lokalSaran pencarian remote
+ Tampilkan indikator gambarMenghapus %1$s unduhantambahkan ke selanjutnyatelah ditambahkan ke selanjutnya
+ Tampilkan Ribon bewarna Picasso di atas gambar yang mengindikasikan asalnya: merah untuk jaringan, biru untuk disk dan hijau untuk memoriJangan memulai memutar video di mini player, tapi nyalakan langsung di mode layar penuh, jika rotasi otomatis terkunci. Anda tetap dapat mengakses mini player dengan keluar dari layar penuhMemproses… Mungkin butuh waktu sebentarPeriksa Pembaruan
diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml
index d921cfac0..ed5ebe99b 100644
--- a/app/src/main/res/values-is/strings.xml
+++ b/app/src/main/res/values-is/strings.xml
@@ -657,6 +657,8 @@
Upprunalegir textar frá þjónustu verða sýnilegir í atriðumSlökkva á fjölmiðlagöngumSlökktu á fjölmiðlagöngum ef þú finnur fyrir svörtum skjá eða stami við spilun myndbandar
+ Sýna myndvísa
+ Sýna Picasso litaða borða ofan á myndum sem gefa til kynna uppruna þeirra: rauðan fyrir netið, bláan fyrir disk og grænan fyrir minniSýna „Hrynja spilara“Sýna valkost til að hrynja spilaraHrynja forrit
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 9d1c4bc0b..2a5ac16d3 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -644,6 +644,8 @@
Commenti disattivatiApprezzato dall\'autoreSegna come visto
+ Mostra gli indicatori colorati Picasso sopra le immagini, per indicare la loro fonte: rosso per la rete, blu per il disco e verde per la memoria
+ Mostra indicatori immagineSuggerimenti di ricerca remotiSuggerimenti di ricerca locali
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 7e7cf83a2..74924125a 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -634,6 +634,8 @@
%s つのダウンロードが完了しました
+ ピカソは、画像の上に、画像の出所を識別する色彩記章を表示します: 赤はネットワーク、青はディスク、緑はメモリ
+ 画像に標識を表示処理中… 少し時間がかかるかもしれません新しいバージョンを手動で確認しますアップデートを確認中…
diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml
index 4344c245d..ecb2a8495 100644
--- a/app/src/main/res/values-ka/strings.xml
+++ b/app/src/main/res/values-ka/strings.xml
@@ -384,6 +384,7 @@
ორიგინალური ტექსტები სერვისებიდან ხილული იქნება ნაკადის ერთეულებშიმედია გვირაბის გათიშვაგამორთეთ მედია გვირაბი, თუ ვიდეოს დაკვრისას შავი ეკრანი ან ჭუჭყი გაქვთ
+ გამოსახულების ინდიკატორების ჩვენებააჩვენე \"დამკვრელის დამსხვრევა\"აჩვენებს ავარიის ვარიანტს დამკვრელის გამოყენებისასგაუშვით შემოწმება ახალი ნაკადებისთვის
@@ -682,6 +683,7 @@
გამოწერების იმპორტი ვერ მოხერხდაშეატყობინეთ სასიცოცხლო ციკლის შეცდომებსიძულებითი მოხსენება შეუსაბამო Rx გამონაკლისების შესახებ ფრაგმენტის ან აქტივობის სასიცოცხლო ციკლის გარეთ განკარგვის შემდეგ
+ აჩვენეთ პიკასოს ფერადი ლენტები სურათების თავზე, სადაც მითითებულია მათი წყარო: წითელი ქსელისთვის, ლურჯი დისკისთვის და მწვანე მეხსიერებისთვისსწრაფი კვების რეჟიმი ამაზე მეტ ინფორმაციას არ იძლევა.„%s“-ის არხის ჩატვირთვა ვერ მოხერხდა.ხელმისაწვდომია ზოგიერთ სერვისში, როგორც წესი, ბევრად უფრო სწრაფია, მაგრამ შეიძლება დააბრუნოს შეზღუდული რაოდენობის ელემენტი და ხშირად არასრული ინფორმაცია (მაგ. ხანგრძლივობის გარეშე, ელემენტის ტიპი, არ არის ლაივის სტატუსი)
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 5d5dfa023..939d97441 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -545,6 +545,8 @@
미디어 터널링 비활성화서비스의 원본 텍스트가 스트림 항목에 표시됩니다동영상 재생 시 검은 화면이 나타나거나 끊김 현상이 발생하면 미디어 터널링을 비활성화하세요.
+ 이미지 표시기 표시
+ 원본을 나타내는 이미지 위에 피카소 컬러 리본 표시: 네트워크는 빨간색, 디스크는 파란색, 메모리는 녹색\"플레이어 충돌\" 표시플레이어를 사용할 때 충돌 옵션을 표시합니다새로운 스트림 확인 실행
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index 2294a357d..c68e49bdd 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -644,6 +644,8 @@
NerodytiŠirdelė nuo kurėjoPažymėti kaip peržiūrėtą
+ Rodyti „Picasso“ spalvotas juosteles ant vaizdų, nurodančių jų šaltinį: raudona tinklui, mėlyna diskui ir žalia atmintis
+ Rodyti vaizdo indikatoriusNuotolinės paieškos pasiūlymaiVietinės paieškos pasiūlymai
diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml
index a28d3e607..58b9a9d76 100644
--- a/app/src/main/res/values-lv/strings.xml
+++ b/app/src/main/res/values-lv/strings.xml
@@ -625,10 +625,12 @@
Nesākt video atskaņošanu samazinātā režīmā, bet pilnekrāna režīmā, ja automātiskā rotācija ir izslēgtaIzslēgt multivides tuneļošanuIzslēdziet multivides tuneļošanu, ja jums video atskaņošanas laikā parādās melns ekrāns vai aizķeršanās
+ Rādīt krāsainas lentes virs attēliem, norādot to avotu: sarkana - tīkls, zila - disks, zaļa - atmiņaIeslēgt teksta atlasīšanu video aprakstāLejupielādes mape vēl nav iestatīta, izvēlieties noklusējuma lejupielādes mapiPārvelciet objektus, lai tos noņemtuLokālie meklēšanas ieteikumi
+ Rādīt attēlu indikatorusAugstas kvalitātes (lielāks)Pārbaudīt atjauninājumusManuāli pārbaudīt, vai ir atjauninājumi
diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml
index ee4b88a41..c439593f7 100644
--- a/app/src/main/res/values-ml/strings.xml
+++ b/app/src/main/res/values-ml/strings.xml
@@ -595,6 +595,7 @@
രണ്ടാം പ്രവർത്തന ബട്ടൺആദ്യ പ്രവർത്തന ബട്ടൺവീഡിയോ കാണുമ്പോൾ കറുത്ത സ്ക്രീൻ, അവ്യക്തത അനുഭവിക്കുന്നു എങ്കിൽ മീഡിയ ട്യൂൺലിങ് പ്രവർത്തനരഹിതമാക്കുക
+ ഉറവിടം തിരിച്ചറിയാൻ പിക്കാസോ കളർഡ് റിബൺ ചിത്രങ്ങളുടെ മുകളിൽ കാണിക്കുക: നെറ്റ്വർക്കിന് ചുവപ്പ്, ഡിസ്കിനു നീല, മെമ്മറിയിക്ക് പച്ചസീക്ബാർ ചെറുചിത്രം പ്രദർശനംസ്നേഹത്തോടെ സൃഷ്ടാവ്ഡിസ്ക്രിപ്ഷനിലെ ടെക്സ്റ്റ് സെലക്ട് ചെയ്യുവാൻ അനുവദിക്കാതെ ഇരിക്കുക
@@ -629,6 +630,7 @@
കാണിക്കരുത്കുറഞ്ഞ നിലവാരം (ചെറുത് )ഉയർന്ന നിലവാരം (വലിയത് )
+ ഇമേജ് ഇൻഡിക്കേറ്ററുകൾ കാണിക്കുകമീഡിയ ട്യൂൺലിങ് പ്രവർത്തനരഹിതമാക്കുകഡൌൺലോഡ് ഫോൾഡർ ഇത് വരെയും സെറ്റ് ചെയ്തിട്ടില്ല, സ്ഥിര ഡൌൺലോഡ് ഫോൾഡർ ഇപ്പോൾ തിരഞ്ഞെക്കുകഅഭിപ്രായങ്ങൾ പ്രവർത്തനരഹിതമായിരിക്കുന്നു
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index 7acf7f4cd..416ebfd02 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -644,7 +644,9 @@
Lokale søkeforslagMarker som settIkke start videoer i minispilleren, men bytt til fullskjermsmodus direkte dersom auto-rotering er låst. Du har fremdeles tilgang til minispilleren ved å avslutte fullskjermsvisningen
+ Vis Picasso-fargede bånd på toppen av bilder for å indikere kilde: Rød for nettverk, blå for disk, og grønn for minneHjertemerket av skaperen
+ Vis bildeindikatorerDra elementer for å fjerne demStart hovedspiller i fullskjermStill i kø neste
diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml
index c744de62c..637eb1751 100644
--- a/app/src/main/res/values-nl-rBE/strings.xml
+++ b/app/src/main/res/values-nl-rBE/strings.xml
@@ -611,6 +611,7 @@
Geen download map ingesteld, kies nu de standaard download mapNiet tonenReacties zijn uitgeschakeld
+ Toon afbeeldingsindicatorenSpeler meldingConfigureer actieve stream meldingMeldingen
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 26e328ed4..b4629a03f 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -632,6 +632,8 @@
Lage kwaliteit (kleiner)Hoge kwaliteit (groter)Zoekbalk miniatuurafbeelding voorbeeld
+ Toon Picasso-gekleurde linten bovenop afbeeldingen die hun bron aangeven: rood voor netwerk, blauw voor schijf en groen voor geheugen
+ Afbeeldingsindicatoren tonenReacties zijn uitgeschakeldZoeksuggesties op afstandLokale zoeksuggesties
diff --git a/app/src/main/res/values-nqo/strings.xml b/app/src/main/res/values-nqo/strings.xml
index f1960b980..94e7ae2f4 100644
--- a/app/src/main/res/values-nqo/strings.xml
+++ b/app/src/main/res/values-nqo/strings.xml
@@ -440,6 +440,8 @@
ߗߋߢߊߟߌ ߟߎ߬ ߞߟߏߜߍ߫ ߓߐߛߎ߲ߡߊ ߟߎ߬ ߦߌ߬ߘߊ߬ߕߐ߫ ߟߋ߬ ߟߊ߬ߖߍ߲߬ߛߍ߲߬ߠߌ߲ ߘߐ߫ߞߋߟߋߞߋߟߋ ߟߊ߫ ߝߊߟߊ߲ߓߍߦߊ ߟߊߛߊ߬ߞߋߟߋߞߋߟߋ ߟߊ߫ ߝߊߟߊ߲ߓߍߦߊ ߟߊߛߊ߬ ߣߴߌ ߞߊ߬ ߥߊ߲߬ߊߥߊ߲߬ ߝߌ߲ ߦߋ߫ ߥߟߊ߫ ߜߊߘߊ߲ߜߊߘߊ߲ߠߌ߲ ߦߋߡߍ߲ߕߊ ߘߏ߫ ߘߐߛߊߙߌ߫ ߕߎߡߊ
+ ߞߊ߬ ߖߌ߬ߦߊ߬ߓߍ߫ ߦߌ߬ߘߊ߬ߟߊ߲ ߠߎ߫ ߝߍ߲߬ߛߍ߲߫
+ ߏ߬ ߦߋ߫ ߔߌߛߊߞߏ߫ ߟߊ߫ ߡߙߎߝߋ߫ ߞߟߐ߬ߡߊ ߟߎ߫ ߟߋ߬ ߝߍ߲߬ߛߍ߲߬ ߠߊ߫ ߖߌ߬ߦߊ߬ߓߍ ߟߎ߫ ߞߎ߲߬ߘߐ߫ ߞߵߊ߬ߟߎ߬ ߓߐߛߎ߲ ߦߌ߬ߘߊ߬: ߥߎߟߋ߲߬ߡߊ߲ ߦߋ߫ ߞߙߏ߬ߝߏ ߕߊ ߘߌ߫߸ ߓߊ߯ߡߊ ߦߋ߫ ߝߘߍ߬ ߜߍߟߍ߲ ߕߊ ߘߌ߫ ߊ߬ߣߌ߫ ߝߙߌߛߌߡߊ ߦߋ߫ ߦߟߌߕߏߟߊ߲ ߕߊ ߘߌ߫ߟߊ߬ߓߐ߬ߟߌ ߦߴߌߘߐ߫…ߞߵߊ߬ ߘߊߡߌ߬ߣߊ߬ߞߊ߲߬ߞߎߡߊ ߟߎ߬ ߟߊߛߊ߬ߣߍ߲ ߠߋ߬
diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml
index 59a6a739a..f9faa8324 100644
--- a/app/src/main/res/values-or/strings.xml
+++ b/app/src/main/res/values-or/strings.xml
@@ -342,6 +342,7 @@
ସେବାଗୁଡିକରୁ ମୂଳ ଲେଖା ଷ୍ଟ୍ରିମ୍ ଆଇଟମ୍ ଗୁଡିକରେ ଦୃଶ୍ୟମାନ ହେବମିଡିଆ ଟନେଲିଂକୁ ଅକ୍ଷମ କରନ୍ତୁଯଦି ଆପଣ ଏକ କଳା ପରଦା ଅନୁଭବ କରନ୍ତି କିମ୍ବା ଭିଡିଓ ପ୍ଲେବେକ୍ ଉପରେ ଝୁଣ୍ଟି ପଡ଼ନ୍ତି ତେବେ ମିଡିଆ ଟନେଲିଂକୁ ଅକ୍ଷମ କରନ୍ତୁ ।
+ ଚିତ୍ରଗୁଡ଼ିକର ଉପରେ ପିକାସୋ ରଙ୍ଗୀନ ଫିତା ଦେଖାନ୍ତୁ: ସେମାନଙ୍କର ଉତ୍ସକୁ ସୂଚାଇଥାଏ: ନେଟୱାର୍କ ପାଇଁ ନାଲି, ଡିସ୍କ ପାଇଁ ନୀଳ ଏବଂ ସ୍ମୃତି ପାଇଁ ସବୁଜଆମଦାନି କରନ୍ତୁଠାରୁ ଆମଦାନୀ କରନ୍ତୁଆମଦାନି…
@@ -656,6 +657,7 @@
ଅଟୋ-ଜେନେରେଟ୍ (କୌଣସି ଅପଲୋଡର୍ ମିଳିଲା ନାହିଁ)ପୁରଣ କରନ୍ତୁକ୍ୟାପସନ୍
+ ପ୍ରତିଛବି ସୂଚକ ଦେଖାନ୍ତୁପ୍ଲେୟାର ବ୍ୟବହାର କରିବା ସମୟରେ ଏକ କ୍ରାସ୍ ବିକଳ୍ପ ଦେଖାଏନୂତନ ଷ୍ଟ୍ରିମ୍ ପାଇଁ ଯାଞ୍ଚ ଚଲାନ୍ତୁଆପ୍ କ୍ରାସ୍ କରନ୍ତୁ
diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml
index d612ff75b..814cdb885 100644
--- a/app/src/main/res/values-pa/strings.xml
+++ b/app/src/main/res/values-pa/strings.xml
@@ -626,6 +626,8 @@
ਨਿਊਪਾਈਪ ਖਾਮੀ ਤੋਂ ਪ੍ਰਭਾਵਤ ਹੋਈ ਹੈ, ਇੱਥੇ ਨੱਪ ਕੇ ਰਿਪੋਰਟ ਕਰੋਇੱਕ ਖਾਮੀ ਪ੍ਰਭਾਵੀ ਹੋਈ ਹੈ, ਨੋਟੀਫੀਕੇਸ਼ਨ ਵੇਖੋਆਈਟਮਾਂ ਨੂੰ ਇੱਕ ਪਾਸੇ ਖਿੱਚ ਕੇ ਹਟਾਓ
+ ਦ੍ਰਿਸ਼ ਸੂਚਕ ਵਿਖਾਓ
+ ਦ੍ਰਿਸ਼ਾਂ ਦੇ ਉੱਪਰ ਉਹਨਾਂ ਦੀ ਸਰੋਤ-ਪਛਾਣ ਲਈ ਪਿਕਾਸੋ ਦੇ ਰੰਗਦਾਰ ਰਿਬਨ ਵਿਖਾਓ : ਨੈੱਟਵਰਕ ਲਈ ਲਾਲ, ਡਿਸਕ ਲਈ ਨੀਲੇ ਤੇ ਮੈਮਰੀ ਲਈ ਹਰੇਨਵੀਂ ਸਟ੍ਰੀਮ ਦੇ ਨੋਟੀਫਿਕੇਸ਼ਨਪਿੰਨ ਕੀਤੀ ਟਿੱਪਣੀਅੱਪਡੇਟ ਦੀ ਉਪਲੱਬਧਤਾ ਪਰਖੀ ਜਾ ਰਹੀ…
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index b7c517ffc..01f242cd9 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -649,6 +649,8 @@
Nie pokazujSerduszko od twórcyOznacz jako obejrzane
+ Pokazuj kolorowe wstążki Picasso nad obrazami wskazujące ich źródło: czerwone dla sieci, niebieskie dla dysku i zielone dla pamięci
+ Pokazuj wskaźniki obrazuZdalne podpowiedzi wyszukiwaniaLokalne podpowiedzi wyszukiwania
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 3d4b57621..5a203e0f2 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -644,6 +644,7 @@
Os comentários estão desabilitadosMarcar como assistidoCurtido pelo criador
+ Exibir fitas coloridas no topo das imagens indicando sua fonte: vermelho para rede, azul para disco e verde para memória%1$s download excluído%1$s downloads excluídos
@@ -654,6 +655,7 @@
%s downloads concluídos%s downloads concluídos
+ Mostrar indicadores de imagemAdicionado na próxima posição da filaEnfileira a próximaDeslize os itens para remove-los
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index 23310adec..498a49a53 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -644,6 +644,8 @@
Ainda não foi definida uma pasta de descarregamento, escolha agora a pasta de descarregamento padrãoComentários estão desativadosMarcar como visto
+ Mostrar fitas coloridas de Picasso em cima das imagens que indicam a sua fonte: vermelho para rede, azul para disco e verde para memória
+ Mostrar indicadores de imagemSugestões de pesquisa remotasSugestões de pesquisa locais
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 99e5cbd04..5534dbf0b 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -644,6 +644,8 @@
Baixa qualidade (menor)Alta qualidade (maior)Os comentários estão desativados
+ Mostrar fitas coloridas de Picasso em cima das imagens que indicam a sua fonte: vermelho para rede, azul para disco e verde para memória
+ Mostrar indicadores de imagemSugestões de pesquisa remotasSugestões de pesquisa locais
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index a5eb21143..bcef4d952 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -660,6 +660,8 @@
Calitate scăzută (mai mică)Calitate înaltă (mai mare)Miniatură de previzualizare în bara de derulare
+ Afișați panglici colorate de Picasso deasupra imaginilor, indicând sursa acestora: roșu pentru rețea, albastru pentru disc și verde pentru memorie
+ Afișați indicatorii de imagineDezactivați tunelarea media dacă întâmpinați un ecran negru sau blocaje la redarea video.Procesarea.. Poate dura un momentVerifică dacă există actualizări
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 667e5413d..9e79b165f 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -652,6 +652,8 @@
Миниатюра над полосой прокруткиАвтору видео понравилось этоПометить проигранным
+ Picasso: указать цветом источник изображений (красный — сеть, синий — диск, зелёный — память)
+ Цветные метки на изображенияхСерверные предложения поискаЛокальные предложения поиска
diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml
index e970950e0..5a4f35de5 100644
--- a/app/src/main/res/values-ryu/strings.xml
+++ b/app/src/main/res/values-ryu/strings.xml
@@ -646,6 +646,8 @@
%sちぬダウンロードぬかんりょうさびたん%sちぬダウンロードぬかんりょうさびたん
+ ピカソー、がぞうぬういに、がぞうくとぅどぅくるしーきびちするしきさいきしーょうひょうじさびーん: あかーネットワーク、あおーディスク、みどぅれーメモリ
+ やしがぞうんかいふぃいょうしきひょうじしーょりちゅう… くーてーんじがんがかかいんかむしりやびらんみーさるバージョンしーゅどうでぃかくにんさびーんアップデートかくにんちゅう…
diff --git a/app/src/main/res/values-sat/strings.xml b/app/src/main/res/values-sat/strings.xml
index 9ede53a76..a5959086e 100644
--- a/app/src/main/res/values-sat/strings.xml
+++ b/app/src/main/res/values-sat/strings.xml
@@ -270,6 +270,7 @@
LeakCanary ᱵᱟᱭ ᱧᱟᱢᱚᱜ ᱠᱟᱱᱟᱢᱮᱢᱚᱨᱤ ᱞᱤᱠᱟᱞ ᱢᱚᱱᱤᱴᱚᱨᱤᱝ ᱦᱤᱯ ᱰᱟᱢᱯᱤᱝ ᱚᱠᱛᱚ ᱨᱮ ᱮᱯᱞᱤᱠᱮᱥᱚᱱ ᱨᱟᱥᱴᱨᱤᱭ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜ-ᱟᱡᱤᱭᱚᱱ ᱪᱤᱠᱤ ᱠᱷᱚᱱ ᱵᱟᱦᱨᱮ ᱨᱮ ᱵᱷᱮᱜᱟᱨ ᱠᱚ ᱚᱱᱚᱞ ᱢᱮ
+ ᱱᱮᱴᱣᱟᱨᱠ ᱞᱟᱹᱜᱤᱫ red, ᱰᱤᱥᱠ ᱞᱟᱹᱜᱤᱫ blue ᱟᱨ ᱢᱮᱢᱚᱨᱤ ᱞᱟᱹᱜᱤᱫ greenᱯᱞᱮᱭᱟᱨ ᱵᱮᱵᱷᱟᱨ ᱚᱠᱛᱮ ᱨᱮ ᱠᱨᱟᱥ ᱚᱯᱥᱚᱱ ᱧᱮᱞᱚᱜ ᱠᱟᱱᱟᱤᱢᱯᱳᱨᱴᱤᱢᱯᱚᱨᱴ
@@ -539,6 +540,7 @@
ᱡᱤᱱᱤᱥ ᱠᱚᱨᱮᱱᱟᱜ ᱢᱩᱞ ᱚᱠᱛᱚ ᱧᱮᱞ ᱢᱮᱥᱮᱵᱟ ᱠᱷᱚᱱ ᱚᱨᱡᱤᱱᱤᱭᱟᱞ ᱴᱮᱠᱥᱴ ᱠᱚ ᱥᱴᱨᱤᱢ ᱤᱴᱮᱢ ᱨᱮ ᱧᱮᱞᱚᱜᱼᱟᱡᱩᱫᱤ ᱟᱢ ᱵᱷᱤᱰᱤᱭᱳ ᱯᱞᱮᱭᱚᱯ ᱨᱮ ᱵᱞᱮᱠ ᱥᱠᱨᱤᱱ ᱟᱨᱵᱟᱝ ᱠᱷᱟᱹᱞᱤ ᱥᱴᱮᱴᱞᱤᱝ ᱮᱢ ᱧᱟᱢᱟ ᱮᱱᱠᱷᱟᱱ ᱢᱤᱰᱤᱭᱟ ᱴᱩᱱᱮᱞᱤᱝ ᱵᱚᱫᱚᱞ ᱢᱮ ᱾
+ ᱪᱤᱛᱟᱹᱨ ᱪᱤᱱᱦᱟᱹ ᱠᱚ ᱧᱮᱞ ᱢᱮᱱᱟᱣᱟ ᱥᱴᱨᱤᱢ ᱞᱟᱹᱜᱤᱫ ᱪᱟᱪᱞᱟᱣ ᱢᱮᱢᱤᱫ error notification ᱛᱮᱭᱟᱨ ᱢᱮᱥᱮᱞᱮᱫ ᱮᱠᱥᱯᱳᱨᱴ ᱵᱟᱝ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜ ᱠᱟᱱᱟ
diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml
index fce5280e1..6b89b32c3 100644
--- a/app/src/main/res/values-sc/strings.xml
+++ b/app/src/main/res/values-sc/strings.xml
@@ -634,6 +634,8 @@
Sos cummentos sunt disabilitadosSu creadore b\'at postu unu coroMarca comente pompiadu
+ Ammustra sos listrones colorados de Picasso in subra de sas immàgines chi indicant sa fonte issoro: ruja pro sa retze, biaita pro su discu e birde pro sa memòria
+ Ammustra sos indicadores de immàginesImpòsitos de chirca remotaImpòsitos de chirca locales
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 5c4210b71..e3aa5b6bc 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -653,6 +653,8 @@
Nízka kvalita (menšie)Vysoká kvalita (väčšie)Náhľad miniatúry pri vyhľadávaní
+ Zobrazí farebné pásiky Picasso na obrázkoch podľa ich zdroja: červený pre sieť, modrý pre disk a zelený pre pamäť
+ Zobraziť indikátory obrázkaPotiahnutím vymazaťKomentáre sú zakázanéAk je automatické otáčanie zablokované, nespustí videá v miniprehrávači, ale prepne sa do celoobrazovkového režimu. Do miniprehrávača sa dostanete po ukončení režimu celej obrazovky
diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml
index 72e661a1b..e37c3a36d 100644
--- a/app/src/main/res/values-so/strings.xml
+++ b/app/src/main/res/values-so/strings.xml
@@ -633,6 +633,8 @@
Fallooyinka waa laxidhayKahelay soosaarahaWaan daawaday
+ Soo bandhig shaambado midabka Picasso leh sawirrada dushooda oo tilmaamaya isha laga keenay: guduud waa khadka, buluug waa kaydka gudaha, cagaar waa kaydka K/G
+ Tus tilmaamayaasha sawirkaSoojeedinada raadinta banaankaSoojeedinada raadinta gudahaCabirka soodaarida udhexeeya
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 2300cd929..5f14a0e51 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -644,6 +644,7 @@
Означи као одгледаноКоментари су онемогућениОбрађивање… Може потрајати пар тренутака
+ Прикажи индикаторе сликеНе покрећите видео снимке у мини-плејеру, већ директно пређите на режим целог екрана, ако је аутоматска ротација закључана. И даље можете приступити мини-плејеру тако што ћете изаћи из целог екранаПокрени главни плејер преко целог екранаСрушите плејер
@@ -739,6 +740,7 @@
Обавештења за пријаву грешакаУвезите или извезите праћења из менија са 3 тачкеАудио снимак
+ Прикажите Picasso обојене траке на врху слика које указују на њихов извор: црвена за мрежу, плава за диск и зелена за меморијуНаправите обавештење о грешциПроценатКористите најновију верзију NewPipe-а
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 50948fd57..8cf57f605 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -633,6 +633,7 @@
Du kan välja det natt-tema du föredrar nedanVälj det natt-tema du föredrar — %sSökradens förhandsvisningsminiatyr
+ Visa bildindikatorerLokala sökningsförslagTog bort %1$s nedladdning
@@ -650,6 +651,7 @@
Svep objekt för att ta bort demFörslag via fjärrsökningStarta inte videor i minispelaren, utan byt till helskärmsläge direkt, om automatisk rotation är låst. Du kan fortfarande komma åt minispelaren genom att gå ut ur helskärmsläge
+ Visa Picasso färgade band ovanpå bilderna som anger deras källa: rött för nätverk, blått för disk och grönt för minneSök efter uppdateringarKolla manuellt efter nya versionerSöker efter uppdateringar…
diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml
index 90708580a..b2846823c 100644
--- a/app/src/main/res/values-te/strings.xml
+++ b/app/src/main/res/values-te/strings.xml
@@ -442,6 +442,7 @@
ప్లేబ్యాక్ స్పీడ్ నియంత్రణలుఏమిలేదుమీరు బ్లాక్ స్క్రీన్ లేదా చలనచిత్రం ప్లేబ్యాక్లో అంతరాయాన్ని అనుభవిస్తే మీడియా టన్నెలింగ్ను నిలిపివేయండి
+ చిత్రాల మూలాన్ని సూచించే విధంగా వాటి పైభాగంలో పికాసో రంగు రిబ్బన్లను చూపండి: నెట్వర్క్ కోసం ఎరుపు, డిస్క్ కోసం నీలం మరియు మెమరీ కోసం ఆకుపచ్చలోపం స్నాక్బార్ని చూపండిమీరు NewPipe యొక్క తాజా సంస్కరణను అమలు చేస్తున్నారుNewPipe నవీకరణ అందుబాటులో ఉంది!
@@ -454,6 +455,7 @@
తక్కువ నాణ్యత (చిన్నది)చూపించవద్దుమీడియా టన్నెలింగ్ని నిలిపివేయండి
+ చిత్ర సూచికలను చూపుకొత్త స్ట్రీమ్ల కోసం తనిఖీని అమలు చేయండిఎర్రర్ నోటిఫికేషన్ను సృష్టించండిదిగుమతి
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 29933bdc6..adecbf3ff 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -633,6 +633,8 @@
Yorumlar devre dışıYaratıcısınca kalplendiİzlendi olarak işaretle
+ Resimlerin üzerinde kaynaklarını gösteren Picasso renkli şeritler göster: ağ için kırmızı, disk için mavi ve bellek için yeşil
+ Resim göstergelerini gösterUzak arama önerileriYerel arama önerileri
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 86350d40e..c34708609 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -646,6 +646,8 @@
Мініатюра з попереднім переглядом на повзунку поступуВподобано авторомПозначити переглянутим
+ Показувати кольорові стрічки Пікассо поверх зображень із зазначенням їх джерела: червоний для мережі, синій для диска та зелений для пам’яті
+ Показати індикатори зображеньВіддалені пропозиції пошукуЛокальні пошукові пропозиції
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index 15f5a86d4..0d71173af 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -624,6 +624,8 @@
Bình luận đã bị tắtĐã được chủ kênh thả \"thính\"Đánh dấu là đã xem
+ Hiển thị các dải băng màu Picasso trên đầu các hình ảnh cho biết nguồn của chúng: màu đỏ cho mạng, màu lam cho đĩa và màu lục cho bộ nhớ
+ Hiện dấu chỉ hình ảnhĐề xuất tìm kiếm trên mạngĐề xuất tìm kiếm cục bộ
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 7b303621b..fa8d31022 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -624,6 +624,8 @@
高品质(较大)被创作者喜爱标记为已观看
+ 在图像顶部显示毕加索彩带,指示其来源:红色代表网络,蓝色代表磁盘,绿色代表内存
+ 显示图像指示器远程搜索建议本地搜索建议
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 9f581b43f..518a1290f 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -668,7 +668,9 @@
新你係咪要刪除呢個谷?淨係顯示未成谷嘅訂閱
+ 啲圖都要騷 Picasso 三色碼顯示源頭:紅碼係網絡上高落嚟,藍碼係儲存喺磁碟本地,綠碼係潛伏喺記憶體中服務原本嘅字會騷返喺串流項目上面
+ 影像要推三色碼若果播片嘅時候窒下窒下或者黑畫面,就停用多媒體隧道啦。點樣用 Google 匯出嚟匯入 YouTube 訂閱:
\n
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index a4ad3578f..c404edeca 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -624,6 +624,8 @@
拖動列縮圖預覽被創作者加心號標記為已觀看
+ 在圖片頂部顯示畢卡索彩色絲帶,指示其來源:紅色代表網路、藍色代表磁碟、綠色代表記憶體
+ 顯示圖片指示器遠端搜尋建議本機搜尋建議
diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml
index e31cebb92..fb68a464d 100644
--- a/app/src/main/res/values/settings_keys.xml
+++ b/app/src/main/res/values/settings_keys.xml
@@ -241,6 +241,7 @@
show_memory_leaks_keyallow_disposed_exceptions_keyshow_original_time_ago_key
+ show_image_indicators_keyshow_crash_the_player_keycheck_new_streamscrash_the_app_key
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index bff35e5d9..56140441c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -486,6 +486,8 @@
Disable media tunnelingDisable media tunneling if you experience a black screen or stuttering on video playback.Media tunneling was disabled by default on your device because your device model is known to not support it.
+ Show image indicators
+ Show Picasso colored ribbons on top of images indicating their source: red for network, blue for disk and green for memoryShow \"Crash the player\"Shows a crash option when using the playerRun check for new streams
diff --git a/app/src/main/res/xml/debug_settings.xml b/app/src/main/res/xml/debug_settings.xml
index d97c5aa1a..84bb281f3 100644
--- a/app/src/main/res/xml/debug_settings.xml
+++ b/app/src/main/res/xml/debug_settings.xml
@@ -34,6 +34,13 @@
app:singleLineTitle="false"
app:iconSpaceReserved="false" />
+
+
Date: Thu, 11 Jul 2024 09:30:22 +0200
Subject: [PATCH 004/134] Fix NPE in MediaSessionPlayerUi while destroying
player
---
.../newpipe/player/mediasession/MediaSessionPlayerUi.java | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java
index 737ebc5dd..c673e688c 100644
--- a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java
+++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java
@@ -38,7 +38,9 @@ public class MediaSessionPlayerUi extends PlayerUi
implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "MediaSessUi";
+ @Nullable
private MediaSessionCompat mediaSession;
+ @Nullable
private MediaSessionConnector sessionConnector;
private final String ignoreHardwareMediaButtonsKey;
@@ -198,6 +200,11 @@ public class MediaSessionPlayerUi extends PlayerUi
return;
}
+ if (sessionConnector == null) {
+ // sessionConnector will be null after destroyPlayer is called
+ return;
+ }
+
// only use the fourth and fifth actions (the settings page also shows only the last 2 on
// Android 13+)
final List newNotificationActions = IntStream.of(3, 4)
From 0e0cee1bcecc0414a25b88ff0b153273c6a9d546 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 11 Jul 2024 23:27:26 +0200
Subject: [PATCH 005/134] Update NewPipeExtractor to v0.24.1
---
app/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle b/app/build.gradle
index 28a208195..eebf9135f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -198,7 +198,7 @@ dependencies {
// name and the commit hash with the commit hash of the (pushed) commit you want to test
// This works thanks to JitPack: https://jitpack.io/
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
- implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.0'
+ implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.1'
implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0'
/** Checkstyle **/
From acc5be92ac0fcf1899ac265575b01349f4768d82 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 11 Jul 2024 23:39:53 +0200
Subject: [PATCH 006/134] Add changelogs for hotfix release v0.27.1 (998)
---
fastlane/metadata/android/ar/changelogs/998.txt | 1 +
fastlane/metadata/android/az/changelogs/998.txt | 1 +
fastlane/metadata/android/cs/changelogs/998.txt | 1 +
fastlane/metadata/android/de/changelogs/998.txt | 1 +
fastlane/metadata/android/en-US/changelogs/998.txt | 4 ++++
fastlane/metadata/android/es/changelogs/998.txt | 1 +
fastlane/metadata/android/fa/changelogs/998.txt | 1 +
fastlane/metadata/android/fr/changelogs/998.txt | 1 +
fastlane/metadata/android/he/changelogs/998.txt | 1 +
fastlane/metadata/android/hi/changelogs/998.txt | 1 +
fastlane/metadata/android/id/changelogs/998.txt | 1 +
fastlane/metadata/android/it/changelogs/998.txt | 4 ++++
fastlane/metadata/android/ka/changelogs/998.txt | 1 +
fastlane/metadata/android/nl/changelogs/998.txt | 1 +
fastlane/metadata/android/pa/changelogs/998.txt | 1 +
fastlane/metadata/android/pt-BR/changelogs/998.txt | 1 +
fastlane/metadata/android/pt-PT/changelogs/998.txt | 1 +
fastlane/metadata/android/pt/changelogs/998.txt | 1 +
fastlane/metadata/android/ru/changelogs/998.txt | 1 +
fastlane/metadata/android/sv/changelogs/998.txt | 1 +
fastlane/metadata/android/tr/changelogs/998.txt | 1 +
fastlane/metadata/android/uk/changelogs/998.txt | 1 +
fastlane/metadata/android/vi/changelogs/998.txt | 1 +
fastlane/metadata/android/zh-Hans/changelogs/998.txt | 1 +
fastlane/metadata/android/zh-Hant/changelogs/998.txt | 1 +
fastlane/metadata/android/zh_Hant_HK/changelogs/998.txt | 1 +
26 files changed, 32 insertions(+)
create mode 100644 fastlane/metadata/android/ar/changelogs/998.txt
create mode 100644 fastlane/metadata/android/az/changelogs/998.txt
create mode 100644 fastlane/metadata/android/cs/changelogs/998.txt
create mode 100644 fastlane/metadata/android/de/changelogs/998.txt
create mode 100644 fastlane/metadata/android/en-US/changelogs/998.txt
create mode 100644 fastlane/metadata/android/es/changelogs/998.txt
create mode 100644 fastlane/metadata/android/fa/changelogs/998.txt
create mode 100644 fastlane/metadata/android/fr/changelogs/998.txt
create mode 100644 fastlane/metadata/android/he/changelogs/998.txt
create mode 100644 fastlane/metadata/android/hi/changelogs/998.txt
create mode 100644 fastlane/metadata/android/id/changelogs/998.txt
create mode 100644 fastlane/metadata/android/it/changelogs/998.txt
create mode 100644 fastlane/metadata/android/ka/changelogs/998.txt
create mode 100644 fastlane/metadata/android/nl/changelogs/998.txt
create mode 100644 fastlane/metadata/android/pa/changelogs/998.txt
create mode 100644 fastlane/metadata/android/pt-BR/changelogs/998.txt
create mode 100644 fastlane/metadata/android/pt-PT/changelogs/998.txt
create mode 100644 fastlane/metadata/android/pt/changelogs/998.txt
create mode 100644 fastlane/metadata/android/ru/changelogs/998.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/998.txt
create mode 100644 fastlane/metadata/android/tr/changelogs/998.txt
create mode 100644 fastlane/metadata/android/uk/changelogs/998.txt
create mode 100644 fastlane/metadata/android/vi/changelogs/998.txt
create mode 100644 fastlane/metadata/android/zh-Hans/changelogs/998.txt
create mode 100644 fastlane/metadata/android/zh-Hant/changelogs/998.txt
create mode 100644 fastlane/metadata/android/zh_Hant_HK/changelogs/998.txt
diff --git a/fastlane/metadata/android/ar/changelogs/998.txt b/fastlane/metadata/android/ar/changelogs/998.txt
new file mode 100644
index 000000000..562f16944
--- /dev/null
+++ b/fastlane/metadata/android/ar/changelogs/998.txt
@@ -0,0 +1 @@
+تم إصلاح YouTube الذي لا يقوم بتشغيل أي دفق
diff --git a/fastlane/metadata/android/az/changelogs/998.txt b/fastlane/metadata/android/az/changelogs/998.txt
new file mode 100644
index 000000000..16a2e1013
--- /dev/null
+++ b/fastlane/metadata/android/az/changelogs/998.txt
@@ -0,0 +1 @@
+YouTube-un heç bir yayım oynatmaması düzəldildi
diff --git a/fastlane/metadata/android/cs/changelogs/998.txt b/fastlane/metadata/android/cs/changelogs/998.txt
new file mode 100644
index 000000000..7035a1112
--- /dev/null
+++ b/fastlane/metadata/android/cs/changelogs/998.txt
@@ -0,0 +1 @@
+Opraveno nepřehrávání jakéhokoli streamu ve službě YouTube
diff --git a/fastlane/metadata/android/de/changelogs/998.txt b/fastlane/metadata/android/de/changelogs/998.txt
new file mode 100644
index 000000000..43623578f
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/998.txt
@@ -0,0 +1 @@
+Behoben, dass YouTube keinen Stream abspielte
diff --git a/fastlane/metadata/android/en-US/changelogs/998.txt b/fastlane/metadata/android/en-US/changelogs/998.txt
new file mode 100644
index 000000000..468df0204
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/998.txt
@@ -0,0 +1,4 @@
+Fixed YouTube not playing any stream because of HTTP 403 errors.
+
+Occasional HTTP 403 errors in the middle of a YouTube video are not fixed yet.
+That issue will be addressed in another hotfix release as soon as possible.
diff --git a/fastlane/metadata/android/es/changelogs/998.txt b/fastlane/metadata/android/es/changelogs/998.txt
new file mode 100644
index 000000000..80b4efa55
--- /dev/null
+++ b/fastlane/metadata/android/es/changelogs/998.txt
@@ -0,0 +1 @@
+Arreglo en YouTube no reproduciendo flujos
diff --git a/fastlane/metadata/android/fa/changelogs/998.txt b/fastlane/metadata/android/fa/changelogs/998.txt
new file mode 100644
index 000000000..ba5413d49
--- /dev/null
+++ b/fastlane/metadata/android/fa/changelogs/998.txt
@@ -0,0 +1 @@
+مشکل عدم نمایش پخشزنده برطرف شد
diff --git a/fastlane/metadata/android/fr/changelogs/998.txt b/fastlane/metadata/android/fr/changelogs/998.txt
new file mode 100644
index 000000000..3ad3bf279
--- /dev/null
+++ b/fastlane/metadata/android/fr/changelogs/998.txt
@@ -0,0 +1 @@
+Correction de YouTube qui ne lisait aucun média
diff --git a/fastlane/metadata/android/he/changelogs/998.txt b/fastlane/metadata/android/he/changelogs/998.txt
new file mode 100644
index 000000000..50731171e
--- /dev/null
+++ b/fastlane/metadata/android/he/changelogs/998.txt
@@ -0,0 +1 @@
+תוקנה התקלה ש־YouTube לא מנגן אף תזרים
diff --git a/fastlane/metadata/android/hi/changelogs/998.txt b/fastlane/metadata/android/hi/changelogs/998.txt
new file mode 100644
index 000000000..071ab64e3
--- /dev/null
+++ b/fastlane/metadata/android/hi/changelogs/998.txt
@@ -0,0 +1 @@
+फिक्स्ड YouTube कोई स्ट्रीम नहीं चला रहा है
diff --git a/fastlane/metadata/android/id/changelogs/998.txt b/fastlane/metadata/android/id/changelogs/998.txt
new file mode 100644
index 000000000..d3fea84ab
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/998.txt
@@ -0,0 +1 @@
+Memperbaiki YouTube yang tidak memutar streaming apa pun
diff --git a/fastlane/metadata/android/it/changelogs/998.txt b/fastlane/metadata/android/it/changelogs/998.txt
new file mode 100644
index 000000000..73fc6f2d8
--- /dev/null
+++ b/fastlane/metadata/android/it/changelogs/998.txt
@@ -0,0 +1,4 @@
+Corretto problema di riproduzione di YouTube causato da errori HTTP 403.
+
+Gli errori HTTP 403 saltuari nel mezzo di un video di YouTube non sono ancora stati sistemati.
+Questo problema sarà affrontato in un altra release hotfix non appena possibile.
diff --git a/fastlane/metadata/android/ka/changelogs/998.txt b/fastlane/metadata/android/ka/changelogs/998.txt
new file mode 100644
index 000000000..d20512f17
--- /dev/null
+++ b/fastlane/metadata/android/ka/changelogs/998.txt
@@ -0,0 +1 @@
+გაასწორა YouTube არ უკრავს არცერთ ნაკადს
diff --git a/fastlane/metadata/android/nl/changelogs/998.txt b/fastlane/metadata/android/nl/changelogs/998.txt
new file mode 100644
index 000000000..9bd8adf86
--- /dev/null
+++ b/fastlane/metadata/android/nl/changelogs/998.txt
@@ -0,0 +1 @@
+YouTube speelt geen stream af opgelost
diff --git a/fastlane/metadata/android/pa/changelogs/998.txt b/fastlane/metadata/android/pa/changelogs/998.txt
new file mode 100644
index 000000000..fe62a1330
--- /dev/null
+++ b/fastlane/metadata/android/pa/changelogs/998.txt
@@ -0,0 +1 @@
+ਸਥਿਰ YouTube ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਚਲਾ ਰਿਹਾ
diff --git a/fastlane/metadata/android/pt-BR/changelogs/998.txt b/fastlane/metadata/android/pt-BR/changelogs/998.txt
new file mode 100644
index 000000000..59fc6a5cd
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/998.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir qualquer transmissão
diff --git a/fastlane/metadata/android/pt-PT/changelogs/998.txt b/fastlane/metadata/android/pt-PT/changelogs/998.txt
new file mode 100644
index 000000000..93519d64d
--- /dev/null
+++ b/fastlane/metadata/android/pt-PT/changelogs/998.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir nenhuma transmissão
diff --git a/fastlane/metadata/android/pt/changelogs/998.txt b/fastlane/metadata/android/pt/changelogs/998.txt
new file mode 100644
index 000000000..93519d64d
--- /dev/null
+++ b/fastlane/metadata/android/pt/changelogs/998.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir nenhuma transmissão
diff --git a/fastlane/metadata/android/ru/changelogs/998.txt b/fastlane/metadata/android/ru/changelogs/998.txt
new file mode 100644
index 000000000..d3978869d
--- /dev/null
+++ b/fastlane/metadata/android/ru/changelogs/998.txt
@@ -0,0 +1 @@
+Исправлено: YouTube не воспроизводил никакие потоки
diff --git a/fastlane/metadata/android/sv/changelogs/998.txt b/fastlane/metadata/android/sv/changelogs/998.txt
new file mode 100644
index 000000000..35f298dbf
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/998.txt
@@ -0,0 +1 @@
+Åtgärdat att YouTube inte spelar någon stream
diff --git a/fastlane/metadata/android/tr/changelogs/998.txt b/fastlane/metadata/android/tr/changelogs/998.txt
new file mode 100644
index 000000000..e5979c68d
--- /dev/null
+++ b/fastlane/metadata/android/tr/changelogs/998.txt
@@ -0,0 +1 @@
+YouTube'un herhangi bir akışı oynatmaması düzeltildi
diff --git a/fastlane/metadata/android/uk/changelogs/998.txt b/fastlane/metadata/android/uk/changelogs/998.txt
new file mode 100644
index 000000000..905287c74
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/998.txt
@@ -0,0 +1 @@
+Виправлено проблему невідтворюваності трансляцій
diff --git a/fastlane/metadata/android/vi/changelogs/998.txt b/fastlane/metadata/android/vi/changelogs/998.txt
new file mode 100644
index 000000000..d2086b62c
--- /dev/null
+++ b/fastlane/metadata/android/vi/changelogs/998.txt
@@ -0,0 +1 @@
+Đã sửa lỗi YouTube không phát bất kỳ luồng nào
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/998.txt b/fastlane/metadata/android/zh-Hans/changelogs/998.txt
new file mode 100644
index 000000000..8a5424c9e
--- /dev/null
+++ b/fastlane/metadata/android/zh-Hans/changelogs/998.txt
@@ -0,0 +1 @@
+修复YouTube无法播放任何视频
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/998.txt b/fastlane/metadata/android/zh-Hant/changelogs/998.txt
new file mode 100644
index 000000000..4e8bf6537
--- /dev/null
+++ b/fastlane/metadata/android/zh-Hant/changelogs/998.txt
@@ -0,0 +1 @@
+修正 YouTube 無法播放任何串流
diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/998.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/998.txt
new file mode 100644
index 000000000..9a4721551
--- /dev/null
+++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/998.txt
@@ -0,0 +1 @@
+修正咗 YouTube 乜嘢實況串流都播唔到嘅問題
From 0f64158469d42a37df5c8ef200f7963cafabe361 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 11 Jul 2024 23:41:53 +0200
Subject: [PATCH 007/134] Hotfix release v0.27.1 (998)
---
app/build.gradle | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index eebf9135f..397a7301e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -20,8 +20,8 @@ android {
resValue "string", "app_name", "NewPipe"
minSdk 21
targetSdk 33
- versionCode 997
- versionName "0.27.0"
+ versionCode 998
+ versionName "0.27.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
From ad6b676c81ad0beca27a287bb2d0b5f8b41f8f20 Mon Sep 17 00:00:00 2001
From: #27 <68751594+tag27@users.noreply.github.com>
Date: Sat, 13 Jul 2024 14:32:24 -0300
Subject: [PATCH 008/134] Update README.pt_BR.md (#11275)
---
doc/README.pt_BR.md | 128 +++++++++++++++++++++++---------------------
1 file changed, 66 insertions(+), 62 deletions(-)
diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md
index 01fa718ad..59ff65db3 100644
--- a/doc/README.pt_BR.md
+++ b/doc/README.pt_BR.md
@@ -1,3 +1,6 @@
+
-*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)*
+*Leia esse documento em outras línguas: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)*
> [!warning]
-> ESTA É UMA VERSÃO BETA, PORTANTO, VOCÊ PODE ENCONTRAR BUGS. ENCONTROU ALGUM, ABRA UM ISSUE ATRAVÉS DO NOSSO REPOSITÓRIO GITHUB.
+> ESTA É UMA VERSÃO BETA, PORTANTO, VOCÊ PODE ENCONTRAR BUGS. ENCONTROU ALGUM, ABRA UM ISSUE ATRAVÉS DO NOSSO REPOSITÓRIO GITHUB PREENCHENDO O MODELO.
>
-> COLOCAR NEWPIPE OU QUALQUER FORK DELE NA GOOGLE PLAY STORE VIOLA SEUS TERMOS E CONDIÇÕES.
+> COLOCAR NEWPIPE, OU QUALQUER FORK DELE, NA GOOGLE PLAY STORE VIOLA SEUS TERMOS E CONDIÇÕES.
## Screenshots
@@ -39,83 +42,84 @@
[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/09.png)
[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/10.png)
-## Descrição
-
-O NewPipe não usa nenhuma biblioteca de framework do Google, nem a API do YouTube. Os sites são apenas analisados para obter informações necessárias, para que este aplicativo possa ser usado em dispositivos sem os serviços do Google instalados. Além disso, você não precisa de uma conta no YouTube para usar o NewPipe, que é um software livre com copyleft.
-
-### Características
-
-* Procurar vídeos
-* Exibir informações gerais sobre vídeos
-* Assista aos vídeos do YouTube
-* Ouça vídeos do YouTube
-* Modo popup (player flutuante)
-* Selecione o player para assistir streaming
-* Baixar vídeos
-* Baixar somente áudio
-* Abrir vídeo no Kodi
-* Mostrar vídeos próximos/relacionados
-* Pesquise no YouTube em um idioma específico
-* Assistir/Bloquear material restrito
-* Exibir informações gerais sobre canais
-* Pesquisar canais
-* Assista a vídeos de um canal
-* Suporte Orbot/Tor (ainda não diretamente)
-* Suporte 1080p/2K/4K
-* Ver histórico
-* Inscreva-se nos canais
-* Procurar histórico
-* Porcurar/Assistir playlists
-* Assistir playlists em fila
-* Vídeos em fila
-* Playlists Local
-* Legenda
-* Suporte a live
-* Mostrar comentários
-
### Serviços Suportados
-O NewPipe suporta vários serviços. Nosso [documentação](https://teamnewpipe.github.io/documentation/) fornecer mais informações sobre como um novo serviço pode ser adicionado ao aplicativo e ao extrator. Por favor, entre em contato conosco se você pretende adicionar um novo. Atualmente, os serviços suportados são:
+Atualmente, os serviços suportados são:
-* YouTube
-* SoundCloud \[beta\]
-* media.ccc.de \[beta\]
-* PeerTube instances \[beta\]
-* Bandcamp \[beta\]
+* YouTube ([site](https://www.youtube.com/)) e YouTube Music ([site](https://music.youtube.com/)) ([wiki](https://en.wikipedia.org/wiki/YouTube))
+* PeerTube ([site](https://joinpeertube.org/)) e todas suas instâncias (abra o site para saber o que isso significa!) ([wiki](https://en.wikipedia.org/wiki/PeerTube))
+* Bandcamp ([site](https://bandcamp.com/)) ([wiki](https://en.wikipedia.org/wiki/Bandcamp))
+* SoundCloud ([site](https://soundcloud.com/)) ([wiki](https://en.wikipedia.org/wiki/SoundCloud))
+* media.ccc.de ([site](https://media.ccc.de/)) ([wiki](https://en.wikipedia.org/wiki/Chaos_Computer_Club))
-## Atualizações
-Quando uma alteração no código NewPipe (devido à adição de recursos ou fixação de bugs), eventualmente ocorrerá uma versão. Estes estão no formato x.xx.x . A fim de obter esta nova versão, você pode:
- 1. Construa um APK de depuração você mesmo. Esta é a maneira mais rápida de obter novos recursos em seu dispositivo, mas é muito mais complicado, por isso recomendamos usar um dos outros métodos.
- 2. Adicione nosso repo personalizado ao F-Droid e instale-o a partir daí assim que publicarmos um lançamento. As instruções estão aqui.: https://newpipe.net/FAQ/tutorials/install-add-fdroid-repo/
- 3. Baixe o APK do [GitHub Releases](https://github.com/TeamNewPipe/NewPipe/releases) e instalá-lo assim que publicarmos um lançamento.
- 4. Atualização via F-droid. Este é o método mais lento para obter atualizações, pois o F-Droid deve reconhecer alterações, construir o próprio APK, assiná-lo e, em seguida, enviar a atualização para os usuários.
+Como você pode ver, o NewPipe suporta múltiplos serviços de vídeo e áudio. Embora tenha começado com o YouTube, outras pessoas adicionaram mais serviços ao longo dos anos, tornando o NewPipe cada vez mais versátil!
-Recomendamos o método 2 para a maioria dos usuários. Os APKs instalados usando o método 2 ou 3 são compatíveis entre si, mas não com aqueles instalados usando o método 4. Isso se deve à mesma chave de assinatura (nossa) sendo usada para 2 e 3, mas uma chave de assinatura diferente (F-Droid's) está sendo usada para 4. Construir um APK depuração usando o método 1 exclui totalmente uma chave. Assinar chaves ajudam a garantir que um usuário não seja enganado para instalar uma atualização maliciosa em um aplicativo.
+Parcialmente devido as circustâncias e a sua popularidade, o YouTube tem o melhor suporte em relação a esses serviços. Se você usa ou é familarizado com qualquer um desses serviços, por favor ajude-nos a melhorar o suporte para eles! Estamos procurando mantenedores para o SoundCloud e o PeerTube.
+
+Se você pretende adicionar um novo serviço, por favor entre em contato conosco primeiro! Nossa [documentação](https://teamnewpipe.github.io/documentation/) traz mais informações em como um novo serviço pode ser adicionado ao aplicativo e no [NewPipe Extractor](https://github.com/TeamNewPipe/NewPipeExtractor).
+
+## Descrição
+
+NewPipe funciona buscando os dados necessários da API oficial (ex. PeerTube) ou do serviço que você está usando. Se a API oficial é restrita (ex. YouTube) para nossos propósitos, ou é proprietária, o aplicativo analisa o site ou usa uma API interna. Isso significa que não é preciso ter uma conta de qualquer serviço para usar o NewPipe.
+
+Também, desde que somos um software livre e de código aberto, nem o aplicativo e nem o Extractor usa qualquer biblioteca ou framework proprietário, como o Google Play Services. Isso significa que você pode usar o NewPipe em dispositivos ou ROMs customizadas em que não tem os aplicativos do Google instalados.
+
+### Recursos
+
+* Assistir vídeos em resoluções de até 4K
+* Escutar o áudio em segundo plano, carregando apenas o fluxo de áudio para salvar dados
+* Modo popup (player flutuante, aka Picture-in-Picture)
+* Assista a transmissões ao vivo
+* Mostrar/esconder legendas/closed captions
+* Buscar vídeos e áudios (no YouTube, você pode especificar o conteúdo da linguagem também)
+* Enfileirar vídeos (e opcionalmente salvar eles como playlists locais)
+* Mostrar/esconder informações gerais sobre os vídeos (como descrições e tags)
+* Mostrar/esconder vídeos próximos/relacionados
+* Mostrar/esconder comentários
+* Buscar vídeos, áudios, canais, playlists e álbuns
+* Navegar vídeos e áudios dentro de um canal
+* Inscrever-se a canais (sim, mesmo se não estiver logado a qualquer conta!)
+* Receba notificações sobre novos vídeos de canais em que você está inscrito
+* Crie e edite grupos de canais (para facilitar a navegação e o gerenciamento)
+* Navege feeds de vídeo gerados a partir dos seus grupos de canais
+* Veja e pesquise seu histórico de vídeos
+* Pesquise e assista playlists (Eles são playlists remotas, o que significa que eles serão obtidos do serviço que você está navegando)
+* Crie e edite playlists locais (Eles são criados e salvos no aplicativo, e não são relacionados com nenhum serviço)
+* Baixe vídeos/áudios/legendas (closed captions)
+* Abra no Kodi
+* Assista/Bloqueie material restrito
+
+## Instalação e atualizações
+Você pode instalar NewPipe com um dos seguintes métodos:
+ 1. Adicione nosso repo personalizado ao F-Droid e instale-o a partir daí. As instruções estão aqui: https://newpipe.net/FAQ/tutorials/install-add-fdroid-repo/
+ 2. Baixe o APK aqui no [GitHub Releases](https://github.com/TeamNewPipe/NewPipe/releases) e instalá-lo assim que publicarmos um lançamento.
+ 3. Atualização via F-droid. Este é o método mais lento para obter atualizações, pois o F-Droid deve reconhecer alterações, construir o próprio APK, assiná-lo e, em seguida, enviar a atualização para os usuários.
+ 4. Construa um APK de depuração você mesmo. Esta é a maneira mais rápida de obter novos recursos em seu dispositivo, mas é muito mais complicado, por isso recomendamos usar um dos outros métodos.
+ 5. Se você estiver interessado em um recurso específico ou uma correção de bug fornecido em uma solicitação de Pull nesse repositório, pode instalar o APK a partir de lá. Leia a descrição da solicitação para instruções. A grande vantagem dos APKs específicos de S.P é que eles são instalados lado a lado com o aplicativo oficial, então você não precisa se preocupar em perder seus dados ou estragar alguma coisa.
+
+Recomendamos o método 1 para a maioria dos usuários. Os APKs instalados usando o método 1 ou 2 são compatíveis entre si (o que significa que se você instalou o NewPipe usando o método 1 ou 2, você também pode atualizar o NewPipe usando o outro), mas não com aqueles instalados usando o método 3. Isso se deve à mesma chave de assinatura (nossa) sendo usada para 1 e 2, mas uma chave de assinatura diferente (F-Droid's) está sendo usada para 3. Construir um APK depuração usando o método 4 exclui totalmente uma chave. Assinar chaves ajudam a garantir que um usuário não seja enganado para instalar uma atualização maliciosa em um aplicativo. Ao usar o método 5, cada APK é assinado com uma chave aleatória diferente fornecida pelo GitHub Actions, portanto você não pode nem mesmo atualizá-lo. Você terá que fazer backup e restaurar os dados do aplicativo sempre que desejar usar um novo APK.
Enquanto isso, se você quiser trocar de fontes por algum motivo (por exemplo, a funcionalidade principal do NewPipe foi quebrada e o F-Droid ainda não tem a atualização), recomendamos seguir este procedimento:
-1. Faça backup de seus dados através de Configurações > Conteúdo > Exportar Base de Dados para que você mantenha seu histórico, inscrições e playlists
+1. Faça backup de seus dados através de Configurações > Backup e Restauração > Exportar Base de Dados para que você mantenha seu histórico, inscrições e playlists
2. Desinstale o NewPipe
3. Baixe o APK da nova fonte e instale-o
-4. Importe os dados da etapa 1 via Configurações > Conteúdo > Inportar Banco de Dados
+4. Importe os dados da etapa 1 via Configurações > Backup e Restauração > Importar Base de Dados
-## Contribuição
-Se você tem ideias, traduções, alterações de design, limpeza de códigos ou mudanças reais de código, a ajuda é sempre bem-vinda.
-Quanto mais for feito, melhor fica!
-
-Se você quiser se envolver, verifique nossa [notas de contribuição](../.github/CONTRIBUTING.md).
+## Contribuições
+Se você tem ideias, traduções, alterações de design, limpeza de códigos ou mudanças reais de código, a ajuda é sempre bem-vinda. O aplicativo fica cada vez melhor a cada contribuição, não importa quão grande ou pequena! Se você quiser se envolver, verifique nossas [notas de contribuição](.github/CONTRIBUTING.md).
-
+
## Doar
-Se você gosta de NewPipe, ficaríamos felizes com uma doação. Você pode enviar bitcoin ou doar via Bountysource ou Liberapay. Para obter mais informações sobre como doar para a NewPipe, visite nosso [site](https://newpipe.net/donate).
+Se você gosta do NewPipe, pode enivar uma doação. Nós preferimos Liberapay, pois é de código aberto e sem fins lucrativos. Para mais informações sobre como doar para o NewPipe, visite nosso [site](https://newpipe.net/donate).
-
-
+
+
From 0e8303f13ae9905e20be9471c8b2cf48a2e04758 Mon Sep 17 00:00:00 2001
From: opusforlife2 <53176348+opusforlife2@users.noreply.github.com>
Date: Thu, 25 Jul 2024 14:21:21 +0000
Subject: [PATCH 009/134] Update Matrix room link, and prioritise it (#11350)
* Update Matrix room link, and prioritise it
* Update Matrix room link in CONTRIBUTING.md
* Prioritise Matrix in contribution doc too
---
.github/CONTRIBUTING.md | 6 +++---
.github/ISSUE_TEMPLATE/config.yml | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 70c81c7b1..647cfbabb 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -79,6 +79,6 @@ The [ktlint](https://github.com/pinterest/ktlint) plugin does the same job as ch
## Communication
-* The #newpipe channel on Libera Chat (`ircs://irc.libera.chat:6697/newpipe`) has the core team and other developers in it. [Click here for webchat](https://web.libera.chat/#newpipe)!
-* You can also use a Matrix account to join the NewPipe channel at [#newpipe:libera.chat](https://matrix.to/#/#newpipe:libera.chat). Some convenient clients, available both for phone and desktop, are listed at that link.
-* You can post your suggestions, changes, ideas etc. on either GitHub or IRC.
+* You can use a Matrix account to join the NewPipe channel at [#newpipe:matrix.newpipe-ev.de](https://matrix.to/#/#newpipe:matrix.newpipe-ev.de). Some convenient clients, available both for phone and desktop, are listed at that link.
+* Alternatively, the #newpipe channel on Libera Chat (`ircs://irc.libera.chat:6697/newpipe`) can also be joined, as it is bridged to the Matrix room. [Click here for webchat](https://web.libera.chat/#newpipe)!
+* You can post your suggestions, changes, ideas etc. on either GitHub or Matrix (including via IRC).
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 4721637bf..49ab78c7d 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -3,9 +3,9 @@ contact_links:
- name: ❓ Question
url: https://github.com/TeamNewPipe/NewPipe/discussions/new?category=questions
about: Ask about anything NewPipe-related
+ - name: 💬 Matrix
+ url: https://matrix.to/#/#newpipe:matrix.newpipe-ev.de
+ about: Chat with us via Matrix for quick Q/A
- name: 💬 IRC
url: https://web.libera.chat/#newpipe
about: Chat with us via IRC for quick Q/A
- - name: 💬 Matrix
- url: https://matrix.to/#/#newpipe:libera.chat
- about: Chat with us via Matrix for quick Q/A
From 947ac2826a3e118b932a9e781e0ec752a5882e9b Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 25 Jul 2024 18:37:05 +0200
Subject: [PATCH 010/134] Update NewPipeExtractor to v0.24.2
---
app/build.gradle | 2 +-
.../java/org/schabi/newpipe/error/ReCaptchaActivity.java | 9 +++------
.../newpipe/settings/DownloadSettingsFragment.java | 3 +--
3 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 397a7301e..142a0dba6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -198,7 +198,7 @@ dependencies {
// name and the commit hash with the commit hash of the (pushed) commit you want to test
// This works thanks to JitPack: https://jitpack.io/
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
- implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.1'
+ implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.2'
implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0'
/** Checkstyle **/
diff --git a/app/src/main/java/org/schabi/newpipe/error/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/error/ReCaptchaActivity.java
index 3c14cfe4c..42ef261a1 100644
--- a/app/src/main/java/org/schabi/newpipe/error/ReCaptchaActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/error/ReCaptchaActivity.java
@@ -27,8 +27,6 @@ import org.schabi.newpipe.databinding.ActivityRecaptchaBinding;
import org.schabi.newpipe.extractor.utils.Utils;
import org.schabi.newpipe.util.ThemeHelper;
-import java.io.UnsupportedEncodingException;
-
/*
* Created by beneth on 06.12.16.
*
@@ -190,11 +188,10 @@ public class ReCaptchaActivity extends AppCompatActivity {
String abuseCookie = url.substring(abuseStart + 13, abuseEnd);
abuseCookie = Utils.decodeUrlUtf8(abuseCookie);
handleCookies(abuseCookie);
- } catch (UnsupportedEncodingException | StringIndexOutOfBoundsException e) {
+ } catch (IllegalArgumentException | StringIndexOutOfBoundsException e) {
if (MainActivity.DEBUG) {
- e.printStackTrace();
- Log.d(TAG, "handleCookiesFromUrl: invalid google abuse starting at "
- + abuseStart + " and ending at " + abuseEnd + " for url " + url);
+ Log.e(TAG, "handleCookiesFromUrl: invalid google abuse starting at "
+ + abuseStart + " and ending at " + abuseEnd + " for url " + url, e);
}
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
index 472db6afe..76163b30a 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
@@ -30,7 +30,6 @@ import org.schabi.newpipe.util.FilePickerActivityHelper;
import java.io.File;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.net.URI;
public class DownloadSettingsFragment extends BasePreferenceFragment {
@@ -125,7 +124,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
try {
rawUri = decodeUrlUtf8(rawUri);
- } catch (final UnsupportedEncodingException e) {
+ } catch (final IllegalArgumentException e) {
// nothing to do
}
From 56b62413117f3d7ca8a46dc7c326b35f16e512b4 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 25 Jul 2024 18:43:03 +0200
Subject: [PATCH 011/134] Hotfix release v0.27.2 (999)
---
app/build.gradle | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 142a0dba6..5706f1c4b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -20,8 +20,8 @@ android {
resValue "string", "app_name", "NewPipe"
minSdk 21
targetSdk 33
- versionCode 998
- versionName "0.27.1"
+ versionCode 999
+ versionName "0.27.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
From 03a6b5c7b9ab1236d42ad2ee7fe953309ee210fd Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 11 Jul 2024 23:39:53 +0200
Subject: [PATCH 012/134] Add changelogs for hotfix release v0.27.2 (999)
---
fastlane/metadata/android/ar/changelogs/999.txt | 1 +
fastlane/metadata/android/az/changelogs/999.txt | 1 +
fastlane/metadata/android/cs/changelogs/999.txt | 1 +
fastlane/metadata/android/de/changelogs/999.txt | 1 +
fastlane/metadata/android/en-US/changelogs/999.txt | 12 ++++++++++++
fastlane/metadata/android/es/changelogs/999.txt | 1 +
fastlane/metadata/android/fa/changelogs/999.txt | 1 +
fastlane/metadata/android/fr/changelogs/999.txt | 1 +
fastlane/metadata/android/he/changelogs/999.txt | 1 +
fastlane/metadata/android/hi/changelogs/999.txt | 1 +
fastlane/metadata/android/id/changelogs/999.txt | 1 +
fastlane/metadata/android/it/changelogs/999.txt | 12 ++++++++++++
fastlane/metadata/android/ka/changelogs/999.txt | 1 +
fastlane/metadata/android/nl/changelogs/999.txt | 1 +
fastlane/metadata/android/pa/changelogs/999.txt | 1 +
fastlane/metadata/android/pt-BR/changelogs/999.txt | 1 +
fastlane/metadata/android/pt-PT/changelogs/999.txt | 1 +
fastlane/metadata/android/pt/changelogs/999.txt | 1 +
fastlane/metadata/android/ru/changelogs/999.txt | 1 +
fastlane/metadata/android/sv/changelogs/999.txt | 1 +
fastlane/metadata/android/tr/changelogs/999.txt | 1 +
fastlane/metadata/android/uk/changelogs/999.txt | 1 +
fastlane/metadata/android/vi/changelogs/999.txt | 1 +
fastlane/metadata/android/zh-Hans/changelogs/999.txt | 1 +
fastlane/metadata/android/zh-Hant/changelogs/999.txt | 1 +
.../metadata/android/zh_Hant_HK/changelogs/999.txt | 1 +
26 files changed, 48 insertions(+)
create mode 100644 fastlane/metadata/android/ar/changelogs/999.txt
create mode 100644 fastlane/metadata/android/az/changelogs/999.txt
create mode 100644 fastlane/metadata/android/cs/changelogs/999.txt
create mode 100644 fastlane/metadata/android/de/changelogs/999.txt
create mode 100644 fastlane/metadata/android/en-US/changelogs/999.txt
create mode 100644 fastlane/metadata/android/es/changelogs/999.txt
create mode 100644 fastlane/metadata/android/fa/changelogs/999.txt
create mode 100644 fastlane/metadata/android/fr/changelogs/999.txt
create mode 100644 fastlane/metadata/android/he/changelogs/999.txt
create mode 100644 fastlane/metadata/android/hi/changelogs/999.txt
create mode 100644 fastlane/metadata/android/id/changelogs/999.txt
create mode 100644 fastlane/metadata/android/it/changelogs/999.txt
create mode 100644 fastlane/metadata/android/ka/changelogs/999.txt
create mode 100644 fastlane/metadata/android/nl/changelogs/999.txt
create mode 100644 fastlane/metadata/android/pa/changelogs/999.txt
create mode 100644 fastlane/metadata/android/pt-BR/changelogs/999.txt
create mode 100644 fastlane/metadata/android/pt-PT/changelogs/999.txt
create mode 100644 fastlane/metadata/android/pt/changelogs/999.txt
create mode 100644 fastlane/metadata/android/ru/changelogs/999.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/999.txt
create mode 100644 fastlane/metadata/android/tr/changelogs/999.txt
create mode 100644 fastlane/metadata/android/uk/changelogs/999.txt
create mode 100644 fastlane/metadata/android/vi/changelogs/999.txt
create mode 100644 fastlane/metadata/android/zh-Hans/changelogs/999.txt
create mode 100644 fastlane/metadata/android/zh-Hant/changelogs/999.txt
create mode 100644 fastlane/metadata/android/zh_Hant_HK/changelogs/999.txt
diff --git a/fastlane/metadata/android/ar/changelogs/999.txt b/fastlane/metadata/android/ar/changelogs/999.txt
new file mode 100644
index 000000000..562f16944
--- /dev/null
+++ b/fastlane/metadata/android/ar/changelogs/999.txt
@@ -0,0 +1 @@
+تم إصلاح YouTube الذي لا يقوم بتشغيل أي دفق
diff --git a/fastlane/metadata/android/az/changelogs/999.txt b/fastlane/metadata/android/az/changelogs/999.txt
new file mode 100644
index 000000000..16a2e1013
--- /dev/null
+++ b/fastlane/metadata/android/az/changelogs/999.txt
@@ -0,0 +1 @@
+YouTube-un heç bir yayım oynatmaması düzəldildi
diff --git a/fastlane/metadata/android/cs/changelogs/999.txt b/fastlane/metadata/android/cs/changelogs/999.txt
new file mode 100644
index 000000000..7035a1112
--- /dev/null
+++ b/fastlane/metadata/android/cs/changelogs/999.txt
@@ -0,0 +1 @@
+Opraveno nepřehrávání jakéhokoli streamu ve službě YouTube
diff --git a/fastlane/metadata/android/de/changelogs/999.txt b/fastlane/metadata/android/de/changelogs/999.txt
new file mode 100644
index 000000000..43623578f
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/999.txt
@@ -0,0 +1 @@
+Behoben, dass YouTube keinen Stream abspielte
diff --git a/fastlane/metadata/android/en-US/changelogs/999.txt b/fastlane/metadata/android/en-US/changelogs/999.txt
new file mode 100644
index 000000000..c089ed197
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/999.txt
@@ -0,0 +1,12 @@
+This hotfix release fixes HTTP 403 errors in the middle of YouTube videos.
+
+New
+• [SoundCloud] Add support for on.soundcloud.com URLs
+
+Improved
+• [Bandcamp] Show additional info in radio kiosk
+
+Fixed
+• [YouTube] Fix occasional HTTP 403 errors at the beginning or in the middle of videos
+• [YouTube] Extract avatar and banner from more channel header types
+• [Bandcamp] Fix various bugs and always use HTTPS
diff --git a/fastlane/metadata/android/es/changelogs/999.txt b/fastlane/metadata/android/es/changelogs/999.txt
new file mode 100644
index 000000000..80b4efa55
--- /dev/null
+++ b/fastlane/metadata/android/es/changelogs/999.txt
@@ -0,0 +1 @@
+Arreglo en YouTube no reproduciendo flujos
diff --git a/fastlane/metadata/android/fa/changelogs/999.txt b/fastlane/metadata/android/fa/changelogs/999.txt
new file mode 100644
index 000000000..ba5413d49
--- /dev/null
+++ b/fastlane/metadata/android/fa/changelogs/999.txt
@@ -0,0 +1 @@
+مشکل عدم نمایش پخشزنده برطرف شد
diff --git a/fastlane/metadata/android/fr/changelogs/999.txt b/fastlane/metadata/android/fr/changelogs/999.txt
new file mode 100644
index 000000000..3ad3bf279
--- /dev/null
+++ b/fastlane/metadata/android/fr/changelogs/999.txt
@@ -0,0 +1 @@
+Correction de YouTube qui ne lisait aucun média
diff --git a/fastlane/metadata/android/he/changelogs/999.txt b/fastlane/metadata/android/he/changelogs/999.txt
new file mode 100644
index 000000000..50731171e
--- /dev/null
+++ b/fastlane/metadata/android/he/changelogs/999.txt
@@ -0,0 +1 @@
+תוקנה התקלה ש־YouTube לא מנגן אף תזרים
diff --git a/fastlane/metadata/android/hi/changelogs/999.txt b/fastlane/metadata/android/hi/changelogs/999.txt
new file mode 100644
index 000000000..071ab64e3
--- /dev/null
+++ b/fastlane/metadata/android/hi/changelogs/999.txt
@@ -0,0 +1 @@
+फिक्स्ड YouTube कोई स्ट्रीम नहीं चला रहा है
diff --git a/fastlane/metadata/android/id/changelogs/999.txt b/fastlane/metadata/android/id/changelogs/999.txt
new file mode 100644
index 000000000..d3fea84ab
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/999.txt
@@ -0,0 +1 @@
+Memperbaiki YouTube yang tidak memutar streaming apa pun
diff --git a/fastlane/metadata/android/it/changelogs/999.txt b/fastlane/metadata/android/it/changelogs/999.txt
new file mode 100644
index 000000000..c2652da28
--- /dev/null
+++ b/fastlane/metadata/android/it/changelogs/999.txt
@@ -0,0 +1,12 @@
+Questo aggiornamento hotfix risolve gli errori HTTP 403 nel mezzo dei video di YouTube.
+
+Novità
+• [SoundCloud] Aggiunto il supporto per gli URL on.soundcloud.com
+
+Migliorie
+• [Bandcamp] Mostra informazioni aggiuntive nel chiosco della radio
+
+Correzioni
+• [YouTube] Corretti errori HTTP 403 occasionali all'inizio o nel mezzo dei video
+• [YouTube] Estrazione avatar e banner da più tipi di canali
+• [Bandcamp] Risolti vari bug e forzato l'uso di HTTPS
diff --git a/fastlane/metadata/android/ka/changelogs/999.txt b/fastlane/metadata/android/ka/changelogs/999.txt
new file mode 100644
index 000000000..d20512f17
--- /dev/null
+++ b/fastlane/metadata/android/ka/changelogs/999.txt
@@ -0,0 +1 @@
+გაასწორა YouTube არ უკრავს არცერთ ნაკადს
diff --git a/fastlane/metadata/android/nl/changelogs/999.txt b/fastlane/metadata/android/nl/changelogs/999.txt
new file mode 100644
index 000000000..9bd8adf86
--- /dev/null
+++ b/fastlane/metadata/android/nl/changelogs/999.txt
@@ -0,0 +1 @@
+YouTube speelt geen stream af opgelost
diff --git a/fastlane/metadata/android/pa/changelogs/999.txt b/fastlane/metadata/android/pa/changelogs/999.txt
new file mode 100644
index 000000000..fe62a1330
--- /dev/null
+++ b/fastlane/metadata/android/pa/changelogs/999.txt
@@ -0,0 +1 @@
+ਸਥਿਰ YouTube ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਚਲਾ ਰਿਹਾ
diff --git a/fastlane/metadata/android/pt-BR/changelogs/999.txt b/fastlane/metadata/android/pt-BR/changelogs/999.txt
new file mode 100644
index 000000000..59fc6a5cd
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/999.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir qualquer transmissão
diff --git a/fastlane/metadata/android/pt-PT/changelogs/999.txt b/fastlane/metadata/android/pt-PT/changelogs/999.txt
new file mode 100644
index 000000000..93519d64d
--- /dev/null
+++ b/fastlane/metadata/android/pt-PT/changelogs/999.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir nenhuma transmissão
diff --git a/fastlane/metadata/android/pt/changelogs/999.txt b/fastlane/metadata/android/pt/changelogs/999.txt
new file mode 100644
index 000000000..93519d64d
--- /dev/null
+++ b/fastlane/metadata/android/pt/changelogs/999.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir nenhuma transmissão
diff --git a/fastlane/metadata/android/ru/changelogs/999.txt b/fastlane/metadata/android/ru/changelogs/999.txt
new file mode 100644
index 000000000..d3978869d
--- /dev/null
+++ b/fastlane/metadata/android/ru/changelogs/999.txt
@@ -0,0 +1 @@
+Исправлено: YouTube не воспроизводил никакие потоки
diff --git a/fastlane/metadata/android/sv/changelogs/999.txt b/fastlane/metadata/android/sv/changelogs/999.txt
new file mode 100644
index 000000000..35f298dbf
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/999.txt
@@ -0,0 +1 @@
+Åtgärdat att YouTube inte spelar någon stream
diff --git a/fastlane/metadata/android/tr/changelogs/999.txt b/fastlane/metadata/android/tr/changelogs/999.txt
new file mode 100644
index 000000000..e5979c68d
--- /dev/null
+++ b/fastlane/metadata/android/tr/changelogs/999.txt
@@ -0,0 +1 @@
+YouTube'un herhangi bir akışı oynatmaması düzeltildi
diff --git a/fastlane/metadata/android/uk/changelogs/999.txt b/fastlane/metadata/android/uk/changelogs/999.txt
new file mode 100644
index 000000000..905287c74
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/999.txt
@@ -0,0 +1 @@
+Виправлено проблему невідтворюваності трансляцій
diff --git a/fastlane/metadata/android/vi/changelogs/999.txt b/fastlane/metadata/android/vi/changelogs/999.txt
new file mode 100644
index 000000000..d2086b62c
--- /dev/null
+++ b/fastlane/metadata/android/vi/changelogs/999.txt
@@ -0,0 +1 @@
+Đã sửa lỗi YouTube không phát bất kỳ luồng nào
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/999.txt b/fastlane/metadata/android/zh-Hans/changelogs/999.txt
new file mode 100644
index 000000000..8a5424c9e
--- /dev/null
+++ b/fastlane/metadata/android/zh-Hans/changelogs/999.txt
@@ -0,0 +1 @@
+修复YouTube无法播放任何视频
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/999.txt b/fastlane/metadata/android/zh-Hant/changelogs/999.txt
new file mode 100644
index 000000000..4e8bf6537
--- /dev/null
+++ b/fastlane/metadata/android/zh-Hant/changelogs/999.txt
@@ -0,0 +1 @@
+修正 YouTube 無法播放任何串流
diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/999.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/999.txt
new file mode 100644
index 000000000..9a4721551
--- /dev/null
+++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/999.txt
@@ -0,0 +1 @@
+修正咗 YouTube 乜嘢實況串流都播唔到嘅問題
From dbcb721dc21429c25aa164afb98dc3b91e19672b Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 25 Jul 2024 20:56:16 +0200
Subject: [PATCH 013/134] Don't warn about rhino class in proguard
Likely related to https://github.com/mozilla/rhino/commit/01a7b20655602f7e2df59af744b47b77f678b6cf but I am not completely sure.
I tested the app and it works well, so I think that org.mozilla.javascript.JavaToJSONConverters is not used really.
This is the full list of errors:
Missing class java.beans.BeanDescriptor (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
Missing class java.beans.BeanInfo (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
Missing class java.beans.IntrospectionException (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
Missing class java.beans.Introspector (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
Missing class java.beans.PropertyDescriptor (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
---
app/build.gradle | 3 +++
app/proguard-rules.pro | 1 +
2 files changed, 4 insertions(+)
diff --git a/app/build.gradle b/app/build.gradle
index 5706f1c4b..35cb8509e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -56,6 +56,9 @@ android {
resValue "string", "app_name", "NewPipe " + System.getProperty('packageSuffix')
archivesBaseName = 'NewPipe_' + System.getProperty('packageSuffix')
}
+ applicationIdSuffix ".whatever"
+ resValue "string", "app_name", "NewPipe whatever"
+ archivesBaseName = 'NewPipe_whatever'
minifyEnabled true
shrinkResources false // disabled to fix F-Droid's reproducible build
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index d21f33e1f..435c4e29b 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -7,6 +7,7 @@
-keep class org.schabi.newpipe.extractor.timeago.patterns.** { *; }
-keep class org.mozilla.javascript.** { *; }
-keep class org.mozilla.classfile.ClassFileWriter
+-dontwarn org.mozilla.javascript.JavaToJSONConverters
-dontwarn org.mozilla.javascript.tools.**
## Rules for ExoPlayer
From d442b458361b002ab90d9608db223203601ee2cc Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 25 Jul 2024 20:58:29 +0200
Subject: [PATCH 014/134] Remove code committed accidentally
---
app/build.gradle | 3 ---
1 file changed, 3 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 35cb8509e..5706f1c4b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -56,9 +56,6 @@ android {
resValue "string", "app_name", "NewPipe " + System.getProperty('packageSuffix')
archivesBaseName = 'NewPipe_' + System.getProperty('packageSuffix')
}
- applicationIdSuffix ".whatever"
- resValue "string", "app_name", "NewPipe whatever"
- archivesBaseName = 'NewPipe_whatever'
minifyEnabled true
shrinkResources false // disabled to fix F-Droid's reproducible build
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
From 9d04a73c858cb39738fb970c80941ef8281ff8dd Mon Sep 17 00:00:00 2001
From: Isira Seneviratne <31027858+Isira-Seneviratne@users.noreply.github.com>
Date: Sun, 11 Aug 2024 08:11:50 +0530
Subject: [PATCH 015/134] Merge dev to refactor (#11427)
* add NP icon for Android Studio's NewUI
* Fix NPE in MediaSessionPlayerUi while destroying player
* Update NewPipeExtractor to v0.24.1
* Add changelogs for hotfix release v0.27.1 (998)
* Hotfix release v0.27.1 (998)
* Update README.pt_BR.md (#11275)
* Update Matrix room link, and prioritise it (#11350)
* Update Matrix room link, and prioritise it
* Update Matrix room link in CONTRIBUTING.md
* Prioritise Matrix in contribution doc too
* Update NewPipeExtractor to v0.24.2
* Hotfix release v0.27.2 (999)
* Add changelogs for hotfix release v0.27.2 (999)
* Don't warn about rhino class in proguard
Likely related to https://github.com/mozilla/rhino/commit/01a7b20655602f7e2df59af744b47b77f678b6cf but I am not completely sure.
I tested the app and it works well, so I think that org.mozilla.javascript.JavaToJSONConverters is not used really.
This is the full list of errors:
Missing class java.beans.BeanDescriptor (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
Missing class java.beans.BeanInfo (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
Missing class java.beans.IntrospectionException (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
Missing class java.beans.Introspector (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
Missing class java.beans.PropertyDescriptor (referenced from: java.lang.Object org.mozilla.javascript.JavaToJSONConverters.lambda$static$4(java.lang.Object))
* Remove code committed accidentally
---------
Co-authored-by: Christian Schabesberger
Co-authored-by: Tobi
Co-authored-by: Stypox
Co-authored-by: #27 <68751594+tag27@users.noreply.github.com>
Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com>
---
.github/CONTRIBUTING.md | 6 +-
.github/ISSUE_TEMPLATE/config.yml | 6 +-
.idea/icon.svg | 21 +++
app/build.gradle | 6 +-
app/proguard-rules.pro | 1 +
.../newpipe/error/ReCaptchaActivity.java | 9 +-
.../mediasession/MediaSessionPlayerUi.java | 7 +
.../settings/DownloadSettingsFragment.java | 3 +-
doc/README.pt_BR.md | 128 +++++++++---------
.../metadata/android/ar/changelogs/998.txt | 1 +
.../metadata/android/ar/changelogs/999.txt | 1 +
.../metadata/android/az/changelogs/998.txt | 1 +
.../metadata/android/az/changelogs/999.txt | 1 +
.../metadata/android/cs/changelogs/998.txt | 1 +
.../metadata/android/cs/changelogs/999.txt | 1 +
.../metadata/android/de/changelogs/998.txt | 1 +
.../metadata/android/de/changelogs/999.txt | 1 +
.../metadata/android/en-US/changelogs/998.txt | 4 +
.../metadata/android/en-US/changelogs/999.txt | 12 ++
.../metadata/android/es/changelogs/998.txt | 1 +
.../metadata/android/es/changelogs/999.txt | 1 +
.../metadata/android/fa/changelogs/998.txt | 1 +
.../metadata/android/fa/changelogs/999.txt | 1 +
.../metadata/android/fr/changelogs/998.txt | 1 +
.../metadata/android/fr/changelogs/999.txt | 1 +
.../metadata/android/he/changelogs/998.txt | 1 +
.../metadata/android/he/changelogs/999.txt | 1 +
.../metadata/android/hi/changelogs/998.txt | 1 +
.../metadata/android/hi/changelogs/999.txt | 1 +
.../metadata/android/id/changelogs/998.txt | 1 +
.../metadata/android/id/changelogs/999.txt | 1 +
.../metadata/android/it/changelogs/998.txt | 4 +
.../metadata/android/it/changelogs/999.txt | 12 ++
.../metadata/android/ka/changelogs/998.txt | 1 +
.../metadata/android/ka/changelogs/999.txt | 1 +
.../metadata/android/nl/changelogs/998.txt | 1 +
.../metadata/android/nl/changelogs/999.txt | 1 +
.../metadata/android/pa/changelogs/998.txt | 1 +
.../metadata/android/pa/changelogs/999.txt | 1 +
.../metadata/android/pt-BR/changelogs/998.txt | 1 +
.../metadata/android/pt-BR/changelogs/999.txt | 1 +
.../metadata/android/pt-PT/changelogs/998.txt | 1 +
.../metadata/android/pt-PT/changelogs/999.txt | 1 +
.../metadata/android/pt/changelogs/998.txt | 1 +
.../metadata/android/pt/changelogs/999.txt | 1 +
.../metadata/android/ru/changelogs/998.txt | 1 +
.../metadata/android/ru/changelogs/999.txt | 1 +
.../metadata/android/sv/changelogs/998.txt | 1 +
.../metadata/android/sv/changelogs/999.txt | 1 +
.../metadata/android/tr/changelogs/998.txt | 1 +
.../metadata/android/tr/changelogs/999.txt | 1 +
.../metadata/android/uk/changelogs/998.txt | 1 +
.../metadata/android/uk/changelogs/999.txt | 1 +
.../metadata/android/vi/changelogs/998.txt | 1 +
.../metadata/android/vi/changelogs/999.txt | 1 +
.../android/zh-Hans/changelogs/998.txt | 1 +
.../android/zh-Hans/changelogs/999.txt | 1 +
.../android/zh-Hant/changelogs/998.txt | 1 +
.../android/zh-Hant/changelogs/999.txt | 1 +
.../android/zh_Hant_HK/changelogs/998.txt | 1 +
.../android/zh_Hant_HK/changelogs/999.txt | 1 +
61 files changed, 188 insertions(+), 79 deletions(-)
create mode 100644 .idea/icon.svg
create mode 100644 fastlane/metadata/android/ar/changelogs/998.txt
create mode 100644 fastlane/metadata/android/ar/changelogs/999.txt
create mode 100644 fastlane/metadata/android/az/changelogs/998.txt
create mode 100644 fastlane/metadata/android/az/changelogs/999.txt
create mode 100644 fastlane/metadata/android/cs/changelogs/998.txt
create mode 100644 fastlane/metadata/android/cs/changelogs/999.txt
create mode 100644 fastlane/metadata/android/de/changelogs/998.txt
create mode 100644 fastlane/metadata/android/de/changelogs/999.txt
create mode 100644 fastlane/metadata/android/en-US/changelogs/998.txt
create mode 100644 fastlane/metadata/android/en-US/changelogs/999.txt
create mode 100644 fastlane/metadata/android/es/changelogs/998.txt
create mode 100644 fastlane/metadata/android/es/changelogs/999.txt
create mode 100644 fastlane/metadata/android/fa/changelogs/998.txt
create mode 100644 fastlane/metadata/android/fa/changelogs/999.txt
create mode 100644 fastlane/metadata/android/fr/changelogs/998.txt
create mode 100644 fastlane/metadata/android/fr/changelogs/999.txt
create mode 100644 fastlane/metadata/android/he/changelogs/998.txt
create mode 100644 fastlane/metadata/android/he/changelogs/999.txt
create mode 100644 fastlane/metadata/android/hi/changelogs/998.txt
create mode 100644 fastlane/metadata/android/hi/changelogs/999.txt
create mode 100644 fastlane/metadata/android/id/changelogs/998.txt
create mode 100644 fastlane/metadata/android/id/changelogs/999.txt
create mode 100644 fastlane/metadata/android/it/changelogs/998.txt
create mode 100644 fastlane/metadata/android/it/changelogs/999.txt
create mode 100644 fastlane/metadata/android/ka/changelogs/998.txt
create mode 100644 fastlane/metadata/android/ka/changelogs/999.txt
create mode 100644 fastlane/metadata/android/nl/changelogs/998.txt
create mode 100644 fastlane/metadata/android/nl/changelogs/999.txt
create mode 100644 fastlane/metadata/android/pa/changelogs/998.txt
create mode 100644 fastlane/metadata/android/pa/changelogs/999.txt
create mode 100644 fastlane/metadata/android/pt-BR/changelogs/998.txt
create mode 100644 fastlane/metadata/android/pt-BR/changelogs/999.txt
create mode 100644 fastlane/metadata/android/pt-PT/changelogs/998.txt
create mode 100644 fastlane/metadata/android/pt-PT/changelogs/999.txt
create mode 100644 fastlane/metadata/android/pt/changelogs/998.txt
create mode 100644 fastlane/metadata/android/pt/changelogs/999.txt
create mode 100644 fastlane/metadata/android/ru/changelogs/998.txt
create mode 100644 fastlane/metadata/android/ru/changelogs/999.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/998.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/999.txt
create mode 100644 fastlane/metadata/android/tr/changelogs/998.txt
create mode 100644 fastlane/metadata/android/tr/changelogs/999.txt
create mode 100644 fastlane/metadata/android/uk/changelogs/998.txt
create mode 100644 fastlane/metadata/android/uk/changelogs/999.txt
create mode 100644 fastlane/metadata/android/vi/changelogs/998.txt
create mode 100644 fastlane/metadata/android/vi/changelogs/999.txt
create mode 100644 fastlane/metadata/android/zh-Hans/changelogs/998.txt
create mode 100644 fastlane/metadata/android/zh-Hans/changelogs/999.txt
create mode 100644 fastlane/metadata/android/zh-Hant/changelogs/998.txt
create mode 100644 fastlane/metadata/android/zh-Hant/changelogs/999.txt
create mode 100644 fastlane/metadata/android/zh_Hant_HK/changelogs/998.txt
create mode 100644 fastlane/metadata/android/zh_Hant_HK/changelogs/999.txt
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 70c81c7b1..647cfbabb 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -79,6 +79,6 @@ The [ktlint](https://github.com/pinterest/ktlint) plugin does the same job as ch
## Communication
-* The #newpipe channel on Libera Chat (`ircs://irc.libera.chat:6697/newpipe`) has the core team and other developers in it. [Click here for webchat](https://web.libera.chat/#newpipe)!
-* You can also use a Matrix account to join the NewPipe channel at [#newpipe:libera.chat](https://matrix.to/#/#newpipe:libera.chat). Some convenient clients, available both for phone and desktop, are listed at that link.
-* You can post your suggestions, changes, ideas etc. on either GitHub or IRC.
+* You can use a Matrix account to join the NewPipe channel at [#newpipe:matrix.newpipe-ev.de](https://matrix.to/#/#newpipe:matrix.newpipe-ev.de). Some convenient clients, available both for phone and desktop, are listed at that link.
+* Alternatively, the #newpipe channel on Libera Chat (`ircs://irc.libera.chat:6697/newpipe`) can also be joined, as it is bridged to the Matrix room. [Click here for webchat](https://web.libera.chat/#newpipe)!
+* You can post your suggestions, changes, ideas etc. on either GitHub or Matrix (including via IRC).
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 4721637bf..49ab78c7d 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -3,9 +3,9 @@ contact_links:
- name: ❓ Question
url: https://github.com/TeamNewPipe/NewPipe/discussions/new?category=questions
about: Ask about anything NewPipe-related
+ - name: 💬 Matrix
+ url: https://matrix.to/#/#newpipe:matrix.newpipe-ev.de
+ about: Chat with us via Matrix for quick Q/A
- name: 💬 IRC
url: https://web.libera.chat/#newpipe
about: Chat with us via IRC for quick Q/A
- - name: 💬 Matrix
- url: https://matrix.to/#/#newpipe:libera.chat
- about: Chat with us via Matrix for quick Q/A
diff --git a/.idea/icon.svg b/.idea/icon.svg
new file mode 100644
index 000000000..51fdf95de
--- /dev/null
+++ b/.idea/icon.svg
@@ -0,0 +1,21 @@
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
index dba278efc..9ea725ad9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -20,8 +20,8 @@ android {
resValue "string", "app_name", "NewPipe"
minSdk 21
targetSdk 33
- versionCode 997
- versionName "0.27.0"
+ versionCode 999
+ versionName "0.27.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -203,7 +203,7 @@ dependencies {
// name and the commit hash with the commit hash of the (pushed) commit you want to test
// This works thanks to JitPack: https://jitpack.io/
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
- implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.1'
+ implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.2'
implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0'
/** Checkstyle **/
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index d21f33e1f..435c4e29b 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -7,6 +7,7 @@
-keep class org.schabi.newpipe.extractor.timeago.patterns.** { *; }
-keep class org.mozilla.javascript.** { *; }
-keep class org.mozilla.classfile.ClassFileWriter
+-dontwarn org.mozilla.javascript.JavaToJSONConverters
-dontwarn org.mozilla.javascript.tools.**
## Rules for ExoPlayer
diff --git a/app/src/main/java/org/schabi/newpipe/error/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/error/ReCaptchaActivity.java
index 3c14cfe4c..42ef261a1 100644
--- a/app/src/main/java/org/schabi/newpipe/error/ReCaptchaActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/error/ReCaptchaActivity.java
@@ -27,8 +27,6 @@ import org.schabi.newpipe.databinding.ActivityRecaptchaBinding;
import org.schabi.newpipe.extractor.utils.Utils;
import org.schabi.newpipe.util.ThemeHelper;
-import java.io.UnsupportedEncodingException;
-
/*
* Created by beneth on 06.12.16.
*
@@ -190,11 +188,10 @@ public class ReCaptchaActivity extends AppCompatActivity {
String abuseCookie = url.substring(abuseStart + 13, abuseEnd);
abuseCookie = Utils.decodeUrlUtf8(abuseCookie);
handleCookies(abuseCookie);
- } catch (UnsupportedEncodingException | StringIndexOutOfBoundsException e) {
+ } catch (IllegalArgumentException | StringIndexOutOfBoundsException e) {
if (MainActivity.DEBUG) {
- e.printStackTrace();
- Log.d(TAG, "handleCookiesFromUrl: invalid google abuse starting at "
- + abuseStart + " and ending at " + abuseEnd + " for url " + url);
+ Log.e(TAG, "handleCookiesFromUrl: invalid google abuse starting at "
+ + abuseStart + " and ending at " + abuseEnd + " for url " + url, e);
}
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java
index 737ebc5dd..c673e688c 100644
--- a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java
+++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java
@@ -38,7 +38,9 @@ public class MediaSessionPlayerUi extends PlayerUi
implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "MediaSessUi";
+ @Nullable
private MediaSessionCompat mediaSession;
+ @Nullable
private MediaSessionConnector sessionConnector;
private final String ignoreHardwareMediaButtonsKey;
@@ -198,6 +200,11 @@ public class MediaSessionPlayerUi extends PlayerUi
return;
}
+ if (sessionConnector == null) {
+ // sessionConnector will be null after destroyPlayer is called
+ return;
+ }
+
// only use the fourth and fifth actions (the settings page also shows only the last 2 on
// Android 13+)
final List newNotificationActions = IntStream.of(3, 4)
diff --git a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
index 472db6afe..76163b30a 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
@@ -30,7 +30,6 @@ import org.schabi.newpipe.util.FilePickerActivityHelper;
import java.io.File;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.net.URI;
public class DownloadSettingsFragment extends BasePreferenceFragment {
@@ -125,7 +124,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
try {
rawUri = decodeUrlUtf8(rawUri);
- } catch (final UnsupportedEncodingException e) {
+ } catch (final IllegalArgumentException e) {
// nothing to do
}
diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md
index 01fa718ad..59ff65db3 100644
--- a/doc/README.pt_BR.md
+++ b/doc/README.pt_BR.md
@@ -1,3 +1,6 @@
+
-*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)*
+*Leia esse documento em outras línguas: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)*
> [!warning]
-> ESTA É UMA VERSÃO BETA, PORTANTO, VOCÊ PODE ENCONTRAR BUGS. ENCONTROU ALGUM, ABRA UM ISSUE ATRAVÉS DO NOSSO REPOSITÓRIO GITHUB.
+> ESTA É UMA VERSÃO BETA, PORTANTO, VOCÊ PODE ENCONTRAR BUGS. ENCONTROU ALGUM, ABRA UM ISSUE ATRAVÉS DO NOSSO REPOSITÓRIO GITHUB PREENCHENDO O MODELO.
>
-> COLOCAR NEWPIPE OU QUALQUER FORK DELE NA GOOGLE PLAY STORE VIOLA SEUS TERMOS E CONDIÇÕES.
+> COLOCAR NEWPIPE, OU QUALQUER FORK DELE, NA GOOGLE PLAY STORE VIOLA SEUS TERMOS E CONDIÇÕES.
## Screenshots
@@ -39,83 +42,84 @@
[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/09.png)
[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/10.png)
-## Descrição
-
-O NewPipe não usa nenhuma biblioteca de framework do Google, nem a API do YouTube. Os sites são apenas analisados para obter informações necessárias, para que este aplicativo possa ser usado em dispositivos sem os serviços do Google instalados. Além disso, você não precisa de uma conta no YouTube para usar o NewPipe, que é um software livre com copyleft.
-
-### Características
-
-* Procurar vídeos
-* Exibir informações gerais sobre vídeos
-* Assista aos vídeos do YouTube
-* Ouça vídeos do YouTube
-* Modo popup (player flutuante)
-* Selecione o player para assistir streaming
-* Baixar vídeos
-* Baixar somente áudio
-* Abrir vídeo no Kodi
-* Mostrar vídeos próximos/relacionados
-* Pesquise no YouTube em um idioma específico
-* Assistir/Bloquear material restrito
-* Exibir informações gerais sobre canais
-* Pesquisar canais
-* Assista a vídeos de um canal
-* Suporte Orbot/Tor (ainda não diretamente)
-* Suporte 1080p/2K/4K
-* Ver histórico
-* Inscreva-se nos canais
-* Procurar histórico
-* Porcurar/Assistir playlists
-* Assistir playlists em fila
-* Vídeos em fila
-* Playlists Local
-* Legenda
-* Suporte a live
-* Mostrar comentários
-
### Serviços Suportados
-O NewPipe suporta vários serviços. Nosso [documentação](https://teamnewpipe.github.io/documentation/) fornecer mais informações sobre como um novo serviço pode ser adicionado ao aplicativo e ao extrator. Por favor, entre em contato conosco se você pretende adicionar um novo. Atualmente, os serviços suportados são:
+Atualmente, os serviços suportados são:
-* YouTube
-* SoundCloud \[beta\]
-* media.ccc.de \[beta\]
-* PeerTube instances \[beta\]
-* Bandcamp \[beta\]
+* YouTube ([site](https://www.youtube.com/)) e YouTube Music ([site](https://music.youtube.com/)) ([wiki](https://en.wikipedia.org/wiki/YouTube))
+* PeerTube ([site](https://joinpeertube.org/)) e todas suas instâncias (abra o site para saber o que isso significa!) ([wiki](https://en.wikipedia.org/wiki/PeerTube))
+* Bandcamp ([site](https://bandcamp.com/)) ([wiki](https://en.wikipedia.org/wiki/Bandcamp))
+* SoundCloud ([site](https://soundcloud.com/)) ([wiki](https://en.wikipedia.org/wiki/SoundCloud))
+* media.ccc.de ([site](https://media.ccc.de/)) ([wiki](https://en.wikipedia.org/wiki/Chaos_Computer_Club))
-## Atualizações
-Quando uma alteração no código NewPipe (devido à adição de recursos ou fixação de bugs), eventualmente ocorrerá uma versão. Estes estão no formato x.xx.x . A fim de obter esta nova versão, você pode:
- 1. Construa um APK de depuração você mesmo. Esta é a maneira mais rápida de obter novos recursos em seu dispositivo, mas é muito mais complicado, por isso recomendamos usar um dos outros métodos.
- 2. Adicione nosso repo personalizado ao F-Droid e instale-o a partir daí assim que publicarmos um lançamento. As instruções estão aqui.: https://newpipe.net/FAQ/tutorials/install-add-fdroid-repo/
- 3. Baixe o APK do [GitHub Releases](https://github.com/TeamNewPipe/NewPipe/releases) e instalá-lo assim que publicarmos um lançamento.
- 4. Atualização via F-droid. Este é o método mais lento para obter atualizações, pois o F-Droid deve reconhecer alterações, construir o próprio APK, assiná-lo e, em seguida, enviar a atualização para os usuários.
+Como você pode ver, o NewPipe suporta múltiplos serviços de vídeo e áudio. Embora tenha começado com o YouTube, outras pessoas adicionaram mais serviços ao longo dos anos, tornando o NewPipe cada vez mais versátil!
-Recomendamos o método 2 para a maioria dos usuários. Os APKs instalados usando o método 2 ou 3 são compatíveis entre si, mas não com aqueles instalados usando o método 4. Isso se deve à mesma chave de assinatura (nossa) sendo usada para 2 e 3, mas uma chave de assinatura diferente (F-Droid's) está sendo usada para 4. Construir um APK depuração usando o método 1 exclui totalmente uma chave. Assinar chaves ajudam a garantir que um usuário não seja enganado para instalar uma atualização maliciosa em um aplicativo.
+Parcialmente devido as circustâncias e a sua popularidade, o YouTube tem o melhor suporte em relação a esses serviços. Se você usa ou é familarizado com qualquer um desses serviços, por favor ajude-nos a melhorar o suporte para eles! Estamos procurando mantenedores para o SoundCloud e o PeerTube.
+
+Se você pretende adicionar um novo serviço, por favor entre em contato conosco primeiro! Nossa [documentação](https://teamnewpipe.github.io/documentation/) traz mais informações em como um novo serviço pode ser adicionado ao aplicativo e no [NewPipe Extractor](https://github.com/TeamNewPipe/NewPipeExtractor).
+
+## Descrição
+
+NewPipe funciona buscando os dados necessários da API oficial (ex. PeerTube) ou do serviço que você está usando. Se a API oficial é restrita (ex. YouTube) para nossos propósitos, ou é proprietária, o aplicativo analisa o site ou usa uma API interna. Isso significa que não é preciso ter uma conta de qualquer serviço para usar o NewPipe.
+
+Também, desde que somos um software livre e de código aberto, nem o aplicativo e nem o Extractor usa qualquer biblioteca ou framework proprietário, como o Google Play Services. Isso significa que você pode usar o NewPipe em dispositivos ou ROMs customizadas em que não tem os aplicativos do Google instalados.
+
+### Recursos
+
+* Assistir vídeos em resoluções de até 4K
+* Escutar o áudio em segundo plano, carregando apenas o fluxo de áudio para salvar dados
+* Modo popup (player flutuante, aka Picture-in-Picture)
+* Assista a transmissões ao vivo
+* Mostrar/esconder legendas/closed captions
+* Buscar vídeos e áudios (no YouTube, você pode especificar o conteúdo da linguagem também)
+* Enfileirar vídeos (e opcionalmente salvar eles como playlists locais)
+* Mostrar/esconder informações gerais sobre os vídeos (como descrições e tags)
+* Mostrar/esconder vídeos próximos/relacionados
+* Mostrar/esconder comentários
+* Buscar vídeos, áudios, canais, playlists e álbuns
+* Navegar vídeos e áudios dentro de um canal
+* Inscrever-se a canais (sim, mesmo se não estiver logado a qualquer conta!)
+* Receba notificações sobre novos vídeos de canais em que você está inscrito
+* Crie e edite grupos de canais (para facilitar a navegação e o gerenciamento)
+* Navege feeds de vídeo gerados a partir dos seus grupos de canais
+* Veja e pesquise seu histórico de vídeos
+* Pesquise e assista playlists (Eles são playlists remotas, o que significa que eles serão obtidos do serviço que você está navegando)
+* Crie e edite playlists locais (Eles são criados e salvos no aplicativo, e não são relacionados com nenhum serviço)
+* Baixe vídeos/áudios/legendas (closed captions)
+* Abra no Kodi
+* Assista/Bloqueie material restrito
+
+## Instalação e atualizações
+Você pode instalar NewPipe com um dos seguintes métodos:
+ 1. Adicione nosso repo personalizado ao F-Droid e instale-o a partir daí. As instruções estão aqui: https://newpipe.net/FAQ/tutorials/install-add-fdroid-repo/
+ 2. Baixe o APK aqui no [GitHub Releases](https://github.com/TeamNewPipe/NewPipe/releases) e instalá-lo assim que publicarmos um lançamento.
+ 3. Atualização via F-droid. Este é o método mais lento para obter atualizações, pois o F-Droid deve reconhecer alterações, construir o próprio APK, assiná-lo e, em seguida, enviar a atualização para os usuários.
+ 4. Construa um APK de depuração você mesmo. Esta é a maneira mais rápida de obter novos recursos em seu dispositivo, mas é muito mais complicado, por isso recomendamos usar um dos outros métodos.
+ 5. Se você estiver interessado em um recurso específico ou uma correção de bug fornecido em uma solicitação de Pull nesse repositório, pode instalar o APK a partir de lá. Leia a descrição da solicitação para instruções. A grande vantagem dos APKs específicos de S.P é que eles são instalados lado a lado com o aplicativo oficial, então você não precisa se preocupar em perder seus dados ou estragar alguma coisa.
+
+Recomendamos o método 1 para a maioria dos usuários. Os APKs instalados usando o método 1 ou 2 são compatíveis entre si (o que significa que se você instalou o NewPipe usando o método 1 ou 2, você também pode atualizar o NewPipe usando o outro), mas não com aqueles instalados usando o método 3. Isso se deve à mesma chave de assinatura (nossa) sendo usada para 1 e 2, mas uma chave de assinatura diferente (F-Droid's) está sendo usada para 3. Construir um APK depuração usando o método 4 exclui totalmente uma chave. Assinar chaves ajudam a garantir que um usuário não seja enganado para instalar uma atualização maliciosa em um aplicativo. Ao usar o método 5, cada APK é assinado com uma chave aleatória diferente fornecida pelo GitHub Actions, portanto você não pode nem mesmo atualizá-lo. Você terá que fazer backup e restaurar os dados do aplicativo sempre que desejar usar um novo APK.
Enquanto isso, se você quiser trocar de fontes por algum motivo (por exemplo, a funcionalidade principal do NewPipe foi quebrada e o F-Droid ainda não tem a atualização), recomendamos seguir este procedimento:
-1. Faça backup de seus dados através de Configurações > Conteúdo > Exportar Base de Dados para que você mantenha seu histórico, inscrições e playlists
+1. Faça backup de seus dados através de Configurações > Backup e Restauração > Exportar Base de Dados para que você mantenha seu histórico, inscrições e playlists
2. Desinstale o NewPipe
3. Baixe o APK da nova fonte e instale-o
-4. Importe os dados da etapa 1 via Configurações > Conteúdo > Inportar Banco de Dados
+4. Importe os dados da etapa 1 via Configurações > Backup e Restauração > Importar Base de Dados
-## Contribuição
-Se você tem ideias, traduções, alterações de design, limpeza de códigos ou mudanças reais de código, a ajuda é sempre bem-vinda.
-Quanto mais for feito, melhor fica!
-
-Se você quiser se envolver, verifique nossa [notas de contribuição](../.github/CONTRIBUTING.md).
+## Contribuições
+Se você tem ideias, traduções, alterações de design, limpeza de códigos ou mudanças reais de código, a ajuda é sempre bem-vinda. O aplicativo fica cada vez melhor a cada contribuição, não importa quão grande ou pequena! Se você quiser se envolver, verifique nossas [notas de contribuição](.github/CONTRIBUTING.md).
-
+
## Doar
-Se você gosta de NewPipe, ficaríamos felizes com uma doação. Você pode enviar bitcoin ou doar via Bountysource ou Liberapay. Para obter mais informações sobre como doar para a NewPipe, visite nosso [site](https://newpipe.net/donate).
+Se você gosta do NewPipe, pode enivar uma doação. Nós preferimos Liberapay, pois é de código aberto e sem fins lucrativos. Para mais informações sobre como doar para o NewPipe, visite nosso [site](https://newpipe.net/donate).
-
-
+
+
diff --git a/fastlane/metadata/android/ar/changelogs/998.txt b/fastlane/metadata/android/ar/changelogs/998.txt
new file mode 100644
index 000000000..562f16944
--- /dev/null
+++ b/fastlane/metadata/android/ar/changelogs/998.txt
@@ -0,0 +1 @@
+تم إصلاح YouTube الذي لا يقوم بتشغيل أي دفق
diff --git a/fastlane/metadata/android/ar/changelogs/999.txt b/fastlane/metadata/android/ar/changelogs/999.txt
new file mode 100644
index 000000000..562f16944
--- /dev/null
+++ b/fastlane/metadata/android/ar/changelogs/999.txt
@@ -0,0 +1 @@
+تم إصلاح YouTube الذي لا يقوم بتشغيل أي دفق
diff --git a/fastlane/metadata/android/az/changelogs/998.txt b/fastlane/metadata/android/az/changelogs/998.txt
new file mode 100644
index 000000000..16a2e1013
--- /dev/null
+++ b/fastlane/metadata/android/az/changelogs/998.txt
@@ -0,0 +1 @@
+YouTube-un heç bir yayım oynatmaması düzəldildi
diff --git a/fastlane/metadata/android/az/changelogs/999.txt b/fastlane/metadata/android/az/changelogs/999.txt
new file mode 100644
index 000000000..16a2e1013
--- /dev/null
+++ b/fastlane/metadata/android/az/changelogs/999.txt
@@ -0,0 +1 @@
+YouTube-un heç bir yayım oynatmaması düzəldildi
diff --git a/fastlane/metadata/android/cs/changelogs/998.txt b/fastlane/metadata/android/cs/changelogs/998.txt
new file mode 100644
index 000000000..7035a1112
--- /dev/null
+++ b/fastlane/metadata/android/cs/changelogs/998.txt
@@ -0,0 +1 @@
+Opraveno nepřehrávání jakéhokoli streamu ve službě YouTube
diff --git a/fastlane/metadata/android/cs/changelogs/999.txt b/fastlane/metadata/android/cs/changelogs/999.txt
new file mode 100644
index 000000000..7035a1112
--- /dev/null
+++ b/fastlane/metadata/android/cs/changelogs/999.txt
@@ -0,0 +1 @@
+Opraveno nepřehrávání jakéhokoli streamu ve službě YouTube
diff --git a/fastlane/metadata/android/de/changelogs/998.txt b/fastlane/metadata/android/de/changelogs/998.txt
new file mode 100644
index 000000000..43623578f
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/998.txt
@@ -0,0 +1 @@
+Behoben, dass YouTube keinen Stream abspielte
diff --git a/fastlane/metadata/android/de/changelogs/999.txt b/fastlane/metadata/android/de/changelogs/999.txt
new file mode 100644
index 000000000..43623578f
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/999.txt
@@ -0,0 +1 @@
+Behoben, dass YouTube keinen Stream abspielte
diff --git a/fastlane/metadata/android/en-US/changelogs/998.txt b/fastlane/metadata/android/en-US/changelogs/998.txt
new file mode 100644
index 000000000..468df0204
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/998.txt
@@ -0,0 +1,4 @@
+Fixed YouTube not playing any stream because of HTTP 403 errors.
+
+Occasional HTTP 403 errors in the middle of a YouTube video are not fixed yet.
+That issue will be addressed in another hotfix release as soon as possible.
diff --git a/fastlane/metadata/android/en-US/changelogs/999.txt b/fastlane/metadata/android/en-US/changelogs/999.txt
new file mode 100644
index 000000000..c089ed197
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/999.txt
@@ -0,0 +1,12 @@
+This hotfix release fixes HTTP 403 errors in the middle of YouTube videos.
+
+New
+• [SoundCloud] Add support for on.soundcloud.com URLs
+
+Improved
+• [Bandcamp] Show additional info in radio kiosk
+
+Fixed
+• [YouTube] Fix occasional HTTP 403 errors at the beginning or in the middle of videos
+• [YouTube] Extract avatar and banner from more channel header types
+• [Bandcamp] Fix various bugs and always use HTTPS
diff --git a/fastlane/metadata/android/es/changelogs/998.txt b/fastlane/metadata/android/es/changelogs/998.txt
new file mode 100644
index 000000000..80b4efa55
--- /dev/null
+++ b/fastlane/metadata/android/es/changelogs/998.txt
@@ -0,0 +1 @@
+Arreglo en YouTube no reproduciendo flujos
diff --git a/fastlane/metadata/android/es/changelogs/999.txt b/fastlane/metadata/android/es/changelogs/999.txt
new file mode 100644
index 000000000..80b4efa55
--- /dev/null
+++ b/fastlane/metadata/android/es/changelogs/999.txt
@@ -0,0 +1 @@
+Arreglo en YouTube no reproduciendo flujos
diff --git a/fastlane/metadata/android/fa/changelogs/998.txt b/fastlane/metadata/android/fa/changelogs/998.txt
new file mode 100644
index 000000000..ba5413d49
--- /dev/null
+++ b/fastlane/metadata/android/fa/changelogs/998.txt
@@ -0,0 +1 @@
+مشکل عدم نمایش پخشزنده برطرف شد
diff --git a/fastlane/metadata/android/fa/changelogs/999.txt b/fastlane/metadata/android/fa/changelogs/999.txt
new file mode 100644
index 000000000..ba5413d49
--- /dev/null
+++ b/fastlane/metadata/android/fa/changelogs/999.txt
@@ -0,0 +1 @@
+مشکل عدم نمایش پخشزنده برطرف شد
diff --git a/fastlane/metadata/android/fr/changelogs/998.txt b/fastlane/metadata/android/fr/changelogs/998.txt
new file mode 100644
index 000000000..3ad3bf279
--- /dev/null
+++ b/fastlane/metadata/android/fr/changelogs/998.txt
@@ -0,0 +1 @@
+Correction de YouTube qui ne lisait aucun média
diff --git a/fastlane/metadata/android/fr/changelogs/999.txt b/fastlane/metadata/android/fr/changelogs/999.txt
new file mode 100644
index 000000000..3ad3bf279
--- /dev/null
+++ b/fastlane/metadata/android/fr/changelogs/999.txt
@@ -0,0 +1 @@
+Correction de YouTube qui ne lisait aucun média
diff --git a/fastlane/metadata/android/he/changelogs/998.txt b/fastlane/metadata/android/he/changelogs/998.txt
new file mode 100644
index 000000000..50731171e
--- /dev/null
+++ b/fastlane/metadata/android/he/changelogs/998.txt
@@ -0,0 +1 @@
+תוקנה התקלה ש־YouTube לא מנגן אף תזרים
diff --git a/fastlane/metadata/android/he/changelogs/999.txt b/fastlane/metadata/android/he/changelogs/999.txt
new file mode 100644
index 000000000..50731171e
--- /dev/null
+++ b/fastlane/metadata/android/he/changelogs/999.txt
@@ -0,0 +1 @@
+תוקנה התקלה ש־YouTube לא מנגן אף תזרים
diff --git a/fastlane/metadata/android/hi/changelogs/998.txt b/fastlane/metadata/android/hi/changelogs/998.txt
new file mode 100644
index 000000000..071ab64e3
--- /dev/null
+++ b/fastlane/metadata/android/hi/changelogs/998.txt
@@ -0,0 +1 @@
+फिक्स्ड YouTube कोई स्ट्रीम नहीं चला रहा है
diff --git a/fastlane/metadata/android/hi/changelogs/999.txt b/fastlane/metadata/android/hi/changelogs/999.txt
new file mode 100644
index 000000000..071ab64e3
--- /dev/null
+++ b/fastlane/metadata/android/hi/changelogs/999.txt
@@ -0,0 +1 @@
+फिक्स्ड YouTube कोई स्ट्रीम नहीं चला रहा है
diff --git a/fastlane/metadata/android/id/changelogs/998.txt b/fastlane/metadata/android/id/changelogs/998.txt
new file mode 100644
index 000000000..d3fea84ab
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/998.txt
@@ -0,0 +1 @@
+Memperbaiki YouTube yang tidak memutar streaming apa pun
diff --git a/fastlane/metadata/android/id/changelogs/999.txt b/fastlane/metadata/android/id/changelogs/999.txt
new file mode 100644
index 000000000..d3fea84ab
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/999.txt
@@ -0,0 +1 @@
+Memperbaiki YouTube yang tidak memutar streaming apa pun
diff --git a/fastlane/metadata/android/it/changelogs/998.txt b/fastlane/metadata/android/it/changelogs/998.txt
new file mode 100644
index 000000000..73fc6f2d8
--- /dev/null
+++ b/fastlane/metadata/android/it/changelogs/998.txt
@@ -0,0 +1,4 @@
+Corretto problema di riproduzione di YouTube causato da errori HTTP 403.
+
+Gli errori HTTP 403 saltuari nel mezzo di un video di YouTube non sono ancora stati sistemati.
+Questo problema sarà affrontato in un altra release hotfix non appena possibile.
diff --git a/fastlane/metadata/android/it/changelogs/999.txt b/fastlane/metadata/android/it/changelogs/999.txt
new file mode 100644
index 000000000..c2652da28
--- /dev/null
+++ b/fastlane/metadata/android/it/changelogs/999.txt
@@ -0,0 +1,12 @@
+Questo aggiornamento hotfix risolve gli errori HTTP 403 nel mezzo dei video di YouTube.
+
+Novità
+• [SoundCloud] Aggiunto il supporto per gli URL on.soundcloud.com
+
+Migliorie
+• [Bandcamp] Mostra informazioni aggiuntive nel chiosco della radio
+
+Correzioni
+• [YouTube] Corretti errori HTTP 403 occasionali all'inizio o nel mezzo dei video
+• [YouTube] Estrazione avatar e banner da più tipi di canali
+• [Bandcamp] Risolti vari bug e forzato l'uso di HTTPS
diff --git a/fastlane/metadata/android/ka/changelogs/998.txt b/fastlane/metadata/android/ka/changelogs/998.txt
new file mode 100644
index 000000000..d20512f17
--- /dev/null
+++ b/fastlane/metadata/android/ka/changelogs/998.txt
@@ -0,0 +1 @@
+გაასწორა YouTube არ უკრავს არცერთ ნაკადს
diff --git a/fastlane/metadata/android/ka/changelogs/999.txt b/fastlane/metadata/android/ka/changelogs/999.txt
new file mode 100644
index 000000000..d20512f17
--- /dev/null
+++ b/fastlane/metadata/android/ka/changelogs/999.txt
@@ -0,0 +1 @@
+გაასწორა YouTube არ უკრავს არცერთ ნაკადს
diff --git a/fastlane/metadata/android/nl/changelogs/998.txt b/fastlane/metadata/android/nl/changelogs/998.txt
new file mode 100644
index 000000000..9bd8adf86
--- /dev/null
+++ b/fastlane/metadata/android/nl/changelogs/998.txt
@@ -0,0 +1 @@
+YouTube speelt geen stream af opgelost
diff --git a/fastlane/metadata/android/nl/changelogs/999.txt b/fastlane/metadata/android/nl/changelogs/999.txt
new file mode 100644
index 000000000..9bd8adf86
--- /dev/null
+++ b/fastlane/metadata/android/nl/changelogs/999.txt
@@ -0,0 +1 @@
+YouTube speelt geen stream af opgelost
diff --git a/fastlane/metadata/android/pa/changelogs/998.txt b/fastlane/metadata/android/pa/changelogs/998.txt
new file mode 100644
index 000000000..fe62a1330
--- /dev/null
+++ b/fastlane/metadata/android/pa/changelogs/998.txt
@@ -0,0 +1 @@
+ਸਥਿਰ YouTube ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਚਲਾ ਰਿਹਾ
diff --git a/fastlane/metadata/android/pa/changelogs/999.txt b/fastlane/metadata/android/pa/changelogs/999.txt
new file mode 100644
index 000000000..fe62a1330
--- /dev/null
+++ b/fastlane/metadata/android/pa/changelogs/999.txt
@@ -0,0 +1 @@
+ਸਥਿਰ YouTube ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਚਲਾ ਰਿਹਾ
diff --git a/fastlane/metadata/android/pt-BR/changelogs/998.txt b/fastlane/metadata/android/pt-BR/changelogs/998.txt
new file mode 100644
index 000000000..59fc6a5cd
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/998.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir qualquer transmissão
diff --git a/fastlane/metadata/android/pt-BR/changelogs/999.txt b/fastlane/metadata/android/pt-BR/changelogs/999.txt
new file mode 100644
index 000000000..59fc6a5cd
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/999.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir qualquer transmissão
diff --git a/fastlane/metadata/android/pt-PT/changelogs/998.txt b/fastlane/metadata/android/pt-PT/changelogs/998.txt
new file mode 100644
index 000000000..93519d64d
--- /dev/null
+++ b/fastlane/metadata/android/pt-PT/changelogs/998.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir nenhuma transmissão
diff --git a/fastlane/metadata/android/pt-PT/changelogs/999.txt b/fastlane/metadata/android/pt-PT/changelogs/999.txt
new file mode 100644
index 000000000..93519d64d
--- /dev/null
+++ b/fastlane/metadata/android/pt-PT/changelogs/999.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir nenhuma transmissão
diff --git a/fastlane/metadata/android/pt/changelogs/998.txt b/fastlane/metadata/android/pt/changelogs/998.txt
new file mode 100644
index 000000000..93519d64d
--- /dev/null
+++ b/fastlane/metadata/android/pt/changelogs/998.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir nenhuma transmissão
diff --git a/fastlane/metadata/android/pt/changelogs/999.txt b/fastlane/metadata/android/pt/changelogs/999.txt
new file mode 100644
index 000000000..93519d64d
--- /dev/null
+++ b/fastlane/metadata/android/pt/changelogs/999.txt
@@ -0,0 +1 @@
+Corrigido YouTube não reproduzir nenhuma transmissão
diff --git a/fastlane/metadata/android/ru/changelogs/998.txt b/fastlane/metadata/android/ru/changelogs/998.txt
new file mode 100644
index 000000000..d3978869d
--- /dev/null
+++ b/fastlane/metadata/android/ru/changelogs/998.txt
@@ -0,0 +1 @@
+Исправлено: YouTube не воспроизводил никакие потоки
diff --git a/fastlane/metadata/android/ru/changelogs/999.txt b/fastlane/metadata/android/ru/changelogs/999.txt
new file mode 100644
index 000000000..d3978869d
--- /dev/null
+++ b/fastlane/metadata/android/ru/changelogs/999.txt
@@ -0,0 +1 @@
+Исправлено: YouTube не воспроизводил никакие потоки
diff --git a/fastlane/metadata/android/sv/changelogs/998.txt b/fastlane/metadata/android/sv/changelogs/998.txt
new file mode 100644
index 000000000..35f298dbf
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/998.txt
@@ -0,0 +1 @@
+Åtgärdat att YouTube inte spelar någon stream
diff --git a/fastlane/metadata/android/sv/changelogs/999.txt b/fastlane/metadata/android/sv/changelogs/999.txt
new file mode 100644
index 000000000..35f298dbf
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/999.txt
@@ -0,0 +1 @@
+Åtgärdat att YouTube inte spelar någon stream
diff --git a/fastlane/metadata/android/tr/changelogs/998.txt b/fastlane/metadata/android/tr/changelogs/998.txt
new file mode 100644
index 000000000..e5979c68d
--- /dev/null
+++ b/fastlane/metadata/android/tr/changelogs/998.txt
@@ -0,0 +1 @@
+YouTube'un herhangi bir akışı oynatmaması düzeltildi
diff --git a/fastlane/metadata/android/tr/changelogs/999.txt b/fastlane/metadata/android/tr/changelogs/999.txt
new file mode 100644
index 000000000..e5979c68d
--- /dev/null
+++ b/fastlane/metadata/android/tr/changelogs/999.txt
@@ -0,0 +1 @@
+YouTube'un herhangi bir akışı oynatmaması düzeltildi
diff --git a/fastlane/metadata/android/uk/changelogs/998.txt b/fastlane/metadata/android/uk/changelogs/998.txt
new file mode 100644
index 000000000..905287c74
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/998.txt
@@ -0,0 +1 @@
+Виправлено проблему невідтворюваності трансляцій
diff --git a/fastlane/metadata/android/uk/changelogs/999.txt b/fastlane/metadata/android/uk/changelogs/999.txt
new file mode 100644
index 000000000..905287c74
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/999.txt
@@ -0,0 +1 @@
+Виправлено проблему невідтворюваності трансляцій
diff --git a/fastlane/metadata/android/vi/changelogs/998.txt b/fastlane/metadata/android/vi/changelogs/998.txt
new file mode 100644
index 000000000..d2086b62c
--- /dev/null
+++ b/fastlane/metadata/android/vi/changelogs/998.txt
@@ -0,0 +1 @@
+Đã sửa lỗi YouTube không phát bất kỳ luồng nào
diff --git a/fastlane/metadata/android/vi/changelogs/999.txt b/fastlane/metadata/android/vi/changelogs/999.txt
new file mode 100644
index 000000000..d2086b62c
--- /dev/null
+++ b/fastlane/metadata/android/vi/changelogs/999.txt
@@ -0,0 +1 @@
+Đã sửa lỗi YouTube không phát bất kỳ luồng nào
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/998.txt b/fastlane/metadata/android/zh-Hans/changelogs/998.txt
new file mode 100644
index 000000000..8a5424c9e
--- /dev/null
+++ b/fastlane/metadata/android/zh-Hans/changelogs/998.txt
@@ -0,0 +1 @@
+修复YouTube无法播放任何视频
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/999.txt b/fastlane/metadata/android/zh-Hans/changelogs/999.txt
new file mode 100644
index 000000000..8a5424c9e
--- /dev/null
+++ b/fastlane/metadata/android/zh-Hans/changelogs/999.txt
@@ -0,0 +1 @@
+修复YouTube无法播放任何视频
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/998.txt b/fastlane/metadata/android/zh-Hant/changelogs/998.txt
new file mode 100644
index 000000000..4e8bf6537
--- /dev/null
+++ b/fastlane/metadata/android/zh-Hant/changelogs/998.txt
@@ -0,0 +1 @@
+修正 YouTube 無法播放任何串流
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/999.txt b/fastlane/metadata/android/zh-Hant/changelogs/999.txt
new file mode 100644
index 000000000..4e8bf6537
--- /dev/null
+++ b/fastlane/metadata/android/zh-Hant/changelogs/999.txt
@@ -0,0 +1 @@
+修正 YouTube 無法播放任何串流
diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/998.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/998.txt
new file mode 100644
index 000000000..9a4721551
--- /dev/null
+++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/998.txt
@@ -0,0 +1 @@
+修正咗 YouTube 乜嘢實況串流都播唔到嘅問題
diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/999.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/999.txt
new file mode 100644
index 000000000..9a4721551
--- /dev/null
+++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/999.txt
@@ -0,0 +1 @@
+修正咗 YouTube 乜嘢實況串流都播唔到嘅問題
From 05271d95a920a7b8bb7e3e45e5d6ef1aa43ce0e0 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Sat, 13 Jul 2024 20:01:07 +0530
Subject: [PATCH 016/134] Migrate about activity to Jetpack Compose
---
app/build.gradle | 11 +-
.../org/schabi/newpipe/about/AboutActivity.kt | 195 ++----------------
.../org/schabi/newpipe/about/AboutClasses.kt | 28 +++
.../org/schabi/newpipe/about/AboutScreen.kt | 96 +++++++++
.../java/org/schabi/newpipe/about/AboutTab.kt | 95 +++++++++
.../java/org/schabi/newpipe/about/License.kt | 11 -
.../schabi/newpipe/about/LicenseFragment.kt | 140 -------------
.../newpipe/about/LicenseFragmentHelper.kt | 52 -----
.../org/schabi/newpipe/about/LicenseTab.kt | 184 +++++++++++++++++
.../schabi/newpipe/about/SoftwareComponent.kt | 17 --
.../schabi/newpipe/{ui => compose}/Toolbar.kt | 6 +-
.../compose/screen/ScaffoldWithToolbar.kt | 40 ++++
.../newpipe/{ui => compose}/theme/Color.kt | 2 +-
.../{ui => compose}/theme/SizeTokens.kt | 2 +-
.../newpipe/{ui => compose}/theme/Theme.kt | 2 +-
.../java/org/schabi/newpipe/ktx/Bundle.kt | 9 -
app/src/main/res/layout/activity_about.xml | 39 ----
app/src/main/res/layout/fragment_about.xml | 148 -------------
app/src/main/res/layout/fragment_licenses.xml | 55 -----
.../res/layout/item_software_component.xml | 28 ---
build.gradle | 2 +-
21 files changed, 467 insertions(+), 695 deletions(-)
create mode 100644 app/src/main/java/org/schabi/newpipe/about/AboutClasses.kt
create mode 100644 app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt
create mode 100644 app/src/main/java/org/schabi/newpipe/about/AboutTab.kt
delete mode 100644 app/src/main/java/org/schabi/newpipe/about/License.kt
delete mode 100644 app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt
delete mode 100644 app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt
create mode 100644 app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt
delete mode 100644 app/src/main/java/org/schabi/newpipe/about/SoftwareComponent.kt
rename app/src/main/java/org/schabi/newpipe/{ui => compose}/Toolbar.kt (97%)
create mode 100644 app/src/main/java/org/schabi/newpipe/compose/screen/ScaffoldWithToolbar.kt
rename app/src/main/java/org/schabi/newpipe/{ui => compose}/theme/Color.kt (98%)
rename app/src/main/java/org/schabi/newpipe/{ui => compose}/theme/SizeTokens.kt (88%)
rename app/src/main/java/org/schabi/newpipe/{ui => compose}/theme/Theme.kt (98%)
delete mode 100644 app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt
delete mode 100644 app/src/main/res/layout/activity_about.xml
delete mode 100644 app/src/main/res/layout/fragment_about.xml
delete mode 100644 app/src/main/res/layout/fragment_licenses.xml
delete mode 100644 app/src/main/res/layout/item_software_component.xml
diff --git a/app/build.gradle b/app/build.gradle
index 9ea725ad9..50c08f883 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -106,7 +106,7 @@ android {
}
composeOptions {
- kotlinCompilerExtensionVersion = "1.5.3"
+ kotlinCompilerExtensionVersion = "1.5.14"
}
}
@@ -230,9 +230,6 @@ dependencies {
implementation "androidx.room:room-rxjava3:${androidxRoomVersion}"
kapt "androidx.room:room-compiler:${androidxRoomVersion}"
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
- // Newer version specified to prevent accessibility regressions with RecyclerView, see:
- // https://developer.android.com/jetpack/androidx/releases/viewpager2#1.1.0-alpha01
- implementation 'androidx.viewpager2:viewpager2:1.1.0-beta02'
implementation "androidx.work:work-runtime-ktx:${androidxWorkVersion}"
implementation "androidx.work:work-rxjava3:${androidxWorkVersion}"
implementation 'com.google.android.material:material:1.11.0'
@@ -289,10 +286,12 @@ dependencies {
implementation "org.ocpsoft.prettytime:prettytime:5.0.8.Final"
// Jetpack Compose
- implementation(platform('androidx.compose:compose-bom:2024.02.01'))
- implementation 'androidx.compose.material3:material3'
+ implementation(platform('androidx.compose:compose-bom:2024.06.00'))
+ implementation 'androidx.compose.material3:material3:1.3.0-beta04'
implementation 'androidx.activity:activity-compose'
implementation 'androidx.compose.ui:ui-tooling-preview'
+ implementation 'androidx.compose.ui:ui-text:1.7.0-beta05' // Needed for parsing HTML to AnnotatedString
+ implementation 'com.github.nanihadesuka:LazyColumnScrollbar:2.2.0'
/** Debugging **/
// Memory leak detection
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
index 0d0d0d48d..0741c272a 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
@@ -1,199 +1,28 @@
package org.schabi.newpipe.about
import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Button
-import androidx.annotation.StringRes
+import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentActivity
-import androidx.viewpager2.adapter.FragmentStateAdapter
-import com.google.android.material.tabs.TabLayoutMediator
-import org.schabi.newpipe.BuildConfig
+import androidx.compose.ui.res.stringResource
import org.schabi.newpipe.R
-import org.schabi.newpipe.databinding.ActivityAboutBinding
-import org.schabi.newpipe.databinding.FragmentAboutBinding
+import org.schabi.newpipe.compose.screen.ScaffoldWithToolbar
+import org.schabi.newpipe.compose.theme.AppTheme
import org.schabi.newpipe.util.Localization
-import org.schabi.newpipe.util.ThemeHelper
-import org.schabi.newpipe.util.external_communication.ShareUtils
class AboutActivity : AppCompatActivity() {
-
override fun onCreate(savedInstanceState: Bundle?) {
Localization.assureCorrectAppLanguage(this)
super.onCreate(savedInstanceState)
- ThemeHelper.setTheme(this)
- title = getString(R.string.title_activity_about)
- val aboutBinding = ActivityAboutBinding.inflate(layoutInflater)
- setContentView(aboutBinding.root)
- setSupportActionBar(aboutBinding.aboutToolbar)
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
-
- // Create the adapter that will return a fragment for each of the three
- // primary sections of the activity.
- val mAboutStateAdapter = AboutStateAdapter(this)
- // Set up the ViewPager with the sections adapter.
- aboutBinding.aboutViewPager2.adapter = mAboutStateAdapter
- TabLayoutMediator(
- aboutBinding.aboutTabLayout,
- aboutBinding.aboutViewPager2
- ) { tab, position ->
- tab.setText(mAboutStateAdapter.getPageTitle(position))
- }.attach()
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == android.R.id.home) {
- finish()
- return true
- }
- return super.onOptionsItemSelected(item)
- }
-
- /**
- * A placeholder fragment containing a simple view.
- */
- class AboutFragment : Fragment() {
- private fun Button.openLink(@StringRes url: Int) {
- setOnClickListener {
- ShareUtils.openUrlInApp(context, requireContext().getString(url))
+ setContent {
+ AppTheme {
+ ScaffoldWithToolbar(
+ title = stringResource(R.string.title_activity_about),
+ onBackClick = { onBackPressedDispatcher.onBackPressed() }
+ ) { padding ->
+ AboutScreen(padding)
+ }
}
}
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- FragmentAboutBinding.inflate(inflater, container, false).apply {
- aboutAppVersion.text = BuildConfig.VERSION_NAME
- aboutGithubLink.openLink(R.string.github_url)
- aboutDonationLink.openLink(R.string.donation_url)
- aboutWebsiteLink.openLink(R.string.website_url)
- aboutPrivacyPolicyLink.openLink(R.string.privacy_policy_url)
- faqLink.openLink(R.string.faq_url)
- return root
- }
- }
- }
-
- /**
- * A [FragmentStateAdapter] that returns a fragment corresponding to
- * one of the sections/tabs/pages.
- */
- private class AboutStateAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
- private val posAbout = 0
- private val posLicense = 1
- private val totalCount = 2
-
- override fun createFragment(position: Int): Fragment {
- return when (position) {
- posAbout -> AboutFragment()
- posLicense -> LicenseFragment.newInstance(SOFTWARE_COMPONENTS)
- else -> throw IllegalArgumentException("Unknown position for ViewPager2")
- }
- }
-
- override fun getItemCount(): Int {
- // Show 2 total pages.
- return totalCount
- }
-
- fun getPageTitle(position: Int): Int {
- return when (position) {
- posAbout -> R.string.tab_about
- posLicense -> R.string.tab_licenses
- else -> throw IllegalArgumentException("Unknown position for ViewPager2")
- }
- }
- }
-
- companion object {
- /**
- * List of all software components.
- */
- private val SOFTWARE_COMPONENTS = arrayListOf(
- SoftwareComponent(
- "ACRA", "2013", "Kevin Gaudin",
- "https://github.com/ACRA/acra", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "AndroidX", "2005 - 2011", "The Android Open Source Project",
- "https://developer.android.com/jetpack", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "ExoPlayer", "2014 - 2020", "Google, Inc.",
- "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "GigaGet", "2014 - 2015", "Peter Cai",
- "https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL3
- ),
- SoftwareComponent(
- "Groupie", "2016", "Lisa Wray",
- "https://github.com/lisawray/groupie", StandardLicenses.MIT
- ),
- SoftwareComponent(
- "Icepick", "2015", "Frankie Sardo",
- "https://github.com/frankiesardo/icepick", StandardLicenses.EPL1
- ),
- SoftwareComponent(
- "Jsoup", "2009 - 2020", "Jonathan Hedley",
- "https://github.com/jhy/jsoup", StandardLicenses.MIT
- ),
- SoftwareComponent(
- "Markwon", "2019", "Dimitry Ivanov",
- "https://github.com/noties/Markwon", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "Material Components for Android", "2016 - 2020", "Google, Inc.",
- "https://github.com/material-components/material-components-android",
- StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "NewPipe Extractor", "2017 - 2020", "Christian Schabesberger",
- "https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3
- ),
- SoftwareComponent(
- "NoNonsense-FilePicker", "2016", "Jonas Kalderstam",
- "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2
- ),
- SoftwareComponent(
- "OkHttp", "2019", "Square, Inc.",
- "https://square.github.io/okhttp/", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "Coil", "2023", "Coil Contributors",
- "https://coil-kt.github.io/coil/", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "PrettyTime", "2012 - 2020", "Lincoln Baxter, III",
- "https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "ProcessPhoenix", "2015", "Jake Wharton",
- "https://github.com/JakeWharton/ProcessPhoenix", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "RxAndroid", "2015", "The RxAndroid authors",
- "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "RxBinding", "2015", "Jake Wharton",
- "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "RxJava", "2016 - 2020", "RxJava Contributors",
- "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2
- ),
- SoftwareComponent(
- "SearchPreference", "2018", "ByteHamster",
- "https://github.com/ByteHamster/SearchPreference", StandardLicenses.MIT
- ),
- )
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutClasses.kt b/app/src/main/java/org/schabi/newpipe/about/AboutClasses.kt
new file mode 100644
index 000000000..bacd944c6
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutClasses.kt
@@ -0,0 +1,28 @@
+package org.schabi.newpipe.about
+
+import android.content.Context
+import androidx.annotation.StringRes
+
+class AboutData(
+ @StringRes val title: Int,
+ @StringRes val description: Int,
+ @StringRes val buttonText: Int,
+ @StringRes val url: Int
+)
+
+/**
+ * Class for storing information about a software license.
+ */
+class License(val name: String, val abbreviation: String, val filename: String) {
+ fun getFormattedLicense(context: Context): String {
+ return context.assets.open(filename).bufferedReader().use { it.readText() }
+ }
+}
+
+class SoftwareComponent(
+ val name: String,
+ val years: String,
+ val copyrightOwner: String,
+ val link: String,
+ val license: License
+)
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt b/app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt
new file mode 100644
index 000000000..088380f74
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt
@@ -0,0 +1,96 @@
+package org.schabi.newpipe.about
+
+import android.content.res.Configuration
+import androidx.collection.intListOf
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.pager.HorizontalPager
+import androidx.compose.foundation.pager.rememberPagerState
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Tab
+import androidx.compose.material3.TabRow
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.NonRestartableComposable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import my.nanihadesuka.compose.ColumnScrollbar
+import org.schabi.newpipe.R
+import org.schabi.newpipe.compose.theme.AppTheme
+
+private val TITLES = intListOf(R.string.tab_about, R.string.tab_licenses)
+
+@Composable
+@NonRestartableComposable
+fun AboutScreen(padding: PaddingValues) {
+ Column(modifier = Modifier.padding(padding)) {
+ var tabIndex by rememberSaveable { mutableIntStateOf(0) }
+ val pagerState = rememberPagerState { TITLES.size }
+
+ LaunchedEffect(tabIndex) {
+ pagerState.animateScrollToPage(tabIndex)
+ }
+ LaunchedEffect(pagerState.currentPage) {
+ tabIndex = pagerState.currentPage
+ }
+
+ TabRow(selectedTabIndex = tabIndex) {
+ TITLES.forEachIndexed { index, titleId ->
+ Tab(
+ text = { Text(text = stringResource(titleId)) },
+ selected = tabIndex == index,
+ onClick = { tabIndex = index }
+ )
+ }
+ }
+
+ HorizontalPager(
+ state = pagerState,
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(1f)
+ ) { page ->
+ val scrollState = rememberScrollState()
+
+ ColumnScrollbar(state = scrollState) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 20.dp, vertical = 10.dp)
+ .verticalScroll(scrollState),
+ verticalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ if (page == 0) {
+ AboutTab()
+ } else {
+ LicenseTab()
+ }
+ }
+ }
+ }
+ }
+}
+
+@Preview(name = "Light mode", uiMode = Configuration.UI_MODE_NIGHT_NO)
+@Preview(name = "Dark mode", uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun AboutScreenPreview() {
+ AppTheme {
+ Surface(color = MaterialTheme.colorScheme.background) {
+ AboutScreen(PaddingValues(8.dp))
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutTab.kt b/app/src/main/java/org/schabi/newpipe/about/AboutTab.kt
new file mode 100644
index 000000000..f391c7790
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutTab.kt
@@ -0,0 +1,95 @@
+package org.schabi.newpipe.about
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.NonRestartableComposable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import org.schabi.newpipe.BuildConfig
+import org.schabi.newpipe.R
+import org.schabi.newpipe.util.external_communication.ShareUtils
+
+private val ABOUT_ITEMS = listOf(
+ AboutData(R.string.faq_title, R.string.faq_description, R.string.faq, R.string.faq_url),
+ AboutData(
+ R.string.contribution_title, R.string.contribution_encouragement,
+ R.string.view_on_github, R.string.github_url
+ ),
+ AboutData(
+ R.string.donation_title, R.string.donation_encouragement, R.string.give_back,
+ R.string.donation_url
+ ),
+ AboutData(
+ R.string.website_title, R.string.website_encouragement, R.string.open_in_browser,
+ R.string.website_url
+ ),
+ AboutData(
+ R.string.privacy_policy_title, R.string.privacy_policy_encouragement,
+ R.string.read_privacy_policy, R.string.privacy_policy_url
+ )
+)
+
+@Composable
+@NonRestartableComposable
+fun AboutTab() {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentSize(Alignment.Center),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Image(
+ painter = painterResource(R.mipmap.ic_launcher_foreground),
+ contentDescription = stringResource(R.string.app_name),
+ modifier = Modifier
+ .clip(CircleShape)
+ .background(Color.Red)
+ )
+ Text(
+ style = MaterialTheme.typography.titleLarge,
+ text = stringResource(R.string.app_name)
+ )
+ Text(text = BuildConfig.VERSION_NAME)
+ }
+
+ Text(text = stringResource(R.string.app_description))
+
+ for (item in ABOUT_ITEMS) {
+ AboutItem(item)
+ }
+}
+
+@Composable
+@NonRestartableComposable
+private fun AboutItem(aboutData: AboutData) {
+ Column {
+ Text(
+ text = stringResource(aboutData.title),
+ style = MaterialTheme.typography.titleMedium
+ )
+ Text(text = stringResource(aboutData.description))
+
+ val context = LocalContext.current
+ TextButton(
+ modifier = Modifier.fillMaxWidth()
+ .wrapContentWidth(Alignment.End),
+ onClick = { ShareUtils.openUrlInApp(context, context.getString(aboutData.url)) }
+ ) {
+ Text(text = stringResource(aboutData.buttonText))
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/about/License.kt b/app/src/main/java/org/schabi/newpipe/about/License.kt
deleted file mode 100644
index 117ff9bf5..000000000
--- a/app/src/main/java/org/schabi/newpipe/about/License.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.schabi.newpipe.about
-
-import android.os.Parcelable
-import kotlinx.parcelize.Parcelize
-import java.io.Serializable
-
-/**
- * Class for storing information about a software license.
- */
-@Parcelize
-class License(val name: String, val abbreviation: String, val filename: String) : Parcelable, Serializable
diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt
deleted file mode 100644
index 9f5ad2a7a..000000000
--- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt
+++ /dev/null
@@ -1,140 +0,0 @@
-package org.schabi.newpipe.about
-
-import android.os.Bundle
-import android.util.Base64
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.webkit.WebView
-import androidx.appcompat.app.AlertDialog
-import androidx.core.os.bundleOf
-import androidx.fragment.app.Fragment
-import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
-import io.reactivex.rxjava3.core.Observable
-import io.reactivex.rxjava3.disposables.CompositeDisposable
-import io.reactivex.rxjava3.disposables.Disposable
-import io.reactivex.rxjava3.schedulers.Schedulers
-import org.schabi.newpipe.BuildConfig
-import org.schabi.newpipe.R
-import org.schabi.newpipe.databinding.FragmentLicensesBinding
-import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding
-import org.schabi.newpipe.ktx.parcelableArrayList
-import org.schabi.newpipe.util.Localization
-import org.schabi.newpipe.util.external_communication.ShareUtils
-
-/**
- * Fragment containing the software licenses.
- */
-class LicenseFragment : Fragment() {
- private lateinit var softwareComponents: List
- private var activeSoftwareComponent: SoftwareComponent? = null
- private val compositeDisposable = CompositeDisposable()
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- softwareComponents = arguments?.parcelableArrayList(ARG_COMPONENTS)!!
- .sortedBy { it.name } // Sort components by name
- activeSoftwareComponent = savedInstanceState?.getSerializable(SOFTWARE_COMPONENT_KEY) as? SoftwareComponent
- }
-
- override fun onDestroy() {
- compositeDisposable.dispose()
- super.onDestroy()
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- val binding = FragmentLicensesBinding.inflate(inflater, container, false)
- binding.licensesAppReadLicense.setOnClickListener {
- compositeDisposable.add(
- showLicense(NEWPIPE_SOFTWARE_COMPONENT)
- )
- }
- for (component in softwareComponents) {
- val componentBinding = ItemSoftwareComponentBinding
- .inflate(inflater, container, false)
- componentBinding.name.text = component.name
- componentBinding.copyright.text = getString(
- R.string.copyright,
- component.years,
- component.copyrightOwner,
- component.license.abbreviation
- )
- val root: View = componentBinding.root
- root.tag = component
- root.setOnClickListener {
- compositeDisposable.add(
- showLicense(component)
- )
- }
- binding.licensesSoftwareComponents.addView(root)
- registerForContextMenu(root)
- }
- activeSoftwareComponent?.let { compositeDisposable.add(showLicense(it)) }
- return binding.root
- }
-
- override fun onSaveInstanceState(savedInstanceState: Bundle) {
- super.onSaveInstanceState(savedInstanceState)
- activeSoftwareComponent?.let { savedInstanceState.putSerializable(SOFTWARE_COMPONENT_KEY, it) }
- }
-
- private fun showLicense(
- softwareComponent: SoftwareComponent
- ): Disposable {
- return if (context == null) {
- Disposable.empty()
- } else {
- val context = requireContext()
- activeSoftwareComponent = softwareComponent
- Observable.fromCallable { getFormattedLicense(context, softwareComponent.license) }
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe { formattedLicense ->
- val webViewData = Base64.encodeToString(
- formattedLicense.toByteArray(), Base64.NO_PADDING
- )
- val webView = WebView(context)
- webView.loadData(webViewData, "text/html; charset=UTF-8", "base64")
-
- Localization.assureCorrectAppLanguage(context)
- val builder = AlertDialog.Builder(requireContext())
- .setTitle(softwareComponent.name)
- .setView(webView)
- .setOnCancelListener { activeSoftwareComponent = null }
- .setOnDismissListener { activeSoftwareComponent = null }
- .setPositiveButton(R.string.done) { dialog, _ -> dialog.dismiss() }
-
- if (softwareComponent != NEWPIPE_SOFTWARE_COMPONENT) {
- builder.setNeutralButton(R.string.open_website_license) { _, _ ->
- ShareUtils.openUrlInApp(requireContext(), softwareComponent.link)
- }
- }
-
- builder.show()
- }
- }
- }
-
- companion object {
- private const val ARG_COMPONENTS = "components"
- private const val SOFTWARE_COMPONENT_KEY = "ACTIVE_SOFTWARE_COMPONENT"
- private val NEWPIPE_SOFTWARE_COMPONENT = SoftwareComponent(
- "NewPipe",
- "2014-2023",
- "Team NewPipe",
- "https://newpipe.net/",
- StandardLicenses.GPL3,
- BuildConfig.VERSION_NAME
- )
-
- fun newInstance(softwareComponents: ArrayList): LicenseFragment {
- val fragment = LicenseFragment()
- fragment.arguments = bundleOf(ARG_COMPONENTS to softwareComponents)
- return fragment
- }
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt
deleted file mode 100644
index 56e21c88a..000000000
--- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.schabi.newpipe.about
-
-import android.content.Context
-import org.schabi.newpipe.R
-import org.schabi.newpipe.util.ThemeHelper
-import java.io.IOException
-
-/**
- * @param context the context to use
- * @param license the license
- * @return String which contains a HTML formatted license page
- * styled according to the context's theme
- */
-fun getFormattedLicense(context: Context, license: License): String {
- try {
- return context.assets.open(license.filename).bufferedReader().use { it.readText() }
- // split the HTML file and insert the stylesheet into the HEAD of the file
- .replace("", "")
- } catch (e: IOException) {
- throw IllegalArgumentException("Could not get license file: ${license.filename}", e)
- }
-}
-
-/**
- * @param context the Android context
- * @return String which is a CSS stylesheet according to the context's theme
- */
-fun getLicenseStylesheet(context: Context): String {
- val isLightTheme = ThemeHelper.isLightThemeSelected(context)
- val licenseBackgroundColor = getHexRGBColor(
- context, if (isLightTheme) R.color.light_license_background_color else R.color.dark_license_background_color
- )
- val licenseTextColor = getHexRGBColor(
- context, if (isLightTheme) R.color.light_license_text_color else R.color.dark_license_text_color
- )
- val youtubePrimaryColor = getHexRGBColor(
- context, if (isLightTheme) R.color.light_youtube_primary_color else R.color.dark_youtube_primary_color
- )
- return "body{padding:12px 15px;margin:0;background:#$licenseBackgroundColor;color:#$licenseTextColor}" +
- "a[href]{color:#$youtubePrimaryColor}pre{white-space:pre-wrap}"
-}
-
-/**
- * Cast R.color to a hexadecimal color value.
- *
- * @param context the context to use
- * @param color the color number from R.color
- * @return a six characters long String with hexadecimal RGB values
- */
-fun getHexRGBColor(context: Context, color: Int): String {
- return context.getString(color).substring(3)
-}
diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt
new file mode 100644
index 000000000..19f687455
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt
@@ -0,0 +1,184 @@
+package org.schabi.newpipe.about
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.NonRestartableComposable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.TextLinkStyles
+import androidx.compose.ui.text.fromHtml
+import androidx.compose.ui.text.style.TextDecoration
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import org.schabi.newpipe.R
+
+private val SOFTWARE_COMPONENTS = listOf(
+ SoftwareComponent(
+ "ACRA", "2013", "Kevin Gaudin",
+ "https://github.com/ACRA/acra", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "AndroidX", "2005 - 2011", "The Android Open Source Project",
+ "https://developer.android.com/jetpack", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "ExoPlayer", "2014 - 2020", "Google, Inc.",
+ "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "GigaGet", "2014 - 2015", "Peter Cai",
+ "https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL3
+ ),
+ SoftwareComponent(
+ "Groupie", "2016", "Lisa Wray",
+ "https://github.com/lisawray/groupie", StandardLicenses.MIT
+ ),
+ SoftwareComponent(
+ "Icepick", "2015", "Frankie Sardo",
+ "https://github.com/frankiesardo/icepick", StandardLicenses.EPL1
+ ),
+ SoftwareComponent(
+ "Jsoup", "2009 - 2020", "Jonathan Hedley",
+ "https://github.com/jhy/jsoup", StandardLicenses.MIT
+ ),
+ SoftwareComponent(
+ "LazyColumnScrollbar", "2024", "nani",
+ "https://github.com/nanihadesuka/LazyColumnScrollbar", StandardLicenses.MIT
+ ),
+ SoftwareComponent(
+ "Markwon", "2019", "Dimitry Ivanov",
+ "https://github.com/noties/Markwon", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "Material Components for Android", "2016 - 2020", "Google, Inc.",
+ "https://github.com/material-components/material-components-android",
+ StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "NewPipe Extractor", "2017 - 2020", "Christian Schabesberger",
+ "https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3
+ ),
+ SoftwareComponent(
+ "NoNonsense-FilePicker", "2016", "Jonas Kalderstam",
+ "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2
+ ),
+ SoftwareComponent(
+ "OkHttp", "2019", "Square, Inc.",
+ "https://square.github.io/okhttp/", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "Picasso", "2013", "Square, Inc.",
+ "https://square.github.io/picasso/", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "PrettyTime", "2012 - 2020", "Lincoln Baxter, III",
+ "https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "ProcessPhoenix", "2015", "Jake Wharton",
+ "https://github.com/JakeWharton/ProcessPhoenix", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "RxAndroid", "2015", "The RxAndroid authors",
+ "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "RxBinding", "2015", "Jake Wharton",
+ "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "RxJava", "2016 - 2020", "RxJava Contributors",
+ "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2
+ ),
+ SoftwareComponent(
+ "SearchPreference", "2018", "ByteHamster",
+ "https://github.com/ByteHamster/SearchPreference", StandardLicenses.MIT
+ )
+)
+
+@Composable
+@NonRestartableComposable
+fun LicenseTab() {
+ var selectedLicense by remember { mutableStateOf(null) }
+ val onClick = remember {
+ { it: SoftwareComponent -> selectedLicense = it }
+ }
+
+ Text(
+ text = stringResource(R.string.app_license_title),
+ style = MaterialTheme.typography.titleLarge
+ )
+ Text(
+ text = stringResource(R.string.app_license),
+ style = MaterialTheme.typography.bodyMedium
+ )
+
+ Text(
+ text = stringResource(R.string.title_licenses),
+ style = MaterialTheme.typography.titleLarge,
+ )
+ for (component in SOFTWARE_COMPONENTS) {
+ LicenseItem(component, onClick)
+ }
+
+ selectedLicense?.let {
+ var formattedLicense by remember { mutableStateOf("") }
+
+ val context = LocalContext.current
+ LaunchedEffect(key1 = it) {
+ formattedLicense = withContext(Dispatchers.IO) {
+ it.license.getFormattedLicense(context)
+ }
+ }
+
+ AlertDialog(
+ onDismissRequest = { selectedLicense = null },
+ confirmButton = {},
+ title = { Text(text = it.name) },
+ text = {
+ val styles = TextLinkStyles(SpanStyle(textDecoration = TextDecoration.Underline))
+ Text(
+ modifier = Modifier.verticalScroll(rememberScrollState()),
+ text = AnnotatedString.fromHtml(formattedLicense, styles)
+ )
+ }
+ )
+ }
+}
+
+@Composable
+@NonRestartableComposable
+private fun LicenseItem(
+ softwareComponent: SoftwareComponent,
+ onClick: (SoftwareComponent) -> Unit
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .clickable { onClick(softwareComponent) }
+ ) {
+ Text(text = softwareComponent.name)
+ Text(
+ style = MaterialTheme.typography.bodyMedium,
+ text = stringResource(
+ R.string.copyright, softwareComponent.years,
+ softwareComponent.copyrightOwner, softwareComponent.license.abbreviation
+ )
+ )
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/about/SoftwareComponent.kt b/app/src/main/java/org/schabi/newpipe/about/SoftwareComponent.kt
deleted file mode 100644
index 262641caa..000000000
--- a/app/src/main/java/org/schabi/newpipe/about/SoftwareComponent.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.schabi.newpipe.about
-
-import android.os.Parcelable
-import kotlinx.parcelize.Parcelize
-import java.io.Serializable
-
-@Parcelize
-class SoftwareComponent
-@JvmOverloads
-constructor(
- val name: String,
- val years: String,
- val copyrightOwner: String,
- val link: String,
- val license: License,
- val version: String? = null
-) : Parcelable, Serializable
diff --git a/app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt b/app/src/main/java/org/schabi/newpipe/compose/Toolbar.kt
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt
rename to app/src/main/java/org/schabi/newpipe/compose/Toolbar.kt
index b788932a2..469d88ec0 100644
--- a/app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt
+++ b/app/src/main/java/org/schabi/newpipe/compose/Toolbar.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.ui
+package org.schabi.newpipe.compose
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -27,8 +27,8 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import org.schabi.newpipe.R
-import org.schabi.newpipe.ui.theme.AppTheme
-import org.schabi.newpipe.ui.theme.SizeTokens
+import org.schabi.newpipe.compose.theme.AppTheme
+import org.schabi.newpipe.compose.theme.SizeTokens
@Composable
fun TextAction(text: String, modifier: Modifier = Modifier) {
diff --git a/app/src/main/java/org/schabi/newpipe/compose/screen/ScaffoldWithToolbar.kt b/app/src/main/java/org/schabi/newpipe/compose/screen/ScaffoldWithToolbar.kt
new file mode 100644
index 000000000..52e982c3b
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/compose/screen/ScaffoldWithToolbar.kt
@@ -0,0 +1,40 @@
+package org.schabi.newpipe.compose.screen
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.RowScope
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.filled.ArrowBack
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
+import androidx.compose.runtime.Composable
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun ScaffoldWithToolbar(
+ title: String,
+ onBackClick: () -> Unit,
+ actions: @Composable RowScope.() -> Unit = {},
+ content: @Composable (PaddingValues) -> Unit
+) {
+ Scaffold(
+ topBar = {
+ TopAppBar(
+ title = { Text(text = title) },
+ navigationIcon = {
+ IconButton(onClick = onBackClick) {
+ Icon(
+ imageVector = Icons.AutoMirrored.Filled.ArrowBack,
+ contentDescription = null
+ )
+ }
+ },
+ actions = actions
+ )
+ },
+ content = content
+ )
+}
diff --git a/app/src/main/java/org/schabi/newpipe/ui/theme/Color.kt b/app/src/main/java/org/schabi/newpipe/compose/theme/Color.kt
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/ui/theme/Color.kt
rename to app/src/main/java/org/schabi/newpipe/compose/theme/Color.kt
index b61906ebe..0aa330390 100644
--- a/app/src/main/java/org/schabi/newpipe/ui/theme/Color.kt
+++ b/app/src/main/java/org/schabi/newpipe/compose/theme/Color.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.ui.theme
+package org.schabi.newpipe.compose.theme
import androidx.compose.ui.graphics.Color
diff --git a/app/src/main/java/org/schabi/newpipe/ui/theme/SizeTokens.kt b/app/src/main/java/org/schabi/newpipe/compose/theme/SizeTokens.kt
similarity index 88%
rename from app/src/main/java/org/schabi/newpipe/ui/theme/SizeTokens.kt
rename to app/src/main/java/org/schabi/newpipe/compose/theme/SizeTokens.kt
index d8104d7ae..274fa9d43 100644
--- a/app/src/main/java/org/schabi/newpipe/ui/theme/SizeTokens.kt
+++ b/app/src/main/java/org/schabi/newpipe/compose/theme/SizeTokens.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.ui.theme
+package org.schabi.newpipe.compose.theme
import androidx.compose.ui.unit.dp
diff --git a/app/src/main/java/org/schabi/newpipe/ui/theme/Theme.kt b/app/src/main/java/org/schabi/newpipe/compose/theme/Theme.kt
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/ui/theme/Theme.kt
rename to app/src/main/java/org/schabi/newpipe/compose/theme/Theme.kt
index 846794d72..1c9325f96 100644
--- a/app/src/main/java/org/schabi/newpipe/ui/theme/Theme.kt
+++ b/app/src/main/java/org/schabi/newpipe/compose/theme/Theme.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.ui.theme
+package org.schabi.newpipe.compose.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
diff --git a/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt b/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt
deleted file mode 100644
index 61721d546..000000000
--- a/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.schabi.newpipe.ktx
-
-import android.os.Bundle
-import android.os.Parcelable
-import androidx.core.os.BundleCompat
-
-inline fun Bundle.parcelableArrayList(key: String?): ArrayList? {
- return BundleCompat.getParcelableArrayList(this, key, T::class.java)
-}
diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml
deleted file mode 100644
index 661c4affc..000000000
--- a/app/src/main/res/layout/activity_about.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml
deleted file mode 100644
index 5e6e11d00..000000000
--- a/app/src/main/res/layout/fragment_about.xml
+++ /dev/null
@@ -1,148 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/fragment_licenses.xml b/app/src/main/res/layout/fragment_licenses.xml
deleted file mode 100644
index c46d888ba..000000000
--- a/app/src/main/res/layout/fragment_licenses.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/item_software_component.xml b/app/src/main/res/layout/item_software_component.xml
deleted file mode 100644
index b5e224a3e..000000000
--- a/app/src/main/res/layout/item_software_component.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
diff --git a/build.gradle b/build.gradle
index 6d19a6f8a..49de98659 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.9.10'
+ ext.kotlin_version = '1.9.24'
repositories {
google()
mavenCentral()
From 8a41c8cf66561c8cdf1a051e6465885633c207bf Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Sun, 14 Jul 2024 08:03:01 +0530
Subject: [PATCH 017/134] Added buttons to alert dialog
---
.../java/org/schabi/newpipe/about/LicenseTab.kt | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt
index 19f687455..a42cf864c 100644
--- a/app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt
+++ b/app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.NonRestartableComposable
@@ -26,6 +27,7 @@ import androidx.compose.ui.text.style.TextDecoration
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.schabi.newpipe.R
+import org.schabi.newpipe.util.external_communication.ShareUtils
private val SOFTWARE_COMPONENTS = listOf(
SoftwareComponent(
@@ -148,8 +150,19 @@ fun LicenseTab() {
AlertDialog(
onDismissRequest = { selectedLicense = null },
- confirmButton = {},
- title = { Text(text = it.name) },
+ confirmButton = {
+ TextButton(onClick = { ShareUtils.openUrlInApp(context, it.link) }) {
+ Text(text = stringResource(R.string.open_website_license))
+ }
+ },
+ dismissButton = {
+ TextButton(onClick = { selectedLicense = null }) {
+ Text(text = stringResource(R.string.done))
+ }
+ },
+ title = {
+ Text(text = it.name, color = MaterialTheme.colorScheme.onBackground)
+ },
text = {
val styles = TextLinkStyles(SpanStyle(textDecoration = TextDecoration.Underline))
Text(
From 6e6c171dd7ef2e028ea2010ec98c2d266e555f9d Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Sun, 14 Jul 2024 13:25:17 +0530
Subject: [PATCH 018/134] Added new icon
---
.../java/org/schabi/newpipe/about/AboutTab.kt | 11 ++---------
app/src/main/res/drawable/icon.xml | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 9 deletions(-)
create mode 100644 app/src/main/res/drawable/icon.xml
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutTab.kt b/app/src/main/java/org/schabi/newpipe/about/AboutTab.kt
index f391c7790..020c57e79 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutTab.kt
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutTab.kt
@@ -1,12 +1,10 @@
package org.schabi.newpipe.about
import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.wrapContentWidth
-import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
@@ -14,8 +12,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -53,11 +49,8 @@ fun AboutTab() {
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
- painter = painterResource(R.mipmap.ic_launcher_foreground),
- contentDescription = stringResource(R.string.app_name),
- modifier = Modifier
- .clip(CircleShape)
- .background(Color.Red)
+ painter = painterResource(R.drawable.icon),
+ contentDescription = stringResource(R.string.app_name)
)
Text(
style = MaterialTheme.typography.titleLarge,
diff --git a/app/src/main/res/drawable/icon.xml b/app/src/main/res/drawable/icon.xml
new file mode 100644
index 000000000..2ce3e492d
--- /dev/null
+++ b/app/src/main/res/drawable/icon.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
From 7a7f81ac7f9ef7778ad51a1c2bea96b0956964a7 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Mon, 15 Jul 2024 04:56:49 +0530
Subject: [PATCH 019/134] Fix tab text color
---
app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt b/app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt
index 088380f74..fc3f70482 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt
@@ -24,6 +24,7 @@ import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -50,7 +51,7 @@ fun AboutScreen(padding: PaddingValues) {
TabRow(selectedTabIndex = tabIndex) {
TITLES.forEachIndexed { index, titleId ->
Tab(
- text = { Text(text = stringResource(titleId)) },
+ text = { Text(text = stringResource(titleId), color = Color.White) },
selected = tabIndex == index,
onClick = { tabIndex = index }
)
From b05b98ca61a37f16d85f50015fe6fe7a0dfc7d5e Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Sun, 28 Jul 2024 07:44:38 +0530
Subject: [PATCH 020/134] Improved component organisation
---
app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt | 5 +++--
.../main/java/org/schabi/newpipe/{compose => ui}/Toolbar.kt | 6 +++---
.../newpipe/{ => ui/components}/about/AboutClasses.kt | 2 +-
.../schabi/newpipe/{ => ui/components}/about/AboutTab.kt | 2 +-
.../schabi/newpipe/{ => ui/components}/about/LicenseTab.kt | 2 +-
.../newpipe/{ => ui/components}/about/StandardLicenses.kt | 2 +-
.../screen => ui/components/common}/ScaffoldWithToolbar.kt | 2 +-
.../org/schabi/newpipe/{about => ui/screens}/AboutScreen.kt | 6 ++++--
.../java/org/schabi/newpipe/{compose => ui}/theme/Color.kt | 2 +-
.../org/schabi/newpipe/{compose => ui}/theme/SizeTokens.kt | 2 +-
.../java/org/schabi/newpipe/{compose => ui}/theme/Theme.kt | 2 +-
11 files changed, 18 insertions(+), 15 deletions(-)
rename app/src/main/java/org/schabi/newpipe/{compose => ui}/Toolbar.kt (97%)
rename app/src/main/java/org/schabi/newpipe/{ => ui/components}/about/AboutClasses.kt (93%)
rename app/src/main/java/org/schabi/newpipe/{ => ui/components}/about/AboutTab.kt (98%)
rename app/src/main/java/org/schabi/newpipe/{ => ui/components}/about/LicenseTab.kt (99%)
rename app/src/main/java/org/schabi/newpipe/{ => ui/components}/about/StandardLicenses.kt (92%)
rename app/src/main/java/org/schabi/newpipe/{compose/screen => ui/components/common}/ScaffoldWithToolbar.kt (96%)
rename app/src/main/java/org/schabi/newpipe/{about => ui/screens}/AboutScreen.kt (94%)
rename app/src/main/java/org/schabi/newpipe/{compose => ui}/theme/Color.kt (98%)
rename app/src/main/java/org/schabi/newpipe/{compose => ui}/theme/SizeTokens.kt (88%)
rename app/src/main/java/org/schabi/newpipe/{compose => ui}/theme/Theme.kt (98%)
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
index 0741c272a..84121eb32 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
@@ -5,8 +5,9 @@ import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.ui.res.stringResource
import org.schabi.newpipe.R
-import org.schabi.newpipe.compose.screen.ScaffoldWithToolbar
-import org.schabi.newpipe.compose.theme.AppTheme
+import org.schabi.newpipe.ui.components.common.ScaffoldWithToolbar
+import org.schabi.newpipe.ui.screens.AboutScreen
+import org.schabi.newpipe.ui.theme.AppTheme
import org.schabi.newpipe.util.Localization
class AboutActivity : AppCompatActivity() {
diff --git a/app/src/main/java/org/schabi/newpipe/compose/Toolbar.kt b/app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/compose/Toolbar.kt
rename to app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt
index 469d88ec0..b788932a2 100644
--- a/app/src/main/java/org/schabi/newpipe/compose/Toolbar.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.compose
+package org.schabi.newpipe.ui
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -27,8 +27,8 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import org.schabi.newpipe.R
-import org.schabi.newpipe.compose.theme.AppTheme
-import org.schabi.newpipe.compose.theme.SizeTokens
+import org.schabi.newpipe.ui.theme.AppTheme
+import org.schabi.newpipe.ui.theme.SizeTokens
@Composable
fun TextAction(text: String, modifier: Modifier = Modifier) {
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutClasses.kt b/app/src/main/java/org/schabi/newpipe/ui/components/about/AboutClasses.kt
similarity index 93%
rename from app/src/main/java/org/schabi/newpipe/about/AboutClasses.kt
rename to app/src/main/java/org/schabi/newpipe/ui/components/about/AboutClasses.kt
index bacd944c6..dcc22dd81 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutClasses.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/components/about/AboutClasses.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.about
+package org.schabi.newpipe.ui.components.about
import android.content.Context
import androidx.annotation.StringRes
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutTab.kt b/app/src/main/java/org/schabi/newpipe/ui/components/about/AboutTab.kt
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/about/AboutTab.kt
rename to app/src/main/java/org/schabi/newpipe/ui/components/about/AboutTab.kt
index 020c57e79..6b7dc09b8 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutTab.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/components/about/AboutTab.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.about
+package org.schabi.newpipe.ui.components.about
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt b/app/src/main/java/org/schabi/newpipe/ui/components/about/LicenseTab.kt
similarity index 99%
rename from app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt
rename to app/src/main/java/org/schabi/newpipe/ui/components/about/LicenseTab.kt
index a42cf864c..ca736f808 100644
--- a/app/src/main/java/org/schabi/newpipe/about/LicenseTab.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/components/about/LicenseTab.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.about
+package org.schabi.newpipe.ui.components.about
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
diff --git a/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.kt b/app/src/main/java/org/schabi/newpipe/ui/components/about/StandardLicenses.kt
similarity index 92%
rename from app/src/main/java/org/schabi/newpipe/about/StandardLicenses.kt
rename to app/src/main/java/org/schabi/newpipe/ui/components/about/StandardLicenses.kt
index c5b9618fe..ce29bfd8a 100644
--- a/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/components/about/StandardLicenses.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.about
+package org.schabi.newpipe.ui.components.about
/**
* Class containing information about standard software licenses.
diff --git a/app/src/main/java/org/schabi/newpipe/compose/screen/ScaffoldWithToolbar.kt b/app/src/main/java/org/schabi/newpipe/ui/components/common/ScaffoldWithToolbar.kt
similarity index 96%
rename from app/src/main/java/org/schabi/newpipe/compose/screen/ScaffoldWithToolbar.kt
rename to app/src/main/java/org/schabi/newpipe/ui/components/common/ScaffoldWithToolbar.kt
index 52e982c3b..bd0b6359c 100644
--- a/app/src/main/java/org/schabi/newpipe/compose/screen/ScaffoldWithToolbar.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/components/common/ScaffoldWithToolbar.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.compose.screen
+package org.schabi.newpipe.ui.components.common
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.RowScope
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt b/app/src/main/java/org/schabi/newpipe/ui/screens/AboutScreen.kt
similarity index 94%
rename from app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt
rename to app/src/main/java/org/schabi/newpipe/ui/screens/AboutScreen.kt
index fc3f70482..9ed4be8df 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutScreen.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/screens/AboutScreen.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.about
+package org.schabi.newpipe.ui.screens
import android.content.res.Configuration
import androidx.collection.intListOf
@@ -30,7 +30,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import my.nanihadesuka.compose.ColumnScrollbar
import org.schabi.newpipe.R
-import org.schabi.newpipe.compose.theme.AppTheme
+import org.schabi.newpipe.ui.components.about.AboutTab
+import org.schabi.newpipe.ui.components.about.LicenseTab
+import org.schabi.newpipe.ui.theme.AppTheme
private val TITLES = intListOf(R.string.tab_about, R.string.tab_licenses)
diff --git a/app/src/main/java/org/schabi/newpipe/compose/theme/Color.kt b/app/src/main/java/org/schabi/newpipe/ui/theme/Color.kt
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/compose/theme/Color.kt
rename to app/src/main/java/org/schabi/newpipe/ui/theme/Color.kt
index 0aa330390..b61906ebe 100644
--- a/app/src/main/java/org/schabi/newpipe/compose/theme/Color.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/theme/Color.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.compose.theme
+package org.schabi.newpipe.ui.theme
import androidx.compose.ui.graphics.Color
diff --git a/app/src/main/java/org/schabi/newpipe/compose/theme/SizeTokens.kt b/app/src/main/java/org/schabi/newpipe/ui/theme/SizeTokens.kt
similarity index 88%
rename from app/src/main/java/org/schabi/newpipe/compose/theme/SizeTokens.kt
rename to app/src/main/java/org/schabi/newpipe/ui/theme/SizeTokens.kt
index 274fa9d43..d8104d7ae 100644
--- a/app/src/main/java/org/schabi/newpipe/compose/theme/SizeTokens.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/theme/SizeTokens.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.compose.theme
+package org.schabi.newpipe.ui.theme
import androidx.compose.ui.unit.dp
diff --git a/app/src/main/java/org/schabi/newpipe/compose/theme/Theme.kt b/app/src/main/java/org/schabi/newpipe/ui/theme/Theme.kt
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/compose/theme/Theme.kt
rename to app/src/main/java/org/schabi/newpipe/ui/theme/Theme.kt
index 1c9325f96..846794d72 100644
--- a/app/src/main/java/org/schabi/newpipe/compose/theme/Theme.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/theme/Theme.kt
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.compose.theme
+package org.schabi.newpipe.ui.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
From ba2efded76461029f7d4c5df5e9525e78e04e93b Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Sat, 10 Aug 2024 18:18:08 +0530
Subject: [PATCH 021/134] Replace Picasso with Coil in about
---
.../org/schabi/newpipe/ui/components/about/LicenseTab.kt | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/about/LicenseTab.kt b/app/src/main/java/org/schabi/newpipe/ui/components/about/LicenseTab.kt
index ca736f808..eb5e1675a 100644
--- a/app/src/main/java/org/schabi/newpipe/ui/components/about/LicenseTab.kt
+++ b/app/src/main/java/org/schabi/newpipe/ui/components/about/LicenseTab.kt
@@ -38,6 +38,10 @@ private val SOFTWARE_COMPONENTS = listOf(
"AndroidX", "2005 - 2011", "The Android Open Source Project",
"https://developer.android.com/jetpack", StandardLicenses.APACHE2
),
+ SoftwareComponent(
+ "Coil", "2023", "Coil Contributors",
+ "https://coil-kt.github.io/coil/", StandardLicenses.APACHE2
+ ),
SoftwareComponent(
"ExoPlayer", "2014 - 2020", "Google, Inc.",
"https://github.com/google/ExoPlayer", StandardLicenses.APACHE2
@@ -83,10 +87,6 @@ private val SOFTWARE_COMPONENTS = listOf(
"OkHttp", "2019", "Square, Inc.",
"https://square.github.io/okhttp/", StandardLicenses.APACHE2
),
- SoftwareComponent(
- "Picasso", "2013", "Square, Inc.",
- "https://square.github.io/picasso/", StandardLicenses.APACHE2
- ),
SoftwareComponent(
"PrettyTime", "2012 - 2020", "Lincoln Baxter, III",
"https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2
From bda961a04cb8172bd3d5d0c4d7ea61da965e8c72 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Sun, 12 May 2024 08:21:13 +0530
Subject: [PATCH 022/134] Convert comment replies views to Jetpack Compose
---
app/build.gradle | 6 +-
.../fragments/list/comments/Comment.kt | 84 ++++++++++++
.../list/comments/CommentRepliesHeader.kt | 121 ++++++++++++++++++
build.gradle | 2 +-
4 files changed, 209 insertions(+), 4 deletions(-)
create mode 100644 app/src/main/java/org/schabi/newpipe/fragments/list/comments/Comment.kt
create mode 100644 app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesHeader.kt
diff --git a/app/build.gradle b/app/build.gradle
index 9ea725ad9..5b5b25350 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -106,7 +106,7 @@ android {
}
composeOptions {
- kotlinCompilerExtensionVersion = "1.5.3"
+ kotlinCompilerExtensionVersion = "1.5.13"
}
}
@@ -267,7 +267,7 @@ dependencies {
implementation "com.github.lisawray.groupie:groupie-viewbinding:${groupieVersion}"
// Image loading
- implementation 'io.coil-kt:coil:2.7.0'
+ implementation 'io.coil-kt:coil-compose:2.7.0'
// Markdown library for Android
implementation "io.noties.markwon:core:${markwonVersion}"
@@ -289,7 +289,7 @@ dependencies {
implementation "org.ocpsoft.prettytime:prettytime:5.0.8.Final"
// Jetpack Compose
- implementation(platform('androidx.compose:compose-bom:2024.02.01'))
+ implementation(platform('androidx.compose:compose-bom:2024.05.00'))
implementation 'androidx.compose.material3:material3'
implementation 'androidx.activity:activity-compose'
implementation 'androidx.compose.ui:ui-tooling-preview'
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/Comment.kt b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/Comment.kt
new file mode 100644
index 000000000..c622aa18d
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/Comment.kt
@@ -0,0 +1,84 @@
+package org.schabi.newpipe.fragments.list.comments
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.fragment.app.FragmentActivity
+import coil.compose.AsyncImage
+import org.schabi.newpipe.R
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem
+import org.schabi.newpipe.extractor.stream.Description
+import org.schabi.newpipe.util.NavigationHelper
+import org.schabi.newpipe.util.image.ImageStrategy
+
+@Composable
+fun Comment(comment: CommentsInfoItem) {
+ val context = LocalContext.current
+
+ Row(modifier = Modifier.padding(all = 8.dp)) {
+ if (ImageStrategy.shouldLoadImages()) {
+ AsyncImage(
+ model = ImageStrategy.choosePreferredImage(comment.uploaderAvatars),
+ contentDescription = null,
+ placeholder = painterResource(R.drawable.placeholder_person),
+ error = painterResource(R.drawable.placeholder_person),
+ modifier = Modifier
+ .size(42.dp)
+ .clip(CircleShape)
+ .clickable {
+ NavigationHelper.openCommentAuthorIfPresent(context as FragmentActivity, comment)
+ }
+ )
+ }
+
+ Spacer(modifier = Modifier.width(8.dp))
+
+ var isExpanded by rememberSaveable { mutableStateOf(false) }
+
+ Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
+ Text(
+ text = comment.uploaderName,
+ color = MaterialTheme.colors.secondary
+ )
+
+ Spacer(modifier = Modifier.height(4.dp))
+
+ Text(
+ text = comment.commentText.content,
+ // If the comment is expanded, we display all its content
+ // otherwise we only display the first line
+ maxLines = if (isExpanded) Int.MAX_VALUE else 1,
+ style = MaterialTheme.typography.body2
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+fun CommentPreview() {
+ val comment = CommentsInfoItem(1, "", "")
+ comment.commentText = Description("Hello world!", Description.PLAIN_TEXT)
+ comment.uploaderName = "Test"
+
+ Comment(comment)
+}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesHeader.kt b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesHeader.kt
new file mode 100644
index 000000000..243d887cd
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesHeader.kt
@@ -0,0 +1,121 @@
+package org.schabi.newpipe.fragments.list.comments
+
+import android.widget.TextView
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
+import androidx.core.text.HtmlCompat
+import androidx.core.text.method.LinkMovementMethodCompat
+import androidx.fragment.app.FragmentActivity
+import coil.compose.AsyncImage
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import org.schabi.newpipe.R
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem
+import org.schabi.newpipe.extractor.stream.Description
+import org.schabi.newpipe.util.Localization
+import org.schabi.newpipe.util.NavigationHelper
+import org.schabi.newpipe.util.ServiceHelper
+import org.schabi.newpipe.util.image.ImageStrategy
+import org.schabi.newpipe.util.text.TextLinkifier
+
+@Composable
+fun CommentRepliesHeader(comment: CommentsInfoItem, disposables: CompositeDisposable) {
+ val context = LocalContext.current
+
+ Column(modifier = Modifier.padding(all = 8.dp)) {
+ Row {
+ Row(
+ modifier = Modifier
+ .padding(all = 8.dp)
+ .clickable {
+ NavigationHelper.openCommentAuthorIfPresent(
+ context as FragmentActivity,
+ comment
+ )
+ }
+ ) {
+ if (ImageStrategy.shouldLoadImages()) {
+ AsyncImage(
+ model = ImageStrategy.choosePreferredImage(comment.uploaderAvatars),
+ contentDescription = null,
+ placeholder = painterResource(R.drawable.placeholder_person),
+ error = painterResource(R.drawable.placeholder_person),
+ modifier = Modifier
+ .size(42.dp)
+ .clip(CircleShape)
+ )
+ }
+
+ Spacer(modifier = Modifier.width(8.dp))
+
+ Column {
+ Text(text = comment.uploaderName)
+
+ Text(
+ text = Localization.relativeTimeOrTextual(
+ context, comment.uploadDate, comment.textualUploadDate
+ )
+ )
+ }
+ }
+
+ if (comment.isHeartedByUploader) {
+ Image(
+ painter = painterResource(R.drawable.ic_heart),
+ contentDescription = stringResource(R.string.detail_heart_img_view_description)
+ )
+ }
+
+ if (comment.isPinned) {
+ Image(
+ painter = painterResource(R.drawable.ic_pin),
+ contentDescription = stringResource(R.string.detail_pinned_comment_view_description)
+ )
+ }
+ }
+
+ AndroidView(
+ factory = { context ->
+ TextView(context).apply {
+ movementMethod = LinkMovementMethodCompat.getInstance()
+ }
+ },
+ update = { view ->
+ // setup comment content
+ TextLinkifier.fromDescription(view, comment.commentText,
+ HtmlCompat.FROM_HTML_MODE_LEGACY,
+ ServiceHelper.getServiceById(comment.serviceId), comment.url, disposables,
+ null
+ )
+ }
+ )
+ }
+}
+
+@Preview
+@Composable
+fun CommentRepliesHeaderPreview() {
+ val disposables = CompositeDisposable()
+ val comment = CommentsInfoItem(1, "", "")
+ comment.commentText = Description("Hello world!", Description.PLAIN_TEXT)
+ comment.uploaderName = "Test"
+ comment.textualUploadDate = "5 months ago"
+
+ CommentRepliesHeader(comment, disposables)
+}
diff --git a/build.gradle b/build.gradle
index 6d19a6f8a..5a1ae1945 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.9.10'
+ ext.kotlin_version = '1.9.23'
repositories {
google()
mavenCentral()
From 644a345b5571fd34ae3471c686ee59afc98fe412 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Sun, 12 May 2024 08:49:14 +0530
Subject: [PATCH 023/134] Rename .java to .kt
---
.../{CommentRepliesFragment.java => CommentRepliesFragment.kt} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename app/src/main/java/org/schabi/newpipe/fragments/list/comments/{CommentRepliesFragment.java => CommentRepliesFragment.kt} (100%)
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt
similarity index 100%
rename from app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java
rename to app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt
From e05d97732eb48c1641367234a26f98db94c1bb98 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Sun, 12 May 2024 08:49:15 +0530
Subject: [PATCH 024/134] Use reply header composable in fragment
---
.../java/org/schabi/newpipe/MainActivity.java | 2 +-
.../list/comments/CommentRepliesFragment.kt | 260 +++++++-----------
.../list/comments/CommentRepliesHeader.kt | 4 +-
.../res/layout/comment_replies_header.xml | 137 ---------
4 files changed, 100 insertions(+), 303 deletions(-)
delete mode 100644 app/src/main/res/layout/comment_replies_header.xml
diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java
index 175694125..43b01c70d 100644
--- a/app/src/main/java/org/schabi/newpipe/MainActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java
@@ -871,7 +871,7 @@ public class MainActivity extends AppCompatActivity {
@Nullable final CommentRepliesFragment repliesFragment =
(CommentRepliesFragment) fm.findFragmentByTag(CommentRepliesFragment.TAG);
@Nullable final CommentsInfoItem rootComment =
- repliesFragment == null ? null : repliesFragment.getCommentsInfoItem();
+ repliesFragment == null ? null : repliesFragment.commentsInfoItem;
// sometimes this function pops the backstack, other times it's handled by the system
if (popBackStack) {
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt
index 4eb73520f..4bfb04d6e 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt
@@ -1,170 +1,104 @@
-package org.schabi.newpipe.fragments.list.comments;
+package org.schabi.newpipe.fragments.list.comments
-import static org.schabi.newpipe.util.ServiceHelper.getServiceById;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.constraintlayout.widget.ConstraintLayout;
-import androidx.core.text.HtmlCompat;
-
-import org.schabi.newpipe.R;
-import org.schabi.newpipe.databinding.CommentRepliesHeaderBinding;
-import org.schabi.newpipe.error.UserAction;
-import org.schabi.newpipe.extractor.ListExtractor;
-import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
-import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
-import org.schabi.newpipe.info_list.ItemViewMode;
-import org.schabi.newpipe.util.DeviceUtils;
-import org.schabi.newpipe.util.ExtractorHelper;
-import org.schabi.newpipe.util.Localization;
-import org.schabi.newpipe.util.NavigationHelper;
-import org.schabi.newpipe.util.image.CoilHelper;
-import org.schabi.newpipe.util.image.ImageStrategy;
-import org.schabi.newpipe.util.text.TextLinkifier;
-
-import java.util.Queue;
-import java.util.function.Supplier;
-
-import icepick.State;
-import io.reactivex.rxjava3.core.Single;
-import io.reactivex.rxjava3.disposables.CompositeDisposable;
-
-public final class CommentRepliesFragment
- extends BaseListInfoFragment {
-
- public static final String TAG = CommentRepliesFragment.class.getSimpleName();
-
- @State
- CommentsInfoItem commentsInfoItem; // the comment to show replies of
- private final CompositeDisposable disposables = new CompositeDisposable();
-
-
- /*//////////////////////////////////////////////////////////////////////////
- // Constructors and lifecycle
- //////////////////////////////////////////////////////////////////////////*/
-
- // only called by the Android framework, after which readFrom is called and restores all data
- public CommentRepliesFragment() {
- super(UserAction.REQUESTED_COMMENT_REPLIES);
- }
-
- public CommentRepliesFragment(@NonNull final CommentsInfoItem commentsInfoItem) {
- this();
- this.commentsInfoItem = commentsInfoItem;
- // setting "" as title since the title will be properly set right after
- setInitialData(commentsInfoItem.getServiceId(), commentsInfoItem.getUrl(), "");
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull final LayoutInflater inflater,
- @Nullable final ViewGroup container,
- @Nullable final Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_comments, container, false);
- }
-
- @Override
- public void onDestroyView() {
- disposables.clear();
- super.onDestroyView();
- }
-
- @Override
- protected Supplier getListHeaderSupplier() {
- return () -> {
- final CommentRepliesHeaderBinding binding = CommentRepliesHeaderBinding
- .inflate(activity.getLayoutInflater(), itemsList, false);
- final CommentsInfoItem item = commentsInfoItem;
-
- // load the author avatar
- CoilHelper.INSTANCE.loadAvatar(binding.authorAvatar, item.getUploaderAvatars());
- binding.authorAvatar.setVisibility(ImageStrategy.shouldLoadImages()
- ? View.VISIBLE : View.GONE);
-
- // setup author name and comment date
- binding.authorName.setText(item.getUploaderName());
- binding.uploadDate.setText(Localization.relativeTimeOrTextual(
- getContext(), item.getUploadDate(), item.getTextualUploadDate()));
- binding.authorTouchArea.setOnClickListener(
- v -> NavigationHelper.openCommentAuthorIfPresent(requireActivity(), item));
-
- // setup like count, hearted and pinned
- binding.thumbsUpCount.setText(
- Localization.likeCount(requireContext(), item.getLikeCount()));
- // for heartImage goneMarginEnd was used, but there is no way to tell ConstraintLayout
- // not to use a different margin only when both the next two views are gone
- ((ConstraintLayout.LayoutParams) binding.thumbsUpCount.getLayoutParams())
- .setMarginEnd(DeviceUtils.dpToPx(
- (item.isHeartedByUploader() || item.isPinned() ? 8 : 16),
- requireContext()));
- binding.heartImage.setVisibility(item.isHeartedByUploader() ? View.VISIBLE : View.GONE);
- binding.pinnedImage.setVisibility(item.isPinned() ? View.VISIBLE : View.GONE);
-
- // setup comment content
- TextLinkifier.fromDescription(binding.commentContent, item.getCommentText(),
- HtmlCompat.FROM_HTML_MODE_LEGACY, getServiceById(item.getServiceId()),
- item.getUrl(), disposables, null);
-
- return binding.getRoot();
- };
- }
-
-
- /*//////////////////////////////////////////////////////////////////////////
- // State saving
- //////////////////////////////////////////////////////////////////////////*/
-
- @Override
- public void writeTo(final Queue