onComp
onCompletion);
}
}
-
- private void openRepliesFragment(final CommentsInfoItem commentsInfoItem) {
- ((MainActivity) itemBuilder.getContext())
- .getSupportFragmentManager()
- .beginTransaction()
- .setCustomAnimations(R.animator.custom_fade_in, R.animator.custom_fade_out,
- R.animator.custom_fade_in, R.animator.custom_fade_out)
- .replace(R.id.fragment_holder,
- new CommentRepliesFragment((CommentsInfo) itemBuilder.getSourceListInfo(),
- commentsInfoItem))
- .addToBackStack(null)
- .commit();
- }
}
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java
index a84c9840416..7f80707bcf3 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java
@@ -12,10 +12,6 @@
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.Localization;
-import androidx.preference.PreferenceManager;
-
-import static org.schabi.newpipe.MainActivity.DEBUG;
-
/*
* Created by Christian Schabesberger on 01.08.16.
*
@@ -81,7 +77,8 @@ private String getStreamInfoDetailLine(final StreamInfoItem infoItem) {
}
}
- final String uploadDate = getFormattedRelativeUploadDate(infoItem);
+ final String uploadDate = Localization.relativeTimeOrTextual(infoItem.getUploadDate(),
+ infoItem.getTextualUploadDate(), itemBuilder.getContext());
if (!TextUtils.isEmpty(uploadDate)) {
if (viewsAndDate.isEmpty()) {
return uploadDate;
@@ -92,20 +89,4 @@ private String getStreamInfoDetailLine(final StreamInfoItem infoItem) {
return viewsAndDate;
}
-
- private String getFormattedRelativeUploadDate(final StreamInfoItem infoItem) {
- if (infoItem.getUploadDate() != null) {
- String formattedRelativeTime = Localization
- .relativeTime(infoItem.getUploadDate().offsetDateTime());
-
- if (DEBUG && PreferenceManager.getDefaultSharedPreferences(itemBuilder.getContext())
- .getBoolean(itemBuilder.getContext()
- .getString(R.string.show_original_time_ago_key), false)) {
- formattedRelativeTime += " (" + infoItem.getTextualUploadDate() + ")";
- }
- return formattedRelativeTime;
- } else {
- return infoItem.getTextualUploadDate();
- }
- }
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java
index 20d21d76b49..dea48651e0b 100644
--- a/app/src/main/java/org/schabi/newpipe/util/Localization.java
+++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java
@@ -1,5 +1,7 @@
package org.schabi.newpipe.util;
+import static org.schabi.newpipe.MainActivity.DEBUG;
+
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
@@ -22,6 +24,7 @@
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.localization.ContentCountry;
+import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.AudioTrackType;
@@ -214,6 +217,14 @@ public static String replyCount(final Context context, final int replyCount) {
String.valueOf(replyCount));
}
+ public static String likeCount(final Context context, final int likeCount) {
+ if (likeCount < 0) {
+ return "-";
+ } else {
+ return shortCount(context, likeCount);
+ }
+ }
+
public static String getDurationString(final long duration) {
final String output;
@@ -333,6 +344,20 @@ public static String relativeTime(final OffsetDateTime offsetDateTime) {
return prettyTime.formatUnrounded(offsetDateTime);
}
+ public static String relativeTimeOrTextual(final DateWrapper parsed,
+ final String textual,
+ @Nullable final Context context) {
+ if (parsed == null) {
+ return textual;
+ } else if (DEBUG && context != null && PreferenceManager
+ .getDefaultSharedPreferences(context)
+ .getBoolean(context.getString(R.string.show_original_time_ago_key), false)) {
+ return relativeTime(parsed.offsetDateTime()) + " (" + textual + ")";
+ } else {
+ return relativeTime(parsed.offsetDateTime());
+ }
+ }
+
public static void assureCorrectAppLanguage(final Context c) {
final Resources res = c.getResources();
final DisplayMetrics dm = res.getDisplayMetrics();
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index b0d7dcf735a..e127a8b55ae 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -1,5 +1,6 @@
package org.schabi.newpipe.util;
+import static android.text.TextUtils.isEmpty;
import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams;
import android.annotation.SuppressLint;
@@ -17,6 +18,7 @@
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
@@ -29,8 +31,11 @@
import org.schabi.newpipe.about.AboutActivity;
import org.schabi.newpipe.database.feed.model.FeedGroupEntity;
import org.schabi.newpipe.download.DownloadActivity;
+import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
+import org.schabi.newpipe.extractor.comments.CommentsInfo;
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.DeliveryMethod;
@@ -41,6 +46,7 @@
import org.schabi.newpipe.fragments.MainFragment;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
import org.schabi.newpipe.fragments.list.channel.ChannelFragment;
+import org.schabi.newpipe.fragments.list.comments.CommentRepliesFragment;
import org.schabi.newpipe.fragments.list.kiosk.KioskFragment;
import org.schabi.newpipe.fragments.list.playlist.PlaylistFragment;
import org.schabi.newpipe.fragments.list.search.SearchFragment;
@@ -476,6 +482,29 @@ public static void openChannelFragment(@NonNull final Fragment fragment,
item.getServiceId(), uploaderUrl, item.getUploaderName());
}
+ public static void openCommentAuthorIfPresent(@NonNull final FragmentActivity activity,
+ final CommentsInfoItem comment) {
+ if (isEmpty(comment.getUploaderUrl())) {
+ return;
+ }
+ try {
+ openChannelFragment(activity.getSupportFragmentManager(), comment.getServiceId(),
+ comment.getUploaderUrl(), comment.getUploaderName());
+ } catch (final Exception e) {
+ ErrorUtil.showUiErrorSnackbar(activity, "Opening channel fragment", e);
+ }
+ }
+
+ public static void openCommentRepliesFragment(@NonNull final FragmentActivity activity,
+ final CommentsInfo commentsInfo,
+ final CommentsInfoItem commentsInfoItem) {
+ defaultTransaction(activity.getSupportFragmentManager())
+ .replace(R.id.fragment_holder,
+ new CommentRepliesFragment(commentsInfo, commentsInfoItem))
+ .addToBackStack(null)
+ .commit();
+ }
+
public static void openPlaylistFragment(final FragmentManager fragmentManager,
final int serviceId, final String url,
@NonNull final String name) {
diff --git a/app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java b/app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java
index acd019ba077..68905e6c963 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java
@@ -144,6 +144,14 @@ public static String getNameOfServiceById(final int serviceId) {
.orElse("");
}
+ @NonNull
+ public static StreamingService getServiceById(final int serviceId) {
+ return ServiceList.all().stream()
+ .filter(s -> s.getServiceId() == serviceId)
+ .findFirst()
+ .orElseThrow();
+ }
+
public static void setSelectedServiceId(final Context context, final int serviceId) {
String serviceName;
try {
From f41ab8b08699974b3c05c1dc5194b276b703172c Mon Sep 17 00:00:00 2001
From: Stypox
Date: Wed, 12 Apr 2023 10:54:28 +0200
Subject: [PATCH 40/82] Add comment replies fragment header
---
.../list/comments/CommentRepliesFragment.java | 59 ++++++++
.../res/layout/comment_replies_header.xml | 137 ++++++++++++++++++
2 files changed, 196 insertions(+)
create mode 100644 app/src/main/res/layout/comment_replies_header.xml
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 783fd18babf..163e7d25f58 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
@@ -1,5 +1,7 @@
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;
@@ -7,20 +9,30 @@
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.CommentsInfo;
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.ImageStrategy;
+import org.schabi.newpipe.util.image.PicassoHelper;
+import org.schabi.newpipe.util.text.TextLinkifier;
import java.util.Queue;
+import java.util.function.Supplier;
import io.reactivex.rxjava3.core.Single;
+import io.reactivex.rxjava3.disposables.CompositeDisposable;
public final class CommentRepliesFragment
extends BaseListInfoFragment {
@@ -29,6 +41,7 @@ public final class CommentRepliesFragment
private CommentsInfo commentsInfo;
// the comment to show replies of
private CommentsInfoItem commentsInfoItem;
+ private final CompositeDisposable disposables = new CompositeDisposable();
/*//////////////////////////////////////////////////////////////////////////
@@ -55,6 +68,52 @@ public View onCreateView(@NonNull final LayoutInflater inflater,
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
+ PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(binding.authorAvatar);
+ 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(
+ item.getUploadDate(), item.getTextualUploadDate(), getContext()));
+ 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
diff --git a/app/src/main/res/layout/comment_replies_header.xml b/app/src/main/res/layout/comment_replies_header.xml
new file mode 100644
index 00000000000..ed5ba1a1084
--- /dev/null
+++ b/app/src/main/res/layout/comment_replies_header.xml
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From 3f37e27852a2d7559722bc69e7233ded68730ab1 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Wed, 12 Apr 2023 15:18:26 +0200
Subject: [PATCH 41/82] Add some documentation and javadocs
Also further simplify CommentRepliesInfo and RelatedItemsInfo
---
.../list/comments/CommentRepliesFragment.java | 4 +--
.../list/comments/CommentRepliesInfo.java | 25 ++++++++---------
.../list/videos/RelatedItemInfo.java | 28 -------------------
.../list/videos/RelatedItemsFragment.java | 22 +++++++--------
.../list/videos/RelatedItemsInfo.java | 22 +++++++++++++++
.../holder/CommentInfoItemHolder.java | 4 +--
.../holder/StreamInfoItemHolder.java | 5 ++--
.../org/schabi/newpipe/util/Localization.java | 23 +++++++++++++--
.../schabi/newpipe/util/NavigationHelper.java | 7 +++++
.../schabi/newpipe/util/ServiceHelper.java | 5 ++++
10 files changed, 83 insertions(+), 62 deletions(-)
delete mode 100644 app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemInfo.java
create mode 100644 app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsInfo.java
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 163e7d25f58..2e0f0d7c6b1 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
@@ -89,7 +89,7 @@ protected Supplier getListHeaderSupplier() {
// setup author name and comment date
binding.authorName.setText(item.getUploaderName());
binding.uploadDate.setText(Localization.relativeTimeOrTextual(
- item.getUploadDate(), item.getTextualUploadDate(), getContext()));
+ getContext(), item.getUploadDate(), item.getTextualUploadDate()));
binding.authorTouchArea.setOnClickListener(
v -> NavigationHelper.openCommentAuthorIfPresent(requireActivity(), item));
@@ -140,7 +140,7 @@ public void readFrom(@NonNull final Queue savedObjects) throws Exception
@Override
protected Single loadResult(final boolean forceLoad) {
- return Single.fromCallable(() -> CommentRepliesInfo.getInfo(commentsInfoItem,
+ return Single.fromCallable(() -> new CommentRepliesInfo(commentsInfoItem,
// the reply count string will be shown as the activity title
Localization.replyCount(requireContext(), commentsInfoItem.getReplyCount())));
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesInfo.java b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesInfo.java
index 7f85dc6bf4e..cc160c39538 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesInfo.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesInfo.java
@@ -7,19 +7,16 @@
import java.util.Collections;
public final class CommentRepliesInfo extends ListInfo {
- private CommentRepliesInfo(final int serviceId,
- final ListLinkHandler listUrlIdHandler,
- final String name) {
- super(serviceId, listUrlIdHandler, name);
- }
-
- public static CommentRepliesInfo getInfo(final CommentsInfoItem comment, final String name) {
- final ListLinkHandler handler =
- new ListLinkHandler("", "", "", Collections.emptyList(), null);
- final CommentRepliesInfo relatedItemInfo = new CommentRepliesInfo(
- comment.getServiceId(), handler, name); // the name will be shown as fragment title
- relatedItemInfo.setNextPage(comment.getReplies());
- relatedItemInfo.setRelatedItems(Collections.emptyList()); // since it must be non-null
- return relatedItemInfo;
+ /**
+ * This class is used to wrap the comment replies page into a ListInfo object.
+ *
+ * @param comment the comment from which to get replies
+ * @param name will be shown as the fragment title
+ */
+ public CommentRepliesInfo(final CommentsInfoItem comment, final String name) {
+ super(comment.getServiceId(),
+ new ListLinkHandler("", "", "", Collections.emptyList(), null), name);
+ setNextPage(comment.getReplies());
+ setRelatedItems(Collections.emptyList()); // since it must be non-null
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemInfo.java b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemInfo.java
deleted file mode 100644
index 9d2985082cb..00000000000
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemInfo.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.schabi.newpipe.fragments.list.videos;
-
-import org.schabi.newpipe.extractor.InfoItem;
-import org.schabi.newpipe.extractor.ListInfo;
-import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
-import org.schabi.newpipe.extractor.stream.StreamInfo;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public final class RelatedItemInfo extends ListInfo {
- private RelatedItemInfo(final int serviceId,
- final ListLinkHandler listUrlIdHandler,
- final String name) {
- super(serviceId, listUrlIdHandler, name);
- }
-
- public static RelatedItemInfo getInfo(final StreamInfo info) {
- final ListLinkHandler handler = new ListLinkHandler(
- info.getOriginalUrl(), info.getUrl(), info.getId(), Collections.emptyList(), null);
- final RelatedItemInfo relatedItemInfo = new RelatedItemInfo(
- info.getServiceId(), handler, info.getName());
- final List relatedItems = new ArrayList<>(info.getRelatedItems());
- relatedItemInfo.setRelatedItems(relatedItems);
- return relatedItemInfo;
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java
index 5ec3164200e..e46937ede3d 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java
@@ -27,11 +27,11 @@
import io.reactivex.rxjava3.core.Single;
-public class RelatedItemsFragment extends BaseListInfoFragment
+public class RelatedItemsFragment extends BaseListInfoFragment
implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String INFO_KEY = "related_info_key";
- private RelatedItemInfo relatedItemInfo;
+ private RelatedItemsInfo relatedItemsInfo;
/*//////////////////////////////////////////////////////////////////////////
// Views
@@ -68,7 +68,7 @@ public void onDestroyView() {
@Override
protected Supplier getListHeaderSupplier() {
- if (relatedItemInfo == null || relatedItemInfo.getRelatedItems() == null) {
+ if (relatedItemsInfo == null || relatedItemsInfo.getRelatedItems() == null) {
return null;
}
@@ -96,8 +96,8 @@ protected Single> loadMoreItemsLogic() {
//////////////////////////////////////////////////////////////////////////*/
@Override
- protected Single loadResult(final boolean forceLoad) {
- return Single.fromCallable(() -> relatedItemInfo);
+ protected Single loadResult(final boolean forceLoad) {
+ return Single.fromCallable(() -> relatedItemsInfo);
}
@Override
@@ -109,7 +109,7 @@ public void showLoading() {
}
@Override
- public void handleResult(@NonNull final RelatedItemInfo result) {
+ public void handleResult(@NonNull final RelatedItemsInfo result) {
super.handleResult(result);
if (headerBinding != null) {
@@ -136,23 +136,23 @@ public void onCreateOptionsMenu(@NonNull final Menu menu,
private void setInitialData(final StreamInfo info) {
super.setInitialData(info.getServiceId(), info.getUrl(), info.getName());
- if (this.relatedItemInfo == null) {
- this.relatedItemInfo = RelatedItemInfo.getInfo(info);
+ if (this.relatedItemsInfo == null) {
+ this.relatedItemsInfo = new RelatedItemsInfo(info);
}
}
@Override
public void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState);
- outState.putSerializable(INFO_KEY, relatedItemInfo);
+ outState.putSerializable(INFO_KEY, relatedItemsInfo);
}
@Override
protected void onRestoreInstanceState(@NonNull final Bundle savedState) {
super.onRestoreInstanceState(savedState);
final Serializable serializable = savedState.getSerializable(INFO_KEY);
- if (serializable instanceof RelatedItemInfo) {
- this.relatedItemInfo = (RelatedItemInfo) serializable;
+ if (serializable instanceof RelatedItemsInfo) {
+ this.relatedItemsInfo = (RelatedItemsInfo) serializable;
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsInfo.java b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsInfo.java
new file mode 100644
index 00000000000..bbc7e1ed001
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsInfo.java
@@ -0,0 +1,22 @@
+package org.schabi.newpipe.fragments.list.videos;
+
+import org.schabi.newpipe.extractor.InfoItem;
+import org.schabi.newpipe.extractor.ListInfo;
+import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
+import org.schabi.newpipe.extractor.stream.StreamInfo;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+public final class RelatedItemsInfo extends ListInfo {
+ /**
+ * This class is used to wrap the related items of a StreamInfo into a ListInfo object.
+ *
+ * @param info the stream info from which to get related items
+ */
+ public RelatedItemsInfo(final StreamInfo info) {
+ super(info.getServiceId(), new ListLinkHandler(info.getOriginalUrl(), info.getUrl(),
+ info.getId(), Collections.emptyList(), null), info.getName());
+ setRelatedItems(new ArrayList<>(info.getRelatedItems()));
+ }
+}
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 03f796f59d2..ef949a7450e 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
@@ -119,8 +119,8 @@ public void updateFromItem(final InfoItem infoItem,
// setup the top row, with pinned icon, author name and comment date
itemPinnedView.setVisibility(item.isPinned() ? View.VISIBLE : View.GONE);
itemTitleView.setText(Localization.concatenateStrings(item.getUploaderName(),
- Localization.relativeTimeOrTextual(item.getUploadDate(),
- item.getTextualUploadDate(), itemBuilder.getContext())));
+ Localization.relativeTimeOrTextual(itemBuilder.getContext(), item.getUploadDate(),
+ item.getTextualUploadDate())));
// setup bottom row, with likes, heart and replies button
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java
index 7f80707bcf3..80f62eed3d1 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java
@@ -77,8 +77,9 @@ private String getStreamInfoDetailLine(final StreamInfoItem infoItem) {
}
}
- final String uploadDate = Localization.relativeTimeOrTextual(infoItem.getUploadDate(),
- infoItem.getTextualUploadDate(), itemBuilder.getContext());
+ final String uploadDate = Localization.relativeTimeOrTextual(itemBuilder.getContext(),
+ infoItem.getUploadDate(),
+ infoItem.getTextualUploadDate());
if (!TextUtils.isEmpty(uploadDate)) {
if (viewsAndDate.isEmpty()) {
return uploadDate;
diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java
index dea48651e0b..ef30e17613e 100644
--- a/app/src/main/java/org/schabi/newpipe/util/Localization.java
+++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java
@@ -217,6 +217,12 @@ public static String replyCount(final Context context, final int replyCount) {
String.valueOf(replyCount));
}
+ /**
+ * @param context the Android context
+ * @param likeCount the like count, possibly negative if unknown
+ * @return if {@code likeCount} is smaller than {@code 0}, the string {@code "-"}, otherwise
+ * the result of calling {@link #shortCount(Context, long)} on the like count
+ */
public static String likeCount(final Context context, final int likeCount) {
if (likeCount < 0) {
return "-";
@@ -344,9 +350,20 @@ public static String relativeTime(final OffsetDateTime offsetDateTime) {
return prettyTime.formatUnrounded(offsetDateTime);
}
- public static String relativeTimeOrTextual(final DateWrapper parsed,
- final String textual,
- @Nullable final Context context) {
+ /**
+ * @param context the Android context; if {@code null} then even if in debug mode and the
+ * setting is enabled, {@code textual} will not be shown next to {@code parsed}
+ * @param parsed the textual date or time ago parsed by NewPipeExtractor, or {@code null} if
+ * the extractor could not parse it
+ * @param textual the original textual date or time ago string as provided by services
+ * @return {@link #relativeTime(OffsetDateTime)} is used if {@code parsed != null}, otherwise
+ * {@code textual} is returned. If in debug mode, {@code context != null},
+ * {@code parsed != null} and the relevant setting is enabled, {@code textual} will
+ * be appended to the returned string for debugging purposes.
+ */
+ public static String relativeTimeOrTextual(@Nullable final Context context,
+ @Nullable final DateWrapper parsed,
+ final String textual) {
if (parsed == null) {
return textual;
} else if (DEBUG && context != null && PreferenceManager
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index e127a8b55ae..e105e551b63 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -482,6 +482,13 @@ public static void openChannelFragment(@NonNull final Fragment fragment,
item.getServiceId(), uploaderUrl, item.getUploaderName());
}
+ /**
+ * Opens the comment author channel fragment, if the {@link CommentsInfoItem#getUploaderUrl()}
+ * of {@code comment} is non-null. Shows a UI-error snackbar if something goes wrong.
+ *
+ * @param activity the activity with the fragment manager and in which to show the snackbar
+ * @param comment the comment whose uploader/author will be opened
+ */
public static void openCommentAuthorIfPresent(@NonNull final FragmentActivity activity,
final CommentsInfoItem comment) {
if (isEmpty(comment.getUploaderUrl())) {
diff --git a/app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java b/app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java
index 68905e6c963..c712157b35b 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java
@@ -144,6 +144,11 @@ public static String getNameOfServiceById(final int serviceId) {
.orElse("");
}
+ /**
+ * @param serviceId the id of the service
+ * @return the service corresponding to the provided id
+ * @throws java.util.NoSuchElementException if there is no service with the provided id
+ */
@NonNull
public static StreamingService getServiceById(final int serviceId) {
return ServiceList.all().stream()
From 8c9287d0c87dc2eb1e99f186535a5e2cb686c037 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Wed, 12 Apr 2023 15:44:50 +0200
Subject: [PATCH 42/82] Revert relying on source ListInfo, use
commentsInfoItem.getUrl() instead
This reverts commit bb01da3691ff1d5c3dccd41b7ca1a5deb1b5676f. This commit was not needed
---
.../fragments/list/BaseListInfoFragment.java | 6 --
.../list/comments/CommentRepliesFragment.java | 21 +++----
.../newpipe/info_list/InfoItemBuilder.java | 60 +++++++++++++++----
.../newpipe/info_list/InfoListAdapter.java | 5 --
.../holder/CommentInfoItemHolder.java | 3 +-
.../schabi/newpipe/util/ExtractorHelper.java | 9 +++
.../schabi/newpipe/util/NavigationHelper.java | 5 +-
7 files changed, 68 insertions(+), 41 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java
index 715512e02b7..dd5eb6c8ab2 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java
@@ -66,7 +66,6 @@ public void onPause() {
@Override
public void onResume() {
super.onResume();
-
// Check if it was loading when the fragment was stopped/paused,
if (wasLoading.getAndSet(false)) {
if (hasMoreItems() && !infoListAdapter.getItemsList().isEmpty()) {
@@ -75,8 +74,6 @@ public void onResume() {
doInitialLoadLogic();
}
}
-
- infoListAdapter.setSourceListInfo(currentInfo);
}
@Override
@@ -140,8 +137,6 @@ public void startLoading(final boolean forceLoad) {
infoListAdapter.clearStreamItemList();
currentInfo = null;
- infoListAdapter.setSourceListInfo(null);
-
if (currentWorker != null) {
currentWorker.dispose();
}
@@ -151,7 +146,6 @@ public void startLoading(final boolean forceLoad) {
.subscribe((@NonNull L result) -> {
isLoading.set(false);
currentInfo = result;
- infoListAdapter.setSourceListInfo(result);
currentNextPage = result.getNextPage();
handleResult(result);
}, throwable ->
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 2e0f0d7c6b1..a28a7f7d554 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
@@ -16,7 +16,6 @@
import org.schabi.newpipe.databinding.CommentRepliesHeaderBinding;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.ListExtractor;
-import org.schabi.newpipe.extractor.comments.CommentsInfo;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.info_list.ItemViewMode;
@@ -37,10 +36,7 @@
public final class CommentRepliesFragment
extends BaseListInfoFragment {
- // the original comments info loaded alongside the stream
- private CommentsInfo commentsInfo;
- // the comment to show replies of
- private CommentsInfoItem commentsInfoItem;
+ private CommentsInfoItem commentsInfoItem; // the comment to show replies of
private final CompositeDisposable disposables = new CompositeDisposable();
@@ -48,16 +44,16 @@ public final class CommentRepliesFragment
// 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(final CommentsInfo commentsInfo,
- final CommentsInfoItem commentsInfoItem) {
+ public CommentRepliesFragment(final CommentsInfoItem commentsInfoItem) {
this();
- this.commentsInfo = commentsInfo;
this.commentsInfoItem = commentsInfoItem;
- setInitialData(commentsInfo.getServiceId(), commentsInfo.getUrl(), commentsInfo.getName());
+ // setting "" as title since the title will be properly set right after
+ setInitialData(commentsInfoItem.getServiceId(), commentsInfoItem.getUrl(), "");
}
@Nullable
@@ -122,14 +118,12 @@ HtmlCompat.FROM_HTML_MODE_LEGACY, getServiceById(item.getServiceId()),
@Override
public void writeTo(final Queue objectsToSave) {
super.writeTo(objectsToSave);
- objectsToSave.add(commentsInfo);
objectsToSave.add(commentsInfoItem);
}
@Override
public void readFrom(@NonNull final Queue savedObjects) throws Exception {
super.readFrom(savedObjects);
- commentsInfo = (CommentsInfo) savedObjects.poll();
commentsInfoItem = (CommentsInfoItem) savedObjects.poll();
}
@@ -147,7 +141,10 @@ protected Single loadResult(final boolean forceLoad) {
@Override
protected Single> loadMoreItemsLogic() {
- return ExtractorHelper.getMoreCommentItems(serviceId, commentsInfo, currentNextPage);
+ // commentsInfoItem.getUrl() should contain the url of the original
+ // ListInfo, which should be the stream url
+ return ExtractorHelper.getMoreCommentItems(
+ serviceId, commentsInfoItem.getUrl(), currentNextPage);
}
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java
index 3b66fa648ab..d959c63277c 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java
@@ -1,13 +1,25 @@
package org.schabi.newpipe.info_list;
import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
-import org.schabi.newpipe.extractor.Info;
-import org.schabi.newpipe.extractor.ListInfo;
+import androidx.annotation.NonNull;
+
+import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
+import org.schabi.newpipe.info_list.holder.ChannelInfoItemHolder;
+import org.schabi.newpipe.info_list.holder.ChannelMiniInfoItemHolder;
+import org.schabi.newpipe.info_list.holder.CommentInfoItemHolder;
+import org.schabi.newpipe.info_list.holder.InfoItemHolder;
+import org.schabi.newpipe.info_list.holder.PlaylistInfoItemHolder;
+import org.schabi.newpipe.info_list.holder.PlaylistMiniInfoItemHolder;
+import org.schabi.newpipe.info_list.holder.StreamInfoItemHolder;
+import org.schabi.newpipe.info_list.holder.StreamMiniInfoItemHolder;
+import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.OnClickGesture;
/*
@@ -42,12 +54,44 @@ public class InfoItemBuilder {
private OnClickGesture onPlaylistSelectedListener;
private OnClickGesture onCommentsSelectedListener;
- private ListInfo> sourceListInfo; // the list-info the info-items from this list belong to
-
public InfoItemBuilder(final Context context) {
this.context = context;
}
+ public View buildView(@NonNull final ViewGroup parent, @NonNull final InfoItem infoItem,
+ final HistoryRecordManager historyRecordManager) {
+ return buildView(parent, infoItem, historyRecordManager, false);
+ }
+
+ public View buildView(@NonNull final ViewGroup parent, @NonNull final InfoItem infoItem,
+ final HistoryRecordManager historyRecordManager,
+ final boolean useMiniVariant) {
+ final InfoItemHolder holder =
+ holderFromInfoType(parent, infoItem.getInfoType(), useMiniVariant);
+ holder.updateFromItem(infoItem, historyRecordManager);
+ return holder.itemView;
+ }
+
+ private InfoItemHolder holderFromInfoType(@NonNull final ViewGroup parent,
+ @NonNull final InfoItem.InfoType infoType,
+ final boolean useMiniVariant) {
+ switch (infoType) {
+ case STREAM:
+ return useMiniVariant ? new StreamMiniInfoItemHolder(this, parent)
+ : new StreamInfoItemHolder(this, parent);
+ case CHANNEL:
+ return useMiniVariant ? new ChannelMiniInfoItemHolder(this, parent)
+ : new ChannelInfoItemHolder(this, parent);
+ case PLAYLIST:
+ return useMiniVariant ? new PlaylistMiniInfoItemHolder(this, parent)
+ : new PlaylistInfoItemHolder(this, parent);
+ case COMMENT:
+ return new CommentInfoItemHolder(this, parent);
+ default:
+ throw new RuntimeException("InfoType not expected = " + infoType.name());
+ }
+ }
+
public Context getContext() {
return context;
}
@@ -84,12 +128,4 @@ public void setOnCommentsSelectedListener(
final OnClickGesture onCommentsSelectedListener) {
this.onCommentsSelectedListener = onCommentsSelectedListener;
}
-
- public Info getSourceListInfo() {
- return sourceListInfo;
- }
-
- public void setSourceListInfo(final ListInfo> sourceListInfo) {
- this.sourceListInfo = sourceListInfo;
- }
}
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java
index 902c4665c9f..575568c00f9 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java
@@ -13,7 +13,6 @@
import org.schabi.newpipe.databinding.PignateFooterBinding;
import org.schabi.newpipe.extractor.InfoItem;
-import org.schabi.newpipe.extractor.ListInfo;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
@@ -116,10 +115,6 @@ public void setOnCommentsSelectedListener(final OnClickGesture
infoItemBuilder.setOnCommentsSelectedListener(listener);
}
- public void setSourceListInfo(final ListInfo> sourceInfo) {
- infoItemBuilder.setSourceListInfo(sourceInfo);
- }
-
public void setUseMiniVariant(final boolean useMiniVariant) {
this.useMiniVariant = useMiniVariant;
}
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 ef949a7450e..ec336f6772f 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
@@ -21,7 +21,6 @@
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.StreamingService;
-import org.schabi.newpipe.extractor.comments.CommentsInfo;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.info_list.InfoItemBuilder;
@@ -174,7 +173,7 @@ private void openCommentAuthor(final CommentsInfoItem item) {
private void openCommentReplies(final CommentsInfoItem item) {
NavigationHelper.openCommentRepliesFragment((FragmentActivity) itemBuilder.getContext(),
- (CommentsInfo) itemBuilder.getSourceListInfo(), item);
+ item);
}
private void allowLinkFocus() {
diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
index 07d0f516de2..c2748f725b3 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
@@ -162,6 +162,15 @@ public static Single> getMoreCommentItems(
CommentsInfo.getMoreItems(NewPipe.getService(serviceId), info, nextPage));
}
+ public static Single> getMoreCommentItems(
+ final int serviceId,
+ final String url,
+ final Page nextPage) {
+ checkServiceId(serviceId);
+ return Single.fromCallable(() ->
+ CommentsInfo.getMoreItems(NewPipe.getService(serviceId), url, nextPage));
+ }
+
public static Single getPlaylistInfo(final int serviceId,
final String url,
final boolean forceLoad) {
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index e105e551b63..00af400b640 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -34,7 +34,6 @@
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
-import org.schabi.newpipe.extractor.comments.CommentsInfo;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.stream.AudioStream;
@@ -503,11 +502,9 @@ public static void openCommentAuthorIfPresent(@NonNull final FragmentActivity ac
}
public static void openCommentRepliesFragment(@NonNull final FragmentActivity activity,
- final CommentsInfo commentsInfo,
final CommentsInfoItem commentsInfoItem) {
defaultTransaction(activity.getSupportFragmentManager())
- .replace(R.id.fragment_holder,
- new CommentRepliesFragment(commentsInfo, commentsInfoItem))
+ .replace(R.id.fragment_holder, new CommentRepliesFragment(commentsInfoItem))
.addToBackStack(null)
.commit();
}
From 5f32d001ccad138faad1c8182be244093da1f8a3 Mon Sep 17 00:00:00 2001
From: TobiGr
Date: Tue, 29 Aug 2023 20:51:47 +0200
Subject: [PATCH 43/82] Expand DetailFragment again when exiting the
CommentRepliesFragment
---
.../java/org/schabi/newpipe/MainActivity.java | 38 ++++++++++++++++---
.../list/comments/CommentRepliesFragment.java | 3 ++
.../schabi/newpipe/util/NavigationHelper.java | 2 +-
3 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java
index ea047ce612c..30069769777 100644
--- a/app/src/main/java/org/schabi/newpipe/MainActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java
@@ -69,6 +69,7 @@
import org.schabi.newpipe.fragments.BackPressable;
import org.schabi.newpipe.fragments.MainFragment;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
+import org.schabi.newpipe.fragments.list.comments.CommentRepliesFragment;
import org.schabi.newpipe.fragments.list.search.SearchFragment;
import org.schabi.newpipe.local.feed.notifications.NotificationWorker;
import org.schabi.newpipe.player.Player;
@@ -546,14 +547,26 @@ public void onBackPressed() {
// interacts with a fragment inside fragment_holder so all back presses should be
// handled by it
if (bottomSheetHiddenOrCollapsed()) {
- final Fragment fragment = getSupportFragmentManager()
- .findFragmentById(R.id.fragment_holder);
+ final FragmentManager fm = getSupportFragmentManager();
+ final Fragment fragment = fm.findFragmentById(R.id.fragment_holder);
// If current fragment implements BackPressable (i.e. can/wanna handle back press)
// delegate the back press to it
if (fragment instanceof BackPressable) {
if (((BackPressable) fragment).onBackPressed()) {
return;
}
+ } else if (fragment instanceof CommentRepliesFragment) {
+ // expand DetailsFragment if CommentRepliesFragment was opened
+ // to show the top level comments again
+ // Expand DetailsFragment if CommentRepliesFragment was opened
+ // and no other CommentRepliesFragments are on top of the back stack
+ // to show the top level comments again.
+ final FragmentManager.BackStackEntry bse = fm.getBackStackEntryAt(
+ fm.getBackStackEntryCount() - 2); // current fragment is at the top
+ if (!CommentRepliesFragment.TAG.equals(bse.getName())) {
+ BottomSheetBehavior.from(mainBinding.fragmentPlayerHolder)
+ .setState(BottomSheetBehavior.STATE_EXPANDED);
+ }
}
} else {
@@ -629,10 +642,23 @@ public void onRequestPermissionsResult(final int requestCode,
*
*/
private void onHomeButtonPressed() {
- // If search fragment wasn't found in the backstack...
- if (!NavigationHelper.tryGotoSearchFragment(getSupportFragmentManager())) {
- // ...go to the main fragment
- NavigationHelper.gotoMainFragment(getSupportFragmentManager());
+ final FragmentManager fm = getSupportFragmentManager();
+ final Fragment fragment = fm.findFragmentById(R.id.fragment_holder);
+
+ if (fragment instanceof CommentRepliesFragment) {
+ // Expand DetailsFragment if CommentRepliesFragment was opened
+ // and no other CommentRepliesFragments are on top of the back stack
+ // to show the top level comments again.
+ fm.popBackStackImmediate();
+ final FragmentManager.BackStackEntry bse = fm.getBackStackEntryAt(
+ fm.getBackStackEntryCount() - 1);
+ if (!CommentRepliesFragment.TAG.equals(bse.getName())) {
+ BottomSheetBehavior.from(mainBinding.fragmentPlayerHolder)
+ .setState(BottomSheetBehavior.STATE_EXPANDED);
+ }
+ } else if (!NavigationHelper.tryGotoSearchFragment(fm)) {
+ // If search fragment wasn't found in the backstack go to the main fragment
+ NavigationHelper.gotoMainFragment(fm);
}
}
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 a28a7f7d554..b8d0f1e6cea 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
@@ -36,6 +36,8 @@
public final class CommentRepliesFragment
extends BaseListInfoFragment {
+ public static final String TAG = CommentRepliesFragment.class.getSimpleName();
+
private CommentsInfoItem commentsInfoItem; // the comment to show replies of
private final CompositeDisposable disposables = new CompositeDisposable();
@@ -156,4 +158,5 @@ protected Single> loadMoreItemsLog
protected ItemViewMode getItemViewMode() {
return ItemViewMode.LIST;
}
+
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index 00af400b640..d0da2273937 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -505,7 +505,7 @@ public static void openCommentRepliesFragment(@NonNull final FragmentActivity ac
final CommentsInfoItem commentsInfoItem) {
defaultTransaction(activity.getSupportFragmentManager())
.replace(R.id.fragment_holder, new CommentRepliesFragment(commentsInfoItem))
- .addToBackStack(null)
+ .addToBackStack(CommentRepliesFragment.TAG)
.commit();
}
From b4016c91c11c4479263aa1e4ccd102c6fb23b7f4 Mon Sep 17 00:00:00 2001
From: TobiGr
Date: Thu, 31 Aug 2023 13:42:07 +0200
Subject: [PATCH 44/82] scroll last comment into view
---
.../java/org/schabi/newpipe/MainActivity.java | 46 +++++++++++++++----
.../fragments/detail/VideoDetailFragment.java | 9 ++++
.../list/comments/CommentRepliesFragment.java | 6 +++
.../list/comments/CommentsFragment.java | 4 ++
.../schabi/newpipe/util/NavigationHelper.java | 3 +-
5 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java
index 30069769777..5c56e867c23 100644
--- a/app/src/main/java/org/schabi/newpipe/MainActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java
@@ -563,10 +563,7 @@ public void onBackPressed() {
// to show the top level comments again.
final FragmentManager.BackStackEntry bse = fm.getBackStackEntryAt(
fm.getBackStackEntryCount() - 2); // current fragment is at the top
- if (!CommentRepliesFragment.TAG.equals(bse.getName())) {
- BottomSheetBehavior.from(mainBinding.fragmentPlayerHolder)
- .setState(BottomSheetBehavior.STATE_EXPANDED);
- }
+ openDetailFragmentFromCommentReplies(fm, bse);
}
} else {
@@ -652,10 +649,7 @@ private void onHomeButtonPressed() {
fm.popBackStackImmediate();
final FragmentManager.BackStackEntry bse = fm.getBackStackEntryAt(
fm.getBackStackEntryCount() - 1);
- if (!CommentRepliesFragment.TAG.equals(bse.getName())) {
- BottomSheetBehavior.from(mainBinding.fragmentPlayerHolder)
- .setState(BottomSheetBehavior.STATE_EXPANDED);
- }
+ openDetailFragmentFromCommentReplies(fm, bse);
} else if (!NavigationHelper.tryGotoSearchFragment(fm)) {
// If search fragment wasn't found in the backstack go to the main fragment
NavigationHelper.gotoMainFragment(fm);
@@ -854,6 +848,42 @@ public void onReceive(final Context context, final Intent intent) {
}
}
+ private void openDetailFragmentFromCommentReplies(
+ @NonNull final FragmentManager fm,
+ @NonNull final FragmentManager.BackStackEntry bse) {
+ if (!CommentRepliesFragment.TAG.equals(bse.getName())) {
+ final CommentRepliesFragment commentRepliesFragment =
+ (CommentRepliesFragment) fm.findFragmentByTag(
+ CommentRepliesFragment.TAG);
+ final BottomSheetBehavior bsb = BottomSheetBehavior
+ .from(mainBinding.fragmentPlayerHolder);
+ bsb.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
+ @Override
+ public void onStateChanged(@NonNull final View bottomSheet,
+ final int newState) {
+ if (newState == BottomSheetBehavior.STATE_EXPANDED) {
+ final Fragment detailFragment = fm.findFragmentById(
+ R.id.fragment_player_holder);
+ if (detailFragment instanceof VideoDetailFragment
+ && commentRepliesFragment != null) {
+ // should always be the case
+ ((VideoDetailFragment) detailFragment).scrollToComment(
+ commentRepliesFragment.getCommentsInfoItem());
+ }
+ bsb.removeBottomSheetCallback(this);
+ }
+ }
+
+ @Override
+ public void onSlide(@NonNull final View bottomSheet,
+ final float slideOffset) {
+ // not needed, listener is removed once the sheet is expanded
+ }
+ });
+ bsb.setState(BottomSheetBehavior.STATE_EXPANDED);
+ }
+ }
+
private boolean bottomSheetHiddenOrCollapsed() {
final BottomSheetBehavior bottomSheetBehavior =
BottomSheetBehavior.from(mainBinding.fragmentPlayerHolder);
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 7db5e0251c1..d607c540146 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
@@ -74,6 +74,7 @@
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.NewPipe;
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.stream.AudioStream;
@@ -1012,6 +1013,14 @@ public void scrollToTop() {
updateTabLayoutVisibility();
}
+ public void scrollToComment(final CommentsInfoItem comment) {
+ final Fragment fragment = pageAdapter.getItem(
+ pageAdapter.getItemPositionByTitle(COMMENTS_TAB_TAG));
+ if (fragment instanceof CommentsFragment) {
+ ((CommentsFragment) fragment).scrollToComment(comment);
+ }
+ }
+
/*//////////////////////////////////////////////////////////////////////////
// Play Utils
//////////////////////////////////////////////////////////////////////////*/
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 b8d0f1e6cea..62f97c72775 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
@@ -159,4 +159,10 @@ protected ItemViewMode getItemViewMode() {
return ItemViewMode.LIST;
}
+ /**
+ * @return the comment to which the replies are shown
+ */
+ public CommentsInfoItem getCommentsInfoItem() {
+ return commentsInfoItem;
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java
index 5a5f8496870..9481eba8131 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java
@@ -110,4 +110,8 @@ public void onCreateOptionsMenu(@NonNull final Menu menu,
protected ItemViewMode getItemViewMode() {
return ItemViewMode.LIST;
}
+
+ public void scrollToComment(final CommentsInfoItem comment) {
+ itemsList.scrollToPosition(infoListAdapter.getItemsList().indexOf(comment));
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index d0da2273937..0fcea5dd217 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -504,7 +504,8 @@ public static void openCommentAuthorIfPresent(@NonNull final FragmentActivity ac
public static void openCommentRepliesFragment(@NonNull final FragmentActivity activity,
final CommentsInfoItem commentsInfoItem) {
defaultTransaction(activity.getSupportFragmentManager())
- .replace(R.id.fragment_holder, new CommentRepliesFragment(commentsInfoItem))
+ .replace(R.id.fragment_holder, new CommentRepliesFragment(commentsInfoItem),
+ CommentRepliesFragment.TAG)
.addToBackStack(CommentRepliesFragment.TAG)
.commit();
}
From d76e9b0bd8940f8afc038f0b1d59581d2f0324fd Mon Sep 17 00:00:00 2001
From: Stypox
Date: Fri, 22 Dec 2023 12:50:32 +0100
Subject: [PATCH 45/82] Fix scrolling to correct comment after closing replies
---
.../java/org/schabi/newpipe/MainActivity.java | 96 ++++++++++++-------
.../fragments/detail/VideoDetailFragment.java | 14 ++-
.../list/comments/CommentsFragment.java | 10 +-
3 files changed, 78 insertions(+), 42 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java
index 5c56e867c23..a096e7eaf55 100644
--- a/app/src/main/java/org/schabi/newpipe/MainActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java
@@ -44,6 +44,7 @@
import android.widget.Spinner;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
@@ -51,6 +52,7 @@
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentContainerView;
import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceManager;
@@ -64,6 +66,7 @@
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.services.peertube.PeertubeInstance;
import org.schabi.newpipe.fragments.BackPressable;
@@ -561,9 +564,7 @@ public void onBackPressed() {
// Expand DetailsFragment if CommentRepliesFragment was opened
// and no other CommentRepliesFragments are on top of the back stack
// to show the top level comments again.
- final FragmentManager.BackStackEntry bse = fm.getBackStackEntryAt(
- fm.getBackStackEntryCount() - 2); // current fragment is at the top
- openDetailFragmentFromCommentReplies(fm, bse);
+ openDetailFragmentFromCommentReplies(fm, false);
}
} else {
@@ -646,10 +647,7 @@ private void onHomeButtonPressed() {
// Expand DetailsFragment if CommentRepliesFragment was opened
// and no other CommentRepliesFragments are on top of the back stack
// to show the top level comments again.
- fm.popBackStackImmediate();
- final FragmentManager.BackStackEntry bse = fm.getBackStackEntryAt(
- fm.getBackStackEntryCount() - 1);
- openDetailFragmentFromCommentReplies(fm, bse);
+ openDetailFragmentFromCommentReplies(fm, true);
} else if (!NavigationHelper.tryGotoSearchFragment(fm)) {
// If search fragment wasn't found in the backstack go to the main fragment
NavigationHelper.gotoMainFragment(fm);
@@ -850,38 +848,64 @@ public void onReceive(final Context context, final Intent intent) {
private void openDetailFragmentFromCommentReplies(
@NonNull final FragmentManager fm,
- @NonNull final FragmentManager.BackStackEntry bse) {
- if (!CommentRepliesFragment.TAG.equals(bse.getName())) {
- final CommentRepliesFragment commentRepliesFragment =
- (CommentRepliesFragment) fm.findFragmentByTag(
- CommentRepliesFragment.TAG);
- final BottomSheetBehavior bsb = BottomSheetBehavior
- .from(mainBinding.fragmentPlayerHolder);
- bsb.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
- @Override
- public void onStateChanged(@NonNull final View bottomSheet,
- final int newState) {
- if (newState == BottomSheetBehavior.STATE_EXPANDED) {
- final Fragment detailFragment = fm.findFragmentById(
- R.id.fragment_player_holder);
- if (detailFragment instanceof VideoDetailFragment
- && commentRepliesFragment != null) {
- // should always be the case
- ((VideoDetailFragment) detailFragment).scrollToComment(
- commentRepliesFragment.getCommentsInfoItem());
- }
- bsb.removeBottomSheetCallback(this);
+ final boolean popBackStack
+ ) {
+ // obtain the name of the fragment under the replies fragment that's going to be popped
+ @Nullable final String fragmentUnderEntryName;
+ if (fm.getBackStackEntryCount() < 2) {
+ fragmentUnderEntryName = null;
+ } else {
+ fragmentUnderEntryName = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 2)
+ .getName();
+ }
+
+ // the root comment is the comment for which the user opened the replies page
+ @Nullable final CommentRepliesFragment repliesFragment =
+ (CommentRepliesFragment) fm.findFragmentByTag(CommentRepliesFragment.TAG);
+ @Nullable final CommentsInfoItem rootComment =
+ repliesFragment == null ? null : repliesFragment.getCommentsInfoItem();
+
+ // sometimes this function pops the backstack, other times it's handled by the system
+ if (popBackStack) {
+ fm.popBackStackImmediate();
+ }
+
+ // only expand the bottom sheet back if there are no more nested comment replies fragments
+ // stacked under the one that is currently being popped
+ if (CommentRepliesFragment.TAG.equals(fragmentUnderEntryName)) {
+ return;
+ }
+
+ final BottomSheetBehavior behavior = BottomSheetBehavior
+ .from(mainBinding.fragmentPlayerHolder);
+ // do not return to the comment if the details fragment was closed
+ if (behavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
+ return;
+ }
+
+ // scroll to the root comment once the bottom sheet expansion animation is finished
+ behavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
+ @Override
+ public void onStateChanged(@NonNull final View bottomSheet,
+ final int newState) {
+ if (newState == BottomSheetBehavior.STATE_EXPANDED) {
+ final Fragment detailFragment = fm.findFragmentById(
+ R.id.fragment_player_holder);
+ if (detailFragment instanceof VideoDetailFragment && rootComment != null) {
+ // should always be the case
+ ((VideoDetailFragment) detailFragment).scrollToComment(rootComment);
}
+ behavior.removeBottomSheetCallback(this);
}
+ }
- @Override
- public void onSlide(@NonNull final View bottomSheet,
- final float slideOffset) {
- // not needed, listener is removed once the sheet is expanded
- }
- });
- bsb.setState(BottomSheetBehavior.STATE_EXPANDED);
- }
+ @Override
+ public void onSlide(@NonNull final View bottomSheet, final float slideOffset) {
+ // not needed, listener is removed once the sheet is expanded
+ }
+ });
+
+ behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
private boolean bottomSheetHiddenOrCollapsed() {
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 d607c540146..4da0a561e80 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
@@ -1014,10 +1014,16 @@ public void scrollToTop() {
}
public void scrollToComment(final CommentsInfoItem comment) {
- final Fragment fragment = pageAdapter.getItem(
- pageAdapter.getItemPositionByTitle(COMMENTS_TAB_TAG));
- if (fragment instanceof CommentsFragment) {
- ((CommentsFragment) fragment).scrollToComment(comment);
+ final int commentsTabPos = pageAdapter.getItemPositionByTitle(COMMENTS_TAB_TAG);
+ final Fragment fragment = pageAdapter.getItem(commentsTabPos);
+ if (!(fragment instanceof CommentsFragment)) {
+ return;
+ }
+
+ // unexpand the app bar only if scrolling to the comment succeeded
+ if (((CommentsFragment) fragment).scrollToComment(comment)) {
+ binding.appBarLayout.setExpanded(false, false);
+ binding.viewPager.setCurrentItem(commentsTabPos, false);
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java
index 9481eba8131..e25e02794f1 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java
@@ -111,7 +111,13 @@ protected ItemViewMode getItemViewMode() {
return ItemViewMode.LIST;
}
- public void scrollToComment(final CommentsInfoItem comment) {
- itemsList.scrollToPosition(infoListAdapter.getItemsList().indexOf(comment));
+ public boolean scrollToComment(final CommentsInfoItem comment) {
+ final int position = infoListAdapter.getItemsList().indexOf(comment);
+ if (position < 0) {
+ return false;
+ }
+
+ itemsList.scrollToPosition(position);
+ return true;
}
}
From aa84d6fc8febd9b442fe26a5ac5b206ce8212b62 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Fri, 22 Dec 2023 18:50:48 +0100
Subject: [PATCH 46/82] Add @NonNull annotations
---
.../list/comments/CommentRepliesFragment.java | 2 +-
.../holder/CommentInfoItemHolder.java | 5 +-
.../org/schabi/newpipe/util/Localization.java | 74 +++++++++++--------
.../schabi/newpipe/util/NavigationHelper.java | 6 +-
4 files changed, 50 insertions(+), 37 deletions(-)
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 62f97c72775..a816b149f1d 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
@@ -51,7 +51,7 @@ public CommentRepliesFragment() {
super(UserAction.REQUESTED_COMMENT_REPLIES);
}
- public CommentRepliesFragment(final CommentsInfoItem commentsInfoItem) {
+ public CommentRepliesFragment(@NonNull final CommentsInfoItem commentsInfoItem) {
this();
this.commentsInfoItem = commentsInfoItem;
// setting "" as title since the title will be properly set right after
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 ec336f6772f..8327b398ba3 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
@@ -14,6 +14,7 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.text.HtmlCompat;
import androidx.fragment.app.FragmentActivity;
@@ -166,12 +167,12 @@ public void updateFromItem(final InfoItem infoItem,
});
}
- private void openCommentAuthor(final CommentsInfoItem item) {
+ private void openCommentAuthor(@NonNull final CommentsInfoItem item) {
NavigationHelper.openCommentAuthorIfPresent((FragmentActivity) itemBuilder.getContext(),
item);
}
- private void openCommentReplies(final CommentsInfoItem item) {
+ private void openCommentReplies(@NonNull final CommentsInfoItem item) {
NavigationHelper.openCommentRepliesFragment((FragmentActivity) itemBuilder.getContext(),
item);
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java
index ef30e17613e..0485413cc55 100644
--- a/app/src/main/java/org/schabi/newpipe/util/Localization.java
+++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java
@@ -85,7 +85,7 @@ public static org.schabi.newpipe.extractor.localization.Localization getPreferre
.fromLocale(getPreferredLocale(context));
}
- public static ContentCountry getPreferredContentCountry(final Context context) {
+ public static ContentCountry getPreferredContentCountry(@NonNull final Context context) {
final String contentCountry = PreferenceManager.getDefaultSharedPreferences(context)
.getString(context.getString(R.string.content_country_key),
context.getString(R.string.default_localization_key));
@@ -95,41 +95,43 @@ public static ContentCountry getPreferredContentCountry(final Context context) {
return new ContentCountry(contentCountry);
}
- public static Locale getPreferredLocale(final Context context) {
+ public static Locale getPreferredLocale(@NonNull final Context context) {
return getLocaleFromPrefs(context, R.string.content_language_key);
}
- public static Locale getAppLocale(final Context context) {
+ public static Locale getAppLocale(@NonNull final Context context) {
return getLocaleFromPrefs(context, R.string.app_language_key);
}
- public static String localizeNumber(final Context context, final long number) {
+ public static String localizeNumber(@NonNull final Context context, final long number) {
return localizeNumber(context, (double) number);
}
- public static String localizeNumber(final Context context, final double number) {
+ public static String localizeNumber(@NonNull final Context context, final double number) {
final NumberFormat nf = NumberFormat.getInstance(getAppLocale(context));
return nf.format(number);
}
- public static String formatDate(final OffsetDateTime offsetDateTime, final Context context) {
+ public static String formatDate(@NonNull final Context context,
+ @NonNull final OffsetDateTime offsetDateTime) {
return DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(getAppLocale(context)).format(offsetDateTime
.atZoneSameInstant(ZoneId.systemDefault()));
}
@SuppressLint("StringFormatInvalid")
- public static String localizeUploadDate(final Context context,
- final OffsetDateTime offsetDateTime) {
- return context.getString(R.string.upload_date_text, formatDate(offsetDateTime, context));
+ public static String localizeUploadDate(@NonNull final Context context,
+ @NonNull final OffsetDateTime offsetDateTime) {
+ return context.getString(R.string.upload_date_text, formatDate(context, offsetDateTime));
}
- public static String localizeViewCount(final Context context, final long viewCount) {
+ public static String localizeViewCount(@NonNull final Context context, final long viewCount) {
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
localizeNumber(context, viewCount));
}
- public static String localizeStreamCount(final Context context, final long streamCount) {
+ public static String localizeStreamCount(@NonNull final Context context,
+ final long streamCount) {
switch ((int) streamCount) {
case (int) ListExtractor.ITEM_COUNT_UNKNOWN:
return "";
@@ -143,7 +145,8 @@ public static String localizeStreamCount(final Context context, final long strea
}
}
- public static String localizeStreamCountMini(final Context context, final long streamCount) {
+ public static String localizeStreamCountMini(@NonNull final Context context,
+ final long streamCount) {
switch ((int) streamCount) {
case (int) ListExtractor.ITEM_COUNT_UNKNOWN:
return "";
@@ -156,12 +159,13 @@ public static String localizeStreamCountMini(final Context context, final long s
}
}
- public static String localizeWatchingCount(final Context context, final long watchingCount) {
+ public static String localizeWatchingCount(@NonNull final Context context,
+ final long watchingCount) {
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, watchingCount,
localizeNumber(context, watchingCount));
}
- public static String shortCount(final Context context, final long count) {
+ public static String shortCount(@NonNull final Context context, final long count) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return CompactDecimalFormat.getInstance(getAppLocale(context),
CompactDecimalFormat.CompactStyle.SHORT).format(count);
@@ -182,37 +186,40 @@ public static String shortCount(final Context context, final long count) {
}
}
- public static String listeningCount(final Context context, final long listeningCount) {
+ public static String listeningCount(@NonNull final Context context, final long listeningCount) {
return getQuantity(context, R.plurals.listening, R.string.no_one_listening, listeningCount,
shortCount(context, listeningCount));
}
- public static String shortWatchingCount(final Context context, final long watchingCount) {
+ public static String shortWatchingCount(@NonNull final Context context,
+ final long watchingCount) {
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, watchingCount,
shortCount(context, watchingCount));
}
- public static String shortViewCount(final Context context, final long viewCount) {
+ public static String shortViewCount(@NonNull final Context context, final long viewCount) {
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
shortCount(context, viewCount));
}
- public static String shortSubscriberCount(final Context context, final long subscriberCount) {
+ public static String shortSubscriberCount(@NonNull final Context context,
+ final long subscriberCount) {
return getQuantity(context, R.plurals.subscribers, R.string.no_subscribers, subscriberCount,
shortCount(context, subscriberCount));
}
- public static String downloadCount(final Context context, final int downloadCount) {
+ public static String downloadCount(@NonNull final Context context, final int downloadCount) {
return getQuantity(context, R.plurals.download_finished_notification, 0,
downloadCount, shortCount(context, downloadCount));
}
- public static String deletedDownloadCount(final Context context, final int deletedCount) {
+ public static String deletedDownloadCount(@NonNull final Context context,
+ final int deletedCount) {
return getQuantity(context, R.plurals.deleted_downloads_toast, 0,
deletedCount, shortCount(context, deletedCount));
}
- public static String replyCount(final Context context, final int replyCount) {
+ public static String replyCount(@NonNull final Context context, final int replyCount) {
return getQuantity(context, R.plurals.replies, 0, replyCount,
String.valueOf(replyCount));
}
@@ -223,7 +230,7 @@ public static String replyCount(final Context context, final int replyCount) {
* @return if {@code likeCount} is smaller than {@code 0}, the string {@code "-"}, otherwise
* the result of calling {@link #shortCount(Context, long)} on the like count
*/
- public static String likeCount(final Context context, final int likeCount) {
+ public static String likeCount(@NonNull final Context context, final int likeCount) {
if (likeCount < 0) {
return "-";
} else {
@@ -263,7 +270,8 @@ public static String getDurationString(final long duration) {
* @return duration in a human readable string.
*/
@NonNull
- public static String localizeDuration(final Context context, final int durationInSecs) {
+ public static String localizeDuration(@NonNull final Context context,
+ final int durationInSecs) {
if (durationInSecs < 0) {
throw new IllegalArgumentException("duration can not be negative");
}
@@ -300,7 +308,7 @@ public static String localizeDuration(final Context context, final int durationI
* @param track an {@link AudioStream} of the track
* @return the localized name of the audio track
*/
- public static String audioTrackName(final Context context, final AudioStream track) {
+ public static String audioTrackName(@NonNull final Context context, final AudioStream track) {
final String name;
if (track.getAudioLocale() != null) {
name = track.getAudioLocale().getDisplayLanguage(getAppLocale(context));
@@ -320,7 +328,8 @@ public static String audioTrackName(final Context context, final AudioStream tra
}
@Nullable
- private static String audioTrackType(final Context context, final AudioTrackType trackType) {
+ private static String audioTrackType(@NonNull final Context context,
+ final AudioTrackType trackType) {
switch (trackType) {
case ORIGINAL:
return context.getString(R.string.audio_track_type_original);
@@ -336,17 +345,17 @@ private static String audioTrackType(final Context context, final AudioTrackType
// Pretty Time
//////////////////////////////////////////////////////////////////////////*/
- public static void initPrettyTime(final PrettyTime time) {
+ public static void initPrettyTime(@NonNull final PrettyTime time) {
prettyTime = time;
// Do not use decades as YouTube doesn't either.
prettyTime.removeUnit(Decade.class);
}
- public static PrettyTime resolvePrettyTime(final Context context) {
+ public static PrettyTime resolvePrettyTime(@NonNull final Context context) {
return new PrettyTime(getAppLocale(context));
}
- public static String relativeTime(final OffsetDateTime offsetDateTime) {
+ public static String relativeTime(@NonNull final OffsetDateTime offsetDateTime) {
return prettyTime.formatUnrounded(offsetDateTime);
}
@@ -383,7 +392,8 @@ public static void assureCorrectAppLanguage(final Context c) {
res.updateConfiguration(conf, dm);
}
- private static Locale getLocaleFromPrefs(final Context context, @StringRes final int prefKey) {
+ private static Locale getLocaleFromPrefs(@NonNull final Context context,
+ @StringRes final int prefKey) {
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
final String defaultKey = context.getString(R.string.default_localization_key);
final String languageCode = sp.getString(context.getString(prefKey), defaultKey);
@@ -399,8 +409,10 @@ private static double round(final double value) {
return new BigDecimal(value).setScale(1, RoundingMode.HALF_UP).doubleValue();
}
- private static String getQuantity(final Context context, @PluralsRes final int pluralId,
- @StringRes final int zeroCaseStringId, final long count,
+ private static String getQuantity(@NonNull final Context context,
+ @PluralsRes final int pluralId,
+ @StringRes final int zeroCaseStringId,
+ final long count,
final String formattedCount) {
if (count == 0) {
return context.getString(zeroCaseStringId);
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index 0fcea5dd217..5dee32371b5 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -489,7 +489,7 @@ public static void openChannelFragment(@NonNull final Fragment fragment,
* @param comment the comment whose uploader/author will be opened
*/
public static void openCommentAuthorIfPresent(@NonNull final FragmentActivity activity,
- final CommentsInfoItem comment) {
+ @NonNull final CommentsInfoItem comment) {
if (isEmpty(comment.getUploaderUrl())) {
return;
}
@@ -502,9 +502,9 @@ public static void openCommentAuthorIfPresent(@NonNull final FragmentActivity ac
}
public static void openCommentRepliesFragment(@NonNull final FragmentActivity activity,
- final CommentsInfoItem commentsInfoItem) {
+ @NonNull final CommentsInfoItem comment) {
defaultTransaction(activity.getSupportFragmentManager())
- .replace(R.id.fragment_holder, new CommentRepliesFragment(commentsInfoItem),
+ .replace(R.id.fragment_holder, new CommentRepliesFragment(comment),
CommentRepliesFragment.TAG)
.addToBackStack(CommentRepliesFragment.TAG)
.commit();
From e4a07411b8a591b4f0a15ef056f796cf519354a1 Mon Sep 17 00:00:00 2001
From: TacoTheDank
Date: Tue, 31 Oct 2023 16:25:19 -0400
Subject: [PATCH 47/82] Update some AndroidX libraries
---
app/build.gradle | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 993363e32ff..131bcaf0fb4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -106,9 +106,9 @@ android {
ext {
checkstyleVersion = '10.12.1'
- androidxLifecycleVersion = '2.5.1'
+ androidxLifecycleVersion = '2.6.2'
androidxRoomVersion = '2.5.2'
- androidxWorkVersion = '2.7.1'
+ androidxWorkVersion = '2.8.1'
icepickVersion = '3.2.0'
exoPlayerVersion = '2.18.7'
@@ -208,25 +208,25 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
/** AndroidX **/
- implementation 'androidx.appcompat:appcompat:1.5.1'
+ implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
- implementation 'androidx.core:core-ktx:1.10.0'
+ implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.documentfile:documentfile:1.0.1'
- implementation 'androidx.fragment:fragment-ktx:1.4.1'
+ implementation 'androidx.fragment:fragment-ktx:1.6.1'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${androidxLifecycleVersion}"
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
implementation 'androidx.media:media:1.6.0'
- implementation 'androidx.preference:preference:1.2.0'
- implementation 'androidx.recyclerview:recyclerview:1.2.1'
+ implementation 'androidx.preference:preference:1.2.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation "androidx.room:room-runtime:${androidxRoomVersion}"
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-beta01'
+ 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.9.0'
From 00566ed4d442bda54533459fbded06d91be230a3 Mon Sep 17 00:00:00 2001
From: TacoTheDank
Date: Tue, 31 Oct 2023 16:26:20 -0400
Subject: [PATCH 48/82] Fix AndroidX Work deprecation
---
.../newpipe/local/feed/notifications/NotificationWorker.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt
index de640dbbbe1..a40bf35dc52 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt
@@ -137,7 +137,7 @@ class NotificationWorker(
.enqueueUniquePeriodicWork(
WORK_TAG,
if (force) {
- ExistingPeriodicWorkPolicy.REPLACE
+ ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE
} else {
ExistingPeriodicWorkPolicy.KEEP
},
From f3b458c803eb1f565d5d16913d37e26cd95992fc Mon Sep 17 00:00:00 2001
From: Isira Seneviratne <31027858+isira-seneviratne@users.noreply.github.com>
Date: Tue, 31 Oct 2023 16:31:16 -0400
Subject: [PATCH 49/82] Bump compileSdk to 34
---
app/build.gradle | 2 +-
.../newpipe/player/gesture/MainPlayerGestureListener.kt | 5 ++---
.../newpipe/player/gesture/PopupPlayerGestureListener.kt | 7 +++++--
.../newpipe/player/notification/NotificationUtil.java | 2 +-
.../org/schabi/newpipe/views/player/CircleClipTapView.kt | 6 +++---
5 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 131bcaf0fb4..d6b49f232a7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -12,7 +12,7 @@ plugins {
}
android {
- compileSdk 33
+ compileSdk 34
namespace 'org.schabi.newpipe'
defaultConfig {
diff --git a/app/src/main/java/org/schabi/newpipe/player/gesture/MainPlayerGestureListener.kt b/app/src/main/java/org/schabi/newpipe/player/gesture/MainPlayerGestureListener.kt
index 8acd7041374..ff0bb269d0a 100644
--- a/app/src/main/java/org/schabi/newpipe/player/gesture/MainPlayerGestureListener.kt
+++ b/app/src/main/java/org/schabi/newpipe/player/gesture/MainPlayerGestureListener.kt
@@ -160,13 +160,12 @@ class MainPlayerGestureListener(
}
override fun onScroll(
- initialEvent: MotionEvent,
+ initialEvent: MotionEvent?,
movingEvent: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
-
- if (!playerUi.isFullscreen) {
+ if (initialEvent == null || !playerUi.isFullscreen) {
return false
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/gesture/PopupPlayerGestureListener.kt b/app/src/main/java/org/schabi/newpipe/player/gesture/PopupPlayerGestureListener.kt
index 23edcaeb844..0b94bf364e0 100644
--- a/app/src/main/java/org/schabi/newpipe/player/gesture/PopupPlayerGestureListener.kt
+++ b/app/src/main/java/org/schabi/newpipe/player/gesture/PopupPlayerGestureListener.kt
@@ -167,7 +167,7 @@ class PopupPlayerGestureListener(
}
override fun onFling(
- e1: MotionEvent,
+ e1: MotionEvent?,
e2: MotionEvent,
velocityX: Float,
velocityY: Float
@@ -218,11 +218,14 @@ class PopupPlayerGestureListener(
}
override fun onScroll(
- initialEvent: MotionEvent,
+ initialEvent: MotionEvent?,
movingEvent: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
+ if (initialEvent == null) {
+ return false
+ }
if (isResizing) {
return super.onScroll(initialEvent, movingEvent, distanceX, distanceY)
diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
index 05c2e3af6dd..3fa7c26233c 100644
--- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
+++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
@@ -364,7 +364,7 @@ private void setLargeIcon(final NotificationCompat.Builder builder) {
final Bitmap thumbnail = player.getThumbnail();
if (thumbnail == null || !showThumbnail) {
// since the builder is reused, make sure the thumbnail is unset if there is not one
- builder.setLargeIcon(null);
+ builder.setLargeIcon((Bitmap) null);
return;
}
diff --git a/app/src/main/java/org/schabi/newpipe/views/player/CircleClipTapView.kt b/app/src/main/java/org/schabi/newpipe/views/player/CircleClipTapView.kt
index e3d14291694..8554e71943d 100644
--- a/app/src/main/java/org/schabi/newpipe/views/player/CircleClipTapView.kt
+++ b/app/src/main/java/org/schabi/newpipe/views/player/CircleClipTapView.kt
@@ -80,10 +80,10 @@ class CircleClipTapView(context: Context?, attrs: AttributeSet) : View(context,
updatePathShape()
}
- override fun onDraw(canvas: Canvas?) {
+ override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
- canvas?.clipPath(shapePath)
- canvas?.drawPath(shapePath, backgroundPaint)
+ canvas.clipPath(shapePath)
+ canvas.drawPath(shapePath, backgroundPaint)
}
}
From 76f1e588f7668e7ed613caac8d0a8cd053d2032b Mon Sep 17 00:00:00 2001
From: TacoTheDank
Date: Tue, 31 Oct 2023 16:35:56 -0400
Subject: [PATCH 50/82] Utilize BundleCompat and IntentCompat methods
---
app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java | 3 ++-
.../subscription/services/SubscriptionsExportService.java | 3 ++-
.../subscription/services/SubscriptionsImportService.java | 3 ++-
app/src/main/java/org/schabi/newpipe/util/StateSaver.java | 4 +++-
4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java b/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java
index 6b34c8e9001..831a8cc4bba 100644
--- a/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java
@@ -17,6 +17,7 @@
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.content.IntentCompat;
import com.grack.nanojson.JsonWriter;
@@ -105,7 +106,7 @@ protected void onCreate(final Bundle savedInstanceState) {
actionBar.setDisplayShowTitleEnabled(true);
}
- errorInfo = intent.getParcelableExtra(ERROR_INFO);
+ errorInfo = IntentCompat.getParcelableExtra(intent, ERROR_INFO, ErrorInfo.class);
// important add guru meditation
addGuruMeditation();
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java
index d56d16f3cc5..54809068ac8 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java
@@ -25,6 +25,7 @@
import android.net.Uri;
import android.util.Log;
+import androidx.core.content.IntentCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.reactivestreams.Subscriber;
@@ -65,7 +66,7 @@ public int onStartCommand(final Intent intent, final int flags, final int startI
return START_NOT_STICKY;
}
- final Uri path = intent.getParcelableExtra(KEY_FILE_PATH);
+ final Uri path = IntentCompat.getParcelableExtra(intent, KEY_FILE_PATH, Uri.class);
if (path == null) {
stopAndReportError(new IllegalStateException(
"Exporting to a file, but the path is null"),
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java
index d624e1038e7..442c7fddb8b 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java
@@ -30,6 +30,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.content.IntentCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.reactivestreams.Subscriber;
@@ -108,7 +109,7 @@ public int onStartCommand(final Intent intent, final int flags, final int startI
if (currentMode == CHANNEL_URL_MODE) {
channelUrl = intent.getStringExtra(KEY_VALUE);
} else {
- final Uri uri = intent.getParcelableExtra(KEY_VALUE);
+ final Uri uri = IntentCompat.getParcelableExtra(intent, KEY_VALUE, Uri.class);
if (uri == null) {
stopAndReportError(new IllegalStateException(
"Importing from input stream, but file path is null"),
diff --git a/app/src/main/java/org/schabi/newpipe/util/StateSaver.java b/app/src/main/java/org/schabi/newpipe/util/StateSaver.java
index 91dc5f35b93..61fdb602f28 100644
--- a/app/src/main/java/org/schabi/newpipe/util/StateSaver.java
+++ b/app/src/main/java/org/schabi/newpipe/util/StateSaver.java
@@ -27,6 +27,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.os.BundleCompat;
import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.MainActivity;
@@ -82,7 +83,8 @@ public static SavedState tryToRestore(final Bundle outState, final WriteRead wri
return null;
}
- final SavedState savedState = outState.getParcelable(KEY_SAVED_STATE);
+ final SavedState savedState = BundleCompat.getParcelable(
+ outState, KEY_SAVED_STATE, SavedState.class);
if (savedState == null) {
return null;
}
From f9fc1cd817ce989db6a636d973f09417c1ff0153 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne <31027858+isira-seneviratne@users.noreply.github.com>
Date: Tue, 31 Oct 2023 16:36:13 -0400
Subject: [PATCH 51/82] Store/retrieve parcelable arrays as lists instead.
---
...agmentStatePagerAdapterMenuWorkaround.java | 12 ++---
.../org/schabi/newpipe/about/AboutActivity.kt | 2 +-
.../schabi/newpipe/about/LicenseFragment.kt | 11 +++--
.../newpipe/download/DownloadDialog.java | 15 +++---
.../java/org/schabi/newpipe/ktx/Bundle.kt | 9 ++++
.../giga/service/DownloadManagerService.java | 47 +++++++++----------
6 files changed, 53 insertions(+), 43 deletions(-)
create mode 100644 app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt
diff --git a/app/src/main/java/androidx/fragment/app/FragmentStatePagerAdapterMenuWorkaround.java b/app/src/main/java/androidx/fragment/app/FragmentStatePagerAdapterMenuWorkaround.java
index 8d87e90bddf..8d03a148604 100644
--- a/app/src/main/java/androidx/fragment/app/FragmentStatePagerAdapterMenuWorkaround.java
+++ b/app/src/main/java/androidx/fragment/app/FragmentStatePagerAdapterMenuWorkaround.java
@@ -25,6 +25,7 @@
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.os.BundleCompat;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager.widget.PagerAdapter;
@@ -284,7 +285,7 @@ public Parcelable saveState() {
Bundle state = null;
if (!mSavedState.isEmpty()) {
state = new Bundle();
- state.putParcelableArray("states", mSavedState.toArray(new Fragment.SavedState[0]));
+ state.putParcelableArrayList("states", mSavedState);
}
for (int i = 0; i < mFragments.size(); i++) {
final Fragment f = mFragments.get(i);
@@ -311,13 +312,12 @@ public void restoreState(@Nullable final Parcelable state, @Nullable final Class
if (state != null) {
final Bundle bundle = (Bundle) state;
bundle.setClassLoader(loader);
- final Parcelable[] fss = bundle.getParcelableArray("states");
+ final var states = BundleCompat.getParcelableArrayList(bundle, "states",
+ Fragment.SavedState.class);
mSavedState.clear();
mFragments.clear();
- if (fss != null) {
- for (final Parcelable parcelable : fss) {
- mSavedState.add((Fragment.SavedState) parcelable);
- }
+ if (states != null) {
+ mSavedState.addAll(states);
}
final Iterable keys = bundle.keySet();
for (final String key : keys) {
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 f1d4c26df8c..7f148e9b5c2 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
@@ -116,7 +116,7 @@ class AboutActivity : AppCompatActivity() {
/**
* List of all software components.
*/
- private val SOFTWARE_COMPONENTS = arrayOf(
+ private val SOFTWARE_COMPONENTS = arrayListOf(
SoftwareComponent(
"ACRA", "2013", "Kevin Gaudin",
"https://github.com/ACRA/acra", StandardLicenses.APACHE2
diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt
index a5cf2924a93..9f5ad2a7a07 100644
--- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt
+++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt
@@ -18,6 +18,7 @@ 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
@@ -25,16 +26,15 @@ import org.schabi.newpipe.util.external_communication.ShareUtils
* Fragment containing the software licenses.
*/
class LicenseFragment : Fragment() {
- private lateinit var softwareComponents: Array
+ private lateinit var softwareComponents: List
private var activeSoftwareComponent: SoftwareComponent? = null
private val compositeDisposable = CompositeDisposable()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- softwareComponents = arguments?.getParcelableArray(ARG_COMPONENTS) as Array
+ softwareComponents = arguments?.parcelableArrayList(ARG_COMPONENTS)!!
+ .sortedBy { it.name } // Sort components by name
activeSoftwareComponent = savedInstanceState?.getSerializable(SOFTWARE_COMPONENT_KEY) as? SoftwareComponent
- // Sort components by name
- softwareComponents.sortBy { it.name }
}
override fun onDestroy() {
@@ -130,7 +130,8 @@ class LicenseFragment : Fragment() {
StandardLicenses.GPL3,
BuildConfig.VERSION_NAME
)
- fun newInstance(softwareComponents: Array): LicenseFragment {
+
+ 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/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java
index 2e0a421da3f..1375d661ef1 100644
--- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java
+++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java
@@ -74,6 +74,7 @@
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -1052,7 +1053,7 @@ private void continueSelectedDownload(@NonNull final StoredFileHelper storage) {
final char kind;
int threads = dialogBinding.threads.getProgress() + 1;
final String[] urls;
- final MissionRecoveryInfo[] recoveryInfo;
+ final List recoveryInfo;
String psName = null;
String[] psArgs = null;
long nearLength = 0;
@@ -1117,9 +1118,7 @@ private void continueSelectedDownload(@NonNull final StoredFileHelper storage) {
urls = new String[] {
selectedStream.getContent()
};
- recoveryInfo = new MissionRecoveryInfo[] {
- new MissionRecoveryInfo(selectedStream)
- };
+ recoveryInfo = List.of(new MissionRecoveryInfo(selectedStream));
} else {
if (secondaryStream.getDeliveryMethod() != PROGRESSIVE_HTTP) {
throw new IllegalArgumentException("Unsupported stream delivery format"
@@ -1129,12 +1128,14 @@ private void continueSelectedDownload(@NonNull final StoredFileHelper storage) {
urls = new String[] {
selectedStream.getContent(), secondaryStream.getContent()
};
- recoveryInfo = new MissionRecoveryInfo[] {new MissionRecoveryInfo(selectedStream),
- new MissionRecoveryInfo(secondaryStream)};
+ recoveryInfo = List.of(
+ new MissionRecoveryInfo(selectedStream),
+ new MissionRecoveryInfo(secondaryStream)
+ );
}
DownloadManagerService.startMission(context, urls, storage, kind, threads,
- currentInfo.getUrl(), psName, psArgs, nearLength, recoveryInfo);
+ currentInfo.getUrl(), psName, psArgs, nearLength, new ArrayList<>(recoveryInfo));
Toast.makeText(context, getString(R.string.download_has_started),
Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt b/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt
new file mode 100644
index 00000000000..61721d5467c
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt
@@ -0,0 +1,9 @@
+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/java/us/shandian/giga/service/DownloadManagerService.java b/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java
index 009a4f4be89..42ff3ca8cb8 100755
--- a/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java
+++ b/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java
@@ -23,7 +23,6 @@
import android.os.Handler.Callback;
import android.os.IBinder;
import android.os.Message;
-import android.os.Parcelable;
import android.util.Log;
import android.widget.Toast;
@@ -36,6 +35,7 @@
import androidx.core.app.PendingIntentCompat;
import androidx.core.app.ServiceCompat;
import androidx.core.content.ContextCompat;
+import androidx.core.content.IntentCompat;
import androidx.preference.PreferenceManager;
import org.schabi.newpipe.R;
@@ -49,6 +49,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import us.shandian.giga.get.DownloadMission;
import us.shandian.giga.get.MissionRecoveryInfo;
@@ -359,29 +360,29 @@ public void updateForegroundState(boolean state) {
*/
public static void startMission(Context context, String[] urls, StoredFileHelper storage,
char kind, int threads, String source, String psName,
- String[] psArgs, long nearLength, MissionRecoveryInfo[] recoveryInfo) {
- Intent intent = new Intent(context, DownloadManagerService.class);
- intent.setAction(Intent.ACTION_RUN);
- intent.putExtra(EXTRA_URLS, urls);
- intent.putExtra(EXTRA_KIND, kind);
- intent.putExtra(EXTRA_THREADS, threads);
- intent.putExtra(EXTRA_SOURCE, source);
- intent.putExtra(EXTRA_POSTPROCESSING_NAME, psName);
- intent.putExtra(EXTRA_POSTPROCESSING_ARGS, psArgs);
- intent.putExtra(EXTRA_NEAR_LENGTH, nearLength);
- intent.putExtra(EXTRA_RECOVERY_INFO, recoveryInfo);
-
- intent.putExtra(EXTRA_PARENT_PATH, storage.getParentUri());
- intent.putExtra(EXTRA_PATH, storage.getUri());
- intent.putExtra(EXTRA_STORAGE_TAG, storage.getTag());
+ String[] psArgs, long nearLength,
+ ArrayList recoveryInfo) {
+ final Intent intent = new Intent(context, DownloadManagerService.class)
+ .setAction(Intent.ACTION_RUN)
+ .putExtra(EXTRA_URLS, urls)
+ .putExtra(EXTRA_KIND, kind)
+ .putExtra(EXTRA_THREADS, threads)
+ .putExtra(EXTRA_SOURCE, source)
+ .putExtra(EXTRA_POSTPROCESSING_NAME, psName)
+ .putExtra(EXTRA_POSTPROCESSING_ARGS, psArgs)
+ .putExtra(EXTRA_NEAR_LENGTH, nearLength)
+ .putExtra(EXTRA_RECOVERY_INFO, recoveryInfo)
+ .putExtra(EXTRA_PARENT_PATH, storage.getParentUri())
+ .putExtra(EXTRA_PATH, storage.getUri())
+ .putExtra(EXTRA_STORAGE_TAG, storage.getTag());
context.startService(intent);
}
private void startMission(Intent intent) {
String[] urls = intent.getStringArrayExtra(EXTRA_URLS);
- Uri path = intent.getParcelableExtra(EXTRA_PATH);
- Uri parentPath = intent.getParcelableExtra(EXTRA_PARENT_PATH);
+ Uri path = IntentCompat.getParcelableExtra(intent, EXTRA_PATH, Uri.class);
+ Uri parentPath = IntentCompat.getParcelableExtra(intent, EXTRA_PARENT_PATH, Uri.class);
int threads = intent.getIntExtra(EXTRA_THREADS, 1);
char kind = intent.getCharExtra(EXTRA_KIND, '?');
String psName = intent.getStringExtra(EXTRA_POSTPROCESSING_NAME);
@@ -389,7 +390,9 @@ private void startMission(Intent intent) {
String source = intent.getStringExtra(EXTRA_SOURCE);
long nearLength = intent.getLongExtra(EXTRA_NEAR_LENGTH, 0);
String tag = intent.getStringExtra(EXTRA_STORAGE_TAG);
- Parcelable[] parcelRecovery = intent.getParcelableArrayExtra(EXTRA_RECOVERY_INFO);
+ final var recovery = IntentCompat.getParcelableArrayListExtra(intent, EXTRA_RECOVERY_INFO,
+ MissionRecoveryInfo.class);
+ Objects.requireNonNull(recovery);
StoredFileHelper storage;
try {
@@ -404,15 +407,11 @@ private void startMission(Intent intent) {
else
ps = Postprocessing.getAlgorithm(psName, psArgs);
- MissionRecoveryInfo[] recovery = new MissionRecoveryInfo[parcelRecovery.length];
- for (int i = 0; i < parcelRecovery.length; i++)
- recovery[i] = (MissionRecoveryInfo) parcelRecovery[i];
-
final DownloadMission mission = new DownloadMission(urls, storage, kind, ps);
mission.threadCount = threads;
mission.source = source;
mission.nearLength = nearLength;
- mission.recoveryInfo = recovery;
+ mission.recoveryInfo = recovery.toArray(MissionRecoveryInfo[]::new);
if (ps != null)
ps.setTemporalDir(DownloadManager.pickAvailableTemporalDir(this));
From 4a7fda95aee59cd9a1ef4444ab8d84570205f8dc Mon Sep 17 00:00:00 2001
From: TacoTheDank
Date: Tue, 31 Oct 2023 21:25:11 -0400
Subject: [PATCH 52/82] Update miscellaneous libraries
---
app/build.gradle | 19 +++++++------------
.../org/schabi/newpipe/database/Converters.kt | 2 +-
.../local/feed/service/FeedEventManager.kt | 2 +-
.../subscription/dialog/FeedGroupDialog.kt | 10 +++++-----
.../dialog/FeedGroupDialogViewModel.kt | 4 ++--
.../local/subscription/FeedGroupIconTest.kt | 4 ++--
build.gradle | 4 ++--
7 files changed, 20 insertions(+), 25 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index d6b49f232a7..3705776b6e8 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -118,7 +118,6 @@ ext {
leakCanaryVersion = '2.12'
stethoVersion = '1.6.0'
- mockitoVersion = '4.0.0'
}
configurations {
@@ -237,13 +236,10 @@ dependencies {
kapt "frankiesardo:icepick-processor:${icepickVersion}"
// HTML parser
- implementation "org.jsoup:jsoup:1.16.1"
+ implementation "org.jsoup:jsoup:1.16.2"
// HTTP client
- implementation "com.squareup.okhttp3:okhttp:4.11.0"
- // okhttp3:4.11.0 introduces a vulnerability from com.squareup.okio:okio@3.3.0,
- // remove com.squareup.okio:okio when updating okhttp
- implementation "com.squareup.okio:okio:3.4.0"
+ implementation "com.squareup.okhttp3:okhttp:4.12.0"
// Media player
implementation "com.google.android.exoplayer:exoplayer-core:${exoPlayerVersion}"
@@ -272,19 +268,19 @@ dependencies {
implementation "io.noties.markwon:linkify:${markwonVersion}"
// Crash reporting
- implementation "ch.acra:acra-core:5.10.1"
+ implementation "ch.acra:acra-core:5.11.3"
// Properly restarting
implementation 'com.jakewharton:process-phoenix:2.1.2'
// Reactive extensions for Java VM
- implementation "io.reactivex.rxjava3:rxjava:3.1.6"
+ implementation "io.reactivex.rxjava3:rxjava:3.1.8"
implementation "io.reactivex.rxjava3:rxandroid:3.0.2"
// RxJava binding APIs for Android UI widgets
implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0"
// Date and time formatting
- implementation "org.ocpsoft.prettytime:prettytime:5.0.6.Final"
+ implementation "org.ocpsoft.prettytime:prettytime:5.0.7.Final"
/** Debugging **/
// Memory leak detection
@@ -297,13 +293,12 @@ dependencies {
/** Testing **/
testImplementation 'junit:junit:4.13.2'
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
- testImplementation "org.mockito:mockito-inline:${mockitoVersion}"
+ testImplementation 'org.mockito:mockito-core:5.6.0'
androidTestImplementation "androidx.test.ext:junit:1.1.5"
androidTestImplementation "androidx.test:runner:1.5.2"
androidTestImplementation "androidx.room:room-testing:${androidxRoomVersion}"
- androidTestImplementation "org.assertj:assertj-core:3.23.1"
+ androidTestImplementation "org.assertj:assertj-core:3.24.2"
}
static String getGitWorkingBranch() {
diff --git a/app/src/main/java/org/schabi/newpipe/database/Converters.kt b/app/src/main/java/org/schabi/newpipe/database/Converters.kt
index 0eafcede1af..6f705a5e4f0 100644
--- a/app/src/main/java/org/schabi/newpipe/database/Converters.kt
+++ b/app/src/main/java/org/schabi/newpipe/database/Converters.kt
@@ -47,6 +47,6 @@ object Converters {
@TypeConverter
fun feedGroupIconOf(id: Int): FeedGroupIcon {
- return FeedGroupIcon.values().first { it.id == id }
+ return FeedGroupIcon.entries.first { it.id == id }
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedEventManager.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedEventManager.kt
index 3d19de9c693..1c2826e7a67 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedEventManager.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedEventManager.kt
@@ -26,7 +26,7 @@ object FeedEventManager {
}
sealed class Event {
- object IdleEvent : Event()
+ data object IdleEvent : Event()
data class ProgressEvent(val currentProgress: Int = -1, val maxProgress: Int = -1, @StringRes val progressMessage: Int = 0) : Event() {
constructor(@StringRes progressMessage: Int) : this(-1, -1, progressMessage)
}
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt
index 19c581c080f..41761fb0102 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt
@@ -55,10 +55,10 @@ class FeedGroupDialog : DialogFragment(), BackPressable {
private var groupSortOrder: Long = -1
sealed class ScreenState : Serializable {
- object InitialScreen : ScreenState()
- object IconPickerScreen : ScreenState()
- object SubscriptionsPickerScreen : ScreenState()
- object DeleteScreen : ScreenState()
+ data object InitialScreen : ScreenState()
+ data object IconPickerScreen : ScreenState()
+ data object SubscriptionsPickerScreen : ScreenState()
+ data object DeleteScreen : ScreenState()
}
@State @JvmField var selectedIcon: FeedGroupIcon? = null
@@ -370,7 +370,7 @@ class FeedGroupDialog : DialogFragment(), BackPressable {
private fun setupIconPicker() {
val groupAdapter = GroupieAdapter()
- groupAdapter.addAll(FeedGroupIcon.values().map { PickerIconItem(it) })
+ groupAdapter.addAll(FeedGroupIcon.entries.map { PickerIconItem(it) })
feedGroupCreateBinding.iconSelector.apply {
layoutManager = GridLayoutManager(requireContext(), 7, RecyclerView.VERTICAL, false)
diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt
index eff1a4400bb..292bda394cc 100644
--- a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt
@@ -110,8 +110,8 @@ class FeedGroupDialogViewModel(
}
sealed class DialogEvent {
- object ProcessingEvent : DialogEvent()
- object SuccessEvent : DialogEvent()
+ data object ProcessingEvent : DialogEvent()
+ data object SuccessEvent : DialogEvent()
}
data class Filter(val query: String, val showOnlyUngrouped: Boolean)
diff --git a/app/src/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt b/app/src/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt
index 1479c3d1eee..2fc44d9b7ab 100644
--- a/app/src/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt
+++ b/app/src/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt
@@ -9,7 +9,7 @@ class FeedGroupIconTest {
fun `No gaps and repeated ids`() {
val usedIds = HashSet()
- for ((shouldBeId, currentIcon) in FeedGroupIcon.values().withIndex()) {
+ for ((shouldBeId, currentIcon) in FeedGroupIcon.entries.withIndex()) {
val added = usedIds.add(currentIcon.id)
assertTrue("Repeated ids (current item: ${currentIcon.name} - ${currentIcon.id})", added)
@@ -24,7 +24,7 @@ class FeedGroupIconTest {
fun `No icons pointing to the same attr`() {
val usedIcons = HashSet()
- for (groupIcon in FeedGroupIcon.values()) {
+ for (groupIcon in FeedGroupIcon.entries) {
val added = usedIcons.add(groupIcon.drawableResource)
assertTrue("Repeated icon (current item: ${groupIcon.name} - ${groupIcon.id})", added)
}
diff --git a/build.gradle b/build.gradle
index f1c861c9f47..2f3d292bb75 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.8.22'
+ ext.kotlin_version = '1.9.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.1.1'
+ classpath 'com.android.tools.build:gradle:8.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
From 0f81a0504ce88682f6b0810f81807676ade64514 Mon Sep 17 00:00:00 2001
From: TacoTheDank
Date: Tue, 31 Oct 2023 21:28:24 -0400
Subject: [PATCH 53/82] Use 'tasks.register' for Gradle tasks
---
app/build.gradle | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 3705776b6e8..1e109259d59 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -132,7 +132,7 @@ checkstyle {
toolVersion = checkstyleVersion
}
-task runCheckstyle(type: Checkstyle) {
+tasks.register('runCheckstyle', Checkstyle) {
source 'src'
include '**/*.java'
exclude '**/gen/**'
@@ -153,7 +153,7 @@ task runCheckstyle(type: Checkstyle) {
def outputDir = "${project.buildDir}/reports/ktlint/"
def inputFiles = project.fileTree(dir: "src", include: "**/*.kt")
-task runKtlint(type: JavaExec) {
+tasks.register('runKtlint', JavaExec) {
inputs.files(inputFiles)
outputs.dir(outputDir)
getMainClass().set("com.pinterest.ktlint.Main")
@@ -162,7 +162,7 @@ task runKtlint(type: JavaExec) {
jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED")
}
-task formatKtlint(type: JavaExec) {
+tasks.register('formatKtlint', JavaExec) {
inputs.files(inputFiles)
outputs.dir(outputDir)
getMainClass().set("com.pinterest.ktlint.Main")
From b31d3831e6b8da432981491f7a3c7eb7e6f51ad9 Mon Sep 17 00:00:00 2001
From: TacoTheDank
Date: Tue, 31 Oct 2023 22:39:11 -0400
Subject: [PATCH 54/82] Change Converters to class to fix build
---
app/src/main/java/org/schabi/newpipe/database/Converters.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/org/schabi/newpipe/database/Converters.kt b/app/src/main/java/org/schabi/newpipe/database/Converters.kt
index 6f705a5e4f0..ec097cc1bf3 100644
--- a/app/src/main/java/org/schabi/newpipe/database/Converters.kt
+++ b/app/src/main/java/org/schabi/newpipe/database/Converters.kt
@@ -7,7 +7,7 @@ import java.time.Instant
import java.time.OffsetDateTime
import java.time.ZoneOffset
-object Converters {
+class Converters {
/**
* Convert a long value to a [OffsetDateTime].
*
From 1e7e2109d232b5f8ec6ee905a05c4c246db5b5e6 Mon Sep 17 00:00:00 2001
From: TacoTheDank
Date: Fri, 17 Nov 2023 16:58:30 -0500
Subject: [PATCH 55/82] Exclude RxJava file from META-INF
---
app/build.gradle | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/app/build.gradle b/app/build.gradle
index 1e109259d59..641b5f9a42c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -98,7 +98,9 @@ android {
resources {
// remove two files which belong to jsoup
// no idea how they ended up in the META-INF dir...
- excludes += ['META-INF/README.md', 'META-INF/CHANGES']
+ excludes += ['META-INF/README.md', 'META-INF/CHANGES',
+ // 'COPYRIGHT' belongs to RxJava...
+ 'META-INF/COPYRIGHT']
}
}
}
From edd4f6b9f3efa087d1775554977fe4fe62e3a191 Mon Sep 17 00:00:00 2001
From: TacoTheDank
Date: Fri, 17 Nov 2023 17:09:35 -0500
Subject: [PATCH 56/82] Update Studio and desugaring versions
---
app/build.gradle | 2 +-
build.gradle | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 641b5f9a42c..fa6c607a6d9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -190,7 +190,7 @@ sonar {
dependencies {
/** Desugaring **/
- coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.3'
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.4'
/** NewPipe libraries **/
// You can use a local version by uncommenting a few lines in settings.gradle
diff --git a/build.gradle b/build.gradle
index 2f3d292bb75..fa94e94ab58 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.1.2'
+ classpath 'com.android.tools.build:gradle:8.1.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
From 5d09a883352382ff821bbab6db59d097af80e64e Mon Sep 17 00:00:00 2001
From: Stypox
Date: Sat, 23 Dec 2023 11:58:58 +0100
Subject: [PATCH 57/82] Update more libraries
---
app/build.gradle | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index fa6c607a6d9..a22228556e8 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -109,7 +109,7 @@ ext {
checkstyleVersion = '10.12.1'
androidxLifecycleVersion = '2.6.2'
- androidxRoomVersion = '2.5.2'
+ androidxRoomVersion = '2.6.1'
androidxWorkVersion = '2.8.1'
icepickVersion = '3.2.0'
@@ -214,11 +214,11 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.documentfile:documentfile:1.0.1'
- implementation 'androidx.fragment:fragment-ktx:1.6.1'
+ implementation 'androidx.fragment:fragment-ktx:1.6.2'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${androidxLifecycleVersion}"
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
- implementation 'androidx.media:media:1.6.0'
+ implementation 'androidx.media:media:1.7.0'
implementation 'androidx.preference:preference:1.2.1'
implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation "androidx.room:room-runtime:${androidxRoomVersion}"
@@ -230,7 +230,7 @@ dependencies {
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.9.0'
+ implementation 'com.google.android.material:material:1.11.0'
/** Third-party libraries **/
// Instance state boilerplate elimination
From cda4b3faaab916d78c136be1bd73aff5e8305e5f Mon Sep 17 00:00:00 2001
From: Stypox
Date: Sat, 23 Dec 2023 12:01:50 +0100
Subject: [PATCH 58/82] Update AGP and Gradle
---
build.gradle | 2 +-
gradle/wrapper/gradle-wrapper.properties | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/build.gradle b/build.gradle
index fa94e94ab58..6d19a6f8a84 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.1.4'
+ classpath 'com.android.tools.build:gradle:8.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 2c3425d49ec..d022615ff6d 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionSha256Sum=e111cb9948407e26351227dabce49822fb88c37ee72f1d1582a69c68af2e702f
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
+distributionSha256Sum=38f66cd6eef217b4c35855bb11ea4e9fbc53594ccccb5fb82dfd317ef8c2c5a3
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
From 6c9955755339cae73d1f90567bf52999779fcb96 Mon Sep 17 00:00:00 2001
From: TobiGr
Date: Fri, 12 May 2023 11:29:09 +0200
Subject: [PATCH 59/82] Add playlist description to PlaylistFragment
---
.../list/playlist/PlaylistFragment.java | 17 +++++++++++++++++
app/src/main/res/layout/playlist_header.xml | 11 ++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)
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 e82a984d5ad..95cead38997 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
@@ -1,7 +1,9 @@
package org.schabi.newpipe.fragments.list.playlist;
+import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
+import static org.schabi.newpipe.util.text.TextLinkifier.SET_LINK_MOVEMENT_METHOD;
import android.content.Context;
import android.os.Bundle;
@@ -17,6 +19,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
+import androidx.core.text.HtmlCompat;
import com.google.android.material.shape.CornerFamily;
import com.google.android.material.shape.ShapeAppearanceModel;
@@ -37,6 +40,7 @@
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
+import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.info_list.dialog.InfoItemDialog;
@@ -51,6 +55,7 @@
import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.PlayButtonHelper;
+import org.schabi.newpipe.util.text.TextLinkifier;
import java.util.ArrayList;
import java.util.List;
@@ -321,6 +326,18 @@ public void handleResult(@NonNull final PlaylistInfo result) {
headerBinding.playlistStreamCount.setText(Localization
.localizeStreamCount(getContext(), result.getStreamCount()));
+ final Description description = result.getDescription();
+ if (description != null && description != Description.EMPTY_DESCRIPTION
+ && !isBlank(description.getContent())) {
+ TextLinkifier.fromDescription(headerBinding.playlistDescription,
+ description, HtmlCompat.FROM_HTML_MODE_LEGACY,
+ result.getService(), result.getUrl(),
+ disposables, SET_LINK_MOVEMENT_METHOD);
+ headerBinding.playlistDescription.setVisibility(View.VISIBLE);
+ } else {
+ headerBinding.playlistDescription.setVisibility(View.GONE);
+ }
+
if (!result.getErrors().isEmpty()) {
showSnackBarError(new ErrorInfo(result.getErrors(), UserAction.REQUESTED_PLAYLIST,
result.getUrl(), result));
diff --git a/app/src/main/res/layout/playlist_header.xml b/app/src/main/res/layout/playlist_header.xml
index 9c038db3a66..2d6f3067684 100644
--- a/app/src/main/res/layout/playlist_header.xml
+++ b/app/src/main/res/layout/playlist_header.xml
@@ -80,10 +80,19 @@
tools:text="234 videos" />
+
+
+ android:layout_below="@id/playlist_description">
Date: Tue, 20 Jun 2023 15:56:43 +0200
Subject: [PATCH 60/82] Ellipsize playlist description if it is longer than 5
lines
The description can be expanded / collapsed via a "show more" / "show less" button.
---
.../list/playlist/PlaylistFragment.java | 30 ++-
.../holder/CommentInfoItemHolder.java | 123 ++---------
.../newpipe/util/text/TextEllipsizer.java | 195 ++++++++++++++++++
app/src/main/res/layout/playlist_header.xml | 17 +-
app/src/main/res/values/strings.xml | 2 +
5 files changed, 249 insertions(+), 118 deletions(-)
create mode 100644 app/src/main/java/org/schabi/newpipe/util/text/TextEllipsizer.java
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 95cead38997..ab3963d614c 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
@@ -3,7 +3,7 @@
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
-import static org.schabi.newpipe.util.text.TextLinkifier.SET_LINK_MOVEMENT_METHOD;
+import static org.schabi.newpipe.util.ServiceHelper.getServiceById;
import android.content.Context;
import android.os.Bundle;
@@ -19,7 +19,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
-import androidx.core.text.HtmlCompat;
import com.google.android.material.shape.CornerFamily;
import com.google.android.material.shape.ShapeAppearanceModel;
@@ -52,10 +51,10 @@
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
-import org.schabi.newpipe.util.image.PicassoHelper;
-import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.PlayButtonHelper;
-import org.schabi.newpipe.util.text.TextLinkifier;
+import org.schabi.newpipe.util.external_communication.ShareUtils;
+import org.schabi.newpipe.util.image.PicassoHelper;
+import org.schabi.newpipe.util.text.TextEllipsizer;
import java.util.ArrayList;
import java.util.List;
@@ -329,13 +328,24 @@ public void handleResult(@NonNull final PlaylistInfo result) {
final Description description = result.getDescription();
if (description != null && description != Description.EMPTY_DESCRIPTION
&& !isBlank(description.getContent())) {
- TextLinkifier.fromDescription(headerBinding.playlistDescription,
- description, HtmlCompat.FROM_HTML_MODE_LEGACY,
- result.getService(), result.getUrl(),
- disposables, SET_LINK_MOVEMENT_METHOD);
- headerBinding.playlistDescription.setVisibility(View.VISIBLE);
+ final TextEllipsizer ellipsizer = new TextEllipsizer(
+ headerBinding.playlistDescription, 5, getServiceById(result.getServiceId()));
+ ellipsizer.setStateChangeListener(isEllipsized ->
+ headerBinding.playlistDescriptionReadMore.setText(
+ Boolean.TRUE.equals(isEllipsized) ? R.string.show_more : R.string.show_less
+ ));
+ ellipsizer.setOnContentChanged(canBeEllipsized -> {
+ headerBinding.playlistDescriptionReadMore.setVisibility(
+ Boolean.TRUE.equals(canBeEllipsized) ? View.VISIBLE : View.GONE);
+ if (Boolean.TRUE.equals(canBeEllipsized)) {
+ ellipsizer.ellipsize();
+ }
+ });
+ ellipsizer.setContent(description);
+ headerBinding.playlistDescriptionReadMore.setOnClickListener(v -> ellipsizer.toggle());
} else {
headerBinding.playlistDescription.setVisibility(View.GONE);
+ headerBinding.playlistDescriptionReadMore.setVisibility(View.GONE);
}
if (!result.getErrors().isEmpty()) {
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 8327b398ba3..a3f0384ad40 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
@@ -1,10 +1,7 @@
package org.schabi.newpipe.info_list.holder;
-import static android.text.TextUtils.isEmpty;
import static org.schabi.newpipe.util.ServiceHelper.getServiceById;
-import android.graphics.Paint;
-import android.text.Layout;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.view.View;
@@ -15,42 +12,28 @@
import android.widget.TextView;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.text.HtmlCompat;
import androidx.fragment.app.FragmentActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
-import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
-import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
+import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.image.ImageStrategy;
import org.schabi.newpipe.util.image.PicassoHelper;
-import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.text.CommentTextOnTouchListener;
-import org.schabi.newpipe.util.text.TextLinkifier;
-
-import java.util.function.Consumer;
-
-import io.reactivex.rxjava3.disposables.CompositeDisposable;
+import org.schabi.newpipe.util.text.TextEllipsizer;
public class CommentInfoItemHolder extends InfoItemHolder {
- private static final String ELLIPSIS = "…";
private static final int COMMENT_DEFAULT_LINES = 2;
- private static final int COMMENT_EXPANDED_LINES = 1000;
-
private final int commentHorizontalPadding;
private final int commentVerticalPadding;
- private final Paint paintAtContentSize;
- private final float ellipsisWidthPx;
-
private final RelativeLayout itemRoot;
private final ImageView itemThumbnailView;
private final TextView itemContentView;
@@ -61,13 +44,8 @@ public class CommentInfoItemHolder extends InfoItemHolder {
private final ImageView itemPinnedView;
private final Button repliesButton;
- private final CompositeDisposable disposables = new CompositeDisposable();
- @Nullable
- private Description commentText;
- @Nullable
- private StreamingService streamService;
- @Nullable
- private String streamUrl;
+ @NonNull
+ private final TextEllipsizer textEllipsizer;
public CommentInfoItemHolder(final InfoItemBuilder infoItemBuilder,
final ViewGroup parent) {
@@ -88,9 +66,14 @@ public CommentInfoItemHolder(final InfoItemBuilder infoItemBuilder,
commentVerticalPadding = (int) infoItemBuilder.getContext()
.getResources().getDimension(R.dimen.comments_vertical_padding);
- paintAtContentSize = new Paint();
- paintAtContentSize.setTextSize(itemContentView.getTextSize());
- ellipsisWidthPx = paintAtContentSize.measureText(ELLIPSIS);
+ textEllipsizer = new TextEllipsizer(itemContentView, COMMENT_DEFAULT_LINES, null);
+ textEllipsizer.setStateChangeListener(isEllipsized -> {
+ if (Boolean.TRUE.equals(isEllipsized)) {
+ denyLinkFocus();
+ } else {
+ determineMovementMethod();
+ }
+ });
}
@Override
@@ -139,16 +122,16 @@ public void updateFromItem(final InfoItem infoItem,
// setup comment content and click listeners to expand/ellipsize it
- streamService = getServiceById(item.getServiceId());
- streamUrl = item.getUrl();
- commentText = item.getCommentText();
- ellipsize();
+ textEllipsizer.setStreamingService(getServiceById(item.getServiceId()));
+ textEllipsizer.setStreamUrl(item.getUrl());
+ textEllipsizer.setContent(item.getCommentText());
+ textEllipsizer.ellipsize();
//noinspection ClickableViewAccessibility
itemContentView.setOnTouchListener(CommentTextOnTouchListener.INSTANCE);
itemView.setOnClickListener(view -> {
- toggleEllipsize();
+ textEllipsizer.toggle();
if (itemBuilder.getOnCommentsSelectedListener() != null) {
itemBuilder.getOnCommentsSelectedListener().selected(item);
}
@@ -202,76 +185,4 @@ private void determineMovementMethod() {
denyLinkFocus();
}
}
-
- private void ellipsize() {
- itemContentView.setMaxLines(COMMENT_EXPANDED_LINES);
- linkifyCommentContentView(v -> {
- boolean hasEllipsis = false;
-
- final CharSequence charSeqText = itemContentView.getText();
- if (charSeqText != null && itemContentView.getLineCount() > COMMENT_DEFAULT_LINES) {
- // Note that converting to String removes spans (i.e. links), but that's something
- // we actually want since when the text is ellipsized we want all clicks on the
- // comment to expand the comment, not to open links.
- final String text = charSeqText.toString();
-
- final Layout layout = itemContentView.getLayout();
- final float lineWidth = layout.getLineWidth(COMMENT_DEFAULT_LINES - 1);
- final float layoutWidth = layout.getWidth();
- final int lineStart = layout.getLineStart(COMMENT_DEFAULT_LINES - 1);
- final int lineEnd = layout.getLineEnd(COMMENT_DEFAULT_LINES - 1);
-
- // remove characters up until there is enough space for the ellipsis
- // (also summing 2 more pixels, just to be sure to avoid float rounding errors)
- int end = lineEnd;
- float removedCharactersWidth = 0.0f;
- while (lineWidth - removedCharactersWidth + ellipsisWidthPx + 2.0f > layoutWidth
- && end >= lineStart) {
- end -= 1;
- // recalculate each time to account for ligatures or other similar things
- removedCharactersWidth = paintAtContentSize.measureText(
- text.substring(end, lineEnd));
- }
-
- // remove trailing spaces and newlines
- while (end > 0 && Character.isWhitespace(text.charAt(end - 1))) {
- end -= 1;
- }
-
- final String newVal = text.substring(0, end) + ELLIPSIS;
- itemContentView.setText(newVal);
- hasEllipsis = true;
- }
-
- itemContentView.setMaxLines(COMMENT_DEFAULT_LINES);
- if (hasEllipsis) {
- denyLinkFocus();
- } else {
- determineMovementMethod();
- }
- });
- }
-
- private void toggleEllipsize() {
- final CharSequence text = itemContentView.getText();
- if (!isEmpty(text) && text.charAt(text.length() - 1) == ELLIPSIS.charAt(0)) {
- expand();
- } else if (itemContentView.getLineCount() > COMMENT_DEFAULT_LINES) {
- ellipsize();
- }
- }
-
- private void expand() {
- itemContentView.setMaxLines(COMMENT_EXPANDED_LINES);
- linkifyCommentContentView(v -> determineMovementMethod());
- }
-
- private void linkifyCommentContentView(@Nullable final Consumer onCompletion) {
- disposables.clear();
- if (commentText != null) {
- TextLinkifier.fromDescription(itemContentView, commentText,
- HtmlCompat.FROM_HTML_MODE_LEGACY, streamService, streamUrl, disposables,
- onCompletion);
- }
- }
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/text/TextEllipsizer.java b/app/src/main/java/org/schabi/newpipe/util/text/TextEllipsizer.java
new file mode 100644
index 00000000000..41084926b12
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/util/text/TextEllipsizer.java
@@ -0,0 +1,195 @@
+package org.schabi.newpipe.util.text;
+
+import android.graphics.Paint;
+import android.text.Layout;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.text.HtmlCompat;
+
+import org.schabi.newpipe.extractor.StreamingService;
+import org.schabi.newpipe.extractor.stream.Description;
+
+import java.util.function.Consumer;
+
+
+import io.reactivex.rxjava3.disposables.CompositeDisposable;
+
+/**
+ * Class to ellipsize text inside a {@link TextView}.
+ * This class provides all utils to automatically ellipsize and expand a text
+ */
+public final class TextEllipsizer {
+ private static final int EXPANDED_LINES = Integer.MAX_VALUE;
+ private static final String ELLIPSIS = "…";
+
+ @NonNull private final CompositeDisposable disposable = new CompositeDisposable();
+
+ @NonNull private final TextView view;
+ private final int maxLines;
+ @NonNull private Description content;
+ @Nullable private StreamingService streamingService;
+ @Nullable private String streamUrl;
+ private boolean isEllipsized = false;
+ @Nullable private Boolean caBeEllipsized = null;
+
+ @NonNull private final Paint paintAtContentSize = new Paint();
+ private final float ellipsisWidthPx;
+ @Nullable private Consumer stateChangeListener = null;
+ @Nullable private Consumer onContentChanged;
+
+ public TextEllipsizer(@NonNull final TextView view,
+ final int maxLines,
+ @Nullable final StreamingService streamingService) {
+ this.view = view;
+ this.maxLines = maxLines;
+ this.streamingService = streamingService;
+
+ paintAtContentSize.setTextSize(view.getTextSize());
+ ellipsisWidthPx = paintAtContentSize.measureText(ELLIPSIS);
+ }
+
+ public void setOnContentChanged(@Nullable final Consumer onContentChanged) {
+ this.onContentChanged = onContentChanged;
+ }
+
+ public void setContent(@NonNull final Description content) {
+ this.content = content;
+ caBeEllipsized = null;
+ linkifyContentView(v -> {
+ final int currentMaxLines = view.getMaxLines();
+ view.setMaxLines(EXPANDED_LINES);
+ caBeEllipsized = view.getLineCount() > maxLines;
+ view.setMaxLines(currentMaxLines);
+ if (onContentChanged != null) {
+ onContentChanged.accept(caBeEllipsized);
+ }
+ });
+ }
+
+ public void setStreamUrl(@Nullable final String streamUrl) {
+ this.streamUrl = streamUrl;
+ }
+
+ public void setStreamingService(@NonNull final StreamingService streamingService) {
+ this.streamingService = streamingService;
+ }
+
+ /**
+ * Expand the {@link TextEllipsizer#content} to its full length.
+ */
+ public void expand() {
+ view.setMaxLines(EXPANDED_LINES);
+ linkifyContentView(v -> isEllipsized = false);
+ }
+
+ /**
+ * Shorten the {@link TextEllipsizer#content} to the given number of
+ * {@link TextEllipsizer#maxLines maximum lines} and add trailing '{@code …}'
+ * if the text was shorted.
+ */
+ public void ellipsize() {
+ // expand text to see whether it is necessary to ellipsize the text
+ view.setMaxLines(EXPANDED_LINES);
+ linkifyContentView(v -> {
+ final CharSequence charSeqText = view.getText();
+ if (charSeqText != null && view.getLineCount() > maxLines) {
+ // Note that converting to String removes spans (i.e. links), but that's something
+ // we actually want since when the text is ellipsized we want all clicks on the
+ // comment to expand the comment, not to open links.
+ final String text = charSeqText.toString();
+
+ final Layout layout = view.getLayout();
+ final float lineWidth = layout.getLineWidth(maxLines - 1);
+ final float layoutWidth = layout.getWidth();
+ final int lineStart = layout.getLineStart(maxLines - 1);
+ final int lineEnd = layout.getLineEnd(maxLines - 1);
+
+ // remove characters up until there is enough space for the ellipsis
+ // (also summing 2 more pixels, just to be sure to avoid float rounding errors)
+ int end = lineEnd;
+ float removedCharactersWidth = 0.0f;
+ while (lineWidth - removedCharactersWidth + ellipsisWidthPx + 2.0f > layoutWidth
+ && end >= lineStart) {
+ end -= 1;
+ // recalculate each time to account for ligatures or other similar things
+ removedCharactersWidth = paintAtContentSize.measureText(
+ text.substring(end, lineEnd));
+ }
+
+ // remove trailing spaces and newlines
+ while (end > 0 && Character.isWhitespace(text.charAt(end - 1))) {
+ end -= 1;
+ }
+
+ final String newVal = text.substring(0, end) + ELLIPSIS;
+ view.setText(newVal);
+ isEllipsized = true;
+ } else {
+ isEllipsized = false;
+ }
+ view.setMaxLines(maxLines);
+ });
+ }
+
+ /**
+ * Toggle the view between the ellipsed and expanded state.
+ */
+ public void toggle() {
+ if (isEllipsized) {
+ expand();
+ } else {
+ ellipsize();
+ }
+ }
+
+ /**
+ * Whether the {@link view} can be ellipsized.
+ * This is only the case when the {@link content} has more lines
+ * than allowed via {@link maxLines}.
+ * @return {@code true} if the {@link content} has more lines than allowed via {@link maxLines}
+ * and thus can be shortened, {@code false} if the {@code content} fits into the {@link view}
+ * without being shortened and {@code null} if the initialization is not completed yet.
+ */
+ @Nullable
+ public Boolean canBeEllipsized() {
+ return caBeEllipsized;
+ }
+
+ private void linkifyContentView(final Consumer consumer) {
+ final boolean oldState = isEllipsized;
+ disposable.clear();
+ TextLinkifier.fromDescription(view, content,
+ HtmlCompat.FROM_HTML_MODE_LEGACY, streamingService, streamUrl, disposable,
+ v -> {
+ consumer.accept(v);
+ notifyStateChangeListener(oldState);
+ });
+
+ }
+
+ /**
+ * Add a listener which is called when the given content is changed,
+ * either from ellipsized to full or vice versa.
+ * @param listener The listener to be called.
+ * The Boolean parameter is the new state.
+ * Ellipsized content is represented as {@code true},
+ * normal or full content by {@code false}.
+ */
+ public void setStateChangeListener(final Consumer listener) {
+ this.stateChangeListener = listener;
+ }
+
+ public void removeStateChangeListener() {
+ this.stateChangeListener = null;
+ }
+
+ private void notifyStateChangeListener(final boolean oldState) {
+ if (oldState != isEllipsized && stateChangeListener != null) {
+ stateChangeListener.accept(isEllipsized);
+ }
+ }
+
+}
diff --git a/app/src/main/res/layout/playlist_header.xml b/app/src/main/res/layout/playlist_header.xml
index 2d6f3067684..c761240d978 100644
--- a/app/src/main/res/layout/playlist_header.xml
+++ b/app/src/main/res/layout/playlist_header.xml
@@ -87,12 +87,25 @@
android:layout_below="@id/playlist_meta"
android:paddingHorizontal="@dimen/video_item_search_padding"
android:paddingTop="6dp"
- tools:text="This is a multiline playlist description. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit" />
+ android:maxLines="5"
+ tools:text="This is a multiline playlist description. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit" />
+
+
+ android:layout_below="@id/playlist_description_read_more">
%s reply
- %s replies
+ Show more
+ Show less
From 9ff1b5230fda1411d031cca528a2b6febed788e4 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Sat, 23 Dec 2023 17:53:27 +0100
Subject: [PATCH 61/82] Improve TextEllipsizer class
---
.../newpipe/util/text/TextEllipsizer.java | 34 +++++++++----------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/util/text/TextEllipsizer.java b/app/src/main/java/org/schabi/newpipe/util/text/TextEllipsizer.java
index 41084926b12..184b73304d8 100644
--- a/app/src/main/java/org/schabi/newpipe/util/text/TextEllipsizer.java
+++ b/app/src/main/java/org/schabi/newpipe/util/text/TextEllipsizer.java
@@ -33,7 +33,7 @@ public final class TextEllipsizer {
@Nullable private StreamingService streamingService;
@Nullable private String streamUrl;
private boolean isEllipsized = false;
- @Nullable private Boolean caBeEllipsized = null;
+ @Nullable private Boolean canBeEllipsized = null;
@NonNull private final Paint paintAtContentSize = new Paint();
private final float ellipsisWidthPx;
@@ -45,6 +45,7 @@ public TextEllipsizer(@NonNull final TextView view,
@Nullable final StreamingService streamingService) {
this.view = view;
this.maxLines = maxLines;
+ this.content = Description.EMPTY_DESCRIPTION;
this.streamingService = streamingService;
paintAtContentSize.setTextSize(view.getTextSize());
@@ -57,14 +58,14 @@ public void setOnContentChanged(@Nullable final Consumer onContentChang
public void setContent(@NonNull final Description content) {
this.content = content;
- caBeEllipsized = null;
+ canBeEllipsized = null;
linkifyContentView(v -> {
final int currentMaxLines = view.getMaxLines();
view.setMaxLines(EXPANDED_LINES);
- caBeEllipsized = view.getLineCount() > maxLines;
+ canBeEllipsized = view.getLineCount() > maxLines;
view.setMaxLines(currentMaxLines);
if (onContentChanged != null) {
- onContentChanged.accept(caBeEllipsized);
+ onContentChanged.accept(canBeEllipsized);
}
});
}
@@ -135,7 +136,7 @@ public void ellipsize() {
}
/**
- * Toggle the view between the ellipsed and expanded state.
+ * Toggle the view between the ellipsized and expanded state.
*/
public void toggle() {
if (isEllipsized) {
@@ -146,16 +147,17 @@ public void toggle() {
}
/**
- * Whether the {@link view} can be ellipsized.
- * This is only the case when the {@link content} has more lines
- * than allowed via {@link maxLines}.
- * @return {@code true} if the {@link content} has more lines than allowed via {@link maxLines}
- * and thus can be shortened, {@code false} if the {@code content} fits into the {@link view}
- * without being shortened and {@code null} if the initialization is not completed yet.
+ * Whether the {@link #view} can be ellipsized.
+ * This is only the case when the {@link #content} has more lines
+ * than allowed via {@link #maxLines}.
+ * @return {@code true} if the {@link #content} has more lines than allowed via
+ * {@link #maxLines} and thus can be shortened, {@code false} if the {@code content} fits into
+ * the {@link #view} without being shortened and {@code null} if the initialization is not
+ * completed yet.
*/
@Nullable
public Boolean canBeEllipsized() {
- return caBeEllipsized;
+ return canBeEllipsized;
}
private void linkifyContentView(final Consumer consumer) {
@@ -173,19 +175,15 @@ private void linkifyContentView(final Consumer consumer) {
/**
* Add a listener which is called when the given content is changed,
* either from ellipsized to full or vice versa.
- * @param listener The listener to be called.
+ * @param listener The listener to be called, or {@code null} to remove it.
* The Boolean parameter is the new state.
* Ellipsized content is represented as {@code true},
* normal or full content by {@code false}.
*/
- public void setStateChangeListener(final Consumer listener) {
+ public void setStateChangeListener(@Nullable final Consumer listener) {
this.stateChangeListener = listener;
}
- public void removeStateChangeListener() {
- this.stateChangeListener = null;
- }
-
private void notifyStateChangeListener(final boolean oldState) {
if (oldState != isEllipsized && stateChangeListener != null) {
stateChangeListener.accept(isEllipsized);
From 0fa2e76c3e396d9456215bd9f5784b3531691107 Mon Sep 17 00:00:00 2001
From: TobiGr
Date: Tue, 26 Dec 2023 16:36:07 +0100
Subject: [PATCH 62/82] Fix NPE when ChannelTabLHFactory not implemented for a
service
Fixes #10698
---
.../fragments/list/channel/ChannelTabFragment.java | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java
index 76849d94d70..95ac42eed08 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java
@@ -17,6 +17,7 @@
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
+import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
import org.schabi.newpipe.extractor.linkhandler.ReadyChannelTabListLinkHandler;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
@@ -128,10 +129,13 @@ public void handleResult(@NonNull final ChannelTabInfo result) {
// once `handleResult` is called, the parsed data was already saved to cache, so
// we can discard any raw data in ReadyChannelTabListLinkHandler and create a
// link handler with identical properties, but without any raw data
- tabHandler = result.getService()
- .getChannelTabLHFactory()
- .fromQuery(tabHandler.getId(), tabHandler.getContentFilters(),
- tabHandler.getSortFilter());
+ final ListLinkHandlerFactory channelTabLHFactory = result.getService()
+ .getChannelTabLHFactory();
+ if (channelTabLHFactory != null) {
+ // some services do not not have a ChannelTabLHFactory
+ tabHandler = channelTabLHFactory.fromQuery(tabHandler.getId(),
+ tabHandler.getContentFilters(), tabHandler.getSortFilter());
+ }
} catch (final ParsingException e) {
// silently ignore the error, as the app can continue to function normally
Log.w(TAG, "Could not recreate channel tab handler", e);
From d0f4600be4ab11f41753c1333c71d295521a35a5 Mon Sep 17 00:00:00 2001
From: TobiGr
Date: Tue, 26 Dec 2023 16:58:49 +0100
Subject: [PATCH 63/82] Add changelog for NewPipe 0.26.1
---
fastlane/metadata/android/en-US/changelogs/996.txt | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 fastlane/metadata/android/en-US/changelogs/996.txt
diff --git a/fastlane/metadata/android/en-US/changelogs/996.txt b/fastlane/metadata/android/en-US/changelogs/996.txt
new file mode 100644
index 00000000000..8e5af53a480
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/996.txt
@@ -0,0 +1,2 @@
+Fixed a NullPointerException when opening a channel / conference in media.ccc.de.
+The Grinch tried to break our Christmas gift to you, but we fixed it.
From 3df21ad25ee6cbb23f0b45804f0006e5288ce39d Mon Sep 17 00:00:00 2001
From: TobiGr
Date: Tue, 26 Dec 2023 16:59:02 +0100
Subject: [PATCH 64/82] Bump version to 0.26.1 (996)
---
app/build.gradle | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 993363e32ff..9d64e59d469 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -20,8 +20,8 @@ android {
resValue "string", "app_name", "NewPipe"
minSdk 21
targetSdk 33
- versionCode 995
- versionName "0.26.0"
+ versionCode 996
+ versionName "0.26.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
From 9220e324638284404d2bd234a460b0ce6bade4f1 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Fri, 29 Dec 2023 10:54:31 +0100
Subject: [PATCH 65/82] Fix FeedDAOTest
---
.../java/org/schabi/newpipe/database/FeedDAOTest.kt | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt b/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt
index 9fa87c31b01..893ae82b7f9 100644
--- a/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt
+++ b/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt
@@ -85,7 +85,13 @@ class FeedDAOTest {
private fun assertEqual(streams: List?, allowedStreams: List) {
assertNotNull(streams)
- assertEquals(allowedStreams, streams!!.stream().map { it.stream }.toList().sortedBy { it.uid })
+ assertEquals(
+ allowedStreams,
+ streams!!
+ .map { it.stream }
+ .sortedBy { it.uid }
+ .toList()
+ )
}
private fun setupUnlinkDelete(time: String) {
From 5a4dae207001da7e3bd3f65dcb7dfb89b6c82ae8 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Fri, 29 Dec 2023 11:36:12 +0100
Subject: [PATCH 66/82] Fix settings_notification.xml indentation
---
.../main/res/layout/settings_notification.xml | 111 +++++++++---------
1 file changed, 55 insertions(+), 56 deletions(-)
diff --git a/app/src/main/res/layout/settings_notification.xml b/app/src/main/res/layout/settings_notification.xml
index d4af3fe71b8..e5d73a4aeca 100644
--- a/app/src/main/res/layout/settings_notification.xml
+++ b/app/src/main/res/layout/settings_notification.xml
@@ -1,5 +1,4 @@
-
+ android:id="@+id/textView"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:clickable="false"
+ android:focusable="false"
+ android:gravity="center"
+ android:text="@string/notification_actions_summary"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
-
+
-
+
-
+
-
+
-
+
-
+
From 30f0db1d28987805612325839432898d1ba77625 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Fri, 29 Dec 2023 12:13:08 +0100
Subject: [PATCH 67/82] Customize only 2 notification actions on Android 13+
---
.../custom/NotificationActionsPreference.java | 34 +++++++++++++++----
.../main/res/layout/settings_notification.xml | 4 +--
app/src/main/res/values/strings.xml | 3 +-
3 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java
index 3e92f297e6e..29a7c49a0d7 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java
@@ -6,6 +6,7 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
+import android.os.Build;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -35,6 +36,7 @@
import org.schabi.newpipe.views.FocusOverlayView;
import java.util.List;
+import java.util.Objects;
import java.util.stream.IntStream;
public class NotificationActionsPreference extends Preference {
@@ -56,6 +58,11 @@ public NotificationActionsPreference(final Context context, final AttributeSet a
public void onBindViewHolder(@NonNull final PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ ((TextView) holder.itemView.findViewById(R.id.summary))
+ .setText(R.string.notification_actions_summary_android13);
+ }
+
holder.itemView.setClickable(false);
setupActions(holder.itemView);
}
@@ -137,11 +144,19 @@ private class NotificationSlot {
NotificationSlot(final int actionIndex, final View parentView) {
this.i = actionIndex;
-
+ selectedAction = Objects.requireNonNull(getSharedPreferences()).getInt(
+ getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
+ NotificationConstants.SLOT_DEFAULTS[i]);
final View view = parentView.findViewById(SLOT_ITEMS[i]);
- setupSelectedAction(view);
- setupTitle(view);
- setupCheckbox(view);
+
+ // only show the last two notification slots on Android 13+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || i >= 3) {
+ setupSelectedAction(view);
+ setupTitle(view);
+ setupCheckbox(view);
+ } else {
+ view.setVisibility(View.GONE);
+ }
}
void setupTitle(final View view) {
@@ -153,6 +168,14 @@ void setupTitle(final View view) {
void setupCheckbox(final View view) {
final CheckBox compactSlotCheckBox = view.findViewById(R.id.notificationActionCheckBox);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ // there are no compact slots to customize on Android 33+
+ compactSlotCheckBox.setVisibility(View.GONE);
+ view.findViewById(R.id.notificationActionCheckBoxClickableArea)
+ .setVisibility(View.GONE);
+ return;
+ }
+
compactSlotCheckBox.setChecked(compactSlots.contains(i));
view.findViewById(R.id.notificationActionCheckBoxClickableArea).setOnClickListener(
v -> {
@@ -174,9 +197,6 @@ void setupCheckbox(final View view) {
void setupSelectedAction(final View view) {
icon = view.findViewById(R.id.notificationActionIcon);
summary = view.findViewById(R.id.notificationActionSummary);
- selectedAction = getSharedPreferences().getInt(
- getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
- NotificationConstants.SLOT_DEFAULTS[i]);
updateInfo();
}
diff --git a/app/src/main/res/layout/settings_notification.xml b/app/src/main/res/layout/settings_notification.xml
index e5d73a4aeca..b8195f18c42 100644
--- a/app/src/main/res/layout/settings_notification.xml
+++ b/app/src/main/res/layout/settings_notification.xml
@@ -7,7 +7,7 @@
android:paddingTop="16dp">
+ app:layout_constraintTop_toBottomOf="@+id/summary" />
Third action button
Fourth action button
Fifth action button
- Edit each notification action below by tapping on it. Select up to three of them to be shown in the compact notification by using the checkboxes on the right
+ Edit each notification action below by tapping on it. Select up to three of them to be shown in the compact notification by using the checkboxes on the right.
+ Edit each notification action below by tapping on it. The first three actions (play/pause, previous and next) are set by the system and cannot be customized.
You can select at most three actions to show in the compact notification!
Repeat
Shuffle
From aab6580195c2448b12a72b439550bd2ad2a3ed42 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Fri, 29 Dec 2023 12:31:59 +0100
Subject: [PATCH 68/82] Extract NotificationSlot from
NotificationActionsPreference
---
.../custom/NotificationActionsPreference.java | 187 ++----------------
.../settings/custom/NotificationSlot.java | 172 ++++++++++++++++
2 files changed, 193 insertions(+), 166 deletions(-)
create mode 100644 app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java
diff --git a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java
index 29a7c49a0d7..43e9d6f0cf6 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java
@@ -5,38 +5,22 @@
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.res.ColorStateList;
import android.os.Build;
import android.util.AttributeSet;
-import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.CheckBox;
-import android.widget.ImageView;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.content.res.AppCompatResources;
-import androidx.core.widget.TextViewCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import org.schabi.newpipe.App;
import org.schabi.newpipe.R;
-import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
-import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
import org.schabi.newpipe.player.notification.NotificationConstants;
-import org.schabi.newpipe.util.DeviceUtils;
-import org.schabi.newpipe.util.ThemeHelper;
-import org.schabi.newpipe.views.FocusOverlayView;
import java.util.List;
-import java.util.Objects;
import java.util.stream.IntStream;
public class NotificationActionsPreference extends Preference {
@@ -47,8 +31,9 @@ public NotificationActionsPreference(final Context context, final AttributeSet a
}
- @Nullable private NotificationSlot[] notificationSlots = null;
- @Nullable private List compactSlots = null;
+ private NotificationSlot[] notificationSlots;
+ private List compactSlots;
+
////////////////////////////////////////////////////////////////////////////
// Lifecycle
@@ -85,10 +70,26 @@ private void setupActions(@NonNull final View view) {
compactSlots = NotificationConstants.getCompactSlotsFromPreferences(getContext(),
getSharedPreferences(), 5);
notificationSlots = IntStream.range(0, 5)
- .mapToObj(i -> new NotificationSlot(i, view))
+ .mapToObj(i -> new NotificationSlot(getContext(), getSharedPreferences(), i, view,
+ compactSlots.contains(i), this::onToggleCompactSlot))
.toArray(NotificationSlot[]::new);
}
+ private void onToggleCompactSlot(final int i, final CheckBox checkBox) {
+ if (checkBox.isChecked()) {
+ compactSlots.remove((Integer) i);
+ } else if (compactSlots.size() < 3) {
+ compactSlots.add(i);
+ } else {
+ Toast.makeText(getContext(),
+ R.string.notification_actions_at_most_three,
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ checkBox.toggle();
+ }
+
////////////////////////////////////////////////////////////////////////////
// Saving
@@ -106,156 +107,10 @@ private void saveChanges() {
for (int i = 0; i < 5; i++) {
editor.putInt(getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
- notificationSlots[i].selectedAction);
+ notificationSlots[i].getSelectedAction());
}
editor.apply();
}
}
-
-
- ////////////////////////////////////////////////////////////////////////////
- // Notification action
- ////////////////////////////////////////////////////////////////////////////
-
- private static final int[] SLOT_ITEMS = {
- R.id.notificationAction0,
- R.id.notificationAction1,
- R.id.notificationAction2,
- R.id.notificationAction3,
- R.id.notificationAction4,
- };
-
- private static final int[] SLOT_TITLES = {
- R.string.notification_action_0_title,
- R.string.notification_action_1_title,
- R.string.notification_action_2_title,
- R.string.notification_action_3_title,
- R.string.notification_action_4_title,
- };
-
- private class NotificationSlot {
-
- final int i;
- @NotificationConstants.Action int selectedAction;
-
- ImageView icon;
- TextView summary;
-
- NotificationSlot(final int actionIndex, final View parentView) {
- this.i = actionIndex;
- selectedAction = Objects.requireNonNull(getSharedPreferences()).getInt(
- getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
- NotificationConstants.SLOT_DEFAULTS[i]);
- final View view = parentView.findViewById(SLOT_ITEMS[i]);
-
- // only show the last two notification slots on Android 13+
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || i >= 3) {
- setupSelectedAction(view);
- setupTitle(view);
- setupCheckbox(view);
- } else {
- view.setVisibility(View.GONE);
- }
- }
-
- void setupTitle(final View view) {
- ((TextView) view.findViewById(R.id.notificationActionTitle))
- .setText(SLOT_TITLES[i]);
- view.findViewById(R.id.notificationActionClickableArea).setOnClickListener(
- v -> openActionChooserDialog());
- }
-
- void setupCheckbox(final View view) {
- final CheckBox compactSlotCheckBox = view.findViewById(R.id.notificationActionCheckBox);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- // there are no compact slots to customize on Android 33+
- compactSlotCheckBox.setVisibility(View.GONE);
- view.findViewById(R.id.notificationActionCheckBoxClickableArea)
- .setVisibility(View.GONE);
- return;
- }
-
- compactSlotCheckBox.setChecked(compactSlots.contains(i));
- view.findViewById(R.id.notificationActionCheckBoxClickableArea).setOnClickListener(
- v -> {
- if (compactSlotCheckBox.isChecked()) {
- compactSlots.remove((Integer) i);
- } else if (compactSlots.size() < 3) {
- compactSlots.add(i);
- } else {
- Toast.makeText(getContext(),
- R.string.notification_actions_at_most_three,
- Toast.LENGTH_SHORT).show();
- return;
- }
-
- compactSlotCheckBox.toggle();
- });
- }
-
- void setupSelectedAction(final View view) {
- icon = view.findViewById(R.id.notificationActionIcon);
- summary = view.findViewById(R.id.notificationActionSummary);
- updateInfo();
- }
-
- void updateInfo() {
- if (NotificationConstants.ACTION_ICONS[selectedAction] == 0) {
- icon.setImageDrawable(null);
- } else {
- icon.setImageDrawable(AppCompatResources.getDrawable(getContext(),
- NotificationConstants.ACTION_ICONS[selectedAction]));
- }
-
- summary.setText(NotificationConstants.getActionName(getContext(), selectedAction));
- }
-
- void openActionChooserDialog() {
- final LayoutInflater inflater = LayoutInflater.from(getContext());
- final SingleChoiceDialogViewBinding binding =
- SingleChoiceDialogViewBinding.inflate(inflater);
-
- final AlertDialog alertDialog = new AlertDialog.Builder(getContext())
- .setTitle(SLOT_TITLES[i])
- .setView(binding.getRoot())
- .setCancelable(true)
- .create();
-
- final View.OnClickListener radioButtonsClickListener = v -> {
- selectedAction = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][v.getId()];
- updateInfo();
- alertDialog.dismiss();
- };
-
- for (int id = 0; id < NotificationConstants.SLOT_ALLOWED_ACTIONS[i].length; ++id) {
- final int action = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id];
- final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater)
- .getRoot();
-
- // if present set action icon with correct color
- final int iconId = NotificationConstants.ACTION_ICONS[action];
- if (iconId != 0) {
- radioButton.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, iconId, 0);
-
- final var color = ColorStateList.valueOf(ThemeHelper
- .resolveColorFromAttr(getContext(), android.R.attr.textColorPrimary));
- TextViewCompat.setCompoundDrawableTintList(radioButton, color);
- }
-
- radioButton.setText(NotificationConstants.getActionName(getContext(), action));
- radioButton.setChecked(action == selectedAction);
- radioButton.setId(id);
- radioButton.setLayoutParams(new RadioGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
- radioButton.setOnClickListener(radioButtonsClickListener);
- binding.list.addView(radioButton);
- }
- alertDialog.show();
-
- if (DeviceUtils.isTv(getContext())) {
- FocusOverlayView.setupFocusObserver(alertDialog);
- }
- }
- }
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java
new file mode 100644
index 00000000000..412215d0f06
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java
@@ -0,0 +1,172 @@
+package org.schabi.newpipe.settings.custom;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.ColorStateList;
+import android.os.Build;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.content.res.AppCompatResources;
+import androidx.core.widget.TextViewCompat;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
+import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
+import org.schabi.newpipe.player.notification.NotificationConstants;
+import org.schabi.newpipe.util.DeviceUtils;
+import org.schabi.newpipe.util.ThemeHelper;
+import org.schabi.newpipe.views.FocusOverlayView;
+
+import java.util.Objects;
+import java.util.function.BiConsumer;
+
+class NotificationSlot {
+
+ private static final int[] SLOT_ITEMS = {
+ R.id.notificationAction0,
+ R.id.notificationAction1,
+ R.id.notificationAction2,
+ R.id.notificationAction3,
+ R.id.notificationAction4,
+ };
+
+ private static final int[] SLOT_TITLES = {
+ R.string.notification_action_0_title,
+ R.string.notification_action_1_title,
+ R.string.notification_action_2_title,
+ R.string.notification_action_3_title,
+ R.string.notification_action_4_title,
+ };
+
+ private final int i;
+ private @NotificationConstants.Action int selectedAction;
+ private final Context context;
+ private final BiConsumer onToggleCompactSlot;
+
+ private ImageView icon;
+ private TextView summary;
+
+ NotificationSlot(final Context context,
+ final SharedPreferences prefs,
+ final int actionIndex,
+ final View parentView,
+ final boolean isCompactSlotChecked,
+ final BiConsumer onToggleCompactSlot) {
+ this.context = context;
+ this.i = actionIndex;
+ this.onToggleCompactSlot = onToggleCompactSlot;
+
+ selectedAction = Objects.requireNonNull(prefs).getInt(
+ context.getString(NotificationConstants.SLOT_PREF_KEYS[i]),
+ NotificationConstants.SLOT_DEFAULTS[i]);
+ final View view = parentView.findViewById(SLOT_ITEMS[i]);
+
+ // only show the last two notification slots on Android 13+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || i >= 3) {
+ setupSelectedAction(view);
+ setupTitle(view);
+ setupCheckbox(view, isCompactSlotChecked);
+ } else {
+ view.setVisibility(View.GONE);
+ }
+ }
+
+ void setupTitle(final View view) {
+ ((TextView) view.findViewById(R.id.notificationActionTitle))
+ .setText(SLOT_TITLES[i]);
+ view.findViewById(R.id.notificationActionClickableArea).setOnClickListener(
+ v -> openActionChooserDialog());
+ }
+
+ void setupCheckbox(final View view, final boolean isCompactSlotChecked) {
+ final CheckBox compactSlotCheckBox = view.findViewById(R.id.notificationActionCheckBox);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ // there are no compact slots to customize on Android 33+
+ compactSlotCheckBox.setVisibility(View.GONE);
+ view.findViewById(R.id.notificationActionCheckBoxClickableArea)
+ .setVisibility(View.GONE);
+ return;
+ }
+
+ compactSlotCheckBox.setChecked(isCompactSlotChecked);
+ view.findViewById(R.id.notificationActionCheckBoxClickableArea).setOnClickListener(
+ v -> onToggleCompactSlot.accept(i, compactSlotCheckBox));
+ }
+
+ void setupSelectedAction(final View view) {
+ icon = view.findViewById(R.id.notificationActionIcon);
+ summary = view.findViewById(R.id.notificationActionSummary);
+ updateInfo();
+ }
+
+ void updateInfo() {
+ if (NotificationConstants.ACTION_ICONS[selectedAction] == 0) {
+ icon.setImageDrawable(null);
+ } else {
+ icon.setImageDrawable(AppCompatResources.getDrawable(context,
+ NotificationConstants.ACTION_ICONS[selectedAction]));
+ }
+
+ summary.setText(NotificationConstants.getActionName(context, selectedAction));
+ }
+
+ void openActionChooserDialog() {
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ final SingleChoiceDialogViewBinding binding =
+ SingleChoiceDialogViewBinding.inflate(inflater);
+
+ final AlertDialog alertDialog = new AlertDialog.Builder(context)
+ .setTitle(SLOT_TITLES[i])
+ .setView(binding.getRoot())
+ .setCancelable(true)
+ .create();
+
+ final View.OnClickListener radioButtonsClickListener = v -> {
+ selectedAction = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][v.getId()];
+ updateInfo();
+ alertDialog.dismiss();
+ };
+
+ for (int id = 0; id < NotificationConstants.SLOT_ALLOWED_ACTIONS[i].length; ++id) {
+ final int action = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id];
+ final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater)
+ .getRoot();
+
+ // if present set action icon with correct color
+ final int iconId = NotificationConstants.ACTION_ICONS[action];
+ if (iconId != 0) {
+ radioButton.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, iconId, 0);
+
+ final var color = ColorStateList.valueOf(ThemeHelper
+ .resolveColorFromAttr(context, android.R.attr.textColorPrimary));
+ TextViewCompat.setCompoundDrawableTintList(radioButton, color);
+ }
+
+ radioButton.setText(NotificationConstants.getActionName(context, action));
+ radioButton.setChecked(action == selectedAction);
+ radioButton.setId(id);
+ radioButton.setLayoutParams(new RadioGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ radioButton.setOnClickListener(radioButtonsClickListener);
+ binding.list.addView(radioButton);
+ }
+ alertDialog.show();
+
+ if (DeviceUtils.isTv(context)) {
+ FocusOverlayView.setupFocusObserver(alertDialog);
+ }
+ }
+
+ @NotificationConstants.Action
+ public int getSelectedAction() {
+ return selectedAction;
+ }
+}
From 9fb8125655060a343eb0a68d9a3fe69b01a28b9d Mon Sep 17 00:00:00 2001
From: Stypox
Date: Fri, 29 Dec 2023 14:04:18 +0100
Subject: [PATCH 69/82] Allow each notification slot to contain any possible
action
---
.../notification/NotificationConstants.java | 37 +++++++---------
.../player/notification/NotificationUtil.java | 43 ++++++++++++-------
.../custom/NotificationActionsPreference.java | 5 ++-
.../settings/custom/NotificationSlot.java | 6 +--
4 files changed, 48 insertions(+), 43 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationConstants.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationConstants.java
index 89bf0b22ae2..b9607f7eabb 100644
--- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationConstants.java
+++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationConstants.java
@@ -13,7 +13,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -65,10 +65,16 @@ private NotificationConstants() {
public static final int CLOSE = 11;
@Retention(RetentionPolicy.SOURCE)
- @IntDef({NOTHING, PREVIOUS, NEXT, REWIND, FORWARD, SMART_REWIND_PREVIOUS, SMART_FORWARD_NEXT,
- PLAY_PAUSE, PLAY_PAUSE_BUFFERING, REPEAT, SHUFFLE, CLOSE})
+ @IntDef({NOTHING, PREVIOUS, NEXT, REWIND, FORWARD,
+ SMART_REWIND_PREVIOUS, SMART_FORWARD_NEXT, PLAY_PAUSE, PLAY_PAUSE_BUFFERING, REPEAT,
+ SHUFFLE, CLOSE})
public @interface Action { }
+ @Action
+ public static final int[] ALL_ACTIONS = {NOTHING, PREVIOUS, NEXT, REWIND, FORWARD,
+ SMART_REWIND_PREVIOUS, SMART_FORWARD_NEXT, PLAY_PAUSE, PLAY_PAUSE_BUFFERING, REPEAT,
+ SHUFFLE, CLOSE};
+
@DrawableRes
public static final int[] ACTION_ICONS = {
0,
@@ -95,16 +101,6 @@ private NotificationConstants() {
CLOSE,
};
- @Action
- public static final int[][] SLOT_ALLOWED_ACTIONS = {
- new int[] {PREVIOUS, REWIND, SMART_REWIND_PREVIOUS},
- new int[] {REWIND, PLAY_PAUSE, PLAY_PAUSE_BUFFERING},
- new int[] {NEXT, FORWARD, SMART_FORWARD_NEXT, PLAY_PAUSE, PLAY_PAUSE_BUFFERING},
- new int[] {NOTHING, PREVIOUS, NEXT, REWIND, FORWARD, SMART_REWIND_PREVIOUS,
- SMART_FORWARD_NEXT, REPEAT, SHUFFLE, CLOSE},
- new int[] {NOTHING, NEXT, FORWARD, SMART_FORWARD_NEXT, REPEAT, SHUFFLE, CLOSE},
- };
-
public static final int[] SLOT_PREF_KEYS = {
R.string.notification_slot_0_key,
R.string.notification_slot_1_key,
@@ -165,14 +161,11 @@ public static String getActionName(@NonNull final Context context, @Action final
/**
* @param context the context to use
* @param sharedPreferences the shared preferences to query values from
- * @param slotCount remove indices >= than this value (set to {@code 5} to do nothing, or make
- * it lower if there are slots with empty actions)
* @return a sorted list of the indices of the slots to use as compact slots
*/
- public static List getCompactSlotsFromPreferences(
+ public static Collection getCompactSlotsFromPreferences(
@NonNull final Context context,
- final SharedPreferences sharedPreferences,
- final int slotCount) {
+ final SharedPreferences sharedPreferences) {
final SortedSet compactSlots = new TreeSet<>();
for (int i = 0; i < 3; i++) {
final int compactSlot = sharedPreferences.getInt(
@@ -180,14 +173,14 @@ public static List getCompactSlotsFromPreferences(
if (compactSlot == Integer.MAX_VALUE) {
// settings not yet populated, return default values
- return new ArrayList<>(SLOT_COMPACT_DEFAULTS);
+ return SLOT_COMPACT_DEFAULTS;
}
- // a negative value (-1) is set when the user does not want a particular compact slot
- if (compactSlot >= 0 && compactSlot < slotCount) {
+ if (compactSlot >= 0) {
+ // compact slot is < 0 if there are less than 3 checked checkboxes
compactSlots.add(compactSlot);
}
}
- return new ArrayList<>(compactSlots);
+ return compactSlots;
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
index 3fa7c26233c..551e2b863e5 100644
--- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
+++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
@@ -23,6 +23,8 @@
import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi;
import org.schabi.newpipe.util.NavigationHelper;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -101,21 +103,7 @@ private synchronized NotificationCompat.Builder createNotification() {
new NotificationCompat.Builder(player.getContext(),
player.getContext().getString(R.string.notification_channel_id));
- initializeNotificationSlots();
-
- // count the number of real slots, to make sure compact slots indices are not out of bound
- int nonNothingSlotCount = 5;
- if (notificationSlots[3] == NotificationConstants.NOTHING) {
- --nonNothingSlotCount;
- }
- if (notificationSlots[4] == NotificationConstants.NOTHING) {
- --nonNothingSlotCount;
- }
-
- // build the compact slot indices array (need code to convert from Integer... because Java)
- final List compactSlotList = NotificationConstants.getCompactSlotsFromPreferences(
- player.getContext(), player.getPrefs(), nonNothingSlotCount);
- final int[] compactSlots = compactSlotList.stream().mapToInt(Integer::intValue).toArray();
+ final int[] compactSlots = initializeNotificationSlots();
final MediaStyle mediaStyle = new MediaStyle().setShowActionsInCompactView(compactSlots);
player.UIs()
@@ -209,12 +197,35 @@ public void cancelNotificationAndStopForeground() {
// ACTIONS
/////////////////////////////////////////////////////
- private void initializeNotificationSlots() {
+ /**
+ * The compact slots array from settings contains indices from 0 to 4, each referring to one of
+ * the five actions configurable by the user. However, if the user sets an action to "Nothing",
+ * then all of the actions coming after will have a "settings index" different than the index
+ * of the corresponding action when sent to the system.
+ *
+ * @return the indices of compact slots referred to the list of non-nothing actions that will be
+ * sent to the system
+ */
+ private int[] initializeNotificationSlots() {
+ final Collection settingsCompactSlots = NotificationConstants
+ .getCompactSlotsFromPreferences(player.getContext(), player.getPrefs());
+ final List adjustedCompactSlots = new ArrayList<>();
+
+ int nonNothingIndex = 0;
for (int i = 0; i < 5; ++i) {
notificationSlots[i] = player.getPrefs().getInt(
player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
NotificationConstants.SLOT_DEFAULTS[i]);
+
+ if (notificationSlots[i] != NotificationConstants.NOTHING) {
+ if (settingsCompactSlots.contains(i)) {
+ adjustedCompactSlots.add(nonNothingIndex);
+ }
+ nonNothingIndex += 1;
+ }
}
+
+ return adjustedCompactSlots.stream().mapToInt(Integer::intValue).toArray();
}
@SuppressLint("RestrictedApi")
diff --git a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java
index 43e9d6f0cf6..7dfddef20d3 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java
@@ -20,6 +20,7 @@
import org.schabi.newpipe.R;
import org.schabi.newpipe.player.notification.NotificationConstants;
+import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
@@ -67,8 +68,8 @@ public void onDetached() {
////////////////////////////////////////////////////////////////////////////
private void setupActions(@NonNull final View view) {
- compactSlots = NotificationConstants.getCompactSlotsFromPreferences(getContext(),
- getSharedPreferences(), 5);
+ compactSlots = new ArrayList<>(NotificationConstants.getCompactSlotsFromPreferences(
+ getContext(), getSharedPreferences()));
notificationSlots = IntStream.range(0, 5)
.mapToObj(i -> new NotificationSlot(getContext(), getSharedPreferences(), i, view,
compactSlots.contains(i), this::onToggleCompactSlot))
diff --git a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java
index 412215d0f06..074532876bd 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java
@@ -130,13 +130,13 @@ void openActionChooserDialog() {
.create();
final View.OnClickListener radioButtonsClickListener = v -> {
- selectedAction = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][v.getId()];
+ selectedAction = NotificationConstants.ALL_ACTIONS[v.getId()];
updateInfo();
alertDialog.dismiss();
};
- for (int id = 0; id < NotificationConstants.SLOT_ALLOWED_ACTIONS[i].length; ++id) {
- final int action = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id];
+ for (int id = 0; id < NotificationConstants.ALL_ACTIONS.length; ++id) {
+ final int action = NotificationConstants.ALL_ACTIONS[id];
final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater)
.getRoot();
From 2c4c28309900276bfa5e36a3cebbf0a16730a1a9 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 16 Nov 2023 09:47:27 +0100
Subject: [PATCH 70/82] Extract NotificationActionData from NotificationUtil
---
.../notification/NotificationActionData.java | 168 ++++++++++++++++++
.../player/notification/NotificationUtil.java | 136 ++------------
2 files changed, 184 insertions(+), 120 deletions(-)
create mode 100644 app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java
diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java
new file mode 100644
index 00000000000..fd5e03bf1ce
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java
@@ -0,0 +1,168 @@
+package org.schabi.newpipe.player.notification;
+
+import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
+import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_CLOSE;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_FAST_FORWARD;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_FAST_REWIND;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_PLAY_NEXT;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_PLAY_PAUSE;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_PLAY_PREVIOUS;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_REPEAT;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_SHUFFLE;
+
+import android.content.Context;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.player.Player;
+
+public final class NotificationActionData {
+ @Nullable
+ private final String action;
+ @NonNull
+ private final String name;
+ @DrawableRes
+ private final int icon;
+
+ public NotificationActionData(@Nullable final String action, @NonNull final String name,
+ @DrawableRes final int icon) {
+ this.action = action;
+ this.name = name;
+ this.icon = icon;
+ }
+
+ @Nullable
+ public String action() {
+ return action;
+ }
+
+ @NonNull
+ public String name() {
+ return name;
+ }
+
+ @DrawableRes
+ public int icon() {
+ return icon;
+ }
+
+
+ @Nullable
+ public static NotificationActionData fromNotificationActionEnum(
+ @NonNull final Player player,
+ @NotificationConstants.Action final int selectedAction
+ ) {
+
+ final int baseActionIcon = NotificationConstants.ACTION_ICONS[selectedAction];
+ final Context ctx = player.getContext();
+
+ switch (selectedAction) {
+ case NotificationConstants.PREVIOUS:
+ return new NotificationActionData(ACTION_PLAY_PREVIOUS,
+ ctx.getString(R.string.exo_controls_previous_description), baseActionIcon);
+
+ case NotificationConstants.NEXT:
+ return new NotificationActionData(ACTION_PLAY_NEXT,
+ ctx.getString(R.string.exo_controls_next_description), baseActionIcon);
+
+ case NotificationConstants.REWIND:
+ return new NotificationActionData(ACTION_FAST_REWIND,
+ ctx.getString(R.string.exo_controls_rewind_description), baseActionIcon);
+
+ case NotificationConstants.FORWARD:
+ return new NotificationActionData(ACTION_FAST_FORWARD,
+ ctx.getString(R.string.exo_controls_fastforward_description),
+ baseActionIcon);
+
+ case NotificationConstants.SMART_REWIND_PREVIOUS:
+ if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) {
+ return new NotificationActionData(ACTION_PLAY_PREVIOUS,
+ ctx.getString(R.string.exo_controls_previous_description),
+ R.drawable.exo_notification_previous);
+ } else {
+ return new NotificationActionData(ACTION_FAST_REWIND,
+ ctx.getString(R.string.exo_controls_rewind_description),
+ R.drawable.exo_controls_rewind);
+ }
+
+ case NotificationConstants.SMART_FORWARD_NEXT:
+ if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) {
+ return new NotificationActionData(ACTION_PLAY_NEXT,
+ ctx.getString(R.string.exo_controls_next_description),
+ R.drawable.exo_notification_next);
+ } else {
+ return new NotificationActionData(ACTION_FAST_FORWARD,
+ ctx.getString(R.string.exo_controls_fastforward_description),
+ R.drawable.exo_controls_fastforward);
+ }
+
+ case NotificationConstants.PLAY_PAUSE_BUFFERING:
+ if (player.getCurrentState() == Player.STATE_PREFLIGHT
+ || player.getCurrentState() == Player.STATE_BLOCKED
+ || player.getCurrentState() == Player.STATE_BUFFERING) {
+ // null intent action -> show hourglass icon that does nothing when clicked
+ return new NotificationActionData(null,
+ ctx.getString(R.string.notification_action_buffering),
+ R.drawable.ic_hourglass_top);
+ }
+
+ // fallthrough
+ case NotificationConstants.PLAY_PAUSE:
+ if (player.getCurrentState() == Player.STATE_COMPLETED) {
+ return new NotificationActionData(ACTION_PLAY_PAUSE,
+ ctx.getString(R.string.exo_controls_pause_description),
+ R.drawable.ic_replay);
+ } else if (player.isPlaying()
+ || player.getCurrentState() == Player.STATE_PREFLIGHT
+ || player.getCurrentState() == Player.STATE_BLOCKED
+ || player.getCurrentState() == Player.STATE_BUFFERING) {
+ return new NotificationActionData(ACTION_PLAY_PAUSE,
+ ctx.getString(R.string.exo_controls_pause_description),
+ R.drawable.exo_notification_pause);
+ } else {
+ return new NotificationActionData(ACTION_PLAY_PAUSE,
+ ctx.getString(R.string.exo_controls_play_description),
+ R.drawable.exo_notification_play);
+ }
+
+ case NotificationConstants.REPEAT:
+ if (player.getRepeatMode() == REPEAT_MODE_ALL) {
+ return new NotificationActionData(ACTION_REPEAT,
+ ctx.getString(R.string.exo_controls_repeat_all_description),
+ R.drawable.exo_media_action_repeat_all);
+ } else if (player.getRepeatMode() == REPEAT_MODE_ONE) {
+ return new NotificationActionData(ACTION_REPEAT,
+ ctx.getString(R.string.exo_controls_repeat_one_description),
+ R.drawable.exo_media_action_repeat_one);
+ } else /* player.getRepeatMode() == REPEAT_MODE_OFF */ {
+ return new NotificationActionData(ACTION_REPEAT,
+ ctx.getString(R.string.exo_controls_repeat_off_description),
+ R.drawable.exo_media_action_repeat_off);
+ }
+
+ case NotificationConstants.SHUFFLE:
+ if (player.getPlayQueue() != null && player.getPlayQueue().isShuffled()) {
+ return new NotificationActionData(ACTION_SHUFFLE,
+ ctx.getString(R.string.exo_controls_shuffle_on_description),
+ R.drawable.exo_controls_shuffle_on);
+ } else {
+ return new NotificationActionData(ACTION_SHUFFLE,
+ ctx.getString(R.string.exo_controls_shuffle_off_description),
+ R.drawable.exo_controls_shuffle_off);
+ }
+
+ case NotificationConstants.CLOSE:
+ return new NotificationActionData(ACTION_CLOSE, ctx.getString(R.string.close),
+ R.drawable.ic_close);
+
+ case NotificationConstants.NOTHING:
+ default:
+ // do nothing
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
index 551e2b863e5..72b979f9da2 100644
--- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
+++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
@@ -1,16 +1,19 @@
package org.schabi.newpipe.player.notification;
+import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
+import static androidx.media.app.NotificationCompat.MediaStyle;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_CLOSE;
+
import android.annotation.SuppressLint;
+import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.graphics.Bitmap;
import android.os.Build;
import android.util.Log;
-import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.app.PendingIntentCompat;
@@ -29,19 +32,6 @@
import java.util.Objects;
import java.util.Optional;
-import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
-import static androidx.media.app.NotificationCompat.MediaStyle;
-import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
-import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
-import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_CLOSE;
-import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_FAST_FORWARD;
-import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_FAST_REWIND;
-import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_PLAY_NEXT;
-import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_PLAY_PAUSE;
-import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_PLAY_PREVIOUS;
-import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_REPEAT;
-import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_SHUFFLE;
-
/**
* This is a utility class for player notifications.
*/
@@ -238,115 +228,21 @@ private void updateActions(final NotificationCompat.Builder builder) {
private void addAction(final NotificationCompat.Builder builder,
@NotificationConstants.Action final int slot) {
- final NotificationCompat.Action action = getAction(slot);
- if (action != null) {
- builder.addAction(action);
+ @Nullable final NotificationActionData data =
+ NotificationActionData.fromNotificationActionEnum(player, slot);
+ if (data == null) {
+ return;
}
- }
- @Nullable
- private NotificationCompat.Action getAction(
- @NotificationConstants.Action final int selectedAction) {
- final int baseActionIcon = NotificationConstants.ACTION_ICONS[selectedAction];
- switch (selectedAction) {
- case NotificationConstants.PREVIOUS:
- return getAction(baseActionIcon,
- R.string.exo_controls_previous_description, ACTION_PLAY_PREVIOUS);
-
- case NotificationConstants.NEXT:
- return getAction(baseActionIcon,
- R.string.exo_controls_next_description, ACTION_PLAY_NEXT);
-
- case NotificationConstants.REWIND:
- return getAction(baseActionIcon,
- R.string.exo_controls_rewind_description, ACTION_FAST_REWIND);
-
- case NotificationConstants.FORWARD:
- return getAction(baseActionIcon,
- R.string.exo_controls_fastforward_description, ACTION_FAST_FORWARD);
-
- case NotificationConstants.SMART_REWIND_PREVIOUS:
- if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) {
- return getAction(R.drawable.exo_notification_previous,
- R.string.exo_controls_previous_description, ACTION_PLAY_PREVIOUS);
- } else {
- return getAction(R.drawable.exo_controls_rewind,
- R.string.exo_controls_rewind_description, ACTION_FAST_REWIND);
- }
-
- case NotificationConstants.SMART_FORWARD_NEXT:
- if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) {
- return getAction(R.drawable.exo_notification_next,
- R.string.exo_controls_next_description, ACTION_PLAY_NEXT);
- } else {
- return getAction(R.drawable.exo_controls_fastforward,
- R.string.exo_controls_fastforward_description, ACTION_FAST_FORWARD);
- }
-
- case NotificationConstants.PLAY_PAUSE_BUFFERING:
- if (player.getCurrentState() == Player.STATE_PREFLIGHT
- || player.getCurrentState() == Player.STATE_BLOCKED
- || player.getCurrentState() == Player.STATE_BUFFERING) {
- // null intent -> show hourglass icon that does nothing when clicked
- return new NotificationCompat.Action(R.drawable.ic_hourglass_top,
- player.getContext().getString(R.string.notification_action_buffering),
- null);
- }
-
- // fallthrough
- case NotificationConstants.PLAY_PAUSE:
- if (player.getCurrentState() == Player.STATE_COMPLETED) {
- return getAction(R.drawable.ic_replay,
- R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE);
- } else if (player.isPlaying()
- || player.getCurrentState() == Player.STATE_PREFLIGHT
- || player.getCurrentState() == Player.STATE_BLOCKED
- || player.getCurrentState() == Player.STATE_BUFFERING) {
- return getAction(R.drawable.exo_notification_pause,
- R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE);
- } else {
- return getAction(R.drawable.exo_notification_play,
- R.string.exo_controls_play_description, ACTION_PLAY_PAUSE);
- }
-
- case NotificationConstants.REPEAT:
- if (player.getRepeatMode() == REPEAT_MODE_ALL) {
- return getAction(R.drawable.exo_media_action_repeat_all,
- R.string.exo_controls_repeat_all_description, ACTION_REPEAT);
- } else if (player.getRepeatMode() == REPEAT_MODE_ONE) {
- return getAction(R.drawable.exo_media_action_repeat_one,
- R.string.exo_controls_repeat_one_description, ACTION_REPEAT);
- } else /* player.getRepeatMode() == REPEAT_MODE_OFF */ {
- return getAction(R.drawable.exo_media_action_repeat_off,
- R.string.exo_controls_repeat_off_description, ACTION_REPEAT);
- }
-
- case NotificationConstants.SHUFFLE:
- if (player.getPlayQueue() != null && player.getPlayQueue().isShuffled()) {
- return getAction(R.drawable.exo_controls_shuffle_on,
- R.string.exo_controls_shuffle_on_description, ACTION_SHUFFLE);
- } else {
- return getAction(R.drawable.exo_controls_shuffle_off,
- R.string.exo_controls_shuffle_off_description, ACTION_SHUFFLE);
- }
-
- case NotificationConstants.CLOSE:
- return getAction(R.drawable.ic_close,
- R.string.close, ACTION_CLOSE);
-
- case NotificationConstants.NOTHING:
- default:
- // do nothing
- return null;
+ final PendingIntent intent;
+ if (data.action() == null) {
+ intent = null;
+ } else {
+ intent = PendingIntentCompat.getBroadcast(player.getContext(), NOTIFICATION_ID,
+ new Intent(data.action()), FLAG_UPDATE_CURRENT, false);
}
- }
- private NotificationCompat.Action getAction(@DrawableRes final int drawable,
- @StringRes final int title,
- final String intentAction) {
- return new NotificationCompat.Action(drawable, player.getContext().getString(title),
- PendingIntentCompat.getBroadcast(player.getContext(), NOTIFICATION_ID,
- new Intent(intentAction), FLAG_UPDATE_CURRENT, false));
+ builder.addAction(new NotificationCompat.Action(data.icon(), data.name(), intent));
}
private Intent getIntentForNotification() {
From 5edafca05ae485940094fb940a4fbac2886d4bd9 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Thu, 16 Nov 2023 11:04:01 +0100
Subject: [PATCH 71/82] Implement notification actions via
MediaSessionConnector on Android 13+
---
.../mediasession/MediaSessionPlayerUi.java | 111 ++++++++++++++++++
.../SessionConnectorActionProvider.java | 51 ++++++++
.../player/notification/NotificationUtil.java | 20 +++-
3 files changed, 177 insertions(+), 5 deletions(-)
create mode 100644 app/src/main/java/org/schabi/newpipe/player/mediasession/SessionConnectorActionProvider.java
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 6f76a91d1c0..53d6c297aa1 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
@@ -1,10 +1,12 @@
package org.schabi.newpipe.player.mediasession;
import static org.schabi.newpipe.MainActivity.DEBUG;
+import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_RECREATE_NOTIFICATION;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
+import android.os.Build;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.util.Log;
@@ -14,14 +16,20 @@
import androidx.media.session.MediaButtonReceiver;
import com.google.android.exoplayer2.ForwardingPlayer;
+import com.google.android.exoplayer2.Player.RepeatMode;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
import org.schabi.newpipe.R;
+import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.player.Player;
+import org.schabi.newpipe.player.notification.NotificationActionData;
+import org.schabi.newpipe.player.notification.NotificationConstants;
import org.schabi.newpipe.player.ui.PlayerUi;
import org.schabi.newpipe.player.ui.VideoPlayerUi;
import org.schabi.newpipe.util.StreamTypeUtil;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
public class MediaSessionPlayerUi extends PlayerUi
@@ -163,4 +171,107 @@ private MediaMetadataCompat buildMediaMetadata() {
return builder.build();
}
+
+
+ private void updateMediaSessionActions() {
+ // On Android 13+ (or Android T or API 33+) the actions in the player notification can't be
+ // controlled directly anymore, but are instead derived from custom media session actions.
+ // However the system allows customizing only two of these actions, since the other three
+ // are fixed to play-pause-buffering, previous, next.
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+ // Although setting media session actions on older android versions doesn't seem to
+ // cause any trouble, it also doesn't seem to do anything, so we don't do anything to
+ // save battery. Check out NotificationUtil.updateActions() to see what happens on
+ // older android versions.
+ return;
+ }
+
+ final List actions = new ArrayList<>(2);
+ for (int i = 3; i < 5; ++i) {
+ // only use the fourth and fifth actions (the settings page also shows only the last 2)
+ final int action = player.getPrefs().getInt(
+ player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
+ NotificationConstants.SLOT_DEFAULTS[i]);
+
+ @Nullable final NotificationActionData data =
+ NotificationActionData.fromNotificationActionEnum(player, action);
+
+ if (data != null) {
+ actions.add(new SessionConnectorActionProvider(data, context));
+ }
+ }
+
+ sessionConnector.setCustomActionProviders(
+ actions.toArray(new MediaSessionConnector.CustomActionProvider[0]));
+ }
+
+ @Override
+ public void onBlocked() {
+ super.onBlocked();
+ updateMediaSessionActions();
+ }
+
+ @Override
+ public void onPlaying() {
+ super.onPlaying();
+ updateMediaSessionActions();
+ }
+
+ @Override
+ public void onBuffering() {
+ super.onBuffering();
+ updateMediaSessionActions();
+ }
+
+ @Override
+ public void onPaused() {
+ super.onPaused();
+ updateMediaSessionActions();
+ }
+
+ @Override
+ public void onPausedSeek() {
+ super.onPausedSeek();
+ updateMediaSessionActions();
+ }
+
+ @Override
+ public void onCompleted() {
+ super.onCompleted();
+ updateMediaSessionActions();
+ }
+
+ @Override
+ public void onRepeatModeChanged(@RepeatMode final int repeatMode) {
+ super.onRepeatModeChanged(repeatMode);
+ updateMediaSessionActions();
+ }
+
+ @Override
+ public void onShuffleModeEnabledChanged(final boolean shuffleModeEnabled) {
+ super.onShuffleModeEnabledChanged(shuffleModeEnabled);
+ updateMediaSessionActions();
+ }
+
+ @Override
+ public void onBroadcastReceived(final Intent intent) {
+ super.onBroadcastReceived(intent);
+ if (ACTION_RECREATE_NOTIFICATION.equals(intent.getAction())) {
+ // the notification actions changed
+ updateMediaSessionActions();
+ }
+ }
+
+ @Override
+ public void onMetadataChanged(@NonNull final StreamInfo info) {
+ super.onMetadataChanged(info);
+ updateMediaSessionActions();
+ }
+
+ @Override
+ public void onPlayQueueEdited() {
+ super.onPlayQueueEdited();
+ updateMediaSessionActions();
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/SessionConnectorActionProvider.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/SessionConnectorActionProvider.java
new file mode 100644
index 00000000000..7b109c149ff
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/SessionConnectorActionProvider.java
@@ -0,0 +1,51 @@
+package org.schabi.newpipe.player.mediasession;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.media.session.PlaybackStateCompat;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.google.android.exoplayer2.Player;
+import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
+
+import org.schabi.newpipe.player.notification.NotificationActionData;
+
+import java.lang.ref.WeakReference;
+
+public class SessionConnectorActionProvider implements MediaSessionConnector.CustomActionProvider {
+
+ private final NotificationActionData data;
+ @NonNull
+ private final WeakReference context;
+
+ public SessionConnectorActionProvider(final NotificationActionData notificationActionData,
+ @NonNull final Context context) {
+ this.data = notificationActionData;
+ this.context = new WeakReference<>(context);
+ }
+
+ @Override
+ public void onCustomAction(@NonNull final Player player,
+ @NonNull final String action,
+ @Nullable final Bundle extras) {
+ final Context actualContext = context.get();
+ if (actualContext != null) {
+ actualContext.sendBroadcast(new Intent(action));
+ }
+ }
+
+ @Nullable
+ @Override
+ public PlaybackStateCompat.CustomAction getCustomAction(@NonNull final Player player) {
+ if (data.action() == null) {
+ return null;
+ } else {
+ return new PlaybackStateCompat.CustomAction.Builder(
+ data.action(), data.name(), data.icon()
+ ).build();
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
index 72b979f9da2..b3cfed1ce36 100644
--- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
+++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
@@ -92,15 +92,21 @@ private synchronized NotificationCompat.Builder createNotification() {
final NotificationCompat.Builder builder =
new NotificationCompat.Builder(player.getContext(),
player.getContext().getString(R.string.notification_channel_id));
-
- final int[] compactSlots = initializeNotificationSlots();
-
- final MediaStyle mediaStyle = new MediaStyle().setShowActionsInCompactView(compactSlots);
+ final MediaStyle mediaStyle = new MediaStyle();
+
+ // setup media style (compact notification slots and media session)
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+ // notification actions are ignored on Android 13+, and are replaced by code in
+ // MediaSessionPlayerUi
+ final int[] compactSlots = initializeNotificationSlots();
+ mediaStyle.setShowActionsInCompactView(compactSlots);
+ }
player.UIs()
.get(MediaSessionPlayerUi.class)
.flatMap(MediaSessionPlayerUi::getSessionToken)
.ifPresent(mediaStyle::setMediaSession);
+ // setup notification builder
builder.setStyle(mediaStyle)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
@@ -135,7 +141,11 @@ private synchronized void updateNotification() {
notificationBuilder.setContentText(player.getUploaderName());
notificationBuilder.setTicker(player.getVideoTitle());
- updateActions(notificationBuilder);
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+ // notification actions are ignored on Android 13+, and are replaced by code in
+ // MediaSessionPlayerUi
+ updateActions(notificationBuilder);
+ }
}
From 17e88f17498234f50ea58ba22bc8c6ab72d6d673 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Fri, 29 Dec 2023 15:08:44 +0100
Subject: [PATCH 72/82] Do not update notification actions if nothing changed
This should avoid costly updates of the media session.
---
.../mediasession/MediaSessionPlayerUi.java | 47 ++++++++++++-------
.../notification/NotificationActionData.java | 17 ++++++-
2 files changed, 46 insertions(+), 18 deletions(-)
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 53d6c297aa1..737ebc5dd04 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
@@ -28,9 +28,11 @@
import org.schabi.newpipe.player.ui.VideoPlayerUi;
import org.schabi.newpipe.util.StreamTypeUtil;
-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;
public class MediaSessionPlayerUi extends PlayerUi
implements SharedPreferences.OnSharedPreferenceChangeListener {
@@ -42,6 +44,10 @@ public class MediaSessionPlayerUi extends PlayerUi
private final String ignoreHardwareMediaButtonsKey;
private boolean shouldIgnoreHardwareMediaButtons = false;
+ // used to check whether any notification action changed, before sending costly updates
+ private List prevNotificationActions = List.of();
+
+
public MediaSessionPlayerUi(@NonNull final Player player) {
super(player);
ignoreHardwareMediaButtonsKey =
@@ -71,6 +77,10 @@ public void initPlayer() {
sessionConnector.setMetadataDeduplicationEnabled(true);
sessionConnector.setMediaMetadataProvider(exoPlayer -> buildMediaMetadata());
+
+ // force updating media session actions by resetting the previous ones
+ prevNotificationActions = List.of();
+ updateMediaSessionActions();
}
@Override
@@ -88,6 +98,7 @@ public void destroyPlayer() {
mediaSession.release();
mediaSession = null;
}
+ prevNotificationActions = List.of();
}
@Override
@@ -187,23 +198,25 @@ private void updateMediaSessionActions() {
return;
}
- final List actions = new ArrayList<>(2);
- for (int i = 3; i < 5; ++i) {
- // only use the fourth and fifth actions (the settings page also shows only the last 2)
- final int action = player.getPrefs().getInt(
- player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
- NotificationConstants.SLOT_DEFAULTS[i]);
-
- @Nullable final NotificationActionData data =
- NotificationActionData.fromNotificationActionEnum(player, action);
-
- if (data != null) {
- actions.add(new SessionConnectorActionProvider(data, context));
- }
+ // 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)
+ .map(i -> player.getPrefs().getInt(
+ player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
+ NotificationConstants.SLOT_DEFAULTS[i]))
+ .mapToObj(action -> NotificationActionData
+ .fromNotificationActionEnum(player, action))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
+ // avoid costly notification actions update, if nothing changed from last time
+ if (!newNotificationActions.equals(prevNotificationActions)) {
+ prevNotificationActions = newNotificationActions;
+ sessionConnector.setCustomActionProviders(
+ newNotificationActions.stream()
+ .map(data -> new SessionConnectorActionProvider(data, context))
+ .toArray(SessionConnectorActionProvider[]::new));
}
-
- sessionConnector.setCustomActionProviders(
- actions.toArray(new MediaSessionConnector.CustomActionProvider[0]));
}
@Override
diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java
index fd5e03bf1ce..98ee3d7b84b 100644
--- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java
+++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java
@@ -20,6 +20,8 @@
import org.schabi.newpipe.R;
import org.schabi.newpipe.player.Player;
+import java.util.Objects;
+
public final class NotificationActionData {
@Nullable
private final String action;
@@ -50,7 +52,6 @@ public int icon() {
return icon;
}
-
@Nullable
public static NotificationActionData fromNotificationActionEnum(
@NonNull final Player player,
@@ -165,4 +166,18 @@ public static NotificationActionData fromNotificationActionEnum(
return null;
}
}
+
+
+ @Override
+ public boolean equals(@Nullable final Object obj) {
+ return (obj instanceof NotificationActionData other)
+ && Objects.equals(this.action, other.action)
+ && this.name.equals(other.name)
+ && this.icon == other.icon;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(action, name, icon);
+ }
}
From 4b1824e8c16aed9725ba970ca00b8cae37171cf6 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Fri, 29 Dec 2023 15:13:18 +0100
Subject: [PATCH 73/82] Allow play/pausing from notification when buffering
This change is in line with a recent change in how the play/pause button behaves in the player ui: if the buffering indicator is shown, it's still possible to toggle play/pause, to allow e.g. pausing videos before they even start.
This change was needed because on Android 13+ notification actions can't be null, and thus the buffering hourglass action wasn't shown.
---
.../SessionConnectorActionProvider.java | 10 +++-------
.../notification/NotificationActionData.java | 16 ++++++++++------
.../player/notification/NotificationUtil.java | 10 ++--------
3 files changed, 15 insertions(+), 21 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/SessionConnectorActionProvider.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/SessionConnectorActionProvider.java
index 7b109c149ff..a5c9fccc9eb 100644
--- a/app/src/main/java/org/schabi/newpipe/player/mediasession/SessionConnectorActionProvider.java
+++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/SessionConnectorActionProvider.java
@@ -40,12 +40,8 @@ public void onCustomAction(@NonNull final Player player,
@Nullable
@Override
public PlaybackStateCompat.CustomAction getCustomAction(@NonNull final Player player) {
- if (data.action() == null) {
- return null;
- } else {
- return new PlaybackStateCompat.CustomAction.Builder(
- data.action(), data.name(), data.icon()
- ).build();
- }
+ return new PlaybackStateCompat.CustomAction.Builder(
+ data.action(), data.name(), data.icon()
+ ).build();
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java
index 98ee3d7b84b..b3abcd0b514 100644
--- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java
+++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationActionData.java
@@ -11,6 +11,7 @@
import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_REPEAT;
import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_SHUFFLE;
+import android.annotation.SuppressLint;
import android.content.Context;
import androidx.annotation.DrawableRes;
@@ -23,21 +24,23 @@
import java.util.Objects;
public final class NotificationActionData {
- @Nullable
+
+ @NonNull
private final String action;
@NonNull
private final String name;
@DrawableRes
private final int icon;
- public NotificationActionData(@Nullable final String action, @NonNull final String name,
+
+ public NotificationActionData(@NonNull final String action, @NonNull final String name,
@DrawableRes final int icon) {
this.action = action;
this.name = name;
this.icon = icon;
}
- @Nullable
+ @NonNull
public String action() {
return action;
}
@@ -52,6 +55,8 @@ public int icon() {
return icon;
}
+
+ @SuppressLint("PrivateResource") // we currently use Exoplayer's internal strings and icons
@Nullable
public static NotificationActionData fromNotificationActionEnum(
@NonNull final Player player,
@@ -105,8 +110,7 @@ public static NotificationActionData fromNotificationActionEnum(
if (player.getCurrentState() == Player.STATE_PREFLIGHT
|| player.getCurrentState() == Player.STATE_BLOCKED
|| player.getCurrentState() == Player.STATE_BUFFERING) {
- // null intent action -> show hourglass icon that does nothing when clicked
- return new NotificationActionData(null,
+ return new NotificationActionData(ACTION_PLAY_PAUSE,
ctx.getString(R.string.notification_action_buffering),
R.drawable.ic_hourglass_top);
}
@@ -171,7 +175,7 @@ public static NotificationActionData fromNotificationActionEnum(
@Override
public boolean equals(@Nullable final Object obj) {
return (obj instanceof NotificationActionData other)
- && Objects.equals(this.action, other.action)
+ && this.action.equals(other.action)
&& this.name.equals(other.name)
&& this.icon == other.icon;
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
index b3cfed1ce36..30420b0c7da 100644
--- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
+++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationUtil.java
@@ -244,14 +244,8 @@ private void addAction(final NotificationCompat.Builder builder,
return;
}
- final PendingIntent intent;
- if (data.action() == null) {
- intent = null;
- } else {
- intent = PendingIntentCompat.getBroadcast(player.getContext(), NOTIFICATION_ID,
- new Intent(data.action()), FLAG_UPDATE_CURRENT, false);
- }
-
+ final PendingIntent intent = PendingIntentCompat.getBroadcast(player.getContext(),
+ NOTIFICATION_ID, new Intent(data.action()), FLAG_UPDATE_CURRENT, false);
builder.addAction(new NotificationCompat.Action(data.icon(), data.name(), intent));
}
From f98548698af0e4d5a58c99a187b35c3e92d10119 Mon Sep 17 00:00:00 2001
From: Stypox
Date: Sat, 30 Dec 2023 21:55:32 +0100
Subject: [PATCH 74/82] Android 33 -> Android 13
Co-authored-by: Tobi
---
.../org/schabi/newpipe/settings/custom/NotificationSlot.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java
index 074532876bd..981ba3e7549 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationSlot.java
@@ -89,7 +89,7 @@ void setupTitle(final View view) {
void setupCheckbox(final View view, final boolean isCompactSlotChecked) {
final CheckBox compactSlotCheckBox = view.findViewById(R.id.notificationActionCheckBox);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- // there are no compact slots to customize on Android 33+
+ // there are no compact slots to customize on Android 13+
compactSlotCheckBox.setVisibility(View.GONE);
view.findViewById(R.id.notificationActionCheckBoxClickableArea)
.setVisibility(View.GONE);
From 2051334bba247422dc8203fa10f89f998ee8642a Mon Sep 17 00:00:00 2001
From: Zongle Wang
Date: Mon, 8 Jan 2024 11:55:57 +0800
Subject: [PATCH 75/82] Bump GH actions
Old ones are deprecated.
---
.github/workflows/ci.yml | 16 ++++++++--------
.github/workflows/image-minimizer.yml | 6 +++---
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 03b04b7c4d0..4800f857803 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -36,7 +36,7 @@ jobs:
contents: read
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v1
- name: create and checkout branch
@@ -47,7 +47,7 @@ jobs:
run: git checkout -B "$BRANCH"
- name: set up JDK 17
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: 17
distribution: "temurin"
@@ -57,7 +57,7 @@ jobs:
run: ./gradlew assembleDebug lintDebug testDebugUnitTest --stacktrace -DskipFormatKtlint
- name: Upload APK
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: app
path: app/build/outputs/apk/debug/*.apk
@@ -80,10 +80,10 @@ jobs:
contents: read
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: set up JDK 17
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: 17
distribution: "temurin"
@@ -98,7 +98,7 @@ jobs:
script: ./gradlew connectedCheck --stacktrace
- name: Upload test report when tests fail # because the printed out stacktrace (console) is too short, see also #7553
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: failure()
with:
name: android-test-report-api${{ matrix.api-level }}
@@ -111,12 +111,12 @@ jobs:
contents: read
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 17
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: 17
distribution: "temurin"
diff --git a/.github/workflows/image-minimizer.yml b/.github/workflows/image-minimizer.yml
index 56c6eb37f26..d9241c33b62 100644
--- a/.github/workflows/image-minimizer.yml
+++ b/.github/workflows/image-minimizer.yml
@@ -17,9 +17,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- - uses: actions/setup-node@v3
+ - uses: actions/setup-node@v4
with:
node-version: 16
@@ -27,7 +27,7 @@ jobs:
run: npm i probe-image-size@7.2.3 --ignore-scripts
- name: Minimize simple images
- uses: actions/github-script@v6
+ uses: actions/github-script@v7
timeout-minutes: 3
with:
script: |
From 6dd62335e923cd5fd57d2d48d6790805897816a2 Mon Sep 17 00:00:00 2001
From: opusforlife2 <53176348+opusforlife2@users.noreply.github.com>
Date: Sat, 27 Jan 2024 16:36:13 +0000
Subject: [PATCH 76/82] Update Matrix room URL to new link
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 9fabb5ac7d9..cec679a5821 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
-
+
Screenshots • Supported Services • Description • Features • Installation and updates • Contribution • Donate • License
From 27730a20d6c76725cd14dc7f00ecf146995fdcc9 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Mon, 5 Feb 2024 10:52:08 +0530
Subject: [PATCH 77/82] Update Jsoup to 1.17.2
---
app/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle b/app/build.gradle
index 6b51f602983..60414e0e507 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -238,7 +238,7 @@ dependencies {
kapt "frankiesardo:icepick-processor:${icepickVersion}"
// HTML parser
- implementation "org.jsoup:jsoup:1.16.2"
+ implementation "org.jsoup:jsoup:1.17.2"
// HTTP client
implementation "com.squareup.okhttp3:okhttp:4.12.0"
From 9d6ac67c46a6cc55e03dec0599d8070f7430098d Mon Sep 17 00:00:00 2001
From: Ikko Eltociear Ashimine
Date: Mon, 18 Mar 2024 14:43:16 +0900
Subject: [PATCH 78/82] Update TextLinkifier.java
minor fix
---
.../main/java/org/schabi/newpipe/util/text/TextLinkifier.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/org/schabi/newpipe/util/text/TextLinkifier.java b/app/src/main/java/org/schabi/newpipe/util/text/TextLinkifier.java
index e59a3dc0577..1419ac85a04 100644
--- a/app/src/main/java/org/schabi/newpipe/util/text/TextLinkifier.java
+++ b/app/src/main/java/org/schabi/newpipe/util/text/TextLinkifier.java
@@ -92,7 +92,7 @@ public static void fromDescription(@NonNull final TextView textView,
* {@link HtmlCompat#fromHtml(String, int)}.
*
*
- * @param textView the {@link TextView} to set the the HTML string block linked
+ * @param textView the {@link TextView} to set the HTML string block linked
* @param htmlBlock the HTML string block to be linked
* @param htmlCompatFlag the int flag to be set when {@link HtmlCompat#fromHtml(String,
* int)} will be called
From e6a4a3fa4f1f1c8cee90a207efd5f8896dcbc25c Mon Sep 17 00:00:00 2001
From: Hosted Weblate
Date: Mon, 18 Mar 2024 09:59:34 +0100
Subject: [PATCH 79/82] Translated using Weblate (Danish)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently translated at 96.4% (703 of 729 strings)
Translated using Weblate (Dutch)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Danish)
Currently translated at 96.4% (703 of 729 strings)
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Danish)
Currently translated at 88.3% (644 of 729 strings)
Translated using Weblate (Danish)
Currently translated at 88.3% (644 of 729 strings)
Translated using Weblate (Belarusian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Slovak)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Russian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Georgian)
Currently translated at 92.2% (71 of 77 strings)
Translated using Weblate (Uzbek (latin))
Currently translated at 62.6% (457 of 729 strings)
Translated using Weblate (Santali)
Currently translated at 12.6% (92 of 729 strings)
Translated using Weblate (French)
Currently translated at 89.6% (69 of 77 strings)
Translated using Weblate (Japanese)
Currently translated at 11.6% (9 of 77 strings)
Translated using Weblate (Bulgarian)
Currently translated at 5.1% (4 of 77 strings)
Translated using Weblate (Bengali)
Currently translated at 20.7% (16 of 77 strings)
Translated using Weblate (German)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Bengali (India))
Currently translated at 40.7% (297 of 729 strings)
Translated using Weblate (Kurdish (Central))
Currently translated at 85.5% (624 of 729 strings)
Translated using Weblate (Tamil)
Currently translated at 46.6% (340 of 729 strings)
Translated using Weblate (Bengali (Bangladesh))
Currently translated at 55.1% (402 of 729 strings)
Translated using Weblate (Turkish)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Greek)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (German)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Portuguese (Portugal))
Currently translated at 98.7% (76 of 77 strings)
Translated using Weblate (Hebrew)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Hebrew)
Currently translated at 99.4% (725 of 729 strings)
Translated using Weblate (Indonesian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Croatian)
Currently translated at 99.4% (725 of 729 strings)
Translated using Weblate (ryu (generated) (ryu))
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Croatian)
Currently translated at 2.5% (2 of 77 strings)
Translated using Weblate (Malay)
Currently translated at 48.6% (355 of 729 strings)
Translated using Weblate (Croatian)
Currently translated at 99.3% (724 of 729 strings)
Translated using Weblate (Romanian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Japanese)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Finnish)
Currently translated at 98.3% (717 of 729 strings)
Translated using Weblate (Hungarian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 22.0% (17 of 77 strings)
Translated using Weblate (Norwegian Bokmål)
Currently translated at 95.4% (696 of 729 strings)
Translated using Weblate (Portuguese)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Portuguese)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Vietnamese)
Currently translated at 42.8% (33 of 77 strings)
Translated using Weblate (Vietnamese)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Turkish)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Esperanto)
Currently translated at 70.7% (516 of 729 strings)
Translated using Weblate (Slovak)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Azerbaijani)
Currently translated at 94.6% (690 of 729 strings)
Translated using Weblate (Hindi)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Turkish)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Dutch)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (French)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Santali)
Currently translated at 10.0% (73 of 729 strings)
Translated using Weblate (Turkish)
Currently translated at 42.8% (33 of 77 strings)
Translated using Weblate (German)
Currently translated at 81.8% (63 of 77 strings)
Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Kannada)
Currently translated at 5.4% (40 of 729 strings)
Translated using Weblate (Russian)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Vietnamese)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Croatian)
Currently translated at 88.7% (647 of 729 strings)
Translated using Weblate (Slovak)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Odia)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Slovak)
Currently translated at 20.7% (16 of 77 strings)
Translated using Weblate (Indonesian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Slovak)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (French)
Currently translated at 99.8% (728 of 729 strings)
Translated using Weblate (Indonesian)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Catalan)
Currently translated at 86.5% (631 of 729 strings)
Translated using Weblate (Telugu)
Currently translated at 58.9% (430 of 729 strings)
Translated using Weblate (Turkish)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Indonesian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Greek)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Tigrinya)
Currently translated at 8.9% (65 of 729 strings)
Translated using Weblate (Russian)
Currently translated at 98.7% (76 of 77 strings)
Translated using Weblate (Belarusian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Swedish)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Slovak)
Currently translated at 99.7% (727 of 729 strings)
Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Italian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Russian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Odia)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Portuguese)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Kurdish (Central))
Currently translated at 85.5% (624 of 729 strings)
Translated using Weblate (Estonian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Portuguese)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Japanese)
Currently translated at 99.8% (728 of 729 strings)
Translated using Weblate (Serbian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Spanish)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (German)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Swedish)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Italian)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Hindi)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Punjabi)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Czech)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Portuguese (Portugal))
Currently translated at 99.8% (728 of 729 strings)
Translated using Weblate (Punjabi)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Hindi)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Swedish)
Currently translated at 99.8% (728 of 729 strings)
Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Polish)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Arabic)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Czech)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Portuguese)
Currently translated at 99.8% (728 of 729 strings)
Translated using Weblate (Italian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (German)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (German)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (729 of 729 strings)
Translated using Weblate (ryu (generated) (ryu))
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Serbian)
Currently translated at 18.1% (14 of 77 strings)
Translated using Weblate (Swedish)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Spanish)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Arabic)
Currently translated at 100.0% (77 of 77 strings)
Translated using Weblate (Greek)
Currently translated at 24.6% (19 of 77 strings)
Translated using Weblate (Estonian)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Swedish)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Polish)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Arabic)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Greek)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Portuguese)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Japanese)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Serbian)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Dutch)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (Spanish)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (German)
Currently translated at 100.0% (728 of 728 strings)
Translated using Weblate (ryu (generated) (ryu))
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Kannada)
Currently translated at 5.5% (40 of 726 strings)
Translated using Weblate (Sinhala)
Currently translated at 2.6% (2 of 76 strings)
Translated using Weblate (Sinhala)
Currently translated at 4.1% (30 of 726 strings)
Translated using Weblate (Bulgarian)
Currently translated at 5.2% (4 of 76 strings)
Translated using Weblate (Punjabi)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Hindi)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Turkish)
Currently translated at 99.8% (725 of 726 strings)
Translated using Weblate (Slovak)
Currently translated at 98.4% (715 of 726 strings)
Translated using Weblate (Italian)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Japanese)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (French)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Polish)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Arabic)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Greek)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Italian)
Currently translated at 99.5% (723 of 726 strings)
Translated using Weblate (Serbian)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Dutch)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Czech)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Spanish)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (German)
Currently translated at 100.0% (726 of 726 strings)
Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 21.0% (16 of 76 strings)
Translated using Weblate (Serbian)
Currently translated at 100.0% (725 of 725 strings)
Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (725 of 725 strings)
Translated using Weblate (Romanian)
Currently translated at 99.8% (724 of 725 strings)
Translated using Weblate (Dutch)
Currently translated at 100.0% (725 of 725 strings)
Translated using Weblate (Spanish)
Currently translated at 100.0% (725 of 725 strings)
Co-authored-by: Agnieszka C
Co-authored-by: Alex25820
Co-authored-by: Alexthegib
Co-authored-by: Allan Nordhøy
Co-authored-by: Andrey F
Co-authored-by: Angelk90
Co-authored-by: Chethan <76928501+ch3thanhs@users.noreply.github.com>
Co-authored-by: Danr
Co-authored-by: David Svane
Co-authored-by: Deleted User
Co-authored-by: DuninduH
Co-authored-by: Eric
Co-authored-by: Fjuro
Co-authored-by: GET100PERCENT
Co-authored-by: Ghost of Sparta
Co-authored-by: Heidhou chazanouvha
Co-authored-by: Hosted Weblate
Co-authored-by: Igor Rückert
Co-authored-by: Igor Sorocean
Co-authored-by: Ihfandi
Co-authored-by: Ihor Hordiichuk
Co-authored-by: Jan Layola
Co-authored-by: Jeff Huang
Co-authored-by: Juan Martinez
Co-authored-by: KarmaKat
Co-authored-by: Kuko
Co-authored-by: LiJu09
Co-authored-by: Martin Constantino–Bodin
Co-authored-by: Mehmet
Co-authored-by: Michalis
Co-authored-by: Milan
Co-authored-by: Milo Ivir
Co-authored-by: NEXI
Co-authored-by: Nils Van Zuijlen
Co-authored-by: Nista <42772160+Nista11@users.noreply.github.com>
Co-authored-by: Oğuz Ersen
Co-authored-by: P.O
Co-authored-by: Philip Goto
Co-authored-by: Pi-Cla
Co-authored-by: Prasanta-Hembram
Co-authored-by: Priit Jõerüüt
Co-authored-by: Random
Co-authored-by: Ray
Co-authored-by: Rex_sa
Co-authored-by: Scrambled777
Co-authored-by: Sergio Marques
Co-authored-by: ShareASmile
Co-authored-by: Subbarayudu
Co-authored-by: Subham Jena
Co-authored-by: T1z3n
Co-authored-by: Terry Louwers
Co-authored-by: TobiGr
Co-authored-by: Vasilis K
Co-authored-by: VfBFan
Co-authored-by: Xəyyam Qocayev
Co-authored-by: Yaron Shahrabani
Co-authored-by: bittin1ddc447d824349b2
Co-authored-by: cat <158170307+cultcats@users.noreply.github.com>
Co-authored-by: ds-z
Co-authored-by: dyare darbani
Co-authored-by: fsbat0
Co-authored-by: gallegonovato
Co-authored-by: hshbuk
Co-authored-by: jspast
Co-authored-by: kuragehime
Co-authored-by: ngocanhtve
Co-authored-by: pjammo
Co-authored-by: ssantos
Co-authored-by: trunars
Co-authored-by: v1s7
Co-authored-by: Åzze
Co-authored-by: Çağla Pickaxe
Co-authored-by: Макар Разин
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/bg/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/bn/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/el/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/es/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/id/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/it/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ja/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ka/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pa/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_PT/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ru/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/si/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sk/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/tr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/vi/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant_HK/
Translation: NewPipe/Metadata
---
app/src/main/res/values-ar/strings.xml | 13 +-
app/src/main/res/values-az/strings.xml | 3 +-
app/src/main/res/values-b+uz+Latn/strings.xml | 2 +-
app/src/main/res/values-be/strings.xml | 125 ++--
app/src/main/res/values-bn-rBD/strings.xml | 6 +-
app/src/main/res/values-bn-rIN/strings.xml | 2 +-
app/src/main/res/values-ca/strings.xml | 23 +-
app/src/main/res/values-ckb/strings.xml | 60 +-
app/src/main/res/values-cs/strings.xml | 10 +-
app/src/main/res/values-da/strings.xml | 228 +++---
app/src/main/res/values-de/strings.xml | 13 +-
app/src/main/res/values-el/strings.xml | 13 +-
app/src/main/res/values-eo/strings.xml | 1 +
app/src/main/res/values-es/strings.xml | 12 +-
app/src/main/res/values-et/strings.xml | 9 +-
app/src/main/res/values-fi/strings.xml | 9 +-
app/src/main/res/values-fr/strings.xml | 10 +-
app/src/main/res/values-he/strings.xml | 10 +-
app/src/main/res/values-hi/strings.xml | 13 +-
app/src/main/res/values-hr/strings.xml | 213 ++++--
app/src/main/res/values-hu/strings.xml | 53 +-
app/src/main/res/values-in/strings.xml | 42 +-
app/src/main/res/values-it/strings.xml | 12 +-
app/src/main/res/values-ja/strings.xml | 8 +-
app/src/main/res/values-kn/strings.xml | 43 +-
app/src/main/res/values-ms/strings.xml | 4 +
app/src/main/res/values-nb-rNO/strings.xml | 30 +-
app/src/main/res/values-nl/strings.xml | 15 +-
app/src/main/res/values-or/strings.xml | 11 +-
app/src/main/res/values-pa/strings.xml | 9 +-
app/src/main/res/values-pl/strings.xml | 9 +
app/src/main/res/values-pt-rBR/strings.xml | 11 +-
app/src/main/res/values-pt-rPT/strings.xml | 10 +-
app/src/main/res/values-pt/strings.xml | 234 +++---
app/src/main/res/values-ro/strings.xml | 19 +-
app/src/main/res/values-ru/strings.xml | 15 +-
app/src/main/res/values-ryu/strings.xml | 23 +-
app/src/main/res/values-sat/strings.xml | 687 +++++++++++++++++-
app/src/main/res/values-si/strings.xml | 7 +
app/src/main/res/values-sk/strings.xml | 149 ++--
app/src/main/res/values-sr/strings.xml | 30 +-
app/src/main/res/values-sv/strings.xml | 9 +-
app/src/main/res/values-ta/strings.xml | 4 +-
app/src/main/res/values-te/strings.xml | 13 +-
app/src/main/res/values-ti/strings.xml | 7 +-
app/src/main/res/values-tr/strings.xml | 51 +-
app/src/main/res/values-uk/strings.xml | 13 +-
app/src/main/res/values-vi/strings.xml | 10 +-
app/src/main/res/values-zh-rCN/strings.xml | 8 +-
app/src/main/res/values-zh-rHK/strings.xml | 14 +-
app/src/main/res/values-zh-rTW/strings.xml | 8 +-
.../metadata/android/ar/changelogs/996.txt | 2 +
.../metadata/android/bg/changelogs/64.txt | 6 +
.../metadata/android/bn/changelogs/64.txt | 2 +-
.../metadata/android/cs/changelogs/996.txt | 2 +
.../metadata/android/de/changelogs/65.txt | 4 +-
.../metadata/android/de/changelogs/66.txt | 18 +
.../metadata/android/de/changelogs/68.txt | 19 +
.../metadata/android/de/changelogs/69.txt | 14 +
.../metadata/android/de/changelogs/70.txt | 10 +
.../metadata/android/de/changelogs/71.txt | 8 +
.../metadata/android/de/changelogs/740.txt | 12 +
.../metadata/android/de/changelogs/750.txt | 15 +
.../metadata/android/de/changelogs/760.txt | 24 +
.../metadata/android/de/changelogs/780.txt | 11 +
.../metadata/android/de/changelogs/790.txt | 13 +
.../metadata/android/de/changelogs/800.txt | 11 +
.../metadata/android/de/changelogs/810.txt | 11 +
.../metadata/android/de/changelogs/840.txt | 10 +
.../metadata/android/de/changelogs/930.txt | 12 +
.../metadata/android/de/changelogs/940.txt | 1 -
.../metadata/android/de/changelogs/951.txt | 1 -
.../metadata/android/de/changelogs/990.txt | 2 -
.../metadata/android/de/changelogs/995.txt | 4 +-
.../metadata/android/de/changelogs/996.txt | 2 +
.../metadata/android/de/full_description.txt | 2 +-
.../metadata/android/de/short_description.txt | 2 +-
.../metadata/android/el/changelogs/65.txt | 26 +
.../metadata/android/el/changelogs/963.txt | 1 +
.../metadata/android/el/changelogs/996.txt | 2 +
.../metadata/android/es/changelogs/996.txt | 2 +
.../metadata/android/fr/changelogs/750.txt | 6 +-
.../metadata/android/hi/changelogs/996.txt | 2 +
.../metadata/android/hr/full_description.txt | 2 +-
.../metadata/android/id/changelogs/66.txt | 12 +-
.../metadata/android/id/changelogs/972.txt | 2 +-
.../metadata/android/id/changelogs/975.txt | 28 +-
.../metadata/android/id/changelogs/976.txt | 6 +-
.../metadata/android/id/changelogs/995.txt | 12 +-
.../metadata/android/id/changelogs/996.txt | 2 +
.../metadata/android/it/changelogs/996.txt | 2 +
.../metadata/android/ja/changelogs/954.txt | 2 +-
.../metadata/android/ka/changelogs/64.txt | 2 +-
.../metadata/android/ka/changelogs/69.txt | 2 +-
.../metadata/android/ka/changelogs/740.txt | 6 +-
.../metadata/android/ka/changelogs/850.txt | 2 +-
.../metadata/android/ka/changelogs/967.txt | 2 +-
.../metadata/android/ka/changelogs/978.txt | 2 +-
.../metadata/android/ka/changelogs/988.txt | 2 +-
.../metadata/android/ka/full_description.txt | 2 +-
.../metadata/android/pa/changelogs/996.txt | 2 +
.../metadata/android/pt-PT/changelogs/995.txt | 16 +
.../metadata/android/pt/changelogs/995.txt | 10 +-
.../metadata/android/pt/changelogs/996.txt | 2 +
.../metadata/android/ru/changelogs/995.txt | 16 +-
.../metadata/android/ru/changelogs/996.txt | 2 +
.../metadata/android/si/full_description.txt | 1 +
.../metadata/android/si/short_description.txt | 1 +
.../metadata/android/sk/changelogs/995.txt | 16 +
.../metadata/android/sk/changelogs/996.txt | 2 +
.../metadata/android/sr/changelogs/996.txt | 2 +
.../metadata/android/sv/changelogs/63.txt | 4 +-
.../metadata/android/sv/changelogs/64.txt | 6 +-
.../metadata/android/sv/changelogs/957.txt | 10 +
.../metadata/android/sv/changelogs/958.txt | 10 +
.../metadata/android/sv/changelogs/961.txt | 12 +
.../metadata/android/sv/changelogs/964.txt | 7 +
.../metadata/android/sv/changelogs/965.txt | 6 +
.../metadata/android/sv/changelogs/966.txt | 14 +
.../metadata/android/sv/changelogs/968.txt | 7 +
.../metadata/android/sv/changelogs/970.txt | 11 +
.../metadata/android/sv/changelogs/975.txt | 15 +
.../metadata/android/sv/changelogs/976.txt | 9 +
.../metadata/android/sv/changelogs/983.txt | 9 +
.../metadata/android/sv/changelogs/986.txt | 15 +
.../metadata/android/sv/changelogs/987.txt | 12 +
.../metadata/android/sv/changelogs/988.txt | 2 +
.../metadata/android/sv/changelogs/989.txt | 3 +
.../metadata/android/sv/changelogs/990.txt | 15 +
.../metadata/android/sv/changelogs/991.txt | 13 +
.../metadata/android/sv/changelogs/992.txt | 17 +
.../metadata/android/sv/changelogs/993.txt | 12 +
.../metadata/android/sv/changelogs/994.txt | 15 +
.../metadata/android/sv/changelogs/995.txt | 16 +
.../metadata/android/sv/changelogs/996.txt | 2 +
.../metadata/android/sv/short_description.txt | 2 +-
.../metadata/android/tr/full_description.txt | 4 +-
.../metadata/android/uk/changelogs/996.txt | 2 +
.../metadata/android/vi/changelogs/996.txt | 2 +
.../android/zh_Hant_HK/changelogs/995.txt | 8 +-
.../android/zh_Hant_HK/changelogs/996.txt | 2 +
141 files changed, 2410 insertions(+), 600 deletions(-)
create mode 100644 fastlane/metadata/android/ar/changelogs/996.txt
create mode 100644 fastlane/metadata/android/bg/changelogs/64.txt
create mode 100644 fastlane/metadata/android/cs/changelogs/996.txt
create mode 100644 fastlane/metadata/android/de/changelogs/66.txt
create mode 100644 fastlane/metadata/android/de/changelogs/68.txt
create mode 100644 fastlane/metadata/android/de/changelogs/69.txt
create mode 100644 fastlane/metadata/android/de/changelogs/70.txt
create mode 100644 fastlane/metadata/android/de/changelogs/71.txt
create mode 100644 fastlane/metadata/android/de/changelogs/740.txt
create mode 100644 fastlane/metadata/android/de/changelogs/750.txt
create mode 100644 fastlane/metadata/android/de/changelogs/760.txt
create mode 100644 fastlane/metadata/android/de/changelogs/780.txt
create mode 100644 fastlane/metadata/android/de/changelogs/790.txt
create mode 100644 fastlane/metadata/android/de/changelogs/800.txt
create mode 100644 fastlane/metadata/android/de/changelogs/810.txt
create mode 100644 fastlane/metadata/android/de/changelogs/840.txt
create mode 100644 fastlane/metadata/android/de/changelogs/930.txt
create mode 100644 fastlane/metadata/android/de/changelogs/996.txt
create mode 100644 fastlane/metadata/android/el/changelogs/65.txt
create mode 100644 fastlane/metadata/android/el/changelogs/963.txt
create mode 100644 fastlane/metadata/android/el/changelogs/996.txt
create mode 100644 fastlane/metadata/android/es/changelogs/996.txt
create mode 100644 fastlane/metadata/android/hi/changelogs/996.txt
create mode 100644 fastlane/metadata/android/id/changelogs/996.txt
create mode 100644 fastlane/metadata/android/it/changelogs/996.txt
create mode 100644 fastlane/metadata/android/pa/changelogs/996.txt
create mode 100644 fastlane/metadata/android/pt-PT/changelogs/995.txt
create mode 100644 fastlane/metadata/android/pt/changelogs/996.txt
create mode 100644 fastlane/metadata/android/ru/changelogs/996.txt
create mode 100644 fastlane/metadata/android/si/full_description.txt
create mode 100644 fastlane/metadata/android/si/short_description.txt
create mode 100644 fastlane/metadata/android/sk/changelogs/995.txt
create mode 100644 fastlane/metadata/android/sk/changelogs/996.txt
create mode 100644 fastlane/metadata/android/sr/changelogs/996.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/957.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/958.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/961.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/964.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/965.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/966.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/968.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/970.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/975.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/976.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/983.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/986.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/987.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/988.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/989.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/990.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/991.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/992.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/993.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/994.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/995.txt
create mode 100644 fastlane/metadata/android/sv/changelogs/996.txt
create mode 100644 fastlane/metadata/android/uk/changelogs/996.txt
create mode 100644 fastlane/metadata/android/vi/changelogs/996.txt
create mode 100644 fastlane/metadata/android/zh_Hant_HK/changelogs/996.txt
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 6bfe11eaad0..ce62198cd14 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -584,7 +584,7 @@
خلط
تكرار
يمكنك تحديد ثلاثة إجراءات كحد أقصى لإظهارها في الإشعار المضغوط!
- قم بتحرير كل إشعار أدناه من خلال النقر عليه. حدد ما يصل إلى ثلاثة منها لتظهر في الإشعار المضغوط باستخدام مربعات الاختيار الموجودة على اليمين
+ قم بتحرير كل إجراء إعلام أدناه من خلال النقر عليه. حدد ما يصل إلى ثلاثة منها ليتم عرضها في الإشعار المضغوط باستخدام مربعات الاختيار الموجودة على اليمين.
زر الإجراء الخامس
زر الإجراء الرابع
زر الإجراء الثالث
@@ -858,4 +858,15 @@
مشاركة قائمة التشغيل
شارك تفاصيل قائمة التشغيل مثل اسم قائمة التشغيل وعناوين الفيديو أو كقائمة بسيطة من عناوين URL للفيديو
- %1$s: %2$s
+
+ - رد %s
+ - رد %s
+ - ردان%s
+ - ردود%s
+ - ردود %s
+ - ردود %s
+
+ عرض المزيد
+ عرض أقل
+ قم بتحرير كل إجراء إعلام أدناه من خلال النقر عليه. يتم تعيين الإجراءات الثلاثة الأولى (تشغيل/إيقاف مؤقت، السابق والتالي) بواسطة النظام ولا يمكن تخصيصها.
\ No newline at end of file
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index e3de4f4d236..da08069ac21 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -694,7 +694,7 @@
Bu video yalnız YouTube Music Premium üzvləri üçün əlçatandır, ona görə də NewPipe tərəfindən yayımlamaq və ya endirmək mümkün deyil.
İndi açıqlamadakı mətni seçə bilərsiniz. Nəzərə alın ki, seçim rejimində səhifə titrəyə və linklər kliklənməyə bilər.
Bildirişdə göstərilən video miniatürünü 16:9-dan 1:1 görünüş nisbətinə qədər kəs
- Aşağıdakı hər bir bildiriş fəaliyyətini üzərinə toxunaraq redaktə et. Sağdakı təsdiq qutularından istifadə edərək yığcam bildirişdə göstərmək üçün onların üçünü seç
+ Aşağıdakı hər bir bildiriş fəaliyyətini üzərinə toxunaraq düzəliş edin. Sağdakı təsdiq qutularından istifadə edərək yığcam bildirişdə göstərmək üçün onların üçünü seçin.
Belə fayl/məzmun mənbəyi yoxdur
Seçilən yayım xarici oynadıcılar tərəfindən dəstəklənmir
Yükləyici tərəfindən hələ dəstəklənməyən yayımlar göstərilmir
@@ -769,4 +769,5 @@
Axın yenilənərkən əldə edilən səhifələr.Kanal sürətli rejim istifadə edərək yenilənirsə, bu seçimin heç bir təsiri yoxdur.
Yükləyici avatarları
Miniatürlər
+ Aşağıdakı hər bildirişə vuraraq ona düzəliş edin. İlk üç əməl (oynatma/fasilə, əvvəlki və sonrakı) sistem tərəfindən təyin olunub və dəyişdirilə bilməz.
\ No newline at end of file
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 0ba69ae41ac..3bd940d111e 100644
--- a/app/src/main/res/values-b+uz+Latn/strings.xml
+++ b/app/src/main/res/values-b+uz+Latn/strings.xml
@@ -58,7 +58,7 @@
Kodi bilan ijro etish
Faqat ba\'zi qurilmalar 2K / 4K videolarni ijro etishi mumkin
Yuqori o\'lchamlarni ko\'rsatish
- "Standart pop-up o\'lchamlari"
+ Standart pop-up o\'lchamlari
Standart o\'lchamlari
Audio fayllar uchun yuklab olish papkasini tanlash
Yuklab olingan videofayllar shu yerda saqlanadi
diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml
index 38905ed7fbc..ed24aac816f 100644
--- a/app/src/main/res/values-be/strings.xml
+++ b/app/src/main/res/values-be/strings.xml
@@ -6,8 +6,8 @@
Патокавы плэер не знойдзены (вы можаце ўсталяваць VLC каб прайграць).
Усталяваць
Скасаваць
- Адкрыць у браўзеры
- Адкрыць у асобным акне
+ Адкрыць ў браўзеры
+ Адкрыць ў асобным акне
Падзяліцца
Спампаваць
Загрузка файла прамой трансляцыі
@@ -37,12 +37,12 @@
Загружаныя аўдыёфайлы захоўваюцца тут
Абярыце тэчку загрузкі для аўдыёфайлаў
Разрознянне па змаўчанні
- Разрозненне усплываючага акна
+ Разрозненне ўсплываючага акна
Высокія разрозненні
Толькі некаторыя прылады могуць прайграваць відэа ў 2K/4K
- Прайграць у Kodi
- Усталяваць адсутную праграму Kore\?
- Паказаць опцыю \"Прайграць у Kodi\"
+ Прайграць ў Kodi
+ Ўсталяваць адсутную праграму Kore?
+ Паказаць опцыю \"Прайграць ў Kodi\"
Паказаць опцыю прайгравання відэа праз медыяцэнтр Kodi
Аўдыё
Фармат аўдыё па змаўчанні
@@ -70,7 +70,7 @@
Узнавіць прайграванне
Працягваць прайграванне пасля перапынкаў (напрыклад, тэлефонных званкоў)
Загрузіць
- \"Наступнае\" и \"Прапанаванае\" відэа
+ \"Наступнае\" і \"Прапанаванае\" відэа
Паказаць падказку \"Утрымлівайце, каб паставіць у чаргу\"
Паказаць падказку пры націсканні фонавай або ўсплывальнай кнопкі ў відэа \"Падрабязнасці:\"
URL не падтрымліваецца
@@ -227,7 +227,7 @@
\nПалітыка прыватнасці NewPipe падрабязна тлумачыць, якія дадзеныя адпраўляюцца і захоўваюцца пры адпраўцы справаздачы аб збоях.
Прачытаць палітыку
Ліцэнзія NewPipe
- NewPipe - гэта праграмнае забеспячэнне, свабоднае ад копілефта: вы можаце выкарыстоўваць, вывучаць, дзяліцца і паляпшаць яго па жаданні. У прыватнасці, вы можаце распаўсюджваць і/ці змяняць яго ў адпаведнасці з умовамі Агульнай грамадскай ліцэнзіі GNU, апублікаванай Фондам свабоднага праграмнага забеспячэння, альбо версіі 3 Ліцэнзіі, альбо (на ваш выбар) любой пазнейшай версіі.
+ NewPipe - гэта праграмнае забеспячэнне, свабоднае ад копілефта: вы можаце выкарыстоўваць, вывучаць, дзяліцца і паляпшаць яго па жаданні. Ў прыватнасці, вы можаце распаўсюджваць і/ці змяняць яго ў адпаведнасці з умовамі Агульнай грамадскай ліцэнзіі GNU, апублікаванай Фондам свабоднага праграмнага забеспячэння, альбо версіі 3 Ліцэнзіі, альбо (на ваш выбар) любой пазнейшай версіі.
Прачытаць ліцэнзію
Гісторыя
Гісторыя
@@ -253,8 +253,8 @@
Выдаліць
Падрабязнасці
Налады аўдыё
- Утрымлівайце, каб дадаць у чаргу
- Пачаць адсюль у фоне
+ Утрымлівайце, каб дадаць ў чаргу
+ Пачаць адсюль ў фоне
Пачніце гуляць ва ўсплываючым акне
Адкрыць бакавую панэль
Зачыніць бакавую панэль
@@ -262,16 +262,16 @@
Пры адкрыцці спасылкі на кантэнт — %s
Відэаплэер
Фонавы плэер
- Плэер у акне
+ Аконны прайгравальнік
Заўсёды пытацца
Атрыманне звестак…
Загрузка запытанага кантэнту
Стварыць плэйліст
Перайменаваць
Імя
- Дадаць у плэйліст
- Усталяваць як мініяцюру плэйліста
- Дадаць плэйліст у закладкі
+ Дадаць ў плэйліст
+ Ўсталяваць як мініяцюру плэйліста
+ Дадаць плэйліст ў закладкі
Выдаліць закладку
Выдаліць плэйліст\?
Плэйліст створаны
@@ -289,7 +289,7 @@
Прымусова паведамляць пра недастаўляемыя Rx-выключэнні па-за фрагментам або жыццёвым цыкле пасля выдалення
Імпарт
Імпарт з
- Экспарт у
+ Экспарт ў
Імпарт…
Экспарт…
Імпарт файла
@@ -299,17 +299,17 @@
Імпарт падпісак YouTube з Google Takeout:
\n
\n1. Перайдзіце па гэтым URL: %1$s
-\n2. Увайдзіце, калі вас папросяць
+\n2. Ўвайдзіце, калі вас папросяць
\n3. Націсніце на «Усе дадзеныя ўключаны», затым на «Адмяніць выбар усіх», затым выберыце толькі «падпіскі» і націсніце «ОК»
\n4. Націсніце на «Наступны крок», а затым на «Стварыць экспарт»
\n5. Націсніце на кнопку «Спампаваць» пасля таго, як яна з\'явіцца
\n6. Пстрыкніце ФАЙЛ ІМПАРТУВАЦЬ ніжэй і выберыце спампаваны файл .zip
\n7. [Калі імпарт .zip не ўдаецца] Распакуйце файл .csv (звычайна ў раздзеле \"YouTube і YouTube Music/subscriptions/subscriptions.csv\"), націсніце ФАЙЛ ІМПАРТУВАЦЬ ніжэй і выберыце выняты файл CSV
- Імпарт падпісак з SoundCloud набраўшы альбо URL, альбо ваш ID:
-\n
-\n1. Уключыце \"рэжым працоўнага стала\" у браўзэры (сайт недаступны на тэлефоне)
-\n2. Перайдзіце на: %1$s
-\n3. Увайдзіце, калі неабходна
+ Імпарт падпісак з SoundCloud набраўшы альбо URL, альбо ваш ID:
+\n
+\n1. Ўключыце \"рэжым працоўнага стала\" ў браўзэры (сайт недаступны на тэлефоне)
+\n2. Перайдзіце на: %1$s
+\n3. Увайдзіце, калі неабходна
\n4. Скапіруйце адрас з адраснага радка.
вашID, soundcloud.com/вашID
Гэтае дзеянне можа выклікаць вялікі расход трафіку.
@@ -322,7 +322,7 @@
Прапускаць цішыню
Крок
Скід
- У адпаведнасці з Агульным рэгламентам па абароне дадзеных ЕС (GDPR), звяртаем вашу ўвагу на палітыку прыватнасці NewPipe. Калі ласка, уважліва азнаёмцеся з ёй.
+ Ў адпаведнасці з Агульным рэгламентам па абароне дадзеных ЕС (GDPR), звяртаем вашу ўвагу на палітыку прыватнасці NewPipe. Калі ласка, уважліва азнаёмцеся з ёй.
\nВам неабходна прыняць яе ўмовы, каб адправіць нам справаздачу пра памылку.
Прыняць
Адмовіцца
@@ -331,8 +331,8 @@
Пры згортванні плэера
Дзеянне пры пераключэнні са стандартнага плэера на іншае прыкладанне — %s
Нічога не рабіць
- Згарнуць у фонавы плэер
- Плэер у акне
+ Згарнуць ў фонавы плэер
+ Плэер ў акне
Адпісацца
Абярыце ўкладку
Абнаўленні
@@ -356,14 +356,14 @@
Скончана
У чарзе
прыпынена
- у чарзе
+ дададзены ў чаргу
постапрацоўка
- Паставіць у чаргу
+ Дадаць ў чаргу
Дзеянне забаронена сістэмай
Памылка загрузкі
Стварыць унікальнае імя
Перазапісаць
- Загрузка з такім імем ужо выконваецца
+ Загрузка з такім імем ўжо выконваецца
Паказаць тэкст памылкі
Немагчыма стварыць папку прызначэння
Немагчыма стварыць файл
@@ -377,7 +377,7 @@
Спыніць
Максімум спробаў
Колькасць спробаў перад адменай загрузкі
- Перапыніць у платных сетках
+ Перапыніць ў платных сетках
Карысна пры пераключэнні на мабільную сетку, хоць некаторыя загрузкі не могуць быць прыпыненыя
Падзеі
Канферэнцыі
@@ -394,10 +394,10 @@
Ачысціць дадзеныя
Пазіцыі прайгравання выдалены
Файл перамешчаны ці выдалены
- Файл з такім імем ужо існуе
- Файл з такім імем ужо існуе
+ Файл з такім імем ўжо існуе
+ Файл з такім імем ўжо існуе
немагчыма перазапісаць файл
- У чарзе ўжо ёсць загрузка з такім імем
+ Ў чарзе ўжо ёсць загрузка з такім імем
NewPipe была зачынена падчас працы над файлам
Скончылася вольнае месца на прыладзе
Прагрэс страчаны, так як файл быў выдалены
@@ -408,8 +408,8 @@
Пачаць загрузку
Прыпыніць загрузку
Запытваць тэчку загрузкі
- Вам будзе прапанавана ўказаць месца захавання кожнай загрузкі.
-\nУключыце сістэмны выбарнік тэчкі (SAF), калі вы хочаце загружаць файлы на знешнюю SD-картку
+ Вам будзе прапанавана указаць месца захавання кожнай загрузкі.
+\nЎключыце сістэмны выбарнік тэчкі (SAF), калі вы хочаце загружаць файлы на знешнюю SD-картку
Выкарыстоўвайце сродак выбару сістэмных тэчак (SAF)
\'Storage Access Framework\' дазваляе загружаць на знешнюю SD-картку
Пераключыць службу, выбраную ў дадзены момант:
@@ -426,7 +426,7 @@
Кнопка другога дзеяння
Кнопка першага дзеяння
Групы каналаў
- Як у сістэме
+ Як ў сістэме
Мова прылады
Выберыце экзэмпляр
Выдаліць загружаныя файлы
@@ -442,15 +442,15 @@
Ніколі
Толькі па Wi-Fi
Паказаць арыгінальны час на элементах
- Уключыць гук
+ Ўключыць гук
Цішына
- Дадаць у чаргу
- Даданае у чаргу
+ Дадаць ў чаргу
+ Даданае ў чаргу
Чарга прайгравання
Найбольш папулярнае
Лакальнае
Нядаўна дададзенае
- Няма закладак у плейлісце
+ Няма закладак ў плейлісце
Выберыце плэйліст
Кіёск па змаўчанні
Так
@@ -478,7 +478,7 @@
Кнопка пятага дзеяння
Афарбоўваць апавяшчэнне асноўным колерам мініяцюры. Падтрымваецца не ўсімі прыладамі
У кампактным апавяшчэнні дасяжна не больш за тры дзеянні!
- Дзеянні можна змяніць, націснуўшы на іх. Адзначце не больш за трох для адлюстравання ў кампактным апавяшчэнні
+ Адрэдагуйце кожнае дзеянне апавяшчэння, націснуўшы на яго. Выберыце да трох з іх, якія будуць адлюстроўвацца ў кампактным апавяшчэнні, выкарыстоўваючы сцяжкі справа.
Не ўдалося распазнаць URL-адрас. Адкрыць у іншай праграме\?
Апавяшченне плэера
Апавяшчэнні
@@ -497,9 +497,9 @@
Падпіскі не выбраны
Апошняе абнаўленне: %s
Аўтаматычна (тэма прылады)
- Выберыце ўлюбёную начную тэму - %s
+ Выберыце любімую начную тэму - %s
Дазвол вылучэння тэксту ў апісанні
- Ніжэй вы можаце абраць улюбёную начную тэму
+ Вы можаце выбраць сваю любімую начную тэму ніжэй
Гэта опцыя даступна толькі тады, калі %s будзе выбранай тэмаю
Загрузка пачалась
Апавяшчэнні адключаныя
@@ -519,7 +519,7 @@
Адкрыць з дапамогай
Начная тэма
Адкрыць вэб-сайт
- Цяпер Вы можаце вылучаць тэкст у апісанні. Звярніце ўвагу, што ў рэжыме вылучэння старонка можа мігацець, а спасылкі могуць быць недаступныя для націскання.
+ Цяпер Вы можаце вылучаць тэкст ў апісанні. Звярніце ўвагу, што ў рэжыме вылучэння старонка можа мігацець, а спасылкі могуць быць недаступныя для націскання.
Запусціць галоўны прайгравальнік у поўнаэкранным рэжыме
Паказаць дэталі канала
Нізкая якасць (менш)
@@ -574,14 +574,14 @@
- Выдалена %1$s зазагрузак
- Выдалена %1$s зазагрузак
- Выдаліць усе загружаныя файлы з дыска\?
+ Выдаліць ўсе загружаныя файлы з дыска?
- %d хвіліна
- %d хвіліны
- %d хвілінаў
- %d хвілінаў
- Змяніць памер інтэрвалу загрузкі прагрэсіўнага змесціва (у цяперашні час %s). Меншае значэнне можа паскорыць іх першапачатковую загрузку
+ Змяніць памер інтэрвалу загрузкі прагрэсіўнага змесціва (ў цяперашні час %s). Меншае значэнне можа паскорыць іх першапачатковую загрузку
Выключыце, каб схаваць апісанне відэа і дадатковую інфармацыю
Прапановы лакальнага пошуку
Наладзіць апавяшчэнне аб бягучым прайграванні патоку
@@ -608,7 +608,7 @@
Разлік хэша
Вырашана
Створана аўтаматычна (запампавальнік не знойдзены)
- Плэйлісты, якія пазначаны шэрым, ужо ўтрымліваюць гэты элемент.
+ Плэйлісты, якія пазначаны шэрым, ўжо ўтрымліваюць гэты элемент.
- %s новы стрым
- %s новыя стрымы
@@ -616,8 +616,8 @@
- %s новых стрымаў
Каментарыі
- У чаргу далей
- У чарзе наступны
+ Ў чаргу далей
+ Ў чарзе наступны
Загрузка звестак аб стрыме…
Апрацоўка... Можа заняць некаторы час
Дублікат дададзены %d раз
@@ -650,7 +650,7 @@
Праверка абнаўленняў…
Выдаліць дублікаты\?
Выдаліць дублікаты
- Вы хочаце выдаліць усе паўтаральныя стрымы ў гэтым плэйлісце\?
+ Вы хочаце выдаліць ўсе паўтаральныя стрымы ў гэтым плэйлісце?
Новыя элементы стужкі
- %d выбраны
@@ -687,12 +687,12 @@
Стужка
Час пасля апошняга абнаўлення, перш чым падпіска лічыцца састарэлай — %s
Памылка загрузкі стужкі
- Уліковы запіс аўтара быў спынены.
-\nNewPipe не зможа загрузіць гэты канал у будучыні.
-\nВы хочаце адмовіцца ад падпіскі на гэты канал\?
+ Ўліковы запіс аўтара быў спынены.
+\nNewPipe не зможа загрузіць гэты канал ў будучыні.
+\nВы хочаце адмовіцца ад падпіскі на гэты канал?
Рэжым хуткай загрузкі стужкі не дае дадатковай інфармацыі аб гэтым.
Атрымлівайце са спецыяльнага канала, калі ён даступны
- Уключыць хуткі рэжым
+ Ўключыць хуткі рэжым
Катэгорыя
Тэгі
Ліцэнзія
@@ -700,7 +700,7 @@
Не ў спісе
Прыватная
,
- Пераключыць усё
+ Пераключыць ўсё
Стрымы, якія яшчэ не падтрымліваюцца загрузчыкам, не адлюстроўваюцца
Мініяцюра аватара канала
Аўтар: %s
@@ -729,7 +729,7 @@
Уліковы запіс спынены
%s дае наступную прычыну:
Рэкамендаваны
- Унутраная
+ Ўнутраная
Цалкам прагледзеў
Гэты кантэнт даступны толькі для аплачаных карыстальнікаў, таму NewPipe не можа яго трансляваць або спампоўваць.
Даступны ў некаторых службах, звычайна нашмат хутчэй, але можа вяртаць абмежаваную колькасць элементаў і часта няпоўную інфармацыю (напрыклад, без працягласці, тыпу элемента, без актыўнага стану)
@@ -739,7 +739,7 @@
Ніякая праграма на вашай прыладзе не можа адкрыць гэта
Стандартнае значэнне ExoPlayer
Часткова прагледжана
- Як вы думаеце, загрузка корму адбываецца занадта павольна\? Калі так, паспрабуйце ўключыць хуткую загрузку (гэта можна змяніць у наладах або націснуўшы кнопку ніжэй).
+ Як вы думаеце, загрузка корму адбываецца занадта павольна? Калі так, паспрабуйце ўключыць хуткую загрузку (гэта можна змяніць ў наладах або націснуўшы кнопку ніжэй).
\n
\nNewPipe прапануе дзве стратэгіі загрузкі корму:
\n• Атрыманне ўсяго канала падпіскі павольнае, але поўнае.
@@ -775,8 +775,8 @@
арыгінальны
дубляваны
апісальны
- Гукавая дарожка ўжо павінна прысутнічаць у гэтай плыні
- Уключыце гэту опцыю, калі ў вас ёсць праблемы з ініцыялізацыяй дэкодэра, якая вяртаецца да дэкодэраў з больш нізкім прыярытэтам, калі ініцыялізацыя асноўных дэкодэраў не ўдаецца. Гэта можа прывесці да нізкай прадукцыйнасці прайгравання, чым пры выкарыстанні асноўных дэкодэраў
+ Гукавая дарожка ўжо павінна прысутнічаць ў гэтай плыні
+ Ўключыце гэту опцыю, калі ў вас ёсць праблемы з ініцыялізацыяй дэкодэра, якая вяртаецца да дэкодэраў з больш нізкім прыярытэтам, калі ініцыялізацыя асноўных дэкодэраў не ўдаецца. Гэта можа прывесці да нізкай прадукцыйнасці прайгравання, чым пры выкарыстанні асноўных дэкодэраў
Кіраванне некаторымі наладамі ExoPlayer. Каб гэтыя змены ўступілі ў сілу, патрабуецца перазапуск гульца
Гэты абыходны шлях вызваляе і паўторна стварае відэакодэкі, калі адбываецца змяненне паверхні, замест таго, каб усталёўваць паверхню непасрэдна для кодэка. ExoPlayer ужо выкарыстоўваецца на некаторых прыладах з гэтай праблемай, гэты параметр мае ўплыў толькі на прыладах з Android 6 і вышэй
\n
@@ -820,7 +820,7 @@
- %1$s: %2$s
Перамясціць селектар галоўнай укладкі ўніз
Няма жывых трансляцый
- Выберыце якасць выявы і ці спампоўваць выявы ўвогуле, каб паменшыць выкарыстанне дадзеных і памяці. Змены ачышчаюць кэш малюнкаў як у памяці, так і на дыску - %s
+ Выберыце якасць выявы і ці спампоўваць выявы ўвогуле, каб паменшыць выкарыстанне дадзеных і памяці. Змены ачышчаюць кэш малюнкаў як ў памяці, так і на дыску - %s
Прайграць
Іншыя опцыі
Мініяцюры
@@ -830,4 +830,13 @@
Каналы
Папярэдні стрым
Жывая трансляцыя
+
+ - %s адказ
+ - %s адказы
+ - %s адказаў
+ - %s адказаў
+
+ Паказаць больш
+ Паказаць менш
+ Адрэдагуйце кожнае дзеянне апавяшчэння, націснуўшы на яго. Першыя тры дзеянні (прайграванне/паўза, папярэдняе і наступнае) задаюцца сістэмай і не могуць быць зменены.
\ No newline at end of file
diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml
index 11fe2c2c891..4f27d60cef3 100644
--- a/app/src/main/res/values-bn-rBD/strings.xml
+++ b/app/src/main/res/values-bn-rBD/strings.xml
@@ -297,7 +297,7 @@
থাম্বনেল ১:১ অনুপাতে সেট করো
সিস্টেম ডিফল্ট
প্লেলিস্ট বুকমার্ক করুন
- "যখন পর্যাপ্ত নিবেদিত ফিড থেকে ডাটা সংগ্রহ করুন"
+ যখন পর্যাপ্ত নিবেদিত ফিড থেকে ডাটা সংগ্রহ করুন
সবসময় হালনগাদ করুন
শেষ হালনাগাদের পর একটি সাবস্ক্রিপশনের আগের সময় সেকেলে বিবেচিত — %s
ফিড হালনাগাদ প্রবেশস্থল
@@ -317,11 +317,11 @@
চ্যানেল গ্রুপ
- %d দিন
- - "%d দিন"
+ - %d দিন
- %d ঘন্টা
- - "%d ঘন্টা"
+ - %d ঘন্টা
- %d মিনিট
diff --git a/app/src/main/res/values-bn-rIN/strings.xml b/app/src/main/res/values-bn-rIN/strings.xml
index b2eacd22a8b..cb5c0e59507 100644
--- a/app/src/main/res/values-bn-rIN/strings.xml
+++ b/app/src/main/res/values-bn-rIN/strings.xml
@@ -275,7 +275,7 @@
নিউ পাইপ ওয়েব সাইট এ যান বিস্তারিত বিবরণ ও খবর এর জন্য
১০০+ ভিডিও
- - "%s শ্রোতা"
+ - %s শ্রোতা
- %s শ্রোতা গন
বিবরণ
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index a0dbc0b36f1..6f4724f3b41 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -151,7 +151,7 @@
El fitxer no existeix o bé no teniu permisos de lectura/escriptura
El nom del fitxer no pot estar en blanc
S\'ha produït un error: %1$s
- Informeu de l\'error per correu electrònic
+ Informeu per correu electrònic
S\'han produït alguns errors.
Informe
Informació:
@@ -561,7 +561,7 @@
Mescla
Repeteix
El màxim d\'accions que poden aparèixer en una notificació compacta és de tres!
- Editeu cada acció de la notificació tocant el botó corresponent. Podeu seleccionar-ne fins a tres, que es mostraran a les notificacions en format compacte
+ Editeu cada acció de la notificació tocant el botó corresponent. Podeu seleccionar-ne fins a tres, que es mostraran a les notificacions en format compacte.
Cinquè botó d\'acció
Quart botó d\'acció
Tercer botó d\'acció
@@ -692,9 +692,26 @@
Cualitat desconeguda
Ordenar
Configura la notificació de reproducció actual.
- Canvia la mida de l\'interval de càrrega (actualment %s). Un valor inferior pot accelerar la càrrega inicial del vídeo. Els canvis requereixen un reinici del jugador.
+ Canvia la mida de l\'interval de càrrega en continguts progressius (actualment %s). Un valor inferior pot accelerar la càrrega inicial del vídeo.
Ignora els esdeveniments dels botons de reproducció físics
Útil, per exemple, si feu servir uns auriculars amb els botons físicament trencats
Trieu un gest per la part esquerra de la pantalla
Mida de l\'interval de càrrega de reproducció
+ Acció de gest esquerra
+ Editeu cada acció de notificació de sota tocant-la. Les tres primeres accions (reproduir/pausa, anterior i següent) són establertes pel sistema i no es poden personalitzar.
+ Tria un gest per a la meitat dreta del reproductor
+ Acció del gest dret
+ Brillantor
+ Volum
+ Cap
+ Mou el selector de pestanya principal a la part inferior
+ Posició de les pestanyes principals
+ Prefereix àudio descriptiu
+ Seleccioneu la pista d\'àudio original independentment de l\'idioma
+ Prefereix l\'àudio original
+ Mode ràpid
+ Carregant Metadades…
+ Seleccioneu una pista d\'àudio amb descripcions per a persones amb discapacitat visual si està disponible
+ Nous streams
+ Notificacions sobre nous streams per a subscripcions
\ No newline at end of file
diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml
index df26383a4f9..3cfa5ef7b9f 100644
--- a/app/src/main/res/values-ckb/strings.xml
+++ b/app/src/main/res/values-ckb/strings.xml
@@ -16,7 +16,7 @@
پڕۆژەی نیوپایپ زانیارییە تایبەتییەکانت بە وردی دەپارێزێت. هەروەها بهرنامهكه هیچ زانایارییەکت بەبێ ئاگاداری تۆ بەکارنابات.
\nسیاسەتی تایبەتی نیوپایپ بە وردی ڕوونکردنەوەت دەداتێ لەسەر ئەو زانیاریانەی وەریاندەگرێت و بەکاریاندەبات.
ناتوانرێت لە بیرگەی دەرەکیدا داببەزێنرێت . شوێنی فۆڵدهری دابهزاندنەکان ڕێکبخرێتەوە؟
- ئایا مەبەستت ئهمهیه \"%1$s\"؟
+ مەبەستت لە ئەمەیە ٪1$s ؟
ماوەی نوێكردنهوهی فیید
هێڵەکی
بهردهوامبوون له (بهبێ دووبارهكردنهوه) نۆبهتی کارپێکەر بهپێی پهخشی هاوشێوه
@@ -33,7 +33,7 @@
ناو
چارەسەرکردن ههرهسی هێنا
بچوکبوونەوە لەکاتی گۆڕینی بهرنامه
- فایلی ڤیدیۆ دابهزێنراوەکان لێرەدا هەڵدەگیرێن
+ فایلی ڤیدیۆ داگیراوەکان لێرەدا هەڵدەگیرێن
هەناردە کردنی مێژوو ، بەژدارییهكان ، خشتهلێدانهكان و ڕێكخستنهكان
بردنەپێشی ناتەواوی خێرا وا لە لێدەرەکە دەکات کە بەخێرایی شوێنەکە بگۆڕێت. بردنەپێشی ٥ یان ١٥ یان ٢٥ چرکەیی لەگەڵ ئەمەدا کارناکات
سکاڵاکردن لەسەر نەگەیاندنی Rx ی پەسەندنەکرا لە دەرەوەی پارچە یان چالاکی لەدوای پوختەکردن
@@ -90,7 +90,7 @@
لێدان به Kodi
ناتوانرێت لێدوانەکان باربکرێن
بەستەری دۆخ دابنێ
- فایلی دەنگە دابهزێنراوەکان لێرەدا هەڵدەگیرێن
+ فایلی دەنگە داگیراوەکان لێرەدا هەڵدەگیرێن
ببورە، هەندێك کێشە ڕوویدا.
هەناردە کردن بۆ
ڕەفتار
@@ -105,13 +105,13 @@
لادانی نیشانهكراو
مۆڵەتەکان
ناتوانرێت بهژداریكردنهكه نوێبكرێتهوه
- پاشبنەما
+ پشت شاشە
بێ ئەنجامه
زمان دەگۆڕدرێت لەدوای داگیرساندنەوەی بهرنامهكه
لادانی سەیرکراو
پیشاندانی نیشانەکەری شوێنی کارپێکەر لە خشتەکاندا
شوێنەکان لە خشتەکاندا
- بهژداریت
+ بهژداریتکرد
بەهۆی گۆڕانکاری لە شێوەی ژێرنووسکردنەکە. پێویستە بهرنامهكه دابگیرسێنیتهوه
- %d دیار کراوه
@@ -132,8 +132,8 @@
- %s بینراو
- %s بینراوان
- ڕاگرتن
- فۆڵدەری دابهزاندنی فایله دەنگییەکان هەڵبژێرە
+ وەستاندن
+ فۆڵدەری داگرتنی فایله دەنگییەکان هەڵبژێرە
نوێ
سڕینەوەی مێژووی سەیرکراو
بەردەوام بوونی کارپێکەر
@@ -158,7 +158,7 @@
لێدانی گشتی
هەمان فایل/بابەت بوونی نییە
دەستپێکردن
- بهژداری
+ بهژداریکردن
بژاردەی ”لێدان بە Kodi“ پیشانبدرێت
بهژدارییهكان
پەڕەی بەتاڵ
@@ -199,12 +199,12 @@
وێنۆچکەی سهروێنهی کەناڵ
دەتەوێت ڕێکخستنەکانیش هاوردە بكرینهوه؟
هیچ لێدەرێکی ڤیدیۆیی نهدۆزرایهوه. دهتهوێت VLC دابمەزرێنیت؟
- فۆڵدهری دابهزاندنی ڤیدیۆ
+ فۆڵدهری داگرتنی ڤیدیۆ
کردنەوەی پلیکانە
ڕووناك
ئەو پێشنیازکراوانە هەڵبژێرە کە پیشان دەدرێن لەکاتی گەڕاندا
کردارەکە ههرهسی هێنا, چونکە ئەو فایله سڕاوەتەوە
- زیادکردن بۆ
+ زیادی بکە بۆ
بهژداری نییه
دۆخی پێرتووب
خشتەلێدان سازکرا
@@ -214,7 +214,7 @@
∞ ڤیدیۆ
بەکارهێنانی بردنەپێشی ناتەواوی خێرا
هەڵەیەک ڕوویدا : %1$s
- فۆڵدهری دابهزاندن بۆ فایلی ڤیدیۆکان هەڵبژێرە
+ فۆڵدهری داگرتن بۆ فایلی ڤیدیۆکان هەڵبژێرە
ساز کراوه لەلایەن %s
بەکارهێنەران
بابەت
@@ -228,7 +228,7 @@
سیاسەتی تایبەتی نیوپایپ
دابهزاندن
ناكاراکردنی دۆخی خێرا
- كردنهوه له وێبگهر
+ ئەم بڕگەی پێڕستە ڤیدیۆیەک یان ستریمێکی دەنگی دەکاتەوە لە وێبگەڕێکدا
ڕاژەکە هیچ داتایەک نانێرێت
شوێنی کارپێکراوەکان سڕانەوە
پەیامەکانی وەشانە نوێیەکانی نیوپایپ
@@ -261,7 +261,7 @@
- %d ڕۆژان
ناولێنانهوه
- دابهزاندن
+ داگرتن
باشە
سڕینهوهی پاشماوەی مێتاداتا
ناتوانرێت ئەمه داببهزێنرێتهوه
@@ -326,7 +326,7 @@
قهبارهی بنەڕەتی
بچووککردنەوە بۆ پەنجەرە
گۆرانییەکان
- دابهزاندنی فایلی پەخش
+ داگرتنی فایلی پەخش
شێوازی پیشاندانی خشتە
زیادکردنی دۆخ
پەسەند
@@ -342,7 +342,7 @@
بابەتی پەڕەی سەرەکی
دیار کردنی بەژدارییەکان
هاوردهكردنی فایل
- فۆڵدهری دابهزاندنی دهنگ
+ فۆڵدهری داگرتنی دهنگ
ههندێك له قهبارهكان دهنگیان تێدا نامێنێتهوه
ڕووداوەکان
وێنۆچکەی کەسی بەرزکەرەوە
@@ -390,7 +390,7 @@
دەستپێکردنی لێدان لە پاشبنەماوە
ناوفایل
دانان لەسەر وێنۆچکەی خشتەلێدان
- دەربارەی نیوپایپ
+ دەربارەی NewPipe
زیادکردن بۆ خشتەلێدان
(نەزانراو)
زمانی بهرنامه
@@ -469,7 +469,7 @@
سڕینەوەی پاشماوەی هەموو ماڵپهڕهكان
بەرنامەکە نهدۆزرایهوه. دابمهزرێت؟
ناتوانرێ پشتگیری دۆخەکە بکرێ
- دامەزراندن
+ دابەزاندن
ڤیدیۆکان
بەستەرەکە پشتگیری نەکراوە
قیڕ
@@ -484,7 +484,7 @@
لەیەک کاتدا تەنیا یەک بابەت دادەبەزێنرێت
دەتەوێت بگەڕێنرێتەوە بۆ شێوازی بنەڕەتی؟
وەستاندنی دابەزاندنەکان
- دەربارە
+ دەربارە و پرسیارەکان
پیشاندانی لێدوانەکان
بۆ جێبەجێکردنی فرمانەکان لەگەڵ یاسای پاراستنی داتای گشتی ئەوروپیدا (GDPR) , ئێمە سەرنجت ڕادەکێشین بۆ سیاسەتە تایبەتییەکانی نیوپایپ. تکایە بەئاگادارییەوە بیخوێنەرهوە.
\nپێویستە پهسهندی بکەیت بۆ ناردنی سکاڵاکانت.
@@ -502,7 +502,7 @@
کاتی دوای دواین نوێکردنەوە پێش بەژداربوون ڕەچاوکراوە — %s
بیرگەی دەرەکی بەردەست نییە
گێڕانەوەی کارپێکەر بۆ شوێنی پێشووتر
- پاشگهزبوونهوه
+ هەڵوەشاندنەوه
تراکەکان
ڕێکخستنەکانی دەنگ
پرست پێ دەکرێت بۆ شوێنی دابەزاندنی هەر بابەتێک.
@@ -541,7 +541,7 @@
تێکەڵکردن
دووبارە
دەتوانیت تا سێ كردار دیار بكهیت تا پیشان بدرێن له پەیامەکەدا!
- دهستكاری ههر یهكێك لهم كردارانهی خوارهوه بكه لهڕێگهی كرته لهسهریان. دهتوانیت تا زیاتر له سێ دانهیان ههڵبژێریت له ڕێگای چوارگۆشهكانی لای ڕاستهوهیان، تا پیشان بدرێن له پەیامەکاندا
+ دەستکاریکردنی هەر کردارێکی ئاگادارکەرەوە لە خوارەوە بە دەستلێدان. ۳- دانە هەڵبژێرە لە ڕێگەی بەکارهێنانی سندوقەبچوکەکە لای ڕاستەوە نیشان دەدرێت
پێنجهم كرداری دوگمه
چوارهم كرداری دوگمه
سێیهم كرداری دوگمه
@@ -555,7 +555,7 @@
پیشاندانی زانیاری مێتا
ناكارایبكه بۆ شاردنهوهی دیسکریپشن لهسهر ڤیدیۆ و زانیاری زیاتر
پیشاندانی دیسکریپشن
- ڕووكاری شهو
+ ڕووكاری تاریک
ئهندرۆید ڕهنگی پەیام دڵخواز دهكات بهپێی ڕهنگی سهرهكی وێنۆچكهكه ( ڕهچاوی ئهوه بكه كه ئهم تایبهتمهندییه ههموو ئامێرێك ناگرێتهوه )
ڕهنگكردنی پەیام
یوتوب ”دۆخی قهدهغهكراو” پێشكهش دهكات كه بابەتە نهشیاوهكان دهشارێتهوه
@@ -582,7 +582,7 @@
\nجا دهتهوێت بهژداری لابدهیت لهم كهناڵه؟
ناتوانرێت فیید باربکرێت تا ً`%s` .
ههڵه له باركردنی فیید
- ئهم تایبهتمهندییه كارابكه گهر ڕوونمای ڕهش یاخوود جامبوونی کارپێکەرت ئهزموون كرد
+ ئەگەر تووشی شاشەی ڕەش یان لکەلکە بوویت لە کاتی پەخشکردنی ڤیدیۆدا، تونێلکردنی میدیا لەکاربخە.
ناوەکی
تایبەتی
خشتەنەکراو
@@ -665,11 +665,11 @@
لێدوانی هەڵواسراو
کڕاش کردنی لێدەر
پیشاندانی هەڵەی سناکباڕ
- هیچ ڕێکخەرێکی فایلی گونجاو نەدۆزرایەوە بۆ ئەم کردارە.
-\nتکایە ڕێکخەری فایلییەک دابمەزرێنە لۆ هەوڵدانی ناکاراکردنی \'%s\' لە ڕێکخستنەکانی دابەزاندندا.
+ هیچ FileManager پەڕگەی گونجاو بۆ ئەم کردارە نەدۆزراوەتەوە.
+\nتکایە بەڕێوەبەری پەڕگەیەک دابمەزرێنە یان هەوڵبدە \'%s\' لە Settings بڕۆ Download لەکاربخە
LeakCanary بەردەست نییە
- هیچ ڕێکخەرێکی فایلی گونجاو نەدۆزرایەوە بۆ ئەم کردارە.
-\nتکایە ڕێکخەرێکی فایلی دابمەزرێنە کە گونجاوبێت لەگەڵ دەسەڵاتی گەیشتن بە بیرگە.
+ هیچ FileManager گونجاو نەدۆزرایەوە بۆ ئەم کردارە.
+\nتکایە FileManager دابمەزرێنە کە گونجاوبێت لەگەڵ دەسەڵاتی گەیشتن بە بیرگە.
پشکنین کردن بۆ پەخشی نوێ
پەیامەکانی پەخشە نوێیەکان
پەیام بکرێم لەکاتی هەبوونی پەخشی نوێی بەژدارییەکان
@@ -694,4 +694,12 @@
لەسەدا
نیمچەتەن
بنەڕەتی ExoPlayer
+ دیاریکردنی تراکی دەنگی ئەسڵی بێ گوێدانە زمانەکە
+ دەستکاریکردنی هەر کردارێکی ئاگادارکەرەوە لە خوارەوە بە دەستلێدان. یەکەم سێ کردار (لێدان/وەستان، پێشوو و دواتر) لەلایەن سیستەمەکەوە دانراوە و ناتوانرێت دەستکاری بکرێت.
+ پەسەند کردنی دەنگی وەسفکراو
+ گۆڕینی قەبارەی ماوەی لۆد لەسەر ناوەڕۆکی پێشکەوتوو (ئێستا ٪s). بەهایەکی کەمتر لەوانەیە بارکردنی سەرەتا خێراتر بکات
+ پەسەندکردنی دەنگی ئەسڵی
+ بەسوودە، بۆ نموونە، ئەگەر هێدسێتێک بەکاربهێنیت لەگەڵ دوگمەی فیزیکی شکاو
+ قەبارەی نێوان بارکردنی پەخشکردن
+ دوگمەی ڕووداوەکانی میدیای هاردوێر بەجێبهێڵە
\ No newline at end of file
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 5c3997d4549..1a5b83e52ca 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -554,7 +554,7 @@
Promíchat
Opakovat
Do kompaktního oznámení lze vybrat nejvíce tři akce!
- Upravte každou akci oznámení níže poklepáním. Pomocí zaškrtávacích políček vpravo vyberte až tři z nich, které se mají zobrazit v kompaktním oznámení
+ Upravte každou akci oznámení níže poklepáním. Pomocí zaškrtávacích políček vpravo vyberte až tři z nich, které se mají zobrazit v kompaktním oznámení.
Páté akční tlačítko
Čtvrté akční tlačítko
Třetí akční tlačítko
@@ -819,4 +819,12 @@
Kanály
Předchozí stream
Živě
+
+ - %s odpověď
+ - %s odpovědi
+ - %s odpovědí
+
+ Zobrazit více
+ Upravte každou akci oznámení níže poklepáním. První tři akce (přehrání/pozastavení, předchozí a další) jsou nastaveny systémem a nemohou být přizpůsobeny.
+ Zobrazit méně
\ No newline at end of file
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index afde293a632..f0ffba311cf 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -4,64 +4,64 @@
Udgivet den %1$s
Ingen streamafspiller blev fundet. Installér VLC\?
Ingen streamafspiller fundet (du kan installere VLC for at afspille den).
- Installer
- Annuller
+ Installér
+ Annullér
Åbn i browser
- Åbn i pop op-tilstand
+ Åbn i popup-tilstand
Del
- Download
- Download stream-fil
+ Hent
+ Hent stream-fil
Søg
Indstillinger
Mente du \"%1$s\"\?
Del med
- Benyt ekstern videoafspiller
+ Brug ekstern videoafspiller
Fjerner lyd ved nogle opløsninger
Brug ekstern lydafspiller
- Abonner
+ Abonnér
Abonnerer
- Afmeld abonnement
- Abonnement afmeldt
+ Afmeld
+ Kanal afmeldt
Kunne ikke ændre abonnement
Kunne ikke opdatere abonnement
Vis info
Abonnementer
- Gemte spillelister
- Vælg fane
+ Gemte Playlister
+ Vælg Fane
Nyheder
Baggrund
- Pop op
+ Popup
Føj til
- Mappe til download af video
- Downloadede videoer gemmes her
- Angiv download-mappe for videofiler
- Download-mappe for lydfiler
- Downloadede lydfiler gemmes her
- Angiv download-mappe for lydfiler
+ Lagringsmappe til videoer
+ Hentede videoer gemmes her
+ Vælg lagringsmappe til videofiler
+ Lagringsmappe til lydfiler
+ Hentede lydfiler gemmes her
+ Vælg lagringsmappe til lydfiler
Standardopløsning
- Standardopløsning for pop op
+ Standardopløsning for popup
Vis højere opløsninger
Kun nogle enheder kan afspille 2K-/4K-videoer
Afspil med Kodi
- Installer manglede Kode-app\?
+ Installér manglende Kore-app?
Vis valgmuligheden \"Afspil med Kodi\"
Vis en knap til at afspille en video via Kodi-mediecenteret
Lyd
Standardformat for lydfiler
Standardformat for videofiler
Tema
- Lyst
- Mørkt
+ Lys
+ Mørk
Sort
- Husk størrelse og placering af pop op
- Husk sidste størrelse og placering af pop op-afspiller
+ Husk popup-egenskaber
+ Husk sidste størrelse og placering af popup-afspiller
Brug hurtig og upræcis søgning
Upræcis søgning lader afspilleren finde placeringer hurtigere, men mindre præcist. Søgninger på 5, 15 eller 25 sekunder fungerer ikke med denne indstilling slået til
Billedcache slettet
- Slet metadata-cachen
- Slet alle websidedata fra cachen
+ Slet metadata-cache
+ Fjern alle cached websidedata
Metadata-cache slettet
- Føj automatisk næste stream til køen
+ Føj automatisk næste stream til kø
Fortsæt en afspilningskø, der afsluttes (ikke-gentagende), ved at tilføje en lignende stream
Søgeforslag
Vælg forslagene, der vises, når der søges
@@ -71,63 +71,63 @@
Husk sete videoer
Fortsæt afspilning
Fortsæt afspilning efter afbrydelser (fx telefonopkald)
- Download
+ Hent
Vis \'Næste\' og \'Lignende\' videoer
Vis \"Hold for at sætte i kø\"-tip
- Vis et tip når der trykkes på baggrunds- eller pop op-knappen på siden med videodetaljer
- Denne webadresse er ikke understøttet
+ Vis tip, når du trykker på baggrunden eller popup-knappen i video \"Detaljer:\"
+ Ikke-understøttet URL
Standardland for indhold
Standardsprog for indhold
Afspiller
- Opførsel
+ Adfærd
Video og lyd
Historik og cache
Udseende
Fejlretning
Opdateringer
Afspiller i baggrunden
- Afspiller i pop op-tilstand
+ Afspiller i popup-tilstand
Indhold
Vis aldersbegrænset indhold
Live
- Downloads
- Downloads
+ Hentet
+ Hentet
Fejlrapport
Alle
Kanaler
- Spillelister
+ Playlister
- Én video
- %s videoer
Numre
Brugere
- Slået fra
- Slet
+ Deaktiveret
+ Ryd
Bedste opløsning
Fortryd
Fil slettet
- Afspil alle
+ Afspil Alle
Altid
- Kun én gang
+ Kun Én Gang
Fil
- NewPipe notifikation
+ NewPipe-notifikation
Notifikationer for NewPipes afspiller
Notifikation om opdatering af app
Notifikationer for nye NewPipe versioner
[Ukendt]
Skift til baggrund
- Skift til pop op
+ Skift til popup
Skift til hovedafspiller
- Importer database
- Eksporter database
+ Importér database
+ Eksportér database
Overskriver din nuværende historik, abonnementer, spillelister og (hvis det ønskes) indstillinger
- Eksporter historik, abonnementer, spillelister og indstillinger
- Slet visningshistorik
+ Eksportér historik, abonnementer, spillelister og indstillinger
+ Ryd visningshistorik
Sletter historikken over afspillede streams og afspilningspositionerne
Slet hele visningshistorikken\?
Visningshistorikken blev slettet
- Slet søgehistorik
+ Ryd søgehistorik
Sletter historikken for søgeord
Slet hele søgehistorikken\?
Søgehistorikken blev slettet
@@ -367,12 +367,12 @@
Maksimalt antal forsøg før downloaden opgives
Afbryd på forbrugsafregnede netværk
Nyttigt ved skift til mobildata, selv om nogle downloads ikke kan sættes på pause
- Kun HTTPS adresser understøttes
+ Kun HTTPS-URL\'er understøttes
Instansen findes allerede
Kunne ikke validere instansen
- Skriv instansens adresse
+ Indtast instans-URL
Tilføj instans
- Find de instanserne du kan lide på %s
+ Find de instanser, du kan lide på %s
Vælg dine yndlings PeerTube-instanser
PeerTube-instanser
Afspil automatisk
@@ -384,11 +384,11 @@
Vis kommentarer
Ingenting
Gentag
- Femte handlingstast
- Fjerde handlingstast
- Første handlingstast
- Anden handlingstast
- Tredje handlingstast
+ Femte handlingsknap
+ Fjerde handlingsknap
+ Første handlingsknap
+ Anden handlingsknap
+ Tredje handlingsknap
Viser resultater for: %s
Åbn med
LeakCanary er ikke tilgængelig
@@ -426,42 +426,42 @@
Slet alle downloadede filer fra drevet\?
Sæt downloads på pause
- Start hovedafspilleren i fuldskærmstilstand
+ Start hovedafspiller i fuld skærm
Downloadmappe endnu ikke valgt. Vælg standardmappen nu
- Læg automatisk i kø
- Konfigurer det spillende streams notifikation
- Vis aldersbegrænset indhold (f.eks. 18+)
- Slå YouTube \"begrænset tilstand\" til
- YouTube har en \"begrænset tilstand\" der skjuler videoer som potientielt er skadelige for børn
+ Sæt automatisk i kø
+ Konfigurér notifikation om igangværende stream
+ Vis indhold, der muligvis er uegnet for børn, fordi det har en aldersgrænse (f.eks. 18+)
+ Slå YouTubes \"Begrænset Tilstand\" til
+ YouTube tilbyder en \"Begrænset Tilstand\", som skjuler potentielt voksenindhold
Denne video er aldersbegrænset.
\n
-\nSlå \"%1$s\" fra i indstillingerne hvis du vil se den.
+\nSlå \"%1$s\" til i indstillingerne, hvis du vil se den.
Nye streams
Notifikationer om nye streams fra abonnementer
- reCAPTCHA cookies er ryddet
+ reCAPTCHA-cookies blev ryddet
Slet alle afspilningspositioner\?
Filen er flyttet eller slettet
NewPipe stødte ind i en fejl, tryk for at rapportere
Rapporter på GitHub
Høj kvalitet (større)
Begræns downloadkøen
- Ryd de cookies som NewPipe opbevarer når du løser en reCAPTCHA
- Farvelæg notifikationen
- Afspillernotifikation
+ Ryd de cookies, som NewPipe opbevarer, når du løser en reCAPTCHA
+ Farvelæg notifikation
+ Afspiller-notifikation
En fejl opstod, se notifikationen
Slå fra for at skjule videobeskrivelsen og yderligere information
- Slå fra for at gemme metainformationskasser med yderligere information om streammets skaber, streammets indhold eller en søgeforespørgsel
+ Slå fra for at skjule metainfo-bokse med yderligere information om streamskaberen, streamindhold eller en søgeforespørgsel
- Download fuldført
- %s downloads fuldført
- Den aktive spilleliste bliver udskiftet
- Hvis du skifter fra en spiller til en anden, kan din kø blive erstattet
- Vis metainformation
+ Den aktive afspillerkø bliver udskiftet
+ Ændring fra én afspiller til en anden kan erstatte din kø
+ Vis metainfo
Lokale søgeforslag
- Fjerne søgeforslag
- Start ikke videoer i miniafspilleren, men gå direkte til fuldskærmstilstand, hvis automatisk rotering er låst. Du kan stadig se miniafspilleren, hvis du går ud af fuldskærmstilstand
- Kunne ikke genkende addressen. Vil du åbne den i en anden app\?
+ Forslag til fjernsøgning
+ Start ikke videoer i miniafspilleren, men skift direkte til fuldskærmstilstand, hvis automatisk rotation er låst. Du kan stadig få adgang til miniafspilleren ved at forlade fuldskærm
+ Kunne ikke genkende URL. Åbn med en anden app?
Videohashfunktion notifikation
Notifikationer om videohashfunktioners status
Fejlrapport-notifikation
@@ -479,22 +479,22 @@
Kopier en formatteret rapport
Giv tilladelse til at vise over andre apps
Vis indikatorer for afspilningsposition i lister
- Afspilningspositioner slettet
- Ryd reCAPTCHA cookies
+ Afspilningspositioner blev slettet
+ Ryd reCAPTCHA-cookies
Der er en afventende download med dette navn
Start downloads
Beskær miniaturebillede til 1:1 format
Beskær video-miniaturebillede i notifikationen fra 16:9 til 1:1 format
- Rediger hver eneste varselshandling nedenunder ved at trykke på dem. Vælg op til tre af dem som bliver vist i den lille notifikation, via afkrydsningsfelterne til højre
+ Redigér hver underretningshandling nedenfor ved at trykke på dem. Vælg op til tre af dem, som bliver vist i den lille notifikation via afkrydsningsfelterne til højre.
Du kan kun vælge op til tre handlinger som kan vises i den lille notifikation!
- Buffer
+ Buffering
Få Android til at vælge notifikationens farve ud fra den primære farve i miniaturebilledet (virker ikke på alle enheder)
- Nattema
- Frem- og tilbagesøgningstid
+ Nat-tema
+ Søgningsvarighed for spole frem/tilbage
Denne video er aldersbegrænset.
-\nPga. YouTubes politik om aldersbegrænsede videoer har NewPipe ikke adgang til videoen.
+\nPga. nye YouTube-politikker om aldersbegrænsede videoer har NewPipe ikke adgang til nogen af dens videostreams og kan derfor ikke afspille dem.
Crash afspilleren
- Spørg om bekræftelse før du rydder en kø
+ Spørg om bekræftelse, før du rydder en kø
Forhåndsvisning af miniaturebilleder på statuslinjen
Sæt i kø som næste
Er sat som næste i køen
@@ -661,7 +661,7 @@
Ukendt format
Ukendt kvalitet
Hjertemarkeret af indholdsskaberen
- Intervalstørrelse for afspilningsindlæsning
+ Størrelse på afspilningsinterval
ExoPlayer-standard
Tomt gruppenavn
Du vil blive spurgt, hvor du vil gemme hver enkelt download.
@@ -713,7 +713,7 @@
Ingen lydstreams er tilgængelige for eksterne afspillere
Vælg kvalitet til eksterne afspillere
Sortér
- Ignorer hardware medie knapper
+ Ignorér hardware medie-knap begivenheder
Brugbart f.eks. hvis du bruger et headset med ødelagte fysiske knapper
Playlists der er grået ud, indeholder allerede dette objekt.
Inaktiver permanent thumbnail
@@ -721,4 +721,68 @@
Brug det originale lydspor uanset sprog
Foretræk lydbeskrivelser
Foretræk original lyd
+ Brug lydbeskrivelser for personer med nedsat syn, hvis tilgængeligt
+ Redigér hver underretningshandling nedenfor ved at trykke på dem. De første tre handlinger (afspil/sæt på pause, forrige og næste) er indstillet af systemet og kan ikke brugerdefineres.
+ Indlæser Metadata…
+ Fjern duplikater?
+ Vælg kvaliteten af billeder, og om billeder overhovedet skal indlæses, for at reducere data- og hukommelsesforbrug. Ændringer rydder både billedcachen i hukommelsen og på disken — %s
+ Middel kvalitet
+ Høj kvalitet
+ Ingen
+ Set helt
+ Ingen streams
+ Vis/skjul streams
+ Lysstyrke
+ Lydstyrke
+ Vælg bevægelse til venstre halvdel af afspillerens skærm
+ Vælg bevægelse til højre halvdel af afspillerens skærm
+ Højre bevægelseshandling
+ Ingen live streams
+ Lyd: %s
+ Lydspor
+ Fjern duplikater
+ Vis følgende streams
+ Hent kanal-faner
+ Faner, der skal hentes, når feedet opdateres. Denne indstilling har ingen effekt, hvis en kanal opdateres i hurtig tilstand.
+ Miniaturebilleder
+ Vælg lydspor til eksterne afspillere
+ Ukendt
+ Delvist set
+ Kommende
+ original
+ Videoer
+ Numre
+ Live
+ Kanaler
+ Playlister
+ Album
+ Om
+ Kanal-faner
+ Hvilke faner vises på kanalsiderne
+ Åbn afspilningskø
+ Skift til fuld skærm
+ Skift skærmretning
+ Forrige stream
+ Næste stream
+ Afspil
+ Afspil igen
+ Varighed
+ Spol tilbage
+ Billedkvalitet
+ Indlæs ikke billeder
+ Lav kvalitet
+ Del playliste
+ Del playliste med detajler såsom playliste navn og videotitler eller som en simpel liste over video-URL\'er
+ Del med Titler
+ Del URL-liste
+
+ - %s svar
+ - %s svar
+
+ Vis mere
+ Vis mindre
+ Skift intervalstørrelsen for indlæsning af progressivt indhold (i øjeblikket %s). En lavere værdi kan fremskynde den første indlæsning
+ Ønsker du at fjerne alle duplikerede streams i denne playliste?
+ Spol frem
+ Venstre bevægelseshandling
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 5260287c1bc..7fd1d4fed97 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -104,7 +104,7 @@
Letzte Größe und Position des Pop-ups merken
Suchvorschläge
Vorschläge auswählen, die bei der Suche angezeigt werden sollen
- Löschen
+ löschen
Beste Auflösung
Über NewPipe
Lizenzen
@@ -425,7 +425,7 @@
Niemand schaut zu
- %s Zuschauer
- - %s Zuschauer
+ - %s Zuschauende
Niemand hört zu
@@ -541,7 +541,7 @@
Nur über WLAN
Nie
Du kannst maximal drei Aktionen auswählen, die in der Kompaktbenachrichtigung angezeigt werden sollen!
- Bearbeite jede Benachrichtigungsaktion unten, indem du darauf tippst. Wähle mithilfe der Kontrollkästchen rechts bis zu drei aus, die in der Kompaktbenachrichtigung angezeigt werden sollen
+ Bearbeite jede Benachrichtigungsaktion unten, indem du auf sie tippst. Wähle mithilfe der Kontrollkästchen rechts bis zu drei aus, die in der Kompaktbenachrichtigung angezeigt werden sollen.
Konnte die angegebene URL nicht erkennen. Mit einer anderen Anwendung öffnen\?
Fünfte Aktionstaste
Vierte Aktionstaste
@@ -806,4 +806,11 @@
Wiedergabeliste teilen
Teile die Wiedergabeliste mit Details wie dem Namen der Wiedergabeliste und den Videotiteln oder als einfache Liste von Video-URLs
- %1$s: %2$s
+
+ - %s Antwort
+ - %s Antworten
+
+ Mehr zeigen
+ Weniger zeigen
+ Bearbeite jede Benachrichtigungsaktion unten, indem du auf sie tippst. Die ersten drei Aktionen (Abspielen/Pause, Zurück und Weiter) sind vom System vorgegeben und können nicht angepasst werden.
\ No newline at end of file
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index c2ab656fe27..881f91b78a2 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -482,7 +482,7 @@
Ανάμιξη
Επανάληψη
Μπορείτε να επιλέξετε το πολύ τρεις ενέργειες για εμφάνιση στη σύντομη ειδοποίηση!
- Επεξεργαστείτε κάθε ενέργεια ειδοποίησης παρακάτω πατώντας πάνω της. Επιλέξτε έως και τρεις από αυτές για να εμφανίζονται στη σύντομη ειδοποίηση, χρησιμοποιώντας τα πλαίσια ελέγχου στα δεξιά
+ Επεξεργαστείτε κάθε ενέργεια ειδοποίησης παρακάτω πατώντας πάνω της. Επιλέξτε έως και τρεις από αυτές για να εμφανίζονται στη σύντομη ειδοποίηση, χρησιμοποιώντας τα πλαίσια ελέγχου στα δεξιά.
Κουμπί πέμπτης ενέργειας
Κουμπί τέταρτης ενέργειας
Κουμπί τρίτης ενέργειας
@@ -595,7 +595,7 @@
Αυτόματο (θέμα συσκευής)
Νυχτερινό θέμα
Εμφάνιση λεπτομερειών καναλιού
- Απενεργοποιήστε το media tunneling, αν εμφανίζεται μαύρη οθόνη ή διακοπτόμενος ήχος κατά την αναπαραγωγή βίντεο
+ Απενεργοποιήστε το media tunneling, αν παρατηρείτε μαύρη οθόνη ή διακοπές κατά την αναπαραγωγή βίντεο.
Απενεργοποίηση media tunneling
Εσωτερικό
Ιδιωτικό
@@ -767,7 +767,7 @@
Συνδρομητές
Ποιες καρτέλες εμφανίζονται στις σελίδες των καναλιών
Καρτέλες καναλιών
- Shorts
+ Σύντομα
Λήψη καρτελών καναλιών
Σχετικά
Άλμπουμ
@@ -806,4 +806,11 @@
Κοινοποίηση λίστας
Μοιραστείτε τη λίστα αναπαραγωγής με λεπτομέρειες όπως το όνομα της λίστας αναπαραγωγής και τους τίτλους βίντεο ή ως μια απλή λίστα διευθύνσεων URL βίντεο
- %1$s: %2$s
+
+ - %s απάντηση
+ - %s απαντήσεις
+
+ Εμφάνιση περισσοτέρων
+ Εμφάνιση λιγότερων
+ Επεξεργαστείτε κάθε ενέργεια ειδοποίησης παρακάτω πατώντας σε αυτήν. Οι τρεις πρώτες ενέργειες (αναπαραγωγή/παύση, προηγούμενηο και επόμενο) ορίζονται από το σύστημα και δεν μπορούν να τροποποιηθούν.
\ No newline at end of file
diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml
index 44e3348ca90..90f5fd2ecac 100644
--- a/app/src/main/res/values-eo/strings.xml
+++ b/app/src/main/res/values-eo/strings.xml
@@ -610,4 +610,5 @@
Rilatajn erojn
Solvi
Malsukcesis kopii al la tondujo
+ Oni petos al vi kien salvi ĉiujn elŝutojn
\ No newline at end of file
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 499610d9b8e..2da61b8d560 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -47,7 +47,7 @@
Miniatura del avatar del usuario
Contenido
Mostrar contenido con restricción de edad
- Pulsa la lupa para empezar.
+ Toca la lupa para empezar.
En directo
Descargas
Descargas
@@ -558,7 +558,7 @@
Almacenar en memoria (búfer)
Repetir
¡Puedes seleccionar como máximo tres acciones para mostrar en la notificación compacta!
- Edite cada una de las acciones de notificación que aparecen a continuación pulsando sobre ellas. Seleccione hasta tres de ellas para que se muestren en la notificación compacta utilizando las casillas de verificación de la derecha
+ Edite cada acción de notificación pulsando sobre ella. Seleccione hasta tres de ellas para que se muestren en la notificación compacta utilizando las casillas de verificación de la derecha.
Botón de quinta acción
Botón de cuarta acción
Botón de tercera acción
@@ -822,4 +822,12 @@
Compartir la lista de reproducción
Compartir las listas de reproducción con los detalles como el nombre de la lista y los títulos de los vídeos o como una simple lista de una dirección URL con los vídeos
- %1$s: %2$s
+
+ - %s respuesta
+ - %s respuestas
+ - %s respuestas
+
+ Ver más
+ Mostrar menos
+ Edite cada acción de notificación pulsando sobre ella. Las tres primeras acciones (reproducir/pausa, anterior y siguiente) las establece el sistema y no se pueden personalizar.
\ No newline at end of file
diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml
index fd84e5d454e..1a9c5daacb2 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -411,7 +411,7 @@
Aja segi
Korda
Sa saad valida kuni kolm tegevust, mida kuvatakse lühiteavituses!
- Muuda iga teavituse tegevusi sellel toksates. Vali märkekastides paremal kuni kolm teavitust, mida kuvada lühiteates
+ Muuda iga teavituse tegevusi sellel toksates. Vali märkekastides paremal kuni kolm teavitust, mida kuvada lühiteates.
Viies tegevusnupp
Neljas tegevusnupp
Kolmas tegevusnupp
@@ -806,4 +806,11 @@
Jaga esitusloendit
Jaga esitusloendit kas väga detailse teabega palade kohta või lihtsa url\'ide loendina
- %1$s: %2$s
+ Näita veel
+
+ - %s vastus
+ - %s vastust
+
+ Näita vähem
+ Muuda iga teavituse tegevust sellel toksates. Kolm esimest tegevust (esita/peata esitus, eelmine video, järgmine video) on süsteemsed ja neid ei saa muuta.
\ No newline at end of file
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 958c82d07e0..a8ee1093e5e 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -789,7 +789,14 @@
Kanavat
Olet nyt tilannut tämän kanavan
Edellinen stream
-
+ Live
Haluatko poistaa kaikki ylimääräiset identtiset suoratoistot tästä soittolistasta\?
Suoratoistot, joita lataaja ei vielä tue, ei näytetä
+
+ - %s vastaus
+ - %s vastausta
+
+ Näytä lisää
+ Näytä vähemmän
+ Kanavan välilehdet
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 738f9f58fbb..81ab11b884c 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -557,7 +557,7 @@
Lire aléatoirement
Répéter
Vous pouvez sélectionner au maximum trois actions à faire figurer dans la notification compacte !
- Modifiez chaque action de notification ci-dessous en appuyant dessus. Sélectionnez jusqu’à trois d’entre elles pour les faire apparaitre dans la notification compacte en utilisant les cases à cocher à droite
+ Modifiez chaque action de notification ci-dessous en appuyant dessus. Sélectionnez jusqu’à trois d’entre elles pour les faire apparaître dans la notification compacte en utilisant les cases à cocher à droite.
Cinquième bouton d’action
Quatrième bouton d’action
Troisième bouton d’action
@@ -821,4 +821,12 @@
Avatars du téléverseur
Sélectionnez la qualité des images et si les images doivent être chargées, pour réduire l\'utilisation de la mémoire et de données. Les modifications vident à la fois le cache des images en mémoire et sur le disque — %s
Lire
+
+ - %s réponse
+ - %s réponses
+ - %s réponses
+
+ Modifiez chaque action de notification ci-dessous en appuyant dessus. Les trois premières actions (lire/pause, précédent, suivant) sont définies par le système et ne peuvent pas être personnalisées.
+ Afficher plus
+ Afficher moins
\ No newline at end of file
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index 729db00b61f..5357e38fd39 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -564,7 +564,7 @@
ערבוב
חזרה
ניתן לבחור עד שלוש פעולות בלבד שתופענה בהתראות המצומצמות!
- ניתן לערוך כל התראה להלן בלחיצה עליה. מותר לבחור עד שלוש מהן שתופענה בהתראה המצומצמת באמצעות תיבות הסימן שמשמאל
+ ניתן לערוך כל התראה להלן בלחיצה עליה. מותר לבחור עד שלוש מהן שתופענה בהתראה המצומצמת באמצעות תיבות הסימן שמשמאל.
כפתור פעולה חמישי
כפתור פעולה רביעי
כפתור פעולה שלישי
@@ -832,4 +832,12 @@
שיתוף רשימת נגינה
שיתוף רשימת נגינה עם פרטים כגון שם רשימת נגינה וכותרות סרטונים או כרשימה פשוטה של כתובות סרטונים
- %1$s: %2$s
+ להציג עוד
+ להציג פחות
+
+ - תשובה %s
+ - %s תשובות
+ - %s תשובות
+
+ אפשר לערוך כל פעולה בהתראה להלן על ידי נגיעה בה. שלוש הפעולות הראשונות (נגינה/השהיה, הקודם והבא) מוגדרות על ידי המערכת ונעולות לעריכה.
\ No newline at end of file
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index 9111f94448e..d155fab9507 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -200,7 +200,7 @@
इतिहास, सब्सक्रिप्शन, प्लेलिस्ट और सेटिंग निर्यात करें
बाहरी प्लेयर्स इन प्रकार के लिंक सपोर्ट नहीं करते
कोई वीडियो स्ट्रीम नहीं मिला
- कोई ऑडियो स्ट्रीम नहीं मिली
+ कोई ऑडियो स्ट्रीम नहीं मिला
फिर से क्रम देने के लिए खींचें
बनाइये
ख़ारिज करें
@@ -471,7 +471,7 @@
शफल करें
दोहराएं
आप कंपैकट नोटीफिकेशन में दिखाए जाने वाले विकल्प में से अधिकतम 3 को चुन सकते है !
- नीचे दी गई प्रत्येक नोटीफिकेशन क्रिया को उस पर टैप करके संपादित करें। दाईं ओर चेकबॉक्स का उपयोग करके उनमें से अधिकतम तीन का चयन करें जिन्हें कंपैकट नोटीफिकेशन में दिखाया जाना है
+ नीचे दी गई प्रत्येक नोटीफिकेशन क्रिया को उस पर टैप करके संपादित करें। दाईं ओर चेकबॉक्स का उपयोग करके उनमें से अधिकतम तीन का चयन करें जिन्हें कंपैकट नोटीफिकेशन में दिखाया जाना है।
पांचवा एक्शन बटन
चतुर्थी एक्शन बटन
तृतीय एक्शन बटन
@@ -628,7 +628,7 @@
सैमीटोन
- डाउनलोड संपूर्ण
- - %s डाउनलोडस संपूर्ण
+ - %s डाउनलोड संपूर्ण
- %d दिन
@@ -806,4 +806,11 @@
प्लेलिस्ट साझा करें
प्लेलिस्ट को प्लेलिस्ट नाम और वीडियो शीर्षक जैसे विवरण के साथ या वीडियो यूआरएल की एक सरल सूची के रूप में साझा करें
- %1$s: %2$s
+
+ - %s जवाब
+ - %s जवाब
+
+ और दिखाओ
+ नीचे दी गई प्रत्येक अधिसूचना कार्रवाई पर टैप करके उसे संपादित करें। पहली तीन क्रियाएँ (चलाएँ/रोकें, पिछली और अगली) सिस्टम द्वारा निर्धारित की जाती हैं और इन्हें अनुकूलित नहीं किया जा सकता है।
+ कम दिखाएं
\ No newline at end of file
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 13535994ab3..330ae2d5caf 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -15,7 +15,7 @@
Dijeli s
Koristi vanjski video player
Uklanja audiosnimku pri nekim rezolucijama
- Koristi vanjski audio player
+ Koristi eksterni audio player
Pretplati se
Pretplaćeno
Pretplata na kanal otkazana
@@ -36,7 +36,7 @@
Prikaži veće rezolucije
Samo neki uređaji podržavaju reprodukciju 2K/4K videa
Reproduciraj s Kodijem
- Instalirati nedostajući Kode program\?
+ Instalirati nedostajuću Kore aplikaciju?
Prikaži opciju „Reproduciraj pomoću Kodija”
Prikaži opciju za reproduciranje videozapisa putem Kodija
Audiosnimka
@@ -56,7 +56,7 @@
Prati gledana videa
Nastavi reprodukciju
Nastavi reproducirati nakon prekidanja (npr. telefonski pozivi)
- Preuzmi
+ Preuzimanje
Prikaži videa „Sljedeći” i „Slični”
URL nije podržan
Zadani jezik sadržaja
@@ -69,7 +69,7 @@
Uživo
Preuzimanja
Preuzimanja
- Prijavi grešku
+ Izvještaj o grešci
Sve
Isključeno
Očisti
@@ -80,14 +80,14 @@
Nije bilo moguće obraditi stranicu
Sadržaj nije dostupan
Nije bilo moguće postaviti izbornik za preuzimanje
- Program/korisničko sučelje su preknuli raditi
+ Aplikacija/korisničko sučelje su preknuli raditi
Oprosti, ovo se nije trebalo dogoditi.
- Prijavi pogrešku putem e-maila
+ Prijavi putem e-maila
Žao nam je, došlo je do neke greške.
Prijavi
Informacije:
Što se dogodilo:
- Što:\\nZahtjev:\\nJezik sadržaja:\\nZemlja sadržaja:\\nJezik programa:\\nUsluga:\\nGMT vrijeme:\\nPaket:\\nVerzija:\\nVerzija OS-a:
+ Što:\\nZahtjev:\\nJezik sadržaja:\\nZemlja sadržaja:\\nJezik aplikacije:\\nUsluga:\\nGMT vrijeme:\\nPaket:\\nVerzija:\\nVerzija OS-a:
Tvoj komentar (na engleskom):
Detalji:
Pokreni video, trajanje:
@@ -128,7 +128,7 @@
© %1$s od %2$s pod %3$s
O aplikaciji i ČPP
Licence
- Slobodan i mali YouTube program za Android.
+ Slobodan i mali streaming na Android uređaju.
Pogledaj na GitHubu
NewPipe licenca
Ako imate ideja za prijevod, promjene u dizajnu, čišćenje koda ili neke veće promjene u kodu, pomoć je uvijek dobro došla. Što više radimo, to bolji postajemo!
@@ -181,8 +181,8 @@
Novi i popularni
Ukloni
Detalji
- Postavke za audiosnimke
- Drži pritisnuto za dodavanje u popis izvođenja
+ Postavke za audio snimke
+ Drži pritisnuto za dodavanje u popis
[Nepoznato]
Doniraj
Web-stranica
@@ -212,7 +212,7 @@
Ispuni
Zumiraj
Automatski generirani
- Praćenje curenja memorije može uzrokovati greške u radu programa prilikom odlaganje gomile
+ Praćenje curenja memorije može uzrokovati greške u radu aplikacije prilikom odlaganje gomile
Izvijesti o krajevima životnog ciklusa
Prikaži informacije
Zabilježene playliste
@@ -302,12 +302,12 @@
Datoteka obrisana
Obavijest za nove NewPipe verzije
Briše povijest ključnih riječi pretraživanja
- Vanjska pohrana nije dostupna
+ Eksterna memorija nije dostupna
Aktualiziranja
- Prikaži obavijest i zatraži aktualiziranje programa kad je dostupna nova verzija
+ Prikaži obavijest za aktualiziranje aplikacije kad je dostupna nova verzija
Popis
- Popločeno
- Dostupna je nova verzija za NewPipe!
+ Mreža
+ Dostupna je nova NewPipe verzija!
Preuzimanje nije uspjelo
Prikaži pogrešku
Izbriši sve podatke web-stranica iz predmemorije
@@ -316,9 +316,9 @@
Nastavi završavati (ne ponavljajući) popis reprodukcija dodavanjem povezanog streama
Zadana zemlja sadržaja
Otkrivanje grešaka
- Obavijest o novoj verziji programa
- Preuzimanje na vanjsku SD karticu nije moguće. Ponovo postaviti lokaciju mape za preuzimanje\?
- Vanjski playeri ne podržavaju ove vrste poveznica
+ Obavijest o novoj verziji aplikacije
+ Preuzimanje na eksternu SD karticu nije moguće. Ponovo postaviti lokaciju mape za preuzimanje?
+ Eksterni playeri ne podržavaju ove vrste poveznica
Nije pronađen nijedan videozapis
Nije pronađena nijedna audiosnimka
Nema takve datoteke/izvora sadržaja
@@ -328,13 +328,13 @@
Obnovi standardne vrijednosti
Želiš li obnoviti standardne vrijednosti\?
Broj pretplatnika nije dostupan
- NewPipe razvijaju volonteri koji provode vrijeme kako bi doprinijeli najboljem iskustvu. Doprinesi programerima kako bi poboljšali NewPipe dok uživaju u šalici kave.
+ NewPipe razvijaju volonteri koji provode vrijeme kako bi doprinijeli najboljem korisničkom iskustvu. Doprinesi programerima kako bi poboljšali NewPipe dok uživaju u šalici kave.
Koje su kartice prikazane na glavnoj stranici
Konferencije
Željena radnja za otvaranje
Zadana radnja pri otvaranju sadržaja — %s
Titlovi
- Promijeni veličinu podnaslova i pozadinske stilove playera. Zahtijeva ponovno pokretanje programa
+ Promijeni veličinu titlova i stilove pozadine playera. Zahtijeva ponovno pokretanje aplikacije
Prisilno izvijesti o neisporučivim Rx iznimaka izvan fragmenta ili životnog ciklusa aktivnosti nakon odlaganja
Uvezi SoundCloud profil upisom URL-a ili svog ID-a:
\n
@@ -345,8 +345,8 @@
Brzina
Visina tona
Odspoji (može prouzročiti izobličenje)
- Smanji prilikom mijenjanje programa
- Radnja prilikom prebacivanja na drugi program iz glavnog video playera – %s
+ Smanji prilikom mijenjanje aplikacije
+ Radnja prilikom prebacivanja na drugu aplikaciju iz glavnog video playera – %s
Smanji na pozadinski player
Smanji na skočni player
Način prikaza kao popis
@@ -356,7 +356,7 @@
pauzirano
stavljeno u popis izvođenja
naknadna obrada
- Popis izvođenja
+ Dodaj u popis
Sustav je odbio radnju
Generiraj jedinstveni naziv
Prepiši
@@ -384,8 +384,8 @@
Nije bilo moguće učitati komentare
Zatvori
NewPipe je copyleft libre softver: Može se koristiti, proučavati i poboljšavati po volji. Konkretno, može se redistribuirati i / ili modificirati pod uvjetima GNU opće javne licence koju je objavila zaklada Free Software Foundation, pod verzijom 3 licence, ili (po vlastitom izboru) bilo koje kasnije verzije.
- Projekt NewPipe ozbiljno shvaća tvou privatnost. Stoga program ne prikuplja nikakve podatke bez tvog pristanka.
-\nNewPipe pravila o privatnosti detaljno objašnjavaju koji se podaci šalju i spremaju kad šalješ izvještaje o prekidu rada programa.
+ Projekt NewPipe ozbiljno shvaća temu o privatnosti. Stoga aplikacija ne prikuplja podatke bez tvog pristanka.
+\nNewPipe pravila o privatnosti detaljno objašnjavaju koji se podaci šalju i spremaju kad šalješ izvještaje o prekidu rada aplikacije.
Kako bismo se uskladili s Europskom općom uredbom o zaštiti podataka (GDPR), ovime upozoravamo na NewPipe politiku privatnosti. Pažljivo je pročitaj.
\nZa slanje izvješća o pogreškama moraš prihvatiti politiku privatnosti.
Nastavi reprodukciju
@@ -406,7 +406,7 @@
Izbrisati sve pozicije reprodukcije\?
Nitko ne gleda
Nitko ne sluša
- Jezik će se promijeniti nakon ponovnog pokretanja programa
+ Jezik će se promijeniti nakon ponovnog pokretanja aplikcije
Standardni kiosk
Podržani su samo HTTP URL-ovi
Lokalni
@@ -414,8 +414,8 @@
Automatski generirano (prenositelj nedefiniran)
Očisti povijest preuzimanja
Izbriši preuzete datoteke
- Dopusti prikaz iznad drugih programa
- Jezik programa
+ Dopusti prikaz preko drugih aplikacija
+ Jezik aplikacije
Zadani sustav
Videa
Isključi zvuk
@@ -424,8 +424,8 @@
Želiš li izbrisati ovu grupu\?
Nova
Uvijek aktualiziraj
- Omogući brz način
- Onemogući brz način
+ Uključi brzi način
+ Isključi brzi način
Memorija uređaja je popunjena
Najomiljeniji
Pritisni „Gotovo” kad je riješeno
@@ -433,13 +433,13 @@
∞ videa
Više od 100 videa
Prijavi grešku na GitHub-u
- Umjetnici
+ Izvođači
Albumi
Pjesme
Stvoren od %s
Nikada
Ograniči popis preuzimanja
- Koristi birač mapa sustava (SAF)
+ Koristi sustavksi birač mapa (SAF)
Ukloni pregledano
Ukloni pogledana videa\?
@@ -471,12 +471,12 @@
Gumb druge radnje
Gumb prve radnje
Prikazuju se rezultati za: %s
- Nije bilo moguće prepoznati URL. Želiš li otvoriti s drugim programom\?
+ Nije bilo moguće prepoznati URL. Otvoriti s jednom drugom aplikacijom?
Odreži sličicu na omjer 1:1
Učitavanje u predmemoriju
Istovremeno se pokreće jedno preuzimanje
Dodano u popis izvođenja
- Dodaj u popis izvođenja
+ Dodaj u popis
Reproduciraj popis izvođenja
Automatski popis izvođenja
Popis izvođenja aktivnog playera će se zamijeniti
@@ -509,7 +509,7 @@
Da, i djelomično pogledana videa
Odaberi jednu instancu
Aplikacija će te pitati kamo spremati preuzimanja.
-\nOmogući birač mapa sustava (SAF), ako želiš preuzimati na vanjsku SD karticu
+\nUključi sustavksi birač mapa (SAF) ako želiš preuzeti na eksternu SD karticu
Nije moguće obnoviti ovo preuzimanje
Napredak je izgubljen, jer je datoteka izbrisana
NewPipe se zatvorio tijekom rada s datotekom
@@ -550,7 +550,7 @@
Promiješaj
Ponovi
Provjeri je li problem već postoji. Prijavljivanje istog već prijavljenog problema krade nam vrijeme koje bismo mogli utrošiti na ispravljanje greške.
- Za uređivanje radnji u obavijestima, dodirni ih. Označi do tri radnje za prikaz u kompaktnoj obavijesti koristeći oznake na desnoj strani
+ Uredi radnje obavijesti dodirom. Označi do tri radnje za prikaz u kompaktnoj obavijesti koristeći potvrdna polja na desnoj strani.
Zbog ograničenja ExoPlayera, trajanje premotavanja postavljeno je na %d s
Neka Android prilagodi boju obavijesti prema glavnoj boji sličice (ovo nije dostupno na svim uređajima)
Oboji obavijest
@@ -560,7 +560,7 @@
Koristi sličicu za pozadinu zaključanog ekrana i za obavijesti
Prikaži sličicu
Prikaži izvorno vrijeme stavki
- „Storage Access Framework” omogućuje preuzimanje na SD karticu
+ „Storage Access Framework” dozvoljava preuzimanje na eksternu SD karticu
Izvorni tekstovi usluga bit će vidljivi u stavkama prijenosa
Dostupno je u nekim uslugama. Obično je puno brže, ali može dohvatiti ograničenu količinu stavki i često nepotpune podatke (npr. bez trajanja, vrste stavke, bez stanja uživo)
Misliš da je učitavanje feeda presporo\? Ako da, pokušaj omogućiti brzo učitavanje (možeš ga promijeniti u postavkama ili pritiskom na donji gumb).
@@ -581,7 +581,7 @@
Isključi za skrivanje polja metapodataka s dodatnim podacima o autoru streama, sadržaju streama ili zahtjevu za pretraživanje
Prikaži metapodatke
Povezane stavke
- Nijedan program na tvom uređaju ovo ne može otvoriti
+ Nijedna aplikacija na tvom uređaju ovo ne može otvoriti
Poglavlja
Opis
Komentari
@@ -601,12 +601,12 @@
Ovaj je video dostupan samo za „YouTube Music Premium” članove, stoga ga NewPipe ne može emitirati ili preuzeti.
Ovaj sadržaj je privatan, stoga ga NewPipe ne može emitirati ili preuzeti.
Ovaj sadržaj nije dostupan u tvojoj zemlji.
- Prekini program
+ Prekini aplikaciju
Riješi
- Noćna tema
+ Tamna tema
Prikaži detalje kanala
Isključi tuneliranje medija ako doživiš crni ekran ili isprekidanu reprodukciju videa.
- Iskljuci medija tuneling
+ Isključi tuneliranje medija
Isklj.
Uklj.
Način rada na tabletu
@@ -615,14 +615,14 @@
Privatno
Nenavedeno
Javno
- Poslužitelj
+ Računalo
Podrška
Jezik
Dobna granica
Licenca
Oznake
Kategorija
- Onemogući biranje teksta u opisu
+ Isključi biranje teksta u opisu
Omogući biranje teksta u opisu
Račun ukinut
Autorov račun je ukinut.
@@ -637,7 +637,7 @@
Visoka kvaliteta (veća)
Pregled sličica premotavanja
Mapa za preuzimanje još nije postavljena, odaberi standardnu mapu za preuzimanje
- Komentari su onemogućeni
+ Komentari su isključeni
Označi kao pogledano
Način rada brzog feeda ne pruža više informacija o ovome.
Interno
@@ -646,15 +646,15 @@
%s pruža ovaj razlog:
Obrada u tijeku … Može malo potrajati
Za ukljanjanje stavki povuci ih
- Prikazati indikatore slike
+ Prikaži indikatore slike
- Preuzimanje je gotovo
- %s preuzimanja su gotova
- %s preuzimanja su gotova
Pokreni glavni player u cjeloekranskom prikazu
- Reproduciraj sljedeći
- Sljedeći u popisu izvođenja
+ Dodaj u popis kao sljedeći
+ Dodano 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 memoriju
- Izbrisano %1$s preuzimanje
@@ -680,7 +680,7 @@
Novi videozapisi
Obavijesti novih streamova od pretplaćenih kanala
Želiš li izbrisati sve preuzete datoteke\?
- Obavijesti su onemogućene
+ Obavijesti su isljučene
Pretplatio/la si se na ovaj kanal
,
Uključi/isključi sve
@@ -695,16 +695,16 @@
Potrebna mrežna veza
Primaj obavijesti
Za ovu radnju nije pronađen odgovarajući upravljač datoteka.
-\nInstaliraj upravljač datoteka ili pokušaj onemogućiti „%s” u postavkama preuzimanja
+\nInstaliraj upravljač datoteka ili pokušaj isključiti „%s” u postavkama preuzimanja
Prikvačeni komentar
Prikazuje opciju prekida rada kad se player koristi
Prikaži „Prekini rad playera”
ExoPlayer standard
Posto
Poluton
- Streamovi koje program za preuzimanje još ne podržava se ne prikazuju
- Vanjski playeri ne podržavaju odabrani stream
- Promijeni veličinu intervala učitavanja (trenutačno %s). Niža vrijednost može ubrzati početno učitavanje videa. Promjene zahtijevaju ponovno pokretanje playera
+ Streamovi koje aplikacija za preuzimanje još ne podržava se ne prikazuju
+ Eksterni playeri ne podržavaju odabrani stream
+ Promijenite veličinu intervala učitavanja progresivnog sadržaja (trenutno %s). Niža vrijednost može ubrzati učitavanje
- %s novi stream
- %s nova streama
@@ -713,9 +713,112 @@
Veličina intervala učitavanja reprodukcije
Nepoznat format
Nepoznata kvaliteta
- Nijedan stream audiosnimaka nije dostupan za vanjske playere
- Nijedan video stream nije dostupan za vanjske playere
- Odaberi kvalitetu za vanjske playere
+ Nema audio prijenosa za eksterne playere
+ Nema video prijenosa za eksterne playere
+ Odaberi kvalitetu za eksterne playere
Za ovu radnju nije pronađen odgovrajući upravljač datoteka.
\nInstaliraj „Storage Access Framework” kompatibilni upravljač datoteka
+ Uredite neke ExoPlayer postavke. Ove promjene zahtjevaju ponovo pokretanje aplikacije
+ Desna gesta
+ Odaberite gestu za lijevu polovicu zaslona
+ Lijeva gesta
+ Svjetlina
+ ExoPlayer postavke
+ Uredite svaku radnju obavijesti ispod tako da je dodirnete. Prve tri akcije (reprodukcija/pauza, prethodna i sljedeća) postavlja sustav i ne mogu se prilagoditi.
+ Odaberite gestu za desnu polovicu zaslona
+ Glasnoća
+ Ništa
+ Pregledano
+ Djelomično pregledano
+ Najava
+ Razvrstaj
+ Koristi razervnu funkciju ExoPlayer dekodera
+ Ignoriranje hardverskih medijskih gumba
+ Korisno, na primjer, ako koristite slušalice s pokvarenim fizičkim gumbima
+ Odaberite zvučni zapis s opisima za slabovidne osobe ako je dostupan
+ Preferiraj originalni zvuk
+ Odaberite izvorni audio zapis bez obzira na jezik
+ Preferirajte opisni zvuk
+ Odaberi audio snimku za eksterne playere
+ Nepoznato
+ %1$s %2$s
+ Nema prijenosa
+ Položaj glavnih kartica
+ Premjesti glavni birač kartica dolje
+ Nema prijenosa uživo
+ Neuspjelo kopiranje u međuspremnik
+ Često postavljena pitanja
+ Ako imaš problema s korištenjem aplikacije, pogledaj odgovore na česta pitanja!
+ Pogledaj na web stranici
+ Audio snimka: %s
+ Traka audio snimke
+ Zasivljene playliste već sadrže ovu stavku.
+ Poništi stalni prikaz sličica
+ Duplikat je dodan %d put(a)
+ Kartica
+ Koristiš najnoviju NewPipe verziju
+ Dodirani za preuzimanje %s
+ Ukloni duplikate
+ Ukloniti duplikate?
+ Želiš li ukloniti sve duple prijenose iz ove playliste?
+ Pokaži sljedeće prijenose
+ Pokaži/Sakrij prijenose
+ Kartice za dohvaćanja kanala
+ Ova je opcija dostupna samo ako je %s odabrano za temu
+ Minijature
+ Avatari
+ Avatari prenositelja
+ Avatari podkanala
+ Pretplatnici
+ Natpisi
+ Audio zapis bi već trebao biti prisutan u ovom prijenosu
+ original
+ Uživo
+ Videa
+ Snimke
+ Kratka videa
+ sinkronizirano
+ opisno
+ Albumi
+ Kanali
+ Playliste
+ Kartice koje se prikazuju na stranici kanala
+ Uključi/Isključi položaj ekrana
+ Informacije
+ Kartice kanala
+ Uključi cjeloekranski prikaz
+ Prethodni prijenos
+ Sljedeći prijenos
+ Reproduciraj ponovo
+ Natrag
+ Naprijed
+ Kvaliteta slike
+ Više opcija
+ Odaberi kvalitetu slika i da li uopće učitati slike kako bi se smanjilo korištenje podataka i memorije. Promjene brišu predmemoriju slika u memoriji i na disku – %s
+ Ne učitavaj slike
+ Niska kvaliteta
+ Srednja kvaliteta
+ Visoka kvaliteta
+ \?
+ Dijeli playlistu s detaljima kao što su ime playliste i naslovi videa ili kao jednostavan popis URL-ova videa
+ Dijeli s naslovima
+ Dijeli popis URL-ova
+ – %1$s: %2$s
+ Pokaži više
+ Pokaži manje
+ Brzi modus
+ Učitavanje metapodataka …
+ Trajanje
+ Uvezi ili izvezi pretplate iz izbornika s 3 točke
+ Otvori popis reprodukcije
+ Reproduciraj
+ Dijeli playlistu
+ %1$s
+\n%2$s
+
+ - %s odgovor
+ - %s odgovora
+ - %s odgovora
+
+ Tuneliranje medija je standardno deaktivirano na tvom uređaju jer je poznato da model tvog uređaja to ne podržava.
\ No newline at end of file
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 0b3b102354f..58428df594f 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -569,7 +569,7 @@
Feldolgozás… Ez eltarthat egy ideig
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ése
Eredeti „ennyi ideje” megjelenítése az elemeken
- Tiltsa le a médiacsatornázást, ha fekete képernyőt vagy akadozást tapasztal videólejátszáskor
+ Tiltsa 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ához
Minden letöltésnél meg fogja kérdezni, hogy hova mentse el
Válasszon egy példányt
@@ -762,4 +762,55 @@
Kezdőlap választó alulra helyezése
Nincs élő adatfolyam
Nincs adatfolyam
+ Az alábbi értesítési műveletek szerkesztéséhez koppintson rá. Az első három műveletet (lejátszás/szünet, előző és következő) a rendszer állítja be, és nem szabhatók testre.
+ Csatornalapok lekérése
+ A hírcsatorna frissítésekor lekérendő lapok. Ennek az opciónak nincs hatása, ha egy csatorna frissítése gyors módban történik.
+ Miniatűrök
+ Feltöltő avatarjai
+ Alcsatorna avatarok
+ Avatarok
+ Bannerek
+ Feliratkozók
+ Csatornák
+ Lejátszási listák
+ Albumok
+ Névjegy
+ Csatorna fülek
+ Milyen lapok jelennek meg a csatornaoldalakon
+ Lejátszási sor megnyitása
+ Képernyő tájolásának váltása
+ Teljes képernyőre váltás
+ Következő közvetítés
+ Előző közvetítés
+ Lejátszás
+ Visszajátszás
+ További opciók
+ Időtartam
+ Visszatekerés
+ Előre
+ Képminőség
+ Az adat- és memóriahasználat csökkentése érdekében válassza ki a képek minőségét valamint azt, hogy a képek egyáltalán betöltésre kerüljenek. A változtatások törlik a memóriában és a lemezen lévő képgyorsítótárat – %s
+ Ne töltsön be képeket
+ Alacsony minőség
+ Közepes minőség
+ Magas minőségű
+ \?
+ Lejátszási lista megosztása
+ Lejátszási lista megosztása olyan részletekkel, mint például a lejátszási lista neve és a videó címe, vagy a videó URL-jei egyszerű listájaként
+ Megosztás címekkel
+ %1$s
+\n%2$s
+
+ - %s válasz
+ - %s válaszok
+
+ Továbbiak
+ Mutass kevesebbet
+ Metaadatok betöltése…
+ URL-lista megosztása
+ - %1$s: %2$s
+ Videók
+ Dalok
+ Rövidek
+ Élő
\ No newline at end of file
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index 2dc9ecdea05..1bab9806649 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -4,23 +4,23 @@
Dipublikasikan pada %1$s
Pasang
Batal
- Buka di browser
+ Buka di peramban
Bagikan
Unduh
- Telusuri
+ Telusur
Pengaturan
Bagikan dengan
Gunakan pemutar video eksternal
Gunakan pemutar audio eksternal
- Folder unduhan Video
+ Folder unduhan video
Berkas video yang diunduh akan disimpan di sini
Pilih folder unduhan untuk berkas video
- Folder unduhan Audio
+ Folder unduhan audio
Berkas audio yang diunduh akan disimpan di sini
Pilih folder unduhan untuk berkas audio
Pilih kualitas
Putar dengan Kodi
- Instal aplikasi Kode yang hilang\?
+ Pasang aplikasi Kore yang hilang?
Tampilkan opsi \"Putar dengan Kodi\"
Tampilkan opsi untuk memutar video via Kodi
Audio
@@ -66,7 +66,7 @@
Mulai
Jeda
Ceksum
- OK
+ Oke
Nama berkas
Galat
NewPipe Sedang Mengunduh
@@ -74,7 +74,7 @@
Mohon tunggu…
Disalin ke papan klip
Silakan pilih folder unduhan di pengaturan
- Pemutar stream tidak ada. Pasang VLC?
+ Pemutar stream tidak ditemukan. Pasang VLC?
App/UI rusak
Apa:\\nPermintaan:\\nBahasa Konten:\\nNegara Konten:\\nBahasa Apl:\\nLayanan:\\nWaktu GMT:\\nPaket:\\nVersi:\\nVersi OS:
Thread
@@ -85,19 +85,19 @@
r
J
T
- Buka dalam mode popup
+ Buka di mode tampilan kecil
Izin ini dibutuhkan untuk
\nmembuka di mode sembul
Memutar dalam mode sembul
Dinonaktifkan
Format video
- Pilih kualitas mode popup
+ Kualitas popup bawaan
Tampilkan kualitas yang lebih tinggi
Hanya perangkat tertentu saja yang bisa memutar video 2K/4K
Latar Belakang
- Munculan
+ Sembulan
Bersihkan
- Menghapus audio pada beberapa resolusi
+ Menghapus audio di beberapa resolusi
Ingat properti popup
Ingat ukuran dan posisi terakhir popup
Saran pencarian
@@ -237,11 +237,11 @@
Isi
Perbesar
Otomatis dibuat
- Pemutar stream tidak ada (pasang VLC untuk memutarnya).
+ Pemutar stream ditemukan (kamu bisa pasang VLC untuk memutarnya).
Unduh berkas stream
Tidak bisa mengubah langganan
Tampilkan info
- Tambahkan Ke
+ Tambah Ke
Hapus riwayat tontonan
Hapus riwayat video yang diputar dan posisi pemutaran
Hapus seluruh riwayat tontonan\?
@@ -254,7 +254,7 @@
1 item dihapus.
Daftar Putar
Putar otomatis video berikutnya
- Berhenti berlanggan channel
+ Berhenti berlangganan saluran
Tidak bisa memperbarui langganan
Langganan
Gunakan tinjau cepat tak pasti
@@ -322,7 +322,7 @@
Nihil
Minimalkan ke pemutar latar belakang
Minimalkan ke pemutar popup
- Berhenti Berlanggan
+ Berhenti Berlangganan
Pilih Tab
Tema
Pembaruan
@@ -534,7 +534,7 @@
Aduk
Ulangi
Anda bisa memilih hingga tiga tindakan untuk ditampilkan dalam notifikasi ringkas!
- Sentuh untuk menyunting tindakan notifikasi di bawah. Pilih hingga tiga diantaranya untuk ditampilkan dalam notifikasi ringkas dengan menggunakan kotak centang di sebelah kanan
+ Sentuh untuk menyunting tindakan notifikasi di bawah. Pilih hingga tiga diantaranya untuk ditampilkan dalam notifikasi ringkas dengan menggunakan kotak centang di sebelah kanan.
Tombol tindakan kelima
Tombol tindakan keempat
Tombol tindakan ketiga
@@ -585,7 +585,7 @@
Tema malam
Pengunduhan dimulai
Tampilkan detail channel
- Nonaktifkan terowongan media (tunnel) jiaka anda mengalami sebuah layar hitam atau kerusakan dalam memutar video.
+ Nonaktifkan terowongan media (tunnel) jika anda mengalami sebuah layar hitam atau kerusakan dalam memutar video.
Nonaktifkan terowongan media (tunnel)
Internal
Privasi
@@ -646,7 +646,7 @@
Item feed baru
Tampilkan \"Mogokkan pemutar\"
Menampilkan opsi penghentian ketika menggunakan pemain video
- Hentikan pemain video
+ Hentikan pemutar video
Notifikasi untuk melaporkan kegalatan
Notifikasi laporan kegalatan
Sebuah kegalatan terjadi, lihat notifikasinya
@@ -793,4 +793,10 @@
Bagikan daftar putar dengan detail seperti nama daftar putar dan judul video atau sebagai daftar video URL yang sederhana
Banner
- %1$s: %2$s
+ Sentuh untuk menyunting tindakan notifikasi di bawah. Tiga tindakan pertama (mainkan/jeda, sebelumnya dan selanjutnya) disetel oleh sistem dan tidak bisa dikustomisasi.
+ Tampilkan lebih sedikit
+ Tampilkan lebih banyak
+
+ - %s balasan
+
\ No newline at end of file
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 71b656234f5..17cdb1c4b4d 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -549,7 +549,7 @@
La coda del lettore attivo sarà sostituita
Chiedi prima di svuotare la coda
Cambiare tipo di riproduzione potrebbe sostituire gli elementi in coda
- Le azioni dei pulsanti della notifica possono essere modificate qua sotto. Selezionane fino a 3, utilizzando le caselle di controllo sulla destra. Verranno visualizzate nella notifica compatta
+ Le azioni dei pulsanti della notifica possono essere modificate qua sotto. Selezionane fino a tre da mostrare nella notifica compatta, usando le caselle di controllo sulla destra.
Azione pulsante 5
Azione pulsante 4
Azione pulsante 3
@@ -779,7 +779,7 @@
Iscritti
Quali schede mostrare nelle pagine del canale
Schede canale
- Short
+ Shorts
Caricamento metadati…
Recupera schede del canale
Informazioni
@@ -819,4 +819,12 @@
Condividi playlist
Condividi la playlist con dettagli come il suo nome e i titoli video o come un semplice elenco di URL video
- %1$s: %2$s
+
+ - %s risposta
+ - %s risposte
+ - %s risposte
+
+ Mostra altro
+ Le azioni dei pulsanti della notifica possono essere modificate qua sotto. Le prime tre (riproduci/pausa, precedente e successivo) sono impostate dal sistema e non possono essere cambiate.
+ Mostra meno
\ No newline at end of file
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 796c6d650dd..93b52997c27 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -531,7 +531,7 @@
URL を認識できませんでした。他のアプリで開きますか?
通知に表示されるサムネイルを 16:9 から正方形にします
サムネイルを正方形にする
- 以下をタップして通知のアクションを編集します。右側にあるチェックボックスを使用してコンパクトな通知に表示するものを 3 つまで選択します
+ 以下をタップして通知のアクションを編集します。右側にあるチェックボックスを使用してコンパクトな通知に表示するものを3つまで選択します。
コンパクトな通知に表示されるアクションは 3 つまで選ぶことができます!
5 番目のアクションボタン
4 番目のアクションボタン
@@ -793,4 +793,10 @@
プレイリストを共有
プレイリスト名やビデオタイトルなどの詳細を含むプレイリスト、またはビデオURLのみのシンプルなリストとしてプレイリストを共有します
- %1$s: %2$s
+
+ - %sの返信
+
+ もっと見る
+ 表示を少なくする
+ 以下の通知アクションをタップして編集します。 最初の3つのアクション (再生/一時停止、前へ、次へ)はシステムによって設定されており、カスタマイズすることはできません。
\ No newline at end of file
diff --git a/app/src/main/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml
index a6b3daec935..ec598114d5e 100644
--- a/app/src/main/res/values-kn/strings.xml
+++ b/app/src/main/res/values-kn/strings.xml
@@ -1,2 +1,43 @@
-
\ No newline at end of file
+
+ ಗೆ ಸೇರಿಸಿ
+ ಮಾಹಿತಿಯನ್ನು ತೋರಿಸಿ
+ ಚಾನಲ್ ಅನ್ಸಬ್ಸ್ಕ್ರೈಬ್ ಮಾಡಲಾಗಿದೆ
+ ಪಾಪ್ಅಪ್ ಮೋಡ್ನಲ್ಲಿ ತೆರೆಯಿರಿ
+ ನೀವು \"%1$s\" ಎಂದು ಅರ್ಥೈಸಿದ್ದೀರಾ?
+ ಬಳಸಿ ಹಂಚಿಕೊಳ್ಳಿ
+ ವೀಡಿಯೊ ಫೈಲ್ಗಳಿಗಾಗಿ ಡೌನ್ಲೋಡ್ ಫೋಲ್ಡರ್ ಆಯ್ಕೆಮಾಡಿ
+ ಸಬ್ಸ್ಕ್ರೈಬ್ ಮಾಡಲಾಗಿದೆ
+ ಡೌನ್ಲೋಡ್ ಮಾಡಿದ ಆಡಿಯೊ ಫೈಲ್ಗಳನ್ನು ಇಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗುತ್ತದೆ
+ ಬಾಹ್ಯ ಆಡಿಯೊ ಪ್ಲೇಯರ್ ಬಳಸಿ
+ ಚಂದಾದಾರಿಕೆಯನ್ನು ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ
+ ಪ್ರಾರಂಭಿಸಲು ಭೂತಗನ್ನಡಿಯನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ.
+ ಕೆಲವು ರೆಸಲ್ಯೂಶನ್ಗಳಲ್ಲಿ ಆಡಿಯೊವನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ
+ %1$s ರಂದು ಪ್ರಕಟಿಸಲಾಗಿದೆ
+ ವೀಕ್ಷಿಸಲಾಗಿದೆ ಎಂದು ಗುರುತಿಸಿ
+ ಯಾವುದೇ ಸ್ಟ್ರೀಮ್ ಪ್ಲೇಯರ್ ಕಂಡುಬಂದಿಲ್ಲ (ಅದನ್ನು ಪ್ಲೇ ಮಾಡಲು ನೀವು VLC ಅನ್ನು ಸ್ಥಾಪಿಸಬಹುದು).
+ ಸರಿ
+ ಬ್ರೌಸರ್ನಲ್ಲಿ ತೆರೆಯಿರಿ
+ ಪಾಪ್ಅಪ್
+ ಡೌನ್ಲೋಡ್ ಮಾಡಿ
+ ಇದಕ್ಕೆ ಫಲಿತಾಂಶಗಳನ್ನು ತೋರಿಸಲಾಗುತ್ತಿದೆ: %s
+ ಇದರೊಂದಿಗೆ ತೆರೆಯಿರಿ
+ ಡೌನ್ಲೋಡ್ ಮಾಡಿದ ವೀಡಿಯೊ ಫೈಲ್ಗಳನ್ನು ಇಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗುತ್ತದೆ
+ ಸ್ಟ್ರೀಮ್ ಫೈಲ್ ಅನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಿ
+ ರದ್ದುಗೊಳಿಸಿ
+ ಆಡಿಯೋ ಡೌನ್ಲೋಡ್ ಫೋಲ್ಡರ್
+ ಬುಕ್ಮಾರ್ಕ್ ಮಾಡಲಾದ ಪ್ಲೇಪಟ್ಟಿಗಳು
+ ಚಂದಾದಾರಿಕೆಯನ್ನು ನವೀಕರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ
+ ಸಬ್ಸ್ಕ್ರೈಬ್
+ ಹುಡುಕಿ
+ ಚಂದಾದಾರಿಕೆಗಳು
+ ಸೆಟ್ಟಿಂಗ್ಗಳು
+ ಬಾಹ್ಯ ವೀಡಿಯೊ ಪ್ಲೇಯರ್ ಬಳಸಿ
+ ಸ್ಥಾಪಿಸಿ
+ ಯಾವುದೇ ಸ್ಟ್ರೀಮ್ ಪ್ಲೇಯರ್ ಕಂಡುಬಂದಿಲ್ಲ. VLC ಸ್ಥಾಪಿಸುವುದೇ?
+ ಶೇರ್ ಮಾಡಿ
+ ವೀಡಿಯೊ ಡೌನ್ಲೋಡ್ ಫೋಲ್ಡರ್
+ ಟ್ಯಾಬ್ ಆಯ್ಕೆಮಾಡಿ
+ ಹಿನ್ನೆಲೆ
+ ಅನ್ಸಬ್ಸ್ಕ್ರೈಬ್ ಮಾಡಿ
+
\ No newline at end of file
diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml
index 33fd41f5908..8c6b8871613 100644
--- a/app/src/main/res/values-ms/strings.xml
+++ b/app/src/main/res/values-ms/strings.xml
@@ -432,4 +432,8 @@
Jangan tunjuk
Nyahbisu
Minta Android menyesuaikan warna pemberitahuan sesuai dengan warna utama di thumbnail (perhatikan bahawa ini tidak tersedia dalam semua perangkat)
+ Auto-main
+ Sambung main
+ Tidak boleh memuat komentar
+ Tutup
\ No newline at end of file
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index 1c8575d7037..c1cb3db93cb 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -30,7 +30,7 @@
Mørk
Lys
Last ned
- Vis \"Neste\" og \"Lignende\" -videoer
+ Vis «Neste» og «Lignende» -videoer
Nettadressen støttes ikke
Forvalgt innholdsspråk
Video og lyd
@@ -558,7 +558,7 @@
Tøm reCAPTCHA-kaker
reCAPTCHA-kaker har blitt slettet
Tøm kaker som NewPipe lagrer når du løser en reCAPTCHA
- YouTube tilbyr en \"Begrenset modus\" som skjuler potensielt modent innhold
+ YouTube tilbyr «Begrenset modus» som skjuler innhold antatt å være for voksne
Vis innhold som muligens er uegnet for barn fordi det har en aldersgrense (som 18+)
La Android tilpasse varselets farge i henhold til hovedfargen i miniatyrbildet (merk at dette ikke er tilgjengelig på alle enheter)
Fargelegg merknad
@@ -772,4 +772,30 @@
Ingen strømmer
Kanaler
Forrige strøm
+ Vis mer
+
+ - %s svar
+ - %s svar
+
+ Flytt hovedfanevelgeren til bunnen
+ Hovedfaneposisjon
+ Videoer
+ Ukjent
+ Direkte
+ Spol tilbake
+ Spol forover
+ Bildekvalitet
+ Vis mindre
+ Del med titler
+ Del nettadresse først
+ - %1$s: %2$s
+ ExoPlayer-innstillinger
+ %1$s %2$s
+ beskrivende
+ Veksle fullskjermsvising
+ Bytt skjermretning
+ Rediger hver merknadshandling nedenfor ved å trykke på den. De første tre (spill av/pause, forrige, og neste) kan ikke tilpasses.
+ Bruk ExoPlayers dekodings-tilbakefall
+ Håndter noen ExoPlayer-innstillinger. Disse endringeren krever omstart av avspilleren.
+ Hvilke faner som vises på kanalsidene
\ No newline at end of file
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index b49526071ef..b08e2020288 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -216,7 +216,7 @@
Dit overschrijft je huidige configuratie.
Streambestand downloaden
Informatie tonen
- Bijgehouden afspeellijsten
+ Bijgehouden afspeellijsten
Toevoegen aan
Versleep om de volgorde te wijzigen
Aanmaken
@@ -374,7 +374,7 @@
Stop
Maximum aantal keer proberen
Maximum aantal pogingen voordat de download wordt geannuleerd
- Pauzeren bij mobiele data verbinding
+ Pauzeren bij mobiele gegevensverbinding
Handig voor wanneer u naar mobiel internet overschakelt, hoewel sommige downloads niet gepauzeerd kunnen worden
Gebeurtenissen
Conferenties
@@ -386,7 +386,7 @@
Kan reacties niet laden
Sluiten
Het \'Storage Access Framework\' staat downloads naar een externe SD kaart toe
- Wis data
+ Gegevens wissen
Afspelen hervatten
Verder afspelen vanaf laatste positie
Posities in lijst
@@ -543,7 +543,7 @@
Willekeurig afspelen
Herhaal
Je kan maximaal drie acties selecteren om te tonen in de compacte notificatie!
- Pas elke meldingsactie hieronder aan door er op te tikken. Selecteer tot drie acties die getoond worden in de compacte melding door gebruik te maken van de selectievakjes aan de rechterkant
+ Pas elke meldingsactie hieronder aan door er op te tikken. Selecteer tot drie acties die getoond worden in de compacte melding door gebruik te maken van de selectievakjes aan de rechterkant.
Vijfde actieknop
Vierde actieknop
Derde actieknop
@@ -806,4 +806,11 @@
Afspeellijst delen
Deel afspeellijst met details zoals afspeellijstnaam en videotitels of als een eenvoudige lijst met video-URL\'s
- %1$s: %2$s
+
+ - %s antwoord
+ - %s antwoorden
+
+ Meer tonen
+ Minder tonen
+ Bewerk elke meldingsactie hieronder door erop te tikken. De eerste drie acties (afspelen/pauzeren, vorige en volgende) zijn ingesteld door het systeem en kunnen niet worden aangepast.
\ No newline at end of file
diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml
index fb2cfd675b4..89715cd8465 100644
--- a/app/src/main/res/values-or/strings.xml
+++ b/app/src/main/res/values-or/strings.xml
@@ -18,7 +18,7 @@
- ମୋଟ %d ମିନିଟ୍
ଆପ୍ ଭାଷା
- ସ୍ୱୟଂଚାଳିତ (ଡିଭାଇସ୍ ଥିମ୍)
+ ସ୍ୱଚାଳିତ (ଡିଵାଇସ୍ ଥିମ୍)
ଗୋପନୀୟତା
ନାମ
ବିବରଣୀ
@@ -147,7 +147,7 @@
ବ୍ୟବହାର
ଵିଡ଼ିଓ ଓ ଅଡ଼ିଓ
ମିନି ପ୍ଲେୟାରରେ ଭିଡିଓ ଆରମ୍ଭ କରନ୍ତୁ ନାହିଁ, କିନ୍ତୁ ଅଟୋ ଘୂର୍ଣ୍ଣନ ବନ୍ଦ ହୋଇଗଲେ ସିଧାସଳଖ ଫୁଲ୍ ସ୍କ୍ରିନ୍ ମୋଡ୍ କୁ ଯାଆନ୍ତୁ। ଫୁଲ୍ ସ୍କ୍ରିନ୍ ଛାଡି ଆପଣ ଏପର୍ଯ୍ୟନ୍ତ ମିନି ପ୍ଲେୟାରକୁ ପ୍ରବେଶ କରିପାରିବେ
- ଏହା ଉପରେ ଟ୍ୟାପ୍ କରି ନିମ୍ନରେ ପ୍ରତ୍ୟେକ ବିଜ୍ଞପ୍ତି କାର୍ଯ୍ୟ ସଂପାଦନ କରନ୍ତୁ। ଡାହାଣରେ ଥିବା ଚେକ୍ ବକ୍ସ ବ୍ୟବହାର କରି କମ୍ପାକ୍ଟ ବିଜ୍ଞପ୍ତିରେ ଦେଖାଯିବାକୁ ସେମାନଙ୍କ ମଧ୍ୟରୁ ତିନୋଟି ପର୍ଯ୍ୟନ୍ତ ଚୟନ କରନ୍ତୁ
+ ଏହା ଉପରେ ଟ୍ୟାପ କରି ନିମ୍ନରେ ଦିଆଯାଇଥିବା ପ୍ରତ୍ୟେକ ବିଜ୍ଞପ୍ତି କାର୍ଯ୍ୟକୁ ସମ୍ପାଦନ କରନ୍ତୁ । ଡାହାଣ ପଟେ ଥିବା ଚେକବକ୍ସଗୁଡ଼ିକୁ ବ୍ୟବହାର କରି କମ୍ପାକ୍ଟ ବିଜ୍ଞପ୍ତିରେ ଦର୍ଶାଇବା ପାଇଁ ସେଗୁଡ଼ିକ ମଧ୍ୟରୁ ତିନିଟି ଚୟନ କରନ୍ତୁ ।
ଷ୍ଟ୍ରିମ୍ ସୃଷ୍ଟିକର୍ତ୍ତା, ଷ୍ଟ୍ରିମ୍ ବିଷୟବସ୍ତୁ କିମ୍ବା ଏକ ସନ୍ଧାନ ଅନୁରୋଧ ବିଷୟରେ ଅତିରିକ୍ତ ସୂଚନା ସହିତ ମେଟା ସୂଚନା ବାକ୍ସଗୁଡ଼ିକୁ ଲୁଚାଇବାକୁ ବନ୍ଦ କରନ୍ତୁ
ପିଲାମାନଙ୍କ ପାଇଁ ସମ୍ଭବତ content ଅନୁପଯୁକ୍ତ ବିଷୟବସ୍ତୁ ଦେଖାନ୍ତୁ କାରଣ ଏହାର ବୟସ ସୀମା ଅଛି (ଯେପରିକି 18+)
ଏହି ଭିଡିଓ ବୟସ-ସୀମିତ ଅଟେ ।
@@ -806,4 +806,11 @@
ଖେଳ ତାଲିକା ସହଭାଗ କରନ୍ତୁ
ପ୍ଲେ-ଲିଷ୍ଟ ନାମ ଏବଂ ଭିଡିଓ ଶୀର୍ଷକ କିମ୍ବା ଭିଡିଓ URLଗୁଡ଼ିକର ଏକ ସରଳ ତାଲିକା ଭାବରେ ବିବରଣୀ ସହିତ ପ୍ଲେ-ଲିଷ୍ଟ ଅଂଶୀଦାର କରନ୍ତୁ
- %1$s: %2$s
+ ଅଧିକ ଦର୍ଶାନ୍ତୁ
+ ଏହା ଉପରେ ଟ୍ୟାପ କରି ନିମ୍ନରେ ଦିଆଯାଇଥିବା ପ୍ରତ୍ୟେକ ବିଜ୍ଞପ୍ତି କାର୍ଯ୍ୟକୁ ସମ୍ପାଦନ କରନ୍ତୁ । ପ୍ରଥମ ତିନୋଟି କାର୍ଯ୍ୟ (ଖେଳ/ବିରତି, ପୂର୍ବବର୍ତ୍ତୀ ଏବଂ ପରବର୍ତ୍ତୀ) ତନ୍ତ୍ର ଦ୍ୱାରା ସେଟ କରାଯାଇଥାଏ ଏବଂ ଏହାକୁ ଇଚ୍ଛାରୂପଣ କରାଯାଇପାରିବ ନାହିଁ ।
+
+ - %s ଉତ୍ତର
+ - %s ଉତ୍ତରଗୁଡ଼ିକ
+
+ କମ୍ ଦର୍ଶାନ୍ତୁ
\ No newline at end of file
diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml
index e74e747f402..ee5b4aacc91 100644
--- a/app/src/main/res/values-pa/strings.xml
+++ b/app/src/main/res/values-pa/strings.xml
@@ -602,7 +602,7 @@
ਬਫ਼ਰਿੰਗ
ਸ਼ਫਲ
ਦੁਹਰਾਓ
- ਹੇਠਾਂ ਹਰੇਕ ਨੋਟੀਫਿਕੇਸ਼ਨ ਕਾਰਵਾਈ ਤੇ ਨੱਪਦਿਆਂ ਇਹਨਾਂ ਨੂੰ ਬਦਲੋ। ਇਹਨਾਂ ਦੇ ਸੱਜੇ ਪਾਸੇ ਬਣੇ ਚੈੱਕਬਾਕਸ ਵਰਤਦਿਆਂ ਇਹਨਾਂ ਵਿਚੋਂ ਵੱਧ-ਤੋਂ-ਵੱਧ ਤਿੰਨ ਕਾਰਵਾਈਆਂ ਨੂੰ ਤੁਸੀਂ ਕੰਪੈਕਟ ਨੋਟੀਫਿਕੇਸ਼ਨ ਵਿੱਚ ਵਿਖਾਉਣ ਲਈ ਚੁਣ ਸਕਦੇ ਹੋ
+ ਹੇਠਾਂ ਹਰੇਕ ਨੋਟੀਫਿਕੇਸ਼ਨ ਕਾਰਵਾਈ ਤੇ ਨੱਪਦਿਆਂ ਇਹਨਾਂ ਨੂੰ ਬਦਲੋ। ਇਹਨਾਂ ਦੇ ਸੱਜੇ ਪਾਸੇ ਬਣੇ ਚੈੱਕਬਾਕਸ ਵਰਤਦਿਆਂ ਇਹਨਾਂ ਵਿਚੋਂ ਵੱਧ-ਤੋਂ-ਵੱਧ ਤਿੰਨ ਕਾਰਵਾਈਆਂ ਨੂੰ ਤੁਸੀਂ ਕੰਪੈਕਟ ਨੋਟੀਫਿਕੇਸ਼ਨ ਵਿੱਚ ਵਿਖਾਉਣ ਲਈ ਚੁਣ ਸਕਦੇ ਹੋ।
ਤੁਸੀਂ ਵੱਧ-ਤੋਂ-ਵੱਧ ਤਿੰਨ ਕਾਰਵਾਈਆਂ ਨੂੰ ਕੰਪੈਕਟ ਨੋਟੀਫਿਕੇਸ਼ਨ ਵਿੱਚ ਵਿਖਾਉਣ ਲਈ ਚੁਣ ਸਕਦੇ ਹੋ!
ਪੰਜਵਾਂ ਕਾਰਵਾਈ ਬਟਨ
ਚੌਥਾ ਕਾਰਵਾਈ ਬਟਨ
@@ -806,4 +806,11 @@
ਪਲੇਲਿਸਟ ਸਾਂਝੀ ਕਰੋ
ਪਲੇਲਿਸਟ ਦੇ ਨਾਮ ਅਤੇ ਵੀਡੀਓ ਸਿਰਲੇਖਾਂ ਜਾਂ ਵੀਡੀਓ URL ਦੀ ਇੱਕ ਸਧਾਰਨ ਸੂਚੀ ਦੇ ਰੂਪ ਵਿੱਚ ਵੇਰਵਿਆਂ ਨਾਲ ਪਲੇਲਿਸਟ ਨੂੰ ਸਾਂਝਾ ਕਰੋ
- %1$s: %2$s
+
+ - %s ਜਵਾਬ
+ - %s ਜਵਾਬ
+
+ ਹੋਰ ਵਿਖਾਓ
+ ਇਸ \'ਤੇ ਟੈਪ ਕਰਕੇ ਹੇਠਾਂ ਹਰੇਕ ਸੂਚਨਾ ਕਾਰਵਾਈ ਨੂੰ ਸੰਪਾਦਿਤ ਕਰੋ। ਪਹਿਲੀਆਂ ਤਿੰਨ ਕਾਰਵਾਈਆਂ (ਪਲੇ/ਪੌਜ਼, ਪਿਛਲਾ ਅਤੇ ਅਗਲਾ) ਸਿਸਟਮ ਦੁਆਰਾ ਸੈੱਟ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ ਅਤੇ ਉਹਨਾਂ ਨੂੰ ਅਨੁਕੂਲਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।
+ ਘੱਟ ਦਿਖਾਓ
\ No newline at end of file
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 8c7a28ddca4..2a7d80396ea 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -827,4 +827,13 @@
Udostępnij playlistę
Udostępnij playlistę ze szczegółami, takimi jak nazwa playlisty i tytuły wideo, lub jako prostą listę adresów URL wideo.
– %1$s: %2$s
+
+ - %s odpowiedź
+ - %s odpowiedzi
+ - %s odpowiedzi
+ - %s odpowiedzi
+
+ Pokaż więcej
+ Pokaż mniej
+ Edytuj każdą poniższą akcję powiadomienia, naciskając ją. Pierwsze trzy akcje (odtwórz/wstrzymaj, poprzedni i następny) są ustawione przez system i nie można ich dostosować
\ No newline at end of file
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 76c6b43fe74..cca254aeaee 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -554,7 +554,7 @@
Nada
Repetir
Você pode selecionar até no máximo três botões para mostrar na notificação compacta!
- Edite os botões de ação de notificação abaixo tocando em cada um. Selecione até três deles para serem mostrados na notificação compacta usando as caixas de seleção à direita
+ Edite os botões de ação de notificação abaixo tocando em cada um. Selecione até três deles para serem mostrados na notificação compacta usando as caixas de seleção à direita.
Quinto botão de ação
Quarto botão de ação
Terceiro botão de ação
@@ -818,4 +818,13 @@
Miniaturas
Duração
Transmissão anterior
+ Banners
+ Mostrar mais
+ Edite cada ação de notificação abaixo tocando nela. As três primeiras ações (reproduzir/pausar, anterior e seguinte) são definidas pelo sistema e não podem ser personalizadas.
+
+ - %s resposta
+ - %s respostas
+ - %s respostas
+
+ Mostrar menos
\ No newline at end of file
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index 335c989ed19..0dae4fc7849 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -554,7 +554,7 @@
Baralhar
Repetir
Pode selecionar, no máximo, três ações para mostrar na notificação compacta!
- Edite cada ação de notificação abaixo tocando nela. Selecione até três delas para serem mostrados na notificação compacta a usar as caixas de seleção à direita
+ Edite cada ação de notificação abaixo, a tocar nela. Selecione até três delas para serem mostradas na notificação compacta, através das caixas de verificação à direita.
Quinto botão de ação
Quarto botão de ação
Terceiro botão de ação
@@ -819,4 +819,12 @@
Canais
Fluxo anterior
Direto
+ Mostrar mais
+ Edite cada ação de notificação abaixo a tocar nela. As três primeiras ações (reproduzir/pausa, anterior e seguinte) são definidas pelo sistema e não podem ser personalizadas.
+
+ - %s resposta
+ - %s respostas
+ - %s respostas
+
+ Mostrar menos
\ No newline at end of file
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index f20bc05b0bc..799166a8995 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -73,7 +73,7 @@
Toque para detalhes
Por favor aguarde…
Copiado para a área de transferência
- Tem que definir, nas definições, uma pasta para as descargas
+ Pode definir, mais tarde, uma pasta para as descargas
OK
Processos
Descarga NewPipe
@@ -107,9 +107,9 @@
Acerca de NewPipe
Licenças de terceiros
© %1$s de %2$s nos termos da %3$s
- Sobre e FAQ
+ Acerca e FAQ
Licenças
- Aplicação livre de reprodução de transmissões para Android.
+ Aplicação de reprodução para Android.
Ver no GitHub
Licença do NewPipe
Se tem ideias para: tradução, alterações de desenho, limpeza de código, ou alterações significativas no código fonte - todas as ajudas são bem-vindas. Quanto mais se faz, melhor ficará!
@@ -133,7 +133,7 @@
Histórico e cache
Desfazer
Notificação NewPipe
- Notificações para o reprodutor do NewPipe
+ Notificações para o reprodutor NewPipe
Sem resultados
Aqui não há nada para ver
Sem subscritores
@@ -154,7 +154,7 @@
- %s vídeos
- %s vídeos
- Transferências
+ Descargas
Carateres permitidos no nome dos ficheiros
Os carateres inválidos são substituídos por este valor
Carácter de substituição
@@ -180,7 +180,7 @@
Detalhes
Definições de áudio
Iniciar reprodução em segundo plano
- Iniciar reprodução num popup
+ Iniciar reprodução em popup
Mostrar informação
Listas de reprodução favoritas
Sempre
@@ -202,7 +202,7 @@
Descarregar ficheiro
Adicionar a
Utilizar pesquisa rápida
- Este tipo de pesquisa e mais rápida mas reduz a precisão. Procurar por 5, 15 ou 25 segundos não funciona corretamente
+ Este tipo de pesquisa é mais rápida mas reduz a precisão. Procurar por 5, 15 ou 25 segundos não funciona corretamente
Cache de imagens limpa
País padrão para conteúdo
Depuração
@@ -237,7 +237,7 @@
Reprodutor \'popup\'
Perguntar sempre
A obter informação…
- A carregar o conteúdo solicitado
+ A carregar conteúdo solicitado
Nova lista de reprodução
Mudar nome
Adicionar à lista de reprodução
@@ -262,13 +262,13 @@
Não foi possível exportar as subscrições
Importar subscrições do YouTube do Google Takeout:
\n
-\n1. Vá para este URL: %1$s
-\n2. Faça o login quando solicitado
-\n3. Clique em \"Todos os dados incluídos\", depois em \"Desmarcar todos\", depois selecione apenas \"subscrições\" e clique em \"OK\".
-\n4. Clique em \"Próximo passo\" e depois em \"Criar exportação\".
+\n1. Aceda ao URL: %1$s
+\n2. Inicie sessão
+\n3. Clique em \"Todos os dados incluídos\", depois em \"Desmarcar todos\", selecione \"Subscrições\" e clique em \"OK\".
+\n4. Clique em \"Próximo passo\" e, depois, em \"Criar exportação\".
\n5. Clique no botão \"Descarregar\" após aparecer
\n6. Clique em IMPORT FILE abaixo e selecione o ficheiro .zip descarregado
-\n7. [Se a importação do .zip falhar] Extraia o ficheiro .csv (geralmente em \"YouTube e YouTube Music/subscriptions/subscriptions.csv\"), clique em IMPORT FILE abaixo e selecione o ficheiro csv extraído
+\n7. [Se a importação falhar] Extraia o ficheiro .csv (geralmente em \"YouTube e YouTube Music/subscriptions/subscriptions.csv\"), clique em IMPORT FILE abaixo e selecione o ficheiro csv extraído
Importe o seu perfil SoundCloud digitando o URL ou a ID.:
\n
\n1. Ative o modo desktop do seu navegador web (o site não está disponível para dispositivos móveis)
@@ -297,7 +297,7 @@
NewPipe é desenvolvido por voluntários que utilizam o seu tempo livre para nos proporcionar a melhor experiência. Retribua para ajudar os programadores a tornarem NewPipe ainda melhor.
Contribuir
Política de privacidade do NewPipe
- O projeto NewPipe leva a sua privacidade muito a sério. Por isso, não recolhe nenhum dado sem o seu consentimento.
+ O projeto NewPipe leva a sua privacidade muito a sério. Por isso, não recolhe dados sem o seu consentimento.
\nA polícia de privacidade do NewPipe explica, em detalhe, os tipos de dados enviados sempre que submete um relatório de erro.
Ver política de privacidade
Adicionar o próximo vídeo à fila automaticamente
@@ -309,7 +309,7 @@
Definir como miniatura da lista de reprodução
Ajustar
Preencher
- Modificar escala de legendas e estilo de fundo. Tem que reiniciar a aplicação para aplicar as alterações
+ Alterar escala das legendas e do estilo de fundo. Tem que reiniciar a aplicação para aplicar as alterações
A monitorização de memória pode tornar a aplicação instável
Reportar erros \'out-of-lifecycle\'
Forçar reporte de exceções Rx não entregáveis ocorrendo fora do fragmento ou ciclo de vida da atividade após eliminação
@@ -343,7 +343,7 @@
Não foi possível ler os separadores guardados e vamos usar os separadores padrão
Repor predefinições
Deseja repor as predefinições\?
- Contagem de subscrições indisponível
+ Número de subscrições indisponível
Separadores mostrados na página principal
Atualizações
Mostrar uma notificação para pedir a atualização da aplicação se existir uma nova versão
@@ -356,7 +356,7 @@
em pausa
na fila
pós-processamento
- Enfileirar
+ Colocar na fila
Ação recusada pelo sistema
Falha ao descarregar
Gerar nome único
@@ -370,14 +370,14 @@
Não foi possível encontrar o servidor
Não foi possível ligar ao servidor
O servidor não envia dados
- O servidor não aceita transferências multi-processo, tente novamente com @string/msg_threads = 1
+ O servidor não aceita descargas multi-processo, tente novamente com @string/msg_threads = 1
Não encontrado
Falha pós-processamento
Parar
Tentativas máximas
Número máximo de tentativas antes de cancelar a descarga
Interromper em redes limitadas
- Útil ao trocar para dados móveis, mas algumas transferências não podem ser suspensas
+ Útil ao trocar para dados móveis, mas algumas descargas não podem ser suspensas
Eventos
Conferências
Pendente
@@ -395,7 +395,7 @@
Posições de reprodução removidas
Ficheiro movido ou eliminado
Já existe um ficheiro com este nome
- não é possível sobrescrever o ficheiro
+ Não foi possível substituir o ficheiro
Existe uma descarga pendente com este nome
NewPipe foi fechado enquanto trabalhava no ficheiro
Não há espaço livre no dispositivo
@@ -404,13 +404,13 @@
Deseja limpar o histórico de descargas ou remover todos os ficheiros descarregados\?
Limitar fila de descargas
Permitir apenas uma descarga de cada vez
- Iniciar transferências
- Pausa nas transferências
- Perguntar para onde transferir
- Ser-lhe-á perguntado onde guardar cada transferência.
-\nAtive o seletor de pastas do sistema (SAF) se quiser transferir para um cartão SD externo
+ Iniciar descargas
+ Pausa nas descargas
+ Perguntar onde guardar
+ Ser-lhe-á perguntado onde guardar cada descarga.
+\nAtive o seletor de pastas do sistema (SAF) se quiser descarregar para um cartão SD externo
Utilizar seletor de pastas do sistema (SAF)
- \'Storage Access Framework\' permite transferências para um cartão SD externo
+ \'Storage Access Framework\' permite descargas para um cartão SD externo
Remover posições de reprodução
Remove todas as posições de reprodução
Remover todas as posições de reprodução\?
@@ -428,8 +428,8 @@
- %s ouvintes
- %s ouvintes
- O idioma será alterado assim que reiniciar a app
- Duração da pesquisa de avanço/recuo rápido
+ O idioma será alterado assim que reiniciar a aplicação
+ Duração de avanço/recuo rápido
Instâncias PeerTube
Defina as suas instâncias PeerTube preferidas
Encontre as instâncias que gosta em %s
@@ -441,7 +441,7 @@
Local
Recentes
Mais apreciados
- Geração automática (não foi encontrado nenhum enviador)
+ Geração automática (não foi encontrado nenhum carregador)
a recuperar
Não é possível recuperar esta descarga
Escolha uma instância
@@ -451,11 +451,11 @@
Idioma da aplicação
Predefinição do sistema
Prima \"Feito\" ao resolver
- Concluído
- Acha que a fonte demora muito tempo a carregar\? Se sim, tente ativar o carregamento rápido (pode alterar a opção nas definições ou no botão abaixo).
+ Feito
+ Acha que a fonte demora muito tempo a carregar? Se sim, tente ativar o carregamento rápido (pode alterar a opção nas definições ou no botão abaixo).
\n
\nNewPipe oferece duas estratégias de carregamento:
-\n- Obter todo o canal de subscrição - lento, mas completo.
+\n- Obter todo o canal - lento, mas completo.
\n- Usar um \'endpoint\' dedicado - mais rápido, mas não completo.
\n
\nA diferença entre os dois é que o rápido geralmente carece de alguma informação, como a duração ou tipo do item (não consegue distinguir entre vídeos em direto e vídeos normais) e pode mostrar menos itens.
@@ -468,11 +468,11 @@
Disponível em alguns serviços, é geralmente muito mais rápido, mas pode devolver uma quantidade limitada de itens e muitas vezes informações incompletas (por exemplo, sem duração, tipo de item, sem estado ativo)
Se possível, obter de uma fonte dedicada
Atualizar sempre
- Tempo após a última atualização antes de a subscrição ser considerada desatualizada - %s
+ Tempo após a última atualização antes da subscrição ser considerada desatualizada - %s
Limite de atualização da fonte
Fonte
Novo
- Deseja apagar este grupo\?
+ Deseja remover este grupo?
O nome do grupo está vazio
- %d selecionado
@@ -547,18 +547,18 @@
Ajustar miniatura de vídeo mostrada na notificação de 16:9 para 1:1
Cortar miniatura na proporção 1:1
Iniciar reprodução automaticamente — %s
- Reproduzir fila
+ Fila de reprodução
Nunca
A carregar
- A fila do reprodutor ativo será substituída
+ A fila de reprodução atual será substituída
URL não reconhecido. Abrir com outra aplicação\?
- Enfileiramento automático
+ Colocar na fila automaticamente
Baralhar
Apenas em Wi-Fi
Nada
Mudar de um reprodutor para outro pode substituir a sua fila
Pedir confirmação antes de limpar a fila
- Edite cada ação de notificação abaixo com um toque. Selecione até três para serem mostradas na notificação compacta utilizando as caixas de seleção à direita
+ Edite cada ação de notificação abaixo, tocando na mesma. Seleccione até três delas para serem mostradas na notificação compacta, utilizando as caixas de verificação à direita.
Pode selecionar, no máximo, três ações para mostrar na notificação compacta!
Repetir
Quinto botão de ação
@@ -572,7 +572,7 @@
Mostrar conteúdo possivelmente impróprio para crianças porque tem um limite de idade (como 18+)
Personalizar cor da notificação com a cor principal da miniatura (esta opção não está disponível em todos os dispositivos)
Notificação colorida
- Usar miniaturas no fundo do ecrã de bloqueio e em notificações
+ Usar miniatura como fundo do ecrã de bloqueio e nas notificações
Mostrar miniatura
A calcular \'hash\'
Notificar sobre o progresso das \'hash\' dos vídeos
@@ -583,18 +583,18 @@
Não possui qualquer aplicação para abrir este ficheiro
Capítulos
Descrição
- Emissões relacionadas
+ Itens relacionados
Comentários
Desative para ocultar a descrição do vídeo e informações adicionais
Mostrar descrição
Abrir com
- A app travou
+ Terminar aplicação
Este vídeo tem uma restrição de idade.
\nDevido às novas políticas do YouTube quanto a restrição de alguns vídeos, o NewPipe não pode aceder a estes vídeos e, por isso, não os consegue reproduzir.
- Este conteúdo só está disponível para utilizadores que pagaram, portanto não pode ser transmitido ou descarregado pelo NewPipe.
- Este vídeo está disponível apenas para os membros do YouTube Music Premium, portanto não pode ser transmitido ou descarregado pelo NewPipe.
- Este conteúdo é privado, portanto não pode ser transmitido ou descarregado pelo NewPipe.
- Esta é uma faixa de SoundCloud Go+, pelo menos no seu país, pelo que não pode ser transmitida ou descarregada por NewPipe.
+ Este conteúdo só está disponível para utilizadores pagantes e não pode ser reproduzido ou descarregado pelo NewPipe.
+ Este vídeo só está disponível para os membros do YouTube Music Premium e não pode ser reproduzido ou descarregado pelo NewPipe.
+ Este conteúdo é privado e não pode ser reproduzido ou descarregado pelo NewPipe.
+ Esta é uma faixa SoundCloud Go+ e, pelo menos no seu país, não pode ser reproduzida ou descarregada por NewPipe.
Este conteúdo não está disponível no seu país.
Rádio
Destaques
@@ -605,37 +605,37 @@
Automático (Tema do dispositivo)
Tema escuro
Mostrar detalhes do canal
- Desative o túnel multimédia se tiver um ecrã preto ou gaguejo na reprodução de vídeo.
+ Desative o túnel multimédia se tiver um ecrã preto ou paragens na reprodução de vídeos.
Desativar túnel multimédia
Sempre que descarregar um ficheiro, terá que indicar o local para o guardar
- Ainda não foi definida uma pasta de descarregamento, escolha agora a pasta de descarregamento padrão
+ Ainda não definiu uma pasta para as descargas. Escolha agora a pasta a utilizar
%s fornece este motivo:
Conta encerrada
- O modo de feed rápido não fornece mais informações sobre isto.
+ O modo de fonte rápida não fornece mais informações sobre isto.
A conta do autor foi encerrada.
-\nNewPipe não será capaz de carregar este feed no futuro.
-\nQuer cancelar a inscrição deste canal\?
- Não foi possível carregar o feed para \'%s\'.
- Erro ao carregar o feed
- A partir do Android 10, apenas o \'Storage Access Framework\' é compatível
- Pré-visualização da miniatura da barra de pesquisa
+\nNewPipe não será capaz de carregar esta fonte.
+\nDeseja cancelar a subscrição deste canal?
+ Não foi possível carregar a fonte para \'%s\'.
+ Erro ao carregar a fonte
+ A partir de Android 10, apenas \'Storage Access Framework\' é compatível
+ Pré-visualização da miniatura na barra de pesquisa
Marcar como visto
Desligado
Ligado
Modo tablet
- Abrir site de web
- Entusiasmado pelo criador
+ Abrir site
+ Adorado pelo criador
Interno
Privado
Não listado
Público
Servidor
- Apoio
+ Suporte
Idioma
Limite de idade
Privacidade
Licença
- Marcadores
+ Etiquetas
Categoria
Desativar seleção de texto na descrição
Ativar seleção de texto na descrição
@@ -643,7 +643,7 @@
Não mostrar
Baixa qualidade (menor)
Alta qualidade (maior)
- Comentários estão desativados
+ 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 imagem
Sugestões de pesquisa remotas
@@ -658,112 +658,112 @@
- %s descargas concluídas
- %s descargas concluídas
- Deslizar itens para removê-los
+ Deslize nos itens para os remover
Não iniciar vídeos em mini-reprodutor e ativar ecrã completo, se a rotação automática estiver bloqueada. Pode aceder ao mini-reprodutor se sair do modo de ecrã completo.
Iniciar reprodutor principal em ecrã completo
- Enfileirado o próximo
- Pôr na fila o próximo
- A processar… Pode demorar um momento
+ Seguinte colocado na fila
+ Colocar seguinte na fila
+ A processar… Pode levar algum tempo
Procurar atualizações
Verificar manualmente se existe uma nova versão
A procurar atualizações…
Novos itens
- Travar o reprodutor
+ Terminou o reprodutor
Mostrar \"Travar o reprodutor\"
- Mostra uma opção de travamento ao usar o reprodutor
+ Mostra uma opção para terminar o reprodutor
Notificação para relatórios de erro
Notificações para reportar erros
NewPipe encontrou um erro, toque para reportar
Ocorreu um erro, veja a notificação
- Mostrar um snackbar de erro
+ Mostrar uma barra de erros
Criar uma notificação de erro
- Nenhum gestor de ficheiros apropriado foi encontrado para esta ação.
-\nPor favor, instale um gestor de ficheiros ou tente desativar \'%s\' nas configurações de descarregar
+ Não foi encontrado um gestor de ficheiros apropriado para esta ação.
+\nPor favor, instale um gestor de ficheiros ou tente desativar \'%s\' nas definições das descargas
Nenhum gestor de ficheiros apropriado foi encontrado para esta ação.
-\nPor favor, instale um gestor de ficheiros compatível com o Storage Access Framework
- Comentário fixado
- LeakCanary não está disponível
- Predefinido do ExoPlayer
+\nPor favor, instale um gestor de ficheiros compatível com SAF (Storage Access Framework)
+ Comentário afixado
+ LeakCanary não disponível
+ Predefinição ExoPlayer
Notificação do reprodutor
Configurar notificação da reprodução do vídeo atual
Notificações
A carregar detalhes do vídeo…
- Verificar se há novos vídeos
+ Procurar novos vídeos
Notificações sobre novos vídeos
- Notificar sobre novos vídeos nas assinaturas
+ Notificar sobre novos vídeos nas subscrições
Frequência da verificação
- Conexão de rede necessária
+ Requer uma ligação de rede
Qualquer rede
- Agora assinou este canal
+ É agora um subscritor deste canal
Alternar tudo
- Apagar todos os ficheiros descarregados do disco\?
+ Remover todos os ficheiros descarregados?
Novos vídeos
Notificações sobre novos vídeos nas subscrições
- - %s vídeo novo
- - %s vídeos novos
- - %s vídeos novos
+ - %s novo vídeo
+ - %s novos vídeos
+ - %s novos vídeos
- Seja notificado
- Notificações são desativadas
+ Obter notificação
+ As notificações estão desativadas
,
- Por cento
- Semitom
- As transmissões que ainda não são suportadas para descarregamento não são mostradas
- Não estão disponíveis transmissões de áudio a reprodutores externos
- Não estão disponíveis transmissões de vídeo a reprodutores externos
+ Percentual
+ Semi-tom
+ Os vídeos não suportadas para descarga não são mostradas
+ Não estão disponíveis reproduções de áudio para reprodutores externos
+ Não estão disponíveis reproduções de vídeo para reprodutores externos
Selecione a qualidade para reprodutores externos
Formato desconhecido
Qualidade desconhecida
- A transmissão selecionada não é suportada por reprodutores externos
+ O vídeo selecionado não é suportado por reprodutores externos
Tamanho do intervalo de carregamento da reprodução
Perguntas frequentes
Ver no site
- Se está a ter problemas a usar a aplicação, veja estas respostas para perguntas mais comuns!
- Ordenação
+ Se está a ter problemas a usar a aplicação, veja estas respostas para as perguntas mais comuns!
+ Ordem
Modo rápido
Importe ou exporte subscrições no menu 3 pontos
Já está a executar a versão mais recente do NewPipe
Toque para descarregar %s
Esta opção só está disponível se estiver selecionado %s para o tema
- Desativar miniatura permanente
+ Desativar miniatura permanentemente
Não foi possível copiar para a área de transferência
Cartão
As listas de reprodução acinzentadas já contêm este item.
- Duplicar adicionado %d vez(es)
- Ignorar eventos com botões físicos
+ Duplicado adicionado %d vez(es)
+ Ignorar botões físicos
Útil, por exemplo, se estiver a utilizar auscultadores com botões físicos danificados
Remover duplicados
Remover duplicados\?
Mostrar/ocultar vídeos
- Proximamente
- Quer remover todos os vídeos duplicados nesta lista de reprodução\?
+ Brevemente
+ Deseja remover todos os vídeos duplicados desta lista de reprodução?
Completamente visto
- Mostrar os seguintes vídeos
+ Mostrar vídeos seguintes
Parcialmente visto
- Ação do gesto para a esquerda
- Ação do gesto para a direita
+ Ação para o gesto à esquerda
+ Ação para o gesto à direita
Brilho
Volume
- Nenhum
- Escolha o gesto para a metade esquerda do ecrã do reprodutor
- Escolha o gesto para a metade direita do ecrã do reprodutor
+ Nada
+ Escolha o gesto para a parte esquerda do ecrã
+ Escolha o gesto para a parte direita do ecrã
Seleciona o áudio com descrição para pessoas com dificuldades de visão, se disponível
- Esta solução alternativa liberta e re-instancia os codificadores de vídeo quando ocorre uma alteração da superfície, em vez de definir diretamente a superfície para o codificador. Já utilizada pelo ExoPlayer em alguns dispositivos com este problema, esta configuração só tem efeito no Android 6 e superior
+ Esta solução alternativa liberta os codificadores de vídeo quando ocorre uma alteração da superfície, em vez de definir diretamente a superfície para o codificador. Já utilizada pelo ExoPlayer em alguns dispositivos com este problema, esta definição só tem efeito no Android 6 e superior
\n
-\nA activação desta opção pode evitar erros de reprodução ao mudar o leitor de vídeo atual ou ao mudar para ecrã inteiro
- Altera o tamanho do intervalo de carregamento progressivo (o atual é %s). Um valor menor pode acelerar o carregamento inicial do vídeo
+\nA ativação desta opção pode evitar erros de reprodução ao mudar o leitor de vídeo atual ou ao mudar para ecrã inteiro
+ Altera o tamanho do intervalo de carregamento progressivo (atualmente %s). Um valor menor pode acelerar o carregamento inicial do conteúdo
Dar preferência ao áudio original
Seleciona o áudio original, independentemente do idioma
Dar preferência ao áudio descritivo
Áudio: %s
Faixa de áudio
- Já deve existir uma faixa de áudio nesta transmissão
- Selecionar faixa de áudio para reprodutores externos
+ Já deve existir uma faixa de áudio neste vídeo
+ Selecione a faixa de áudio para reprodutores externos
Desconhecida
- Configurações ExoPlayer
- Gere algumas configurações de ExoPlayer. É necessário reiniciar o reprodutor para aplicar as alterações
- Utilizar a função de fallback do descodificador do ExoPlayer
+ Definições ExoPlayer
+ Gere algumas definições ExoPlayer. Tem que reiniciar o reprodutor para aplicar as alterações
+ Utilizar descodificador se recurso do ExoPlayer
Ative esta opção se tiver problemas de inicialização do descodificador, que retorna codificadores de baixa prioridade se o descodificador primário falhar. Isto pode resultar num desempenho inferior de reprodução
Usar sempre a configuração de saída alternativa de vídeo do ExoPlayer
%1$s %2$s
@@ -772,12 +772,12 @@
descritivo
Mova o seletor do separador principal para a parte inferior
Posição dos separadores principais
- O túnel multimédia foi desativado por predefinição no seu dispositivo porque se sabe que o modelo do dispositivo não o suporta.
+ O túnel multimédia foi desativado no seu dispositivo porque o seu dispositivo não tem suporte à opção.
Nenhum vídeo em direto
Nenhum vídeo
A carregar metadados…
Obter separadores de canais
- Separadores a obter ao atualizar o feed. Esta opção não tem efeito se um canal for atualizado utilizando o modo rápido.
+ Separadores a obter ao atualizar a fonte. Esta opção não tem efeito se um canal for atualizado utilizando o modo rápido.
Qualidade da imagem
Vídeos
\?
@@ -793,7 +793,7 @@
Baixa qualidade
Alternar ecrã completo
Avatars
- Fluxo seguinte
+ Vídeo seguinte
Avatar de subcanais
Abrir fila de reprodução
Não carregar imagens
@@ -815,8 +815,16 @@
Faixas
Duração
Canais
- Fluxo anterior
+ Vídeo anterior
Direto
Partilhe a lista de reprodução com detalhes como o nome da lista de reprodução e os títulos dos vídeos ou como uma simples lista de URLs de vídeos
Escolha a qualidade das imagens e se pretende carregar imagens, para reduzir a utilização de dados e de memória. As alterações limpam a cache de imagens na memória e no disco - %s
+ Mostrar mais
+
+ - %s resposta
+ - %s respostas
+ - %s respostas
+
+ Mostrar menos
+ Edite cada ação de notificação abaixo a tocar nela. As três primeiras ações (reproduzir/pausa, anterior e seguinte) são definidas pelo sistema e não podem ser personalizadas.
\ No newline at end of file
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 42e23c3a428..bc3b81e1e6b 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -176,7 +176,7 @@
Niciun player pentru streaming găsit. (Totuși, puteți instala VLC).
Descărcați fișierul de flux
Afișare informații
- Playlist-uri salvate
+ Playlisturi salvate
Salvare în
Folosește parcurgerea rapidă inexactă
Derularea inexactă permite player-ului să deruleze mai rapid, cu o precizie redusă. Derularea timp de 5, 15 sau 25 de secunde nu funcționează cu aceasta
@@ -363,7 +363,7 @@
Redare aleatorie
Repetare
Puteți selecta cel mult trei acțiuni pentru afișare în notificarea compactă!
- Modificați fiecare acțiune de notificare de mai jos, atingând-o. Selectați până la trei dintre ele pentru a fi afișate în notificarea compactă, utilizând casetele de selectare din dreapta
+ Modifică fiecare acțiune de notificare de mai jos, atingând-o. Selectează până la trei dintre ele pentru a fi afișate în notificarea compactă, utilizând casetele de selectare din dreapta.
Al cincilea buton de acțiune
Al patrulea buton de acțiune
Al treilea buton de acțiune
@@ -604,7 +604,7 @@
Aceasta este o piesă SoundCloud Go+, cel puțin în țara dvs., deci nu poate fi difuzată sau descărcată de NewPipe.
Acest conținut nu este disponibil în țara dumneavoastră.
Afișați detaliile canalului
- Temă Nocturnă
+ Tema de noapte
Următorul pus în coadă
Adăugați în coadă pe următorul
Marcare ca vizionat
@@ -627,7 +627,7 @@
Categorie
Dezactivați selectarea textului în descriere
Activați selectarea textului în descriere
- Acum puteți selecta text în interiorul descrierii. Rețineți că este posibil ca pagina să pâlpâie, iar link-urile să nu poată fi accesate în modul de selecție.
+ Acum puteți selecta text în interiorul descrierii. Rețineți că este posibil ca pagina să pâlpâie, iar linkurile să nu poată fi accesate în modul de selecție.
%s oferă acest motiv:
Contul a fost închis
Modul rapid nu furnizează mai multe informații în acest sens.
@@ -817,4 +817,15 @@
Transmisia anterioară
Alegeți un gest pentru jumătatea stângă din ecranul playerului
În direct
+ Shorturi
+ Avatarele autorului
+ Editează fiecare acțiune de notificare de mai jos atingând-o. Primele trei acțiuni (redare/pauză, anterioară și următoare) sunt setate de sistem și nu pot fi personalizate.
+
+ - %s răspuns
+ - %s răspunsuri
+ - %s răspunsuri
+
+ Arată mai multe
+ Arată mai puține
+ Piste
\ No newline at end of file
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 63d576594ec..32454ae7268 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -78,7 +78,7 @@
Аудио
Повтор
Не удалось загрузить все миниатюры
- В фоне
+ Фон
В окне
Только некоторые устройства поддерживают видео в 2K/4K
Формат видео по умолчанию
@@ -562,7 +562,7 @@
Перемешать
Повтор
В компактном уведомлении доступно не более трёх действий!
- Действия можно изменить, нажав на них. Отметьте не более трёх для отображения в компактном уведомлении
+ Отредактируйте каждое действие уведомления ниже, нажав на него. Выберите до трёх из них, которые будут отображаться в компактном уведомлении, используя флажки справа.
Пятое действие
Четвёртое действие
Третье действие
@@ -789,7 +789,7 @@
%1$s
\n%2$s
Вкладки канала
- Shorts
+ Шорты
Загрузка метаданных…
Изменить ориентацию экрана
Низкое качество
@@ -823,4 +823,13 @@
Каналы
Предыдущий стрим
Живая трансляция
+ Показать больше
+ Показать меньше
+
+ - %s ответ
+ - %s ответа
+ - %s ответов
+ - %s ответов
+
+ Отредактируйте каждое действие уведомления ниже, нажав на него. Первые три действия (воспроизведение/пауза, предыдущее и следующее) задаются системой и не подлежат настройке.
\ No newline at end of file
diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml
index abd1f089b65..dab5815dbd5 100644
--- a/app/src/main/res/values-ryu/strings.xml
+++ b/app/src/main/res/values-ryu/strings.xml
@@ -318,7 +318,7 @@
うんじゅがID, soundcloud.com/うんじゅがid
くぬあしっさにゆりちうしんりょうきんがかじゅーいるくとぅがあいびーん。ぐちゅういください。
\n
-\nずっこうさびーが\?
+\nずっこうさびーが?
とうるくさゃすう
すくどぅとぅうんていりんちゃーさじんかいへいるかん(ゆがむんかむしりやびらん)
むうんぬあいだにはやうくり
@@ -330,7 +330,7 @@
みーさるNewPipeバージョンぬちうち
がいぶちうちゅるすうちはりようなやびらん
っちいちんかいむどぅすん
- きていぬしっていふちゅるぎんさびーが\?
+ きていぬしっていふちゅるぎんさびーが?
とうるくさゃすうはりようでぃきましん
がいぎ
ヨーロッパぬいちぱんデータふぐきせい(GDPR)にじゅんきょしーんたみに、NewPipeぬくじんじょうほうふぐほうしんにぐちゅういください。ゆーゆでぃくぃみそーれー。
@@ -369,7 +369,7 @@
ダウンロードちゅうしするまでぃぬさちゃるいさいしこうかいすん
ファイルさちゅるじょさびたん
アプリぬこうしんちうち
- やしがいぶSDカードんかいダウンロードなやびらん。ダウンロードフォルダーぬばしょリセットさびーが\?
+ やしがいぶSDカードんかいダウンロードなやびらん。ダウンロードフォルダーぬばしょリセットさびーが?
ふずんさったるタブゆみくみらんたみ、デフォルトぬタブしーようさびーん
メインページんかいひょうじさりーるタブ
みーさるバージョンがいようかのうなとぅちにアプリぬこうしんかくにんすんちうちひょうじさびーん
@@ -394,7 +394,7 @@
ファイルぬさぎょうちゅうにNewPipeぬくーららりやびたん
デバイスんかいにりらりょうぬあいびらん
ファイルぬさちゅるじょさったるたみ、しんこうじょうちゅーがうしならりやびたん
- ダウンロードりりき、あらんでぃダウンロードさるファイルしーょうきょさびーが\?
+ ダウンロードりりき、あらんでぃダウンロードさるファイルしーょうきょさびーが?
ダウンロードキューぬせいぎん
どうじーがてぃーちぬダウンロードぬじっこうさりやびーん
ダウンロードぬかいし
@@ -406,7 +406,7 @@
ストレージアクセスフレームワークー、がいぶSDカードんかいぬダウンロードぬかのうやいびーん
さいせいいちのさくじょ
まじりぬさいせいいちさちゅるじょさびーん
- まじりぬさいせいいちさちゅるじょさびーが\?
+ まじりぬさいせいいちさちゅるじょさびーが?
サービスぬきりけーい、ぎんじぇーぬしんたく:
- %sふんぬちゃーしが
@@ -541,7 +541,7 @@
URLにいるしちなやびらんたん。ふかぬアプリっしふぃらちゃびーが?
ちまーにひょうじさりーるサムネイル16:9からせいほうけいなさびーん
サムネイルせいほうけいなすん
- いかタップしちうちぬアクションへんしゅうさびーん。みぎぬわんかいあんチェックボックスしーようしコンパクトやるちまーにひょうじすし3ちまっししんたくさびーん
+ いかタップしちうちぬアクションへんしゅうさびーん。みぎぬわんかいあんチェックボックスしーようしコンパクトやるちまーにひょうじすし3ちまっししんたくさびーん。
コンパクトやるちまーにひょうじさりーるアクションー3ちまっしいらぶるくとぅがなやびーん!
5ばんみぬアクションボタン
4ばんみぬアクションボタン
@@ -718,9 +718,9 @@
はいーらでぃひょうじさっとーるプレイリストんかえー、しでぃにくぬアイテムぬくくまっとーいびーん。
%dかいじゅうふくちいかさりやびたん
くていサムネイルぬしっていこーいじょ
- じゅうふくさくじょさびーが\?
+ じゅうふくさくじょさびーが?
たとぅいねー、ぶちりボタンぬやんでぃたるヘッドセットしーようそーーあいにびんりやいびーん
- くぬさいせいリストねーんぬじゅうふくさるストリームまじりさくじょさびーが\?
+ くぬさいせいリストねーんぬじゅうふくさるストリームまじりさくじょさびーが?
ハードウェアメディアボタンイベントむしすん
じゅうふくさちゅるじょ
ちぎぬストリームひょうじ
@@ -806,4 +806,11 @@
プレイリストちゅーゆーいん
プレイリストめいてぃがろービデオタイトルんでーぬしょうさいくくむるプレイリスト、あらんでぃビデオURLぬみぬシンプルやるリストとぅしてぃプレイリストちゅーゆーいんさびーん
- %1$s: %2$s
+
+ - %sぬへんしん
+ - %sぬへんしん
+
+ なーふぃんんーじゅん
+ ひょうじいきらくすん
+ いかぬちうちアクションタップしへんしゅうさびーん。さいしょぬみーちぬアクション (さいせい/いちじていし、めーんかい、ちぎんかい)ーシステムにゆってぃしっていさりてぃうぅい、カスタマイズすしぇーなやびらん。
\ No newline at end of file
diff --git a/app/src/main/res/values-sat/strings.xml b/app/src/main/res/values-sat/strings.xml
index 836ab01c3f9..65dbffbaef2 100644
--- a/app/src/main/res/values-sat/strings.xml
+++ b/app/src/main/res/values-sat/strings.xml
@@ -59,7 +59,7 @@
ᱛᱮᱥᱟᱨ ᱠᱟᱹᱢᱤ ᱵᱩᱛᱟᱹᱢ
ᱫᱚᱥᱟᱨ ᱠᱟᱹᱢᱤ ᱵᱩᱛᱟᱹᱢ
ᱢᱟᱲᱟᱝ ᱠᱟᱹᱢᱤ ᱵᱩᱛᱟᱹᱢ
- ᱛᱷᱟᱹᱢᱵᱽᱱᱮᱞ ᱫᱚ ᱑:᱑ ᱮᱥᱯᱮᱠᱼᱴ ᱨᱮᱥᱤᱭᱚ ᱨᱮ ᱢᱟᱯ ᱢᱮ
+ ᱛᱷᱟᱹᱢᱵᱽᱱᱮᱞ ᱫᱚ ᱑:᱑ ᱮᱥᱯᱮᱠᱼᱴ ᱨᱮᱥᱤᱭᱚ ᱨᱮ ᱜᱮᱫ ᱟᱠᱟᱱᱟ
ᱴᱷᱤᱠ
ᱥᱟᱰᱮ
ᱧᱮᱞ ᱠᱟᱱ ᱞᱮᱠᱷᱟ ᱪᱤᱱᱦᱟᱹ ᱠᱟᱜ ᱢᱮ
@@ -69,4 +69,689 @@
ᱧᱩᱛ
ᱧᱩᱛ ᱛᱷᱤᱢ
ᱦᱮᱱᱫᱮ
+ ᱪᱮᱛᱟᱱ ᱥᱤᱠᱷᱱᱟᱹᱛ (ᱢᱟᱨᱟᱝ)
+ %1$s %2$s
+ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱡᱚᱛᱚ ᱠᱷᱚᱱ ᱱᱟᱯᱟᱭ ᱨᱩᱣᱟᱹ
+ ᱦᱟᱹᱴᱤᱧ ᱪᱷᱟᱯᱟ ᱟᱠᱟᱱᱟ
+ ᱢᱤᱰᱤᱭᱟ ᱴᱚᱱᱮᱞᱤᱝ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱥᱟᱱᱟᱢ ᱚᱵᱚᱫᱷᱤ
+ ᱰᱤᱯᱷᱚᱞᱴ ᱥᱟᱰᱮ ᱯᱷᱚᱨᱢᱮᱴ
+ ᱧᱮᱞ ᱱᱟᱜᱟᱢ
+ ᱠᱷᱤᱞᱚᱱᱰ ᱮᱦᱚᱵ ᱢᱮ
+ ᱴᱨᱮᱠ
+ ᱤᱢᱯᱳᱨᱴ ᱰᱮᱴᱟᱵᱮᱥ
+ ᱪᱷᱟᱸᱪ
+ ᱟᱢᱟᱜ ᱟᱭᱳ ᱟᱲᱟᱝ, ᱰᱤᱡᱟᱭᱤᱱ ᱵᱮᱵᱚᱥᱛᱟ, ᱠᱳᱰ ᱥᱟᱹᱠᱷᱭᱟᱹᱛ, ᱟᱨᱵᱟᱝ ᱟᱹᱰᱤ ᱢᱟᱨᱟᱝ ᱠᱳᱰ ᱵᱮᱵᱚᱥᱛᱟ ᱨᱮᱱᱟᱜ ᱟᱭᱳ ᱟᱲᱟᱝ ᱢᱮᱱᱟᱜᱼᱟ ⁇ ᱜᱚᱲᱚ ᱫᱚ ᱡᱚᱛᱚ ᱚᱠᱛᱚ ᱨᱮᱜᱮ ᱥᱟᱨᱦᱟᱣ ᱢᱮᱱᱟᱜᱼᱟ ᱾ ᱰᱤᱜᱟᱱ ᱠᱟᱹᱢᱤ ᱦᱩᱭ ᱞᱮᱱ ᱠᱷᱟᱱ ᱚᱱᱟ ᱜᱮ ᱱᱟᱯᱟᱭᱚᱜ-ᱟ ᱾
+ GitHub ᱨᱮ ᱧᱮᱞ ᱢᱮ
+ ᱡᱟᱹᱥᱛᱤ ᱞᱟᱭᱠᱟᱨ
+ ᱰᱟᱩᱱᱞᱚᱰ ᱟᱠᱟᱱ ᱯᱷᱤᱞᱤᱯ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱰᱤᱥᱠ ᱠᱷᱚᱱ ᱡᱚᱛᱚ ᱰᱟᱩᱱᱞᱚᱰ ᱟᱠᱟᱱ ᱯᱷᱤᱞ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ?
+ ᱨᱮᱰᱤᱭᱳ
+ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ
+ ᱜᱽᱨᱤᱰ
+ ᱥᱴᱚᱯ
+ ᱰᱟᱩᱱᱞᱚᱰ ᱞᱤᱢᱤᱴᱮᱰ ᱠᱩᱣᱮ
+ ᱢᱩᱬᱩᱛ ᱴᱮᱵᱽ ᱵᱟᱪᱷᱟᱣᱤᱭᱟᱹ ᱫᱚ ᱞᱟᱛᱟᱨ ᱨᱮ ᱞᱟᱜᱟᱜ ᱢᱮ
+ ᱵᱞᱮᱠ ᱥᱟᱦᱴᱟ
+ ᱠᱟᱨᱰ
+ ᱵᱟᱦᱨᱮ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱠᱚ ᱞᱟᱹᱜᱤᱫ ᱵᱷᱤᱰᱤᱭᱳ ᱥᱴᱨᱤᱢ ᱵᱟᱭ ᱧᱟᱢᱚᱜ ᱠᱟᱱᱟ
+ ᱵᱟᱦᱨᱮ ᱮᱱᱮᱡᱤᱭᱟᱹ ᱠᱚ ᱞᱟᱹᱜᱤᱫ ᱛᱮ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱵᱟᱝ ᱵᱟᱰᱟᱭ ᱟᱠᱟᱱ ᱯᱷᱚᱨᱢᱮᱴ
+ ᱵᱟᱹᱱᱩᱜᱼᱟ ᱫᱟᱜ
+ ᱱᱚᱶᱟ ᱞᱟᱹᱠᱛᱤᱭᱟᱱ ᱞᱟᱹᱠᱛᱤ ᱠᱟᱱᱟ_x000D_
+\nᱯᱚᱯ-ᱟᱯ ᱢᱚᱰ ᱨᱮ ᱮᱛᱦᱚᱵ ᱢᱮ
+ ᱡᱚᱠᱷᱚᱱ ᱥᱟᱦᱟᱣ ᱟᱠᱟᱱᱟ \"Done\" ᱚᱞ ᱢᱮ
+ ᱨᱩᱣᱟ.
+ ᱠᱤᱭᱳᱥᱠ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱱᱟᱣᱟ ᱟᱨ ᱦᱮᱴ
+ ᱱᱟᱦᱟᱜ ᱥᱮᱞᱮᱫ ᱟᱠᱟᱱᱟ
+ ᱪᱟᱱᱮᱞ ᱵᱟᱰᱟᱭ ᱧᱮᱞ ᱢᱮ
+ ᱤᱱᱠᱭᱩᱤᱝ
+ ᱮᱱᱠᱭᱩᱣᱮᱰ
+ ᱚᱛᱱᱚ ᱨᱮ ᱥᱮᱞᱮᱫ ᱮᱛᱚᱦᱚᱵ ᱢᱮ
+ ᱡᱚᱛᱚ ᱚᱠᱛᱚ ᱯᱮᱨᱮᱡ ᱢᱮ
+ ᱤᱱᱯᱷᱳ ᱧᱟᱢ…
+ ᱞᱟᱹᱠᱛᱤ ᱟᱠᱟᱱ ᱥᱟᱦᱴᱟ ᱞᱚᱰ ᱮᱱᱟ
+ ᱧᱩᱛᱩᱢ
+ ᱥᱮᱨᱮᱧ ᱞᱤᱥᱴᱤ ᱨᱮ ᱥᱮᱞᱮᱫᱽ ᱢᱮ
+ ᱠᱟᱹᱢᱤᱦᱚᱨᱟ... ᱚᱠᱛᱚ ᱫᱷᱟᱹᱵᱤᱡ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ
+ ᱠᱨᱟᱥ ᱴᱷᱮᱱ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ
+ ᱟᱢᱟᱜ ᱚᱱᱚᱞ ᱨᱮ ᱢᱤᱰᱤᱭᱟ ᱴᱩᱱᱮᱞᱤᱝ ᱫᱚ ᱰᱤᱯᱚᱞᱴ ᱞᱮᱠᱟᱛᱮ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ ᱪᱮᱫᱟᱜ ᱥᱮ ᱟᱢᱟᱜ ᱚᱱᱚᱞ ᱢᱚᱰᱮᱞ ᱱᱚᱶᱟ ᱵᱟᱭ ᱥᱚᱦᱚᱫᱟ ᱾
+ ᱮᱯᱞᱤᱠᱮᱥᱚᱱ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱢᱤᱫ error ᱥᱱᱮᱠᱵᱟᱨ ᱧᱮᱞ ᱢᱮ
+ URL ᱥᱮ ᱟᱢᱟᱜ ID ᱚᱞ ᱠᱟᱛᱮᱜ ᱢᱤᱫ SoundCloud ᱯᱨᱚᱯᱷᱟᱭᱤᱞ ᱮᱢ ᱢᱮ:_x000D_
+\n_x000D_
+\n1. ᱢᱤᱫ ᱣᱮᱵᱽ-ᱵᱽᱨᱟᱣᱡᱚᱨ ᱨᱮ \"ᱰᱮᱥᱠᱴᱚᱯ ᱢᱳᱰ\" ᱮᱱᱮᱡ ᱢᱮ (ᱡᱚᱵᱮᱛᱟᱨᱮ ᱢᱚᱵᱟᱭᱤᱞ ᱰᱤᱵᱟᱤᱥ ᱞᱟᱹᱜᱤᱫ ᱵᱟᱝ ᱧᱟᱢᱚᱜᱼᱟ)_x000D_
+\n2. ᱱᱚᱶᱟ URL ᱨᱮ ᱪᱟᱞᱟᱜ ᱢᱮ: %1$s_x000D_
+\n3. ᱞᱚᱜᱤᱱ ᱢᱮ ᱡᱚᱠᱷᱚᱱ ᱞᱟᱹᱠᱛᱤ ᱠᱟᱱᱟ_x000D_
+\n4. ᱟᱢ ᱚᱠᱟ ᱨᱮ ᱥᱮᱞᱮᱫ ᱞᱮᱱᱟᱢ ᱚᱱᱟ ᱯᱨᱚᱯᱷᱟᱭᱤᱞ URL ᱠᱚᱯᱤ ᱢᱮ.
+ ᱯᱞᱮᱵᱮᱠ ᱥᱯᱤᱰ ᱠᱚᱱᱴᱨᱚᱞ
+ ᱴᱮᱢᱯᱳ
+ ᱵᱚᱫᱚᱞ ᱢᱮ (ᱵᱚᱫᱚᱞ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ)
+ ᱥᱤᱛᱩᱝ ᱚᱠᱛᱚ ᱨᱮ ᱯᱷᱮᱥᱯᱷᱚᱨᱰ ᱢᱮ
+ ᱯᱨᱚ᱐ᱤᱥᱚᱫ
+ ᱮᱠᱥᱮᱯᱴ
+ ᱱᱟᱣᱟ ᱥᱴᱨᱚᱢ ᱨᱮᱭᱟᱜ ᱠᱷᱚᱵᱚᱨ
+ ᱪᱟᱪᱞᱟᱣ ᱚᱵᱚᱥᱛᱟ
+ ᱱᱟᱣᱟ ᱥᱟᱦᱴᱟ ᱧᱮᱞ ᱢᱮ
+ ᱛᱷᱟᱯᱚᱱ
+ ᱱᱚᱶᱟ ᱧᱩᱛᱩᱢ ᱟᱱᱟᱜ ᱢᱤᱫ ᱯᱷᱤᱞ ᱢᱮᱱᱟᱜᱼᱟ
+ ᱱᱚᱶᱟ ᱧᱩᱛᱩᱢ ᱟᱱ ᱢᱤᱫ ᱰᱟᱩᱱᱞᱚᱰ ᱟᱠᱟᱱ ᱯᱷᱤᱞ ᱢᱮᱱᱟᱜᱼᱟ
+ ᱥᱤᱠᱷᱱᱟᱹᱛ ᱡᱚᱱᱚᱲᱟᱣ ᱵᱟᱭ ᱛᱮᱭᱟᱨ ᱫᱟᱲᱮᱭᱟᱜ ᱠᱟᱱᱟ
+ ᱡᱟᱦᱟᱸ ᱨᱮ ᱰᱟᱩᱱᱞᱚᱰ ᱢᱮ
+ ᱮᱠᱥᱳᱯᱞᱮᱭᱟᱨ ᱞᱟᱹᱠᱛᱤᱭᱟᱜ ᱞᱟᱹᱠᱛᱤᱭᱟᱜ ᱞᱟᱹᱠᱛᱤᱭᱟᱜ ᱚᱠᱛᱚ %d ᱥᱮᱠᱮᱱᱰ ᱨᱮ ᱞᱟᱜᱟᱣ ᱟᱠᱟᱱᱟ
+ ᱪᱮᱫ ᱱᱟᱣᱟ
+ ᱵᱟᱦᱨᱮ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹᱠᱚ ᱵᱟᱠᱚ ᱥᱚᱦᱚᱫ ᱟᱠᱟᱫ ᱪᱷᱟᱸᱪ
+ ᱵᱟᱦᱨᱮ ᱯᱞᱮᱭᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱚᱰᱤᱭᱚ ᱥᱴᱨᱤᱢ ᱵᱟᱭ ᱧᱟᱢᱚᱜ ᱠᱟᱱᱟ
+ ᱚᱥᱚᱞ
+ ᱥᱮᱨᱮᱧ
+ ᱱᱟᱣᱟ
+ ᱱᱚᱶᱟ ᱨᱮ ᱴᱟᱯ ᱠᱟᱛᱮ ᱞᱟᱛᱟᱨ ᱨᱮ ᱮᱢ ᱟᱠᱟᱱ ᱡᱚᱛᱚ ᱱᱤᱯᱷᱩᱴ ᱮᱠᱥᱚᱱ ᱥᱟᱯᱲᱟᱣ ᱢᱮ ᱾ ᱯᱩᱭᱞᱩ ᱯᱮᱭᱟ ᱠᱟᱹᱢᱤ (ᱯᱞᱮ/ᱯᱷᱟᱣᱩᱥ, ᱯᱩᱭᱞᱩ ᱟᱨ ᱛᱟᱭᱚᱢ) ᱫᱚ ᱥᱤᱥᱴᱚᱢ ᱦᱚᱛᱮᱛᱮ ᱥᱮᱴᱮᱨ ᱟᱠᱟᱱᱟ ᱟᱨ ᱱᱚᱣᱟ ᱠᱚ ᱟᱹᱨᱤᱪᱟᱹᱞᱤ ᱛᱮ ᱵᱟᱭ ᱵᱚᱫᱚᱞ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱾
+ ᱟᱱᱰᱨᱚᱭᱮᱰ ᱴᱷᱟᱹᱣᱠᱟᱹ ᱟᱠᱟᱱ ᱪᱤᱛᱟᱹᱨ ᱨᱮ ᱢᱩᱬ ᱪᱤᱛᱟᱹᱨ ᱞᱮᱠᱟᱛᱮ ᱱᱤᱯᱷᱩᱴ ᱪᱤᱛᱟᱹᱨ ᱨᱮᱱᱟᱜ ᱨᱚᱝ ᱵᱮᱱᱟᱣ ᱢᱮ (ᱱᱚᱶᱟ ᱡᱚᱛᱚ ᱰᱤᱵᱟᱤᱥ ᱨᱮ ᱵᱟᱝ ᱧᱟᱢᱚᱜᱼᱟ)
+ ᱴᱟᱴᱠᱟ ᱜᱩᱱᱠᱚ ᱢᱚᱱᱮ ᱠᱟᱜ ᱢᱮ
+ ᱯᱷᱮᱥᱯᱷᱚᱨᱰ/ᱨᱟᱭᱣᱤᱞᱰ ᱥᱮᱪᱮᱛ ᱚᱠᱛᱚ
+ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱚ ᱞᱟᱹᱜᱤᱫ, ᱡᱩᱫᱤ ᱟᱢ ᱡᱟᱦᱟᱸᱭ ᱵᱷᱤᱛᱨᱤ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱ ᱵᱷᱤᱛᱨᱤ ᱵᱚᱫᱚᱞ ᱛᱮ ᱦᱮᱰᱥᱮᱴ ᱠᱚ ᱵᱮᱵᱷᱟᱨ ᱮᱫᱟ
+ ᱴᱤᱯᱚᱬᱤ ᱠᱚ ᱧᱮᱞ ᱢᱮ
+ ᱵᱷᱤᱰᱤᱭᱳ ᱵᱟᱵᱚᱫᱽ ᱟᱨ ᱮᱴᱟᱜ ᱵᱟᱰᱟᱭ ᱞᱟᱹᱜᱤᱫ ᱱᱚᱶᱟ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱪᱤᱛᱟᱹᱨ ᱠᱮᱪ ᱵᱚᱫᱚᱞ
+ ᱠᱟᱪᱷ ᱢᱮᱴᱟᱰᱮᱴᱟ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱥᱟᱱᱟᱢ ᱠᱮᱪ ᱟᱠᱟᱱ ᱣᱮᱵᱽ ᱯᱮᱡ ᱨᱮᱱᱟᱜ ᱰᱮᱴᱟ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱥᱠᱨᱤᱱ ᱨᱮᱱᱟᱜ ᱪᱮᱛᱟᱱ ᱨᱮ ᱪᱤᱱᱦᱟᱹ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱵᱷᱚᱞᱚᱢ
+ ᱡᱟᱦᱟᱱ ᱵᱟᱝ
+ ᱛᱚᱨᱡᱚᱢᱟ ᱱᱟᱜᱟᱢ
+ ᱞᱚᱠᱟᱞ ᱞᱮᱠᱟᱛᱮ ᱥᱩᱪᱚᱱᱟ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱞᱤᱥᱴᱤ ᱨᱮ ᱯᱳᱡᱤᱥᱚᱱ
+ ᱞᱤᱥᱴᱤ ᱨᱮ ᱯᱞᱮᱼᱯᱷᱚᱞ ᱯᱳᱡᱤᱥᱚᱱ ᱤᱱᱰᱮᱠᱴᱚᱨ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱥᱟᱱᱛᱟᱲᱤ ᱚᱱᱚᱞ
+ enqueue ᱴᱤᱯ ᱞᱟᱹᱜᱤᱫ ᱫᱚᱦᱚᱭ ᱢᱮ
+ Details: ᱨᱮ ᱵᱷᱤᱰᱤᱭᱳ ᱨᱮ ᱯᱷᱚᱱ ᱥᱮ ᱯᱚᱯᱯᱟᱯ ᱵᱩᱛᱟᱹᱢ ᱞᱟᱜᱟᱣ ᱞᱮᱠᱷᱟᱱ ᱴᱤᱯ ᱮᱢ ᱢᱮ
+ %s ᱨᱮ ᱟᱢᱟᱜ ᱞᱟᱹᱠᱛᱤ ᱠᱚ ᱧᱮᱞ ᱢᱮ
+ ᱱᱟᱜᱟᱢ ᱟᱨ ᱠᱷᱟᱪ
+ ᱧᱮᱧᱮᱞ
+ ᱰᱤᱵᱩᱜ
+ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱵᱟᱰᱟᱭ
+ ᱛᱷᱚᱠ ᱨᱮ ᱥᱮᱞᱮᱫᱚᱜ
+ ᱱᱚᱶᱟ ᱵᱷᱤᱰᱤᱭᱳ ᱫᱚ ᱩᱢᱮᱨ ᱦᱟᱹᱴᱤᱧ ᱠᱟᱱᱟ._x000D_
+\n_x000D_
+\nᱡᱩᱫᱤ ᱟᱢ ᱱᱚᱶᱟ ᱧᱮᱞᱢᱮ ᱠᱷᱟᱱ ᱟᱢᱟᱜ ᱥᱤᱴᱤᱝ ᱨᱮ %1$s\" ᱚᱞ ᱢᱮ ᱾\"
+ ᱰᱟᱩᱱᱞᱚᱰ
+ ᱰᱟᱩᱱᱞᱚᱰ
+ ᱟᱞᱵᱚᱢ
+ ᱟᱨᱴᱤᱥᱴ ᱠᱚ
+ ᱵᱷᱮᱜᱟᱨ ᱦᱚᱲ
+ ᱠᱞᱟᱨ
+ ᱱᱤᱭᱩ ᱯᱟᱭᱯᱮ ᱨᱮᱱᱟᱜ ᱯᱞᱮᱭᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱱᱳᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ
+ ᱵᱷᱤᱰᱤᱭᱳ ᱦᱟᱥᱤᱝ ᱯᱨᱚᱜᱨᱮᱥ ᱞᱟᱹᱜᱤᱫ ᱠᱷᱚᱵᱚᱨ
+ ᱱᱟᱣᱟ ᱫᱟᱨᱮ ᱠᱚ
+ ᱥᱮᱞᱮᱫ ᱞᱟᱹᱜᱤᱫ ᱱᱟᱣᱟ ᱥᱴᱨᱚᱢ ᱠᱚ ᱵᱟᱰᱟᱭ ᱦᱚᱪᱚ
+ ᱵᱟᱹᱲᱤᱡ ᱠᱚ ᱞᱟᱹᱜᱤᱫ ᱠᱷᱚᱵᱚᱨ ᱠᱚ
+ [ᱱᱚᱣᱟ ᱵᱟᱰᱟᱭᱚᱜ ᱠᱟᱱᱟ]
+ reCAPTCHA ᱠᱩᱠᱤ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ reCAPTCHA ᱠᱩᱠᱤ ᱠᱚ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ
+ ᱮᱠᱥᱯᱳᱨᱴ ᱦᱤᱥᱛᱟ, ᱥᱚᱵᱽᱥᱠᱨᱟᱭᱵᱮᱥᱚᱱ, ᱯᱞᱮ ᱞᱤᱥᱴ ᱟᱨ ᱥᱮᱴᱤᱝ
+ ᱧᱮᱞ ᱛᱟᱵᱩᱱ ᱯᱮ ᱱᱟᱜᱟᱢ
+ ᱠᱷᱮᱞ ᱟᱠᱟᱱ ᱥᱴᱨᱤᱢ ᱨᱮᱱᱟᱜ ᱱᱟᱜᱟᱢ ᱟᱨ ᱠᱷᱮᱞ ᱟᱠᱟᱱ ᱯᱳᱡᱤᱥᱚᱱ ᱠᱚ ᱵᱚᱫᱚᱞᱟ
+ ᱥᱟᱱᱟᱢ ᱧᱮᱞ ᱱᱟᱜᱟᱢ ᱵᱚᱫᱚᱞ ᱢᱮ?
+ ᱧᱮᱞ ᱛᱟᱵᱩᱱ ᱯᱮ
+ ᱵᱟᱦᱨᱮ ᱥᱴᱳᱨᱮᱡ ᱵᱟᱭ ᱧᱟᱢᱚᱜ
+ ᱧᱮᱞ ᱛᱟᱵᱩᱱ ᱯᱮ ᱺ
+ ᱦᱟᱛᱟᱝ ᱢᱚᱰ
+ ᱢᱩᱬᱩᱛ ᱴᱮᱵᱽ ᱨᱮᱱᱟᱜ ᱴᱷᱟᱶ
+ ᱵᱟᱦᱨᱮ SD ᱠᱟᱨᱰ ᱨᱮ ᱰᱟᱩᱱᱞᱚᱰ ᱦᱚᱪᱚ ᱵᱟᱝ ᱜᱟᱱᱚᱜ ᱟ. ᱰᱟᱩᱱᱞᱚᱰ ᱯᱷᱳᱞᱰᱟᱨ ᱞᱚᱠᱮᱥᱚᱱ ᱨᱤᱥᱮᱴ ᱢᱮ ?
+ ᱡᱚᱛᱚ ᱪᱤᱛᱟᱹᱨ ᱠᱚ ᱞᱚᱰ ᱵᱟᱝ ᱜᱟᱱᱚᱜ ᱠᱟᱱᱟ
+ ᱣᱮᱵᱽᱥᱟᱭᱤᱴ ᱵᱟᱭ ᱯᱟᱨᱥ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ
+ ᱥᱟᱦᱴᱟ ᱵᱟᱹᱱᱩᱜ-ᱟ
+ ᱵᱟᱦᱨᱮ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱠᱚ ᱱᱚᱝᱠᱟᱱ ᱡᱚᱱᱚᱲ ᱠᱚ ᱵᱟᱠᱚ ᱥᱚᱦᱚᱫᱟ
+ ᱡᱟᱦᱟᱱ ᱵᱷᱤᱰᱤᱭᱳ ᱥᱴᱨᱤᱢ ᱵᱟᱝ ᱧᱟᱢ ᱟᱠᱟᱱᱟ
+ ᱚᱰᱤᱭᱳ ᱥᱴᱨᱤᱢ ᱵᱟᱝ ᱧᱟᱢ ᱟᱠᱟᱱᱟ
+ ᱢᱤᱫ ᱵᱷᱩᱞ ᱦᱩᱭ ᱞᱮᱱᱟ, ᱱᱤᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ ᱧᱮᱞ ᱢᱮ
+ GitHub ᱨᱮ ᱚᱱᱚᱞ
+ ᱨᱤᱯᱚᱨᱴ
+ What:\\nRequest:\\nContent Language:\\nContent ᱫᱤᱥᱚᱢ:\\nApp Language:\\nService:\\nGMT ᱚᱠᱛᱚ:\\nPackage:\\nVersion:\\nOS version:
+ ᱟᱢᱟᱜ ᱯᱟᱹᱛᱭᱟᱹᱣ (ᱤᱝᱞᱤᱥ ᱛᱮ):
+ ᱚᱯᱞᱚᱰᱟᱨᱟᱜ ᱟᱵᱟᱛᱟᱨ ᱛᱷᱩᱱᱤᱠᱟ
+ ᱞᱟᱭᱠ
+ ᱡᱟᱦᱟᱱ ᱡᱤᱱᱤᱥ
+ ᱱᱚᱣᱟ ᱨᱮᱫᱚ ᱡᱟᱹᱥᱛᱤ ᱡᱟᱹᱥᱛᱤ ᱠᱨᱤᱠᱮᱴ ᱢᱮᱱᱟᱜᱼᱟ ᱾
+ ᱵᱷᱤᱰᱤᱭᱳ
+ k
+ M
+ ᱥᱮᱞᱮᱫᱤᱭᱟᱹ ᱠᱚᱣᱟᱜ ᱞᱮᱠᱷᱟ ᱵᱟᱭ ᱦᱟᱹᱴᱤᱧ ᱟᱠᱟᱱᱟ
+ ᱵᱟᱱᱩᱜ ᱧᱮᱞ
+ ᱵᱷᱤᱰᱤᱭᱳ ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱑᱐᱐+ ᱵᱷᱤᱰᱤᱭᱳ
+ ᱡᱤᱣᱤ ᱥᱴᱨᱤᱢ ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱪᱮᱠᱥᱢ
+ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱫᱟᱭᱟ ᱠᱟᱛᱮ ᱮᱛᱦᱚᱵ ᱢᱮ ᱾
+ ᱠᱞᱤᱯᱵᱳᱨᱰ ᱨᱮ ᱠᱚᱯᱤ ᱟᱠᱟᱱᱟ
+ reCAPTCHA ᱪᱟᱞᱟᱣ
+ ᱵᱮᱱᱟᱣ ᱪᱤᱠᱤ
+ ᱵᱟᱹᱞᱤ ᱪᱤᱠᱤ ᱠᱚ ᱱᱚᱶᱟ ᱢᱟᱹᱱ ᱥᱟᱞᱟᱜ ᱛᱮ ᱵᱚᱫᱚᱞᱚᱜᱼᱟ
+ ᱚᱞ ᱟᱨ ᱮᱞ
+ ᱡᱟᱹᱥᱛᱤ ᱵᱤᱥᱮᱥ ᱪᱤᱠᱤ
+ ᱪᱟᱹᱞᱩ ZIP ᱯᱷᱤᱞ ᱫᱚ ᱵᱟᱝ
+ ᱞᱟᱹᱱᱟᱹᱤ: ᱡᱚᱛᱚ ᱪᱤᱱᱦᱟᱹ ᱠᱚ ᱤᱱᱯᱷᱚᱨᱢ ᱵᱟᱭ ᱫᱟᱲᱮᱭᱟᱜ ᱠᱟᱱᱟ.
+ ᱱᱚᱶᱟ ᱫᱚ ᱟᱢᱟᱜ ᱱᱮᱛᱟᱨᱟᱜ ᱥᱮᱴᱯᱟᱴ ᱩᱫᱩᱜ ᱮᱫᱟ ᱾
+ ᱟᱢ ᱥᱤᱴᱤᱝ ᱦᱚᱸ ᱟᱢᱯᱷᱮᱨᱟᱣ ᱦᱩᱭᱩᱜ ᱛᱟᱢᱟ?
+ ᱠᱚᱢᱮᱱᱴ ᱞᱚᱰ ᱫᱚ ᱵᱟᱝ ᱜᱟᱱᱚᱜ ᱠᱟᱱᱟ
+ ᱢᱩᱬ ᱕᱐
+ ᱠᱚᱱᱯᱷᱮᱨᱮᱱᱥ
+ ᱠᱷᱮᱞ ᱞᱟᱦᱟ
+ ᱥᱟᱦᱟᱣ ᱢᱮ
+ ᱡᱚᱠᱷᱟ
+ ᱚᱰᱤᱭᱳ ᱴᱨᱟᱠ
+ ᱥᱮᱞᱮᱫᱚᱜ ᱞᱟᱹᱜᱤᱫ ᱫᱚᱦᱚᱭ ᱢᱮ
+ ᱛᱟᱭᱚᱢ ᱛᱮ Enqueue
+ ᱛᱟᱭᱚᱢ ᱛᱮ ᱥᱮᱞᱮᱫ ᱢᱮ
+ ᱚᱯᱮᱱ ᱰᱨᱟᱵᱷᱤᱴ
+ ᱵᱟᱹᱲᱛᱤ ᱞᱟᱹᱠᱛᱤᱭᱟᱱ \"ᱚᱯᱮᱱ\" ᱠᱟᱹᱢᱤ
+ ⁇ %s ᱡᱚᱠᱷᱚᱱ ᱥᱟᱦᱴᱟ ᱵᱚᱫᱚᱞᱚᱜ-ᱟ
+ ᱵᱷᱤᱰᱤᱭᱳ ᱯᱞᱮᱭᱟᱨ
+ ᱯᱟᱛᱷᱟᱢ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ
+ ᱯᱚᱯᱯᱟᱯ ᱯᱞᱮᱭᱟᱨ
+ ᱥᱟᱨᱮᱡ ᱟᱠᱟᱱ ᱯᱞᱮ ᱞᱤᱥᱴᱤ ᱨᱮ ᱱᱤᱛᱚᱜ ᱱᱚᱣᱟ ᱡᱤᱱᱤᱥ ᱢᱮᱱᱟᱜᱼᱟ ᱾
+ ᱧᱩᱛᱩᱢ ᱵᱚᱫᱚᱞ ᱢᱮ
+ Unmute
+ ᱵᱟᱝ ᱥᱮᱴᱮᱨ ᱟᱠᱟᱱ ᱟᱹᱪᱩᱨ ᱦᱟᱹᱴᱤᱧ
+ ᱯᱮᱭᱞᱤᱥᱴ
+ %d ᱚᱠᱛᱚ ᱵᱟᱨᱟᱵᱟᱨᱤ ᱥᱮᱞᱮᱫᱚᱜᱼᱟ
+ ᱪᱤᱛᱟᱹᱨ ᱵᱮᱱᱟᱣ ᱟᱠᱟᱱᱟ
+ ᱥᱮᱨᱮᱧ ᱞᱤᱥᱴᱤ ᱨᱮᱱᱟᱜ ᱛᱷᱤᱢᱵᱽᱱᱟᱭᱟᱨ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ.
+ ᱚᱴᱚ-ᱡᱮᱱᱮᱨᱮᱴ (ᱯᱷᱮᱰᱟᱛ ᱵᱟᱭ ᱧᱟᱢ ᱞᱮᱱᱟ)
+ ᱚᱞ ᱪᱤᱠᱤ ᱵᱟᱹᱱᱩᱜ
+ ᱞᱟᱹᱠᱛᱤ ᱠᱟᱱᱟ
+ ᱯᱷᱤᱞᱰ
+ ᱡᱩᱢ
+ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱜ ᱪᱷᱟᱸᱪ ᱚᱞ ᱨᱮᱱᱟᱜ ᱟᱥᱚᱞ ᱟᱨ ᱯᱟᱛᱷᱟᱢ ᱥᱴᱟᱭᱤᱞᱥ ᱵᱚᱫᱚᱞ ᱢᱮ. ᱪᱟᱹᱞᱩᱜ ᱞᱟᱹᱜᱤᱫ ᱮᱯ ᱮᱥᱴᱟᱨᱴ ᱞᱟᱹᱠᱛᱤ ᱠᱟᱱᱟ
+ ᱢᱮᱢᱚᱨᱤ ᱞᱤᱠᱟᱞ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ LeakCanary ᱵᱟᱭ ᱧᱟᱢᱚᱜ ᱠᱟᱱᱟ
+ ᱢᱮᱢᱚᱨᱤ ᱞᱤᱠᱟᱞ ᱢᱚᱱᱤᱴᱚᱨᱤᱝ ᱦᱤᱯ ᱰᱟᱢᱯᱤᱝ ᱚᱠᱛᱚ ᱨᱮ ᱮᱯᱞᱤᱠᱮᱥᱚᱱ ᱨᱟᱥᱴᱨᱤᱭ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ
+ ᱡᱤᱭᱚᱱ ᱪᱤᱠᱤ ᱠᱷᱚᱱ ᱵᱟᱦᱨᱮ ᱨᱮ ᱵᱷᱮᱜᱟᱨ ᱠᱚ ᱚᱱᱚᱞ ᱢᱮ
+ ᱱᱮᱴᱣᱟᱨᱠ ᱞᱟᱹᱜᱤᱫ red, ᱰᱤᱥᱠ ᱞᱟᱹᱜᱤᱫ blue ᱟᱨ ᱢᱮᱢᱚᱨᱤ ᱞᱟᱹᱜᱤᱫ green
+ ᱯᱞᱮᱭᱟᱨ ᱵᱮᱵᱷᱟᱨ ᱚᱠᱛᱮ ᱨᱮ ᱠᱨᱟᱥ ᱚᱯᱥᱚᱱ ᱧᱮᱞᱚᱜ ᱠᱟᱱᱟ
+ ᱤᱢᱯᱳᱨᱴ
+ ᱤᱢᱯᱚᱨᱴ
+ ᱮᱥᱯᱳᱨᱴ ᱢᱮ
+ ᱤᱢᱯᱳᱨᱴ…
+ ᱮᱠᱥᱯᱳᱨᱴ…
+ ᱤᱢᱯᱳᱨᱴ ᱯᱷᱤᱞ
+ ᱢᱟᱲᱟᱝ ᱮᱠᱥᱯᱚᱨᱴ
+ ᱥᱚᱵᱥᱠᱨᱤᱯᱥᱚᱱ ᱮᱢ ᱫᱟᱲᱮᱭᱟᱜ ᱵᱟᱝ ᱠᱟᱱᱟ
+ \"ᱱᱚᱶᱟ ᱚᱯᱨᱮᱥᱚᱱ ᱨᱮ ᱱᱮᱴᱣᱟᱨᱠ ᱰᱷᱮᱨ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱢᱮᱱᱛᱮ ᱢᱟᱱᱟᱣ ᱢᱮ ᱾\"
+\n
+\nᱟᱢ ᱫᱚ ᱪᱮᱫ ᱮᱢ ᱪᱟᱞᱟᱜ ᱠᱟᱱᱟ?\"
+ ᱨᱤᱥᱮᱴ
+ ᱥᱮᱢᱤᱴᱚᱱ
+ ᱰᱷᱮᱨᱚᱜ
+ ᱞᱤᱢᱤᱴ ᱵᱟᱹᱱᱩᱜ
+ ᱢᱚᱵᱟᱤᱞ ᱰᱟᱴᱟ ᱵᱮᱵᱷᱟᱨ ᱚᱠᱛᱚ ᱨᱮ ᱞᱤᱢᱤᱴ ᱫᱟᱲᱮ
+ ᱱᱟᱣᱟ ᱵᱷᱮᱨᱥᱚᱱ ᱞᱟᱹᱜᱤᱫ ᱛᱮ ᱢᱟᱱᱩᱣᱟᱞ ᱪᱮᱠ
+ ᱟᱯᱞᱤᱠᱮᱥᱚᱱ ᱥᱤᱴᱤᱪ ᱨᱮ ᱞᱟᱹᱴᱩ ᱦᱚᱪᱚ
+ ᱢᱩᱬᱩᱛ ᱵᱷᱤᱰᱤᱭᱳ ᱯᱞᱮᱭᱟᱨ ᱠᱷᱚᱱ ᱮᱴᱟᱜ ᱮᱯᱞᱤᱠᱮᱥᱚᱱ ᱨᱮ ᱥᱮᱞᱮᱫᱚᱜ ᱚᱠᱛᱚ ᱨᱮᱱᱟᱜ ᱠᱟᱹᱢᱤ ⁇ %s
+ ᱡᱟᱦᱟᱱ ᱵᱟᱝ
+ ᱚᱛᱱᱚ ᱯᱞᱮᱭᱟᱨ ᱨᱮ ᱞᱟᱹᱴᱩ ᱦᱚᱪᱚ
+ Wi-Fi ᱨᱮᱜᱮ
+ Seekbar thumbnail preview ᱧᱮᱞᱢᱮ
+ ᱠᱚᱢ ᱠᱣᱟᱞᱤᱴᱤ (ᱢᱤᱫ ᱠᱷᱚᱱ ᱠᱚᱢ)
+ ᱵᱟᱝ ᱧᱮᱞᱚᱜ
+ ᱟᱢ NewPipe ᱨᱮᱭᱟᱜ ᱱᱟᱣᱟ ᱵᱟᱨᱥᱚᱱ ᱪᱟᱞᱟᱜ ᱠᱟᱱᱟ
+ ᱯᱮᱱᱰᱤᱝ
+ ᱠᱩᱠᱞᱤ
+ ᱯᱟᱥᱴᱟ ᱯᱨᱚᱥᱟᱥᱚᱱ
+ ᱤᱱᱠᱭᱩᱤᱝ
+ ᱥᱤᱥᱴᱮᱢ ᱦᱚᱛᱮᱛᱮ ᱵᱟᱝ ᱧᱟᱢ ᱟᱠᱟᱱ ᱠᱟᱹᱢᱤ
+ ᱯᱷᱟᱹᱞ ᱪᱮᱛᱟᱱ ᱵᱟᱝ ᱚᱞ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ
+ ᱱᱚᱶᱟ ᱧᱩᱛᱩᱢ ᱛᱮ ᱢᱤᱫ ᱰᱟᱩᱱᱞᱚᱰ ᱪᱟᱞᱟᱜ ᱠᱟᱱᱟ
+ ᱱᱚᱶᱟ ᱧᱩᱛᱩᱢ ᱛᱮ ᱢᱤᱫ ᱚᱞᱚᱜ ᱠᱟᱱ ᱰᱟᱩᱱᱞᱚᱰ ᱢᱮᱱᱟᱜᱼᱟ
+ ᱴᱷᱟᱶ ᱯᱷᱳᱞᱰᱚᱨ ᱛᱮᱭᱟᱨ ᱵᱟᱝ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ
+ ᱱᱚᱶᱟ ᱰᱟᱩᱱᱞᱚᱰ ᱫᱚ ᱵᱟᱭ ᱨᱤᱠᱳᱨᱰ ᱫᱟᱲᱮᱭᱟᱜ ᱠᱟᱱᱟ
+ ᱰᱟᱩᱱᱞᱚᱰ ᱦᱤᱥᱛᱟ ᱪᱷᱟᱯᱟ ᱢᱮ
+ ᱟᱹᱰᱤ ᱡᱟᱹᱥᱛᱤ ᱫᱟᱲᱮ
+ ᱢᱤᱴᱟᱨ ᱛᱮᱭᱟᱨ ᱟᱠᱟᱱ ᱱᱮᱴᱣᱟᱨᱠ ᱨᱮ ᱵᱚᱫᱚᱞ
+ ᱰᱟᱩᱱᱞᱚᱰ ᱮᱦᱚᱵ ᱢᱮ
+ ᱧᱮᱞᱚᱜ ᱟᱠᱟᱱ ᱥᱟᱯᱲᱟᱣ ᱢᱮ
+ ᱧᱮᱞ ᱟᱠᱟᱱ ᱵᱷᱤᱰᱤᱭᱳ ᱠᱚ ᱪᱷᱩᱴᱟᱹᱣ?
+ ᱫᱩᱯᱞᱟᱹᱲ ᱠᱚ ᱦᱮᱡ ᱢᱮ
+ ᱭ, ᱟᱨ ᱵᱷᱤᱰᱤᱭᱳ ᱠᱚ ᱡᱟᱦᱟᱸ ᱞᱮᱠᱟ ᱧᱮᱞᱚᱜᱼᱟ
+ ᱪᱟᱱᱮᱞ ᱜᱨᱩᱯ
+ ᱯᱷᱤᱰ ᱢᱩᱪᱟᱹᱫ ᱵᱚᱫᱚᱞᱟᱠᱟᱱ: %s
+ ᱵᱟᱝ ᱞᱚᱰ ᱟᱠᱟᱱᱟ: %d
+ ᱯᱷᱤᱰ ᱞᱚᱰᱚᱜ ᱠᱟᱱᱟ…
+ ᱠᱟᱹᱢᱤᱦᱚᱨᱟ ᱡᱚᱢᱟᱜ…
+ ᱜᱩᱴ ᱧᱩᱛᱩᱢ ᱵᱟᱱᱩᱜᱼᱟ
+ ᱟᱢ ᱱᱚᱶᱟ ᱜᱽᱨᱩᱯ ᱵᱚᱫᱚᱞ ᱢᱮᱢᱮ?
+ ᱱᱟᱣᱟ
+ ᱦᱟᱹᱴᱤᱧ ᱢᱚᱰ ᱨᱮ ᱥᱮᱞᱮᱫ ᱢᱮ
+ ᱞᱟᱛᱟᱨ ᱨᱮ ᱚᱞ ᱟᱠᱟᱱ ᱥᱴᱨᱤᱢ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱪᱟᱱᱮᱞ ᱛᱟᱵᱽ ᱠᱚ ᱦᱟᱛᱟᱣ
+ %s ᱛᱮᱭᱟᱨ ᱟᱠᱟᱱᱟ
+ %s ᱦᱚᱛᱮᱛᱮ
+ ᱛᱟᱢᱤᱞ ᱪᱤᱛᱟᱹᱨ ᱧᱮᱞ ᱢᱮ
+ ᱪᱮᱯᱴᱟᱨᱥ
+ ᱞᱟᱹᱠᱛᱤ ᱠᱟᱱᱟ ᱟᱢ ᱢᱤᱫ ᱯᱷᱤᱞ ᱢᱟᱱᱮᱡᱚᱨ ᱤᱱᱥᱴᱚᱞ ᱢᱮ ᱟᱨᱵᱟᱝ ᱰᱟᱩᱱᱞᱚᱰ ᱥᱤᱴᱤᱝ ᱨᱮ ᱵᱚᱫᱚᱞ ᱦᱚᱪᱚ ᱞᱟᱹᱜᱤᱫ ᱯᱨᱚᱵᱷᱟᱣ ᱢᱮ\"
+ ᱱᱚᱶᱟ ᱵᱷᱤᱰᱤᱭᱳ ᱫᱚ ᱭᱩᱴᱭᱩᱵᱽ ᱢᱤᱣᱡᱤᱠ ᱯᱨᱤᱢᱤᱭᱟᱢ ᱥᱮᱞᱮᱫᱤᱭᱟᱹ ᱠᱚ ᱞᱟᱹᱜᱤᱫ ᱜᱮ ᱧᱟᱢᱚᱜᱼᱟ, ᱚᱱᱟᱛᱮ ᱱᱚᱶᱟ ᱫᱚ ᱱᱤᱭᱩ ᱯᱟᱭᱤᱯ ᱦᱚᱛᱮᱛᱮ ᱵᱟᱝ ᱥᱴᱨᱤᱢ ᱟᱨ ᱵᱟᱝ ᱰᱟᱩᱱᱞᱳᱰ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱾
+ %s ᱫᱚ ᱱᱚᱶᱟ ᱞᱟᱹᱠᱛᱤ ᱠᱟᱱᱟ:
+ ᱚᱴᱚᱢᱟᱴᱤᱠ (ᱰᱤᱵᱟᱤᱥ ᱛᱷᱮᱢ)
+ ᱟᱢᱟᱜ ᱯᱩᱭᱞᱩ ᱧᱤᱫᱟᱹ ᱛᱷᱤᱢ ᱵᱟᱪᱷᱟᱣ ᱢᱮ ⁇ %s
+ ᱟᱢ ᱞᱟᱛᱟᱨ ᱨᱮ ᱟᱢᱟᱜ ᱧᱤᱫᱟᱹ ᱪᱮᱛᱟᱱ ᱵᱟᱪᱷᱟᱣ ᱫᱟᱲᱮᱭᱟᱜ ᱟ
+ ᱪᱤᱛᱟᱹᱨ ᱨᱮ ᱚᱞ ᱪᱤᱠᱤ ᱵᱟᱪᱷᱟᱣ ᱫᱚᱦᱚᱭ ᱢᱮ
+ ᱛᱷᱚᱠ
+ ᱞᱟᱭᱥᱮᱱᱥ
+ ᱟᱵᱟᱛᱟᱨ
+ ᱵᱮᱱᱚᱨ
+ ᱵᱟᱝ ᱞᱤᱥᱴᱤ ᱟᱠᱟᱱᱟ
+ ᱱᱤᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ ᱠᱚ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ
+ ᱟᱢ ᱱᱤᱛᱚᱜ ᱱᱚᱣᱟ ᱪᱮᱱᱮᱞ ᱨᱮ ᱥᱮᱞᱮᱫ ᱟᱠᱟᱱᱟᱢ
+ ,
+ ᱵᱟᱦᱨᱮ ᱯᱞᱮᱭᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱚᱰᱤᱭᱚ ᱴᱨᱟᱠ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱵᱟᱝ ᱵᱟᱰᱟᱭ ᱧᱟᱢ ᱟᱠᱟᱱ ᱥᱤᱠᱷᱱᱟᱹᱛ
+ ᱵᱟᱝ ᱵᱟᱰᱟᱭ
+ ᱡᱚᱛᱚ ᱛᱮ ᱧᱮᱞᱚᱜᱼᱟ
+ ExoPlayer ᱨᱮᱭᱟᱜ ᱵᱷᱤᱰᱤᱭᱳ ᱟᱯᱩᱴ ᱥᱩᱨᱥᱩᱯᱩᱨ ᱥᱤᱴᱤᱝ ᱣᱟᱨᱠᱟᱨᱚᱸᱜ ᱵᱮᱵᱷᱟᱨ ᱢᱮ
+ ᱵᱷᱤᱰᱤᱭᱳ
+ ᱴᱨᱮᱠ
+ ᱥᱟᱨᱴᱥ
+ ᱡᱤᱣᱤ
+ ᱪᱟᱱᱮᱞ
+ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱠᱚ
+ ᱟᱞᱵᱚᱢ
+ ᱤᱫᱤ ᱠᱟᱛᱮ
+ ᱪᱟᱱᱮᱞ ᱛᱟᱵᱽ
+ ᱥᱠᱨᱤᱱ ᱴᱳᱜᱞ ᱳᱭᱨᱮᱱᱟᱥᱚᱱ
+ ᱢᱟᱲᱟᱝ ᱥᱴᱨᱤᱢ
+ ᱯᱷᱚᱨᱣᱟᱨᱰ
+ ᱪᱤᱛᱟᱹᱨ ᱥᱤᱠᱷᱱᱟᱹᱛ
+ ᱪᱤᱛᱟᱹᱨ ᱵᱟᱝ ᱞᱚᱰ ᱢᱮ
+ \?
+ ᱥᱮᱨᱮᱧ ᱛᱟᱹᱞᱠᱟᱹ ᱮᱢ
+ ᱧᱩᱛᱩᱢ ᱥᱟᱶ ᱮᱱᱮᱢ ᱢᱮ
+ %1$s
+\n%2$s
+ ᱟᱨᱦᱚᱸ ᱧᱮᱞ ᱢᱮ
+ ᱠᱚᱢ ᱧᱮᱞ ᱢᱮ
+ ᱛᱟᱹᱞᱠᱟᱹ ᱪᱟᱪᱞᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱯᱟᱹᱛᱭᱟᱹᱣ ᱮᱢ ᱢᱮ
+ ᱢᱤᱫ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟ. ᱠᱷᱚᱱ ᱮᱴᱟᱜ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟ. ᱛᱮ ᱵᱚᱫᱚᱞ ᱠᱟᱛᱮᱜ ᱟᱢᱟᱜ ᱠᱩᱠᱞᱤ ᱵᱚᱫᱚᱞ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ
+ ᱮᱠᱴᱤᱵᱽ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱠᱩᱠᱞᱤ ᱫᱚ ᱵᱚᱫᱚᱞᱚᱜ-ᱟ
+ ᱞᱟᱹᱱᱟᱹᱤ ᱠᱚ ᱧᱮᱞ ᱢᱮ
+ ᱰᱤᱯᱷᱚᱞᱴ ᱠᱚ ᱨᱤᱯᱚᱴ ᱢᱮ
+ ᱯᱞᱮᱵᱮᱠ ᱞᱚᱰ ᱤᱱᱴᱟᱨᱵᱷᱮᱞ ᱨᱮᱱᱟᱜ ᱢᱟᱨᱟᱝ
+ ᱞᱚᱠᱟᱞ
+ ᱮᱠᱟᱩᱱᱴ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ
+ ᱵᱟᱰᱟᱭ ᱢᱮ
+ ᱦᱟᱨᱰᱣᱮᱭᱟᱨ ᱢᱤᱰᱤᱭᱟ ᱵᱩᱴᱚᱱ ᱦᱮᱯᱨᱟᱣ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ System folder picker (SAF) ᱵᱮᱵᱷᱟᱨ ᱢᱮ
+ ᱰᱤᱯᱷᱚᱞᱴ ᱵᱷᱤᱰᱤᱭᱳ ᱯᱷᱚᱨᱢᱮᱴ
+ ᱯᱚᱯ-ᱟᱯ ᱨᱮᱱᱟᱜ ᱢᱩᱪᱟᱹᱫ ᱢᱟᱨᱟᱝ ᱟᱨ ᱴᱷᱟᱶ ᱫᱚᱦᱚᱭ ᱢᱮ
+ ᱦᱩᱰᱤᱧ ᱵᱟᱹᱱᱩᱜ-ᱟ ᱞᱟᱦᱟᱱᱛᱤ ᱵᱮᱵᱷᱟᱨ
+ ᱵᱟᱝ ᱥᱟᱹᱨᱤ ᱧᱮᱞ ᱠᱷᱟᱱ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱫᱚ ᱵᱟᱹᱲᱛᱤ ᱥᱟᱹᱠᱷᱭᱟᱹᱛ ᱥᱟᱶ ᱥᱟᱹᱠᱷᱭᱟᱹᱛ ᱠᱚ ᱵᱟᱰᱟᱭ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱾ ᱕, ᱑᱕ ᱟᱨ ᱒᱕ ᱥᱮᱠᱮᱱᱰ ᱞᱟᱹᱜᱤᱫ ᱧᱮᱞᱚᱜᱼᱟ ᱱᱚᱶᱟ ᱥᱟᱶ ᱵᱟᱝ ᱠᱟᱹᱢᱤᱭᱟ
+ ᱮᱱᱮᱢ ᱠᱚ ᱵᱚᱫᱚᱞ ᱞᱟᱹᱜᱤᱫ ᱱᱚᱶᱟ ᱵᱚᱫᱚᱞ ᱢᱮ
+ \'Next\' ᱟᱨ \'Similar\' ᱵᱷᱤᱰᱤᱭᱳ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱢᱮᱴᱟ ᱴᱷᱟᱶ ᱧᱮᱞ ᱢᱮ
+ ᱥᱴᱨᱤᱢ ᱵᱮᱱᱟᱣᱤᱭᱟᱹ, ᱥᱴᱨᱤᱢ ᱟᱹᱛᱩ ᱟᱨᱵᱟᱝ ᱥᱟᱨᱪ ᱞᱟᱹᱠᱛᱤ ᱵᱟᱵᱚᱛ ᱟᱨᱦᱚᱸ ᱵᱟᱰᱟᱭ ᱞᱟᱹᱜᱤᱫ ᱢᱮᱴᱟ ᱤᱱᱯᱷᱳ ᱵᱚᱠᱥ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱱᱮᱛᱟᱨᱟᱜ ᱥᱴᱨᱤᱢ ᱨᱮ ᱚᱴᱚᱼᱠᱤᱣ
+ ᱡᱚᱲᱟᱣ ᱟᱠᱟᱱ ᱥᱴᱨᱤᱢ ᱥᱮᱞᱮᱫ ᱠᱟᱛᱮ ᱪᱟᱪᱞᱟᱣ ᱪᱮᱛᱟᱱ (ᱱᱚᱱ-ᱨᱩᱯᱨᱤᱭᱩᱴᱤᱝ) ᱯᱞᱮᱼᱵᱷᱤᱠ ᱪᱮᱛᱟᱱ ᱪᱟᱪᱞᱟᱣ ᱢᱮ
+ ᱯᱟᱹᱨᱥᱤ ᱵᱟᱝ ᱧᱮᱞ ᱠᱟᱛᱮᱜ ᱚᱨᱡᱤᱱᱤᱭᱟᱞ ᱚᱰᱤᱭᱚ ᱴᱨᱟᱠ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱰᱤᱥᱠᱨᱤᱯᱴᱤᱵᱷ ᱚᱰᱤᱭᱚ ᱵᱟᱹᱲᱛᱤ
+ ᱚᱴᱚ-ᱮᱱᱠᱭᱩᱤᱝ
+ ᱡᱩᱫᱤ ᱢᱮᱱᱟᱜ ᱟ ᱡᱩᱫᱤ ᱧᱮᱞ ᱵᱟᱹᱲᱤᱡ ᱦᱚᱲ ᱠᱚ ᱞᱟᱹᱜᱤᱫ ᱢᱤᱫ ᱚᱰᱤᱭᱚ ᱴᱨᱟᱠ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱢᱮᱴᱟᱰᱮᱴᱟ ᱠᱮᱪ ᱵᱚᱫᱚᱞ
+ ᱞᱤᱣᱮᱴ ᱡᱮᱥᱴ ᱮᱠᱥᱚᱱ
+ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱥᱠᱨᱤᱱ ᱨᱮᱱᱟᱜ ᱪᱮᱛᱟᱱ ᱨᱮ ᱪᱤᱱᱦᱟᱹ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱞᱟᱹᱭ ᱪᱤᱠᱤ ᱠᱟᱹᱢᱤ
+ ᱢᱤᱱᱤ ᱯᱞᱮᱭᱟᱨ ᱨᱮ ᱵᱷᱤᱰᱤᱭᱳ ᱠᱚ ᱮᱛᱚᱦᱚᱵ ᱵᱟᱝ ᱢᱮ, ᱡᱩᱫᱤ ᱚᱴᱚᱯᱷᱤ ᱨᱚᱴᱮᱴ ᱞᱚᱠ ᱟᱠᱟᱱᱟ ᱮᱱᱠᱷᱟᱱ ᱥᱟᱹᱛ ᱥᱠᱨᱤᱱ ᱨᱮ ᱵᱚᱫᱚᱞ ᱢᱮ ᱾ ᱟᱢ ᱢᱤᱱᱤ ᱯᱞᱮᱭᱟᱨ ᱪᱷᱟᱰᱟ ᱠᱟᱛᱮᱜ ᱦᱚᱸ ᱥᱮᱞᱮᱫ ᱫᱟᱲᱮᱭᱟᱜ ᱟ
+ ᱚᱴᱚᱯᱷᱟᱭ
+ ᱵᱟᱝ ᱥᱚᱦᱚᱫ ᱟᱠᱟᱱ URL
+ URL ᱵᱟᱭ ᱧᱟᱢ ᱫᱟᱲᱮᱭᱟᱫᱼᱟ. ᱮᱴᱟᱜ ᱟᱯᱞᱤᱠᱮᱥᱚᱱ ᱛᱮ ᱮᱛᱚᱦᱚᱵ ᱢᱮ?
+ ᱡᱤᱞᱤᱧ
+ ᱛᱚᱨᱡᱚᱢᱟ ᱥᱟᱯᱲᱟᱣ
+ ᱧᱮᱞ ᱛᱟᱵᱩᱱ ᱯᱮ ᱺ
+ ᱨᱮᱢᱳᱴ ᱥᱟᱨᱪ ᱥᱩᱯᱨᱮᱥ
+ ᱧᱮᱞ ᱟᱠᱟᱱ ᱵᱷᱤᱰᱤᱭᱳ ᱠᱚ ᱪᱮᱛᱟᱱ ᱨᱮ ᱫᱚᱦᱚᱭ ᱢᱮ
+ ᱡᱟᱦᱟᱱᱟᱜ ᱵᱚᱫᱚᱞ ᱛᱟᱭᱚᱢ ᱠᱷᱮᱞ ᱫᱚᱦᱚᱭ ᱢᱮ (ᱡᱮᱞᱮᱠᱟ: ᱯᱷᱚᱱ ᱠᱚᱞ)
+ ᱰᱟᱩᱱᱞᱚᱰ ᱢᱮ
+ ᱢᱩᱬᱩᱛ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱡᱚᱛᱚ ᱪᱤᱛᱟᱹᱨ ᱨᱮ ᱮᱛᱚᱦᱚᱵ ᱢᱮ
+ ᱰᱤᱯᱷᱚᱞᱴ ᱠᱚᱱᱴᱮᱱᱴ ᱯᱟᱹᱨᱥᱤ
+ PeerTube ᱚᱞ ᱠᱚ
+ ᱟᱢᱟᱜ ᱧᱩᱛᱩᱢᱟᱱ PeerTube ᱵᱷᱤᱛᱨᱤ ᱠᱚ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱞᱟᱹᱱᱟᱹᱤ ᱫᱚᱦᱚ ᱫᱟᱲᱮᱭᱟᱜ ᱵᱟᱝ
+ ᱵᱷᱤᱰᱤᱭᱳ ᱟᱨ ᱚᱰᱤᱭᱳ
+ HTTPS URL ᱠᱚ ᱜᱮ ᱥᱚᱯᱷᱴᱣᱮᱨ ᱟᱠᱟᱱᱟ
+ ᱤᱱᱥᱴᱮᱱᱥ ᱫᱚ ᱟᱞᱮ ᱢᱮᱱᱟᱜᱼᱟ
+ ᱟᱹᱱᱟᱹᱨᱤ
+ ᱚᱛᱱᱚᱜ ᱪᱤᱛᱟᱹᱨ ᱠᱷᱚᱸᱫᱽᱨᱚᱸᱫᱽ ᱥᱟᱯᱲᱟᱣ
+ ᱜᱤᱫᱨᱟᱹ ᱠᱚ ᱞᱟᱹᱜᱤᱫ ᱵᱟᱝ ᱞᱟᱹᱠᱛᱤᱭᱟᱱ ᱠᱟᱛᱷᱟ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ ᱪᱮᱫᱟᱜ ᱥᱮ ᱱᱚᱣᱟ ᱨᱮ ᱢᱤᱫ ᱩᱢᱮᱨ ᱞᱤᱢᱤᱴ ᱢᱮᱱᱟᱜᱼᱟ (ᱡᱮᱞᱮᱠᱟ ᱑᱘+)
+ ᱭᱩᱴᱭᱩᱵᱽ ᱢᱤᱫ \"Restricted Mode\" ᱮᱢᱚᱜᱼᱟ ᱡᱟᱦᱟᱸ ᱫᱚ ᱯᱚᱴᱮᱱᱥᱤᱭᱟᱞ ᱢᱚᱰᱩᱞ ᱠᱚᱱᱴᱮᱱᱴ (mature content) ᱫᱚᱦᱚᱭᱟ
+ ᱱᱤᱭᱟᱹ ᱵᱷᱤᱰᱤᱭᱳ ᱫᱚ ᱩᱢᱚᱨ ᱞᱟᱹᱜᱤᱫ ᱜᱮ᱾_x000D_
+\nᱭᱩᱴᱭᱩᱵᱽ ᱨᱮ ᱵᱷᱤᱰᱤᱭᱳ ᱨᱮᱱᱟᱜ ᱩᱢᱮᱨ ᱫᱚᱦᱚ ᱞᱟᱹᱜᱤᱫ ᱱᱟᱣᱟ ᱯᱳᱞᱤᱥᱤ ᱠᱷᱟᱹᱛᱤᱨ, ᱱᱤᱭᱩ ᱯᱟᱭᱤᱯᱷ ᱫᱚ ᱟᱡᱟᱜ ᱵᱷᱤᱰᱤᱭᱳ ᱥᱴᱨᱤᱢ ᱨᱮᱱᱟᱜ ᱡᱟᱦᱟᱸᱭ ᱦᱚᱸ ᱥᱮᱴᱮᱨ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱵᱟᱝ ᱟᱨ ᱚᱱᱟᱛᱮ ᱱᱚᱶᱟ ᱯᱞᱮᱭ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ᱾
+ ᱡᱤᱣᱤ
+ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱠᱚ
+ ᱵᱷᱤᱰᱤᱭᱳ
+ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ
+ ᱜᱷᱚᱴᱚᱱ ᱠᱚ
+ ᱮᱯ ᱟᱯᱰᱮᱴ ᱱᱳᱴᱤᱯᱮᱥᱚᱱ
+ ᱱᱟᱣᱟ ᱱᱤᱭᱩ ᱯᱟᱭᱤᱯ ᱵᱟᱨᱥᱚᱱ ᱞᱟᱹᱜᱤᱫ ᱠᱷᱚᱵᱚᱨ
+ ᱪᱷᱟᱸᱪ ᱠᱚ
+ ᱵᱷᱤᱰᱤᱭᱳ ᱦᱟᱥ ᱱᱮᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ
+ ᱪᱟᱹᱠᱨᱤ ᱠᱷᱚᱵᱚᱨ ᱠᱷᱚᱵᱚᱨ
+ ᱯᱷᱚᱱ ᱨᱮ ᱥᱮᱞᱮᱫᱽ ᱢᱮ
+ ᱯᱚᱯ-ᱟᱯ ᱨᱮ ᱥᱮᱞᱮᱫ ᱢᱮ
+ ᱢᱩᱬᱩᱛ ᱨᱮ ᱞᱤᱱ ᱢᱮ
+ ᱮᱠᱥᱯᱳᱨᱴ ᱰᱮᱴᱟᱵᱮᱥ
+ ᱟᱢᱟᱜ ᱱᱮᱛᱟᱨᱟᱜ ᱱᱟᱜᱟᱢ, ᱥᱟᱵᱽᱥᱠᱨᱟᱭᱵᱽᱥ, ᱯᱷᱟᱭᱞᱤᱥᱴ ᱟᱨ (ᱵᱟᱪᱷᱱᱟᱣ ᱞᱮᱠᱟᱛᱮ) ᱥᱤᱴᱤᱝ ᱠᱚ ᱩᱪᱟᱹᱲᱟ
+ ᱟᱢ ᱢᱤᱫ reCAPTCHA ᱥᱟᱯᱲᱟᱣ ᱞᱮᱠᱷᱟᱱ NewPipe ᱥᱟᱦᱴᱟᱨᱮ ᱥᱚᱫᱚᱨ ᱟᱠᱟᱱ ᱠᱩᱠᱤ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱯᱷᱟᱭᱞᱟᱣ ᱴᱷᱟᱶ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱡᱚᱛᱚ ᱯᱞᱮᱤᱯᱷᱟᱭᱤᱰ ᱯᱚᱡᱤᱥᱚᱱ ᱠᱚ ᱵᱚᱫᱚᱞᱟ
+ ᱡᱚᱛᱚ ᱯᱞᱮᱵᱟᱠ ᱯᱳᱡᱤᱥᱚᱱ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ?
+ ᱠᱷᱮᱞᱚᱸᱰ ᱨᱮᱱᱟᱜ ᱴᱷᱟᱶ ᱠᱚ ᱪᱷᱩᱴᱟᱹᱣ ᱟᱠᱟᱱᱟ
+ ᱥᱩᱪᱚᱱᱟ ᱨᱮᱭᱟᱜ ᱱᱟᱜᱟᱢ ᱪᱷᱟᱯᱟ ᱢᱮ
+ ᱪᱷᱟᱸᱪ:Search keywords ᱨᱮᱱᱟᱜ ᱱᱟᱜᱟᱢ ᱪᱷᱟᱸᱪᱟᱣᱟ
+ ᱥᱟᱱᱟᱢ ᱥᱩᱪᱚᱱᱟ ᱱᱟᱜᱟᱢ ᱵᱚᱫᱚᱞ ᱢᱮ?
+ ᱰᱟᱩᱱᱞᱚᱰ ᱢᱮᱱᱩ ᱵᱟᱭ ᱥᱮᱯᱴᱮᱭᱟ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ
+ ᱮᱯᱞᱤᱠᱮᱥᱚᱱ/UI ᱠᱨᱟᱥ ᱞᱮᱱᱟ
+ ᱱᱚᱣᱟ ᱥᱴᱨᱤᱢ ᱯᱞᱮ ᱵᱟᱭ ᱫᱟᱲᱮᱭᱟᱜ ᱠᱟᱱᱟ
+ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱵᱟᱭ ᱵᱩᱡᱷᱟᱹᱣ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ
+ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱦᱩᱫᱤᱥ ᱠᱷᱚᱱ ᱨᱤᱠᱳᱨᱰ
+ ᱱᱚᱶᱟ ᱯᱷᱤᱞ ᱵᱟᱹᱱᱩᱜᱼᱟ ᱥᱮ ᱱᱚᱶᱟ ᱨᱮ ᱚᱞ ᱟᱨ ᱯᱟᱲᱦᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱫᱟᱣ ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱯᱷᱤᱞᱤᱢ ᱧᱩᱛᱩᱢ ᱵᱚᱸᱫᱚ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱵᱟᱝ
+ %1$s ᱢᱤᱫ ᱵᱷᱩᱞ ᱦᱩᱭ ᱞᱮᱱᱟ:
+ ᱰᱟᱩᱱᱞᱚᱰ ᱞᱟᱹᱜᱤᱫ ᱡᱟᱦᱟᱱ ᱥᱴᱨᱤᱢ ᱵᱟᱭ
+ ᱥᱚᱞᱦᱮ ᱟᱠᱟᱱ ᱴᱮᱵᱽ ᱠᱚ ᱵᱟᱝ ᱯᱟᱲᱦᱟᱣ ᱫᱟᱲᱮᱭᱟᱜ ᱠᱟᱱᱟ, ᱚᱱᱟᱛᱮ ᱵᱮᱵᱷᱟᱨᱤᱡᱽ ᱠᱚ
+ ᱟᱢ ᱥᱩᱯᱚᱨᱴ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮᱢᱮ?
+ ᱮᱴᱟᱜ ᱮᱯ ᱨᱮ ᱵᱚᱫᱚᱞ ᱞᱟᱹᱜᱤᱫ ᱫᱟᱣ ᱮᱢ ᱢᱮ
+ NewPipe ᱨᱮ ᱢᱤᱫᱴᱟᱹᱝ ᱵᱷᱩᱞ ᱧᱟᱢ ᱞᱮᱱᱟ, ᱠᱷᱚᱵᱚᱨ ᱞᱟᱹᱜᱤᱫ ᱴᱟᱯ ᱢᱮ
+ ᱤᱧᱤᱧ ᱵᱟᱹᱧ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ, ᱱᱚᱶᱟ ᱫᱚ ᱵᱟᱝ ᱦᱩᱭᱩᱜ ᱞᱟᱹᱠᱛᱤ ᱛᱟᱦᱮᱸᱫ ᱾
+ ᱤ-ᱢᱮᱞ ᱤᱫᱤ ᱠᱟᱛᱮ ᱨᱤᱯᱚᱨᱴ ᱢᱮ
+ ᱯᱷᱚᱨᱢᱮᱴ ᱟᱠᱟᱱ ᱨᱤᱯᱳᱨᱴ ᱠᱚᱯᱤ ᱢᱮ
+ ᱟᱢᱟᱜ ᱠᱨᱮᱥᱴ ᱵᱟᱵᱚᱫᱽ ᱛᱮ ᱢᱤᱫ ᱚᱱᱚᱞ ᱢᱮᱱᱟᱜ ᱟ ᱥᱮ ᱵᱟᱝ ᱚᱱᱟ ᱧᱮᱞ ᱢᱮ ᱾ ᱰᱩᱯᱞᱤᱠᱮᱴ ᱴᱤᱠᱮᱴ ᱵᱮᱱᱟᱣ ᱞᱮᱠᱷᱟᱱ, ᱟᱢ ᱫᱚ ᱚᱠᱛᱚ ᱟᱢᱮᱢ ᱦᱟᱛᱟᱣᱮᱫᱟ ᱡᱟᱦᱟᱸ ᱫᱚ ᱟᱥᱚᱞ ᱵᱟᱜ ᱥᱟᱯᱲᱟᱣ ᱨᱮ ᱟᱢᱮᱢ ᱦᱟᱛᱟᱣ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱾
+ ᱤᱱᱯᱷᱳ:
+ ᱪᱮᱫ ᱦᱩᱭ ᱞᱮᱱᱟ:
+ ᱞᱟᱹᱱᱟᱹᱤ:
+ ᱵᱷᱤᱰᱤᱭᱚ ᱯᱞᱮ, ᱚᱠᱛᱚ:
+ ᱵᱟᱹᱲᱤᱡ
+ ᱠᱚᱢᱮᱱᱴ
+ ᱥᱟᱶᱦᱮᱫ ᱮᱞᱠᱷᱟ
+ ᱞᱟᱹᱱᱟᱹᱤ
+ ᱓ ᱰᱳᱴ ᱢᱮᱱᱩ ᱠᱷᱚᱱ ᱤᱢᱯᱳᱨᱴ ᱟᱨ ᱮᱠᱥᱯᱳᱨᱴ ᱥᱟᱵᱥᱠᱨᱟᱭᱵᱮᱥᱚᱱ
+ ᱱᱟᱣᱟ ᱟᱹᱨᱡᱤ ᱞᱟᱹᱜᱤᱫ ᱟᱹᱪᱩᱨ ᱢᱮ
+ ᱚᱰᱤᱭᱳ
+ ᱟᱨᱦᱚᱸ ᱯᱟᱲᱦᱟᱣ ᱢᱮ
+ ᱵᱤ
+ ᱱᱤᱛᱚᱜ ᱵᱟᱪᱷᱟᱣ ᱟᱠᱟᱱ ᱴᱳᱜᱞ ᱥᱮᱵᱟ:
+ ᱚᱵᱷᱤᱱᱮᱛᱟᱨ ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱚᱠᱚᱭ ᱦᱚᱸ ᱵᱟᱝ ᱧᱮᱞᱚᱜ ᱠᱟᱱᱟ
+ ᱜᱚᱴᱟ ᱟᱠᱟᱱᱟ
+ ᱱᱤᱭᱩ ᱯᱟᱭᱯᱮ ᱵᱟᱵᱚᱛ
+ ᱯᱮᱨᱟᱜ ᱞᱟᱭᱥᱮᱱᱥ
+ ᱰᱳᱱᱮᱴ ᱢᱮ
+ ᱡᱟᱦᱟᱸᱭ ᱜᱮᱭ ᱟᱸᱡᱚᱢᱟ
+ ∞ ᱵᱷᱤᱰᱤᱭᱳ
+ ᱵᱟᱦᱟ ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱠᱚᱢᱮᱱᱴ ᱫᱚ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ
+ ᱮᱛᱚᱦᱚᱵ
+ ᱯᱷᱟᱭᱩᱥ
+ ᱵᱮᱱᱟᱣ ᱢᱮ
+ ᱛᱷᱚᱠ ᱨᱮ ᱛᱟᱭᱚᱢ ᱛᱮ ᱢᱤᱫ ᱰᱟᱩᱱᱞᱚᱰ ᱯᱷᱳᱞᱰᱟᱨ ᱮᱢ ᱢᱮ
+ ᱢᱤᱫᱴᱟᱹᱝ ᱡᱤᱱᱤᱥ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ
+ reCAPTCHA challenge ᱞᱟᱹᱠᱛᱤ ᱠᱟᱱᱟ
+ ᱥᱚᱞᱦᱮ
+ ᱱᱤᱭᱩ ᱯᱟᱭᱤᱯ ᱫᱚ ᱱᱤᱡᱮᱨᱟᱜ ᱚᱠᱛᱚ ᱟᱢᱟᱜ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱵᱷᱟᱹᱜᱤ ᱵᱷᱟᱹᱜᱤ ᱥᱟᱹᱜᱟᱹᱭ ᱮᱢ ᱠᱟᱛᱮ ᱵᱮᱱᱟᱣ ᱟᱠᱟᱱᱟ ᱾ ᱱᱤᱣ ᱯᱟᱭᱤᱯ ᱵᱮᱨᱮᱫ ᱞᱟᱹᱜᱤᱫ ᱮᱱᱮᱢᱤᱭᱟᱹ ᱠᱚ ᱜᱚᱲᱚ ᱥᱚᱦᱚᱫ ᱮᱢ ᱢᱮ ᱾
+ ᱣᱮᱵᱽᱥᱟᱭᱤᱴ
+ ᱱᱤᱣ ᱯᱟᱭᱯ ᱨᱮᱭᱟᱜ ᱞᱟᱭᱥᱮᱱᱥ
+ ᱱᱤᱭᱩ ᱯᱟᱭᱯ ᱫᱚ ᱠᱚᱯᱤᱞᱮᱠᱴ ᱞᱤᱵᱨᱮ ᱥᱚᱯᱷᱴᱣᱮᱭᱟᱨ ᱠᱟᱱᱟ ᱾ ᱟᱢ ᱱᱚᱶᱟ ᱵᱮᱵᱷᱟᱨ, ᱯᱟᱲᱦᱟᱣ, ᱮᱴᱟᱜ ᱦᱚᱲ ᱥᱟᱶ ᱮᱢ ᱟᱨ ᱵᱮᱵᱚᱥᱛᱟ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱾ ᱟᱢ ᱱᱚᱶᱟ GNU General Public License ᱞᱮᱠᱟᱛᱮ ᱯᱟᱨᱥᱟᱞ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱟᱨ/ᱟᱨᱵᱟᱝ Free Software Foundation ᱦᱚᱛᱮᱛᱮ ᱵᱮᱵᱦᱟᱨ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ, ᱡᱟᱦᱟᱸ ᱫᱚ ᱞᱟᱭᱥᱮᱱᱥ ᱨᱮᱱᱟᱜ ᱵᱟᱨᱥᱚᱱ ᱓ ᱥᱮ (ᱛᱟᱢᱟᱜ ᱵᱟᱪᱷᱟᱣ ᱞᱮᱠᱟᱛᱮ) ᱡᱟᱦᱟᱸᱱᱟᱜ ᱛᱟᱭᱚᱢ ᱵᱟᱨᱥᱚᱱ ᱠᱟᱱᱟ ᱾
+ ᱟᱨᱦᱚᱸ ᱵᱟᱰᱟᱭ ᱟᱨ ᱠᱷᱚᱵᱚᱨ ᱞᱟᱹᱜᱤᱫ NewPipe ᱣᱮᱵᱽᱥᱟᱭᱤᱴ ᱧᱮᱞ ᱢᱮ ᱾
+ ᱡᱩᱫᱤ ᱟᱢ ᱱᱚᱶᱟ ᱮᱯᱞᱤᱠᱮᱥᱚᱱ ᱵᱮᱵᱚᱦᱟᱨ ᱨᱮ ᱠᱷᱟᱡᱽᱱᱟ ᱮ ᱧᱟᱢᱟ, ᱮᱱᱠᱷᱟᱱ ᱱᱚᱶᱟ ᱥᱟᱸᱣ ᱡᱩᱲᱟᱹᱣ ᱟᱠᱟᱱ ᱯᱩᱥᱴᱟᱹ ᱠᱚ ᱧᱮᱞ ᱢᱮ!
+ ᱣᱮᱵᱽᱥᱟᱭᱤᱴ ᱨᱮ ᱧᱮᱞ ᱢᱮ
+ ᱱᱟᱜᱟᱢ
+ ᱱᱟᱜᱟᱢ
+ ᱟᱢ ᱱᱚᱶᱟ ᱡᱤᱱᱤᱥ ᱥᱟᱸᱪᱟᱨ ᱱᱟᱜᱟᱢ ᱠᱷᱚᱱ ᱵᱚᱫᱚᱞ ᱢᱮᱢᱮ?
+ ᱢᱩᱪᱟᱹᱫ ᱠᱷᱮᱞ ᱟᱠᱟᱱᱟ
+ ᱡᱟᱹᱥᱛᱤ ᱠᱷᱮᱞ ᱟᱠᱟᱱ
+ ᱢᱩᱬᱩᱛ ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ ᱥᱟᱦᱴᱟ
+ ᱢᱩᱬᱩᱛ ᱥᱟᱦᱴᱟ ᱨᱮ ᱚᱠᱟ ᱛᱟᱵᱽ ᱠᱚ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ
+ ᱡᱤᱱᱤᱥ ᱠᱚ ᱵᱟᱧᱪᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱥᱣᱟᱭᱯ ᱢᱮ
+ ᱰᱤᱯᱷᱚᱞᱴ ᱠᱤᱭᱳᱥᱠ
+ ᱠᱤᱭᱳᱥᱠ ᱥᱟᱦᱴᱟ
+ ᱪᱟᱱᱮᱞ ᱥᱟᱦᱴᱟ
+ ᱪᱟᱱᱮᱞ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱱᱤᱛ ᱦᱟᱹᱵᱤᱡ ᱪᱮᱱᱮᱞ ᱥᱚᱵᱽᱥᱠᱨᱟᱭᱵᱽ ᱵᱟᱝ
+ ᱢᱤᱫ ᱯᱷᱟᱤᱞᱤᱥᱴ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱤᱢᱯᱳᱨᱴ
+ ᱱᱤᱛ ᱦᱟᱹᱵᱤᱡ playlist bookmarks ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱮᱯ ᱮᱦᱚᱵ ᱞᱮᱠᱷᱟᱱ ᱯᱟᱹᱨᱥᱤ ᱵᱚᱫᱚᱞᱚᱜ-ᱟ
+ ᱮᱥᱯᱟᱨᱴ ᱟᱠᱟᱱᱟ
+ ᱴᱨᱮᱱᱰᱤᱝ
+ ᱚᱰᱤᱭᱳ ᱥᱮᱴᱤᱝ
+ ᱚᱰᱤᱭᱳ: %s
+ ᱥᱴᱨᱤᱢ ᱨᱮᱱᱟᱜ ᱰᱮᱴᱮᱞ ᱞᱚᱰ ᱠᱟᱱᱟ…
+ ᱥᱩᱯᱚᱨ ᱰᱨᱟᱵᱷᱤᱴ
+ ᱱᱟᱶᱟ ᱯᱞᱮᱭᱞᱤᱥᱴ
+ ᱢᱩᱴ
+ ᱢᱤᱫ ᱯᱚᱯ-ᱟᱯ ᱨᱮ ᱠᱷᱮᱞᱚᱸᱰ ᱮᱛᱚᱦᱚᱵ ᱢᱮ
+ ᱯᱷᱟᱤᱞᱤᱯᱷᱟᱤᱞᱤ ᱞᱮᱠᱟᱛᱮ ᱥᱮᱞᱮᱫ ᱢᱮ
+ ᱵᱩᱠᱢᱟᱨᱠ ᱯᱞᱮᱭᱞᱤᱥᱴ
+ ᱪᱷᱟᱸᱪ
+ ᱡᱤᱵᱚᱱ ᱪᱟᱞᱟᱣ ᱛᱟᱭᱚᱢ ᱡᱟᱹᱛᱤ ᱥᱮ ᱠᱟᱹᱢᱤ ᱡᱤᱭᱚᱱ ᱪᱮᱛᱟᱱ ᱵᱟᱦᱨᱮ ᱨᱮ ᱵᱟᱝ ᱦᱟᱹᱴᱤᱧ ᱫᱟᱲᱮᱭᱟᱜ Rx ᱮᱥᱠᱮᱪᱥᱚᱱ ᱨᱮᱱᱟᱜ ᱯᱷᱚᱨᱥ ᱨᱮᱯᱚᱨᱴᱤᱝ
+ ᱵᱩᱠᱢᱟᱨᱠ ᱚᱪᱚᱭ ᱢᱮ
+ ᱱᱚᱶᱟ ᱯᱷᱟᱭᱞᱤᱥᱴ ᱵᱚᱫᱚᱞ ᱢᱮ?
+ ᱚᱴᱚ-ᱡᱮᱱᱮᱨᱮᱴ
+ ᱡᱤᱱᱤᱥ ᱠᱚᱨᱮᱱᱟᱜ ᱢᱩᱞ ᱚᱠᱛᱚ ᱧᱮᱞ ᱢᱮ
+ ᱥᱮᱵᱟ ᱠᱷᱚᱱ ᱚᱨᱡᱤᱱᱤᱭᱟᱞ ᱴᱮᱠᱥᱴ ᱠᱚ ᱥᱴᱨᱤᱢ ᱤᱴᱮᱢ ᱨᱮ ᱧᱮᱞᱚᱜᱼᱟ
+ ᱡᱩᱫᱤ ᱟᱢ ᱵᱷᱤᱰᱤᱭᱳ ᱯᱞᱮᱭᱚᱯ ᱨᱮ ᱵᱞᱮᱠ ᱥᱠᱨᱤᱱ ᱟᱨᱵᱟᱝ ᱠᱷᱟᱹᱞᱤ ᱥᱴᱮᱴᱞᱤᱝ ᱮᱢ ᱧᱟᱢᱟ ᱮᱱᱠᱷᱟᱱ ᱢᱤᱰᱤᱭᱟ ᱴᱩᱱᱮᱞᱤᱝ ᱵᱚᱫᱚᱞ ᱢᱮ ᱾
+ ᱪᱤᱛᱟᱹᱨ ᱪᱤᱱᱦᱟᱹ ᱠᱚ ᱧᱮᱞ ᱢᱮ
+ ᱱᱟᱣᱟ ᱥᱴᱨᱤᱢ ᱞᱟᱹᱜᱤᱫ ᱪᱟᱪᱞᱟᱣ ᱢᱮ
+ ᱢᱤᱫ error notification ᱛᱮᱭᱟᱨ ᱢᱮ
+ ᱥᱮᱞᱮᱫ ᱮᱠᱥᱯᱳᱨᱴ ᱵᱟᱝ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜ ᱠᱟᱱᱟ
+ \"ᱜᱩᱜᱩᱞ ᱴᱮᱠᱟᱣᱩᱴ ᱠᱷᱚᱱ ᱭᱩᱴᱭᱩᱵᱽ ᱥᱚᱵᱽᱥᱠᱨᱟᱭᱵᱽᱥ ᱤᱱᱯᱳᱨᱴ ᱢᱮ:
+\n
+\n1. ᱱᱚᱶᱟ URL ᱨᱮ ᱪᱟᱞᱟᱜ ᱢᱮ: %1$s
+\n2. ᱞᱚᱜᱤᱱ ᱢᱮ ᱡᱚᱠᱷᱚᱱ ᱞᱟᱹᱠᱛᱤ ᱠᱟᱱᱟ
+\n3. \"\'All data included\"\' ᱨᱮ ᱞᱤᱱ ᱢᱮ, ᱛᱟᱭᱚᱢ \"\'Deselect all\"\' ᱨᱮ ᱞᱤᱱ ᱢᱮ, ᱛᱟᱭᱚᱢ \"\'subscriptions\"\' ᱨᱮ ᱞᱤᱱ ᱢᱮ ᱟᱨ \"\'OK\"\' ᱨᱮ ᱞᱤᱱ ᱢᱮ
+\n4. \"Next step\" ᱨᱮ ᱟᱨ ᱚᱱᱟ ᱛᱟᱭᱚᱢ \"Create export\" ᱨᱮ ᱞᱤᱱ ᱢᱮ
+\n5. ᱱᱚᱶᱟ ᱧᱮᱞ ᱛᱟᱭᱚᱢ \"\"Download\"\" ᱵᱩᱴᱚᱱ ᱨᱮ ᱠᱞᱤᱠ ᱢᱮ
+\n6. ᱞᱟᱛᱟᱨ ᱨᱮ IMPORT FILE ᱨᱮ ᱞᱤᱱ ᱢᱮ ᱟᱨ ᱰᱟᱩᱱᱞᱚᱰ ᱟᱠᱟᱱ . zip ᱯᱷᱤᱞ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+\n7. ᱡᱩᱫᱤ .zip ᱤᱱᱯᱷᱚᱨᱴ ᱞᱟᱹᱠᱛᱤᱭᱟᱱ ᱵᱟᱝ ᱠᱟᱱᱟ ᱮᱱᱠᱷᱟᱱ .csv ᱯᱷᱤᱞ ᱮᱠᱥᱴᱨᱟᱠᱴ ᱢᱮ (\"ᱭᱩᱴᱭᱩᱵᱽ ᱟᱨ ᱭᱩᱴᱭᱩᱵᱽ ᱢᱤᱣᱡᱤᱠ/ᱥᱵᱽᱥᱠᱨᱟᱭᱵᱮᱥᱚᱱ/ᱥᱵᱽᱥᱠᱨᱟᱭᱵᱮᱥᱚᱱ.ᱥᱤᱵᱷ\" ᱨᱮ), ᱞᱟᱛᱟᱨ ᱨᱮ IMPORT FILE ᱨᱮ ᱠᱞᱤᱠ ᱢᱮ ᱟᱨ ᱮᱠᱥᱴᱨᱟᱠᱴ ᱟᱠᱟᱱ csv ᱯᱷᱤᱞ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ yourID, soundcloud.com/yourid
+ \"ᱤᱭᱩᱨᱚᱯᱤᱭᱚ ᱡᱚᱡᱚᱱᱟ ᱯᱨᱚᱫᱚᱭᱚᱜᱤᱠᱤ (ᱡᱤ.ᱰᱤ.ᱯᱤ.ᱟᱨ.) ᱥᱟᱞᱟᱜ ᱥᱚᱢᱵᱚᱸᱫᱷ ᱞᱟᱹᱜᱤᱫ ᱛᱮ, ᱱᱚᱣᱟ ᱦᱚᱛᱮᱛᱮ ᱱᱤᱭᱩ ᱯᱟᱭᱤᱯ ᱨᱮᱭᱟᱜ ᱯᱨᱟᱭᱵᱷᱮᱴ ᱯᱚᱞᱤᱥᱤ ᱨᱮ ᱟᱵᱚᱣᱟᱜ ᱟᱫᱷᱤᱱᱤᱭᱚᱢ ᱠᱚ ᱩᱫᱩᱜ ᱦᱚᱪᱚᱭᱟ। ᱱᱚᱶᱟ ᱫᱚ ᱞᱟᱹᱭᱛᱮ ᱯᱟᱲᱦᱟᱣ ᱢᱮ ᱾
+\nᱟᱢ ᱫᱚ ᱱᱚᱶᱟ ᱯᱟᱹᱛᱭᱟᱹᱣ ᱢᱮ ᱡᱮ ᱟᱢ ᱵᱷᱤᱜᱽ ᱨᱮᱯᱳᱨᱴ ᱮᱢ ᱢᱮ ᱾\"
+ ᱥᱚᱵᱥᱠᱨᱟᱭᱵᱮᱥᱚᱱ ᱠᱷᱚᱱ ᱱᱟᱣᱟ ᱥᱴᱨᱤᱢ ᱠᱚ ᱵᱟᱰᱟᱭ ᱢᱮ
+ ᱚᱯᱰᱮᱴᱥ
+ ᱡᱚᱠᱷᱚᱱ ᱱᱟᱣᱟ ᱵᱟᱨᱥᱚᱱ ᱢᱮᱱᱟᱜ-ᱟ ᱮᱯ ᱟᱯᱰᱮᱴ ᱞᱟᱹᱜᱤᱫ ᱯᱟᱹᱛᱭᱟᱹᱣ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱯᱚᱯ-ᱟᱯ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱞᱟᱹᱜᱤᱫ ᱞᱟᱹᱴᱩ ᱦᱚᱪᱚ
+ ᱚᱞᱪᱤᱠᱤ ᱛᱮ ᱨᱩᱭᱟᱹᱲᱚᱜ ᱢᱮ - %s
+ ᱞᱤᱥᱴᱤ ᱧᱮᱧᱮᱞ ᱢᱚᱰ
+ ᱞᱤᱥᱴᱤ
+ ᱚᱴᱚ
+ ᱱᱟᱣᱟ ᱯᱟᱭᱤᱯ ᱚᱯᱰᱮᱴ ᱢᱮᱱᱟᱜ-ᱟ!
+ %s ᱠᱚᱰ ᱦᱚᱪᱚ ᱞᱟᱹᱜᱤᱫ ᱴᱟᱯ ᱢᱮ
+ ᱢᱩᱪᱟᱹᱫ
+ ᱱᱤᱛᱚᱜᱟᱜ ᱠᱷᱚᱵᱚᱨ ᱠᱚ ᱧᱮᱞᱚᱜ ᱠᱟᱱᱟ…
+ ᱰᱟᱩᱱᱞᱚᱰ ᱵᱟᱹᱱᱩᱜ-ᱟ
+ ᱧᱩᱛᱩᱢ ᱛᱮᱭᱟᱨ ᱢᱮ
+ ᱩᱫᱩᱜ ᱢᱮ
+ ᱪᱷᱟᱸᱪ:Fact
+ ᱯᱷᱤᱞ ᱵᱮᱱᱟᱣ ᱫᱚ ᱵᱟᱝ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜ
+ ᱥᱮᱵᱟ ᱧᱟᱢ ᱵᱟᱝ ᱜᱟᱱᱚᱜ ᱠᱟᱱᱟ
+ ᱥᱮᱵᱟ ᱫᱚ ᱚᱱᱚᱞ ᱵᱟᱝ ᱪᱟᱞᱟᱜ ᱠᱟᱱᱟ
+ ᱥᱟᱨᱵᱟᱨ ᱫᱚ ᱢᱚᱞᱴᱤ-ᱛᱷᱨᱮᱰ ᱰᱟᱩᱱᱞᱚᱰ ᱠᱚ ᱵᱟᱝ ᱮᱢᱚᱜ ᱠᱟᱱᱟ, @string/msg_threads = 1 ᱥᱟᱶᱛᱮ ᱮᱱᱮᱡ ᱢᱮ
+ ᱛᱟᱭᱚᱢ ᱛᱮᱭᱟᱨ ᱵᱟᱝ ᱪᱟᱞᱟᱣ ᱟᱠᱟᱱᱟ
+ ᱱᱩᱯᱯᱟᱭᱤᱯᱷ ᱯᱷᱤᱞ ᱨᱮ ᱠᱟᱹᱢᱤ ᱚᱠᱛᱚ ᱨᱮ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ
+ ᱯᱟᱹᱛᱭᱟᱹᱣ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ, ᱪᱮᱫᱟᱜ ᱥᱮ ᱯᱷᱤᱞᱤᱯᱟᱭᱤᱰ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ
+ ᱡᱚᱱᱚᱲ ᱚᱠᱛᱚ
+ ᱟᱢ ᱟᱢᱟᱜ ᱰᱟᱩᱱᱞᱚᱰ ᱦᱤᱥᱛᱟ ᱵᱚᱫᱚᱞ ᱢᱮ ᱟᱨᱵᱟᱝ ᱥᱟᱱᱟᱢ ᱰᱟᱩᱱᱞᱚᱰ ᱟᱠᱟᱱ ᱯᱷᱤᱞ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ?
+ ᱰᱟᱩᱱᱞᱚᱰ ᱵᱚᱫᱚᱞ ᱦᱚᱪᱚ ᱞᱟᱹᱜᱤᱫ ᱡᱚᱛᱚ ᱠᱷᱚᱱ ᱵᱟᱲᱛᱤ ᱥᱟᱸᱣᱛᱟ
+ ᱢᱚᱵᱟᱤᱞ ᱰᱟᱴᱟ ᱨᱮ ᱵᱚᱫᱚᱞ ᱞᱟᱹᱜᱤᱫ ᱵᱮᱵᱚᱦᱟᱨᱚᱜ ᱟ, ᱢᱮᱱᱠᱷᱟᱱ ᱛᱤᱱᱟᱹᱜ ᱜᱟᱱ ᱰᱟᱩᱱᱞᱚᱰ ᱠᱚ ᱵᱚᱫᱚᱞ ᱫᱟᱲᱮᱭᱟᱜ ᱟ
+ ᱢᱤᱫᱴᱟᱹᱝ ᱰᱟᱩᱱᱞᱚᱰ ᱢᱤᱫ ᱚᱠᱛᱚ ᱨᱮ ᱪᱟᱞᱟᱜᱼᱟ
+ ᱰᱟᱩᱱᱞᱚᱰ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱡᱚᱛᱚ ᱰᱟᱩᱱᱞᱚᱰ ᱠᱚ ᱡᱟᱦᱟᱸ ᱨᱮ ᱫᱚᱦᱚᱭ ᱢᱮ ᱚᱱᱟ ᱟᱢᱮᱢ ᱩᱫᱩᱜᱟ._x000D_
+\nᱡᱩᱫᱤ ᱟᱢ ᱵᱟᱦᱨᱮ SD ᱠᱟᱨᱰ ᱨᱮ ᱰᱟᱩᱱᱞᱚᱰ ᱞᱟᱹᱜᱤᱫ ᱮᱠᱴᱤᱵᱷ ᱢᱮ
+ ᱟᱢ ᱡᱟᱦᱟᱸ ᱨᱮ ᱡᱚᱛᱚ ᱰᱟᱩᱱᱞᱚᱰ ᱥᱟᱦᱴᱟ ᱠᱚ ᱵᱚᱫᱚᱞ ᱦᱚᱪᱚᱭ ᱢᱮ
+ \'ᱥᱴᱚᱨᱮᱡᱽ ᱮᱠᱥᱮᱥ ᱯᱷᱨᱮᱢᱠᱣᱟᱨᱠ\' ᱢᱤᱫ ᱵᱟᱦᱨᱮ SD ᱠᱟᱨᱰ ᱨᱮ ᱰᱟᱩᱱᱞᱚᱰ ᱞᱟᱹᱜᱤᱫ ᱮᱢᱚᱜ ᱟ
+ ᱚᱸᱰᱨᱚᱭᱮᱰ ᱑᱐ ᱠᱷᱚᱱ ᱮᱛᱚᱦᱚᱵ ᱠᱟᱛᱮ \'ᱥᱴᱳᱨᱮᱡ ᱮᱠᱥᱮᱥ ᱯᱷᱨᱮᱢᱚᱠ\' ᱜᱮ ᱥᱚᱯᱷᱚᱨᱴ ᱟᱠᱟᱱᱟ
+ ᱢᱤᱫ ᱤᱱᱥᱴᱟᱱᱥ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱟᱯᱞᱤᱠᱮᱥᱚᱱ ᱯᱟᱹᱨᱥᱤ
+ ᱥᱤᱥᱴᱮᱢ ᱰᱤᱯᱚᱞᱴ
+ ᱰᱩᱯᱞᱤᱠᱮᱴ ᱠᱚ ᱪᱷᱩᱴᱟᱹᱣ?
+ ᱟᱢ ᱱᱚᱶᱟ ᱯᱷᱟᱭᱞᱤᱥᱴ ᱨᱮ ᱡᱚᱛᱚ ᱫᱩᱯᱞᱤᱠᱮᱴ ᱥᱴᱨᱤᱢ ᱠᱚ ᱦᱮᱡ ᱟᱫᱮᱭᱟᱢ ᱥᱮ?
+ ᱥᱮᱨᱮᱧ ᱛᱟᱹᱞᱤᱠᱟ ᱨᱮ ᱥᱮᱞᱮᱫᱚᱜ ᱢᱟᱲᱟᱝ ᱟᱨ ᱛᱟᱭᱚᱢ ᱨᱮ ᱡᱟᱦᱟᱸ ᱵᱷᱤᱰᱤᱣ ᱠᱚ ᱧᱮᱞ ᱟᱠᱟᱱᱟ, ᱚᱱᱟ ᱠᱚ ᱪᱷᱟᱹᱲ ᱮᱢ ᱦᱩᱭᱩᱜᱼᱟ ᱾ ᱟᱢ ᱠᱤ ᱜᱚᱴᱟᱵᱩᱴᱟᱹ ᱠᱟᱱᱟ? ᱱᱚᱶᱟ ᱫᱚ ᱨᱩᱣᱟᱹᱲ ᱵᱟᱝ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱾
+ ᱱᱟᱣᱟ ᱡᱚᱢᱟᱜ ᱡᱤᱱᱤᱥ ᱠᱚ
+ ᱥᱮᱞᱮᱫ ᱠᱚ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ ᱪᱮᱫ ᱦᱚᱸ ᱵᱟᱱᱟᱣ ᱟᱠᱟᱱᱟ
+ ᱡᱟᱦᱟᱱᱟᱜ ᱵᱟᱝ ᱜᱩᱴ ᱟᱠᱟᱱ ᱥᱚᱵᱥᱠᱨᱟᱭᱵᱮᱥ ᱠᱚ ᱧᱮᱞ ᱢᱮ
+ ᱯᱷᱮᱰ
+ ᱯᱷᱤᱰ ᱟᱯᱰᱮᱴ ᱞᱟᱦᱟᱨᱮ
+ ᱢᱤᱫ ᱥᱚᱵᱥᱠᱨᱟᱭᱵᱽᱥᱚᱱ ᱵᱟᱥᱠᱮᱴᱮᱰ ᱦᱩᱭᱩᱜ ᱢᱟᱬᱟᱝ ᱨᱮ ᱯᱟᱹᱪᱷᱤᱢ ᱩᱫᱩᱜ ᱠᱷᱚᱱ ᱛᱟᱭᱚᱢ ᱚᱠᱛᱚ ⁇ %s
+ Error loading feed ᱥᱟᱯᱲᱟᱣ
+ \'%s\' ᱞᱟᱹᱜᱤᱫ ᱯᱷᱤᱰ ᱞᱚᱰ ᱵᱟᱝ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ.
+ ᱮᱠᱴᱚᱨᱟᱜ ᱮᱠᱟᱶᱴ ᱫᱚ ᱛᱷᱟᱯᱚᱱ ᱟᱠᱟᱱᱟ ᱾
+\nNewPipe ᱫᱚ ᱱᱚᱣᱟ ᱯᱷᱤᱰ ᱫᱚ ᱟᱵᱚ ᱦᱟᱵᱤᱡ ᱵᱟᱝ ᱞᱚᱰ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱾
+\nᱟᱢ ᱱᱚᱣᱟ ᱪᱟᱱᱮᱨ ᱠᱷᱚᱱ ᱟᱹᱪᱩᱨ ᱚᱪᱚᱜ ᱠᱟᱹᱢᱤᱭᱟᱢ ᱥᱮ?
+ ᱯᱷᱚᱥᱴ ᱯᱷᱤᱰ ᱢᱚᱰ ᱱᱚᱶᱟ ᱨᱮ ᱵᱟᱹᱲᱛᱤ ᱵᱟᱰᱟᱭ ᱮᱢ ᱮᱫᱟ ᱾
+ ᱡᱩᱫᱤ ᱢᱮᱱᱟᱜᱼᱟ ᱮᱢ ᱟᱠᱟᱱ ᱡᱚᱢᱟᱜ ᱠᱷᱚᱱ ᱦᱟᱛᱟᱣ
+ ᱟᱭᱢᱟ ᱥᱮᱵᱟ ᱨᱮ ᱧᱟᱢᱚᱜᱼᱟ, ᱱᱚᱶᱟ ᱫᱚ ᱟᱥᱚᱠᱟᱭ ᱛᱮ ᱟᱹᱰᱤ ᱦᱩᱰᱤᱧ ᱜᱮᱭᱟ ᱢᱮᱱᱠᱷᱟᱱ ᱢᱤᱫ ᱞᱮᱠᱟᱱ ᱤᱱᱴᱮᱢᱥ ᱟᱨ ᱟᱥᱚᱠᱟᱭ ᱛᱮ ᱵᱟᱝ ᱯᱩᱨᱟᱹᱣ ᱟᱠᱟᱱ ᱤᱱᱯᱷᱚᱨᱢᱮᱥᱚᱱ (ᱡᱮᱞᱮᱠᱟ ᱺ ᱚᱠᱛᱚ ᱵᱟᱝ, ᱤᱱᱴᱮᱢᱥ ᱨᱮᱱᱟᱜ ᱞᱮᱠᱷᱟ, ᱚᱞᱤᱵᱽ ᱥᱴᱮᱴᱥ ᱵᱟᱝ) ᱨᱩᱣᱟᱹᱲ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ
+ ᱯᱷᱮᱥᱵᱩᱠ ᱢᱚᱰ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱟᱢᱟᱜ ᱢᱚᱱᱮ ᱨᱮ ᱡᱚᱢᱟᱜ ᱨᱮᱱᱟᱜ ᱞᱚᱰ ᱟᱹᱰᱤ ᱟᱞᱜᱟ ᱜᱮᱭᱟ? ᱡᱩᱫᱤ ᱱᱚᱶᱟ ᱦᱩᱭᱩᱜ ᱠᱟᱱᱟ, ᱮᱱᱠᱷᱟᱱ ᱥᱯᱤᱰ ᱞᱚᱰ ᱮᱱᱟᱝ ᱮᱱᱮᱡ (ᱡᱟᱦᱟᱸ ᱫᱚ ᱟᱢ ᱥᱤᱴᱤᱝ ᱨᱮ ᱥᱮ ᱞᱟᱛᱟᱨ ᱨᱮᱭᱟᱜ ᱵᱩᱛᱟᱹᱢ ᱚᱞ ᱠᱟᱛᱮᱢ ᱵᱚᱫᱚᱞ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ)
+\n
+\nᱱᱤᱣ ᱯᱟᱭᱤᱯ ᱫᱚ ᱵᱟᱨᱭᱟ ᱯᱷᱤᱰ ᱞᱚᱰ ᱥᱴᱨᱮᱴᱡᱤ ᱮᱢᱚᱜ ᱠᱟᱱᱟ:
+\n• ᱡᱚᱛᱚ ᱥᱚᱵᱽᱥᱠᱨᱟᱭᱵᱽ ᱪᱮᱱᱮᱞ ᱦᱟᱛᱟᱣ, ᱡᱟᱦᱟᱸ ᱫᱚ ᱟᱞᱜᱟ ᱜᱮᱭᱟ ᱢᱮᱱᱠᱷᱟᱱ ᱯᱩᱨᱟᱹᱣᱜᱼᱟ ᱾
+\n• ᱰᱮᱰᱤᱠᱮᱴᱮᱰ ᱥᱮᱵᱟ ᱮᱱᱰ ᱯᱚᱭᱮᱱᱴ ᱵᱮᱵᱷᱟᱨ, ᱡᱟᱦᱟᱸ ᱫᱚ ᱦᱩᱲᱟᱹᱜ ᱜᱮᱭᱟ ᱢᱮᱱᱠᱷᱟᱱ ᱟᱥᱚᱠᱟᱭ ᱛᱮ ᱯᱩᱨᱟᱹᱣ ᱫᱚ ᱵᱟᱝ ᱦᱩᱭᱩᱜᱼᱟ ᱾
+\n
+\nᱵᱟᱨᱭᱟ ᱛᱟᱞᱟᱨᱮᱱᱟᱜ ᱵᱷᱮᱜᱟᱨ ᱫᱚ ᱦᱩᱭᱩᱜ ᱠᱟᱱᱟ ᱡᱮ ᱦᱩᱲᱟᱹᱜ ᱢᱤᱫᱴᱟᱹᱝ ᱜᱮ ᱤᱱᱯᱷᱚᱨᱢᱮᱥᱚᱱ ᱵᱟᱹᱱᱩᱜᱼᱟ, ᱡᱮᱞᱮᱠᱟ ᱤᱢᱮᱠᱥ ᱨᱮᱱᱟᱜ ᱚᱠᱛᱚ ᱥᱮ ᱛᱷᱚᱠ (ᱡᱟᱦᱟᱸ ᱫᱚ ᱞᱟᱭᱤᱵᱷᱤᱰᱤᱭᱳ ᱟᱨ ᱱᱚᱨᱢᱟᱞ ᱨᱮᱱᱟᱜ ᱵᱷᱮᱜᱟᱨ ᱵᱟᱭ ᱵᱟᱰᱟᱭ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ) ᱟᱨ ᱱᱚᱶᱟ ᱠᱚᱢ ᱤᱢᱮᱠᱥ ᱠᱚ ᱨᱩᱣᱟᱹᱲ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱾
+\n
+\nᱭᱩᱴᱭᱩᱵᱽ ᱫᱚ ᱢᱤᱫᱴᱮᱱ ᱥᱮᱵᱟ ᱨᱮᱱᱟᱜ ᱢᱤᱫ ᱞᱟᱹᱱᱟᱹᱤ ᱠᱟᱱᱟ ᱡᱟᱦᱟᱸ ᱫᱚ ᱱᱚᱶᱟ ᱦᱚᱨᱟ ᱟᱡᱟᱜ RSS ᱯᱷᱤᱰ ᱥᱟᱶᱛᱮ ᱮᱢᱚᱜ ᱠᱟᱱᱟ ᱾
+\n
+\nᱚᱱᱟᱛᱮ ᱵᱟᱪᱷᱟᱣ ᱫᱚ ᱟᱢ ᱪᱮᱫ ᱜᱮᱢ ᱵᱷᱟᱹᱵᱤᱛᱟ: ᱦᱩᱲᱟᱹᱜ ᱟᱨᱵᱟᱝ ᱥᱟᱹᱠᱷᱭᱟᱹᱛ ᱠᱟᱛᱷᱟ ᱾
+ ᱥᱴᱨᱤᱢ ᱠᱚ ᱵᱚᱫᱚᱞ/ᱥᱚᱫᱚᱨ ᱢᱮ
+ ᱡᱚᱠᱷᱚᱱ ᱯᱷᱤᱰ ᱚᱯᱰᱮᱴ ᱦᱩᱭᱩᱜᱼᱟ, ᱚᱱᱟ ᱞᱟᱹᱜᱤᱫ ᱛᱮ ᱴᱮᱵᱽ ᱠᱚ ᱦᱟᱛᱟᱣ ᱢᱮ ᱾ ᱡᱩᱫᱤ ᱢᱤᱫ ᱪᱮᱱᱮᱞ ᱫᱚ fast mode ᱵᱮᱵᱷᱟᱨ ᱠᱟᱛᱮ update ᱟᱠᱟᱱᱟ ᱮᱱᱠᱷᱟᱱ ᱱᱚᱶᱟ option ᱫᱚ ᱵᱟᱹᱱᱩᱜ-ᱟ ᱾
+ ᱱᱩᱣᱟ ᱯᱟᱭᱤᱯ ᱱᱤᱛ ᱦᱟᱹᱵᱤᱡ ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟᱨᱮ ᱥᱚᱯᱷᱴᱣᱮᱭᱟᱨ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾_x000D_
+\n_x000D_
+\nᱱᱚᱶᱟ ᱫᱚ ᱢᱚᱵᱟᱤᱞ ᱣᱟᱨᱥᱚᱱ ᱨᱮ ᱥᱚᱯᱷᱴᱣᱮᱨ ᱦᱩᱭᱩᱜᱼᱟ ᱾
+ ᱞᱚᱠ ᱥᱠᱨᱤᱱ ᱛᱷᱚᱠ ᱟᱨ ᱱᱳᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ ᱵᱟᱱᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱛᱚᱢᱱᱤᱞ ᱵᱮᱵᱷᱟᱨ ᱢᱮ
+ ᱟᱢᱟᱜ ᱰᱤᱵᱟᱤᱥ ᱨᱮ ᱱᱚᱶᱟ ᱮᱯ ᱵᱟᱹᱱᱩᱜ-ᱟ
+ ᱱᱚᱶᱟ ᱠᱟᱹᱢᱤ ᱞᱟᱹᱜᱤᱫ ᱫᱚ ᱞᱟᱹᱠᱛᱤᱭᱟᱱ ᱯᱷᱤᱞ ᱢᱮᱱᱮᱡᱚᱨ ᱵᱟᱝ ᱧᱟᱢ ᱞᱮᱱᱟ ᱾ %s
+ ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱟᱢᱟᱜ ᱫᱤᱥᱚᱢ ᱨᱮ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾
+ ᱱᱩᱶᱟ ᱫᱚ ᱢᱤᱫ ᱥᱟᱣᱚᱱᱰᱠᱞᱟᱣᱩᱰ ᱜᱳ+ ᱴᱨᱟᱠ ᱠᱟᱱᱟ, ᱟᱢᱟᱜ ᱫᱤᱥᱚᱢ ᱨᱮ ᱡᱚᱛᱚ ᱠᱷᱚᱱ ᱠᱚᱢ, ᱚᱱᱟᱛᱮ ᱱᱩᱭᱯᱟᱭᱤᱯ ᱫᱚ ᱱᱚᱣᱟ ᱴᱨᱟᱠ ᱥᱴᱨᱤᱢ ᱟᱨ ᱰᱟᱩᱱᱞᱚᱰ ᱵᱟᱭ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱾
+ ᱱᱩᱣᱟ ᱯᱟᱭᱤᱯ ᱫᱚ ᱱᱤᱡᱮᱨᱟᱜ ᱠᱟᱱᱟ, ᱚᱱᱟᱛᱮ ᱱᱩᱣᱟ ᱯᱟᱭᱤᱯ ᱫᱚ ᱱᱚᱣᱟ ᱵᱟᱭ ᱰᱟᱩᱱᱞᱚᱰ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱟᱨ ᱵᱟᱝ ᱥᱴᱨᱤᱢ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ᱾
+ ᱱᱩᱣᱟ ᱯᱟᱭᱤᱯ ᱨᱮᱱ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱚ ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟᱨᱮ ᱡᱟᱦᱟᱸᱱ ᱯᱮᱨᱮᱡ ᱥᱮᱞᱮᱫ ᱠᱚᱣᱟ, ᱚᱱᱟᱛᱮ ᱱᱩᱣᱟ ᱯᱟᱭᱤᱯ ᱨᱮᱱ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱚ ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟᱨᱮ ᱡᱟᱦᱟᱸᱱ ᱯᱮᱨᱮᱡ ᱥᱮᱞᱮᱫ ᱵᱟᱝ ᱠᱚ ᱧᱟᱢ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ᱾
+ ᱯᱷᱮᱭᱟᱨ ᱟᱠᱟᱱ
+ ᱱᱚᱶᱟ ᱵᱟᱪᱷᱟᱣ ᱫᱚ ᱚᱱᱠᱟᱱ ᱞᱟᱹᱜᱤᱫ ᱜᱮ ᱵᱮᱵᱦᱟᱨᱚᱜᱼᱟ ᱡᱩᱫᱤ %s ᱴᱷᱤᱠᱟᱹᱱᱟ
+ ᱰᱟᱩᱱᱞᱚᱰ ᱮᱛᱚᱦᱚᱵ ᱟᱠᱟᱱᱟ
+ ᱟᱢ ᱱᱤᱛᱚᱜ ᱚᱞ ᱪᱤᱠᱤ ᱨᱮ ᱚᱞ ᱪᱤᱠᱤ ᱵᱟᱪᱷᱟᱣ ᱫᱟᱲᱮᱭᱟᱜ ᱟ. ᱵᱟᱰᱟᱭ ᱢᱮ ᱡᱮ ᱥᱟᱦᱴᱟ ᱫᱚ ᱵᱷᱤᱸᱰᱟᱹᱣ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱟᱨ ᱵᱟᱪᱷᱟᱣ ᱢᱚᱰ ᱨᱮ ᱞᱤᱱᱠ ᱫᱚ ᱵᱟᱝ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱾
+ ᱪᱤᱠᱤ ᱨᱮ ᱚᱞ ᱵᱟᱪᱷᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱮᱱᱮᱢ ᱢᱮ
+ ᱯᱨᱟᱭᱵᱷᱮᱴ
+ ᱩᱢᱚᱨ ᱨᱮᱭᱟᱜ ᱞᱤᱢᱤᱴ
+ ᱯᱟᱹᱨᱥᱤ
+ ᱥᱚᱦᱚᱫ
+ ᱛᱷᱩᱢᱱᱟᱭᱤᱴ
+ ᱚᱯᱞᱚᱰᱟᱨ ᱟᱵᱟᱛᱟᱨ
+ ᱥᱟᱵ-ᱪᱟᱱᱮᱞ ᱟᱵᱟᱛᱟᱨ
+ ᱯᱨᱟᱭᱵᱷᱮᱴ
+ ᱤᱱᱴᱟᱨᱱᱟᱞ
+ ᱥᱚᱵᱽᱥᱠᱨᱟᱭᱵᱟᱨ
+ ᱯᱤᱱ ᱟᱠᱟᱱ ᱟᱹᱱᱤᱡ
+ ᱵᱮᱱᱟᱣᱤᱡᱟᱜ ᱢᱚᱱᱮ
+ ᱚᱯᱮᱱ ᱣᱮᱵᱥᱟᱤᱴ
+ ᱴᱮᱵᱽᱞᱮᱴ ᱢᱚᱰ
+ ᱨᱮ
+ ᱚᱯᱷ
+ ᱮᱠᱥᱳᱯᱞᱮᱭᱟᱨ ᱰᱤᱯᱚᱞᱴ
+ ᱥᱟᱱᱟᱢ ᱪᱟᱞᱟᱣ ᱢᱮ
+ ᱡᱟᱦᱟᱸᱱ ᱥᱴᱨᱤᱢ ᱠᱚ ᱱᱤᱛ ᱫᱷᱟᱹᱵᱤᱡ ᱰᱟᱩᱱᱞᱚᱰᱡᱚᱨ ᱦᱚᱛᱮᱛᱮ ᱥᱚᱯᱷᱴᱣᱮᱰ ᱵᱟᱱᱟᱣ ᱟᱠᱟᱱᱟ ᱚᱱᱟ ᱠᱚ ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱱᱚᱶᱟ ᱥᱴᱨᱤᱢ ᱨᱮ ᱢᱤᱫᱴᱟᱹᱝ ᱚᱰᱤᱭᱳ ᱴᱨᱟᱠ ᱢᱮᱱᱟᱜ ᱛᱟᱭᱟ
+ ᱡᱟᱹᱥᱛᱤ ᱧᱮᱞ ᱟᱠᱟᱱᱟ
+ ᱢᱟᱲᱟᱝ ᱨᱮ
+ ᱡᱩᱫᱤ ᱟᱢᱟᱜ ᱰᱤᱠᱳᱰᱟᱨ ᱮᱛᱚᱦᱚᱵ ᱨᱮᱭᱟᱜ ᱞᱟᱹᱞᱤᱥ ᱛᱟᱦᱮᱸᱱᱟ, ᱮᱱᱠᱷᱟᱱ ᱱᱚᱶᱟ ᱵᱟᱪᱷᱱᱟᱣ ᱫᱚ ᱮᱥᱮᱨ ᱢᱮ, ᱡᱟᱦᱟᱫᱚ ᱮᱛᱚᱦᱚᱵ ᱰᱤᱠᱳᱰᱟᱨ ᱮᱛᱚᱦᱚᱵ ᱵᱟᱝ ᱦᱩᱭ ᱞᱮᱱ ᱠᱷᱟᱱ ᱞᱟᱛᱟᱨᱼᱯᱨᱳᱭᱨᱤᱴᱤ ᱰᱤᱠᱳᱰᱟᱨ ᱨᱮ ᱨᱩᱣᱟᱹᱲ ᱦᱮᱡᱚᱜᱼᱟ ᱾ ᱱᱚᱶᱟ ᱨᱮᱭᱟᱜ ᱚᱡᱮ ᱫᱚ ᱮᱛᱚᱦᱚᱵ ᱰᱤᱠᱳᱰᱟᱨ ᱠᱚ ᱵᱮᱣᱦᱟᱨ ᱚᱠᱛᱚ ᱠᱷᱚᱱ ᱵᱮᱼᱲᱤᱪᱟᱹᱲ ᱯᱟᱥᱱᱟᱶ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱾
+ ᱱᱚᱶᱟ ᱠᱟᱹᱢᱤ ᱦᱚᱨᱟ ᱫᱚ ᱥᱩᱨᱥᱩᱯᱩᱨ ᱵᱚᱫᱚᱞ ᱦᱩᱭ ᱞᱮᱱ ᱠᱷᱟᱱ ᱵᱷᱤᱰᱤᱭᱳ ᱠᱳᱰᱮᱠ ᱠᱚ ᱵᱚᱫᱚᱞ ᱟᱨ ᱨᱤ-ᱤᱱᱥᱴᱟᱱᱥᱟᱭᱤᱴ (re-instantiates) ᱮᱫᱟ, ᱚᱱᱟ ᱫᱚ ᱥᱩᱨᱥᱩᱯᱩᱨ ᱠᱳᱰᱮᱠ ᱨᱮ ᱞᱟᱹᱜᱤᱫ ᱛᱮ ᱥᱩᱯᱩᱨ ᱥᱩᱯᱩᱨ ᱛᱮ ᱥᱮᱴᱮᱨᱚᱜ ᱨᱮᱱᱟᱜ ᱠᱟᱱᱟ ᱾ ᱱᱚᱶᱟ ᱥᱟᱛᱟᱢ ᱥᱟᱶᱛᱮ ᱮᱠᱥᱳᱯᱞᱮᱭᱟᱨ ᱟᱭᱢᱟ ᱚᱱᱚᱞ ᱨᱮ ᱵᱮᱵᱷᱟᱨ ᱟᱠᱟᱱᱟ, ᱱᱚᱶᱟ ᱥᱤᱴᱤᱝ ᱫᱚ ᱟᱱᱰᱨᱚᱭᱮᱰ ᱖ ᱟᱨ ᱚᱱᱟ ᱠᱷᱚᱱ ᱪᱮᱛᱟᱱ ᱨᱮᱜᱮ ᱟᱯᱷᱮᱠᱴ ᱟᱠᱟᱱᱟ
+\n
+\nᱱᱮᱛᱟᱨᱟᱜ ᱵᱷᱤᱰᱤᱭᱳ ᱯᱞᱮᱭᱟᱨ ᱥᱮ ᱯᱷᱩᱞᱥᱠᱨᱤᱱ ᱨᱮ ᱥᱮᱞᱮᱫᱚᱜ ᱡᱚᱠᱷᱚᱱ ᱱᱚᱶᱟ ᱵᱟᱪᱷᱟᱣ ᱮᱢ ᱫᱚᱦᱚ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ
+ ᱪᱮᱱᱟᱞ ᱥᱟᱦᱴᱟ ᱠᱚᱨᱮ ᱪᱮᱫ ᱴᱮᱵᱽ ᱠᱚ ᱵᱚᱫᱚᱞᱟ
+ ᱚᱯᱮᱱ ᱯᱞᱮ ᱠᱭᱩᱤ
+ ᱡᱚᱛᱚ ᱥᱠᱨᱤᱱ ᱨᱮ ᱵᱷᱮᱡᱟ ᱢᱮ
+ ᱱᱮᱛᱟᱨᱟᱜ ᱫᱟᱜᱽ
+ ᱠᱷᱮᱞ
+ ᱨᱤᱯᱷᱟᱭᱤᱞ
+ ᱚᱠᱛᱚ
+ ᱨᱩᱣᱟ.
+ ᱰᱮᱴᱟ ᱟᱨ ᱢᱮᱢᱚᱨᱤ ᱵᱮᱵᱷᱟᱨ ᱠᱚᱢ ᱞᱟᱹᱜᱤᱫ ᱛᱮ ᱪᱤᱛᱟᱹᱨ ᱠᱚᱣᱟᱜ ᱥᱤᱠᱷᱱᱟᱹᱛ ᱵᱟᱪᱷᱟᱣ ᱢᱮ ᱟᱨ ᱪᱤᱛᱟᱹᱨ ᱠᱚ ᱚᱞ ᱦᱚᱪᱚ ᱞᱟᱹᱜᱤᱫ ᱛᱮ ᱵᱟᱪᱷᱟᱣ ᱢᱮ. ᱢᱤᱢᱮᱨᱤ ᱟᱨ ᱚᱱ-ᱰᱤᱥᱠ ᱪᱤᱛᱟᱹᱨ ᱠᱮᱪ ᱵᱟᱱᱟᱨ ⁇ %s ᱪᱷᱟᱯᱟ ᱟᱠᱟᱱᱟ
+ ᱞᱟᱯᱷᱟᱝ ᱥᱤᱠᱷᱱᱟ.
+ ᱛᱟᱞᱢᱟ ᱥᱤᱠᱷᱱᱟᱹᱛ
+ ᱩᱥᱩᱞ ᱥᱤᱠᱷᱱᱟᱹᱛ
+ ᱯᱷᱟᱭᱞᱤᱥᱴ ᱧᱩᱛᱩᱢ ᱟᱨ ᱵᱷᱤᱰᱤᱭᱳ ᱧᱩᱛᱩᱢ ᱞᱮᱠᱟᱛᱮ ᱟᱨᱵᱟᱝ ᱵᱷᱤᱰᱤᱭᱳ URL ᱨᱮᱱᱟᱜ ᱢᱤᱫ ᱞᱮᱠᱟᱱ ᱞᱤᱥᱴᱤ ᱞᱮᱠᱟᱛᱮ ᱴᱷᱟᱶ ᱮᱢ ᱢᱮ
+ URL ᱛᱟᱹᱞᱠᱟᱹ ᱥᱟᱯᱲᱟᱣ
+ - %1$s: %2$s
+ ᱱᱚᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ ᱨᱮ ᱑᱖:᱙ ᱠᱷᱚᱱ ᱑:᱑ ᱟᱥᱯᱮᱠᱴ ᱚᱱᱩᱯᱟᱹᱛ ᱨᱮ ᱵᱷᱤᱰᱤᱭᱳ ᱛᱷᱚᱢᱵᱱᱮᱞ ᱜᱮᱫᱽ ᱢᱮ
+ ᱨᱤᱠᱟᱵᱽᱞᱤᱝ
+ ᱰᱤᱯᱷᱚᱞᱴ ᱠᱚᱱᱴᱮᱱᱴ ᱫᱤᱥᱚᱢ
+ ᱯᱤᱪ
+ ᱦᱳᱥᱴ
+ ExoPlayer ᱨᱮᱭᱟᱜ ᱰᱤᱠᱚᱰᱟᱨ ᱯᱷᱮᱞᱚᱵᱮᱠ ᱯᱷᱤᱪᱚᱨ ᱵᱮᱵᱷᱟᱨ ᱢᱮ
+ ᱮᱠᱥᱳᱯᱞᱮᱭᱟᱨ ᱥᱮᱴᱤᱝ
+ ᱮᱠᱥᱳᱯᱞᱮᱭᱟᱨ ᱥᱮᱴᱤᱸᱜᱽᱥ ᱠᱚ ᱪᱟᱪᱞᱟᱣ ᱢᱮ ᱾ ᱱᱚᱶᱟ ᱞᱟᱹᱜᱤᱫ ᱠᱷᱮᱞᱚᱸᱰᱤᱭᱟᱹ ᱠᱚᱣᱟᱜ ᱨᱤᱥᱴᱟᱨᱴ ᱞᱟᱹᱠᱛᱤ ᱠᱟᱱᱟ
+ ᱰᱟᱵᱞᱤᱝ
+ ᱰᱮᱥᱠᱨᱤᱯᱴᱤᱵ
+ ᱯᱨᱚᱜᱨᱮᱥᱤᱵᱽ ᱠᱚᱴᱮᱱᱴ (ᱱᱤᱛᱚᱜ %s) ᱨᱮ ᱞᱚᱰ ᱤᱱᱴᱟᱨᱵᱷᱮᱞ ᱨᱮᱱᱟᱜ ᱢᱟᱨᱟᱝ ᱮᱢ ᱢᱮ ᱢᱤᱫ ᱠᱚᱢ ᱵᱷᱚᱞᱮᱡᱽ ᱟᱡᱟᱜ ᱮᱛᱚᱦᱚᱵ ᱞᱚᱰᱰᱤᱝ ᱨᱮᱱᱟᱜ ᱟᱯᱞᱚᱰ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ
+ ᱚᱥᱴᱨᱮᱞᱤᱭᱟᱱ ᱚᱰᱤᱭᱳ ᱞᱟᱹᱜᱤᱫ
+ ᱴᱚᱴᱷᱟᱠᱤᱭᱟ. ᱥᱩᱪᱚᱱᱟ
+ ᱠᱷᱚᱵᱚᱨ ᱮᱦᱚᱵ ᱢᱮ
+ ᱢᱩᱪᱟᱹᱫ ᱠᱷᱚᱵᱚᱨ ᱴᱷᱟᱹᱶᱠᱟᱹ
+ ᱤᱱᱥᱴᱮᱸᱥ ᱥᱮᱞᱮᱫ ᱢᱮ
+ ᱤᱱᱥᱴᱟᱱᱥ URL ᱮᱢ ᱢᱮ
+ ᱚᱯᱰᱮᱴᱥ
+ ᱯᱚᱯ-ᱟᱯ ᱢᱚᱰ ᱨᱮ ᱠᱷᱮᱞᱚᱸᱰ
+ ᱥᱟᱦᱴᱟ
+ ᱩᱢᱮᱨ ᱞᱟᱹᱠᱛᱤᱭᱟᱱ ᱠᱟᱛᱷᱟ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱭᱩᱴᱭᱩᱵᱽ ᱨᱮᱱᱟᱜ \"Restricted Mode\" ᱚᱞ ᱢᱮ
+ ᱡᱚᱛᱚ
+ ᱱᱮᱴᱣᱟᱨᱠ ᱵᱷᱩᱞ
+ ᱟᱱᱰᱨᱚᱭᱮᱰ ᱨᱮ ᱞᱤᱵᱨᱮ ᱞᱟᱭᱤᱴᱣᱮᱴ ᱥᱴᱨᱤᱢᱤᱝ
+ ᱴᱮᱜᱥ
+ ᱥᱚᱨᱠᱟᱨᱤ
+ ᱚᱱᱚᱞ ᱨᱮ ᱡᱟᱭᱜᱟ ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱪᱮᱱᱮᱞ ᱨᱮᱱᱟᱜ ᱟᱵᱟᱛᱟᱨ ᱛᱷᱩᱱᱤᱠᱟ
+ ᱥᱮᱨᱮᱧ ᱞᱤᱥᱴᱤ ᱥᱟᱦᱴᱟ
+ ᱵᱟᱝ
+ ᱰᱟᱩᱱᱞᱚᱰ ᱢᱮ
+ ᱯᱷᱤᱞ ᱧᱩᱛᱩᱢ ᱨᱮ ᱞᱟᱹᱠᱛᱤᱭᱟᱱ ᱪᱤᱠᱤ ᱠᱚ
+ ᱪᱷᱟᱸᱪ:Copy to clipboard ᱨᱮ ᱪᱷᱟᱸᱪ:Copy to clipboard
+ ᱧᱩᱛᱩᱢ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱯᱷᱤᱞᱤᱢ ᱧᱩᱛᱩᱢ
+ ᱛᱷᱤᱭᱮᱴᱚᱨ
+ ᱪᱷᱟᱸᱪ
+ NewPipe ᱮᱯᱞᱤᱠᱮᱥᱚᱱ
+ ᱵᱟᱰᱟᱭ ᱞᱟᱹᱜᱤᱫ ᱴᱟᱯ ᱢᱮ
+ ᱦᱟᱥᱤ ᱠᱚᱞᱠᱟᱛᱟ
+ ᱱᱤᱛ ᱦᱟᱹᱵᱤᱡ ᱰᱟᱩᱱᱞᱚᱰ ᱯᱷᱳᱞᱰᱟᱨ ᱥᱮᱴ ᱵᱟᱝ, ᱱᱤᱛ ᱦᱟᱹᱵᱤᱡ ᱰᱟᱩᱱᱞᱚᱰ ᱯᱷᱳᱞᱰᱟᱨ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+ © %1$s ᱛᱮ %2$s ᱞᱟᱛᱟᱨ ᱨᱮ %3$s
+ About & FAQ
+ ᱞᱟᱭᱥᱮᱱᱥ
+ ᱥᱮᱞᱮᱫᱚᱜ ᱢᱮ
+ ᱱᱤᱭᱩ ᱯᱟᱭᱯᱮ ᱨᱮᱱᱟᱜ ᱯᱨᱟᱭᱵᱷᱮᱴᱤ ᱯᱚᱞᱤᱥᱤ
+ ᱱᱤᱣ ᱯᱟᱭᱤᱯ ᱯᱨᱚᱡᱮᱠᱴ ᱟᱢᱟᱜ ᱯᱨᱟᱭᱵᱷᱮᱴ ᱟᱹᱰᱤ ᱥᱚᱨᱮᱥ ᱜᱮᱭᱟ. ᱚᱱᱟᱛᱮ, ᱟᱢᱟᱜ ᱟᱹᱭᱫᱟᱹᱨᱤ ᱵᱟᱹᱱᱩᱜ ᱠᱷᱟᱱ ᱱᱚᱶᱟ ᱮᱯᱞᱤᱠᱮᱥᱚᱱ ᱡᱟᱦᱟᱱ ᱰᱮᱴᱟ ᱵᱟᱭ ᱥᱟᱢᱟᱝᱟ ᱾_x000D_
+\nᱱᱤᱣ ᱯᱟᱭᱤᱯ ᱨᱮᱱᱟᱜ ᱯᱨᱟᱭᱵᱷᱮᱴ ᱯᱚᱞᱤᱥᱤ ᱨᱮ ᱡᱟᱦᱟᱸᱱ ᱰᱮᱴᱟ ᱠᱚ ᱟᱢ ᱠᱨᱮᱥᱚᱨ ᱨᱮᱯᱳᱨᱴ ᱚᱠᱟᱛᱮ ᱟᱢ ᱚᱠᱟ ᱞᱮᱠᱟᱛᱮ ᱟᱢᱟᱜ ᱰᱮᱴᱟ ᱠᱚ ᱵᱚᱫᱚᱞᱟ ᱟᱨ ᱵᱚᱫᱚᱞᱟ ᱚᱱᱟ ᱵᱟᱵᱚᱫ ᱛᱮ ᱡᱚᱛᱚ ᱵᱟᱰᱟᱭ ᱮᱢᱚᱜ ᱟ᱾
+ ᱯᱨᱟᱭᱵᱷᱮᱴᱤ ᱯᱚᱞᱤᱥ ᱯᱟᱲᱦᱟᱣ ᱢᱮ
+ ᱞᱟᱭᱥᱮᱱᱥ ᱯᱟᱲᱦᱟᱣ ᱢᱮ
+ ᱟᱥᱚᱠᱟᱭ ᱛᱮ ᱚᱞ ᱟᱠᱟᱱ ᱯᱩᱥᱴᱟ
+ ᱯᱷᱤᱞ ᱥᱮᱴᱮᱨ ᱟᱠᱟᱱᱟ ᱟᱨ ᱵᱟᱝ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱᱟ
+ ᱱᱚᱝᱠᱟᱱ ᱯᱷᱳᱞᱰᱟᱨ ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱱᱚᱝᱠᱟᱱ ᱯᱷᱤᱞ/ᱥᱟᱹᱛ ᱨᱮᱱᱟᱜ ᱜᱟᱞᱢᱟᱨᱟᱣ ᱵᱟᱹᱱᱩᱜᱼᱟ
+ ᱢᱮᱴᱟᱰᱟᱴᱟ ᱞᱚᱰ ᱠᱟᱱᱟ…
+ ᱪᱟᱱᱮᱞ
+ ᱵᱚᱫᱚᱞ ᱢᱮ
+ ᱥᱟᱱᱟᱢ ᱠᱷᱮᱞ ᱢᱮ
+ ᱡᱚᱦᱚᱜ
+ ᱢᱤᱫ ᱫᱷᱟᱣ
+ ᱯᱷᱤᱞᱤ
+ ᱱᱳᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ
+ ᱱᱤᱭᱩ ᱯᱟᱭᱯᱮ ᱵᱟᱰᱟᱭ ᱦᱚᱪᱚ
+ ᱥᱴᱮᱯ
+ ᱥᱮᱵᱟ ᱨᱮ ᱡᱚᱲᱟᱣ ᱵᱟᱭ ᱫᱟᱲᱮᱭᱟᱜ ᱠᱟᱱᱟ
+ ᱵᱟᱝ ᱧᱟᱢ ᱟᱠᱟᱱᱟ
+ ᱥᱮᱞᱮᱫ
+ ᱤᱧ ᱵᱟᱹᱧ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ, ᱡᱟᱦᱟᱸᱱᱟᱜ ᱠᱷᱟᱹᱛᱤᱨ ᱤᱧ ᱵᱟᱹᱧ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱾
+ ᱞᱟᱹᱠᱛᱤᱭᱟᱱ ᱱᱮᱴᱣᱟᱨᱠ ᱡᱚᱲᱟᱣ
+ ᱡᱟᱦᱟᱱ ᱱᱮᱴᱣᱟᱨᱠ
+ ᱥᱩᱯᱩᱨ
+ ᱰᱷᱮᱨ ᱵᱟᱪᱷᱟᱣ
\ No newline at end of file
diff --git a/app/src/main/res/values-si/strings.xml b/app/src/main/res/values-si/strings.xml
index cbc248b8b92..85f248b1189 100644
--- a/app/src/main/res/values-si/strings.xml
+++ b/app/src/main/res/values-si/strings.xml
@@ -23,4 +23,11 @@
ඇතුලත් කරන්න මෙයට
චලන රූප භාගත කරන ස්තානය
චලන රූප ගබඩා කිරීමට ස්තානයක් තෝරන්න
+ උත්පතන මාදිලියේ විවෘත කරන්න
+ සමඟ බෙදාගන්න
+ බාහිර ශ්රව්ය වාදකය භාවිතා කරන්න
+ සමහර විභේදනවලදී හඬ ඉවත් කරයි
+ ප්රවාහ වාදකයක් හමු නොවීය (ඔබට එය වාදනය කිරීමට VLC ස්ථාපනය කළ හැක).
+ ප්රවාහ ගොනුව බාගන්න
+ ප්රවාහ වාදකයක් හමු නොවීය. VLC ස්ථාපනය කරන්නද?
\ No newline at end of file
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 3ad8a70238c..a76bc1d4df1 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -15,15 +15,15 @@
Použiť externý prehrávač zvuku
Prevzaté video ukladať do
Prevzaté video súbory sú uložené tu
- Vyberte priečinok na ukladanie videí
- Adresár pre stiahnuté audio
- Vyberte adresár pre ukladanie audio súborov
+ Vyberte priečinok pre stiahnuté video
+ Priečinok pre stiahnuté audio
+ Vyberte priečinok pre audio súbory
Prevzaté zvukové súbory sú uložené tu
Štandardné rozlíšenie
Prehrať cez Kodi
Nainštalovať chýbajúcu aplikáciu Kore\?
Zobraziť možnosť \"Prehrať cez Kodi\"
- Zobraziť možnosť \"Prehrať cez Kodi\"
+ Zobrazí možnosť prehrať video cez mediálne centrum Kodi
Zvuk
Predvolený zvukový formát
Téma
@@ -86,7 +86,7 @@
M
B
Požiadavka reCAPTCHA
- Spustiť v okne
+ Otvoriť vo vyskakovacom okne
Tieto práva sú potrebné pre
\nprehrávanie v mini okne
Preferovaný formát videa
@@ -100,11 +100,11 @@
Vyčistiť
Odstráni audio pri niektorých rozlíšeniach
Zapamätať si parametre mini okna
- Zapamätať si posledné nastavenie veľkosti a pozície mini okna
+ Zapamätá si posledné nastavenie veľkosti a pozície vyskakovacieho okna
Hľadať návrhy
Vyberte návrhy, ktoré sa majú zobrazovať pri vyhľadávaní
Najlepšie rozlíšenie
- Odber
+ Odoberať
Odoberané
Odber zrušený
Nemožno zmeniť odber
@@ -112,16 +112,16 @@
Odbery
Čo je nové
Hľadať v histórií
- Hľadané výrazy ukladať lokálne
+ Hľadané výrazy uloží lokálne
História pozretí
- Ukladať históriu pozretých videí
+ Uloží históriu pozretých videí
Pokračovať v prehrávaní
- Pokračovať po prerušeniach (napr. telefonát)
+ Pokračouje v prehrávaní po prerušení (napr. po telefonáte)
NewPipe oznámenia
Notifikácie NewPipe prehrávača
Preberanie
Povolené znaky v názvoch súborov
- Neplatné znaky budú nahradené týmito znakmi
+ Neplatné znaky budú nahradené znakmi s týmto významom
Náhradný znak
Písmená a číslice
Väčšina špeciálnych znakov
@@ -163,12 +163,12 @@
- %s videí
Nebol nájdený žiadny prehrávač pre stream (môžete si nainštalovať napr. VLC).
- Stiahnuť súbor stream
+ Stiahnuť súbor streamu
Zobraziť info
Uložené zoznamy
Pridať do
Zobrazovať tip \"Pridať podržaním\"
- Zobraziť tip pre stlačenie tlačidiel \"Pozadie\" alebo \"V okne\" v detailoch videa
+ Zobrazí tip pri stlačení tlačidiel pozadia alebo vyskakovacieho okna videa \"Podrobnosti:\"
Predvolený obsah pre krajinu
Prehrať všetko
Vždy
@@ -179,8 +179,8 @@
Prepnúť na Video
Importovať databázu
Exportovať databázu
- Prepíše aktuálnu históriu, odbery, zoznamy skladieb a (voliteľne aj) nastavenia
- Exportovať históriu, odbery, zoznamy skladieb a nastavenia
+ Prepíše aktuálnu históriu, odbery, zoznamy skladieb a (voliteľne) nastavenia
+ Exportuje históriu, odbery, zoznamy skladieb a nastavenia
Nepodarilo sa prehrať tento stream
Pri prehrávaní došlo k chybe a nemožno pokračovať
Zotavovanie po chybe v prehrávaní
@@ -247,7 +247,7 @@
Rýchly posun umožňuje prejsť na novú pozíciu rýchlejšie, ale s menšou presnosťou. Posun o 5, 15 alebo 25 sekúnd v tomto prípade nie je možný
Vyrovnávacia pamäť obrázkov vymazaná
Vymazať metadáta uložené vo vyrovnávacej pamäti
- Odstrániť všetky údaje webových stránok vo vyrovnávacej pamäti
+ Odstráni všetky údaje webových stránok vo vyrovnávacej pamäti
Vyrovnávacia pamäť metadát bola vymazaná
Automaticky zaradiť ďalší stream
Končiaci (neopakujúci sa) zoznam prehrávania bude pokračovať súvisiacim streamom
@@ -264,9 +264,9 @@
Automaticky vygenerované
Titulky
Upravte mierku textu titulkov prehrávača a štýly pozadia. Vyžaduje sa reštart aplikácie
- Monitorovanie pretečenia pamäte môže spôsobiť, že aplikácia nebude reagovať
+ Monitorovanie úniku pamäte môže spôsobiť, že aplikácia nebude reagovať
Nahlásiť mimo-cyklické chyby
- Vynútiť hlásenie výnimiek nedoručiteľných Rx mimo časového cyklu fragmentov alebo aktivity po zneškodnení
+ Vynúti hlásenie nedoručiteľných výnimiek Rx mimo časového cyklu fragmentov alebo aktivity po zneškodnení
Import
Importovať z
Exportovať do
@@ -304,7 +304,7 @@
Vymazať celú históriu pozretí\?
História pozretí bola vymazaná
Vymazať históriu vyhľadávania
- Vymaže históriu vyhľadávania kľúčových slov
+ Odstráni históriu vyhľadávania kľúčových slov
Vymazať celú históriu vyhľadávania\?
História vyhľadávaní bola vymazaná
1 položka bola vymazaná.
@@ -328,7 +328,7 @@
Krok
Vynulovať
Minimalizovať pri prepnutí aplikácie
- Akcia pri prepnutí na inú aplikáciu z hlavného prehrávača videa — %s
+ Akcia pri prepnutí do inej aplikácie z hlavného prehrávača videa - %s
Nič
Prehrávať na pozadí
Prehrávať v okne
@@ -345,7 +345,7 @@
Obnoviť predvolené nastavenia
Chcete obnoviť predvolené hodnoty\?
Počet odberateľov nie je k dispozícii
- Karty, ktoré sa zobrazujú na hlavnej stránke
+ Aké karty sa zobrazujú na hlavnej stránke
Konferencie
Aktualizácie
Zobrazí sa výzva na aktualizáciu aplikácie, keď je k dispozícii nová verzia
@@ -379,7 +379,7 @@
Post-spracovanie zlyhalo
Stop
Maximum opakovaní
- Maximálny počet pokusov pred zrušením stiahnutia
+ Maximálny počet pokusov pred zrušením sťahovania
Pozastaviť pri prechode na mobilné dáta
Je to užitočné pri prechode na mobilné dáta, niektoré sťahovania však nemožno pozastaviť
Zobraziť komentáre
@@ -389,9 +389,9 @@
Nemožno načítať komentáre
Zatvoriť
Obnoviť prehrávanie
- Obnovenie poslednej pozície prehrávania
+ Obnoví poslednú pozíciu prehrávania
Poradie v zoznamoch
- Zobraziť indikátory polohy prehrávania v zoznamoch
+ Zobrazí indikátory pozície prehrávania v zoznamoch
Vymazať údaje
Pozície prehrávania boli odstránené
Súbor bol presunutý alebo odstránený
@@ -477,7 +477,7 @@
- %d dní
Skupiny kanálov
- Aktualizované: %s
+ Zdroj naposledy aktualizovaný: %s
Nenačítané: %d
Načítavanie zdroja…
Spracovávanie zdroja…
@@ -493,7 +493,7 @@
Nová
Zdroj
Interval obnovy zdroja
- Čas po ktorom sa kontrola odberu považuje za zastaralú — %s
+ Čas od poslednej aktualizácie, kedy sa odber považuje za neaktuálny - %s
Vždy aktualizovať
Načítať z vyhradeného zdroja, ak je k dispozícii
Služba je dostupná len pre určité zdroje, zvyčajne je rýchlejšia ale môže vrátiť obmedzený počet položiek alebo neúplné informácie (napr. dĺžka, typ, status)
@@ -539,7 +539,7 @@
Zobraziť iba nezoskupené odbery
Nikdy
Iba na WiFi
- Spustiť automatické prehrávanie — %s
+ Spustí automatické prehrávanie - %s
Prehrať zoznam
Zatiaľ bez záložiek zoznamu
Vyberte zoznam skladieb
@@ -547,38 +547,38 @@
Nemožno rozpoznať URL. Otvoriť pomocou inej aplikácie\?
Automatický rad
Zoznam aktuálneho prehrávača bude prepísaný
- Prepnutie prehrávača môže vymazať zoznam
+ Prepnutie z jedného prehrávača na druhý môže nahradiť vaše poradie
Vyžadovať povolenie pred vyčistením zoznamu
Nič
Bufferuje
Náhodné
Opakovať
V kompaktnom oznámení môžete vybrať najviac tri akcie, ktoré sa majú zobraziť!
- Všetky nasledovné upozornenia môžete upraviť poklepaním. Tri z nich môžete vybrať a tieto sa budú zobrazovať v kompaktnom oznámení
+ Všetky nasledovné oznámenia môžete upraviť poklepaním. Tri z nich môžete vybrať a tieto sa budú zobrazovať v kompaktnom oznámení.
Akčné tlačidlo päť
Akčné tlačidlo štyri
Akčné tlačidlo tri
Akčné tlačidlo dva
Akčné tlačidlo jedna
- Orezať pomer strán videa zobrazovaného v miniatúre z 16:9 na 1:1
+ Oreže miniatúru videa zobrazenej v oznámení z pomeru strán 16:9 na 1:1
Orezať pomer strán miniatúry na 1: 1
Zobraziť memory leaks
Zaradené do poradia
Zaradiť do poradia
- Vymazať cookies, ktoré NewPipe ukladá, keď vyriešite reCAPTCHA
+ Vymaže cookies, ktoré NewPipe ukladá, keď vyriešite reCAPTCHA
reCAPTCHA cookies boli vymazané
Vymazať cookies reCAPTCHA
YouTube poskytuje \"Obmedzený režim\", ktorý skrýva potenciálny obsah pre dospelých
- Zobraziť obsah, ktorý je možno nevhodný pre deti, pretože má vekovú hranicu (napríklad 18+)
- Nechajte Android, aby prispôsobil farbu upozornenia podľa hlavnej farby v miniatúre (nemusí to fungovať na všetkých zariadeniach)
+ Zobrazí obsah, ktorý je pravdepodobne nevhodný pre deti, pretože má vekové obmedzenie (napríklad 18+)
+ Nechajte Android, aby prispôsobil farbu oznámenia podľa hlavnej farby v miniatúre (nemusí to fungovať na všetkých zariadeniach)
Farby upozornení
Zobrazovať miniatúru
- Používať miniatúru ako pozadie pri uzamknutej obrazovke a v upozorneniach
+ Použije miniatúru pre pozadie uzamknutej obrazovke a oznámenia
Počítanie hash
- Upozornenie pri generovaní hash z názu videa
+ Oznámenia o priebehu hašovania videa
Oznámenie o hashovaní videa
Nedávne
- Vypnite, pokiaľ nechcete zobrazovať meta informácie ako autor streamu, obsah streamu alebo vyhľadávanie
+ Vypnutím skryjete metainformačné polia s ďalšími informáciami o autorovi streamu, obsahu streamu alebo požiadavke na vyhľadávanie
Zobrazovať meta informácie
Kapitoly
Popis
@@ -605,7 +605,7 @@
Zobraziť podrobnosti kanála
Vyrieš
Nočná téma
- Ak vám video pri prehrávaní seká alebo sa zobrazuje čierna obrazovka zakážte tunelovanie médií
+ Ak sa video pri prehrávaní seká alebo sa objaví čierna obrazovka, vypnite tunelovanie médií.
Zakázať tunelovanie médií
Interné
Súkromné
@@ -631,8 +631,8 @@
\nChcete sa odhlásiť z odberu tohto kanála\?
Nemožno načítať informačný kanál \'%s\'.
Chyba pri načítaní kanála
- \'Storage Access Framework\' je podporovaný len od Androidu 10 a vyššie
- Pri každom sťahovaní sa zobrazí výzva kam uložiť súbor
+ Od Androidu 10 je podporovaný len \'Storage Access Framework\'
+ Pri každom sťahovaní sa zobrazí výzva, kam uložiť súbor
Nie je nastavený adresár na sťahovanie, nastavte ho teraz
Označiť ako videné
Vypnuté
@@ -653,11 +653,11 @@
Nízka kvalita (menšie)
Vysoká kvalita (väčšie)
Náhľad miniatúry pri vyhľadávaní
- Zobraziť farebné stužky Picassa na obrázkoch podľa ich zdroja: červená pre sieť, modrá pre disk a zelená pre pamäť
+ 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ázka
Potiahnutím vymazať
Komentáre sú zakázané
- Pri zamknutej auto-rotácií nespúšťať videá v mini prehrávači, ale prepnúť sa priamo do režimu celej obrazovky. Prístup k mini prehrávaču bude po ukončení režimu celej obrazovky
+ 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
Hlavný prehrávač na celej obrazovke
Návrhy vzdialeného vyhľadávania
Miestne návrhy vyhľadávania
@@ -689,13 +689,13 @@
Vymazať všetky stiahnuté súbory z disku\?
Upozornenia sú vypnuté
Upozornenie z prehrávača
- Nastavte notifikáciu aktuálneho prehrávania
+ Nastavte oznámenie aktuálneho streamu prehrávania
Je vyžadované pripojenie na internet
Začali ste odoberať tento kanál
,
Zapnúť všetko
Nové streamy
- Upozornenia na nové streamy v odberoch
+ Oznámenia o nových streamoch v odberoch
- %s nový stream
- %s nové streamy
@@ -703,7 +703,7 @@
Skontrolovať nové streamy
Upozornenia na nové streamy
- Upozorniť na nové streamy z odberov
+ Upozorní na nové streamy z odberov
Akákoľvek sieť
Dostávať upozornenia
Poltón
@@ -732,9 +732,9 @@
Rýchly režim
Import alebo export odberov z 3-bodkovej ponuky
Akcia gesta vľavo
- Akcia pre gesto v pravej polovici obrazovky
+ Vyberte gesto pre pravú polovicu obrazovky prehrávača
Akcia gesta vpravo
- Akcia pre gesto v ľavej polovici obrazovky
+ Vyberte gesto pre ľavú polovicu obrazovky prehrávača
Jas
Hlasitosť
Nič
@@ -742,11 +742,11 @@
Odstrániť duplikáty\?
Rozpozerané
Dopozerané
- Toto sa môže hodiť v prípade, že máte pokazené tlačidlo na slúchadlách
+ Toto sa môže hodiť v prípade, že máte pokazené tlačidlá na slúchadlách
Ignorovať fyzické tlačidlá
- Zmena veľkosti intervalu načítania pri progresívnom obsahu (v súčasnosti %s). Nižšia hodnota môže urýchliť ich počiatočné načítanie
+ Zmení veľkosť intervalu načítania pri progresívnom obsahu (v súčasnosti %s). Nižšia hodnota môže urýchliť ich počiatočné načítanie
Preferovať pôvodné audio
- Vyberať pôvodnú zvukový stopu bez ohľadu na nastavený jazyk
+ Vyberte pôvodnú zvukovú stopu bez ohľadu na jazyk
Preferovať prehrávanie popisu
Zvuk: %s
Zvuková stopa
@@ -756,41 +756,41 @@
Výber zvukovej stopy pre externé prehrávače
Neznáma
Nadchádzajúce
- Úprava nastavení prehrávača ExoPlayer. Pre aplikovanie týchto zmien je nutné reštartovať ExoPlayer
+ Úprava niektorých nastavení prehrávača ExoPlayer. Pre aplikovanie týchto zmien je potrebné reštartovať prehrávač
Túto možnosť povoľte, ak máte problémy s inicializáciou dekodéra, ktorý sa v prípade zlyhania inicializácie primárnych dekodérov vráti k dekodérom s nižšou prioritou. To môže mať za následok nižší výkon prehrávania ako pri použití primárnych dekodérov
- Používať funkciu záložného dekodéra prehrávača ExoPlayer
+ Použiť funkciu záložného dekodéra prehrávača ExoPlayer
Vždy použiť nastavenia výstupu videa ExoPlayera
%1$s %2$s
povodná
dabovaná
- Vyberať zvukovú stopu s popisom pre zrakovo postihnutých ak je k dispozicií
+ Vyberte zvukovú stopu s popisom pre osoby so zrakovým postihnutím, ak je k dispozícii
Zobrazovať/Skrývať streamy
Nastavenia ExoPlayer
- Toto riešenie spôsobí to, že pri zmene textúry sa aktuálne používaný kodek uvoľní a potom znova použije, miesto toho aby sa textúra rovno použila na kodek. Toto nastavenie, ktoré už ExoPlayer používa na niektorých zariadeniach s týmto problémom, má vplyv len na Android 6 a vyšší
+ Toto riešenie uvoľní a znovu nastaví videokodeky pri zmene rozhrania namiesto priameho nastavenia rozhrania kodeku. Nastavenie už používa ExoPlayer na niektorých zariadeniach s týmto problémom a týka sa len systému Android 6 a vyššie
\n
-\nPovolenie tejto možnosti môže zabrániť chybám pri prehrávaní pri prepínaní aktuálneho prehrávača videa alebo prepínaní na celú obrazovku
+\nPovolením tejto možnosti môžete zabrániť chybám prehrávania pri zmene aktuálneho prehrávača videa alebo pri prepnutí do režimu celej obrazovky
popisná
Videá
Odberatelia
- Karty zobrazované na stránkach kanála
+ Aké karty sa zobrazujú na stránkach kanála
Karty kanálov
Krátke
Načítavanie metadát…
Prepnúť orientáciu obrazovky
- Pozícia hlavných kariet
+ Poloha hlavných kariet
Prepnúť na celú obrazovku
Načítať karty kanála
- Ďalší prúd
+ Ďalší stream
Vaše zariadenie nepodporuje tunelovanie medií a preto bolo tunelovanie medií zakázané.
Otvoriť zoznam prehrávania
O kanále
Dopredu
Albumy
Dozadu
- Opakovať
- Karty na načítanie pri aktualizácii informačného kanála. Táto možnosť nemá žiadny účinok, ak je kanál aktualizovaný pomocou rýchleho režimu.
+ Opäť prehrať
+ Karty, ktoré sa majú načítať pri aktualizácii informačného kanála. Táto možnosť nemá žiadny účinok, ak je kanál aktualizovaný pomocou rýchleho režimu.
Zoznamy skladieb
- Presunúť lištu kariet dolu
+ Presunie výber hlavnej karty do spodnej časti
Žiadne živé prenosy
Prehrať
Ďalšie možnosti
@@ -798,6 +798,33 @@
Dĺžka
Žiadne videá
Kanály
- Predchádzajúci prúd
+ Predchádzajúci stream
Naživo
+ Kvalita obrázkov
+ \?
+ Nízka kvalita
+ Avatary
+ Nenačítavať obrázky
+ Vysoká kvalita
+ Zdieľať playlist
+ Stredná kvalita
+ Bannery
+ Vyberte kvalitu obrázkov a či sa majú obrázky vôbec načítať, aby sa znížila spotreba dát a pamäte. Zmeny vymažú vyrovnávaciu pamäť obrázkov v pamäti a na disku - %s
+ Zobraziť viac
+ Zobraziť menej
+ Každú akciu oznámenia upravte poklepaním. Prvé tri akcie (prehrať/pozastaviť, predchádzajúce, ďalšie) sú nastavené systémom a nie je možné ich prispôsobiť.
+ Náhľady
+ Avatary uploadera
+ Sub-kanálové avatary
+ Zdieľať s názvami
+ Zdieľať URL playlistu
+
+ - %s odpoveď
+ - %s odpovede
+ - %s odpovedí
+
+ Zdieľajte playlist s podrobnosťami, ako je jeho názov a názvy videí, alebo ako jednoduchý zoznam URL adries videí
+ - %1$s: %2$s
+ %1$s
+\n%2$s
\ No newline at end of file
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 8bb8d1b3de7..66659c77a2d 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -227,7 +227,7 @@
Ограничи ред за преузимање
Затвори
Корисно при преласку на мобилне податке, иако нека преузимања не могу бити обустављена
- Прекид на мереним мрежама
+ Прекид на мрежама с ограничењем
Највећи број покушаја пре отказивања преузимања
Највише покушаја
Заустави
@@ -280,7 +280,7 @@
Умањи при мењању апликације
Прикажи обавештење када постоји нова верзија апликације
Ажурирања
- Ограничи резолуцију када користиш мобилне податке
+ Ограничење резолуције када се користе мобилни подаци
Одбиј
Без ограничења
Прихвати
@@ -448,7 +448,7 @@
Очисти историју гледања
Чисти колачиће које NewPipe чува када решите „reCAPTCHA“
Извоз историје, праћења, плејлисти и подешавања
- Замениће вашу тренутну историју, праћења, плејлисте и (опционо) подешавања
+ Замениће вашу тренутну историју, праћења, плејлисте и (опционално) подешавања
„reCAPTCHA“ колачићи су очишћени
Очисти „reCAPTCHA“ колачиће
Извоз базе података
@@ -485,7 +485,7 @@
Није могуће потврдити инстанцу
Унесите URL адресу инстанце
Додајте инстанцу
- Пронађите инстанце које Вам се свиђају на %s
+ Пронађите инстанце које вам се свиђају на %s
PeerTube инстанце
Изаберите своје омиљене PeerTube инстанце
URL адреса није препозната. Отворити помоћу друге апликације\?
@@ -521,7 +521,7 @@
Дугме треће радње
Дугме друге радње
Дугме прве радње
- Исеците сличицу видеа приказану у обавештењу с размере 16:9 на размеру 1:1
+ Исеците сличицу видео снимка приказану у обавештењу с размере 16:9 на размеру 1:1
Исеци сличицу на размеру 1:1
Приказивање резултата за: %s
Отвори помоћу
@@ -572,9 +572,9 @@
Желите ли да избришете ову групу\?
Празан назив групе
- - %d одабран
- - %d одабрана
- - %d одабраних
+ - %d изабран
+ - %d изабрана
+ - %d изабраних
Нема изабраних праћења
Изабрана праћења
@@ -719,7 +719,7 @@
Преглед сличице траке за претрагу
Прикажи следеће стримове
Прикажи/сакриј стримове
- Користите резервну функцију декодера ExoPlayer-а
+ Користи резервну функцију декодера ExoPlayer-а
оригинални
Промените величину интервала учитавања на прогресивним садржајима (тренутно %s). Нижа вредност може убрзати њихово почетно учитавање
Корисно, на пример, ако користите слушалице са поквареним физичким дугмадима
@@ -731,7 +731,7 @@
Конфигуришите обавештење о тренутно репродукованом стриму
Изаберите оригинални аудио снимак, без обзира на језик
Изаберите аудио снимак са описима за особе са оштећеним видом, ако је доступан
- Дај предност описном аудио снимку
+ Преферирај описни аудио снимак
Радња покретом удесно
Осветљеност
Јачина звука
@@ -764,7 +764,7 @@
описни
синхронизовани
Управљајте неким подешавањима ExoPlayer-а. Ове промене захтевају рестартовање плејера да би се примениле
- Дај предност оригиналном аудио снимку
+ Преферирај оригинални аудио снимак
Ово заобилазно решење ослобађа и поново инстанцира кодеке видео снимка када дође до промене површине, уместо да се површина директно поставља на кодек. ExoPlayer већ користи ово на неким уређајима са овим проблемом, ово подешавање утиче само на Android 6 и новије верзије.
\n
\nОмогућавање ове опције може спречити грешке при репродукцији приликом пребацивања тренутног плејера видео снимака или преласка на цео екран
@@ -819,4 +819,12 @@
Дели плејлисту
Делите плејлисту са детаљима, као што су назив плејлисте и наслови видео снимака или као једноставна листа URL адреса видео снимака
-%1$s: %2$s
+
+ - %s одговор
+ - %s одговора
+ - %s одговора
+
+ Прикажи више
+ Прикажи мање
+ Измените сваку радњу обавештења у наставку тако што ћете је додирнути. Прве три радње (пусти/паузирај, претходни и следећи) поставља систем и не могу се прилагодити.
\ No newline at end of file
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index d3739e29ed8..2f66aa0de0b 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -567,7 +567,7 @@
Inaktivera för att dölja videobeskrivning och ytterligare information
Visa meta-information
Använd miniatyrbild som bakgrund till både låsskärm och aviseringar
- Redigera varje aviseringsåtgärd nedan genom att trycka på den. Välj upp till tre av dem som ska visas i den kompakta aviseringen genom att använda kryssrutorna till höger
+ Redigera varje aviseringsåtgärd nedan genom att trycka på den. Välj upp till tre av dem som ska visas i den kompakta aviseringen genom att använda kryssrutorna till höger.
Låt Android färglägga varje avisering individuellt utifrån miniatyrbildens huvudsakliga färg (notera att detta inte är tillgängligt på alla enheter)
Färglägg avisering
Du kan som mest välja tre åtgärder att visa i den kompakta aviseringen!
@@ -806,4 +806,11 @@
- %1$s: %2$s
Dela spellistan med detaljer så som spellistans namn och video-titlarna eller som en enkel lista med URL till videorna
Välj bildkvalitet och om bilder överhuvudtaget ska laddas för att minska data och minnesanvändningen. Ändringar rensar både i minnet och bildcache på disk – %s
+ Visa mer
+
+ - %s svar
+ - %s svar
+
+ Visa mindre
+ Redigera varje aviseringsåtgärd nedan genom att trycka på den. De tre första åtgärderna (spela/pausa, föregående och nästa) är satta av systemet och kan inte ändras.
\ No newline at end of file
diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml
index 9b97445e121..73cc5a3da8a 100644
--- a/app/src/main/res/values-ta/strings.xml
+++ b/app/src/main/res/values-ta/strings.xml
@@ -145,8 +145,8 @@
- %s பார்வைகள்
- - காணொளிகள்
- - காணொளிகள்
+ - %sகாணொளிகள்
+ - %sகாணொளிகள்
முதற்பக்கத்துக்கு மாற்று
எந்த காணொலியும் இல்லை
diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml
index aaf1bf4cbee..b2846823c94 100644
--- a/app/src/main/res/values-te/strings.xml
+++ b/app/src/main/res/values-te/strings.xml
@@ -146,7 +146,7 @@
పూర్తి స్క్రీన్లో ప్రధాన ప్లేయర్ని ప్రారంభించండి
డీబగ్ చేయండి
ఏమిలేదు
- నోటిఫికేషన్లో చూపబడిన వీడియో థంబ్నెయిల్ను 16:9 నుండి 1:1 కారక నిష్పత్తికి స్కేల్ చేయండి (వక్రీకరణలను ప్రవేశపెట్టవచ్చు)
+ నోటిఫికేషన్లో చూపబడిన వీడియో థంబ్నెయిల్ను 16:9 నుండి 1:1 కారక నిష్పత్తికి మార్చుము
పునరావృతం చేయండి
వీడియో \"వివరాలు:\"లో బ్యాక్గ్రౌండ్ లేదా పాప్అప్ బటన్ను నొక్కినప్పుడు చిట్కాను చూపు
URLని గుర్తించడం సాధ్యపడలేదు. మరొక యాప్తో తెరవాలా\?
@@ -177,7 +177,7 @@
ట్యాబ్ని ఎంచుకోండి
సభ్యత్వాన్ని తొలగించుము
సమాచారాన్ని చూపుము
- సూక్ష్మచిత్రాన్ని 1:1 కారక నిష్పత్తికి స్కేల్ చేయండి
+ సూక్ష్మచిత్రాన్ని 1:1 కారక నిష్పత్తికి మార్చుము
ఒక ప్లేయర్ నుండి మరొక ప్లేయర్కు మారడం వలన మీ క్యూను భర్తీ చేయవచ్చు
సంబంధిత స్ట్రీమ్ను జోడించడం ద్వారా (పునరావృతం కాని) ప్లేబ్యాక్ క్యూను ముగించడాన్ని కొనసాగించండి
దిగువన ఉన్న ప్రతి నోటిఫికేషన్ చర్యను దానిపై నొక్కడం ద్వారా సవరించండి. కుడివైపు ఉన్న చెక్బాక్స్లను ఉపయోగించడం ద్వారా కాంపాక్ట్ నోటిఫికేషన్లో చూపబడే వాటిలో మూడు వరకు ఎంచుకోండి
@@ -201,7 +201,7 @@
షఫుల్ చేయండి
బఫరింగ్
డిఫాల్ట్ వీడియో ఫార్మాట్
- రాత్రి థీమ్
+ చీకటి థీమ్
చీకటి
ఫాస్ట్-ఫార్వర్డ్/-రివైండ్ సీక్ వ్యవధి
క్యూను క్లియర్ చేయడానికి ముందు నిర్ధారణ కోసం అడగండి
@@ -462,4 +462,11 @@
ఆగిపోయింది
క్రమం
%sని డౌన్లోడ్ చేయడానికి నొక్కండి
+ దిగువన ఉన్న ప్రతి నోటిఫికేషన్ చర్యను దానిపై నొక్కడం ద్వారా సవరించండి. మొదటి మూడు చర్యలు (ప్లే/పాజ్, మునుపటి మరియు తదుపరి) సిస్టమ్ ద్వారా సెట్ చేయబడ్డాయి మరియు అనుకూలీకరించబడవు.
+ భాషతో సంబంధం లేకుండా అసలు ఆడియో ట్రాక్ని ఎంచుకోండి
+ వివరణాత్మక ఆడియోకు ప్రాధాన్యత ఇవ్వండి
+ ఉదాహరణకు, మీరు విరిగిన భౌతిక బటన్లతో హెడ్సెట్ని ఉపయోగిస్తుంటే ఉపయోగకరంగా ఉంటుంది
+ ప్రగతిశీల విషయాలపై లోడ్ విరామం పరిమాణాన్ని మార్చండి (ప్రస్తుతం %s). తక్కువ విలువ వాటి ప్రారంభ లోడింగ్ను వేగవంతం చేయవచ్చు
+ హార్డ్వేర్ మీడియా బటన్ ఈవెంట్లను విస్మరించండి
+ అసలు శ్రావ్యయానికి ప్రాధాన్యత ఇవ్వండి
\ No newline at end of file
diff --git a/app/src/main/res/values-ti/strings.xml b/app/src/main/res/values-ti/strings.xml
index ab3505453d0..7845242c2b8 100644
--- a/app/src/main/res/values-ti/strings.xml
+++ b/app/src/main/res/values-ti/strings.xml
@@ -47,7 +47,7 @@
ፖፕኣፕ
ትሑዝ ድንቀት
ዝወረዱ ናይ ተንቃሳቀሴ-ምስሌ ፋይላት ኣብዚ ይኽዘኑ
-
+
ናይ እኽሊ ምስሊ ምስ ናይ 1:1 ርክባት
ቀዳማይ ወሰን ተጠዋቃ
ደገመ
@@ -62,4 +62,9 @@
ተንቃሳቀሴ-ምስሌ ፋይል ኣራግፍ
ታብ ምረጽ
ድሕረ ባይታ
+ ብርሃን
+ ጸልማት
+ ካልኣይ ስጉምቲ መጠወቒ
+ ሳልሳይ ስጉምቲ መጠወቒ
+ ሓሙሻይ ስጉምቲ መጠወቒ
\ No newline at end of file
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index b1ecacfc3f4..056434a4d69 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -2,7 +2,7 @@
Başlamak için büyütece dokunun.
%1$s tarihinde yayınlandı
- Akış oynatıcısı bulunamadı. VLC kurulsun mu\?
+ Video oynatıcısı bulunamadı. VLC kurulsun mu?
Kur
İptal
Tarayıcıda aç
@@ -25,7 +25,7 @@
Eksik Kore uygulaması yüklensin mi\?
\"Kodi ile oynat\" seçeneğini göster
Kodi ortam merkezi üzerinden video oynatmak için bir seçenek göster
- Öntanımlı ses biçimi
+ Varsayılan ses biçimi
Tema
Koyu
Açık
@@ -77,11 +77,11 @@
Panoya kopyalandı
Lütfen daha sonra ayarlardan uygun indirme klasörü belirleyin
İndirme menüsü ayarlanamadı
- Açılır pencere kipinde aç
- Öntanımlı açılır pencere çözünürlüğü
+ Açılır pencere modunda aç
+ Varsayılan açılır pencere çözünürlüğü
Yüksek çözünürlükleri göster
Yalnızca bazı aygıtlar 2K/4K videoları oynatabilir
- Öntanımlı video biçimi
+ Varsayılan video biçimi
Siyah
Açılır pencere kipinde oynatılıyor
Tümü
@@ -190,7 +190,7 @@
Ana Görünüme Geç
Çekmeceyi Aç
Çekmeceyi Kapat
- Akış oynatıcı bulunamadı (Oynatmak için VLC kurabilirsiniz).
+ Video oynatıcı bulunamadı (Oynatmak için VLC kurabilirsiniz).
Her Zaman
Yalnızca Bir Kez
Dış oynatıcılar bu tür bağlantıları desteklemez
@@ -243,7 +243,7 @@
Parçanın dışında veya atımdan sonraki etkinlik yaşam döngüsündeki teslim edilemeyen Rx beklentilerinin bildirimini zorla
Hızlı isabetsiz konumlama kullan
İsabetsiz konumlama, oynatıcının daha düşük hassasiyetle daha hızlı konumlamasını sağlar. 5, 15 veya 25 saniyeye konumlama bununla birlikte çalışmamaktadır
- Sonraki akışı kuyruğa kendiliğinden ekle
+ Sonraki videoyu kuyruğa otomatik ekle
İlgili bir akış ekleyerek sonlanacak (yinelemeyen) oynatma sırasını sürdür
Dosya
Böylesi klasör yok
@@ -280,7 +280,7 @@
\n
\nSürdürmek istiyor musunuz\?
Resim önbelleği temizlendi
- Önbelleğe alınmış üstverileri temizle
+ Önbelleğe alınmış meta verileri silin
Önbelleğe alınmış tüm web sayfası verilerini kaldır
Üstveri önbelleği temizlendi
Oynatım Hızı Denetimleri
@@ -423,7 +423,7 @@
- %s dinleyici
Uygulama yeniden başlatıldıktan sonra dil değişecektir
- Hızlı ileri/geri konumlama süresi
+ Hızlı ileri/geri atlama süresi
PeerTube örnekleri
Favori PeerTube örneklerinizi seçin
%s adresinde beğendiğiniz örnekleri bulun
@@ -475,7 +475,7 @@
Abonelik seçilmedi
- %d öğe seçildi
- - "%d öğe seçildi"
+ - %d öğe seçildi
Boş grup adı
Bu grubu silmek istiyor musunuz\?
@@ -534,16 +534,16 @@
Oynatmayı kendiliğinden başlat — %s
Oynatma kuyruğu
URL tanınamadı. Başka bir uygulamayla açılsın mı\?
- Kendiliğinden kuyruğa alış
+ Otomatik kuyruğa alış
Etkin oynatıcının kuyruğu değiştirilecek
Bir oynatıcıdan diğerine geçmek kuyruğunuzu değiştirebilir
- Bir kuyruğu temizlemeden önce onay iste
+ Bir sırayı temizlemeden önce onay iste
Hiçbir şey
Ara belleğe alınıyor
Karıştır
- Tekrarla
+ Yinele
Bildirim sekmesinde gösterilecek en fazla üç eylem seçebilirsiniz!
- Aşağıdaki bildirim eyleminlerini üzerine dokunarak düzenleyin. Sağdaki onay kutularını kullanarak sıkışık bildirimde gösterilecek üç eylemi seçin
+ Aşağıdaki bildirim eyleminlerini üzerine dokunarak düzenleyin. Sağdaki onay kutularını kullanarak üst bildirimde gösterilecek üç eylemi seçin.
Beşinci eylem düğmesi
Dördüncü eylem düğmesi
Üçüncü eylem düğmesi
@@ -632,7 +632,7 @@
Yüksek nitelik (geniş)
Yorumlar devre dışı
Yaratıcısınca kalplendi
- İzlendi olarak imle
+ İ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öster
Uzak arama önerileri
@@ -667,7 +667,7 @@
\nLütfen Depolama Erişimi Çerçevesi uyumlu dosya yönetici kurun
Hata raporları için bildirimler
Oynatıcı kullanırken çöktürme seçeneği gösterir
- Oynatıcıyı çöktür
+ Oynatıcıyı çökert
Sabitlenmiş yorum
LeakCanary yok
ExoPlayer öntanımlısı
@@ -732,7 +732,7 @@
Ses düzeyi
Hiçbiri
Parmağınızı ekranın sol yarısında kaydırırken ne yapılacağını seçin
- Varsa, görsel engelli kişiler için betimlemeli ses parçasını seç
+ Varsa, görsel engelli kişiler için betimli ses parçasını seç
Bilinmeyen
ExoPlayer ayarları
Kimi ExoPlayer ayarlarını yönet. Bu değişiklikler oynatıcının yeniden başlatılmasını gerektirir
@@ -741,15 +741,15 @@
betimlemeli
%1$s %2$s
Dış oynatıcılar için ses parçası seç
- Dil ne olursa olsun özgün ses parçasını seç
+ Dilden bağımsız olarak orijinal ses parçasını seçin
Ses: %s
- Özgün sesi yeğle
- Betimlemeli sesi yeğle
+ Orijinal sesi tercih edin
+ Açıklayıcı sesi tercih edin
Ses parçası
Bu akışta halihazırda bir ses parçası bulunmalıdır
Akış yok
Canlı akış yok
- Sağ kaydırma eylemi
+ Sağ hareket işlemi
Ana sekme seçiciyi alta taşı
Ana sekme konumu
Ortam tünelleme öntanımlı olarak devre dışı bırakılmıştır çünkü aygıt modelinizin desteği bilinmemektedir.
@@ -759,7 +759,7 @@
\n
\nBu ayarı etkinleştirmek, geçerli video oynatıcısını değiştirirken veya tam ekrana geçerkenki oynatma hatalarını önleyebilir
Progresif içeriklerdeki yükleme aralığı boyutunu değiştir (şu anda %s). Daha düşük değer ilk yüklemeyi hızlandırabilir
- Sol kaydırma eylemi
+ Sol hareket işlemi
Parmağınızı ekranın sağ yarısında kaydırırken ne yapılacağını seçin
ExoPlayer\'ın çözücü yedek özelliğini kullan
Resim niteliği
@@ -806,4 +806,11 @@
Kanallar
Önceki akış
Canlı
+ Daha fazla göster
+ Daha az göster
+ Aşağıdaki her bir bildirim eylemini üzerine dokunarak düzenleyin. İlk üç eylem (oynat/duraklat, önceki ve sonraki) sistem tarafından ayarlanır ve özelleştirilemez.
+
+ - %s yanıt
+ - %s yanıt
+
\ No newline at end of file
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 16212c93373..76813a04f70 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -605,7 +605,7 @@
Кольорувати повідомлення основним кольором мініатюри. Підтримується не всіма пристроями
Кольорове сповіщення
У компактному сповіщенні є не більше трьох дій!
- Дії можна змінити, натиснувши на них. Позначте не більше трьох для показу в компактному сповіщенні
+ Відредагуйте кожну дію сповіщення, натиснувши на неї. Виберіть до трьох з них, які будуть показані в компактному сповіщенні, за допомогою прапорців праворуч.
Обрізати мініатюру відео показувану в сповіщенні з пропорцій 16: 9 до 1:1
Вимкнення тунелювання медіаданих за наявності чорного екрана або гальмування під час відтворення відео.
Вимкнути тунелювання медіа
@@ -657,7 +657,7 @@
- Видалено %1$s завантажень
- - Завантаження завершено
+ - %s завантаження завершено
- %s завантаження завершено
- %s завантажень завершено
- %s завантажень завершено
@@ -823,4 +823,13 @@
Поділитися добіркою
Поділитися добіркою з подробицями, такими як назва добірки та назви відео, або просто списком URL-адрес відео
- %1$s: %2$s
+ Показати більше
+ Відредагуйте кожну дію сповіщення, натиснувши на неї. Перші три дії (відтворення/пауза, попередній і наступний) встановлюються системою і не можуть бути змінені.
+
+ - %s відповідь
+ - %s відповіді
+ - %s відповідей
+ - %s відповідей
+
+ Показати менше
\ No newline at end of file
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index f6719c1ed4c..bac36139592 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -533,7 +533,7 @@
Ngẫu nhiên
Lặp lại
Bạn có thể chọn tối đa ba hành động để hiện trong thông báo thu gọn!
- Chỉnh sửa mỗi hành động trong thông báo ở dưới bằng cách nhấn vào nó. Chọn tối đa ba hành động để hiện trong thông báo thu gọn bằng cách sử dụng các ô đánh dấu bên phải
+ Chỉnh sửa từng hành động thông báo bên dưới bằng cách nhấn vào nó. Chọn tối đa ba trong số chúng để hiển thị trong thông báo thu gọn bằng cách sử dụng các hộp kiểm ở bên phải.
Nút hành động thứ năm
Nút hành động thứ tư
Nút hành động thứ ba
@@ -551,7 +551,7 @@
Xoá Cookie mà NewPipe lưu trữ sau khi bạn hoàn thành nó
Cookie reCAPTCHA đã được xóa
Dọn dẹp Cookie của reCAPCHA
- YouTube cung cấp \"Chế độ hạn chế\" để ẩn nội dung không phụ hợp
+ YouTube cung cấp \"Chế độ hạn chế\" để ẩn nội dung có khả năng dành cho người trưởng thành
Yêu cầu Android tùy chỉnh màu của thông báo theo màu chính của ảnh thu nhỏ (lưu ý rằng việc này không khả dụng trên tất cả thiết bị)
Tô màu thông báo
Thiết bị của bạn không có ứng dụng để mở tệp này
@@ -793,4 +793,10 @@
Chọn chất lượng hình ảnh và chọn có tải chất lượng ảnh hay không, để giảm mức sử dụng dữ liệu và bộ nhớ. Thay đổi xoá cache ảnh cho cả trong bộ nhớ lẫn ổ cứng - %s
Track
Trực tiếp
+ Chỉnh sửa từng hành động thông báo bên dưới bằng cách nhấn vào nó. Ba hành động đầu tiên (phát/tạm dừng, trước đó và tiếp theo) do hệ thống thiết lập và không thể tùy chỉnh.
+ Hiện ít hơn
+ Hiện nhiều hơn
+
+ - %s hồi đáp
+
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 47752a150c7..f1d3fbf618a 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -534,7 +534,7 @@
随机播放
单曲循环
最多可以选择三个操作显示在紧凑通知中!
- 点击编辑下面的每一个通知操作。使用右方的复选框选择在紧凑通知中显示的动作,最多可以选择三个
+ 轻按下面的每一个通知操作进行编辑。使用右方的复选框选择在紧凑通知中显示的操作,最多可以选择三个。
第五操作按钮
第四操作按钮
第三操作按钮
@@ -793,4 +793,10 @@
分享播放列表
分享详细的播放列表(带名称和视频标题等信息)或只分享视频网址列表
- %1$s: %2$s
+
+ - %s 条回复
+
+ 显示较多
+ 显示较少
+ 轻按下方的每个通知操作进行编辑。头三个动作(播放/暂停、上一个和下一个)是系统设置的,不能自定义。
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 3afaf86de19..e9eb5bf12ba 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -44,7 +44,7 @@
撳放大鏡開始。
內容
顯示年齡設限嘅內容
- 實況
+ 直播
問題
載入唔晒全部縮圖
解析唔到網站
@@ -155,7 +155,7 @@
開啟方式係
搜尋到嘅嘢係:%s
第五粒動作掣
- 撳下面嘅掣去更改對應嘅通知動作。用右手邊嘅格仔剔選最多三個,擺喺精簡通知度
+ 撳下面嘅掣去更改對應嘅通知動作。用右手邊嘅格仔剔選最多三個,擺落去精簡通知度。
精簡通知最多淨係擺到三個動作!
循環播放
顯示留言
@@ -516,7 +516,7 @@
主機
喺影片詳情撳一下「幕後播」或「浮面播」個掣嘅時候顯示提示
紀錄
- 歷史紀錄
+ 紀錄
攝咗做下個播
記憶體洩露監測喺傾卸堆疊嘢嘅時候,或者會導致個 app 冇反應
閂埋選單
@@ -721,7 +721,7 @@
揀選右手邊播放器螢幕嘅手勢
右手邊手勢動作
調整光暗度
- 調整大細聲
+ 音量
乜都唔使做
優先揀原聲
優先揀旁述
@@ -793,4 +793,10 @@
頻道
上一個串流
直播
+
+ - %s 個回覆
+
+ 摺埋
+ 拉開
+ 撳下面嘅掣去更改對應嘅通知動作。頭三個動作 (播放/暫停、上一個、下一個) 系統預設咗,冇得揀。
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 8e613161a90..382a9547996 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -534,7 +534,7 @@
隨機播放
循環播放
您可以選取最多三個動作來顯示在簡潔通知中!
- 透過輕觸下方的通知來編輯它。使用右側的勾選框,最多可以選取三個在簡潔通知中顯示
+ 透過輕觸下方的通知來編輯它。使用右側的勾選框,最多可以選取三個在簡潔通知中顯示。
第五動作按鈕
第四動作按鈕
第三動作按鈕
@@ -793,4 +793,10 @@
分享播放清單
分享包含播放清單名稱與影片標題等詳細資訊的播放清單,或是僅作為簡單的影片 URL 清單
- %1$s:%2$s
+
+ - %s 個回覆
+
+ 顯示更多
+ 顯示較少
+ 透過點擊下面的每個通知操作來編輯它。前三個動作(播放/暫停、上一個與下一個)由系統設定,無法自訂。
\ No newline at end of file
diff --git a/fastlane/metadata/android/ar/changelogs/996.txt b/fastlane/metadata/android/ar/changelogs/996.txt
new file mode 100644
index 00000000000..1dd4e3de593
--- /dev/null
+++ b/fastlane/metadata/android/ar/changelogs/996.txt
@@ -0,0 +1,2 @@
+تم إصلاح NullPointerException عند فتح قناة / مؤتمر في media.ccc.de.
+حاول احدهم كسر الهدية التي قدمناها لك، لكننا تخطينا الأمر.
diff --git a/fastlane/metadata/android/bg/changelogs/64.txt b/fastlane/metadata/android/bg/changelogs/64.txt
new file mode 100644
index 00000000000..f5ece1568e0
--- /dev/null
+++ b/fastlane/metadata/android/bg/changelogs/64.txt
@@ -0,0 +1,6 @@
+### Подобрения
+-Добавена е възможността да се ограничи качеството на видеото ако се използва мобилен интернет. #1339
+- Запаметява яркостта за сесията #1442
+- Оптимизиране при изтегляне с по-слаби процесори #1431
+### Поправени
+- Поправен срив при отваряне на изтегления #1441
diff --git a/fastlane/metadata/android/bn/changelogs/64.txt b/fastlane/metadata/android/bn/changelogs/64.txt
index d5e5901e56f..e76c3130e3c 100644
--- a/fastlane/metadata/android/bn/changelogs/64.txt
+++ b/fastlane/metadata/android/bn/changelogs/64.txt
@@ -1,5 +1,5 @@
### অগ্রগতিসমূহ
-- মোবাইল ডাটা ব্যবহার করার সময় ভিডিও মানের সীমা নির্ধারণ করা যাবে। #1339।
+- মোবাইল ডাটা ব্যবহার করার সময় ভিডিও মানের সীমা নির্ধারণ করা যাবে। #1339।
- প্লেয়ারের উজ্জ্বলতা মনে রাখুন #1442।
- দুর্বল সিপিইউর ডিভাইসে পারফরম্যান্স উন্নত করা হয়েছে #1431।
- মিডিয়া সেশন এখন সঠিকভাবে কাজ করে #1433।
diff --git a/fastlane/metadata/android/cs/changelogs/996.txt b/fastlane/metadata/android/cs/changelogs/996.txt
new file mode 100644
index 00000000000..a220330bce7
--- /dev/null
+++ b/fastlane/metadata/android/cs/changelogs/996.txt
@@ -0,0 +1,2 @@
+Opravena chyba NullPointerException při otevírání kanálu / konference na media.ccc.de.
+Ježíšek nám málem doručil rozbitý dárek pro vás, ale opravili jsme to.
diff --git a/fastlane/metadata/android/de/changelogs/65.txt b/fastlane/metadata/android/de/changelogs/65.txt
index 3405af36342..6815d432a3e 100644
--- a/fastlane/metadata/android/de/changelogs/65.txt
+++ b/fastlane/metadata/android/de/changelogs/65.txt
@@ -1,4 +1,5 @@
Verbesserungen
+
-Menüanimation deaktiviert #1486
-Löschen von Downloads rückgängig machen #1472
-Option zum Downloaden im Teilen-Menü #1498
@@ -6,5 +7,4 @@ Verbesserungen
-Minimieren der Wiedergabe beim Beenden #1354
-Datenbank Versions Aktualisierung und Datenbestand Wiederherstellung #1510
-ExoPlayer 2.8.2 aktualisiert #1392
--Überarbeitung der Wiedergabegeschwindigkeitskontrolle um Änderungen besser zu unterstützen
--hinzufügen der Möglichkeit Stille zu überspringen(Hilfreich bei Audiobücher und einigen Musikarten) unterstützt dadurch eine nahtlose Wiedergabe (Nicht so toll bei Liedern, in denen es auch stille Passagen gibt.)
+-Überarbeitung der Wiedergabegeschwindigkeitskontrolle um Änderungen besser zu unterstützen.
diff --git a/fastlane/metadata/android/de/changelogs/66.txt b/fastlane/metadata/android/de/changelogs/66.txt
new file mode 100644
index 00000000000..937bfd642cb
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/66.txt
@@ -0,0 +1,18 @@
+# Versionsänderung von v0.13.7
+
+### Behebungen
+- Probleme der Filterung von v.0.13.6 behoben
+
+# Versionsänderung von v0.13.6
+
+### Verbesserungen
+
+- Animation der Burgermenü-Icon entfernt #1486
+- Löschen von Downloads rückgängig machen #1472
+- Im "Teilen"-Tab die Download option hinzugefügt #1498
+- Option "Teilen" zum Long-Tap-Menü hinzugefügt #1454
+
+### Behebungen
+
+- Probleme mit dem kaputten Video Info layout behoben. #1440 / #1491
+- Probleme mit dem Verlauf wurden behoben. #1497.
diff --git a/fastlane/metadata/android/de/changelogs/68.txt b/fastlane/metadata/android/de/changelogs/68.txt
new file mode 100644
index 00000000000..6cdbd55a00e
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/68.txt
@@ -0,0 +1,19 @@
+# Änderungen von v0.14.1
+
+### Fixed
+- nicht entschlüsselt Video url #1659
+- Beschreibungs Link nicht extrahierbar #1657
+
+# Änderungen von v0.14.0
+
+### New
+- Neues Schubladendesign #1461
+- Neue anpassbare Titelseite #1461
+
+### Verbesserungen
+- Reworked Gesture Controls #1604
+- Neue Möglichkeit, den Popup-Player #1597 zu schließen
+
+### Fixed
+- Fehler beheben, wenn die Anzahl der Abonnements nicht verfügbar ist. Schließt #1649.
+- Zeigen Sie "Abonnentenzählung nicht verfügbar" in diesen Fällen.
diff --git a/fastlane/metadata/android/de/changelogs/69.txt b/fastlane/metadata/android/de/changelogs/69.txt
new file mode 100644
index 00000000000..8802508a323
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/69.txt
@@ -0,0 +1,14 @@
+### New
+- Long-tap Löschen & Teilen in Abonnements #1516
+- Tablet UI & Rasterlistenlayout #1617
+
+### Verbesserungen
+- Speichern und Nachladen des zuletzt verwendeten Seitenverhältnisses #1748
+- Separate Einstellungen für Lautstärke & Helligkeitsgesten #1644
+
+### Fixes
+- Anzahl der Abonnements
+- Foreground Service Erlaubnis für API 28+ Geräte #1830 hinzugefügt
+
+### Known Bugs
+- Wiedergabe kann nicht auf Android P gespeichert werden
diff --git a/fastlane/metadata/android/de/changelogs/70.txt b/fastlane/metadata/android/de/changelogs/70.txt
new file mode 100644
index 00000000000..59a09b21096
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/70.txt
@@ -0,0 +1,10 @@
+ACHTUNG: Diese Version ist wahrscheinlich ein Bugfest.
+
+### Verbesserungen
+* heruntergeladene Dateien können mit einem Klick #1879 geöffnet werden
+* Drop-Unterstützung für Android 4.1 - 4.3 #1884
+* Streams aus der aktuellen Warteschlange entfernt, indem sie nach rechts swipen #1915
+
+### Fixed
+* Crash mit Standard-Auflösung eingestellt auf beste und begrenzte mobile Datenauflösung #1835
+* Pop-up-Spieler-Absturz behoben #1874
diff --git a/fastlane/metadata/android/de/changelogs/71.txt b/fastlane/metadata/android/de/changelogs/71.txt
new file mode 100644
index 00000000000..0132de3c32b
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/71.txt
@@ -0,0 +1,8 @@
+### Verbesserungen
+* App-Update-Benachrichtigung für GitHub build hinzufügen (#1608 von @krtkush)
+* Verschiedene Verbesserungen des Downloaders (#1944 von @kapodamy):
+* Fügen Sie fehlende weiße Icons hinzu und verwenden Sie hardcored Weg, um die Icon Farben zu ändern
+* neue MPEG-4 muxer fixieren nicht-synchrone Video- und Audiostreams (#2039)
+
+### Fixed
+* YouTube Live-Streams spielen nach kurzer Zeit (#1996 von @yausername)
diff --git a/fastlane/metadata/android/de/changelogs/740.txt b/fastlane/metadata/android/de/changelogs/740.txt
new file mode 100644
index 00000000000..0d28a157ab3
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/740.txt
@@ -0,0 +1,12 @@
+Verbesserungen
+
+Make Links in Kommentare klickbar, erhöhen Textgröße
+seek zum Klicken von Zeitstempel-Links in Kommentare
+Beliebte Registerkarte basierend auf kürzlich ausgewähltem Zustand anzeigen
+Add-Unterstützung für Invidious links
+
+Fixed
+
+fixed scroll w/kommentare und verwandten Streams deaktiviert
+fixiert CheckForNewAppVersionTask wird ausgeführt, wenn es sollten't
+
diff --git a/fastlane/metadata/android/de/changelogs/750.txt b/fastlane/metadata/android/de/changelogs/750.txt
new file mode 100644
index 00000000000..78a25282a00
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/750.txt
@@ -0,0 +1,15 @@
+Neu
+Playback Lebenslauf #2288
+• Resume Streams, wo Sie letztes Mal aufgehört haben
+Downloader Verbesserungen #2149
+
+
+Verbessert
+• Gemaketten entfernen #2295
+• Handle (auto)Rotationsänderungen während des Aktivitätszyklus #2444
+
+Behoben
+• Fixed Downloads bei 99,9% #2440
+• Aktualisieren der Spielwarteschlange Metadaten #2453
+• [SoundCloud] Fester Absturz beim Laden von Wiedergabelisten TeamNewPipe/NewPipeExtractor#170
+• [YouTube] Feste Dauer kann nicht paresd TeamNewPipe/NewPipeExtractor#177
diff --git a/fastlane/metadata/android/de/changelogs/760.txt b/fastlane/metadata/android/de/changelogs/760.txt
new file mode 100644
index 00000000000..f0eac002f6e
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/760.txt
@@ -0,0 +1,24 @@
+Veränderung in 0,17.1
+
+Neu
+• thailändische Lokalisierung
+
+
+Verbessert
+• Schalter für SAF / Legacy Datei Picker #2521 hinzufügen
+
+Behoben
+• Löschen Sie Löschtasten in Downloads Ansicht beim Umschalten von Apps #2487
+
+Veränderungen in 0,17,0
+
+Neu
+Playback Lebenslauf #2288
+• Resume Streams, wo Sie letztes Mal aufgehört haben
+Downloader Verbesserungen #2149
+
+Verbessert
+• Gemaketten entfernen #2295
+
+Behoben
+• Behoben ausgewählter Subtitle Track Name nicht angezeigt #2394
diff --git a/fastlane/metadata/android/de/changelogs/780.txt b/fastlane/metadata/android/de/changelogs/780.txt
new file mode 100644
index 00000000000..4deac3709a1
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/780.txt
@@ -0,0 +1,11 @@
+Veränderungen in 0,17,3
+
+Verbessert
+• Hinzugefügte Option, um die Wiedergabezustände #2550 zu löschen
+• Versteckte Verzeichnisse in der Datei Picker #2591 anzeigen
+• Unterstützung von URLs von `invidio.us` Instanzen, die mit NewPipe #2488 geöffnet werden sollen
+• Unterstützung für `music.youtube.com` URLs TeamNewPipe/NewPipeExtractor#194
+
+Behoben
+• [YouTube] Behoben 'java.lang.IllegalArgumentException #192
+• [YouTube] Feste Live-Streams nicht arbeiten TeamNewPipe/NewPipeExtractor#195
diff --git a/fastlane/metadata/android/de/changelogs/790.txt b/fastlane/metadata/android/de/changelogs/790.txt
new file mode 100644
index 00000000000..345cb37aa01
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/790.txt
@@ -0,0 +1,13 @@
+Verbessert
+• Weitere Titel hinzufügen, um die Zugänglichkeit für Blinde zu verbessern #2655
+• Sprache des Download-Ordners konsistenter und weniger eindeutig #2637
+
+Behoben
+• Fixed Scrolling in Video Detail Fragment #2672
+• Entfernen Sie doppelte Suche klare Box-Animationen zu einem #2695
+• [SoundCloud] Client_id Extraktion fix #2745
+
+Entwicklung
+• Hinzufügen fehlender Abhängigkeiten von NewPipeExtractor in NewPipe #2535
+• Migration auf AndroidX #2685
+• Update auf ExoPlayer 2.10.6 #2697, #2736
diff --git a/fastlane/metadata/android/de/changelogs/800.txt b/fastlane/metadata/android/de/changelogs/800.txt
new file mode 100644
index 00000000000..792b15461fb
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/800.txt
@@ -0,0 +1,11 @@
+Neu
+• PeerTube Unterstützung ohne P2P (#2201) (Beta)
+ Es könnte Probleme mit SSL Handshakes auf Android 4.4 & 7.1 geben, wenn auf bestimmte Instanzen zugegriffen wird.
+
+Verbessert
+• Neue Localization and Downloader von Extractor #2713
+• Schwarze Navigationsleiste für schwarzes Theme #2569
+
+Behoben
+• Fehler wurde behoben, der den Popup-Player nicht verschieben konnte, wenn ein anderer Finger beim Verschieben des Popup-Players #2772 platziert wurde
+• [SoundCloud] Audio-Stream-Extraktion
diff --git a/fastlane/metadata/android/de/changelogs/810.txt b/fastlane/metadata/android/de/changelogs/810.txt
new file mode 100644
index 00000000000..9b57ce03ccb
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/810.txt
@@ -0,0 +1,11 @@
+Neu
+• Video Vorschau auf den Sperrbildschirm beim Spielen im Hintergrund anzeigen
+
+Verbessert
+• Fügen Sie lokale Wiedergabeliste hinzu, um zu löschen, wenn lange Drücken auf Hintergrund / Popup-Taste
+
+Behoben
+• Mehrere Probleme behoben, wenn ein Video zu NewPipe geteilt und seine Streams direkt herunterladen
+• [YouTube] Festes Einschalten Null verursacht NPE
+• [YouTube] Behobene Betrachtungskommentare beim Öffnen eines invidio.us url
+• [SoundCloud] Update von client_id
diff --git a/fastlane/metadata/android/de/changelogs/840.txt b/fastlane/metadata/android/de/changelogs/840.txt
new file mode 100644
index 00000000000..73e9904ec55
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/840.txt
@@ -0,0 +1,10 @@
+Neu
+• Sprachauswahl hinzugefügt, um die App-Sprache zu ändern
+• Hinzugefügt senden zu Kodi Taste zu Spieler zusammenklappbare Menü
+
+Verbessert
+• Entfernen von dot-menu für Schublade und verstecken Geschichte Taste, wenn die Uhr Geschichte nicht in den Einstellungen aktiviert ist
+
+Behoben
+• Fix initialer Helligkeitswert für die Geste
+• [YouTube] Timestamps in der Beschreibung sind wieder anklickbar
diff --git a/fastlane/metadata/android/de/changelogs/930.txt b/fastlane/metadata/android/de/changelogs/930.txt
new file mode 100644
index 00000000000..e2ddba83f1a
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/930.txt
@@ -0,0 +1,12 @@
+Neu
+• Suche auf YouTube Musik
+• Basic Android TV-Unterstützung
+
+Verbessert
+• Hinzugefügt die Fähigkeit, alle beobachteten Videos von einer lokalen Wiedergabeliste zu entfernen
+• Nachricht anzeigen, wenn der Inhalt noch nicht unterstützt wird, anstatt zu stürzen
+
+Behoben
+• Feste altersbeschränkte Inhaltseinstellung nicht funktionieren
+• Behoben bestimmte Arten von reCAPTCHAs
+• Feste Sichtbarkeit der Gruppen-Sort-Taste im Abonnement-Bereich
diff --git a/fastlane/metadata/android/de/changelogs/940.txt b/fastlane/metadata/android/de/changelogs/940.txt
index 3cbf73516fb..e96340b16a3 100644
--- a/fastlane/metadata/android/de/changelogs/940.txt
+++ b/fastlane/metadata/android/de/changelogs/940.txt
@@ -10,4 +10,3 @@ Verbessert
Behoben
- Einfrieren des Download-Dialogs behoben
-...
diff --git a/fastlane/metadata/android/de/changelogs/951.txt b/fastlane/metadata/android/de/changelogs/951.txt
index 7c6d939820b..790d6329db0 100644
--- a/fastlane/metadata/android/de/changelogs/951.txt
+++ b/fastlane/metadata/android/de/changelogs/951.txt
@@ -8,4 +8,3 @@ Neu
Verbessert
- Anwendungsmetadaten nicht mehr in gemuxte Dateien schreiben
- Fehlerhafte Streams nicht aus der Warteschlange entfernen
-...
diff --git a/fastlane/metadata/android/de/changelogs/990.txt b/fastlane/metadata/android/de/changelogs/990.txt
index a629c8654a2..6e56a8e70d3 100644
--- a/fastlane/metadata/android/de/changelogs/990.txt
+++ b/fastlane/metadata/android/de/changelogs/990.txt
@@ -8,8 +8,6 @@ Neu:
Verbessert:
• Player-Code in kleine Komponenten refaktorisiert: weniger RAM-Verbrauch, weniger Bugs
• Skalierungsmodus für Miniaturansicht
-…
Behoben:
• Verschiedene Probleme mit Player-Benachrichtigung: veraltete/fehlende Medieninfos, verzerrte Miniaturansicht
-…
diff --git a/fastlane/metadata/android/de/changelogs/995.txt b/fastlane/metadata/android/de/changelogs/995.txt
index 9c9ed11473d..0c026e50f57 100644
--- a/fastlane/metadata/android/de/changelogs/995.txt
+++ b/fastlane/metadata/android/de/changelogs/995.txt
@@ -11,6 +11,4 @@ Verbessert
Behoben
• [YouTube] Erhalten der Like-Anzahl
• Nicht reagierende Popups und Abstürze des Players
-• Auswahl der falschen Sprachen in der Sprachauswahl
-• Audio-Fokus des Players respektiert keine Stummschaltung
-…
+• Hinzufügen von Wiedergabelistenelementen funktionierte gelegentlich nicht
diff --git a/fastlane/metadata/android/de/changelogs/996.txt b/fastlane/metadata/android/de/changelogs/996.txt
new file mode 100644
index 00000000000..bcdea8f4f73
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/996.txt
@@ -0,0 +1,2 @@
+Eine NullPointerException beim Öffnen eines Kanals / einer Konferenz in media.ccc.de behoben.
+Der Grinch hat versucht, unser Weihnachtsgeschenk für Sie zu zerstören, aber wir haben es behoben.
diff --git a/fastlane/metadata/android/de/full_description.txt b/fastlane/metadata/android/de/full_description.txt
index a476e427e17..ef2ac9577a3 100644
--- a/fastlane/metadata/android/de/full_description.txt
+++ b/fastlane/metadata/android/de/full_description.txt
@@ -1 +1 @@
-NewPipe verwendet keine Bibliotheken des Google-Frameworks oder der YouTube-API. Es analysiert die Website, um die benötigten Informationen zu erlangen. Aus diesem Grund kann die App ohne die Google Services verwendet werden. Ebenso wird kein YouTube-Konto für NewPipe benötigt und es ist FLOSS (Freie Software / Open-Source-Software).
+NewPipe verwendet keine Bibliotheken des Google-Frameworks oder der YouTube-API. Es analysiert die Website, um die benötigten Informationen zu erlangen. Aus diesem Grund kann die App ohne die Google Services verwendet werden. Ebenso wird kein YouTube-Konto für NewPipe benötigt und es ist FOSS (Freie Software / Open-Source-Software).
diff --git a/fastlane/metadata/android/de/short_description.txt b/fastlane/metadata/android/de/short_description.txt
index 138e55523ae..ec47872eb07 100644
--- a/fastlane/metadata/android/de/short_description.txt
+++ b/fastlane/metadata/android/de/short_description.txt
@@ -1 +1 @@
-Eine freie, leichtgewichtige YouTube-App für Android.
+Eine freie, leichte YouTube-App für Android.
diff --git a/fastlane/metadata/android/el/changelogs/65.txt b/fastlane/metadata/android/el/changelogs/65.txt
new file mode 100644
index 00000000000..0417512c781
--- /dev/null
+++ b/fastlane/metadata/android/el/changelogs/65.txt
@@ -0,0 +1,26 @@
+### Βελτιώσεις
+
+- Απενεργοποίηση της κίνησης του εικονιδίου του burgermenu #1486
+- Αναίρεση διαγραφής λήψεων #1472
+- Επιλογή λήψης στο μενού κοινής χρήσης #1498
+- Προστέθηκε επιλογή κοινής χρήσης στο μενού παρατεταμένου πατήματος #1454
+- Ελαχιστοποίηση του κύριου προγράμματος αναπαραγωγής κατά την έξοδο #1354
+- Ενημέρωση της έκδοσης της βιβλιοθήκης και διόρθωση αντιγράφων ασφαλείας της βάσης δεδομένων #1510
+- Ενημέρωση ExoPlayer 2.8.2 #1392
+ - Ανασχεδιάστηκε ο διάλογος ελέγχου της ταχύτητας αναπαραγωγής ώστε να υποστηρίζει διαφορετικά μεγέθη βημάτων για ταχύτερη αλλαγή ταχύτητας.
+ - Προστέθηκε μια εναλλαγή για γρήγορη μετακίνηση προς τα εμπρός κατά τη διάρκεια σιωπής στον έλεγχο ταχύτητας αναπαραγωγής. Αυτό θα πρέπει να είναι χρήσιμο για τα ακουστικά βιβλία και ορισμένα είδη μουσικής και μπορεί να φέρει μια πραγματικά απρόσκοπτη εμπειρία (και μπορεί να σπάσει ένα τραγούδι με πολλές σιωπές =\\).
+ - Αναδιαμόρφωση της ανάλυσης πηγής πολυμέσων ώστε να επιτρέπεται η μετάδοση μεταδεδομένων μαζί με τα πολυμέσα εσωτερικά στον αναπαραγωγέα, αντί να γίνεται χειροκίνητα. Τώρα έχουμε μια ενιαία πηγή μεταδεδομένων και είναι άμεσα διαθέσιμα κατά την έναρξη της αναπαραγωγής.
+ - Διορθώθηκε η μη ενημέρωση των απομακρυσμένων μεταδεδομένων της λίστας αναπαραγωγής όταν είναι διαθέσιμα νέα μεταδεδομένα κατά το άνοιγμα του τμήματος της λίστας αναπαραγωγής.
+ - Διάφορες διορθώσεις στο UI: #1383, τα στοιχεία ελέγχου ειδοποίησης αναπαραγωγής στο παρασκήνιο είναι τώρα πάντα λευκά, είναι ευκολότερο να κλείσετε το αναδυόμενο πρόγραμμα αναπαραγωγής μέσω εκτίναξης
+- Χρήση νέου εξαηωγέα με ανασχεδιασμένη αρχιτεκτονική για πολλαπλές υπηρεσίες
+
+### Διορθώσεις
+
+- Διόρθωση #1440 Προβληματική διάταξη πληροφοριών βίντεο #1491
+- Διόρθωση ιστορικού προβολής #1497
+ - #1495, ενημέρωση των μεταδεδομένων (μικρογραφία, τίτλος και αριθμός βίντεο) μόλις ο χρήστης αποκτήσει πρόσβαση στη λίστα αναπαραγωγής.
+ - #1475, με την καταχώριση μιας προβολής στη βάση δεδομένων όταν ο χρήστης ξεκινάει ένα βίντεο σε εξωτερική συσκευή αναπαραγωγής σε λεπτομερές θραύσμα.
+- Διόρθωση του χρονικού ορίου creen σε περίπτωση λειτουργίας αναδυόμενου παραθύρου. #1463 (Διορθώθηκε το #640)
+- Διόρθωση του κύριου προγράμματος αναπαραγωγής βίντεο #1509
+ - #1412] Διορθώθηκε η λειτουργία επανάληψης που προκαλεί NPE του αναπαραγωγέα όταν λαμβάνεται νέα εντολή ενώ εργάζεται στο παρασκήνιο.
+ - Διορθώθηκε κατά την ελαχιστοποίηση του αναπαραγωγέα σε αναδυόμενο παράθυρο, να μην τον καταστρέφει όταν δεν έχει χορηγηθεί άδεια αναδυόμενου παραθύρου.
diff --git a/fastlane/metadata/android/el/changelogs/963.txt b/fastlane/metadata/android/el/changelogs/963.txt
new file mode 100644
index 00000000000..b6c30aa9d84
--- /dev/null
+++ b/fastlane/metadata/android/el/changelogs/963.txt
@@ -0,0 +1 @@
+• [YouTube] Διόρθωση της συνέχισης ενός καναλιού
diff --git a/fastlane/metadata/android/el/changelogs/996.txt b/fastlane/metadata/android/el/changelogs/996.txt
new file mode 100644
index 00000000000..58223cb1ae6
--- /dev/null
+++ b/fastlane/metadata/android/el/changelogs/996.txt
@@ -0,0 +1,2 @@
+Διορθώθηκε μια NullPointerException κατά το άνοιγμα ενός καναλιού/συνεδρίου στο media.ccc.de.
+Ο Grinch προσπάθησε να σπάσει το χριστουγεννιάτικο δώρο μας προς εσάς, αλλά το διορθώσαμε.
diff --git a/fastlane/metadata/android/es/changelogs/996.txt b/fastlane/metadata/android/es/changelogs/996.txt
new file mode 100644
index 00000000000..e620b525f59
--- /dev/null
+++ b/fastlane/metadata/android/es/changelogs/996.txt
@@ -0,0 +1,2 @@
+Corregida una NullPointerException al abrir un canal / conferencia en media.ccc.de.
+El Grinch trató de romper nuestro regalo de Navidad para usted, pero lo arreglamos.
diff --git a/fastlane/metadata/android/fr/changelogs/750.txt b/fastlane/metadata/android/fr/changelogs/750.txt
index 1276a514d99..422529abf85 100644
--- a/fastlane/metadata/android/fr/changelogs/750.txt
+++ b/fastlane/metadata/android/fr/changelogs/750.txt
@@ -2,7 +2,7 @@ Nouveau
Reprise de lecture #2288
• Reprise des flux où ils s'étaient arrêtés
Améliorations du téléchargeur #2149
-• Utilisation du Storage Access Framework pour stocker sur cartes SD
+• Utilisation du Storage Access Framework pour stocker sur cartes SD
• Nouveau multiplexeur mp4
• Peut changer le dossier de téléchargement
• Respect des réseaux tarifés
@@ -10,12 +10,12 @@ Améliorations du téléchargeur #2149
Améliorations
• Suppression des chaînes gema #2295
-• Gestion des changements de rotation #2444
+• Gestion des changements de rotation #2444
• Uniformisation des menus longue-pression #2368
Corrections
• Nom de la piste de sous-titres sélectionnée qui ne s'affiche pas #2394
-• Ne plante pas quand la vérification de la mise à jour de l'application échoue #2423
+• Ne plante pas quand la vérification de la mise à jour de l'application échoue #2423
• Téléchargements bloqués à 99,9 % #2440
• Mise à jour des métadonnées de la file de lecture #2453
• [SoundCloud] Ne plante pas lors du chargement des playlists TeamNewPipe/NewPipeExtractor#170
diff --git a/fastlane/metadata/android/hi/changelogs/996.txt b/fastlane/metadata/android/hi/changelogs/996.txt
new file mode 100644
index 00000000000..0a9369d878f
--- /dev/null
+++ b/fastlane/metadata/android/hi/changelogs/996.txt
@@ -0,0 +1,2 @@
+Media.ccc.de में चैनल/कॉन्फ़्रेंस खोलते समय NullPointerException को ठीक किया गया।
+ग्रिंच ने आपको हमारा क्रिसमस उपहार तोड़ने की कोशिश की, लेकिन हमने इसे ठीक कर दिया।
diff --git a/fastlane/metadata/android/hr/full_description.txt b/fastlane/metadata/android/hr/full_description.txt
index 14826925eba..1e3977d33f1 100644
--- a/fastlane/metadata/android/hr/full_description.txt
+++ b/fastlane/metadata/android/hr/full_description.txt
@@ -1 +1 @@
-NewPipe ne koristi nijednu Googleovu biblioteku niti YouTube API, već samo analizira web-stranicu kako bi pribavio potrebne podatke. Stoga se ovaj program može koristiti na uređajima bez da su Googleove usluge instalirane. Također, za korištenje programa NewPipe nije potreban YouTube račun. NewPipe je slobodan program otvorenog koda.
+NewPipe ne koristi nijednu Googleovu biblioteku niti YouTube API, već samo analizira web-stranicu kako bi pribavio potrebne podatke. Stoga se ova aplikacija može koristiti na uređajima bez instaliranih Google usluga. Također, NewPipe se može koristiti bez YouTube računa. NewPipe je slobodna aplikacija otvorenog koda.
diff --git a/fastlane/metadata/android/id/changelogs/66.txt b/fastlane/metadata/android/id/changelogs/66.txt
index 62c8fd3e765..adbbff49ca3 100644
--- a/fastlane/metadata/android/id/changelogs/66.txt
+++ b/fastlane/metadata/android/id/changelogs/66.txt
@@ -11,12 +11,12 @@
- batalkan penghapusan unduhan #1472
- Opsi unduh di menu berbagi #1498
- Menambahkan opsi berbagi ke menu ketuk panjang #1454
-- Minimalkan pemain utama di pintu keluar #1354
-- Pembaruan versi perpustakaan dan perbaikan cadangan basis data #1510
+- Minimalkan pemutar utama saat keluar #1354
+- Pembaruan versi library dan perbaikan cadangan basis data #1510
- Pembaruan ExoPlayer 2.8.2 #1392
- Mengolah ulang dialog kontrol kecepatan pemutaran untuk mendukung ukuran langkah yang berbeda untuk perubahan kecepatan yang lebih cepat.
- Menambahkan tombol untuk maju cepat selama hening di kontrol kecepatan pemutaran. Ini akan berguna untuk buku audio dan genre musik tertentu, dan dapat menghadirkan pengalaman yang benar-benar mulus (dan dapat memecah lagu dengan banyak keheningan =\\).
- - Resolusi sumber media yang difaktorkan ulang untuk memungkinkan penyampaian metadata bersama media secara internal di pemutar, daripada melakukannya secara manual. Sekarang kami memiliki satu sumber metadata dan langsung tersedia saat pemutaran dimulai.
+ - Refaktor ulang resolusi sumber media untuk memungkinkan penyampaian metadata bersama media secara internal di pemutar, daripada melakukannya secara manual. Sekarang kami memiliki satu sumber metadata dan langsung tersedia saat pemutaran dimulai.
- Memperbaiki metadata daftar putar jarak jauh yang tidak diperbarui ketika metadata baru tersedia ketika fragmen daftar putar dibuka.
- Berbagai perbaikan UI: #1383, kontrol notifikasi pemutar latar belakang kini selalu berwarna putih, lebih mudah untuk mematikan pemutar popup melalui lemparan
- Gunakan ekstraktor baru dengan arsitektur yang difaktorkan ulang untuk multilayanan
@@ -25,9 +25,9 @@
- Perbaiki #1440 Tata Letak Info Video Rusak #1491
- Lihat perbaikan riwayat #1497
- - #1495, dengan memperbarui metadata (thumbnail, judul, dan jumlah video) segera setelah pengguna mengakses playlist.
+ - #1495, dengan memperbarui metadata (thumbnail, judul, dan jumlah video) segera setelah pengguna mengakses daftar putar.
- #1475, dengan mendaftarkan tampilan di database saat pengguna memulai video di pemutar eksternal pada fragmen detail.
- Perbaiki batas waktu layar jika ada mode popup. #1463 (Diperbaiki #640)
- Perbaikan pemutar video utama #1509
- - [#1412] Memperbaiki mode pengulangan yang menyebabkan NPE pemain ketika niat baru diterima saat aktivitas pemain berada di latar belakang.
- - Memperbaiki meminimalkan pemain ke popup tidak menghancurkan pemain ketika izin popup tidak diberikan.
+ - [#1412] Memperbaiki mode pengulangan yang menyebabkan pemutar NPE ketika intent baru diterima saat aktivitas pemutar berada di latar belakang.
+ - Perbaiki meminimalkan pemutar ke popup tidak menghancurkan pemutar ketika izin popup tidak diberikan.
diff --git a/fastlane/metadata/android/id/changelogs/972.txt b/fastlane/metadata/android/id/changelogs/972.txt
index e6b705eeb74..99990cc9030 100644
--- a/fastlane/metadata/android/id/changelogs/972.txt
+++ b/fastlane/metadata/android/id/changelogs/972.txt
@@ -11,4 +11,4 @@ Memperbarui instance Invidious dan mendukung tautan Piped.
Diperbaiki
[YouTube] Konten yang dibatasi usia
-Cegah jendela bocor Pengecualian saat membuka dialog pilihan
+Cegah Pengecualian jendela bocor saat membuka dialog pilihan
diff --git a/fastlane/metadata/android/id/changelogs/975.txt b/fastlane/metadata/android/id/changelogs/975.txt
index 65e6bcebdb3..b8f4aca1fc0 100644
--- a/fastlane/metadata/android/id/changelogs/975.txt
+++ b/fastlane/metadata/android/id/changelogs/975.txt
@@ -1,17 +1,17 @@
Baru
-• Tampilkan pratinjau thumbnail saat mencari
-• Mendeteksi komentar yang dinonaktifkan
-• Izinkan menandai item feed sebagai ditonton
-• Tampilkan komentar hati
+• Menampilkan Thumbnail ketika Mempercepat
+• Deteksi komentar yang dimatikan
+• Penandaan item feed sebagai ditonton
+• Menampilkan Komentar disukai
-Ditingkatkan
-• Memperbaiki metadata dan tata letak tag
-• Menerapkan warna layanan ke komponen UI
+Peningkatan
+• Pembaruan Layout metadata dan tag
+• Penerapan warna layanan pada komponen UI
-Tetap
-• Perbaiki thumbnail di mini player
-• Memperbaiki buffering tanpa akhir pada item antrian duplikat
-• Beberapa perbaikan pemain seperti rotasi dan penutupan lebih cepat
-• Perbaiki ReCAPTCHA yang tersisa dimuat di latar belakang
-• Nonaktifkan klik saat menyegarkan feed
-• Memperbaiki beberapa pengunduh yang mogok
+Perbaikan
+• Perbaiki thumbnail pada mini player
+• Perbaiki buffering tanpa akhir pada item antrian duplikat
+• Perbaikan Beberapa player rotasi layar dan penutupan yang lebih cepat
+• Perbaiki ReCaptcha tetap termuat di latar belakang
+• Matikan klik saat memuat feed
+• Perbaiki beberapa kerusakan pengunduh
diff --git a/fastlane/metadata/android/id/changelogs/976.txt b/fastlane/metadata/android/id/changelogs/976.txt
index d76b10e917e..d3c7e505b69 100644
--- a/fastlane/metadata/android/id/changelogs/976.txt
+++ b/fastlane/metadata/android/id/changelogs/976.txt
@@ -1,9 +1,9 @@
-• Ditambahkan opsi untuk langsung membuka pemutar dalam layar penuh
+• Tambahkan opsi untuk langsung membuka pemutar dalam layar penuh
• Izinkan memilih jenis saran pencarian yang akan ditampilkan
• Tema gelap kini lebih gelap + layar splash gelap ditambahkan
-• Peningkatan pemilih file untuk menghilangkan file yang tidak diinginkan
+• Peningkatan pemilih file untuk menyembunyikan file yang tidak diinginkan
• Memperbaiki impor langganan YouTube
-• Memutar ulang streaming memerlukan ketukan pada tombol putar ulang lagi
+• Memutar ulang stream memerlukan ketukan pada tombol putar ulang lagi
• Memperbaiki sesi audio penutup
• [Android TV] Memperbaiki lompatan seekbar yang panjang saat menggunakan DPad
diff --git a/fastlane/metadata/android/id/changelogs/995.txt b/fastlane/metadata/android/id/changelogs/995.txt
index 277b2468a72..b3db15bf162 100644
--- a/fastlane/metadata/android/id/changelogs/995.txt
+++ b/fastlane/metadata/android/id/changelogs/995.txt
@@ -4,13 +4,13 @@ Baru
• Dapatkan URL ke semua gambar
Ditingkatkan
-• Aksesibilitas antarmuka pemain
-• Pilihan audio yang lebih baik untuk download video saja
-• Pilihan untuk memasukkan nama playlist dan video ke konten playlist bersama
+• Aksesibilitas antarmuka pemutar
+• Pilihan audio yang lebih baik untuk unduhan video saja
+• Pilihan untuk memasukkan nama playlist dan video ke konten daftar putar bersama
-Tetap
+Diperbaiki
• [YouTube] Perbaiki penghitungan jumlah suka
-• Memperbaiki pemain yang tidak merespons popup dan crash
+• Perbaiki pemutar yang tidak merespons popup dan crash
• Pemilihan bahasa yang salah di pemilih bahasa
• Fokus audio pemutar tidak menerapkan mode senyap
-• Penambahan item playlist terkadang tidak berfungsi
+• Penambahan item daftar putar terkadang tidak berfungsi
diff --git a/fastlane/metadata/android/id/changelogs/996.txt b/fastlane/metadata/android/id/changelogs/996.txt
new file mode 100644
index 00000000000..d1fd9d5b768
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/996.txt
@@ -0,0 +1,2 @@
+Perbaiki NullPointerException saat membuka saluran / konferensi di media.ccc.de.
+The Grinch mencoba untuk merusak hadiah Natal kami ke anda, tapi kami memperbaikinya.
diff --git a/fastlane/metadata/android/it/changelogs/996.txt b/fastlane/metadata/android/it/changelogs/996.txt
new file mode 100644
index 00000000000..0d69a32647b
--- /dev/null
+++ b/fastlane/metadata/android/it/changelogs/996.txt
@@ -0,0 +1,2 @@
+Corretto un NullPointerException quando si apre un canale / conferenza in media.ccc.de.
+Il Grinch ha cercato di rompere il nostro regalo di Natale per te, ma l'abbiamo risolto.
diff --git a/fastlane/metadata/android/ja/changelogs/954.txt b/fastlane/metadata/android/ja/changelogs/954.txt
index e927e8e5178..6b0da159847 100644
--- a/fastlane/metadata/android/ja/changelogs/954.txt
+++ b/fastlane/metadata/android/ja/changelogs/954.txt
@@ -1,6 +1,6 @@
・新しいアプリケーションの利用体系: 詳細ページで動画を再生し、下にスワイプしてプレイヤーを最小化する
・MediaStyle 通知: 通知のカスタマイズ可能なアクション、パフォーマンスの向上
-・デスクトップアプリのような NewPipe 使用中のリサイズ
+・デスクトップアプリのような NewPipe 使用中のリサイズ
・サポートしていない URL のとき他のアプリで開くオプションを表示する
・取得できなかった場合の検索サジェストのユーザー体験の向上
diff --git a/fastlane/metadata/android/ka/changelogs/64.txt b/fastlane/metadata/android/ka/changelogs/64.txt
index 5d32b7c0d0d..de50608ab7b 100644
--- a/fastlane/metadata/android/ka/changelogs/64.txt
+++ b/fastlane/metadata/android/ka/changelogs/64.txt
@@ -1,5 +1,5 @@
### გაუმჯობესებები
- - დაემატა ვიდეოს ხარისხის შეზღუდვის შესაძლებლობა მობილური ინტერნეტის გამოყენებისას. #1339
+ - დაემატა ვიდეოს ხარისხის შეზღუდვის შესაძლებლობა მობილური ინტერნეტის გამოყენებისას. #1339
- დაიმახსოვრე სიკაშკაშე #1442 სესიისთვის
- გააუმჯობესეთ ჩამოტვირთვის შესრულება სუსტი CPU-ებისთვის #1431
- დაამატეთ (სამუშაო) მხარდაჭერა მედია სესიისთვის #1433
diff --git a/fastlane/metadata/android/ka/changelogs/69.txt b/fastlane/metadata/android/ka/changelogs/69.txt
index b5d54c5655f..4bc9f3c0382 100644
--- a/fastlane/metadata/android/ka/changelogs/69.txt
+++ b/fastlane/metadata/android/ka/changelogs/69.txt
@@ -11,7 +11,7 @@
- დაამატეთ მხარდაჭერა ლოკალიზაციის #1792-ისთვის
### ასწორებს
- - დააფიქსირეთ დროის ანალიზი . ფორმატში, ამიტომ NewPipe შეიძლება გამოყენებულ იქნას ფინეთში
+ - დააფიქსირეთ დროის ანალიზი . ფორმატში, ამიტომ NewPipe შეიძლება გამოყენებულ იქნას ფინეთში
- შეასწორეთ გამოწერების რაოდენობა
- დაამატეთ წინა პლანზე სერვისის ნებართვა API 28+ მოწყობილობებისთვის #1830
diff --git a/fastlane/metadata/android/ka/changelogs/740.txt b/fastlane/metadata/android/ka/changelogs/740.txt
index 3589197f90a..b6f13456b04 100644
--- a/fastlane/metadata/android/ka/changelogs/740.txt
+++ b/fastlane/metadata/android/ka/changelogs/740.txt
@@ -3,11 +3,11 @@
გახადეთ კომენტარებში ბმულები დაწკაპუნებით, გაზარდეთ ტექსტის ზომა
მოძებნეთ კომენტარებში დროის ანაბეჭდის ბმულებზე დაწკაპუნებით
სასურველი ჩანართის ჩვენება ახლახან არჩეული მდგომარეობის მიხედვით
- დაამატე დასაკრავი სია რიგში, როდესაც დიდხანს დააწკაპუნებთ 'ფონზე' დასაკრავი სიის ფანჯარაში
+ დაამატე დასაკრავი სია რიგში, როდესაც დიდხანს დააწკაპუნებთ 'ფონზე' დასაკრავი სიის ფანჯარაში
მოძებნეთ გაზიარებული ტექსტი, როდესაც ის არ არის URL
- დაამატეთ "გაზიარება მიმდინარე დროს" ღილაკი მთავარ ვიდეო დამკვრელზე
+ დაამატეთ "გაზიარება მიმდინარე დროს" ღილაკი მთავარ ვიდეო დამკვრელზე
დახურვის ღილაკის დამატება მთავარ დამკვრელზე, როდესაც ვიდეო რიგი დასრულდება
- დაამატეთ "დაკვრა პირდაპირ ფონზე" ვიდეო სიის ელემენტების მენიუს ხანგრძლივი დაჭერისთვის
+ დაამატეთ "დაკვრა პირდაპირ ფონზე" ვიდეო სიის ელემენტების მენიუს ხანგრძლივი დაჭერისთვის
გააუმჯობესეთ ინგლისური თარგმანი Play/Enqueue ბრძანებებისთვის
შესრულების მცირე გაუმჯობესება
გამოუყენებელი ფაილების წაშლა
diff --git a/fastlane/metadata/android/ka/changelogs/850.txt b/fastlane/metadata/android/ka/changelogs/850.txt
index c78859a4ee3..7f6cc55e250 100644
--- a/fastlane/metadata/android/ka/changelogs/850.txt
+++ b/fastlane/metadata/android/ka/changelogs/850.txt
@@ -1 +1 @@
-ამ გამოშვებაში განახლდა YouTube ვებსაიტის ვერსია. ვებსაიტის ძველი ვერსია შეწყდება მარტში და, შესაბამისად, თქვენ უნდა განაახლოთ NewPipe.
+ამ გამოშვებაში განახლდა YouTube ვებსაიტის ვერსია. ვებსაიტის ძველი ვერსია შეწყდება მარტში და, შესაბამისად, თქვენ უნდა განაახლოთ NewPipe.
diff --git a/fastlane/metadata/android/ka/changelogs/967.txt b/fastlane/metadata/android/ka/changelogs/967.txt
index 5d1835b2e95..232586a7315 100644
--- a/fastlane/metadata/android/ka/changelogs/967.txt
+++ b/fastlane/metadata/android/ka/changelogs/967.txt
@@ -1 +1 @@
-გაასწორა YouTube, რომელიც ევროკავშირში არ მუშაობს გამართულად. ეს გამოწვეული იყო ახალი ქუქი-ჩანაწერით და კონფიდენციალურობის თანხმობის სისტემით, რომელიც მოითხოვს NewPipe-ს დააყენოს თანხმობის ქუქი-ფაილები.
+გაასწორა YouTube, რომელიც ევროკავშირში არ მუშაობს გამართულად. ეს გამოწვეული იყო ახალი ქუქი-ჩანაწერით და კონფიდენციალურობის თანხმობის სისტემით, რომელიც მოითხოვს NewPipe-ს დააყენოს თანხმობის ქუქი-ფაილები.
diff --git a/fastlane/metadata/android/ka/changelogs/978.txt b/fastlane/metadata/android/ka/changelogs/978.txt
index 600962d14f3..787d5d12e26 100644
--- a/fastlane/metadata/android/ka/changelogs/978.txt
+++ b/fastlane/metadata/android/ka/changelogs/978.txt
@@ -1 +1 @@
-დაფიქსირდა შემოწმების შესრულება NewPipe-ის ახალი ვერსიისთვის. ეს შემოწმება ხანდახან ძალიან ადრე სრულდებოდა და, შესაბამისად, იწვევს აპის ავარიას. ეს ახლა უნდა გამოსწორდეს.
+დაფიქსირდა შემოწმების შესრულება NewPipe-ის ახალი ვერსიისთვის. ეს შემოწმება ხანდახან ძალიან ადრე სრულდებოდა და, შესაბამისად, იწვევს აპის ავარიას. ეს ახლა უნდა გამოსწორდეს.
diff --git a/fastlane/metadata/android/ka/changelogs/988.txt b/fastlane/metadata/android/ka/changelogs/988.txt
index e42877c9c2d..3c74e29f5da 100644
--- a/fastlane/metadata/android/ka/changelogs/988.txt
+++ b/fastlane/metadata/android/ka/changelogs/988.txt
@@ -1,2 +1,2 @@
[YouTube] გაასწორდა შეცდომა „ვერ მივიღე ნაკადი“ რომელიმე ვიდეოს დაკვრის მცდელობისას
- [YouTube] შეასწორდა „შემდეგი კონტენტი მიუწვდომელია ამ აპში“. მოთხოვნილი ვიდეოს ნაცვლად ნაჩვენები შეტყობინება
+ [YouTube] შეასწორდა „შემდეგი კონტენტი მიუწვდომელია ამ აპში“. მოთხოვნილი ვიდეოს ნაცვლად ნაჩვენები შეტყობინება
diff --git a/fastlane/metadata/android/ka/full_description.txt b/fastlane/metadata/android/ka/full_description.txt
index eff57aabe3d..e65267b469c 100644
--- a/fastlane/metadata/android/ka/full_description.txt
+++ b/fastlane/metadata/android/ka/full_description.txt
@@ -1 +1 @@
-NewPipe არ იყენებს Google Framework ბიბლიოთეკას ან YouTube API-ს. ის მხოლოდ აანალიზებს ვებსაიტს, რათა მოიპოვოს მისთვის საჭირო ინფორმაცია. ამიტომ ამ აპლიკაციის გამოყენება შესაძლებელია მოწყობილობებზე Google სერვისების დაყენების გარეშე. გარდა ამისა, თქვენ არ გჭირდებათ YouTube ანგარიში NewPipe-ის გამოსაყენებლად და ეს არის FLOSS.
+NewPipe არ იყენებს Google Framework ბიბლიოთეკას ან YouTube API-ს. ის მხოლოდ აანალიზებს ვებსაიტს, რათა მოიპოვოს მისთვის საჭირო ინფორმაცია. ამიტომ ამ აპლიკაციის გამოყენება შესაძლებელია მოწყობილობებზე Google სერვისების დაყენების გარეშე. გარდა ამისა, თქვენ არ გჭირდებათ YouTube ანგარიში NewPipe-ის გამოსაყენებლად და ეს არის FLOSS.
diff --git a/fastlane/metadata/android/pa/changelogs/996.txt b/fastlane/metadata/android/pa/changelogs/996.txt
new file mode 100644
index 00000000000..ac5940bc333
--- /dev/null
+++ b/fastlane/metadata/android/pa/changelogs/996.txt
@@ -0,0 +1,2 @@
+media.ccc.de ਵਿੱਚ ਇੱਕ ਚੈਨਲ / ਕਾਨਫਰੰਸ ਖੋਲ੍ਹਣ ਵੇਲੇ ਇੱਕ NullPointerException ਫਿਕਸ ਕੀਤਾ ਗਿਆ।
+ਗ੍ਰਿੰਚ ਨੇ ਤੁਹਾਡੇ ਲਈ ਸਾਡੇ ਕ੍ਰਿਸਮਸ ਤੋਹਫ਼ੇ ਨੂੰ ਤੋੜਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ, ਪਰ ਅਸੀਂ ਇਸਨੂੰ ਠੀਕ ਕਰ ਦਿੱਤਾ।
diff --git a/fastlane/metadata/android/pt-PT/changelogs/995.txt b/fastlane/metadata/android/pt-PT/changelogs/995.txt
new file mode 100644
index 00000000000..b22d3122aac
--- /dev/null
+++ b/fastlane/metadata/android/pt-PT/changelogs/995.txt
@@ -0,0 +1,16 @@
+Novo
+- Separadores de canais de suporte
+- Selecionar a qualidade da imagem
+- Obter URLs para todas as imagens
+
+Melhorado
+- Acessibilidade das interfaces do leitor
+- Melhor seleção de áudio para transferências apenas de vídeo
+- Opção para incluir nomes de listas de reprodução e de vídeos no conteúdo de listas de reprodução partilhadas
+
+Corrigido
+- YouTube] Correção da contagem de gostos
+- Correção de popups e falhas do leitor que não responde
+- Seleção de idiomas errados no seletor de idiomas
+- A focagem do áudio do leitor não respeitava o silêncio
+- A adição de itens à lista de reprodução não funcionava ocasionalmente.
diff --git a/fastlane/metadata/android/pt/changelogs/995.txt b/fastlane/metadata/android/pt/changelogs/995.txt
index ebe4e742f18..db7a183475a 100644
--- a/fastlane/metadata/android/pt/changelogs/995.txt
+++ b/fastlane/metadata/android/pt/changelogs/995.txt
@@ -5,10 +5,12 @@ Novo
Melhorado
- Acessibilidade das interfaces do leitor
-- Opção para adicionar o nome da lista de reprodução e o nome do vídeo ao conteúdo de partilha da lista de reprodução
-- Melhorias internas e atualizações de dependências
+- Melhor seleção de áudio para transferências apenas de vídeo
+- Opção para incluir nomes de listas de reprodução e de vídeos no conteúdo de listas de reprodução partilhadas
Corrigido
+- YouTube] Correção da contagem de gostos
+- Correção de popups e falhas do leitor que não responde
- Seleção de idiomas errados no seletor de idiomas
-- O foco do áudio do leitor não estava a respeitar o silêncio
-- A adição de itens a listas de reprodução não funcionava em casos específicos
+- A focagem do áudio do leitor não estava a respeitar o silêncio
+- A adição de itens à lista de reprodução não funcionava ocasionalmente.
diff --git a/fastlane/metadata/android/pt/changelogs/996.txt b/fastlane/metadata/android/pt/changelogs/996.txt
new file mode 100644
index 00000000000..4f1c8f22993
--- /dev/null
+++ b/fastlane/metadata/android/pt/changelogs/996.txt
@@ -0,0 +1,2 @@
+Foi corrigida uma NullPointerException ao abrir um canal/conferência em media.ccc.de.
+O Grinch tentou estragar a nossa prenda de Natal, mas nós resolvemos o problema.
diff --git a/fastlane/metadata/android/ru/changelogs/995.txt b/fastlane/metadata/android/ru/changelogs/995.txt
index dcefd106a5c..11b54b66207 100644
--- a/fastlane/metadata/android/ru/changelogs/995.txt
+++ b/fastlane/metadata/android/ru/changelogs/995.txt
@@ -1,14 +1,16 @@
-Из нового
+Новое
• Поддержка вкладок каналов
• Выбор качества изображения
• Получение URL всех изображений
-Улучшения
-• Доступность интерфейсов проигрывателей
-• Добавлена возможность добавлять название подборки и название видеораспространяемого содержимого подборки.
-• Внутренние усовершенствования и обновление зависимостей
+Улучшено
+• Доступность интерфейсов плееров
+• Выбор аудио для скачивания только видео
+• Возможность включения названий плейлистов и видео в общий плейлист
-Исправления
+Исправлено
+• Получение кол-ва лайков
+• Плеер не видит всплывающие окона и вылетает
• Выбор неправильных языков в переключателе языков
• Фокусировка звука проигрывателя не учитывала выключение звука
-• Добавление элементов в подборки не работало в определённых случаях
+• Добавление элемента плейлиста иногда не работает
diff --git a/fastlane/metadata/android/ru/changelogs/996.txt b/fastlane/metadata/android/ru/changelogs/996.txt
new file mode 100644
index 00000000000..d516b0bc288
--- /dev/null
+++ b/fastlane/metadata/android/ru/changelogs/996.txt
@@ -0,0 +1,2 @@
+Исправлена ошибка NullPointerException при открытии канала/конференции в media.ccc.de.
+Гринч пытался сломать наш рождественский подарок вам, но мы починили его.
diff --git a/fastlane/metadata/android/si/full_description.txt b/fastlane/metadata/android/si/full_description.txt
new file mode 100644
index 00000000000..c5300a7e97e
--- /dev/null
+++ b/fastlane/metadata/android/si/full_description.txt
@@ -0,0 +1 @@
+NewPipe කිසිදු Google රාමු පුස්තකාලයක් හෝ YouTube API භාවිතා නොකරයි. එය අවශ්ය තොරතුරු ලබා ගැනීම සඳහා වෙබ් අඩවිය විග්රහ කරයි. එබැවින් මෙම යෙදුම Google සේවා ස්ථාපනය කර නොමැති උපාංග මත භාවිතා කළ හැක. එසේම, ඔබට NewPipe භාවිතා කිරීමට YouTube ගිණුමක් අවශ්ය නොවන අතර එය FLOSS වේ.
diff --git a/fastlane/metadata/android/si/short_description.txt b/fastlane/metadata/android/si/short_description.txt
new file mode 100644
index 00000000000..6f79e214d4a
--- /dev/null
+++ b/fastlane/metadata/android/si/short_description.txt
@@ -0,0 +1 @@
+Android සඳහා නොමිලේ සැහැල්ලු YouTube ඉදිරි අන්තය.
diff --git a/fastlane/metadata/android/sk/changelogs/995.txt b/fastlane/metadata/android/sk/changelogs/995.txt
new file mode 100644
index 00000000000..9729b3f70b3
--- /dev/null
+++ b/fastlane/metadata/android/sk/changelogs/995.txt
@@ -0,0 +1,16 @@
+Nové
+- Podpora kariet kanálov
+- Výber kvality obrázka
+- Získate adresy URL všetkých obrázkov
+
+Vylepšené
+- Prístupnosť rozhrania prehrávača
+- Lepší výber zvuku pri sťahovaní videa
+- Možnosť zahrnúť názvy playlistov a videí do zdieľaného obsahu playlistov
+
+Opravené
+- [YouTube] Oprava získavania počtu lajkov
+- Oprava vyskakovacích okien a pádov prehrávača
+- Výber nesprávnych jazykov vo výbere jazyka
+- Zameranie zvuku prehrávača nerešpektovalo stlmenie
+- Občas nefungovalo pridávanie položiek do playlistu
diff --git a/fastlane/metadata/android/sk/changelogs/996.txt b/fastlane/metadata/android/sk/changelogs/996.txt
new file mode 100644
index 00000000000..25fa111b5a2
--- /dev/null
+++ b/fastlane/metadata/android/sk/changelogs/996.txt
@@ -0,0 +1,2 @@
+Opravená výnimka NullPointerException pri otvorení kanála/konferencie v media.ccc.de.
+Grinch sa pokúsil prekaziť náš vianočný darček pre vás, ale opravili sme to.
diff --git a/fastlane/metadata/android/sr/changelogs/996.txt b/fastlane/metadata/android/sr/changelogs/996.txt
new file mode 100644
index 00000000000..749b74624ab
--- /dev/null
+++ b/fastlane/metadata/android/sr/changelogs/996.txt
@@ -0,0 +1,2 @@
+Поправљен NullPointerException приликом отварања канала/конференције у media.ccc.de.
+Гринч је покушао да вам поквари наш божићни поклон, али смо то поправили.
diff --git a/fastlane/metadata/android/sv/changelogs/63.txt b/fastlane/metadata/android/sv/changelogs/63.txt
index dcf52354b1f..51c6551c18a 100644
--- a/fastlane/metadata/android/sv/changelogs/63.txt
+++ b/fastlane/metadata/android/sv/changelogs/63.txt
@@ -1,7 +1,7 @@
### Förbättringar
-- Import/export inställningar #1333
+- Import/exportinställningar #1333
- Minskade överdragningen (prestandaförbättring) #1371
-- Små kod förbättringar #1375
+- Små kodförbättringar #1375
- La till allt om GDPR #1420
### Fixade
diff --git a/fastlane/metadata/android/sv/changelogs/64.txt b/fastlane/metadata/android/sv/changelogs/64.txt
index f874eebffb9..182fc0156b3 100644
--- a/fastlane/metadata/android/sv/changelogs/64.txt
+++ b/fastlane/metadata/android/sv/changelogs/64.txt
@@ -1,8 +1,8 @@
### Förbättringar
-- La till möjligheten all begränsa video kvaliteten vid användning av mobildata. #1339
+- La till möjligheten all begränsa videokvaliteten vid användning av mobildata. #1339
- Kom ihåg ljusstyrka för sessionen #1442
-- Förbättra nedladdnings prestandan på svagare CPUs #1431
-- La till (fungerande) support för media sessioner #1433
+- Förbättra nedladdningsprestandan på svagare CPUs #1431
+- La till (fungerande) support för mediasessioner #1433
### Fixade
- Fixade krasch vid öppning av nedladdningar (fixen är nu tillgänglig för release builds) #1441
diff --git a/fastlane/metadata/android/sv/changelogs/957.txt b/fastlane/metadata/android/sv/changelogs/957.txt
new file mode 100644
index 00000000000..a8be4f09b55
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/957.txt
@@ -0,0 +1,10 @@
+• Förenade specifika kö åtgärder
+• Två finger gest att stänga spelare
+• Tillåt rensning av reCAPTCHA-cookies
+• Inställning för att inte färglägga meddelande
+• Förbättra hur videoinformation öppnas för att fixa oändlig buffring, buggigt beteende när du delar till NewPipe och andra inkonsekvenser
+• Snabba upp YouTube-videor och fixa åldersbegränsning
+• Fixa krasch vid snabb fram/bak spolning
+• Ordna inte listor genom att dra miniatyrer
+• Kom alltid ihåg popup egenskaper
+• Lägga till Santali språk
diff --git a/fastlane/metadata/android/sv/changelogs/958.txt b/fastlane/metadata/android/sv/changelogs/958.txt
new file mode 100644
index 00000000000..268362f8739
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/958.txt
@@ -0,0 +1,10 @@
+Nytt och förbättrat:
+• La till inställning för att dölja miniatyr på låsskärmen
+• Dra för att uppdatera flöde
+• Förbättrad prestanda vid hämtning av lokala listor
+
+Fixat:
+• Fixade krasch när du startar NewPipe efter att den togs bort från RAM
+• Fixade krasch vid start när det inte finns någon internetanslutning
+• Fixade respekt för ljusstyrka- och volymgestinställningar
+• [YouTube] Fixade långa spellistor
diff --git a/fastlane/metadata/android/sv/changelogs/961.txt b/fastlane/metadata/android/sv/changelogs/961.txt
new file mode 100644
index 00000000000..6e1abc229dc
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/961.txt
@@ -0,0 +1,12 @@
+• [YouTube] Mix stöd
+• [YouTube] Visa information om offentliga programföretag och Covid-19
+• [media.ccc.de] La till nya videor
+• La till somalisk översättning
+
+• Många interna förbättringar
+
+• Fixade delning av videor ifrån spelaren
+• Fixade blank ReCaptcha webview
+• Fixade krasch som inträffade när du tar bort en ström från en lista
+• [PeerTube] Fixade relaterade strömmar
+• [YouTube] Fixade YouTube Musiksökning
diff --git a/fastlane/metadata/android/sv/changelogs/964.txt b/fastlane/metadata/android/sv/changelogs/964.txt
new file mode 100644
index 00000000000..cbdc9f4ffc5
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/964.txt
@@ -0,0 +1,7 @@
+• La till stöd för kapitel i spelarkontroller
+• [PeerTube] La till Sepia-sökning
+• La till dela knappen i videodetaljvy och flyttad strömbeskrivning till flik layouten
+• Inaktivera återställande av ljusstyrka om ljusstyrks gest är inaktiverad
+• Lägg till listobjekt för att spela video på kodi
+• Fixade krasch när ingen standardwebbläsare är inställd på vissa enheter och förbättrade dela dialog
+• Växla spela/pausa med hårdvaru mellanslags knapp i fullskärm
diff --git a/fastlane/metadata/android/sv/changelogs/965.txt b/fastlane/metadata/android/sv/changelogs/965.txt
new file mode 100644
index 00000000000..9b298947a4d
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/965.txt
@@ -0,0 +1,6 @@
+Fixade krasch som inträffade vid förflyttning av kanalgrupper.
+Fixade hämtning av fler YouTube videor från kanaler och spellistor.
+Fixade hämtning av YouTube kommentarer.
+La till stöd för /watch /, /v / och /w / subpaths i YouTube adresser.
+Fixade extraktion av SoundCloud klient id och geobegränsat innehåll.
+La till nordkurdisk lokalisering.
diff --git a/fastlane/metadata/android/sv/changelogs/966.txt b/fastlane/metadata/android/sv/changelogs/966.txt
new file mode 100644
index 00000000000..b8e18360429
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/966.txt
@@ -0,0 +1,14 @@
+Nytt:
+• La till en ny tjänst: Bandcamp
+
+Förbättrat:
+• Lägg till en inställning för att appen ska följa enhetstemat
+• Förhindra vissa kraschar genom att visa en förbättrad felpanel
+• Visa mer information om varför innehåll är otillgängligt
+• Hårdvaru mellanslagsknapp ändrar spela/pausa
+• Visa "Nedladdning startad" toast
+
+Fixat:
+• Fixade liten miniatyr i videodetaljer medan du spelar i bakgrunden
+• Fixade tom titel i minimerad spelare
+• Fixade senaste storleksläge som inte återställdes korrekt
diff --git a/fastlane/metadata/android/sv/changelogs/968.txt b/fastlane/metadata/android/sv/changelogs/968.txt
new file mode 100644
index 00000000000..4582309f434
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/968.txt
@@ -0,0 +1,7 @@
+La till kanalinformationsalternativ i långtrycksmenyn.
+La till funktionalitet för att byta namn från spellistans gränssnitt.
+Låt användaren pausa medan en video buffrar.
+Polerade det ljusa temat.
+Fixade överlappande teckensnitt när du använder en större teckenstorlek.
+Fixade ingen video på Formuler och Zephier enheter.
+Fixade olika kraschar.
diff --git a/fastlane/metadata/android/sv/changelogs/970.txt b/fastlane/metadata/android/sv/changelogs/970.txt
new file mode 100644
index 00000000000..020ee2c1bd6
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/970.txt
@@ -0,0 +1,11 @@
+Nytt
+• Visa innehåll metadata (taggar, kategorier, licens, ...) under beskrivningen
+• Lägg till alternativet "Visa kanalinformation" i distans (icke-lokala) spellistor
+• Lägg till "Öppna i webbläsare" -alternativ för långtrycksmeny
+
+Fixat
+• Fixade rotations krasch på video detalj sida
+• Fixade "Spela med Kodi" knappen i spelaren som alltid uppmanade till att installera Kore
+• Fixade och förbättrad inställning av import och exportvägar
+• [YouTube] Fixade kommentarers gilla antal
+Och mycket mer
diff --git a/fastlane/metadata/android/sv/changelogs/975.txt b/fastlane/metadata/android/sv/changelogs/975.txt
new file mode 100644
index 00000000000..f280c383054
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/975.txt
@@ -0,0 +1,15 @@
+Nytt
+• Visa en miniatyr förhandsvisning medan du söker
+• Upptäck avstängda kommentarer
+• Tillåt markering av ett flödesobjekt som visat
+• Visa kommentar hjärtan
+
+Förbättrat
+• Förbättrade metadata och tagg layout
+• Applicera service färg till UI komponenter
+
+Fixat
+• Fixade miniatyrbild i minispelare
+• Fixade oändlig buffring på dubbla köartiklar
+• Vissa spelare fixar som rotation och snabbare stängning
+• Fixade ReCAPTCHA som var kvar i bakgrunden
diff --git a/fastlane/metadata/android/sv/changelogs/976.txt b/fastlane/metadata/android/sv/changelogs/976.txt
new file mode 100644
index 00000000000..96b005170a2
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/976.txt
@@ -0,0 +1,9 @@
+• La till alternativ för att direkt öppna spelare i fullskärm
+• Tillåt användaren att välja vilka typer av sökförslag som ska visas
+• Mörkt tema är nu mörkare + mörk startskärm tillagd
+• Förbättrade fil väljare att gråa ut oönskade filer
+• Fixade import av YouTube prenumerationer
+• Att spela en ström kräver tryck på spela knappen igen
+• [Android TV] Fixa långa sökbar hopp vid användning av en DPad
+
+För att se ytterligare ändringar, se ändringsloggen (och blogginlägg) från Länkfliken nedan.
diff --git a/fastlane/metadata/android/sv/changelogs/983.txt b/fastlane/metadata/android/sv/changelogs/983.txt
new file mode 100644
index 00000000000..edc397a2918
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/983.txt
@@ -0,0 +1,9 @@
+La till nytt dubbel tryck för att söka UI och beteende
+Gör inställningar sökbara
+Markera fäst kommentarer som sådana
+Lägg till öppna med app stöd för FSFE PeerTube instans
+Lägg till felmeddelanden
+Fixade repris av första kö objekt vid spelar förändring
+Vänta längre vid buffring under livestreams innan misslyckande
+Fixade ordning av lokala sökresultat
+Fixade tomma objektfält i spelkö
diff --git a/fastlane/metadata/android/sv/changelogs/986.txt b/fastlane/metadata/android/sv/changelogs/986.txt
new file mode 100644
index 00000000000..2ebaacaa856
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/986.txt
@@ -0,0 +1,15 @@
+Nytt
+• Avisering för nya strömningar
+• Sömlös övergång mellan bakgrund och videospelare
+• Ändra pitch av semitoner
+• Lägg till huvudspelarens kö i en spellista
+
+Förbättrat
+• Kom ihåg hastighet/pitch steg storlek
+• Mildra initial lång buffring i videospelaren
+• Förbättra spelarens UI för Android TV
+• Bekräfta innan borttagning av alla nedladdade filer
+
+Fixat
+• Fixade media knapp som inte gömde spelarkontroller
+• Fixade uppspelningsåterställning vid spelar förändring
diff --git a/fastlane/metadata/android/sv/changelogs/987.txt b/fastlane/metadata/android/sv/changelogs/987.txt
new file mode 100644
index 00000000000..59416e59e30
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/987.txt
@@ -0,0 +1,12 @@
+Nytt
+• Stöd andra leveransmetoder än progressiv HTTP: snabbare uppspelningstid, fixar för PeerTube och SoundCloud, uppspelning av nyligen avslutade YouTube strömmar
+• La till knapp för att lägga till en fjärrspellista till en lokal
+• Bildförhandsvisning i Android 10+ dela blad
+
+Förbättrat
+• Förbättrade uppspelningsparametrar dialog
+• Flytta abonnemang import/exportknappar till trepunktsmenyn
+
+Fixat
+• Fixade ta bort tittade videor från spellista
+• Fixade dela meny tema och "lägg till i spellista"
diff --git a/fastlane/metadata/android/sv/changelogs/988.txt b/fastlane/metadata/android/sv/changelogs/988.txt
new file mode 100644
index 00000000000..09335ecbc67
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/988.txt
@@ -0,0 +1,2 @@
+[YouTube] Fixade "Kan inte få någon ström" fel vid spelning av någon video
+[YouTube] Fixade "Det följande innehållet är inte tillgängligt på den här appen." meddelandet visas istället för videon som begärs
diff --git a/fastlane/metadata/android/sv/changelogs/989.txt b/fastlane/metadata/android/sv/changelogs/989.txt
new file mode 100644
index 00000000000..28dcdf24507
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/989.txt
@@ -0,0 +1,3 @@
+• [YouTube] Fixade oändlig laddning vid försök att spela någon video
+• [YouTube] Fixade throttling på vissa videor
+• Uppgraderade jsoup-biblioteket till 1.15.3, vilket inkluderar en säkerhetsfix
diff --git a/fastlane/metadata/android/sv/changelogs/990.txt b/fastlane/metadata/android/sv/changelogs/990.txt
new file mode 100644
index 00000000000..1f1069accbc
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/990.txt
@@ -0,0 +1,15 @@
+Denna version avslutar stödet för Android 4.4 KitKat, nu är den minsta versionen Android 5 Lollipop!
+
+Nytt
+• Ladda ner från lång-tryck menyn
+• Dölj framtida videor i flödet
+• Dela lokala spellistor
+
+Förbättrat
+• Refaktorera spelarkoden i små komponenter: mindre RAM används, mindre buggar
+• Förbättra miniatyrernas skalläge
+• Vectorisera bildplatshållare
+
+Fixat
+• Fixade problem med spelarens meddelande: föråldrad/saknad media info, förvrängd miniatyr
+• Fixade fullskärm som använde 1/4 av skärmen
diff --git a/fastlane/metadata/android/sv/changelogs/991.txt b/fastlane/metadata/android/sv/changelogs/991.txt
new file mode 100644
index 00000000000..7f79c5ee726
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/991.txt
@@ -0,0 +1,13 @@
+Nytt
+• Lägg till "Öppna i webbläsare" knappen i felpanel
+• Lägg till inställning för att visa kanalgrupper som lista
+• [YouTube] Långtryck på strömsegment för att dela tidsstämpel URL
+• Lägg till play kö knapp till minispelare
+
+Förbättrat
+• Lägg till isländsk lokalisering och uppdatera många andra översättningar
+• Många interna förbättringar
+
+Fixat
+• Fixade flera kraschar
+• [YouTube] Fixade laddning av kanaler, icke-dedikerade flöden och uppspelningsproblem i vissa länder
diff --git a/fastlane/metadata/android/sv/changelogs/992.txt b/fastlane/metadata/android/sv/changelogs/992.txt
new file mode 100644
index 00000000000..253f1e5311f
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/992.txt
@@ -0,0 +1,17 @@
+Nytt
+• Prenumerant antal i videodetaljer
+• Ladda ner från kön
+• Ställ in en permanent miniatyr fr spellista
+• Långtryckt hashtags och länkar
+• Kortvys läge
+
+Förbättrat
+• Större minispelar stäng knapp
+• Mjukare miniatyrs nedskalning
+• Sikta på Android 13 (API 33)
+• Sökning pausar inte längre spelaren
+
+Fixat
+• Fixade overlay på DeX/Mouse
+• Tillåt bakgrundsspelare utan separata ljudströmmar
+• Olika YouTube-fixar och mer…
diff --git a/fastlane/metadata/android/sv/changelogs/993.txt b/fastlane/metadata/android/sv/changelogs/993.txt
new file mode 100644
index 00000000000..a06eafcd747
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/993.txt
@@ -0,0 +1,12 @@
+Nytt
+• La till varning vid tilläggning av dubbletter i spellista och la till knapp för att ta bort dem
+• Tillåt ignorering av hårdvaruknappar
+• Tillåt att dölja delvis tittade videor från flödet
+
+Förbättrat
+• Använd fler rutnät kolumner på stora skärmar
+• Gör framstegsindikatorer konsekventa med inställningar
+
+Fixat
+• Fixade öppning av webbläsar URLs, nedladdningar och externa spelare på Android 11+
+• Fixade interaktion med helskärm som kräver två tryck på MIUI
diff --git a/fastlane/metadata/android/sv/changelogs/994.txt b/fastlane/metadata/android/sv/changelogs/994.txt
new file mode 100644
index 00000000000..a07e8350091
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/994.txt
@@ -0,0 +1,15 @@
+Nytt
+• Stöd flera ljudspår/språk
+• Tillåt inställning av volym och ljusstyrks gester på valfri sida av skärmen
+• Stöd för att visa huvudflikar längst ner på skärmen
+
+Förbättrat
+• [Bandcamp] Hantera spår bakom betalvägg
+
+Fixat
+• [YouTube] 403 HTTP-fel för strömmar
+• Svart spelare vid byte till huvudspelare från spellistans vy
+• Spela service minnesläckor
+• [PeerTube] Uppladdare och sub kanal avatarer var utbytta
+
+och mer
diff --git a/fastlane/metadata/android/sv/changelogs/995.txt b/fastlane/metadata/android/sv/changelogs/995.txt
new file mode 100644
index 00000000000..be146073997
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/995.txt
@@ -0,0 +1,16 @@
+Nytt
+• Stöd kanalflikar
+• Välj bildkvalitet
+• Få webbadresser till alla bilder
+
+Förbättrat
+• Tillgänglighet för spelargränssnitt
+• Bättre ljudval för endast video nedladdningar
+• Alternativ att inkludera spellista och videonamn till delat spellistinnehåll
+
+Fixat
+• [YouTube] Fixade hämtning av gillaantal
+• Fixade spelare som inte svarar popup och kraschar
+• Val av fel språk i språkväljare
+• Spelarens ljudfokus respekterade inte mute
+• Spellist-objekt addition som ibland inte fungerade
diff --git a/fastlane/metadata/android/sv/changelogs/996.txt b/fastlane/metadata/android/sv/changelogs/996.txt
new file mode 100644
index 00000000000..8ee87d8c838
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/996.txt
@@ -0,0 +1,2 @@
+Fixade en NullPointerException när du öppnar en kanal / konferens i media.ccc.de.
+Grinchen försökte förstöra vår julklapp till er, men vi fixade den.
diff --git a/fastlane/metadata/android/sv/short_description.txt b/fastlane/metadata/android/sv/short_description.txt
index 6b29f892c4d..d0e04f5853c 100644
--- a/fastlane/metadata/android/sv/short_description.txt
+++ b/fastlane/metadata/android/sv/short_description.txt
@@ -1 +1 @@
-En gratis lättviktsklient för YouTube på Android.
+En gratis lättviktsklient för YouTube för Android.
diff --git a/fastlane/metadata/android/tr/full_description.txt b/fastlane/metadata/android/tr/full_description.txt
index 9422ff2bafa..2b31f8dfdaa 100644
--- a/fastlane/metadata/android/tr/full_description.txt
+++ b/fastlane/metadata/android/tr/full_description.txt
@@ -1,2 +1,2 @@
-NewPipe herhangi bir Google frameworkü veya YouTube API'si kullanmaz. Sadece, ihtiyaç duyduğu bilgiyi edinmek için web sitesini ayrıştırır.
-Bu nedenle Google hizmetlerinin kurulmadığı aygıtlarda kullanılabilir. Ayrıca, NewPipe'ı kullanırken YouTube hesabına ihtiyacınız yok, ve bu özgür ve açık kaynaklı bir yazılımdır.
+NewPipe herhangi bir Google framework’ü ya da YouTube API’ı kullanmaz. Yalnızca, kendisine gereken bilgiyi edinmek için web sitesini ayrıştırır.
+Bu nedenle Google hizmetlerinin kurulmadığı aygıtlarda kullanılabilir. Ayrıca NewPipe'ı kullanırken bir YouTube hesabına gerek yoktur ve NewPipe özgür ve açık kaynaklı bir yazılımdır.
diff --git a/fastlane/metadata/android/uk/changelogs/996.txt b/fastlane/metadata/android/uk/changelogs/996.txt
new file mode 100644
index 00000000000..e9fd2c523fa
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/996.txt
@@ -0,0 +1,2 @@
+Виправлено NullPointerException під час відкриття каналу / конференції у media.ccc.de.
+Грінч намагався зламати наш різдвяний подарунок, але ми його полагодили.
diff --git a/fastlane/metadata/android/vi/changelogs/996.txt b/fastlane/metadata/android/vi/changelogs/996.txt
new file mode 100644
index 00000000000..2f92c6dc28d
--- /dev/null
+++ b/fastlane/metadata/android/vi/changelogs/996.txt
@@ -0,0 +1,2 @@
+Đã sửa lỗi NullPointerException khi mở kênh/hội nghị trong media.ccc.de.
+Grinch đã cố làm vỡ món quà Giáng sinh của chúng tôi dành cho bạn, nhưng chúng tôi đã sửa nó.
diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/995.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/995.txt
index ddd775f0884..87050f4a535 100644
--- a/fastlane/metadata/android/zh_Hant_HK/changelogs/995.txt
+++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/995.txt
@@ -1,14 +1,16 @@
新嘢
• 支援頻道分頁
• 啲圖有得揀畫質
-• 啲圖全部都有得攞返個 URL
+• 啲圖全部都有得攞返條拎
進步
• 播放器介面暢易達
-• 分享播放清單有得加埋播放清單個名同入面啲片名
-• 內部提昇以及依賴元件更新
+• 揀返條靚啲嘅聲黐返落去齋晝面嘅影片下載
+• 分享播放清單時有得加埋播放清單個名同入面啲片名
修正
+• [YouTube] 執返掂個 like 數
+• 執返好播放器話冇回應個框框同埋閃退
• 揀選版面語言揀錯文
• 播放器聲音焦點無視噤聲
• 加入項目去播放清單有時唔得
diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/996.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/996.txt
new file mode 100644
index 00000000000..8b136fc4256
--- /dev/null
+++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/996.txt
@@ -0,0 +1,2 @@
+修正開啟 media.ccc.de 嘅頻道/會議時發生 NullPointerException 失卻指標錯誤。
+柳煙輕愜夜,俊緒留江影。謝謝您陪我哋跑完悲歡離合嘅一年。
From bec18e13d3a82f6b946d6bced353dd97178743c9 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Mon, 27 Nov 2023 09:08:53 +0530
Subject: [PATCH 80/82] Improve app signature check
---
.../schabi/newpipe/util/ReleaseVersionUtil.kt | 88 ++++---------------
1 file changed, 15 insertions(+), 73 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
index 5a54b29d224..fc31a4d9432 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
+++ b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
@@ -1,97 +1,39 @@
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.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"
+ private const val RELEASE_CERT_PUBLIC_KEY_SHA256 =
+ "cb84069bd68116bafae5ee4ee5b08a567aa6d898404e7cb12f9e756df5cf5cab"
@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 cf = CertificateFactory.getInstance("X509")
- cf.generateCertificate(signatures[0].toByteArray().inputStream()) 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)
+ @Suppress("NewApi")
+ val certificates = mapOf(
+ RELEASE_CERT_PUBLIC_KEY_SHA256.toByteArray() to PackageManager.CERT_INPUT_SHA256
)
+ val app = App.getApp()
+ return try {
+ PackageInfoCompat.hasSignatures(app.packageManager, app.packageName, certificates, false)
+ } catch (e: PackageManager.NameNotFoundException) {
+ createNotification(
+ app, ErrorInfo(e, UserAction.CHECK_FOR_NEW_APP_VERSION, "Could not find package info")
+ )
+ false
+ }
}
fun isLastUpdateCheckExpired(expiry: Long): Boolean {
- return Instant.ofEpochSecond(expiry).isBefore(Instant.now())
+ return Instant.ofEpochSecond(expiry) < Instant.now()
}
/**
From 2e53a99361cdc9f380ccd7ace8dd21ed8aa321f4 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Tue, 6 Feb 2024 05:11:13 +0530
Subject: [PATCH 81/82] Convert isReleaseApk to lazy value
---
.../main/java/org/schabi/newpipe/NewVersionWorker.kt | 10 ++++------
.../schabi/newpipe/settings/MainSettingsFragment.java | 2 +-
.../org/schabi/newpipe/settings/SettingsActivity.java | 2 +-
.../java/org/schabi/newpipe/util/ReleaseVersionUtil.kt | 5 ++---
4 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt b/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt
index 39d8e90dcdc..000b83953ec 100644
--- a/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt
+++ b/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt
@@ -20,9 +20,7 @@ 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 org.schabi.newpipe.util.ReleaseVersionUtil
import java.io.IOException
class NewVersionWorker(
@@ -84,7 +82,7 @@ class NewVersionWorker(
@Throws(IOException::class, ReCaptchaException::class)
private fun checkNewVersion() {
// Check if the current apk is a github one or not.
- if (!isReleaseApk()) {
+ if (!ReleaseVersionUtil.isReleaseApk) {
return
}
@@ -93,7 +91,7 @@ class NewVersionWorker(
// 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)) {
+ if (!ReleaseVersionUtil.isLastUpdateCheckExpired(expiry)) {
return
}
}
@@ -108,7 +106,7 @@ class NewVersionWorker(
try {
// Store a timestamp which needs to be exceeded,
// before a new request to the API is made.
- val newExpiry = coerceUpdateCheckExpiry(response.getHeader("expires"))
+ val newExpiry = ReleaseVersionUtil.coerceUpdateCheckExpiry(response.getHeader("expires"))
prefs.edit {
putLong(applicationContext.getString(R.string.update_expiry_key), newExpiry)
}
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 3776d78f679..32e33d55bf6 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java
@@ -23,7 +23,7 @@ public void onCreatePreferences(final Bundle savedInstanceState, final String ro
setHasOptionsMenu(true); // Otherwise onCreateOptionsMenu is not called
// Check if the app is updatable
- if (!ReleaseVersionUtil.isReleaseApk()) {
+ if (!ReleaseVersionUtil.INSTANCE.isReleaseApk()) {
getPreferenceScreen().removePreference(
findPreference(getString(R.string.update_pref_screen_key)));
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 3ee6668bf94..529e5344220 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java
@@ -266,7 +266,7 @@ private void initSearch(
*/
private void ensureSearchRepresentsApplicationState() {
// Check if the update settings are available
- if (!ReleaseVersionUtil.isReleaseApk()) {
+ if (!ReleaseVersionUtil.INSTANCE.isReleaseApk()) {
SettingsResourceRegistry.getInstance()
.getEntryByPreferencesResId(R.xml.update_settings)
.setSearchable(false);
diff --git a/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
index fc31a4d9432..fc1a7d8cc2d 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
+++ b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
@@ -15,14 +15,13 @@ object ReleaseVersionUtil {
private const val RELEASE_CERT_PUBLIC_KEY_SHA256 =
"cb84069bd68116bafae5ee4ee5b08a567aa6d898404e7cb12f9e756df5cf5cab"
- @JvmStatic
- fun isReleaseApk(): Boolean {
+ val isReleaseApk by lazy {
@Suppress("NewApi")
val certificates = mapOf(
RELEASE_CERT_PUBLIC_KEY_SHA256.toByteArray() to PackageManager.CERT_INPUT_SHA256
)
val app = App.getApp()
- return try {
+ try {
PackageInfoCompat.hasSignatures(app.packageManager, app.packageName, certificates, false)
} catch (e: PackageManager.NameNotFoundException) {
createNotification(
From 5bdb6f18d60783b38043f547f0131104531e70e5 Mon Sep 17 00:00:00 2001
From: Isira Seneviratne
Date: Wed, 20 Mar 2024 06:49:09 +0530
Subject: [PATCH 82/82] Use hexToByteArray() extension
---
.../main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
index fc1a7d8cc2d..3ea19fa4f8b 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
+++ b/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt
@@ -15,10 +15,11 @@ object ReleaseVersionUtil {
private const val RELEASE_CERT_PUBLIC_KEY_SHA256 =
"cb84069bd68116bafae5ee4ee5b08a567aa6d898404e7cb12f9e756df5cf5cab"
+ @OptIn(ExperimentalStdlibApi::class)
val isReleaseApk by lazy {
@Suppress("NewApi")
val certificates = mapOf(
- RELEASE_CERT_PUBLIC_KEY_SHA256.toByteArray() to PackageManager.CERT_INPUT_SHA256
+ RELEASE_CERT_PUBLIC_KEY_SHA256.hexToByteArray() to PackageManager.CERT_INPUT_SHA256
)
val app = App.getApp()
try {