diff --git a/app/build.gradle b/app/build.gradle
index 2234a8ebf..51762db75 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -220,6 +220,7 @@ dependencies {
// https://developer.android.com/jetpack/androidx/releases/viewpager2#1.1.0-alpha01
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
implementation 'androidx.webkit:webkit:1.4.0'
+ implementation 'androidx.work:work-runtime:2.7.1'
implementation 'com.google.android.material:material:1.5.0'
/** Third-party libraries **/
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 28cdbf020..f9c99819c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -381,9 +381,6 @@
-
diff --git a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
deleted file mode 100644
index 122660d64..000000000
--- a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
+++ /dev/null
@@ -1,264 +0,0 @@
-package org.schabi.newpipe;
-
-import android.app.Application;
-import android.app.IntentService;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.pm.Signature;
-import android.net.Uri;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.app.NotificationCompat;
-import androidx.core.app.NotificationManagerCompat;
-import androidx.core.content.pm.PackageInfoCompat;
-import androidx.preference.PreferenceManager;
-
-import com.grack.nanojson.JsonObject;
-import com.grack.nanojson.JsonParser;
-import com.grack.nanojson.JsonParserException;
-
-import org.schabi.newpipe.error.ErrorInfo;
-import org.schabi.newpipe.error.ErrorUtil;
-import org.schabi.newpipe.error.UserAction;
-import org.schabi.newpipe.extractor.downloader.Response;
-import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.List;
-
-public final class CheckForNewAppVersion extends IntentService {
- public CheckForNewAppVersion() {
- super("CheckForNewAppVersion");
- }
-
- private static final boolean DEBUG = MainActivity.DEBUG;
- private static final String TAG = CheckForNewAppVersion.class.getSimpleName();
-
- // Public key of the certificate that is used in NewPipe release versions
- private static final String RELEASE_CERT_PUBLIC_KEY_SHA1
- = "B0:2E:90:7C:1C:D6:FC:57:C3:35:F0:88:D0:8F:50:5F:94:E4:D2:15";
- private static final String NEWPIPE_API_URL = "https://newpipe.net/api/data.json";
-
- /**
- * Method to get the APK's SHA1 key. See https://stackoverflow.com/questions/9293019/#22506133.
- *
- * @param application The application
- * @return String with the APK's SHA1 fingerprint in hexadecimal
- */
- @NonNull
- private static String getCertificateSHA1Fingerprint(@NonNull final Application application) {
- final List signatures;
- try {
- signatures = PackageInfoCompat.getSignatures(application.getPackageManager(),
- application.getPackageName());
- } catch (final PackageManager.NameNotFoundException e) {
- ErrorUtil.createNotification(application, new ErrorInfo(e,
- UserAction.CHECK_FOR_NEW_APP_VERSION, "Could not find package info"));
- return "";
- }
- if (signatures.isEmpty()) {
- return "";
- }
-
- final X509Certificate c;
- try {
- final byte[] cert = signatures.get(0).toByteArray();
- final InputStream input = new ByteArrayInputStream(cert);
- final CertificateFactory cf = CertificateFactory.getInstance("X509");
- c = (X509Certificate) cf.generateCertificate(input);
- } catch (final CertificateException e) {
- ErrorUtil.createNotification(application, new ErrorInfo(e,
- UserAction.CHECK_FOR_NEW_APP_VERSION, "Certificate error"));
- return "";
- }
-
- try {
- final MessageDigest md = MessageDigest.getInstance("SHA1");
- final byte[] publicKey = md.digest(c.getEncoded());
- return byte2HexFormatted(publicKey);
- } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
- ErrorUtil.createNotification(application, new ErrorInfo(e,
- UserAction.CHECK_FOR_NEW_APP_VERSION, "Could not retrieve SHA1 key"));
- return "";
- }
- }
-
- private static String byte2HexFormatted(final byte[] arr) {
- final StringBuilder str = new StringBuilder(arr.length * 2);
-
- for (int i = 0; i < arr.length; i++) {
- String h = Integer.toHexString(arr[i]);
- final int l = h.length();
- if (l == 1) {
- h = "0" + h;
- }
- if (l > 2) {
- h = h.substring(l - 2, l);
- }
- str.append(h.toUpperCase());
- if (i < (arr.length - 1)) {
- str.append(':');
- }
- }
- return str.toString();
- }
-
- /**
- * Method to compare the current and latest available app version.
- * If a newer version is available, we show the update notification.
- *
- * @param application The application
- * @param versionName Name of new version
- * @param apkLocationUrl Url with the new apk
- * @param versionCode Code of new version
- */
- private static void compareAppVersionAndShowNotification(@NonNull final Application application,
- final String versionName,
- final String apkLocationUrl,
- final int versionCode) {
- if (BuildConfig.VERSION_CODE >= versionCode) {
- return;
- }
-
- // A pending intent to open the apk location url in the browser.
- final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(apkLocationUrl));
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- final PendingIntent pendingIntent
- = PendingIntent.getActivity(application, 0, intent, 0);
-
- final String channelId = application
- .getString(R.string.app_update_notification_channel_id);
- final NotificationCompat.Builder notificationBuilder
- = new NotificationCompat.Builder(application, channelId)
- .setSmallIcon(R.drawable.ic_newpipe_update)
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
- .setContentIntent(pendingIntent)
- .setAutoCancel(true)
- .setContentTitle(application
- .getString(R.string.app_update_notification_content_title))
- .setContentText(application
- .getString(R.string.app_update_notification_content_text)
- + " " + versionName);
-
- final NotificationManagerCompat notificationManager
- = NotificationManagerCompat.from(application);
- notificationManager.notify(2000, notificationBuilder.build());
- }
-
- public static boolean isReleaseApk(@NonNull final App app) {
- return getCertificateSHA1Fingerprint(app).equals(RELEASE_CERT_PUBLIC_KEY_SHA1);
- }
-
- private void checkNewVersion() throws IOException, ReCaptchaException {
- final App app = App.getApp();
-
- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
- final NewVersionManager manager = new NewVersionManager();
-
- // Check if the current apk is a github one or not.
- if (!isReleaseApk(app)) {
- return;
- }
-
- // Check if the last request has happened a certain time ago
- // to reduce the number of API requests.
- final long expiry = prefs.getLong(app.getString(R.string.update_expiry_key), 0);
- if (!manager.isExpired(expiry)) {
- return;
- }
-
- // Make a network request to get latest NewPipe data.
- final Response response = DownloaderImpl.getInstance().get(NEWPIPE_API_URL);
- handleResponse(response, manager, prefs, app);
- }
-
- private void handleResponse(@NonNull final Response response,
- @NonNull final NewVersionManager manager,
- @NonNull final SharedPreferences prefs,
- @NonNull final App app) {
- try {
- // Store a timestamp which needs to be exceeded,
- // before a new request to the API is made.
- final long newExpiry = manager
- .coerceExpiry(response.getHeader("expires"));
- prefs.edit()
- .putLong(app.getString(R.string.update_expiry_key), newExpiry)
- .apply();
- } catch (final Exception e) {
- if (DEBUG) {
- Log.w(TAG, "Could not extract and save new expiry date", e);
- }
- }
-
- // Parse the json from the response.
- try {
-
- final JsonObject githubStableObject = JsonParser.object()
- .from(response.responseBody()).getObject("flavors")
- .getObject("github").getObject("stable");
-
- final String versionName = githubStableObject
- .getString("version");
- final int versionCode = githubStableObject
- .getInt("version_code");
- final String apkLocationUrl = githubStableObject
- .getString("apk");
-
- compareAppVersionAndShowNotification(app, versionName,
- apkLocationUrl, versionCode);
- } catch (final JsonParserException e) {
- // Most likely something is wrong in data received from NEWPIPE_API_URL.
- // Do not alarm user and fail silently.
- if (DEBUG) {
- Log.w(TAG, "Could not get NewPipe API: invalid json", e);
- }
- }
- }
-
- /**
- * Start a new service which
- * checks if all conditions for performing a version check are met,
- * fetches the API endpoint {@link #NEWPIPE_API_URL} containing info
- * about the latest NewPipe version
- * and displays a notification about ana available update.
- *
- * Following conditions need to be met, before data is request from the server:
- *
- * - The app is signed with the correct signing key (by TeamNewPipe / schabi).
- * If the signing key differs from the one used upstream, the update cannot be installed.
- * - The user enabled searching for and notifying about updates in the settings.
- * - The app did not recently check for updates.
- * We do not want to make unnecessary connections and DOS our servers.
- *
- * Must not be executed when the app is in background.
- */
- public static void startNewVersionCheckService() {
- final Intent intent = new Intent(App.getApp().getApplicationContext(),
- CheckForNewAppVersion.class);
- App.getApp().startService(intent);
- }
-
- @Override
- protected void onHandleIntent(@Nullable final Intent intent) {
- try {
- checkNewVersion();
- } catch (final IOException e) {
- Log.w(TAG, "Could not fetch NewPipe API: probably network problem", e);
- } catch (final ReCaptchaException e) {
- Log.e(TAG, "ReCaptchaException should never happen here.", e);
- }
-
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java
index 95663ea0a..b208d8443 100644
--- a/app/src/main/java/org/schabi/newpipe/MainActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java
@@ -20,7 +20,6 @@
package org.schabi.newpipe;
-import static org.schabi.newpipe.CheckForNewAppVersion.startNewVersionCheckService;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import android.content.BroadcastReceiver;
@@ -174,10 +173,9 @@ public class MainActivity extends AppCompatActivity {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
if (prefs.getBoolean(app.getString(R.string.update_app_key), true)) {
- // Start the service which is checking all conditions
+ // Start the worker which is checking all conditions
// and eventually searching for a new version.
- // The service searching for a new NewPipe version must not be started in background.
- startNewVersionCheckService();
+ NewVersionWorker.enqueueNewVersionCheckingWork(app);
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/NewVersionManager.kt b/app/src/main/java/org/schabi/newpipe/NewVersionManager.kt
deleted file mode 100644
index 36de1ecfc..000000000
--- a/app/src/main/java/org/schabi/newpipe/NewVersionManager.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.schabi.newpipe
-
-import java.time.Instant
-import java.time.ZonedDateTime
-import java.time.format.DateTimeFormatter
-
-class NewVersionManager {
-
- fun isExpired(expiry: Long): Boolean {
- return Instant.ofEpochSecond(expiry).isBefore(Instant.now())
- }
-
- /**
- * Coerce expiry date time in between 6 hours and 72 hours from now
- *
- * @return Epoch second of expiry date time
- */
- fun coerceExpiry(expiryString: String?): Long {
- val now = ZonedDateTime.now()
- return expiryString?.let {
-
- var expiry = ZonedDateTime.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(expiryString))
- expiry = maxOf(expiry, now.plusHours(6))
- expiry = minOf(expiry, now.plusHours(72))
- expiry.toEpochSecond()
- } ?: now.plusHours(6).toEpochSecond()
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt b/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt
new file mode 100644
index 000000000..060114974
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt
@@ -0,0 +1,163 @@
+package org.schabi.newpipe
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.util.Log
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import androidx.core.content.edit
+import androidx.core.net.toUri
+import androidx.preference.PreferenceManager
+import androidx.work.OneTimeWorkRequest
+import androidx.work.WorkManager
+import androidx.work.WorkRequest
+import androidx.work.Worker
+import androidx.work.WorkerParameters
+import com.grack.nanojson.JsonParser
+import com.grack.nanojson.JsonParserException
+import org.schabi.newpipe.extractor.downloader.Response
+import org.schabi.newpipe.extractor.exceptions.ReCaptchaException
+import org.schabi.newpipe.util.ReleaseVersionUtil.coerceUpdateCheckExpiry
+import org.schabi.newpipe.util.ReleaseVersionUtil.isLastUpdateCheckExpired
+import org.schabi.newpipe.util.ReleaseVersionUtil.isReleaseApk
+import java.io.IOException
+
+class NewVersionWorker(
+ context: Context,
+ workerParams: WorkerParameters
+) : Worker(context, workerParams) {
+
+ /**
+ * Method to compare the current and latest available app version.
+ * If a newer version is available, we show the update notification.
+ *
+ * @param versionName Name of new version
+ * @param apkLocationUrl Url with the new apk
+ * @param versionCode Code of new version
+ */
+ private fun compareAppVersionAndShowNotification(
+ versionName: String,
+ apkLocationUrl: String?,
+ versionCode: Int
+ ) {
+ if (BuildConfig.VERSION_CODE >= versionCode) {
+ return
+ }
+ val app = App.getApp()
+
+ // A pending intent to open the apk location url in the browser.
+ val intent = Intent(Intent.ACTION_VIEW, apkLocationUrl?.toUri())
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ val pendingIntent = PendingIntent.getActivity(app, 0, intent, 0)
+ val channelId = app.getString(R.string.app_update_notification_channel_id)
+ val notificationBuilder = NotificationCompat.Builder(app, channelId)
+ .setSmallIcon(R.drawable.ic_newpipe_update)
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ .setContentIntent(pendingIntent)
+ .setAutoCancel(true)
+ .setContentTitle(app.getString(R.string.app_update_notification_content_title))
+ .setContentText(
+ app.getString(R.string.app_update_notification_content_text) +
+ " " + versionName
+ )
+ val notificationManager = NotificationManagerCompat.from(app)
+ notificationManager.notify(2000, notificationBuilder.build())
+ }
+
+ @Throws(IOException::class, ReCaptchaException::class)
+ private fun checkNewVersion() {
+ // Check if the current apk is a github one or not.
+ if (!isReleaseApk()) {
+ return
+ }
+
+ val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
+ // Check if the last request has happened a certain time ago
+ // to reduce the number of API requests.
+ val expiry = prefs.getLong(applicationContext.getString(R.string.update_expiry_key), 0)
+ if (!isLastUpdateCheckExpired(expiry)) {
+ return
+ }
+
+ // Make a network request to get latest NewPipe data.
+ val response = DownloaderImpl.getInstance().get(NEWPIPE_API_URL)
+ handleResponse(response)
+ }
+
+ private fun handleResponse(response: Response) {
+ val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
+ try {
+ // Store a timestamp which needs to be exceeded,
+ // before a new request to the API is made.
+ val newExpiry = coerceUpdateCheckExpiry(response.getHeader("expires"))
+ prefs.edit {
+ putLong(applicationContext.getString(R.string.update_expiry_key), newExpiry)
+ }
+ } catch (e: Exception) {
+ if (DEBUG) {
+ Log.w(TAG, "Could not extract and save new expiry date", e)
+ }
+ }
+
+ // Parse the json from the response.
+ try {
+ val githubStableObject = JsonParser.`object`()
+ .from(response.responseBody()).getObject("flavors")
+ .getObject("github").getObject("stable")
+
+ val versionName = githubStableObject.getString("version")
+ val versionCode = githubStableObject.getInt("version_code")
+ val apkLocationUrl = githubStableObject.getString("apk")
+ compareAppVersionAndShowNotification(versionName, apkLocationUrl, versionCode)
+ } catch (e: JsonParserException) {
+ // Most likely something is wrong in data received from NEWPIPE_API_URL.
+ // Do not alarm user and fail silently.
+ if (DEBUG) {
+ Log.w(TAG, "Could not get NewPipe API: invalid json", e)
+ }
+ }
+ }
+
+ override fun doWork(): Result {
+ try {
+ checkNewVersion()
+ } catch (e: IOException) {
+ Log.w(TAG, "Could not fetch NewPipe API: probably network problem", e)
+ return Result.failure()
+ } catch (e: ReCaptchaException) {
+ Log.e(TAG, "ReCaptchaException should never happen here.", e)
+ return Result.failure()
+ }
+ return Result.success()
+ }
+
+ companion object {
+ private val DEBUG = MainActivity.DEBUG
+ private val TAG = NewVersionWorker::class.java.simpleName
+ private const val NEWPIPE_API_URL = "https://newpipe.net/api/data.json"
+
+ /**
+ * Start a new worker which
+ * checks if all conditions for performing a version check are met,
+ * fetches the API endpoint [.NEWPIPE_API_URL] containing info
+ * about the latest NewPipe version
+ * and displays a notification about ana available update.
+ *
+ * Following conditions need to be met, before data is request from the server:
+ *
+ * * The app is signed with the correct signing key (by TeamNewPipe / schabi).
+ * If the signing key differs from the one used upstream, the update cannot be installed.
+ * * The user enabled searching for and notifying about updates in the settings.
+ * * The app did not recently check for updates.
+ * We do not want to make unnecessary connections and DOS our servers.
+ *
+ */
+ @JvmStatic
+ fun enqueueNewVersionCheckingWork(context: Context) {
+ val workRequest: WorkRequest =
+ OneTimeWorkRequest.Builder(NewVersionWorker::class.java).build()
+ WorkManager.getInstance(context).enqueue(workRequest)
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java
index 9ea6c020d..0eb56d716 100644
--- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java
@@ -350,7 +350,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment removeWatchedStreams(false))
.setNeutralButton(
R.string.remove_watched_popup_yes_and_partially_watched_videos,
diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java
index e0c5ab083..4bee4ec36 100644
--- a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java
@@ -1,5 +1,9 @@
package org.schabi.newpipe.player;
+import static org.schabi.newpipe.QueueItemMenuUtil.openPopupMenu;
+import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed;
+import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -23,11 +27,9 @@ import androidx.recyclerview.widget.RecyclerView;
import com.google.android.exoplayer2.PlaybackParameters;
import org.schabi.newpipe.R;
-import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.ActivityPlayerQueueControlBinding;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
-import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.player.event.PlayerEventListener;
import org.schabi.newpipe.player.helper.PlaybackParameterDialog;
import org.schabi.newpipe.player.playqueue.PlayQueue;
@@ -42,13 +44,6 @@ import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.ThemeHelper;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static org.schabi.newpipe.QueueItemMenuUtil.openPopupMenu;
-import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed;
-import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
-
public final class PlayQueueActivity extends AppCompatActivity
implements PlayerEventListener, SeekBar.OnSeekBarChangeListener,
View.OnClickListener, PlaybackParameterDialog.Callback {
@@ -129,7 +124,7 @@ public final class PlayQueueActivity extends AppCompatActivity
NavigationHelper.openSettings(this);
return true;
case R.id.action_append_playlist:
- appendAllToPlaylist();
+ player.onAddToPlaylistClicked(getSupportFragmentManager());
return true;
case R.id.action_playback_speed:
openPlaybackParameterDialog();
@@ -443,24 +438,6 @@ public final class PlayQueueActivity extends AppCompatActivity
seeking = false;
}
- ////////////////////////////////////////////////////////////////////////////
- // Playlist append
- ////////////////////////////////////////////////////////////////////////////
-
- private void appendAllToPlaylist() {
- if (player != null && player.getPlayQueue() != null) {
- openPlaylistAppendDialog(player.getPlayQueue().getStreams());
- }
- }
-
- private void openPlaylistAppendDialog(final List playQueueItems) {
- PlaylistDialog.createCorrespondingDialog(
- getApplicationContext(),
- playQueueItems.stream().map(StreamEntity::new).collect(Collectors.toList()),
- dialog -> dialog.show(getSupportFragmentManager(), TAG)
- );
- }
-
////////////////////////////////////////////////////////////////////////////
// Binding Service Listener
////////////////////////////////////////////////////////////////////////////
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 85a50cb23..2bdb14901 100644
--- a/app/src/main/java/org/schabi/newpipe/player/Player.java
+++ b/app/src/main/java/org/schabi/newpipe/player/Player.java
@@ -105,6 +105,7 @@ import androidx.core.graphics.Insets;
import androidx.core.view.GestureDetectorCompat;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
+import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
@@ -138,6 +139,7 @@ import com.squareup.picasso.Target;
import org.schabi.newpipe.DownloaderImpl;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
+import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.PlayerBinding;
import org.schabi.newpipe.databinding.PlayerPopupCloseOverlayBinding;
import org.schabi.newpipe.error.ErrorInfo;
@@ -152,6 +154,7 @@ import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
import org.schabi.newpipe.info_list.StreamSegmentAdapter;
import org.schabi.newpipe.ktx.AnimationType;
+import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.player.MainPlayer.PlayerType;
import org.schabi.newpipe.player.event.DisplayPortion;
@@ -197,6 +200,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import java.util.stream.Collectors;
import java.util.stream.IntStream;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
@@ -541,6 +545,7 @@ public final class Player implements
binding.segmentsButton.setOnClickListener(this);
binding.repeatButton.setOnClickListener(this);
binding.shuffleButton.setOnClickListener(this);
+ binding.addToPlaylistButton.setOnClickListener(this);
binding.playPauseButton.setOnClickListener(this);
binding.playPreviousButton.setOnClickListener(this);
@@ -2389,6 +2394,32 @@ public final class Player implements
+ /*//////////////////////////////////////////////////////////////////////////
+ // Playlist append
+ //////////////////////////////////////////////////////////////////////////*/
+ //region Playlist append
+
+ public void onAddToPlaylistClicked(@NonNull final FragmentManager fragmentManager) {
+ if (DEBUG) {
+ Log.d(TAG, "onAddToPlaylistClicked() called");
+ }
+
+ if (getPlayQueue() != null) {
+ PlaylistDialog.createCorrespondingDialog(
+ getContext(),
+ getPlayQueue()
+ .getStreams()
+ .stream()
+ .map(StreamEntity::new)
+ .collect(Collectors.toList()),
+ dialog -> dialog.show(fragmentManager, TAG)
+ );
+ }
+ }
+ //endregion
+
+
+
/*//////////////////////////////////////////////////////////////////////////
// Mute / Unmute
//////////////////////////////////////////////////////////////////////////*/
@@ -3131,6 +3162,7 @@ public final class Player implements
binding.itemsListHeaderDuration.setVisibility(View.VISIBLE);
binding.shuffleButton.setVisibility(View.VISIBLE);
binding.repeatButton.setVisibility(View.VISIBLE);
+ binding.addToPlaylistButton.setVisibility(View.VISIBLE);
hideControls(0, 0);
binding.itemsListPanel.requestFocus();
@@ -3168,6 +3200,7 @@ public final class Player implements
binding.itemsListHeaderDuration.setVisibility(View.GONE);
binding.shuffleButton.setVisibility(View.GONE);
binding.repeatButton.setVisibility(View.GONE);
+ binding.addToPlaylistButton.setVisibility(View.GONE);
hideControls(0, 0);
binding.itemsListPanel.requestFocus();
@@ -3196,6 +3229,7 @@ public final class Player implements
binding.shuffleButton.setVisibility(View.GONE);
binding.repeatButton.setVisibility(View.GONE);
+ binding.addToPlaylistButton.setVisibility(View.GONE);
binding.itemsListClose.setOnClickListener(view -> closeItemsList());
}
@@ -3733,6 +3767,11 @@ public final class Player implements
} else if (v.getId() == binding.shuffleButton.getId()) {
onShuffleClicked();
return;
+ } else if (v.getId() == binding.addToPlaylistButton.getId()) {
+ if (getParentActivity() != null) {
+ onAddToPlaylistClicked(getParentActivity().getSupportFragmentManager());
+ }
+ return;
} else if (v.getId() == binding.moreOptionsButton.getId()) {
onMoreOptionsClicked();
} else if (v.getId() == binding.share.getId()) {
@@ -3799,6 +3838,10 @@ public final class Player implements
case KeyEvent.KEYCODE_SPACE:
if (isFullscreen) {
playPause();
+ if (isPlaying()) {
+ hideControls(0, 0);
+ }
+ return true;
}
break;
case KeyEvent.KEYCODE_BACK:
diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/PlayerMediaSession.java b/app/src/main/java/org/schabi/newpipe/player/playback/PlayerMediaSession.java
index 9dcb12344..ee0a6f118 100644
--- a/app/src/main/java/org/schabi/newpipe/player/playback/PlayerMediaSession.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playback/PlayerMediaSession.java
@@ -88,6 +88,8 @@ public class PlayerMediaSession implements MediaSessionCallback {
@Override
public void play() {
player.play();
+ // hide the player controls even if the play command came from the media session
+ player.hideControls(0, 0);
}
@Override
diff --git a/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java
index d7fb559d6..3776d78f6 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java
@@ -7,10 +7,9 @@ import android.view.MenuItem;
import androidx.annotation.NonNull;
-import org.schabi.newpipe.App;
-import org.schabi.newpipe.CheckForNewAppVersion;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
+import org.schabi.newpipe.util.ReleaseVersionUtil;
public class MainSettingsFragment extends BasePreferenceFragment {
public static final boolean DEBUG = MainActivity.DEBUG;
@@ -24,7 +23,7 @@ public class MainSettingsFragment extends BasePreferenceFragment {
setHasOptionsMenu(true); // Otherwise onCreateOptionsMenu is not called
// Check if the app is updatable
- if (!CheckForNewAppVersion.isReleaseApk(App.getApp())) {
+ if (!ReleaseVersionUtil.isReleaseApk()) {
getPreferenceScreen().removePreference(
findPreference(getString(R.string.update_pref_screen_key)));
diff --git a/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java
index dfc053a62..391f17383 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java
@@ -191,7 +191,7 @@ public class PeertubeInstanceListFragment extends Fragment {
.setTitle(R.string.restore_defaults)
.setMessage(R.string.restore_defaults_confirmation)
.setNegativeButton(R.string.cancel, null)
- .setPositiveButton(R.string.yes, (dialog, which) -> {
+ .setPositiveButton(R.string.ok, (dialog, which) -> {
sharedPreferences.edit().remove(savedInstanceListKey).apply();
selectInstance(PeertubeInstance.defaultInstance);
updateInstanceList();
diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java
index 7510bb3bc..7078514dd 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java
@@ -23,8 +23,6 @@ import androidx.preference.PreferenceFragmentCompat;
import com.jakewharton.rxbinding4.widget.RxTextView;
-import org.schabi.newpipe.App;
-import org.schabi.newpipe.CheckForNewAppVersion;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.SettingsLayoutBinding;
@@ -37,6 +35,7 @@ import org.schabi.newpipe.settings.preferencesearch.PreferenceSearchResultListen
import org.schabi.newpipe.settings.preferencesearch.PreferenceSearcher;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.KeyboardUtil;
+import org.schabi.newpipe.util.ReleaseVersionUtil;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.views.FocusOverlayView;
@@ -267,7 +266,7 @@ public class SettingsActivity extends AppCompatActivity implements
*/
private void ensureSearchRepresentsApplicationState() {
// Check if the update settings are available
- if (!CheckForNewAppVersion.isReleaseApk(App.getApp())) {
+ if (!ReleaseVersionUtil.isReleaseApk()) {
SettingsResourceRegistry.getInstance()
.getEntryByPreferencesResId(R.xml.update_settings)
.setSearchable(false);
diff --git a/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java
index 04bad3815..1043e88c2 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java
@@ -1,12 +1,11 @@
package org.schabi.newpipe.settings;
-import static org.schabi.newpipe.CheckForNewAppVersion.startNewVersionCheckService;
-
import android.os.Bundle;
import android.widget.Toast;
import androidx.preference.Preference;
+import org.schabi.newpipe.NewVersionWorker;
import org.schabi.newpipe.R;
public class UpdateSettingsFragment extends BasePreferenceFragment {
@@ -33,7 +32,7 @@ public class UpdateSettingsFragment extends BasePreferenceFragment {
// Reset the expire time. This is necessary to check for an update immediately.
defaultPreferences.edit()
.putLong(getString(R.string.update_expiry_key), 0).apply();
- startNewVersionCheckService();
+ NewVersionWorker.enqueueNewVersionCheckingWork(getContext());
}
@Override
diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java
index 490e299bd..eb879d2f2 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java
@@ -136,7 +136,7 @@ public class ChooseTabsFragment extends Fragment {
.setTitle(R.string.restore_defaults)
.setMessage(R.string.restore_defaults_confirmation)
.setNegativeButton(R.string.cancel, null)
- .setPositiveButton(R.string.yes, (dialog, which) -> {
+ .setPositiveButton(R.string.ok, (dialog, which) -> {
tabsManager.resetTabs();
updateTabList();
selectedTabsAdapter.notifyDataSetChanged();
diff --git a/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
new file mode 100644
index 000000000..21a9059e2
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
@@ -0,0 +1,116 @@
+package org.schabi.newpipe.util
+
+import android.content.pm.PackageManager
+import android.content.pm.Signature
+import androidx.core.content.pm.PackageInfoCompat
+import org.schabi.newpipe.App
+import org.schabi.newpipe.error.ErrorInfo
+import org.schabi.newpipe.error.ErrorUtil.Companion.createNotification
+import org.schabi.newpipe.error.UserAction
+import java.io.ByteArrayInputStream
+import java.io.InputStream
+import java.security.MessageDigest
+import java.security.NoSuchAlgorithmException
+import java.security.cert.CertificateEncodingException
+import java.security.cert.CertificateException
+import java.security.cert.CertificateFactory
+import java.security.cert.X509Certificate
+import java.time.Instant
+import java.time.ZonedDateTime
+import java.time.format.DateTimeFormatter
+
+object ReleaseVersionUtil {
+ // Public key of the certificate that is used in NewPipe release versions
+ private const val RELEASE_CERT_PUBLIC_KEY_SHA1 =
+ "B0:2E:90:7C:1C:D6:FC:57:C3:35:F0:88:D0:8F:50:5F:94:E4:D2:15"
+
+ @JvmStatic
+ fun isReleaseApk(): Boolean {
+ return certificateSHA1Fingerprint == RELEASE_CERT_PUBLIC_KEY_SHA1
+ }
+
+ /**
+ * Method to get the APK's SHA1 key. See https://stackoverflow.com/questions/9293019/#22506133.
+ *
+ * @return String with the APK's SHA1 fingerprint in hexadecimal
+ */
+ private val certificateSHA1Fingerprint: String
+ get() {
+ val app = App.getApp()
+ val signatures: List = try {
+ PackageInfoCompat.getSignatures(app.packageManager, app.packageName)
+ } catch (e: PackageManager.NameNotFoundException) {
+ showRequestError(app, e, "Could not find package info")
+ return ""
+ }
+ if (signatures.isEmpty()) {
+ return ""
+ }
+ val x509cert = try {
+ val cert = signatures[0].toByteArray()
+ val input: InputStream = ByteArrayInputStream(cert)
+ val cf = CertificateFactory.getInstance("X509")
+ cf.generateCertificate(input) as X509Certificate
+ } catch (e: CertificateException) {
+ showRequestError(app, e, "Certificate error")
+ return ""
+ }
+
+ return try {
+ val md = MessageDigest.getInstance("SHA1")
+ val publicKey = md.digest(x509cert.encoded)
+ byte2HexFormatted(publicKey)
+ } catch (e: NoSuchAlgorithmException) {
+ showRequestError(app, e, "Could not retrieve SHA1 key")
+ ""
+ } catch (e: CertificateEncodingException) {
+ showRequestError(app, e, "Could not retrieve SHA1 key")
+ ""
+ }
+ }
+
+ private fun byte2HexFormatted(arr: ByteArray): String {
+ val str = StringBuilder(arr.size * 2)
+ for (i in arr.indices) {
+ var h = Integer.toHexString(arr[i].toInt())
+ val l = h.length
+ if (l == 1) {
+ h = "0$h"
+ }
+ if (l > 2) {
+ h = h.substring(l - 2, l)
+ }
+ str.append(h.uppercase())
+ if (i < arr.size - 1) {
+ str.append(':')
+ }
+ }
+ return str.toString()
+ }
+
+ private fun showRequestError(app: App, e: Exception, request: String) {
+ createNotification(
+ app, ErrorInfo(e, UserAction.CHECK_FOR_NEW_APP_VERSION, request)
+ )
+ }
+
+ fun isLastUpdateCheckExpired(expiry: Long): Boolean {
+ return Instant.ofEpochSecond(expiry).isBefore(Instant.now())
+ }
+
+ /**
+ * Coerce expiry date time in between 6 hours and 72 hours from now
+ *
+ * @return Epoch second of expiry date time
+ */
+ fun coerceUpdateCheckExpiry(expiryString: String?): Long {
+ val now = ZonedDateTime.now()
+ return expiryString?.let {
+ var expiry =
+ ZonedDateTime.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(expiryString))
+ expiry = maxOf(expiry, now.plusHours(6))
+ expiry = minOf(expiry, now.plusHours(72))
+ expiry.toEpochSecond()
+ } ?: now.plusHours(6).toEpochSecond()
+ }
+}
diff --git a/app/src/main/res/layout/player.xml b/app/src/main/res/layout/player.xml
index 1fc769c18..a6043c65a 100644
--- a/app/src/main/res/layout/player.xml
+++ b/app/src/main/res/layout/player.xml
@@ -581,6 +581,21 @@
app:srcCompat="@drawable/ic_close"
app:tint="@color/white" />
+
+
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index a13589c19..d25b478ef 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -91,7 +91,6 @@
محتوى مقيد للبالغين
بث مباشر
تقرير عن المشكلة
- نعم
متوقف
تنظيف
أفضل دقة
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index faad933a7..3e3ac2428 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -169,7 +169,6 @@
Ən yaxşı görüntü keyfiyyəti
Təmizlə
Deaktiv edilib
- Bəli
İfaçılar
Albomlar
Mahnılar
diff --git a/app/src/main/res/values-b+ast/strings.xml b/app/src/main/res/values-b+ast/strings.xml
index aab0a83bb..29611db80 100644
--- a/app/src/main/res/values-b+ast/strings.xml
+++ b/app/src/main/res/values-b+ast/strings.xml
@@ -44,7 +44,6 @@
Tarrezmes
Formatu de videu predetermináu
Prietu
- Sí
mil
mill.
mil mill.
diff --git a/app/src/main/res/values-b+uz+Latn/strings.xml b/app/src/main/res/values-b+uz+Latn/strings.xml
index f984fbea9..6f5a5e8fc 100644
--- a/app/src/main/res/values-b+uz+Latn/strings.xml
+++ b/app/src/main/res/values-b+uz+Latn/strings.xml
@@ -112,7 +112,6 @@
Eng yaxshi qaror
Tozalash
Ijrochilar o\'chirib qo\'yilgan
- Ha
Artistlar
Albomlar
Qo\'shiqlar
diff --git a/app/src/main/res/values-b+zh+HANS+CN/strings.xml b/app/src/main/res/values-b+zh+HANS+CN/strings.xml
index 9ae77924a..d9f874de8 100644
--- a/app/src/main/res/values-b+zh+HANS+CN/strings.xml
+++ b/app/src/main/res/values-b+zh+HANS+CN/strings.xml
@@ -28,7 +28,6 @@
不支持的 URL
外观
全部
- 是
网络错误
- %s 个视频
diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml
index 249b8ca38..ef81078e2 100644
--- a/app/src/main/res/values-be/strings.xml
+++ b/app/src/main/res/values-be/strings.xml
@@ -97,7 +97,6 @@
Плэйлісты
Дарожкі
Карыстальнікі
- Так
Адключана
Ачысціць
Лепшае разрозненне
diff --git a/app/src/main/res/values-ber/strings.xml b/app/src/main/res/values-ber/strings.xml
index 6d49cad2b..0d6c89db5 100644
--- a/app/src/main/res/values-ber/strings.xml
+++ b/app/src/main/res/values-ber/strings.xml
@@ -56,7 +56,6 @@
ⴰⴼⴰⵢⵍⵓ
ⵖⵔ ⵎⴰⵕⵕⴰ
ⵉⵜⵜⵡⴰⴽⴽⵙ ⵓⴼⴰⵢⵍⵓ
- ⵢⴰⵀ
ⵉⴼⵉⴷⵢⵓⵜⵏ
ⵎⴰⵕⵕⴰ
ⵓⴳⴳⴰⵎⵏ
diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml
index 5aac01afb..73c240aae 100644
--- a/app/src/main/res/values-bg/strings.xml
+++ b/app/src/main/res/values-bg/strings.xml
@@ -75,7 +75,6 @@
Изтегляния
Съобщение за грешка
Всички
- Да
Забранено
Изчисти
Най-добра резолюция
diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml
index 8a014cdf8..807de8735 100644
--- a/app/src/main/res/values-bn-rBD/strings.xml
+++ b/app/src/main/res/values-bn-rBD/strings.xml
@@ -55,7 +55,6 @@
ডাউনলোডগুলি
ত্রুটি প্রতিবেদন
সবগুলি
- হ্যাঁ
নিস্ক্রীয়
পরিষ্কার
diff --git a/app/src/main/res/values-bn-rIN/strings.xml b/app/src/main/res/values-bn-rIN/strings.xml
index d087905a4..ff864b337 100644
--- a/app/src/main/res/values-bn-rIN/strings.xml
+++ b/app/src/main/res/values-bn-rIN/strings.xml
@@ -53,7 +53,6 @@
সবসময়
পরিষ্কার
নিস্ক্রীয়
- হ্যাঁ
সবগুলি
ত্রুটি প্রতিবেদন
ডাউনলোডগুলি
diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml
index 89a95c6fb..c17f34ae0 100644
--- a/app/src/main/res/values-bn/strings.xml
+++ b/app/src/main/res/values-bn/strings.xml
@@ -176,7 +176,6 @@
সেরা রেজুলিউসন
পরিষ্কার
নিস্ক্রীয়
- হ্যাঁ
শিল্পীরা
অ্যালবাম গুলি
গান গুলি
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 13b8c5ac3..15e43a307 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -37,7 +37,6 @@
Baixades
Baixades
Tot
- Sí
Desactivat
Neteja
Millor resolució
diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml
index 036aa19f5..2eacf992f 100644
--- a/app/src/main/res/values-ckb/strings.xml
+++ b/app/src/main/res/values-ckb/strings.xml
@@ -101,7 +101,6 @@
مۆڵەتنامەی لایەنی-سێیەم
مۆڵەتنامەی نیوپایپ
پیشاندانی ڕێنمایی ”داگرتن تا پاشکۆ”
- بەڵێ
دابەشکراوەکان
زۆرترین لێدراو
لادانی نیشانهكراو
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index f65a350fe..2b9df57f7 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -84,7 +84,6 @@
Určete prosím složku pro stahování později v nastavení
Co:\\nŽádost:\\nJazyk obsahu\\nZemě obsahu:\\nJazyk aplikace:\\nSlužba:\\nČas GMT:\\nBalíček:\\nVerze:\\nVerze OS:
Vše
- Ano
tis.
Otevřít ve vyskakovacím okně
mil.
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index d348dc4a2..8fadebacd 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -108,7 +108,6 @@
Numre
Brugere
- Ja
Slået fra
Slet
Bedste opløsning
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index ba15174a9..0721ebfad 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -88,7 +88,6 @@
Schwarz
reCAPTCHA-Aufgabe
reCAPTCHA-Aufgabe angefordert
- Ja
Alle
Deaktiviert
Im Pop-up-Modus öffnen
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index a57011bc3..5e7fd4940 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -52,7 +52,6 @@
Λήψεις
Λήψεις
Όλα
- Ναι
Σφάλμα
Αναφορά
Πληροφορίες:
diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml
index 43798f344..062bda7e8 100644
--- a/app/src/main/res/values-eo/strings.xml
+++ b/app/src/main/res/values-eo/strings.xml
@@ -95,7 +95,6 @@
- %s filmeto
- %s filmetoj
- Jes
Tiu permeso estas necesa por
\nmalfermi en ŝprucfenestra modo
Ludante en ŝprucfenestra modo
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index bd40f0c61..295fa22f8 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -82,7 +82,6 @@
Lo sucedido:\\nPetición:\\nIdioma del contenido:\\nPaís del contenido:\\nIdioma de la aplicación:\\nServicio:\\nHora GMT:\\nPaquete:\\nVersión:\\nVersión del SO:
Negro
Todo
- Sí
k
M
MM
diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml
index b22d1e782..c2fd8ef9e 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -93,7 +93,6 @@
Allalaadimised
Vea teatamine
Kõik
- Jah
Keelatud
Kustuta
Parim lahutus
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 88b8d90f9..7a5e274b1 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -62,7 +62,6 @@
Deskargak
Errore-txostena
Dena
- Bai
Desgaituta
Garbitu
Bereizmen onena
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index db8e85f17..34fda3cae 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -109,7 +109,6 @@
کانالها
سیاهههای پخش
کاربران
- بله
غیرفعال
پاککردن
پخش همه
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 2c871c051..2bd6ccba8 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -73,7 +73,6 @@
Lataukset
Virheraportti
Kaikki
- Kyllä
Poistettu käytöstä
Pyyhi
Paras resoluutio
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 2e4257695..50fe7b687 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -86,7 +86,6 @@
Défi reCAPTCHA demandé
Ouvrir en mode pop-up
Lecture en mode flottant
- Oui
Désactivés
Quoi :\\nRequest :\\nContent Language :\\nContent Country :\\nApp Language :\\nService :\\nGMT Time :\\nPackage :\\nVersion :\\nOS version :
k
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index a9357a5cd..bfe9710f4 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -96,7 +96,6 @@
Listas de reprodución
Pistas
Usuarios
- Si
Desactivado
Limpar
Mellor resolución
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index 3ec3ee00b..f3777c909 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -58,7 +58,6 @@
הורדות
דוח שגיאה
הכול
- כן
מושבת
ניקוי
שגיאה
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index d9e9c83d2..46990aad4 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -90,7 +90,6 @@
डाउनलोड
त्रुटी की रिपोर्ट
सारे
- सहमत हूँ
बंद करे
साफ़
बेहतर विडियो की क्वालिटी
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 09c85052c..92e81f3c0 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -71,7 +71,6 @@
Preuzimanja
Prijavi grešku
Sve
- Da
Isključeno
Očisti
Najbolja rezolucija
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 04fe0cd01..cbe83c4ea 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -111,7 +111,6 @@
Hibaelhárítás
Lejátszás felugró ablakban
Összes
- Igen
Letiltva
Törlés
Legjobb felbontás
diff --git a/app/src/main/res/values-hy/strings.xml b/app/src/main/res/values-hy/strings.xml
index ea2750a93..e914ff303 100644
--- a/app/src/main/res/values-hy/strings.xml
+++ b/app/src/main/res/values-hy/strings.xml
@@ -65,7 +65,6 @@
Ֆայլը ջնջվեց
Ֆայլ
Երգեր
- Այո
Որոնման պատմություն
Փակել
diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml
index 656a37d25..e9d400be2 100644
--- a/app/src/main/res/values-ia/strings.xml
+++ b/app/src/main/res/values-ia/strings.xml
@@ -85,7 +85,6 @@
Pistas
Usatores
Eventos
- Si
Disactivate
Vacuar
Melior resolution
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index fb02fd4ff..8c01bbbcb 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -86,7 +86,6 @@
r
J
T
- Ya
Buka dalam mode popup
Izin ini dibutuhkan untuk
\nmembuka di mode sembul
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 524e83a89..90a9cc9c3 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -87,7 +87,6 @@
M
Mrd
È richiesta la risoluzione del reCAPTCHA
- Sì
Apri in modalità popup
Riproduzione in modalità popup
Disattivato
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index f659a9149..74a90752c 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -87,7 +87,6 @@
k
M
B
- はい
ポップアップモードで開く
ポップアップモードで開くには
\n権限の許可が必要です
diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml
index b3679ce82..d84f7f698 100644
--- a/app/src/main/res/values-kab/strings.xml
+++ b/app/src/main/res/values-kab/strings.xml
@@ -30,7 +30,6 @@
Sifeḍ ɣer
Rnu ɣer
Amecwaṛ
- Ih
Azdam n NewPipe
Err-d imezwar
Yerna-t %s
diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml
index f4af24f36..241192866 100644
--- a/app/src/main/res/values-kmr/strings.xml
+++ b/app/src/main/res/values-kmr/strings.xml
@@ -169,7 +169,6 @@
NewPipe nermalava kopîleft libre ye: Hûn dikarin li gorî kêfa xwe bikar bînin, parve bikin û baştir bikin. Bi taybetî hûn dikarin wê di bin mercên Lîsansa Giştî ya GNU ya Giştî ya ku ji hêla Weqfa Nermalava Azad ve hatî weşandin de, an guhertoya 3 ya Lîsansê, an jî (li gorî vebijarka we) guhertoyek paşîn ji nû ve belav bikin û / an biguherînin.
Zelal
Bêmecel
- Erê
Hunermend
Album
Stran
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 3c9158753..16dc06956 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -102,7 +102,6 @@
팝업 모드에서 재생 중
오류 보고
전부
- 네
해제됨
지우기
최대 해상도
diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml
index 59c2df022..f4d7056a3 100644
--- a/app/src/main/res/values-ku/strings.xml
+++ b/app/src/main/res/values-ku/strings.xml
@@ -86,7 +86,6 @@
دابەزاندنەکان
ناتوانرێ سکاڵابکرێ
گشتی
- بەڵێ
ناکارایە
پاککردنەوە
باشترین قەبارە
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index 7608e6821..658b30129 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -58,7 +58,6 @@
Atsisiuntimai
Klaidų ataskaita
Visi
- Taip
Išjungta
Išvalyti
Geriausia raiška
diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml
index 6a311be05..6f83ce867 100644
--- a/app/src/main/res/values-lv/strings.xml
+++ b/app/src/main/res/values-lv/strings.xml
@@ -236,7 +236,6 @@
Labākā izšķirtspēja
Notīrīt
Atspējots
- Jā
Mākslinieki
Albūmi
Dziesmas
diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml
index 392bc39d2..0aaa8d546 100644
--- a/app/src/main/res/values-mk/strings.xml
+++ b/app/src/main/res/values-mk/strings.xml
@@ -93,7 +93,6 @@
Превземања
Извештај за грешки
Сите
- Да
Оневозможено
Избриши
Најдобра резолуција
diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml
index 26b4158c4..959e4c5af 100644
--- a/app/src/main/res/values-ml/strings.xml
+++ b/app/src/main/res/values-ml/strings.xml
@@ -270,7 +270,6 @@
മികച്ച റിസല്യൂഷൻ
തെളിക്കുക
അസാധുവാക്കപ്പെട്ടു
- അതെ
കലാകാരന്മാർ
ആൽബങ്ങൾ
പാട്ടുകൾ
diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml
index d102b529d..b38105b5a 100644
--- a/app/src/main/res/values-ms/strings.xml
+++ b/app/src/main/res/values-ms/strings.xml
@@ -105,7 +105,6 @@
Trek
Pengguna
Peristiwa
- Ya
Dinyahdayakan
Bersihkan
Resolusi terbaik
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index 251083236..1735bd0c1 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -89,7 +89,6 @@
Svart
Spiller av i oppsprettsmodus
Alle
- Ja
Avskrudd
k
M
diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml
index d9abdfefd..9cbad12ab 100644
--- a/app/src/main/res/values-ne/strings.xml
+++ b/app/src/main/res/values-ne/strings.xml
@@ -111,7 +111,6 @@
ट्रयाकहरु
प्रयोगकर्ताहरु
घटनाहरू
- हो
अक्षम
स्पष्ट
सर्वश्रेष्ठ रेसोलुशन
diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml
index 336c654de..542e4a001 100644
--- a/app/src/main/res/values-nl-rBE/strings.xml
+++ b/app/src/main/res/values-nl-rBE/strings.xml
@@ -93,7 +93,6 @@
Downloads
Foutrapport
Alles
- Ja
Uitgeschakeld
Wissen
Beste resolutie
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 92eabcab1..e9f20e620 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -85,7 +85,6 @@
reCAPTCHA-uitdaging gevraagd
Openen in pop-upmodus
Alles
- Ja
k
M
B
diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml
index 005b30a89..68178f37c 100644
--- a/app/src/main/res/values-pa/strings.xml
+++ b/app/src/main/res/values-pa/strings.xml
@@ -92,7 +92,6 @@
ਡਾਊਨਲੋਡਸ
Error ਰਿਪੋਰਟ
ਸਾਰੇ
- ਹਾਂ
ਬੰਦ ਕੀਤਾ
ਮਿਟਾਓ
ਵਧੀਆ Resolution
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 93a497d7b..f0e74e4b8 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -95,7 +95,6 @@
Wybierz podpowiedzi, które będą wyświetlane podczas wyszukiwania
Odtwarzanie w trybie okienkowym
Wszystkie
- Tak
Wyłączone
Wyczyść
tys.
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 9c1b47d32..a445bf9c1 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -90,7 +90,6 @@
Formato de vídeo padrão
Reproduzindo em modo popup
Tudo
- Sim
Desativado
k
M
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index ef920fb9c..72f05896a 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -395,7 +395,6 @@
Tentativas máximas
Histórico
Velocidade
- Sim
Não é possível recuperar esta descarga
Mudar nome
Nenhuma subscrição selecionada
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 70c50a89e..7d9f6f959 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -83,7 +83,6 @@
Abrir no modo popup
Preto
Tudo
- Sim
k
M
MM
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 802b2ab69..774512671 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -90,7 +90,6 @@
Negru
Redare în mod pop-up
Toate
- Da
Dezactivat
Aplicația/UI s-a oprit
Ce:\\nSolicitare:\\nLimba conținutului:\\nȚara conținutului:\\nLimba aplicației:\\nServiciu:\\nOra GMT:\\nPachet:\\nVersiune: \\nVersiune SO:
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index e5a8e53b8..dd72474e7 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -86,7 +86,6 @@
Чёрная
Помнить параметры окна
Воспроизведение во всплывающем окне
- Да
Очистить
Всё
Что:\\nЗапрос:\\nЯзык контента:\\nСтрана контента:\\nЯзык приложения:\\nСервис:\\nВремя по Гринвичу:\\nПакет:\\nВерсия пакета:\\nВерсия ОС:
diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml
index 1b4e4c37c..599c4a97b 100644
--- a/app/src/main/res/values-sc/strings.xml
+++ b/app/src/main/res/values-sc/strings.xml
@@ -415,7 +415,6 @@
Risolutzione mègius
Isbòida
Disabilitadu
- Eja
Artista
Albums
Cantzones
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 1253ef053..13ecd5190 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -87,7 +87,6 @@
M
B
Požiadavka reCAPTCHA
- Áno
Spustiť v okne
Tieto práva sú potrebné pre
\nprehrávanie v mini okne
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index 8d13d5f62..4702e7452 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -87,7 +87,6 @@
k
mio
mrd
- Da
Odpri v pojavnem načinu
To dovoljenje je potrebno za odpiranje
\nv pojavnem načinu
diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml
index 3de28220a..5a9d19448 100644
--- a/app/src/main/res/values-so/strings.xml
+++ b/app/src/main/res/values-so/strings.xml
@@ -319,7 +319,6 @@
Toos
Soo celi
Xidhan
- Haa
Isticmaale
Muuqaalo
Dhammaan
diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml
index 26ab1997f..d8ca670bd 100644
--- a/app/src/main/res/values-sq/strings.xml
+++ b/app/src/main/res/values-sq/strings.xml
@@ -34,7 +34,6 @@
Shkarkimet
Raporti i gabimit
Të gjitha
- Po
Në pritje
- %d i zgjedhur
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 82e8eb953..639eb3171 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -87,7 +87,6 @@
хиљ
мил
млрд
- Да
Отвори у искачућем режиму
Ова дозвола је потребна за
\nотварање у искачућем режиму
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index c632b264c..641722771 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -58,7 +58,6 @@
Hämtningar
Felrapport
Alla
- Ja
Inaktiverad
Rensa
Bästa upplösningen
diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml
index c762d21d4..62368b84b 100644
--- a/app/src/main/res/values-ta/strings.xml
+++ b/app/src/main/res/values-ta/strings.xml
@@ -73,7 +73,6 @@
அனைத்தும்
ஒளிச்சரங்கள்
பயனர்கள்
- ஆம்
அழி
எப்பொழுதும்
ஒரு முறை
diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml
index 157ad1729..b5d5ef0b7 100644
--- a/app/src/main/res/values-te/strings.xml
+++ b/app/src/main/res/values-te/strings.xml
@@ -52,7 +52,6 @@
డౌన్ లోడ్
లోపం నివేదిక
అన్ని
- అవును
అన్నింటినీ ప్లే చేయండి
న్యూప్యాప్ నోటిఫికేషన్
లోపం
diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml
index bf8e56d75..3c0848af1 100644
--- a/app/src/main/res/values-th/strings.xml
+++ b/app/src/main/res/values-th/strings.xml
@@ -104,7 +104,6 @@
แทร็ค
ผู้ใช้
เหตุการณ์
- ใช่
ปิดการใช้งาน
ล้าง
ความละเอียดที่ดีที่สุด
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index fa87a4a18..0263336c7 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -86,7 +86,6 @@
Siyah
Açılır pencere kipinde oynatılıyor
Tümü
- Evet
Devre dışı
Yorumunuz (İngilizce):
Ayrıntılar:
diff --git a/app/src/main/res/values-tzm/strings.xml b/app/src/main/res/values-tzm/strings.xml
index d53dcec8b..5bae4ff2f 100644
--- a/app/src/main/res/values-tzm/strings.xml
+++ b/app/src/main/res/values-tzm/strings.xml
@@ -123,7 +123,6 @@
Afaylu
Ku dwal
Sfeḍ
- Yah
Inaẓuṛen
Tiɣennijin
Imezza
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 6af7304d8..4a47fe100 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -58,7 +58,6 @@
Завантаження
Звіт про помилку
Усе
- Так
Вимкнено
Збій застосунку/інтерфейсу
Ваш коментар (англійською):
diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml
index f2c5afc33..56e8b7ed7 100644
--- a/app/src/main/res/values-ur/strings.xml
+++ b/app/src/main/res/values-ur/strings.xml
@@ -92,7 +92,6 @@
ڈاؤن لوڈز
خرابی کی اطلاع
تمام
- ہاں
غیر فعال
صاف
بہترین ریزولوشن
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index fc923dc3d..0d528a3b9 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -56,7 +56,6 @@
Tải xuống
Báo lỗi
Tất cả
- Có
Vô hiệu
Xóa
Độ phân giải tốt nhất
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 9fec7c065..27b06de45 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -28,7 +28,6 @@
不支持的 URL
外观
全部
- 是
网络错误
- %s 个视频
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 83085d9e4..233174f06 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -86,7 +86,6 @@
純黑
以畫中畫模式播放
所有
- 是
App/界面閃退
經過:\\n請求:\\n內容語言:\\n內容國家:\\nApp 語言:\\n服務:\\nGMT 時間:\\n封裝:\\n版本:\\nOS 版本:
千
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index bc1f40873..53dc34025 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -61,7 +61,6 @@
下載
錯誤回報
全部
- 是的
已停用
清除
最佳解析度
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8b8945b40..a249f1731 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -168,7 +168,6 @@
Songs
Albums
Artists
- Yes
Disabled
Clear
Best resolution
diff --git a/app/src/test/java/org/schabi/newpipe/NewVersionManagerTest.kt b/app/src/test/java/org/schabi/newpipe/NewVersionManagerTest.kt
index d2dacc783..7a2d965f7 100644
--- a/app/src/test/java/org/schabi/newpipe/NewVersionManagerTest.kt
+++ b/app/src/test/java/org/schabi/newpipe/NewVersionManagerTest.kt
@@ -2,8 +2,9 @@ package org.schabi.newpipe
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
-import org.junit.Before
import org.junit.Test
+import org.schabi.newpipe.util.ReleaseVersionUtil.coerceUpdateCheckExpiry
+import org.schabi.newpipe.util.ReleaseVersionUtil.isLastUpdateCheckExpired
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
@@ -11,18 +12,11 @@ import kotlin.math.abs
class NewVersionManagerTest {
- private lateinit var manager: NewVersionManager
-
- @Before
- fun setup() {
- manager = NewVersionManager()
- }
-
@Test
fun `Expiry is reached`() {
val oneHourEarlier = Instant.now().atZone(ZoneId.of("GMT")).minusHours(1)
- val expired = manager.isExpired(oneHourEarlier.toEpochSecond())
+ val expired = isLastUpdateCheckExpired(oneHourEarlier.toEpochSecond())
assertTrue(expired)
}
@@ -31,7 +25,7 @@ class NewVersionManagerTest {
fun `Expiry is not reached`() {
val oneHourLater = Instant.now().atZone(ZoneId.of("GMT")).plusHours(1)
- val expired = manager.isExpired(oneHourLater.toEpochSecond())
+ val expired = isLastUpdateCheckExpired(oneHourLater.toEpochSecond())
assertFalse(expired)
}
@@ -47,7 +41,7 @@ class NewVersionManagerTest {
fun `Expiry must be returned as is because it is inside the acceptable range of 6-72 hours`() {
val sixHoursLater = Instant.now().atZone(ZoneId.of("GMT")).plusHours(6)
- val coerced = manager.coerceExpiry(DateTimeFormatter.RFC_1123_DATE_TIME.format(sixHoursLater))
+ val coerced = coerceUpdateCheckExpiry(DateTimeFormatter.RFC_1123_DATE_TIME.format(sixHoursLater))
assertNearlyEqual(sixHoursLater.toEpochSecond(), coerced)
}
@@ -56,7 +50,7 @@ class NewVersionManagerTest {
fun `Expiry must be increased to 6 hours if below`() {
val tooLow = Instant.now().atZone(ZoneId.of("GMT")).plusHours(5)
- val coerced = manager.coerceExpiry(DateTimeFormatter.RFC_1123_DATE_TIME.format(tooLow))
+ val coerced = coerceUpdateCheckExpiry(DateTimeFormatter.RFC_1123_DATE_TIME.format(tooLow))
assertNearlyEqual(tooLow.plusHours(1).toEpochSecond(), coerced)
}
@@ -65,7 +59,7 @@ class NewVersionManagerTest {
fun `Expiry must be decreased to 72 hours if above`() {
val tooHigh = Instant.now().atZone(ZoneId.of("GMT")).plusHours(73)
- val coerced = manager.coerceExpiry(DateTimeFormatter.RFC_1123_DATE_TIME.format(tooHigh))
+ val coerced = coerceUpdateCheckExpiry(DateTimeFormatter.RFC_1123_DATE_TIME.format(tooHigh))
assertNearlyEqual(tooHigh.minusHours(1).toEpochSecond(), coerced)
}