From 8fc5fa979db75bff71f4cd3d0f32e6289afe283a Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sat, 3 Dec 2022 09:52:04 +0100 Subject: [PATCH 01/84] Added menu with tappable list items --- .../playlist/model/PlaylistEntity.java | 1 + .../local/bookmark/BookmarkFragment.java | 33 +++++++++++++++++++ .../local/playlist/LocalPlaylistFragment.java | 5 ++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java index 71abf2732..37e79f060 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java @@ -15,6 +15,7 @@ public class PlaylistEntity { public static final String PLAYLIST_ID = "uid"; public static final String PLAYLIST_NAME = "name"; public static final String PLAYLIST_THUMBNAIL_URL = "thumbnail_url"; + //TODO: add field @PrimaryKey(autoGenerate = true) @ColumnInfo(name = PLAYLIST_ID) diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index be7414542..2170f7d97 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.local.bookmark; +import android.content.DialogInterface; import android.os.Bundle; import android.os.Parcelable; import android.text.InputType; @@ -23,6 +24,7 @@ import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity; import org.schabi.newpipe.databinding.DialogEditTextBinding; +import org.schabi.newpipe.databinding.DialogTitleBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.BaseLocalListFragment; @@ -256,6 +258,37 @@ public final class BookmarkFragment extends BaseLocalListFragment { + switch (index) { + case 0: showRenameDialog(selectedItem); + break; + case 1: + break; + case 2: + break; + } + }; + + //TODO add rename dialog + + final AlertDialog.Builder builder = new AlertDialog.Builder(activity); + + builder.setItems(items, action) + .create() + .show(); + } + + private void showRenameDialog(final PlaylistMetadataEntry selectedItem) { final DialogEditTextBinding dialogBinding = DialogEditTextBinding.inflate(getLayoutInflater()); dialogBinding.dialogEditText.setHint(R.string.name); diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index d98ce4121..66e7cbf8f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -406,6 +406,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment notWatchedItems = new ArrayList<>(); boolean thumbnailVideoRemoved = false; + //TODO: add blocker here if (removePartiallyWatched) { for (final var playlistItem : playlist) { @@ -590,6 +591,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Date: Sun, 4 Dec 2022 17:59:22 +0530 Subject: [PATCH 02/84] added Language suffix for subtitle downloads --- .../newpipe/download/DownloadDialog.java | 18 ++++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 2 files changed, 19 insertions(+) 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 2975fe43a..c54fd5173 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -562,6 +562,24 @@ public class DownloadDialog extends DialogFragment selectedSubtitleIndex = position; break; } + onItemSelectedSetFileName(); + } + + private void onItemSelectedSetFileName() { + final String setSubtitleLanguageCode = subtitleStreamsAdapter.getItem(selectedSubtitleIndex) + .getLanguageTag(); + switch (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()) { + case R.id.audio_button: + case R.id.video_button: + dialogBinding.fileName.setText(FilenameUtils.createFilename(getContext(), + currentInfo.getName())); + break; + case R.id.subtitle_button: + dialogBinding.fileName.setText(FilenameUtils.createFilename(getContext(), + currentInfo.getName() + getString( + R.string.caption_file_name, setSubtitleLanguageCode))); + break; + } } @Override diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3fa37155a..fefba2c77 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -452,6 +452,7 @@ Zoom Auto-generated + -%s Captions Modify player caption text scale and background styles. Requires app restart to take effect From 10a5741f36e0fa8c3d806a6a64c1584f06b4ef40 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Wed, 7 Dec 2022 02:32:53 +0100 Subject: [PATCH 03/84] Tried to implement the feature --- .../playlist/model/PlaylistEntity.java | 18 ++++++- .../local/bookmark/BookmarkFragment.java | 53 ++++++++++++------- .../local/dialog/PlaylistAppendDialog.java | 2 +- .../local/playlist/LocalPlaylistFragment.java | 26 +++++---- .../local/playlist/LocalPlaylistManager.java | 18 ++++--- app/src/main/res/values/strings.xml | 2 + 6 files changed, 80 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java index 37e79f060..a04a284da 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java @@ -15,7 +15,7 @@ public class PlaylistEntity { public static final String PLAYLIST_ID = "uid"; public static final String PLAYLIST_NAME = "name"; public static final String PLAYLIST_THUMBNAIL_URL = "thumbnail_url"; - //TODO: add field + public static final String PLAYLIST_THUMBNAIL_SET = "isThumbnailSet"; @PrimaryKey(autoGenerate = true) @ColumnInfo(name = PLAYLIST_ID) @@ -27,9 +27,14 @@ public class PlaylistEntity { @ColumnInfo(name = PLAYLIST_THUMBNAIL_URL) private String thumbnailUrl; - public PlaylistEntity(final String name, final String thumbnailUrl) { + @ColumnInfo(name = PLAYLIST_THUMBNAIL_SET) + private boolean isThumbnailSet; + + public PlaylistEntity(final String name, final String thumbnailUrl, + final boolean isThumbnailSet) { this.name = name; this.thumbnailUrl = thumbnailUrl; + this.isThumbnailSet = isThumbnailSet; } public long getUid() { @@ -55,4 +60,13 @@ public class PlaylistEntity { public void setThumbnailUrl(final String thumbnailUrl) { this.thumbnailUrl = thumbnailUrl; } + + public boolean getIsThumbnailSet() { + return isThumbnailSet; + } + + public void setIsThumbnailSet(final boolean isThumbnailSet) { + this.isThumbnailSet = isThumbnailSet; + } + } diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 2170f7d97..65db40d16 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -8,6 +8,8 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -24,7 +26,6 @@ import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity; import org.schabi.newpipe.databinding.DialogEditTextBinding; -import org.schabi.newpipe.databinding.DialogTitleBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.BaseLocalListFragment; @@ -258,32 +259,51 @@ public final class BookmarkFragment extends BaseLocalListFragment arrayAdapter = new ArrayAdapter<>(getContext(), + android.R.layout.simple_list_item_1) { + @Override + public View getView(final int position, final View convertView, + final ViewGroup parent) { + final View v = super.getView(position, convertView, parent); + final TextView textView = v.findViewById(android.R.id.text1); - final DialogTitleBinding dialogBinding = - DialogTitleBinding.inflate(LayoutInflater.from(requireContext())); + if (!isPlaylistThumbnailSet && position == 2) { + textView.setEnabled(false); + return v; + } - dialogBinding.itemRoot.setVisibility(View.GONE); - dialogBinding.itemTitleView.setVisibility(View.GONE); - dialogBinding.itemAdditionalDetails.setVisibility(View.GONE); - final String[] items = new String[]{"Delete", "Rename", "Thumbnail"}; - final DialogInterface.OnClickListener action = (d, index) -> { + textView.setEnabled(true); + return v; + } + }; + arrayAdapter.addAll(getString(R.string.rename), getString(R.string.delete), + getString(R.string.unset_playlist_thumbnail)); + + // Rename = 0; Delete = 1; Unset Thumbnail = 2 + final DialogInterface.OnClickListener action = (dialog, index) -> { switch (index) { case 0: showRenameDialog(selectedItem); break; case 1: + showDeleteDialog(selectedItem.name, + localPlaylistManager.deletePlaylist(selectedItem.uid)); + dialog.dismiss(); break; case 2: + if (isPlaylistThumbnailSet) { + final String ur = "drawable://" + R.drawable.placeholder_thumbnail_playlist; + localPlaylistManager.changePlaylistThumbnail(selectedItem.uid, ur, + false).observeOn(AndroidSchedulers.mainThread()).subscribe(); + } break; } }; - //TODO add rename dialog - - final AlertDialog.Builder builder = new AlertDialog.Builder(activity); - - builder.setItems(items, action) + builder.setAdapter(arrayAdapter, action) .create() .show(); } @@ -302,11 +322,6 @@ public final class BookmarkFragment extends BaseLocalListFragment { - showDeleteDialog(selectedItem.name, - localPlaylistManager.deletePlaylist(selectedItem.uid)); - dialog.dismiss(); - }) .create() .show(); } diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 3d5d16c39..88dec3911 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -134,7 +134,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog { if (playlist.thumbnailUrl .equals("drawable://" + R.drawable.placeholder_thumbnail_playlist)) { playlistDisposables.add(manager - .changePlaylistThumbnail(playlist.uid, streams.get(0).getThumbnailUrl()) + .changePlaylistThumbnail(playlist.uid, streams.get(0).getThumbnailUrl(), false) .observeOn(AndroidSchedulers.mainThread()) .subscribe(ignored -> successToast.show())); } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 66e7cbf8f..78e455c78 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -405,8 +405,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment { // Remove Watched, Functionality data final List notWatchedItems = new ArrayList<>(); + final boolean isThumbnailSet = playlistManager + .getIsPlaylistThumbnailSet(playlistId); boolean thumbnailVideoRemoved = false; - //TODO: add blocker here if (removePartiallyWatched) { for (final var playlistItem : playlist) { @@ -415,7 +416,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment successToast.show(), throwable -> showError(new ErrorInfo(throwable, UserAction.REQUESTED_BOOKMARK, @@ -612,8 +612,11 @@ public class LocalPlaylistFragment extends BaseLocalListFragment - changeThumbnailUrl(item.getStreamEntity().getThumbnailUrl())) + changeThumbnailUrl(item.getStreamEntity().getThumbnailUrl(), + true)) .setAction( StreamDialogDefaultEntry.DELETE, (f, i) -> deleteItem(item)) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index 33296aa84..2510b284d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -41,7 +41,7 @@ public class LocalPlaylistManager { } final StreamEntity defaultStream = streams.get(0); final PlaylistEntity newPlaylist = - new PlaylistEntity(name, defaultStream.getThumbnailUrl()); + new PlaylistEntity(name, defaultStream.getThumbnailUrl(), false); return Maybe.fromCallable(() -> database.runInTransaction(() -> upsertStreams(playlistTable.insert(newPlaylist), streams, 0)) @@ -96,24 +96,29 @@ public class LocalPlaylistManager { } public Maybe renamePlaylist(final long playlistId, final String name) { - return modifyPlaylist(playlistId, name, null); + return modifyPlaylist(playlistId, name, null, false); } public Maybe changePlaylistThumbnail(final long playlistId, - final String thumbnailUrl) { - return modifyPlaylist(playlistId, null, thumbnailUrl); + final String thumbnailUrl, + final boolean isPermanent) { + return modifyPlaylist(playlistId, null, thumbnailUrl, isPermanent); } public String getPlaylistThumbnail(final long playlistId) { return playlistTable.getPlaylist(playlistId).blockingFirst().get(0).getThumbnailUrl(); } + public boolean getIsPlaylistThumbnailSet(final long playlistId) { + return playlistTable.getPlaylist(playlistId).blockingFirst().get(0).getIsThumbnailSet(); + } + private Maybe modifyPlaylist(final long playlistId, @Nullable final String name, - @Nullable final String thumbnailUrl) { + @Nullable final String thumbnailUrl, + final boolean isPermanent) { return playlistTable.getPlaylist(playlistId) .firstElement() - .filter(playlistEntities -> !playlistEntities.isEmpty()) .map(playlistEntities -> { final PlaylistEntity playlist = playlistEntities.get(0); if (name != null) { @@ -121,6 +126,7 @@ public class LocalPlaylistManager { } if (thumbnailUrl != null) { playlist.setThumbnailUrl(thumbnailUrl); + playlist.setIsThumbnailSet(isPermanent); } return playlistTable.update(playlist); }).subscribeOn(Schedulers.io()); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3fa37155a..b79bb2815 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,6 +7,7 @@ Install Cancel OK + Yes Open in browser Mark as watched Open in popup mode @@ -438,6 +439,7 @@ Mute Unmute Set as playlist thumbnail + Unset thumbnail Bookmark Playlist Remove Bookmark Delete this playlist\? From bf1ebf8733c3d55a8443aa13bf599cbff2fa1981 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Thu, 8 Dec 2022 23:31:20 +0100 Subject: [PATCH 04/84] Fixed some bugs and improved code quality --- .../playlist/dao/PlaylistStreamDAO.java | 10 +++ .../local/bookmark/BookmarkFragment.java | 62 ++++++++++--------- .../local/playlist/LocalPlaylistManager.java | 7 +++ 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index 4941d9395..df4ef2e52 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -25,6 +25,7 @@ import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.JO import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.PLAYLIST_STREAM_JOIN_TABLE; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_ID; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE; +import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_THUMBNAIL_URL; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID_ALIAS; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE; @@ -53,6 +54,15 @@ public interface PlaylistStreamDAO extends BasicDAO { + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") Flowable getMaximumIndexOf(long playlistId); + @Query("SELECT CASE WHEN COUNT(*) != 0 then " + STREAM_THUMBNAIL_URL + " ELSE :defaultUrl END" + + " FROM " + STREAM_TABLE + + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE + + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID + + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId " + + " LIMIT 1" + ) + Flowable getAutomaticThumbnailUrl(long playlistId, String defaultUrl); + @RewriteQueriesToDropUnusedColumns @Transaction @Query("SELECT * FROM " + STREAM_TABLE + " INNER JOIN " diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 65db40d16..1ef61bf31 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -259,11 +259,42 @@ public final class BookmarkFragment extends BaseLocalListFragment arrayAdapter = new ArrayAdapter<>(getContext(), + final ArrayAdapter arrayAdapter = getLocalDialogArrayAdapter(isPlaylistThumbnailSet, + unsetThumbnail); + arrayAdapter.addAll(rename, delete, unsetThumbnail); + + final DialogInterface.OnClickListener action = (dialog, index) -> { + if (index == arrayAdapter.getPosition(rename)) { + showRenameDialog(selectedItem); + } else if (index == arrayAdapter.getPosition(delete)) { + showDeleteDialog(selectedItem.name, localPlaylistManager + .deletePlaylist(selectedItem.uid)); + dialog.dismiss(); + } else if (isPlaylistThumbnailSet) { + final String thumbnail_url = localPlaylistManager + .getAutomaticPlaylistThumbnail(selectedItem.uid); + localPlaylistManager.changePlaylistThumbnail(selectedItem.uid, thumbnail_url, false) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(); + } + }; + + builder.setAdapter(arrayAdapter, action) + .create() + .show(); + } + + private ArrayAdapter getLocalDialogArrayAdapter(final boolean isPlaylistThumbnailSet, + final String unsetThumbnail) { + return new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1) { @Override public View getView(final int position, final View convertView, @@ -271,7 +302,8 @@ public final class BookmarkFragment extends BaseLocalListFragment { - switch (index) { - case 0: showRenameDialog(selectedItem); - break; - case 1: - showDeleteDialog(selectedItem.name, - localPlaylistManager.deletePlaylist(selectedItem.uid)); - dialog.dismiss(); - break; - case 2: - if (isPlaylistThumbnailSet) { - final String ur = "drawable://" + R.drawable.placeholder_thumbnail_playlist; - localPlaylistManager.changePlaylistThumbnail(selectedItem.uid, ur, - false).observeOn(AndroidSchedulers.mainThread()).subscribe(); - } - break; - } - }; - - builder.setAdapter(arrayAdapter, action) - .create() - .show(); } private void showRenameDialog(final PlaylistMetadataEntry selectedItem) { diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index 2510b284d..8d975241b 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -2,6 +2,7 @@ package org.schabi.newpipe.local.playlist; import androidx.annotation.Nullable; +import org.schabi.newpipe.R; import org.schabi.newpipe.database.AppDatabase; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; @@ -113,12 +114,18 @@ public class LocalPlaylistManager { return playlistTable.getPlaylist(playlistId).blockingFirst().get(0).getIsThumbnailSet(); } + public String getAutomaticPlaylistThumbnail(final long playlistId) { + final String def = "drawable://" + R.drawable.placeholder_thumbnail_playlist; + return playlistStreamTable.getAutomaticThumbnailUrl(playlistId, def).blockingFirst(); + } + private Maybe modifyPlaylist(final long playlistId, @Nullable final String name, @Nullable final String thumbnailUrl, final boolean isPermanent) { return playlistTable.getPlaylist(playlistId) .firstElement() + .filter(playlistEntities -> !playlistEntities.isEmpty()) .map(playlistEntities -> { final PlaylistEntity playlist = playlistEntities.get(0); if (name != null) { From 1ac62541a8b601c15816065ba5d4a2b8702afa8b Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 9 Dec 2022 12:01:59 +0100 Subject: [PATCH 05/84] Formatting, renaming and small fixes --- .../playlist/model/PlaylistEntity.java | 18 +++++++++--------- .../local/bookmark/BookmarkFragment.java | 16 +++++++--------- .../local/playlist/LocalPlaylistFragment.java | 13 +++++++------ .../local/playlist/LocalPlaylistManager.java | 7 ++++--- app/src/main/res/values/strings.xml | 1 - 5 files changed, 27 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java index a04a284da..051b7c318 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java @@ -15,7 +15,7 @@ public class PlaylistEntity { public static final String PLAYLIST_ID = "uid"; public static final String PLAYLIST_NAME = "name"; public static final String PLAYLIST_THUMBNAIL_URL = "thumbnail_url"; - public static final String PLAYLIST_THUMBNAIL_SET = "isThumbnailSet"; + public static final String PLAYLIST_THUMBNAIL_PERMANENT = "isThumbnailSet"; @PrimaryKey(autoGenerate = true) @ColumnInfo(name = PLAYLIST_ID) @@ -27,14 +27,14 @@ public class PlaylistEntity { @ColumnInfo(name = PLAYLIST_THUMBNAIL_URL) private String thumbnailUrl; - @ColumnInfo(name = PLAYLIST_THUMBNAIL_SET) - private boolean isThumbnailSet; + @ColumnInfo(name = PLAYLIST_THUMBNAIL_PERMANENT) + private boolean isThumbnailPermanent; public PlaylistEntity(final String name, final String thumbnailUrl, - final boolean isThumbnailSet) { + final boolean isThumbnailPermanent) { this.name = name; this.thumbnailUrl = thumbnailUrl; - this.isThumbnailSet = isThumbnailSet; + this.isThumbnailPermanent = isThumbnailPermanent; } public long getUid() { @@ -61,12 +61,12 @@ public class PlaylistEntity { this.thumbnailUrl = thumbnailUrl; } - public boolean getIsThumbnailSet() { - return isThumbnailSet; + public boolean getIsThumbnailPermanent() { + return isThumbnailPermanent; } - public void setIsThumbnailSet(final boolean isThumbnailSet) { - this.isThumbnailSet = isThumbnailSet; + public void setIsThumbnailPermanent(final boolean isThumbnailSet) { + this.isThumbnailPermanent = isThumbnailSet; } } diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 1ef61bf31..8cb544e0b 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -262,12 +262,12 @@ public final class BookmarkFragment extends BaseLocalListFragment arrayAdapter = getLocalDialogArrayAdapter(isPlaylistThumbnailSet, + final ArrayAdapter arrayAdapter = getLocalDialogArrayAdapter(isThumbnailPermanent, unsetThumbnail); arrayAdapter.addAll(rename, delete, unsetThumbnail); @@ -277,11 +277,10 @@ public final class BookmarkFragment extends BaseLocalListFragment getLocalDialogArrayAdapter(final boolean isPlaylistThumbnailSet, final String unsetThumbnail) { - return new ArrayAdapter<>(getContext(), - android.R.layout.simple_list_item_1) { + return new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1) { @Override public View getView(final int position, final View convertView, final ViewGroup parent) { diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 78e455c78..d584ceefb 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -405,8 +405,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment { // Remove Watched, Functionality data final List notWatchedItems = new ArrayList<>(); - final boolean isThumbnailSet = playlistManager - .getIsPlaylistThumbnailSet(playlistId); + final boolean isThumbnailPermanent = playlistManager + .getIsPlaylistThumbnailPermanent(playlistId); boolean thumbnailVideoRemoved = false; if (removePartiallyWatched) { @@ -416,7 +416,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragmentInstall Cancel OK - Yes Open in browser Mark as watched Open in popup mode From fedc26e3cbbb2b3737c609d75d999e0df6743899 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 9 Dec 2022 22:40:54 +0100 Subject: [PATCH 06/84] Added migration to new database --- .../newpipe/database/DatabaseMigrationTest.kt | 40 ++++++++++++++----- .../org/schabi/newpipe/NewPipeDatabase.java | 4 +- .../schabi/newpipe/database/AppDatabase.java | 4 +- .../schabi/newpipe/database/Migrations.java | 9 +++++ .../playlist/model/PlaylistEntity.java | 2 +- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt b/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt index 28dea13e9..be95c8e27 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt @@ -33,7 +33,8 @@ class DatabaseMigrationTest { @get:Rule val testHelper = MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), - AppDatabase::class.java.canonicalName, FrameworkSQLiteOpenHelperFactory() + AppDatabase::class.java.canonicalName, + FrameworkSQLiteOpenHelperFactory() ) @Test @@ -42,7 +43,8 @@ class DatabaseMigrationTest { databaseInV2.run { insert( - "streams", SQLiteDatabase.CONFLICT_FAIL, + "streams", + SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { put("service_id", DEFAULT_SERVICE_ID) put("url", DEFAULT_URL) @@ -54,14 +56,16 @@ class DatabaseMigrationTest { } ) insert( - "streams", SQLiteDatabase.CONFLICT_FAIL, + "streams", + SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { put("service_id", DEFAULT_SECOND_SERVICE_ID) put("url", DEFAULT_SECOND_URL) } ) insert( - "streams", SQLiteDatabase.CONFLICT_FAIL, + "streams", + SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { put("service_id", DEFAULT_SERVICE_ID) } @@ -70,18 +74,31 @@ class DatabaseMigrationTest { } testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, Migrations.DB_VER_3, - true, Migrations.MIGRATION_2_3 + AppDatabase.DATABASE_NAME, + Migrations.DB_VER_3, + true, + Migrations.MIGRATION_2_3 ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, Migrations.DB_VER_4, - true, Migrations.MIGRATION_3_4 + AppDatabase.DATABASE_NAME, + Migrations.DB_VER_4, + true, + Migrations.MIGRATION_3_4 ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, Migrations.DB_VER_5, - true, Migrations.MIGRATION_4_5 + AppDatabase.DATABASE_NAME, + Migrations.DB_VER_5, + true, + Migrations.MIGRATION_4_5 + ) + + testHelper.runMigrationsAndValidate( + AppDatabase.DATABASE_NAME, + Migrations.DB_VER_6, + true, + Migrations.MIGRATION_5_6 ) val migratedDatabaseV3 = getMigratedDatabase() @@ -121,7 +138,8 @@ class DatabaseMigrationTest { private fun getMigratedDatabase(): AppDatabase { val database: AppDatabase = Room.databaseBuilder( ApplicationProvider.getApplicationContext(), - AppDatabase::class.java, AppDatabase.DATABASE_NAME + AppDatabase::class.java, + AppDatabase.DATABASE_NAME ) .build() testHelper.closeWhenFinished(database) diff --git a/app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java b/app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java index 402d4648d..fc3423994 100644 --- a/app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java +++ b/app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java @@ -5,6 +5,7 @@ import static org.schabi.newpipe.database.Migrations.MIGRATION_1_2; import static org.schabi.newpipe.database.Migrations.MIGRATION_2_3; import static org.schabi.newpipe.database.Migrations.MIGRATION_3_4; import static org.schabi.newpipe.database.Migrations.MIGRATION_4_5; +import static org.schabi.newpipe.database.Migrations.MIGRATION_5_6; import android.content.Context; import android.database.Cursor; @@ -24,7 +25,8 @@ public final class NewPipeDatabase { private static AppDatabase getDatabase(final Context context) { return Room .databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME) - .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5) + .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, + MIGRATION_5_6) .build(); } diff --git a/app/src/main/java/org/schabi/newpipe/database/AppDatabase.java b/app/src/main/java/org/schabi/newpipe/database/AppDatabase.java index 28ddc8184..563e80b17 100644 --- a/app/src/main/java/org/schabi/newpipe/database/AppDatabase.java +++ b/app/src/main/java/org/schabi/newpipe/database/AppDatabase.java @@ -1,6 +1,6 @@ package org.schabi.newpipe.database; -import static org.schabi.newpipe.database.Migrations.DB_VER_5; +import static org.schabi.newpipe.database.Migrations.DB_VER_6; import androidx.room.Database; import androidx.room.RoomDatabase; @@ -38,7 +38,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity; FeedEntity.class, FeedGroupEntity.class, FeedGroupSubscriptionEntity.class, FeedLastUpdatedEntity.class }, - version = DB_VER_5 + version = DB_VER_6 ) public abstract class AppDatabase extends RoomDatabase { public static final String DATABASE_NAME = "newpipe.db"; diff --git a/app/src/main/java/org/schabi/newpipe/database/Migrations.java b/app/src/main/java/org/schabi/newpipe/database/Migrations.java index 7de08442c..e301e3f1f 100644 --- a/app/src/main/java/org/schabi/newpipe/database/Migrations.java +++ b/app/src/main/java/org/schabi/newpipe/database/Migrations.java @@ -23,6 +23,7 @@ public final class Migrations { public static final int DB_VER_3 = 3; public static final int DB_VER_4 = 4; public static final int DB_VER_5 = 5; + public static final int DB_VER_6 = 6; private static final String TAG = Migrations.class.getName(); public static final boolean DEBUG = MainActivity.DEBUG; @@ -188,6 +189,14 @@ public final class Migrations { } }; + public static final Migration MIGRATION_5_6 = new Migration(DB_VER_5, DB_VER_6) { + @Override + public void migrate(@NonNull final SupportSQLiteDatabase database) { + database.execSQL("ALTER TABLE `playlists` ADD COLUMN `is_thumbnail_permanent` " + + "INTEGER NOT NULL DEFAULT 0"); + } + }; + private Migrations() { } } diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java index 051b7c318..086362da2 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java @@ -15,7 +15,7 @@ public class PlaylistEntity { public static final String PLAYLIST_ID = "uid"; public static final String PLAYLIST_NAME = "name"; public static final String PLAYLIST_THUMBNAIL_URL = "thumbnail_url"; - public static final String PLAYLIST_THUMBNAIL_PERMANENT = "isThumbnailSet"; + public static final String PLAYLIST_THUMBNAIL_PERMANENT = "is_thumbnail_permanent"; @PrimaryKey(autoGenerate = true) @ColumnInfo(name = PLAYLIST_ID) From dfd6534a1cd2c733d0ca183415d6a0fac29bd9d3 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sat, 10 Dec 2022 17:32:02 +0100 Subject: [PATCH 07/84] Added "6.json" --- .../6.json | 737 ++++++++++++++++++ 1 file changed, 737 insertions(+) create mode 100644 app/schemas/org.schabi.newpipe.database.AppDatabase/6.json diff --git a/app/schemas/org.schabi.newpipe.database.AppDatabase/6.json b/app/schemas/org.schabi.newpipe.database.AppDatabase/6.json new file mode 100644 index 000000000..ee69363cc --- /dev/null +++ b/app/schemas/org.schabi.newpipe.database.AppDatabase/6.json @@ -0,0 +1,737 @@ +{ + "formatVersion": 1, + "database": { + "version": 6, + "identityHash": "4084aa342aef315dc7b558770a7755a9", + "entities": [ + { + "tableName": "subscriptions", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service_id` INTEGER NOT NULL, `url` TEXT, `name` TEXT, `avatar_url` TEXT, `subscriber_count` INTEGER, `description` TEXT, `notification_mode` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "serviceId", + "columnName": "service_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "avatarUrl", + "columnName": "avatar_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subscriberCount", + "columnName": "subscriber_count", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "notificationMode", + "columnName": "notification_mode", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_subscriptions_service_id_url", + "unique": true, + "columnNames": [ + "service_id", + "url" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_subscriptions_service_id_url` ON `${TABLE_NAME}` (`service_id`, `url`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "search_history", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`creation_date` INTEGER, `service_id` INTEGER NOT NULL, `search` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "creationDate", + "columnName": "creation_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "serviceId", + "columnName": "service_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "search", + "columnName": "search", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_search_history_search", + "unique": false, + "columnNames": [ + "search" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_search_history_search` ON `${TABLE_NAME}` (`search`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "streams", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service_id` INTEGER NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `stream_type` TEXT NOT NULL, `duration` INTEGER NOT NULL, `uploader` TEXT NOT NULL, `uploader_url` TEXT, `thumbnail_url` TEXT, `view_count` INTEGER, `textual_upload_date` TEXT, `upload_date` INTEGER, `is_upload_date_approximation` INTEGER)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "serviceId", + "columnName": "service_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "streamType", + "columnName": "stream_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "uploader", + "columnName": "uploader", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "uploaderUrl", + "columnName": "uploader_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnail_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "viewCount", + "columnName": "view_count", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "textualUploadDate", + "columnName": "textual_upload_date", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "uploadDate", + "columnName": "upload_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "isUploadDateApproximation", + "columnName": "is_upload_date_approximation", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_streams_service_id_url", + "unique": true, + "columnNames": [ + "service_id", + "url" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_streams_service_id_url` ON `${TABLE_NAME}` (`service_id`, `url`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "stream_history", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stream_id` INTEGER NOT NULL, `access_date` INTEGER NOT NULL, `repeat_count` INTEGER NOT NULL, PRIMARY KEY(`stream_id`, `access_date`), FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "streamUid", + "columnName": "stream_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "accessDate", + "columnName": "access_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "repeatCount", + "columnName": "repeat_count", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "stream_id", + "access_date" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_stream_history_stream_id", + "unique": false, + "columnNames": [ + "stream_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_stream_history_stream_id` ON `${TABLE_NAME}` (`stream_id`)" + } + ], + "foreignKeys": [ + { + "table": "streams", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "stream_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "stream_state", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stream_id` INTEGER NOT NULL, `progress_time` INTEGER NOT NULL, PRIMARY KEY(`stream_id`), FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "streamUid", + "columnName": "stream_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "progressMillis", + "columnName": "progress_time", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "stream_id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [ + { + "table": "streams", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "stream_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "playlists", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `thumbnail_url` TEXT, `is_thumbnail_permanent` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnail_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isThumbnailPermanent", + "columnName": "is_thumbnail_permanent", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_playlists_name", + "unique": false, + "columnNames": [ + "name" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_playlists_name` ON `${TABLE_NAME}` (`name`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "playlist_stream_join", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`playlist_id` INTEGER NOT NULL, `stream_id` INTEGER NOT NULL, `join_index` INTEGER NOT NULL, PRIMARY KEY(`playlist_id`, `join_index`), FOREIGN KEY(`playlist_id`) REFERENCES `playlists`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "playlistUid", + "columnName": "playlist_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "streamUid", + "columnName": "stream_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "index", + "columnName": "join_index", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "playlist_id", + "join_index" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_playlist_stream_join_playlist_id_join_index", + "unique": true, + "columnNames": [ + "playlist_id", + "join_index" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_playlist_stream_join_playlist_id_join_index` ON `${TABLE_NAME}` (`playlist_id`, `join_index`)" + }, + { + "name": "index_playlist_stream_join_stream_id", + "unique": false, + "columnNames": [ + "stream_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_playlist_stream_join_stream_id` ON `${TABLE_NAME}` (`stream_id`)" + } + ], + "foreignKeys": [ + { + "table": "playlists", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "playlist_id" + ], + "referencedColumns": [ + "uid" + ] + }, + { + "table": "streams", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "stream_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "remote_playlists", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service_id` INTEGER NOT NULL, `name` TEXT, `url` TEXT, `thumbnail_url` TEXT, `uploader` TEXT, `stream_count` INTEGER)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "serviceId", + "columnName": "service_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailUrl", + "columnName": "thumbnail_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "uploader", + "columnName": "uploader", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "streamCount", + "columnName": "stream_count", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_remote_playlists_name", + "unique": false, + "columnNames": [ + "name" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_remote_playlists_name` ON `${TABLE_NAME}` (`name`)" + }, + { + "name": "index_remote_playlists_service_id_url", + "unique": true, + "columnNames": [ + "service_id", + "url" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_remote_playlists_service_id_url` ON `${TABLE_NAME}` (`service_id`, `url`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "feed", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stream_id` INTEGER NOT NULL, `subscription_id` INTEGER NOT NULL, PRIMARY KEY(`stream_id`, `subscription_id`), FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`subscription_id`) REFERENCES `subscriptions`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "streamId", + "columnName": "stream_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subscriptionId", + "columnName": "subscription_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "stream_id", + "subscription_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_feed_subscription_id", + "unique": false, + "columnNames": [ + "subscription_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_feed_subscription_id` ON `${TABLE_NAME}` (`subscription_id`)" + } + ], + "foreignKeys": [ + { + "table": "streams", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "stream_id" + ], + "referencedColumns": [ + "uid" + ] + }, + { + "table": "subscriptions", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "subscription_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "feed_group", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `icon_id` INTEGER NOT NULL, `sort_order` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sortOrder", + "columnName": "sort_order", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "uid" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_feed_group_sort_order", + "unique": false, + "columnNames": [ + "sort_order" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_feed_group_sort_order` ON `${TABLE_NAME}` (`sort_order`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "feed_group_subscription_join", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`group_id` INTEGER NOT NULL, `subscription_id` INTEGER NOT NULL, PRIMARY KEY(`group_id`, `subscription_id`), FOREIGN KEY(`group_id`) REFERENCES `feed_group`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`subscription_id`) REFERENCES `subscriptions`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "feedGroupId", + "columnName": "group_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subscriptionId", + "columnName": "subscription_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "group_id", + "subscription_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_feed_group_subscription_join_subscription_id", + "unique": false, + "columnNames": [ + "subscription_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_feed_group_subscription_join_subscription_id` ON `${TABLE_NAME}` (`subscription_id`)" + } + ], + "foreignKeys": [ + { + "table": "feed_group", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "group_id" + ], + "referencedColumns": [ + "uid" + ] + }, + { + "table": "subscriptions", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "subscription_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "feed_last_updated", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`subscription_id` INTEGER NOT NULL, `last_updated` INTEGER, PRIMARY KEY(`subscription_id`), FOREIGN KEY(`subscription_id`) REFERENCES `subscriptions`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "subscriptionId", + "columnName": "subscription_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastUpdated", + "columnName": "last_updated", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "subscription_id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [ + { + "table": "subscriptions", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "subscription_id" + ], + "referencedColumns": [ + "uid" + ] + } + ] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '4084aa342aef315dc7b558770a7755a9')" + ] + } +} \ No newline at end of file From 50269d0f5ebd3653f3498c78020792294762827f Mon Sep 17 00:00:00 2001 From: pratyaksh1610 Date: Mon, 2 Jan 2023 16:23:45 +0530 Subject: [PATCH 08/84] updated caption file name and clean code --- .../org/schabi/newpipe/download/DownloadDialog.java | 10 +++++----- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) 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 c54fd5173..7777f87fe 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -568,16 +568,16 @@ public class DownloadDialog extends DialogFragment private void onItemSelectedSetFileName() { final String setSubtitleLanguageCode = subtitleStreamsAdapter.getItem(selectedSubtitleIndex) .getLanguageTag(); + final String fileName = FilenameUtils.createFilename(getContext(), + currentInfo.getName()); switch (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()) { case R.id.audio_button: case R.id.video_button: - dialogBinding.fileName.setText(FilenameUtils.createFilename(getContext(), - currentInfo.getName())); + dialogBinding.fileName.setText(fileName); break; case R.id.subtitle_button: - dialogBinding.fileName.setText(FilenameUtils.createFilename(getContext(), - currentInfo.getName() + getString( - R.string.caption_file_name, setSubtitleLanguageCode))); + dialogBinding.fileName.setText(fileName + getString( + R.string.caption_file_name, fileName, setSubtitleLanguageCode)); break; } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fefba2c77..f9d1361a8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -452,7 +452,7 @@ Zoom Auto-generated - -%s + %1$s-%2$s Captions Modify player caption text scale and background styles. Requires app restart to take effect From 3e15c77a05209b76215fb0ef080930f19cfd62e8 Mon Sep 17 00:00:00 2001 From: pratyaksh1610 Date: Tue, 3 Jan 2023 14:07:28 +0530 Subject: [PATCH 09/84] move string to donottranslate.xml and fix nits --- .../java/org/schabi/newpipe/download/DownloadDialog.java | 6 +++--- app/src/main/res/values/donottranslate.xml | 1 + app/src/main/res/values/strings.xml | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) 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 7777f87fe..77bb48a81 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -566,8 +566,6 @@ public class DownloadDialog extends DialogFragment } private void onItemSelectedSetFileName() { - final String setSubtitleLanguageCode = subtitleStreamsAdapter.getItem(selectedSubtitleIndex) - .getLanguageTag(); final String fileName = FilenameUtils.createFilename(getContext(), currentInfo.getName()); switch (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()) { @@ -576,7 +574,9 @@ public class DownloadDialog extends DialogFragment dialogBinding.fileName.setText(fileName); break; case R.id.subtitle_button: - dialogBinding.fileName.setText(fileName + getString( + final String setSubtitleLanguageCode = subtitleStreamsAdapter + .getItem(selectedSubtitleIndex).getLanguageTag(); + dialogBinding.fileName.setText(getString( R.string.caption_file_name, fileName, setSubtitleLanguageCode)); break; } diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index d28f794c0..09bf9080c 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -27,4 +27,5 @@ SoundCloud @string/app_name LeakCanary + %1$s-%2$s diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f9d1361a8..3fa37155a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -452,7 +452,6 @@ Zoom Auto-generated - %1$s-%2$s Captions Modify player caption text scale and background styles. Requires app restart to take effect From f10d591462bdcc68ff58e18cb8f5eba82a45064d Mon Sep 17 00:00:00 2001 From: Robin Date: Tue, 3 Jan 2023 10:06:46 +0100 Subject: [PATCH 10/84] Samsung DeX should only be checked on Samsung devices Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> --- .../main/java/org/schabi/newpipe/util/DeviceUtils.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java index 46ab6da51..4b08cfcb5 100644 --- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java @@ -1,5 +1,7 @@ package org.schabi.newpipe.util; +import static android.content.Context.INPUT_SERVICE; + import android.annotation.SuppressLint; import android.app.UiModeManager; import android.content.Context; @@ -27,11 +29,10 @@ import org.schabi.newpipe.R; import java.lang.reflect.Method; -import static android.content.Context.INPUT_SERVICE; - public final class DeviceUtils { private static final String AMAZON_FEATURE_FIRE_TV = "amazon.hardware.fire_tv"; + private static final boolean SAMSUNG = Build.MANUFACTURER.equals("samsung"); private static Boolean isTV = null; private static Boolean isFireTV = null; @@ -120,6 +121,10 @@ public final class DeviceUtils { return true; } + if (!SAMSUNG) { + return false; + // DeX is Samsung-specific, skip the checks below on non-Samsung devices + } // DeX check for standalone and multi-window mode, from: // https://developer.samsung.com/samsung-dex/modify-optimizing.html try { From fd55d85bbf050bd0da7b6e1fd81f52a5a584613f Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Wed, 2 Nov 2022 20:39:33 +0530 Subject: [PATCH 11/84] Remove SimplifyOptionalCallChains. --- .../fragments/detail/VideoDetailFragment.java | 20 ++-- .../org/schabi/newpipe/player/Player.java | 90 ++++++++-------- .../player/playback/MediaSourceManager.java | 2 +- .../SeekbarPreviewThumbnailHelper.java | 19 ++-- .../newpipe/player/ui/MainPlayerUi.java | 10 +- .../newpipe/player/ui/VideoPlayerUi.java | 101 ++++++++---------- 6 files changed, 109 insertions(+), 133 deletions(-) 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 679084bdf..abb995ecd 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 @@ -255,11 +255,8 @@ public final class VideoDetailFragment playerUi.ifPresent(MainPlayerUi::toggleFullscreen); } - //noinspection SimplifyOptionalCallChains - if (playAfterConnect - || (currentInfo != null - && isAutoplayEnabled() - && !playerUi.isPresent())) { + if (playAfterConnect || (currentInfo != null && isAutoplayEnabled() + && playerUi.isEmpty())) { autoPlayEnabled = true; // forcefully start playing openVideoPlayerAutoFullscreen(); } @@ -1174,16 +1171,15 @@ public final class VideoDetailFragment * be reused in a few milliseconds and the flickering would be annoying. */ private void hideMainPlayerOnLoadingNewStream() { - //noinspection SimplifyOptionalCallChains - if (!isPlayerServiceAvailable() || !getRoot().isPresent() - || !player.videoPlayerSelected()) { + final var root = getRoot(); + if (!isPlayerServiceAvailable() || root.isEmpty() || !player.videoPlayerSelected()) { return; } removeVideoPlayerView(); if (isAutoplayEnabled()) { playerService.stopForImmediateReusing(); - getRoot().ifPresent(view -> view.setVisibility(View.GONE)); + root.ifPresent(view -> view.setVisibility(View.GONE)); } else { playerHolder.stopService(); } @@ -1887,10 +1883,8 @@ public final class VideoDetailFragment @Override public void onFullscreenStateChanged(final boolean fullscreen) { setupBrightness(); - //noinspection SimplifyOptionalCallChains - if (!isPlayerAndPlayerServiceAvailable() - || !player.UIs().get(MainPlayerUi.class).isPresent() - || getRoot().map(View::getParent).orElse(null) == null) { + if (!isPlayerAndPlayerServiceAvailable() || player.UIs().get(MainPlayerUi.class).isEmpty() + || getRoot().map(View::getParent).isEmpty()) { return; } diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 95520ba1e..da337b394 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -1695,26 +1695,25 @@ public final class Player implements PlaybackListener, Listener { } private void saveStreamProgressState(final long progressMillis) { - //noinspection SimplifyOptionalCallChains - if (!getCurrentStreamInfo().isPresent() - || !prefs.getBoolean(context.getString(R.string.enable_watch_history_key), true)) { - return; - } - if (DEBUG) { - Log.d(TAG, "saveStreamProgressState() called with: progressMillis=" + progressMillis - + ", currentMetadata=[" + getCurrentStreamInfo().get().getName() + "]"); - } + getCurrentStreamInfo().ifPresent(info -> { + if (!prefs.getBoolean(context.getString(R.string.enable_watch_history_key), true)) { + return; + } + if (DEBUG) { + Log.d(TAG, "saveStreamProgressState() called with: progressMillis=" + progressMillis + + ", currentMetadata=[" + info.getName() + "]"); + } - databaseUpdateDisposable - .add(recordManager.saveStreamState(getCurrentStreamInfo().get(), progressMillis) - .observeOn(AndroidSchedulers.mainThread()) - .doOnError(e -> { - if (DEBUG) { - e.printStackTrace(); - } - }) - .onErrorComplete() - .subscribe()); + databaseUpdateDisposable.add(recordManager.saveStreamState(info, progressMillis) + .observeOn(AndroidSchedulers.mainThread()) + .doOnError(e -> { + if (DEBUG) { + e.printStackTrace(); + } + }) + .onErrorComplete() + .subscribe()); + }); } public void saveStreamProgressState() { @@ -2036,40 +2035,35 @@ public final class Player implements PlaybackListener, Listener { // in livestreams) so we will be not able to execute the block below. // Reload the play queue manager in this case, which is the behavior when we don't know the // index of the video renderer or playQueueManagerReloadingNeeded returns true. - final Optional optCurrentStreamInfo = getCurrentStreamInfo(); - if (!optCurrentStreamInfo.isPresent()) { - reloadPlayQueueManager(); - setRecovery(); - return; - } + getCurrentStreamInfo().ifPresentOrElse(info -> { + // In the case we don't know the source type, fallback to the one with video with audio + // or audio-only source. + final SourceType sourceType = videoResolver.getStreamSourceType() + .orElse(SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY); - final StreamInfo info = optCurrentStreamInfo.get(); + if (playQueueManagerReloadingNeeded(sourceType, info, getVideoRendererIndex())) { + reloadPlayQueueManager(); + } else { + if (StreamTypeUtil.isAudio(info.getStreamType())) { + // Nothing to do more than setting the recovery position + setRecovery(); + return; + } - // In the case we don't know the source type, fallback to the one with video with audio or - // audio-only source. - final SourceType sourceType = videoResolver.getStreamSourceType().orElse( - SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY); + final var parametersBuilder = trackSelector.buildUponParameters(); - if (playQueueManagerReloadingNeeded(sourceType, info, getVideoRendererIndex())) { - reloadPlayQueueManager(); - } else { - if (StreamTypeUtil.isAudio(info.getStreamType())) { - // Nothing to do more than setting the recovery position - setRecovery(); - return; + // Enable/disable the video track and the ability to select subtitles + parametersBuilder.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, !videoEnabled); + parametersBuilder.setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, !videoEnabled); + + trackSelector.setParameters(parametersBuilder); } - final DefaultTrackSelector.Parameters.Builder parametersBuilder = - trackSelector.buildUponParameters(); - - // Enable/disable the video track and the ability to select subtitles - parametersBuilder.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, !videoEnabled); - parametersBuilder.setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, !videoEnabled); - - trackSelector.setParameters(parametersBuilder); - } - - setRecovery(); + setRecovery(); + }, () -> { + reloadPlayQueueManager(); + setRecovery(); + }); } /** diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java index 9b13bb3d7..f58aa6e91 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java @@ -423,7 +423,7 @@ public class MediaSourceManager { private Single getLoadedMediaSource(@NonNull final PlayQueueItem stream) { return stream.getStream().map(streamInfo -> { final MediaSource source = playbackListener.sourceOf(stream, streamInfo); - if (source == null || !MediaItemTag.from(source.getMediaItem()).isPresent()) { + if (source == null || MediaItemTag.from(source.getMediaItem()).isEmpty()) { final String message = "Unable to resolve source from stream info. " + "URL: " + stream.getUrl() + ", " + "audio count: " + streamInfo.getAudioStreams().size() + ", " diff --git a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java index 9eea89e78..b7441c272 100644 --- a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java @@ -8,6 +8,7 @@ import android.widget.ImageView; import androidx.annotation.IntDef; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.graphics.BitmapCompat; import androidx.core.math.MathUtils; import androidx.preference.PreferenceManager; @@ -16,7 +17,6 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.util.DeviceUtils; import java.lang.annotation.Retention; -import java.util.Optional; import java.util.function.IntSupplier; import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -66,21 +66,19 @@ public final class SeekbarPreviewThumbnailHelper { public static void tryResizeAndSetSeekbarPreviewThumbnail( @NonNull final Context context, - @NonNull final Optional optPreviewThumbnail, + @Nullable final Bitmap previewThumbnail, @NonNull final ImageView currentSeekbarPreviewThumbnail, @NonNull final IntSupplier baseViewWidthSupplier) { - - if (!optPreviewThumbnail.isPresent()) { + if (previewThumbnail == null) { currentSeekbarPreviewThumbnail.setVisibility(View.GONE); return; } currentSeekbarPreviewThumbnail.setVisibility(View.VISIBLE); - final Bitmap srcBitmap = optPreviewThumbnail.get(); // Resize original bitmap try { - final int srcWidth = srcBitmap.getWidth() > 0 ? srcBitmap.getWidth() : 1; + final int srcWidth = previewThumbnail.getWidth() > 0 ? previewThumbnail.getWidth() : 1; final int newWidth = MathUtils.clamp( // Use 1/4 of the width for the preview Math.round(baseViewWidthSupplier.getAsInt() / 4f), @@ -90,15 +88,16 @@ public final class SeekbarPreviewThumbnailHelper { Math.round(srcWidth * 2.5f)); final float scaleFactor = (float) newWidth / srcWidth; - final int newHeight = (int) (srcBitmap.getHeight() * scaleFactor); + final int newHeight = (int) (previewThumbnail.getHeight() * scaleFactor); - currentSeekbarPreviewThumbnail.setImageBitmap(BitmapCompat.createScaledBitmap(srcBitmap, - newWidth, newHeight, null, true)); + currentSeekbarPreviewThumbnail.setImageBitmap( + BitmapCompat.createScaledBitmap(previewThumbnail, newWidth, newHeight, null, + true)); } catch (final Exception ex) { Log.e(TAG, "Failed to resize and set seekbar preview thumbnail", ex); currentSeekbarPreviewThumbnail.setVisibility(View.GONE); } finally { - srcBitmap.recycle(); + previewThumbnail.recycle(); } } } diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java index 6226900f6..eadb1ac99 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java @@ -74,6 +74,7 @@ import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.external_communication.KoreUtils; import org.schabi.newpipe.util.external_communication.ShareUtils; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -746,15 +747,10 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh } private int getNearestStreamSegmentPosition(final long playbackPosition) { - //noinspection SimplifyOptionalCallChains - if (!player.getCurrentStreamInfo().isPresent()) { - return 0; - } - int nearestPosition = 0; final List segments = player.getCurrentStreamInfo() - .get() - .getStreamSegments(); + .map(StreamInfo::getStreamSegments) + .orElse(Collections.emptyList()); for (int i = 0; i < segments.size(); i++) { if (segments.get(i).getStartTimeSeconds() * 1000L > playbackPosition) { diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java index bce75d77f..896bb4e70 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java @@ -566,7 +566,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa SeekbarPreviewThumbnailHelper .tryResizeAndSetSeekbarPreviewThumbnail( player.getContext(), - seekbarPreviewThumbnailHolder.getBitmapAt(progress), + seekbarPreviewThumbnailHolder.getBitmapAt(progress).orElse(null), binding.currentSeekbarPreviewThumbnail, binding.subtitleView::getWidth); @@ -982,61 +982,56 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa } private void updateStreamRelatedViews() { - //noinspection SimplifyOptionalCallChains - if (!player.getCurrentStreamInfo().isPresent()) { - return; - } - final StreamInfo info = player.getCurrentStreamInfo().get(); + player.getCurrentStreamInfo().ifPresent(info -> { + binding.qualityTextView.setVisibility(View.GONE); + binding.playbackSpeed.setVisibility(View.GONE); - binding.qualityTextView.setVisibility(View.GONE); - binding.playbackSpeed.setVisibility(View.GONE); + binding.playbackEndTime.setVisibility(View.GONE); + binding.playbackLiveSync.setVisibility(View.GONE); - binding.playbackEndTime.setVisibility(View.GONE); - binding.playbackLiveSync.setVisibility(View.GONE); - - switch (info.getStreamType()) { - case AUDIO_STREAM: - case POST_LIVE_AUDIO_STREAM: - binding.surfaceView.setVisibility(View.GONE); - binding.endScreen.setVisibility(View.VISIBLE); - binding.playbackEndTime.setVisibility(View.VISIBLE); - break; - - case AUDIO_LIVE_STREAM: - binding.surfaceView.setVisibility(View.GONE); - binding.endScreen.setVisibility(View.VISIBLE); - binding.playbackLiveSync.setVisibility(View.VISIBLE); - break; - - case LIVE_STREAM: - binding.surfaceView.setVisibility(View.VISIBLE); - binding.endScreen.setVisibility(View.GONE); - binding.playbackLiveSync.setVisibility(View.VISIBLE); - break; - - case VIDEO_STREAM: - case POST_LIVE_STREAM: - //noinspection SimplifyOptionalCallChains - if (player.getCurrentMetadata() != null - && !player.getCurrentMetadata().getMaybeQuality().isPresent() - || (info.getVideoStreams().isEmpty() - && info.getVideoOnlyStreams().isEmpty())) { + switch (info.getStreamType()) { + case AUDIO_STREAM: + case POST_LIVE_AUDIO_STREAM: + binding.surfaceView.setVisibility(View.GONE); + binding.endScreen.setVisibility(View.VISIBLE); + binding.playbackEndTime.setVisibility(View.VISIBLE); break; - } - buildQualityMenu(); + case AUDIO_LIVE_STREAM: + binding.surfaceView.setVisibility(View.GONE); + binding.endScreen.setVisibility(View.VISIBLE); + binding.playbackLiveSync.setVisibility(View.VISIBLE); + break; - binding.qualityTextView.setVisibility(View.VISIBLE); - binding.surfaceView.setVisibility(View.VISIBLE); - // fallthrough - default: - binding.endScreen.setVisibility(View.GONE); - binding.playbackEndTime.setVisibility(View.VISIBLE); - break; - } + case LIVE_STREAM: + binding.surfaceView.setVisibility(View.VISIBLE); + binding.endScreen.setVisibility(View.GONE); + binding.playbackLiveSync.setVisibility(View.VISIBLE); + break; - buildPlaybackSpeedMenu(); - binding.playbackSpeed.setVisibility(View.VISIBLE); + case VIDEO_STREAM: + case POST_LIVE_STREAM: + if (player.getCurrentMetadata() != null + && player.getCurrentMetadata().getMaybeQuality().isEmpty() + || (info.getVideoStreams().isEmpty() + && info.getVideoOnlyStreams().isEmpty())) { + break; + } + + buildQualityMenu(); + + binding.qualityTextView.setVisibility(View.VISIBLE); + binding.surfaceView.setVisibility(View.VISIBLE); + // fallthrough + default: + binding.endScreen.setVisibility(View.GONE); + binding.playbackEndTime.setVisibility(View.VISIBLE); + break; + } + + buildPlaybackSpeedMenu(); + binding.playbackSpeed.setVisibility(View.VISIBLE); + }); } //endregion @@ -1198,8 +1193,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa if (menuItem.getGroupId() == POPUP_MENU_ID_QUALITY) { final int menuItemIndex = menuItem.getItemId(); @Nullable final MediaItemTag currentMetadata = player.getCurrentMetadata(); - //noinspection SimplifyOptionalCallChains - if (currentMetadata == null || !currentMetadata.getMaybeQuality().isPresent()) { + if (currentMetadata == null || currentMetadata.getMaybeQuality().isEmpty()) { return true; } @@ -1300,9 +1294,8 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa // Build UI buildCaptionMenu(availableLanguages); - //noinspection SimplifyOptionalCallChains if (player.getTrackSelector().getParameters().getRendererDisabled( - player.getCaptionRendererIndex()) || !selectedTracks.isPresent()) { + player.getCaptionRendererIndex()) || selectedTracks.isEmpty()) { binding.captionTextView.setText(R.string.caption_none); } else { binding.captionTextView.setText(selectedTracks.get().language); From e3062d7c6622a665b734eaf3caaaaf37199d7a3c Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Thu, 3 Nov 2022 06:00:51 +0530 Subject: [PATCH 12/84] Use Optional chaining. --- .../fragments/detail/VideoDetailFragment.java | 13 +++---- .../org/schabi/newpipe/player/Player.java | 21 +++++------- .../player/mediaitem/MediaItemTag.java | 11 +++--- .../player/playback/MediaSourceManager.java | 34 ++++++++++--------- .../SeekbarPreviewThumbnailHelper.java | 5 ++- .../newpipe/player/ui/MainPlayerUi.java | 33 ++++++++---------- 6 files changed, 53 insertions(+), 64 deletions(-) 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 abb995ecd..d32b694d7 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 @@ -2423,23 +2423,20 @@ public final class VideoDetailFragment // helpers to check the state of player and playerService boolean isPlayerAvailable() { - return (player != null); + return player != null; } boolean isPlayerServiceAvailable() { - return (playerService != null); + return playerService != null; } boolean isPlayerAndPlayerServiceAvailable() { - return (player != null && playerService != null); + return player != null && playerService != null; } public Optional getRoot() { - if (player == null) { - return Optional.empty(); - } - - return player.UIs().get(VideoPlayerUi.class) + return Optional.ofNullable(player) + .flatMap(player1 -> player1.UIs().get(VideoPlayerUi.class)) .map(playerUi -> playerUi.getBinding().getRoot()); } diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index da337b394..cc95d6be3 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -1877,21 +1877,16 @@ public final class Player implements PlaybackListener, Listener { @Nullable public VideoStream getSelectedVideoStream() { - @Nullable final MediaItemTag.Quality quality = Optional.ofNullable(currentMetadata) + return Optional.ofNullable(currentMetadata) .flatMap(MediaItemTag::getMaybeQuality) + .filter(quality -> { + final int selectedStreamIndex = quality.getSelectedVideoStreamIndex(); + return selectedStreamIndex >= 0 + && selectedStreamIndex < quality.getSortedVideoStreams().size(); + }) + .map(quality -> quality.getSortedVideoStreams() + .get(quality.getSelectedVideoStreamIndex())) .orElse(null); - if (quality == null) { - return null; - } - - final List availableStreams = quality.getSortedVideoStreams(); - final int selectedStreamIndex = quality.getSelectedVideoStreamIndex(); - - if (selectedStreamIndex >= 0 && availableStreams.size() > selectedStreamIndex) { - return availableStreams.get(selectedStreamIndex); - } else { - return null; - } } //endregion diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java index d23dd4574..f08086287 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java @@ -61,12 +61,11 @@ public interface MediaItemTag { @NonNull static Optional from(@Nullable final MediaItem mediaItem) { - if (mediaItem == null || mediaItem.localConfiguration == null - || !(mediaItem.localConfiguration.tag instanceof MediaItemTag)) { - return Optional.empty(); - } - - return Optional.of((MediaItemTag) mediaItem.localConfiguration.tag); + return Optional.ofNullable(mediaItem) + .map(item -> item.localConfiguration) + .map(localConfiguration -> localConfiguration.tag) + .filter(MediaItemTag.class::isInstance) + .map(MediaItemTag.class::cast); } @NonNull diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java index f58aa6e91..6d9fb8a1c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java @@ -7,8 +7,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.collection.ArraySet; -import com.google.android.exoplayer2.source.MediaSource; - import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import org.schabi.newpipe.extractor.exceptions.ExtractionException; @@ -27,6 +25,7 @@ import org.schabi.newpipe.util.ServiceHelper; import java.util.Collection; import java.util.Collections; +import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -422,21 +421,24 @@ public class MediaSourceManager { private Single getLoadedMediaSource(@NonNull final PlayQueueItem stream) { return stream.getStream().map(streamInfo -> { - final MediaSource source = playbackListener.sourceOf(stream, streamInfo); - if (source == null || MediaItemTag.from(source.getMediaItem()).isEmpty()) { - final String message = "Unable to resolve source from stream info. " - + "URL: " + stream.getUrl() + ", " - + "audio count: " + streamInfo.getAudioStreams().size() + ", " - + "video count: " + streamInfo.getVideoOnlyStreams().size() + ", " - + streamInfo.getVideoStreams().size(); - return (ManagedMediaSource) - FailedMediaSource.of(stream, new MediaSourceResolutionException(message)); - } + final var source = playbackListener.sourceOf(stream, streamInfo); - final MediaItemTag tag = MediaItemTag.from(source.getMediaItem()).get(); - final long expiration = System.currentTimeMillis() - + ServiceHelper.getCacheExpirationMillis(streamInfo.getServiceId()); - return new LoadedMediaSource(source, tag, stream, expiration); + return Optional.ofNullable(source) + .flatMap(source1 -> MediaItemTag.from(source1.getMediaItem())) + .map(tag -> { + final long expiration = System.currentTimeMillis() + + ServiceHelper.getCacheExpirationMillis(streamInfo.getServiceId()); + return new LoadedMediaSource(source, tag, stream, expiration); + }) + .orElseGet(() -> { + final String message = "Unable to resolve source from stream info. " + + "URL: " + stream.getUrl() + ", " + + "audio count: " + streamInfo.getAudioStreams().size() + ", " + + "video count: " + streamInfo.getVideoOnlyStreams().size() + ", " + + streamInfo.getVideoStreams().size(); + return FailedMediaSource.of(stream, new MediaSourceResolutionException( + message)); + }); }).onErrorReturn(throwable -> { if (throwable instanceof ExtractionException) { return FailedMediaSource.of(stream, new StreamInfoLoadException(throwable)); diff --git a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java index b7441c272..28856d606 100644 --- a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java @@ -90,9 +90,8 @@ public final class SeekbarPreviewThumbnailHelper { final float scaleFactor = (float) newWidth / srcWidth; final int newHeight = (int) (previewThumbnail.getHeight() * scaleFactor); - currentSeekbarPreviewThumbnail.setImageBitmap( - BitmapCompat.createScaledBitmap(previewThumbnail, newWidth, newHeight, null, - true)); + currentSeekbarPreviewThumbnail.setImageBitmap(BitmapCompat + .createScaledBitmap(previewThumbnail, newWidth, newHeight, null, true)); } catch (final Exception ex) { Log.e(TAG, "Failed to resize and set seekbar preview thumbnail", ex); currentSeekbarPreviewThumbnail.setVisibility(View.GONE); diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java index eadb1ac99..683629c25 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java @@ -862,14 +862,11 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh @Override protected void onPlaybackSpeedClicked() { - final AppCompatActivity activity = getParentActivity().orElse(null); - if (activity == null) { - return; - } - - PlaybackParameterDialog.newInstance(player.getPlaybackSpeed(), player.getPlaybackPitch(), - player.getPlaybackSkipSilence(), player::setPlaybackParameters) - .show(activity.getSupportFragmentManager(), null); + getParentActivity().ifPresent(activity -> + PlaybackParameterDialog.newInstance(player.getPlaybackSpeed(), + player.getPlaybackPitch(), player.getPlaybackSkipSilence(), + player::setPlaybackParameters) + .show(activity.getSupportFragmentManager(), null)); } @Override @@ -969,22 +966,22 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh //////////////////////////////////////////////////////////////////////////*/ //region Getters + private Optional getParentContext() { + return Optional.ofNullable(binding.getRoot().getParent()) + .filter(ViewGroup.class::isInstance) + .map(parent -> ((ViewGroup) parent).getContext()); + } + public Optional getParentActivity() { - final ViewParent rootParent = binding.getRoot().getParent(); - if (rootParent instanceof ViewGroup) { - final Context activity = ((ViewGroup) rootParent).getContext(); - if (activity instanceof AppCompatActivity) { - return Optional.of((AppCompatActivity) activity); - } - } - return Optional.empty(); + return getParentContext() + .filter(AppCompatActivity.class::isInstance) + .map(AppCompatActivity.class::cast); } public boolean isLandscape() { // DisplayMetrics from activity context knows about MultiWindow feature // while DisplayMetrics from app context doesn't - return DeviceUtils.isLandscape( - getParentActivity().map(Context.class::cast).orElse(player.getService())); + return DeviceUtils.isLandscape(getParentContext().orElse(player.getService())); } //endregion } From e8216b2e80868f3dd3baaa91efccda39cf486cf1 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Wed, 4 Jan 2023 05:42:09 +0530 Subject: [PATCH 13/84] Apply code review suggestions. --- .../org/schabi/newpipe/player/Player.java | 1 + .../player/playback/MediaSourceManager.java | 63 ++++++++++--------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index cc95d6be3..1b60f80c9 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -2056,6 +2056,7 @@ public final class Player implements PlaybackListener, Listener { setRecovery(); }, () -> { + // This is executed when the current stream info is not available. reloadPlayQueueManager(); setRecovery(); }); diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java index 6d9fb8a1c..88d7145bc 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java @@ -21,7 +21,6 @@ import org.schabi.newpipe.player.playqueue.events.MoveEvent; import org.schabi.newpipe.player.playqueue.events.PlayQueueEvent; import org.schabi.newpipe.player.playqueue.events.RemoveEvent; import org.schabi.newpipe.player.playqueue.events.ReorderEvent; -import org.schabi.newpipe.util.ServiceHelper; import java.util.Collection; import java.util.Collections; @@ -42,6 +41,7 @@ import io.reactivex.rxjava3.subjects.PublishSubject; import static org.schabi.newpipe.player.mediasource.FailedMediaSource.MediaSourceResolutionException; import static org.schabi.newpipe.player.mediasource.FailedMediaSource.StreamInfoLoadException; import static org.schabi.newpipe.player.playqueue.PlayQueue.DEBUG; +import static org.schabi.newpipe.util.ServiceHelper.getCacheExpirationMillis; public class MediaSourceManager { @NonNull @@ -420,34 +420,39 @@ public class MediaSourceManager { } private Single getLoadedMediaSource(@NonNull final PlayQueueItem stream) { - return stream.getStream().map(streamInfo -> { - final var source = playbackListener.sourceOf(stream, streamInfo); - - return Optional.ofNullable(source) - .flatMap(source1 -> MediaItemTag.from(source1.getMediaItem())) - .map(tag -> { - final long expiration = System.currentTimeMillis() - + ServiceHelper.getCacheExpirationMillis(streamInfo.getServiceId()); - return new LoadedMediaSource(source, tag, stream, expiration); - }) - .orElseGet(() -> { - final String message = "Unable to resolve source from stream info. " - + "URL: " + stream.getUrl() + ", " - + "audio count: " + streamInfo.getAudioStreams().size() + ", " - + "video count: " + streamInfo.getVideoOnlyStreams().size() + ", " - + streamInfo.getVideoStreams().size(); - return FailedMediaSource.of(stream, new MediaSourceResolutionException( - message)); - }); - }).onErrorReturn(throwable -> { - if (throwable instanceof ExtractionException) { - return FailedMediaSource.of(stream, new StreamInfoLoadException(throwable)); - } - // Non-source related error expected here (e.g. network), - // should allow retry shortly after the error. - return FailedMediaSource.of(stream, new Exception(throwable), - /*allowRetryIn=*/TimeUnit.MILLISECONDS.convert(3, TimeUnit.SECONDS)); - }); + return stream.getStream() + .map(streamInfo -> Optional + .ofNullable(playbackListener.sourceOf(stream, streamInfo)) + .flatMap(source -> + MediaItemTag.from(source.getMediaItem()) + .map(tag -> { + final int serviceId = streamInfo.getServiceId(); + final long expiration = System.currentTimeMillis() + + getCacheExpirationMillis(serviceId); + return new LoadedMediaSource(source, tag, stream, + expiration); + }) + ) + .orElseGet(() -> { + final String message = "Unable to resolve source from stream info. " + + "URL: " + stream.getUrl() + + ", audio count: " + streamInfo.getAudioStreams().size() + + ", video count: " + streamInfo.getVideoOnlyStreams().size() + + ", " + streamInfo.getVideoStreams().size(); + return FailedMediaSource.of(stream, + new MediaSourceResolutionException(message)); + }) + ) + .onErrorReturn(throwable -> { + if (throwable instanceof ExtractionException) { + return FailedMediaSource.of(stream, new StreamInfoLoadException(throwable)); + } + // Non-source related error expected here (e.g. network), + // should allow retry shortly after the error. + final long allowRetryIn = TimeUnit.MILLISECONDS.convert(3, + TimeUnit.SECONDS); + return FailedMediaSource.of(stream, new Exception(throwable), allowRetryIn); + }); } private void onMediaSourceReceived(@NonNull final PlayQueueItem item, From 2679a4bf1e712f82bf6bcb40b4eacd973c7206c7 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Wed, 4 Jan 2023 16:21:16 +0100 Subject: [PATCH 14/84] Removed the "Unset Thumbnail" item if you can't use this feature --- .../local/bookmark/BookmarkFragment.java | 52 ++++++------------- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 8cb544e0b..e2f493a8a 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -8,8 +8,6 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -34,6 +32,7 @@ import org.schabi.newpipe.local.playlist.RemotePlaylistManager; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.OnClickGesture; +import java.util.ArrayList; import java.util.List; import icepick.State; @@ -267,49 +266,30 @@ public final class BookmarkFragment extends BaseLocalListFragment arrayAdapter = getLocalDialogArrayAdapter(isThumbnailPermanent, - unsetThumbnail); - arrayAdapter.addAll(rename, delete, unsetThumbnail); + final ArrayList items = new ArrayList<>(); + items.add(rename); + items.add(delete); + if (isThumbnailPermanent) { + items.add(unsetThumbnail); + } - final DialogInterface.OnClickListener action = (dialog, index) -> { - if (index == arrayAdapter.getPosition(rename)) { + final DialogInterface.OnClickListener action = (d, index) -> { + if (items.get(index).equals(rename)) { showRenameDialog(selectedItem); - } else if (index == arrayAdapter.getPosition(delete)) { - showDeleteDialog(selectedItem.name, localPlaylistManager - .deletePlaylist(selectedItem.uid)); - } else if (isThumbnailPermanent) { + } else if (items.get(index).equals(delete)) { + showDeleteDialog(selectedItem.name, + localPlaylistManager.deletePlaylist(selectedItem.uid)); + } else if (isThumbnailPermanent && items.get(index).equals(unsetThumbnail)) { final String thumbnailUrl = localPlaylistManager .getAutomaticPlaylistThumbnail(selectedItem.uid); - localPlaylistManager.changePlaylistThumbnail(selectedItem.uid, thumbnailUrl, false) + localPlaylistManager + .changePlaylistThumbnail(selectedItem.uid, thumbnailUrl, false) .observeOn(AndroidSchedulers.mainThread()) .subscribe(); } }; - builder.setAdapter(arrayAdapter, action) - .create() - .show(); - } - - private ArrayAdapter getLocalDialogArrayAdapter(final boolean isPlaylistThumbnailSet, - final String unsetThumbnail) { - return new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1) { - @Override - public View getView(final int position, final View convertView, - final ViewGroup parent) { - final View v = super.getView(position, convertView, parent); - final TextView textView = v.findViewById(android.R.id.text1); - - // If the PlaylistThumbnail is not set permanently, the unset option is disabled. - if (!isPlaylistThumbnailSet && textView.getText().equals(unsetThumbnail)) { - textView.setEnabled(false); - return v; - } - - textView.setEnabled(true); - return v; - } - }; + builder.setItems(items.toArray(new String[0]), action).create().show(); } private void showRenameDialog(final PlaylistMetadataEntry selectedItem) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 85f82e60c..dd30aaefa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -438,7 +438,7 @@ Mute Unmute Set as playlist thumbnail - Unset thumbnail + Unset permanent thumbnail Bookmark Playlist Remove Bookmark Delete this playlist\? From 9c19e9813a879209edf87c29a665054cc792468c Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sun, 8 Jan 2023 11:53:42 +0100 Subject: [PATCH 15/84] Fixed a bug that caused multiple empty playlists to be not shown. --- .../schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index 4941d9395..09355deed 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -80,7 +80,7 @@ public interface PlaylistStreamDAO extends BasicDAO { + " FROM " + PLAYLIST_TABLE + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE + " ON " + PLAYLIST_ID + " = " + JOIN_PLAYLIST_ID - + " GROUP BY " + JOIN_PLAYLIST_ID + + " GROUP BY " + PLAYLIST_ID + " ORDER BY " + PLAYLIST_NAME + " COLLATE NOCASE ASC") Flowable> getPlaylistMetadata(); } From edff696ecc503c4a0e964636bbabef71ad1d6def Mon Sep 17 00:00:00 2001 From: petlyh <88139840+petlyh@users.noreply.github.com> Date: Tue, 10 Jan 2023 13:57:36 +0100 Subject: [PATCH 16/84] Ask for permission when enqueuing in a popup --- .../main/java/org/schabi/newpipe/util/NavigationHelper.java | 5 +++++ 1 file changed, 5 insertions(+) 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 13413e89d..483f5067a 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -183,6 +183,11 @@ public final class NavigationHelper { public static void enqueueOnPlayer(final Context context, final PlayQueue queue, final PlayerType playerType) { + if ((playerType == PlayerType.POPUP) && !PermissionHelper.isPopupEnabled(context)) { + PermissionHelper.showPopupEnablementToast(context); + return; + } + Toast.makeText(context, R.string.enqueued, Toast.LENGTH_SHORT).show(); final Intent intent = getPlayerEnqueueIntent(context, PlayerService.class, queue); From 9c7ed80662dd8feb63ccb0cbc70852044e34fbcc Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 11 Jan 2023 14:47:53 +0100 Subject: [PATCH 17/84] Use Optional.map correctly and other improvements --- .../fragments/detail/VideoDetailFragment.java | 9 +++++--- .../org/schabi/newpipe/player/Player.java | 6 ++--- .../player/mediaitem/MediaItemTag.java | 4 ++-- .../newpipe/player/ui/VideoPlayerUi.java | 23 ++++++++----------- 4 files changed, 19 insertions(+), 23 deletions(-) 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 d32b694d7..1fb6b5859 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 @@ -255,7 +255,9 @@ public final class VideoDetailFragment playerUi.ifPresent(MainPlayerUi::toggleFullscreen); } - if (playAfterConnect || (currentInfo != null && isAutoplayEnabled() + if (playAfterConnect + || (currentInfo != null + && isAutoplayEnabled() && playerUi.isEmpty())) { autoPlayEnabled = true; // forcefully start playing openVideoPlayerAutoFullscreen(); @@ -1883,8 +1885,9 @@ public final class VideoDetailFragment @Override public void onFullscreenStateChanged(final boolean fullscreen) { setupBrightness(); - if (!isPlayerAndPlayerServiceAvailable() || player.UIs().get(MainPlayerUi.class).isEmpty() - || getRoot().map(View::getParent).isEmpty()) { + if (!isPlayerAndPlayerServiceAvailable() + || player.UIs().get(MainPlayerUi.class).isEmpty() + || getRoot().flatMap(v -> Optional.ofNullable(v.getParent())).isEmpty()) { return; } diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 1b60f80c9..b6098a1ef 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -1875,8 +1875,7 @@ public final class Player implements PlaybackListener, Listener { loadController.disablePreloadingOfCurrentTrack(); } - @Nullable - public VideoStream getSelectedVideoStream() { + public Optional getSelectedVideoStream() { return Optional.ofNullable(currentMetadata) .flatMap(MediaItemTag::getMaybeQuality) .filter(quality -> { @@ -1885,8 +1884,7 @@ public final class Player implements PlaybackListener, Listener { && selectedStreamIndex < quality.getSortedVideoStreams().size(); }) .map(quality -> quality.getSortedVideoStreams() - .get(quality.getSelectedVideoStreamIndex())) - .orElse(null); + .get(quality.getSelectedVideoStreamIndex())); } //endregion diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java index f08086287..4f808caac 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java @@ -62,8 +62,8 @@ public interface MediaItemTag { @NonNull static Optional from(@Nullable final MediaItem mediaItem) { return Optional.ofNullable(mediaItem) - .map(item -> item.localConfiguration) - .map(localConfiguration -> localConfiguration.tag) + .flatMap(item -> Optional.ofNullable(item.localConfiguration)) + .flatMap(localConfiguration -> Optional.ofNullable(localConfiguration.tag)) .filter(MediaItemTag.class::isInstance) .map(MediaItemTag.class::cast); } diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java index 896bb4e70..e4f5b05e1 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java @@ -1060,12 +1060,11 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa qualityPopupMenu.getMenu().add(POPUP_MENU_ID_QUALITY, i, Menu.NONE, MediaFormat .getNameById(videoStream.getFormatId()) + " " + videoStream.getResolution()); } - final VideoStream selectedVideoStream = player.getSelectedVideoStream(); - if (selectedVideoStream != null) { - binding.qualityTextView.setText(selectedVideoStream.getResolution()); - } qualityPopupMenu.setOnMenuItemClickListener(this); qualityPopupMenu.setOnDismissListener(this); + + player.getSelectedVideoStream() + .ifPresent(s -> binding.qualityTextView.setText(s.getResolution())); } private void buildPlaybackSpeedMenu() { @@ -1171,12 +1170,9 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa qualityPopupMenu.show(); isSomePopupMenuVisible = true; - final VideoStream videoStream = player.getSelectedVideoStream(); - if (videoStream != null) { - //noinspection SetTextI18n - binding.qualityTextView.setText(MediaFormat.getNameById(videoStream.getFormatId()) - + " " + videoStream.getResolution()); - } + player.getSelectedVideoStream() + .map(s -> MediaFormat.getNameById(s.getFormatId()) + " " + s.getResolution()) + .ifPresent(binding.qualityTextView::setText); } /** @@ -1232,10 +1228,9 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa Log.d(TAG, "onDismiss() called with: menu = [" + menu + "]"); } isSomePopupMenuVisible = false; //TODO check if this works - final VideoStream selectedVideoStream = player.getSelectedVideoStream(); - if (selectedVideoStream != null) { - binding.qualityTextView.setText(selectedVideoStream.getResolution()); - } + player.getSelectedVideoStream() + .ifPresent(s -> binding.qualityTextView.setText(s.getResolution())); + if (player.isPlaying()) { hideControls(DEFAULT_CONTROLS_DURATION, 0); hideSystemUIIfNeeded(); From 400ee808e08055fcbec4304a5488dbe38afa8a04 Mon Sep 17 00:00:00 2001 From: devlearner Date: Sat, 15 Oct 2022 23:34:39 +0800 Subject: [PATCH 18/84] Set up theme/locale before super.create() This seems to solve a bug where the Open action menu dialog does not appear the first time on cold start on older Android (8.0). This is also the order of things in MainActivity and probably good practice. --- .../main/java/org/schabi/newpipe/RouterActivity.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 936beecff..b012be109 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -114,6 +114,11 @@ public class RouterActivity extends AppCompatActivity { @Override protected void onCreate(final Bundle savedInstanceState) { + ThemeHelper.setDayNightMode(this); + setTheme(ThemeHelper.isLightThemeSelected(this) + ? R.style.RouterActivityThemeLight : R.style.RouterActivityThemeDark); + Localization.assureCorrectAppLanguage(this); + super.onCreate(savedInstanceState); Icepick.restoreInstanceState(this, savedInstanceState); @@ -125,11 +130,6 @@ public class RouterActivity extends AppCompatActivity { finish(); } } - - ThemeHelper.setDayNightMode(this); - setTheme(ThemeHelper.isLightThemeSelected(this) - ? R.style.RouterActivityThemeLight : R.style.RouterActivityThemeDark); - Localization.assureCorrectAppLanguage(this); } @Override From 73e32889b674d9344306b7494247529d0a3925d6 Mon Sep 17 00:00:00 2001 From: devlearner Date: Sun, 16 Oct 2022 01:01:19 +0800 Subject: [PATCH 19/84] Don't finish() to allow recreate when orientation change is on foot --- app/src/main/java/org/schabi/newpipe/RouterActivity.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index b012be109..5892d9766 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -161,6 +161,14 @@ public class RouterActivity extends AppCompatActivity { disposables.clear(); } + @Override + public void finish() { + // allow the activity to recreate in case orientation changes + if (!isChangingConfigurations()) { + super.finish(); + } + } + private void handleUrl(final String url) { disposables.add(Observable .fromCallable(() -> { From b175774ad882eaec1530d329ddcc104c5500aca8 Mon Sep 17 00:00:00 2001 From: devlearner Date: Sun, 16 Oct 2022 02:32:41 +0800 Subject: [PATCH 20/84] Try to amicably handle DialogFragment in FragmentManager when recreated from orientation change - Handle finish() call instead of passing around callbacks to setOnDismissListener() - Don't start over again if returning to DialogFragment before orientation change --- .../org/schabi/newpipe/RouterActivity.java | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 5892d9766..0c4cff8d1 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -31,6 +31,7 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.core.app.NotificationCompat; import androidx.core.app.ServiceCompat; import androidx.core.math.MathUtils; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.preference.PreferenceManager; @@ -151,7 +152,32 @@ public class RouterActivity extends AppCompatActivity { protected void onStart() { super.onStart(); - handleUrl(currentUrl); + // FragmentManager will take care to recreate DialogFragments when screen rotates + // currently that's namely PlaylistDialog or DownloadDialog + // We used to .setOnDismissListener(dialog ->finish()); when creating those Dialogs + // but those callbacks won't survive a config change + // Try an alternate approach to hook into FragmentManager instead, to that effect + // (courtesy of https://stackoverflow.com/a/44028453) + final FragmentManager fm = getSupportFragmentManager(); + fm.registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() { + @Override + public void onFragmentViewDestroyed(@NonNull final FragmentManager fm, + @NonNull final Fragment f) { + super.onFragmentViewDestroyed(fm, f); + if (fm.getFragments().isEmpty()) { + // No more Dialog, we're done + finish(); + } + } + }, false); + + // Don't overlap the DialogFragment after rotating the screen + // If there's no DialogFragment, we're either starting afresh + // or we didn't make it to PlaylistDialog or DownloadDialog before the orientation change + if (fm.getFragments().isEmpty()) { + // Start over from scratch + handleUrl(currentUrl); + } } @Override @@ -659,12 +685,12 @@ public class RouterActivity extends AppCompatActivity { getThemeWrapperContext(), List.of(new StreamEntity(info)), playlistDialog -> { - playlistDialog.setOnDismissListener(dialog -> finish()); + // to be handled by FragmentManager + // playlistDialog.setOnDismissListener(dialog ->finish()); - playlistDialog.show( - this.getSupportFragmentManager(), - "addToPlaylistDialog" - ); + final FragmentManager fm = getSupportFragmentManager(); + playlistDialog.show(fm, "addToPlaylistDialog"); + fm.executePendingTransactions(); } ), throwable -> handleError(this, new ErrorInfo( @@ -684,7 +710,8 @@ public class RouterActivity extends AppCompatActivity { .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { final DownloadDialog downloadDialog = new DownloadDialog(this, result); - downloadDialog.setOnDismissListener(dialog -> finish()); + // to be handled by FragmentManager since listener would be gone when recreated + // playlistDialog.setOnDismissListener(dialog ->finish()); final FragmentManager fm = getSupportFragmentManager(); downloadDialog.show(fm, "downloadDialog"); From c1f37d85919686ea5ee1eef6cba695f63146d3fd Mon Sep 17 00:00:00 2001 From: devlearner Date: Sun, 16 Oct 2022 02:47:53 +0800 Subject: [PATCH 21/84] Also show toast in openDownloadDialog() and lengthened a bit to inform user to wait... --- .../org/schabi/newpipe/RouterActivity.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 0c4cff8d1..4a26a7905 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -669,13 +669,7 @@ public class RouterActivity extends AppCompatActivity { } private void openAddToPlaylistDialog() { - // Getting the stream info usually takes a moment - // Notifying the user here to ensure that no confusion arises - Toast.makeText( - getApplicationContext(), - getString(R.string.processing_may_take_a_moment), - Toast.LENGTH_SHORT) - .show(); + pleaseWait(); disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false) .subscribeOn(Schedulers.io()) @@ -705,6 +699,8 @@ public class RouterActivity extends AppCompatActivity { @SuppressLint("CheckResult") private void openDownloadDialog() { + pleaseWait(); + disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -719,6 +715,16 @@ public class RouterActivity extends AppCompatActivity { }, throwable -> showUnsupportedUrlDialog(currentUrl))); } + private void pleaseWait() { + // Getting the stream info usually takes a moment + // Notifying the user here to ensure that no confusion arises + Toast.makeText( + getApplicationContext(), + getString(R.string.processing_may_take_a_moment), + Toast.LENGTH_LONG) + .show(); + } + @Override public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, From 391830558e4eb8261447d5e69e2fbe83afab90ea Mon Sep 17 00:00:00 2001 From: devlearner Date: Sun, 16 Oct 2022 03:10:37 +0800 Subject: [PATCH 22/84] Ensure our transparent activity doesn't block touch events to underlying windows so we won't hold up UI while fetching media info for Add to Playlist or Download actions lest user might think it freezes when in fact a network request is underway --- app/src/main/java/org/schabi/newpipe/RouterActivity.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 4a26a7905..3f3eb1670 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -16,6 +16,7 @@ import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.WindowManager; import android.widget.Button; import android.widget.RadioButton; import android.widget.RadioGroup; @@ -120,6 +121,14 @@ public class RouterActivity extends AppCompatActivity { ? R.style.RouterActivityThemeLight : R.style.RouterActivityThemeDark); Localization.assureCorrectAppLanguage(this); + // Pass-through touch events to background activities + // so that our transparent window won't lock UI in the mean time + // network request is underway before showing PlaylistDialog or DownloadDialog + // (courtesy of https://stackoverflow.com/a/10606141) + getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + super.onCreate(savedInstanceState); Icepick.restoreInstanceState(this, savedInstanceState); From f860392ae9e67cf82eb82ee10dc9ed03c4ec2e33 Mon Sep 17 00:00:00 2001 From: devlearner Date: Fri, 2 Dec 2022 06:13:54 +0000 Subject: [PATCH 23/84] Address LayoutParams.FLAG_NOT_TOUCHABLE restriction on Andriod 12+ --- .../main/java/org/schabi/newpipe/RouterActivity.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 3f3eb1670..afc4321c1 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -124,11 +124,21 @@ public class RouterActivity extends AppCompatActivity { // Pass-through touch events to background activities // so that our transparent window won't lock UI in the mean time // network request is underway before showing PlaylistDialog or DownloadDialog - // (courtesy of https://stackoverflow.com/a/10606141) + // (ref: https://stackoverflow.com/a/10606141) getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + // Android never fails to impress us with a list of new restrictions per API. + // Starting with S (Android 12) one of the prerequisite conditions has to be met + // before the FLAG_NOT_TOUCHABLE flag is allowed to kick in: + // @see WindowManager.LayoutParams#FLAG_NOT_TOUCHABLE + // For our present purpose it seems we can just set LayoutParams.alpha to 0 + // on the strength of "4. Fully transparent windows" without affecting the scrim of dialogs + final WindowManager.LayoutParams params = getWindow().getAttributes(); + params.alpha = 0f; + getWindow().setAttributes(params); + super.onCreate(savedInstanceState); Icepick.restoreInstanceState(this, savedInstanceState); From 0f9c20c986d8a58f48990fff57c03323b6e9ca70 Mon Sep 17 00:00:00 2001 From: devlearner Date: Fri, 2 Dec 2022 09:25:06 +0000 Subject: [PATCH 24/84] Improve (un)registering FragmentLifecycleCallbacks to avoid adding it multiple times and ensure proper cleanup --- .../org/schabi/newpipe/RouterActivity.java | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index afc4321c1..35bb8612f 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -32,6 +32,7 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.core.app.NotificationCompat; import androidx.core.app.ServiceCompat; import androidx.core.math.MathUtils; +import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.preference.PreferenceManager; @@ -113,6 +114,7 @@ public class RouterActivity extends AppCompatActivity { private boolean selectionIsDownload = false; private boolean selectionIsAddToPlaylist = false; private AlertDialog alertDialogChoice = null; + private FragmentManager.FragmentLifecycleCallbacks dismissListener = null; @Override protected void onCreate(final Bundle savedInstanceState) { @@ -142,6 +144,27 @@ public class RouterActivity extends AppCompatActivity { super.onCreate(savedInstanceState); Icepick.restoreInstanceState(this, savedInstanceState); + // FragmentManager will take care to recreate (Playlist|Download)Dialog when screen rotates + // We used to .setOnDismissListener(dialog -> finish()); when creating these DialogFragments + // but those callbacks won't survive a config change + // Try an alternate approach to hook into FragmentManager instead, to that effect + // (ref: https://stackoverflow.com/a/44028453) + final FragmentManager fm = getSupportFragmentManager(); + if (dismissListener == null) { + dismissListener = new FragmentManager.FragmentLifecycleCallbacks() { + @Override + public void onFragmentDestroyed(@NonNull final FragmentManager fm, + @NonNull final Fragment f) { + super.onFragmentDestroyed(fm, f); + if (f instanceof DialogFragment && fm.getFragments().isEmpty()) { + // No more DialogFragments, we're done + finish(); + } + } + }; + } + fm.registerFragmentLifecycleCallbacks(dismissListener, false); + if (TextUtils.isEmpty(currentUrl)) { currentUrl = getUrl(getIntent()); @@ -171,29 +194,10 @@ public class RouterActivity extends AppCompatActivity { protected void onStart() { super.onStart(); - // FragmentManager will take care to recreate DialogFragments when screen rotates - // currently that's namely PlaylistDialog or DownloadDialog - // We used to .setOnDismissListener(dialog ->finish()); when creating those Dialogs - // but those callbacks won't survive a config change - // Try an alternate approach to hook into FragmentManager instead, to that effect - // (courtesy of https://stackoverflow.com/a/44028453) - final FragmentManager fm = getSupportFragmentManager(); - fm.registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() { - @Override - public void onFragmentViewDestroyed(@NonNull final FragmentManager fm, - @NonNull final Fragment f) { - super.onFragmentViewDestroyed(fm, f); - if (fm.getFragments().isEmpty()) { - // No more Dialog, we're done - finish(); - } - } - }, false); - // Don't overlap the DialogFragment after rotating the screen // If there's no DialogFragment, we're either starting afresh // or we didn't make it to PlaylistDialog or DownloadDialog before the orientation change - if (fm.getFragments().isEmpty()) { + if (getSupportFragmentManager().getFragments().isEmpty()) { // Start over from scratch handleUrl(currentUrl); } @@ -203,6 +207,9 @@ public class RouterActivity extends AppCompatActivity { protected void onDestroy() { super.onDestroy(); + if (dismissListener != null) { + getSupportFragmentManager().unregisterFragmentLifecycleCallbacks(dismissListener); + } disposables.clear(); } From 585bfff11da4edecc9b68ac2d2f408ef272d4c27 Mon Sep 17 00:00:00 2001 From: devlearner Date: Fri, 2 Dec 2022 14:22:00 +0000 Subject: [PATCH 25/84] Utilize a retained fragment to safekeep network requests in flight pending result for openAddToPlaylistDialog() and openDownloadDialog() Despite marked deprecated, setRetainInstance(true) is probably our best bet (since a ViewModel is probably too overkill for our present purpose) --- .../org/schabi/newpipe/RouterActivity.java | 203 ++++++++++++++---- 1 file changed, 163 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 35bb8612f..e61f1f738 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -83,9 +83,11 @@ import org.schabi.newpipe.util.urlfinder.UrlFinder; import org.schabi.newpipe.views.FocusOverlayView; import java.io.Serializable; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Vector; import icepick.Icepick; import icepick.State; @@ -300,7 +302,7 @@ public class RouterActivity extends AppCompatActivity { } } - private void showUnsupportedUrlDialog(final String url) { + protected void showUnsupportedUrlDialog(final String url) { final Context context = getThemeWrapperContext(); new AlertDialog.Builder(context) .setTitle(R.string.unsupported_url) @@ -587,7 +589,7 @@ public class RouterActivity extends AppCompatActivity { return returnedItems; } - private Context getThemeWrapperContext() { + protected Context getThemeWrapperContext() { return new ContextThemeWrapper(this, ThemeHelper.isLightThemeSelected(this) ? R.style.LightTheme : R.style.DarkTheme); } @@ -694,54 +696,175 @@ public class RouterActivity extends AppCompatActivity { return playerType == null || playerType == PlayerType.MAIN; } + public static class PersistentFragment extends Fragment { + private WeakReference context; + private boolean isPaused = true; + private final Vector buffer = new Vector<>(); + private final CompositeDisposable disposables = new CompositeDisposable(); + + public interface ResultRunnable { + void run(AppCompatActivity context); + } + + @Override + public void onAttach(@NonNull final Context activityContext) { + super.onAttach(activityContext); + context = new WeakReference<>((AppCompatActivity) activityContext); + } + + @SuppressWarnings("deprecation") + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setRetainInstance(true); + } + + @Override + public void onDestroy() { + super.onDestroy(); + disposables.clear(); + } + + @Override + public void onPause() { + isPaused = true; + super.onPause(); + } + + @Override + public void onResume() { + isPaused = false; + playback(); + super.onResume(); + } + + private AppCompatActivity getActivityContext() { + return context == null ? null : context.get(); + } + + // guard against IllegalStateException in calling DialogFragment.show() whilst in background + // (which could happen, say, when the user pressed the home button while waiting for + // the network request to return) when it internally calls FragmentTransaction.commit() + // after the FragmentManager has saved its states (isStateSaved() == true) + // (ref: https://stackoverflow.com/a/39813506) + private void playback() { + if (activityGone()) { + done(); + } + if (buffer.size() == 0 || isPaused) { + return; + } + while (buffer.size() > 0) { + final ResultRunnable runnable = buffer.elementAt(0); + buffer.removeElementAt(0); + getActivityContext().runOnUiThread(() -> { + // execute queued task with new context, in case activity has been recreated + runnable.run(getActivityContext()); + }); + } + done(); + } + private boolean activityGone() { + return getActivityContext() == null || getActivityContext().isFinishing(); + } + + // a DefaultLifecycleObserver is probably a good candidate here, but for now + // let's stick with a vanilla approach to avoid pulling in an extra artifact just for this + private void runOnVisible(final ResultRunnable runnable) { + if (activityGone()) { + done(); + } + if (isPaused) { + buffer.add(runnable); + if (!getActivityContext().isChangingConfigurations()) { + // try to bring the activity back to front if minimised + final Intent i = new Intent(getActivityContext(), RouterActivity.class); + i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + startActivity(i); + } + } else { + getActivityContext().runOnUiThread(() -> { + runnable.run(getActivityContext()); + done(); + }); + } + } + + private void done() { + if (getActivityContext() != null) { + getActivityContext().getSupportFragmentManager() + .beginTransaction().remove(this).commit(); + } + } + + @SuppressLint("CheckResult") + protected void openDownloadDialog(final int currentServiceId, final String currentUrl) { + disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(result -> + runOnVisible(ctx -> { + final FragmentManager fm = ctx.getSupportFragmentManager(); + final DownloadDialog downloadDialog = new DownloadDialog(ctx, result); + // dismiss listener to be handled by FragmentManager + downloadDialog.show(fm, "downloadDialog"); + } + ), throwable -> runOnVisible(ctx -> + ((RouterActivity) ctx).showUnsupportedUrlDialog(currentUrl)))); + } + + private void openAddToPlaylistDialog(final int currentServiceId, final String currentUrl) { + disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + info -> runOnVisible(ctx -> + PlaylistDialog.createCorrespondingDialog( + ((RouterActivity) ctx).getThemeWrapperContext(), + List.of(new StreamEntity(info)), + playlistDialog -> { + // dismiss listener to be handled by FragmentManager + final FragmentManager fm = ctx.getSupportFragmentManager(); + playlistDialog.show(fm, "addToPlaylistDialog"); + } + )), + throwable -> runOnVisible(ctx -> handleError(ctx, new ErrorInfo( + throwable, + UserAction.REQUESTED_STREAM, + "Tried to add " + currentUrl + " to a playlist", + ((RouterActivity) ctx).currentService.getServiceId()) + )) + ) + ); + } + } + private void openAddToPlaylistDialog() { pleaseWait(); - disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - info -> PlaylistDialog.createCorrespondingDialog( - getThemeWrapperContext(), - List.of(new StreamEntity(info)), - playlistDialog -> { - // to be handled by FragmentManager - // playlistDialog.setOnDismissListener(dialog ->finish()); - - final FragmentManager fm = getSupportFragmentManager(); - playlistDialog.show(fm, "addToPlaylistDialog"); - fm.executePendingTransactions(); - } - ), - throwable -> handleError(this, new ErrorInfo( - throwable, - UserAction.REQUESTED_STREAM, - "Tried to add " + currentUrl + " to a playlist", - currentService.getServiceId()) - ) - ) - ); + getPersistFragment().openAddToPlaylistDialog(currentServiceId, currentUrl); } - @SuppressLint("CheckResult") private void openDownloadDialog() { pleaseWait(); - disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(result -> { - final DownloadDialog downloadDialog = new DownloadDialog(this, result); - // to be handled by FragmentManager since listener would be gone when recreated - // playlistDialog.setOnDismissListener(dialog ->finish()); - - final FragmentManager fm = getSupportFragmentManager(); - downloadDialog.show(fm, "downloadDialog"); - fm.executePendingTransactions(); - }, throwable -> showUnsupportedUrlDialog(currentUrl))); + getPersistFragment().openDownloadDialog(currentServiceId, currentUrl); } - private void pleaseWait() { + private PersistentFragment getPersistFragment() { + final FragmentManager fm = getSupportFragmentManager(); + PersistentFragment persistFragment = + (PersistentFragment) fm.findFragmentByTag("PERSIST_FRAGMENT"); + if (persistFragment == null) { + persistFragment = new PersistentFragment(); + fm.beginTransaction() + .add(persistFragment, "PERSIST_FRAGMENT") + .commitNow(); + } + return persistFragment; + } + + protected void pleaseWait() { // Getting the stream info usually takes a moment // Notifying the user here to ensure that no confusion arises Toast.makeText( From de7057ac3a6f188a9c54348432330b01b9d4b087 Mon Sep 17 00:00:00 2001 From: devlearner Date: Fri, 2 Dec 2022 17:31:01 +0000 Subject: [PATCH 26/84] Skip REORDER_TO_FRONT trick which doesn't seem to work on newer Androids probably due to background restrictions on Android 10+ --- app/src/main/java/org/schabi/newpipe/RouterActivity.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index e61f1f738..1a33c0ca4 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -10,6 +10,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; import android.text.TextUtils; import android.view.ContextThemeWrapper; @@ -776,7 +777,10 @@ public class RouterActivity extends AppCompatActivity { } if (isPaused) { buffer.add(runnable); - if (!getActivityContext().isChangingConfigurations()) { + // this trick doesn't seem to work on Android 10+ (API 29) + // which places restrictions on starting activities from the background + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q + && !getActivityContext().isChangingConfigurations()) { // try to bring the activity back to front if minimised final Intent i = new Intent(getActivityContext(), RouterActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); From c744f6756b75814243fae93924ea7fc62b0d885e Mon Sep 17 00:00:00 2001 From: devlearner Date: Fri, 2 Dec 2022 17:41:43 +0000 Subject: [PATCH 27/84] Fix Sonar reported code smell --- app/src/main/java/org/schabi/newpipe/RouterActivity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 1a33c0ca4..432bbcdaa 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -758,10 +758,10 @@ public class RouterActivity extends AppCompatActivity { while (buffer.size() > 0) { final ResultRunnable runnable = buffer.elementAt(0); buffer.removeElementAt(0); - getActivityContext().runOnUiThread(() -> { + getActivityContext().runOnUiThread(() -> // execute queued task with new context, in case activity has been recreated - runnable.run(getActivityContext()); - }); + runnable.run(getActivityContext()) + ); } done(); } From 61da167b4f52d0732d23396c8d131faeb596f5af Mon Sep 17 00:00:00 2001 From: devlearner Date: Sat, 3 Dec 2022 13:23:36 +0800 Subject: [PATCH 28/84] Oops, added back missing return; --- app/src/main/java/org/schabi/newpipe/RouterActivity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 432bbcdaa..dc7c8a77e 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -751,6 +751,7 @@ public class RouterActivity extends AppCompatActivity { private void playback() { if (activityGone()) { done(); + return; } if (buffer.size() == 0 || isPaused) { return; @@ -774,6 +775,7 @@ public class RouterActivity extends AppCompatActivity { private void runOnVisible(final ResultRunnable runnable) { if (activityGone()) { done(); + return; } if (isPaused) { buffer.add(runnable); From 40442f3f828e449dbbc4795f84756ddf43c528ea Mon Sep 17 00:00:00 2001 From: devlearner Date: Wed, 7 Dec 2022 13:43:27 +0000 Subject: [PATCH 29/84] Utilize Lifecycle observer I thought it would have required an extra dependency; apparently that doesn't seem to be the case... --- .../org/schabi/newpipe/RouterActivity.java | 103 ++++++++---------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index dc7c8a77e..87d402654 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -36,6 +36,9 @@ import androidx.core.math.MathUtils; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.DefaultLifecycleObserver; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleOwner; import androidx.preference.PreferenceManager; import org.schabi.newpipe.database.stream.model.StreamEntity; @@ -88,7 +91,6 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Vector; import icepick.Icepick; import icepick.State; @@ -213,6 +215,7 @@ public class RouterActivity extends AppCompatActivity { if (dismissListener != null) { getSupportFragmentManager().unregisterFragmentLifecycleCallbacks(dismissListener); } + disposables.clear(); } @@ -699,9 +702,20 @@ public class RouterActivity extends AppCompatActivity { public static class PersistentFragment extends Fragment { private WeakReference context; - private boolean isPaused = true; - private final Vector buffer = new Vector<>(); private final CompositeDisposable disposables = new CompositeDisposable(); + private int running = 0; + + private synchronized void inFlight(final boolean started) { + if (started) { + running++; + } else { + running--; + if (running <= 0 && getActivityContext() != null) { + getActivityContext().getSupportFragmentManager() + .beginTransaction().remove(this).commit(); + } + } + } public interface ResultRunnable { void run(AppCompatActivity context); @@ -726,59 +740,44 @@ public class RouterActivity extends AppCompatActivity { disposables.clear(); } - @Override - public void onPause() { - isPaused = true; - super.onPause(); - } - - @Override - public void onResume() { - isPaused = false; - playback(); - super.onResume(); - } - private AppCompatActivity getActivityContext() { return context == null ? null : context.get(); } + private boolean activityGone() { + return getActivityContext() == null || getActivityContext().isFinishing(); + } + // guard against IllegalStateException in calling DialogFragment.show() whilst in background // (which could happen, say, when the user pressed the home button while waiting for // the network request to return) when it internally calls FragmentTransaction.commit() // after the FragmentManager has saved its states (isStateSaved() == true) // (ref: https://stackoverflow.com/a/39813506) - private void playback() { - if (activityGone()) { - done(); - return; - } - if (buffer.size() == 0 || isPaused) { - return; - } - while (buffer.size() > 0) { - final ResultRunnable runnable = buffer.elementAt(0); - buffer.removeElementAt(0); - getActivityContext().runOnUiThread(() -> - // execute queued task with new context, in case activity has been recreated - runnable.run(getActivityContext()) - ); - } - done(); - } - private boolean activityGone() { - return getActivityContext() == null || getActivityContext().isFinishing(); - } - - // a DefaultLifecycleObserver is probably a good candidate here, but for now - // let's stick with a vanilla approach to avoid pulling in an extra artifact just for this private void runOnVisible(final ResultRunnable runnable) { if (activityGone()) { - done(); + inFlight(false); return; } - if (isPaused) { - buffer.add(runnable); + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { + getActivityContext().runOnUiThread(() -> { + runnable.run(getActivityContext()); + inFlight(false); + }); + } else { + getLifecycle().addObserver(new DefaultLifecycleObserver() { + @Override + public void onResume(@NonNull final LifecycleOwner owner) { + getLifecycle().removeObserver(this); + if (activityGone()) { + inFlight(false); + return; + } + getActivityContext().runOnUiThread(() -> { + runnable.run(getActivityContext()); + inFlight(false); + }); + } + }); // this trick doesn't seem to work on Android 10+ (API 29) // which places restrictions on starting activities from the background if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q @@ -788,23 +787,12 @@ public class RouterActivity extends AppCompatActivity { i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(i); } - } else { - getActivityContext().runOnUiThread(() -> { - runnable.run(getActivityContext()); - done(); - }); - } - } - - private void done() { - if (getActivityContext() != null) { - getActivityContext().getSupportFragmentManager() - .beginTransaction().remove(this).commit(); } } @SuppressLint("CheckResult") - protected void openDownloadDialog(final int currentServiceId, final String currentUrl) { + private void openDownloadDialog(final int currentServiceId, final String currentUrl) { + inFlight(true); disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -820,6 +808,7 @@ public class RouterActivity extends AppCompatActivity { } private void openAddToPlaylistDialog(final int currentServiceId, final String currentUrl) { + inFlight(true); disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -870,7 +859,7 @@ public class RouterActivity extends AppCompatActivity { return persistFragment; } - protected void pleaseWait() { + private void pleaseWait() { // Getting the stream info usually takes a moment // Notifying the user here to ensure that no confusion arises Toast.makeText( From 28109fef38b2f00a8759cd34ad1473af83db50bf Mon Sep 17 00:00:00 2001 From: devlearner Date: Sun, 11 Dec 2022 18:10:00 +0000 Subject: [PATCH 30/84] Improve showing of toast We provide visual feedback via a toast to the user that, well, they're supposed to wait; but with the benefit of the cache openAddToPlaylistDialog() may return (almost) immediately, which would render the toast otiose (if not a bit confusing). This commit improves that by cancelling the toast once the wait's over ... (by 'abusing' RxJava's ambWith(); ref on compose() and Transformer: https://blog.danlew.net/2015/03/02/dont-break-the-chain/ and for me, first time laying my hands at RxJava so kindly bear with me; open for suggestions) --- .../org/schabi/newpipe/RouterActivity.java | 57 ++++++++++++------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 87d402654..d660b6f3d 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -97,6 +97,7 @@ import icepick.State; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.core.SingleTransformer; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.functions.Consumer; @@ -790,12 +791,32 @@ public class RouterActivity extends AppCompatActivity { } } + SingleTransformer pleaseWait() { + return single -> single + // 'abuse' ambWith() here to cancel the toast for us when the wait is over + .ambWith(Single.create(emitter -> { + if (!activityGone()) { + getActivityContext().runOnUiThread(() -> { + // Getting the stream info usually takes a moment + // Notifying the user here to ensure that no confusion arises + final Toast t = Toast.makeText( + getActivityContext().getApplicationContext(), + getString(R.string.processing_may_take_a_moment), + Toast.LENGTH_LONG); + t.show(); + emitter.setCancellable(t::cancel); + }); + } + })); + } + @SuppressLint("CheckResult") private void openDownloadDialog(final int currentServiceId, final String currentUrl) { inFlight(true); disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) + .compose(pleaseWait()) .subscribe(result -> runOnVisible(ctx -> { final FragmentManager fm = ctx.getSupportFragmentManager(); @@ -812,17 +833,23 @@ public class RouterActivity extends AppCompatActivity { disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) + .compose(pleaseWait()) .subscribe( - info -> runOnVisible(ctx -> + info -> { + if (!activityGone()) { PlaylistDialog.createCorrespondingDialog( - ((RouterActivity) ctx).getThemeWrapperContext(), + getActivityContext(), List.of(new StreamEntity(info)), - playlistDialog -> { - // dismiss listener to be handled by FragmentManager - final FragmentManager fm = ctx.getSupportFragmentManager(); - playlistDialog.show(fm, "addToPlaylistDialog"); - } - )), + playlistDialog -> + runOnVisible(ctx -> { + // dismiss listener to be handled by FragmentManager + final FragmentManager fm = + ctx.getSupportFragmentManager(); + playlistDialog.show(fm, "addToPlaylistDialog"); + }) + ); + } + }, throwable -> runOnVisible(ctx -> handleError(ctx, new ErrorInfo( throwable, UserAction.REQUESTED_STREAM, @@ -835,14 +862,10 @@ public class RouterActivity extends AppCompatActivity { } private void openAddToPlaylistDialog() { - pleaseWait(); - getPersistFragment().openAddToPlaylistDialog(currentServiceId, currentUrl); } private void openDownloadDialog() { - pleaseWait(); - getPersistFragment().openDownloadDialog(currentServiceId, currentUrl); } @@ -859,16 +882,6 @@ public class RouterActivity extends AppCompatActivity { return persistFragment; } - private void pleaseWait() { - // Getting the stream info usually takes a moment - // Notifying the user here to ensure that no confusion arises - Toast.makeText( - getApplicationContext(), - getString(R.string.processing_may_take_a_moment), - Toast.LENGTH_LONG) - .show(); - } - @Override public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, From 944e295ae70a9641c43494b7fda1ce340cb28589 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 11 Jan 2023 15:08:10 +0100 Subject: [PATCH 31/84] Use Optional for simpler code --- .../org/schabi/newpipe/RouterActivity.java | 160 +++++++++--------- 1 file changed, 77 insertions(+), 83 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index d660b6f3d..010f35bc3 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -91,16 +91,16 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; import icepick.Icepick; import icepick.State; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; -import io.reactivex.rxjava3.core.SingleTransformer; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; -import io.reactivex.rxjava3.functions.Consumer; import io.reactivex.rxjava3.schedulers.Schedulers; /** @@ -702,7 +702,7 @@ public class RouterActivity extends AppCompatActivity { } public static class PersistentFragment extends Fragment { - private WeakReference context; + private WeakReference weakContext; private final CompositeDisposable disposables = new CompositeDisposable(); private int running = 0; @@ -711,21 +711,23 @@ public class RouterActivity extends AppCompatActivity { running++; } else { running--; - if (running <= 0 && getActivityContext() != null) { - getActivityContext().getSupportFragmentManager() - .beginTransaction().remove(this).commit(); + if (running <= 0) { + getActivityContext().ifPresent(context -> context.getSupportFragmentManager() + .beginTransaction().remove(this).commit()); } } } - public interface ResultRunnable { - void run(AppCompatActivity context); - } - @Override public void onAttach(@NonNull final Context activityContext) { super.onAttach(activityContext); - context = new WeakReference<>((AppCompatActivity) activityContext); + weakContext = new WeakReference<>((AppCompatActivity) activityContext); + } + + @Override + public void onDetach() { + super.onDetach(); + weakContext = null; } @SuppressWarnings("deprecation") @@ -741,12 +743,13 @@ public class RouterActivity extends AppCompatActivity { disposables.clear(); } - private AppCompatActivity getActivityContext() { - return context == null ? null : context.get(); - } - - private boolean activityGone() { - return getActivityContext() == null || getActivityContext().isFinishing(); + /** + * @return the activity context, if there is one and the activity is not finishing + */ + private Optional getActivityContext() { + return Optional.ofNullable(weakContext) + .flatMap(context -> Optional.ofNullable(context.get())) + .filter(context -> !context.isFinishing()); } // guard against IllegalStateException in calling DialogFragment.show() whilst in background @@ -754,60 +757,56 @@ public class RouterActivity extends AppCompatActivity { // the network request to return) when it internally calls FragmentTransaction.commit() // after the FragmentManager has saved its states (isStateSaved() == true) // (ref: https://stackoverflow.com/a/39813506) - private void runOnVisible(final ResultRunnable runnable) { - if (activityGone()) { - inFlight(false); - return; - } - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { - getActivityContext().runOnUiThread(() -> { - runnable.run(getActivityContext()); - inFlight(false); - }); - } else { - getLifecycle().addObserver(new DefaultLifecycleObserver() { - @Override - public void onResume(@NonNull final LifecycleOwner owner) { - getLifecycle().removeObserver(this); - if (activityGone()) { - inFlight(false); - return; + private void runOnVisible(final Consumer runnable) { + getActivityContext().ifPresentOrElse(context -> { + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { + context.runOnUiThread(() -> { + runnable.accept(context); + inFlight(false); + }); + } else { + getLifecycle().addObserver(new DefaultLifecycleObserver() { + @Override + public void onResume(@NonNull final LifecycleOwner owner) { + getLifecycle().removeObserver(this); + getActivityContext().ifPresentOrElse(context -> + context.runOnUiThread(() -> { + runnable.accept(context); + inFlight(false); + }), + () -> inFlight(false) + ); } - getActivityContext().runOnUiThread(() -> { - runnable.run(getActivityContext()); - inFlight(false); - }); + }); + // this trick doesn't seem to work on Android 10+ (API 29) + // which places restrictions on starting activities from the background + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q + && !context.isChangingConfigurations()) { + // try to bring the activity back to front if minimised + final Intent i = new Intent(context, RouterActivity.class); + i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + startActivity(i); } - }); - // this trick doesn't seem to work on Android 10+ (API 29) - // which places restrictions on starting activities from the background - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q - && !getActivityContext().isChangingConfigurations()) { - // try to bring the activity back to front if minimised - final Intent i = new Intent(getActivityContext(), RouterActivity.class); - i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - startActivity(i); } - } + + }, () -> { + // this branch is executed if there is no activity context + inFlight(false); + }); } - SingleTransformer pleaseWait() { - return single -> single - // 'abuse' ambWith() here to cancel the toast for us when the wait is over - .ambWith(Single.create(emitter -> { - if (!activityGone()) { - getActivityContext().runOnUiThread(() -> { - // Getting the stream info usually takes a moment - // Notifying the user here to ensure that no confusion arises - final Toast t = Toast.makeText( - getActivityContext().getApplicationContext(), - getString(R.string.processing_may_take_a_moment), - Toast.LENGTH_LONG); - t.show(); - emitter.setCancellable(t::cancel); - }); - } - })); + Single pleaseWait(final Single single) { + // 'abuse' ambWith() here to cancel the toast for us when the wait is over + return single.ambWith(Single.create(emitter -> getActivityContext().ifPresent(context -> + context.runOnUiThread(() -> { + // Getting the stream info usually takes a moment + // Notifying the user here to ensure that no confusion arises + final Toast toast = Toast.makeText(context, + getString(R.string.processing_may_take_a_moment), + Toast.LENGTH_LONG); + toast.show(); + emitter.setCancellable(toast::cancel); + })))); } @SuppressLint("CheckResult") @@ -816,7 +815,7 @@ public class RouterActivity extends AppCompatActivity { disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .compose(pleaseWait()) + .compose(this::pleaseWait) .subscribe(result -> runOnVisible(ctx -> { final FragmentManager fm = ctx.getSupportFragmentManager(); @@ -833,23 +832,18 @@ public class RouterActivity extends AppCompatActivity { disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .compose(pleaseWait()) + .compose(this::pleaseWait) .subscribe( - info -> { - if (!activityGone()) { - PlaylistDialog.createCorrespondingDialog( - getActivityContext(), - List.of(new StreamEntity(info)), - playlistDialog -> - runOnVisible(ctx -> { - // dismiss listener to be handled by FragmentManager - final FragmentManager fm = - ctx.getSupportFragmentManager(); - playlistDialog.show(fm, "addToPlaylistDialog"); - }) - ); - } - }, + info -> getActivityContext().ifPresent(context -> + PlaylistDialog.createCorrespondingDialog(context, + List.of(new StreamEntity(info)), + playlistDialog -> runOnVisible(ctx -> { + // dismiss listener to be handled by FragmentManager + final FragmentManager fm = + ctx.getSupportFragmentManager(); + playlistDialog.show(fm, "addToPlaylistDialog"); + }) + )), throwable -> runOnVisible(ctx -> handleError(ctx, new ErrorInfo( throwable, UserAction.REQUESTED_STREAM, From ad605e2c5a38e57af1b0ec7d4c991a9a9240dfff Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 11 Jan 2023 15:26:46 +0100 Subject: [PATCH 32/84] Actually there is no need to use flatMap `null` values returned in the lambda are converted to empty `Optional`s in the `map` method: https://developer.android.com/reference/java/util/Optional#map(java.util.function.Function%3C?%20super%20T,%20?%20extends%20U%3E) --- app/src/main/java/org/schabi/newpipe/RouterActivity.java | 3 ++- .../schabi/newpipe/fragments/detail/VideoDetailFragment.java | 2 +- .../org/schabi/newpipe/player/mediaitem/MediaItemTag.java | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 010f35bc3..2567df993 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -87,6 +87,7 @@ import org.schabi.newpipe.util.urlfinder.UrlFinder; import org.schabi.newpipe.views.FocusOverlayView; import java.io.Serializable; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; @@ -748,7 +749,7 @@ public class RouterActivity extends AppCompatActivity { */ private Optional getActivityContext() { return Optional.ofNullable(weakContext) - .flatMap(context -> Optional.ofNullable(context.get())) + .map(Reference::get) .filter(context -> !context.isFinishing()); } 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 1fb6b5859..601135cbb 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 @@ -1887,7 +1887,7 @@ public final class VideoDetailFragment setupBrightness(); if (!isPlayerAndPlayerServiceAvailable() || player.UIs().get(MainPlayerUi.class).isEmpty() - || getRoot().flatMap(v -> Optional.ofNullable(v.getParent())).isEmpty()) { + || getRoot().map(View::getParent).isEmpty()) { return; } diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java index 4f808caac..f08086287 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java @@ -62,8 +62,8 @@ public interface MediaItemTag { @NonNull static Optional from(@Nullable final MediaItem mediaItem) { return Optional.ofNullable(mediaItem) - .flatMap(item -> Optional.ofNullable(item.localConfiguration)) - .flatMap(localConfiguration -> Optional.ofNullable(localConfiguration.tag)) + .map(item -> item.localConfiguration) + .map(localConfiguration -> localConfiguration.tag) .filter(MediaItemTag.class::isInstance) .map(MediaItemTag.class::cast); } From 0a64eac7783fa8127b9a14781e14b2846384ab36 Mon Sep 17 00:00:00 2001 From: ge78fug Date: Wed, 11 Jan 2023 16:06:11 +0100 Subject: [PATCH 33/84] Added the "What's New"-section to the default tabs --- .../java/org/schabi/newpipe/settings/tabs/TabsJsonHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsJsonHelper.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsJsonHelper.java index 32f25ccbd..30676477c 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsJsonHelper.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsJsonHelper.java @@ -20,6 +20,7 @@ public final class TabsJsonHelper { private static final List FALLBACK_INITIAL_TABS_LIST = List.of( Tab.Type.DEFAULT_KIOSK.getTab(), + Tab.Type.FEED.getTab(), Tab.Type.SUBSCRIPTIONS.getTab(), Tab.Type.BOOKMARKS.getTab()); From 2afbe58722215494e5eea8de148cd42d8970715e Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 11 Jan 2023 19:45:55 +0100 Subject: [PATCH 34/84] UX improvements: keep user edits & do not reset cursor --- .../newpipe/download/DownloadDialog.java | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) 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 77bb48a81..208d27bb2 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -75,6 +75,7 @@ import java.io.IOException; import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.Optional; import icepick.Icepick; import icepick.State; @@ -566,19 +567,34 @@ public class DownloadDialog extends DialogFragment } private void onItemSelectedSetFileName() { - final String fileName = FilenameUtils.createFilename(getContext(), - currentInfo.getName()); - switch (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()) { - case R.id.audio_button: - case R.id.video_button: - dialogBinding.fileName.setText(fileName); - break; - case R.id.subtitle_button: - final String setSubtitleLanguageCode = subtitleStreamsAdapter - .getItem(selectedSubtitleIndex).getLanguageTag(); - dialogBinding.fileName.setText(getString( - R.string.caption_file_name, fileName, setSubtitleLanguageCode)); - break; + final String fileName = FilenameUtils.createFilename(getContext(), currentInfo.getName()); + final String prevFileName = Optional.ofNullable(dialogBinding.fileName.getText()) + .map(Object::toString) + .orElse(""); + + if (prevFileName.isEmpty() + || prevFileName.equals(fileName) + || prevFileName.startsWith(getString(R.string.caption_file_name, fileName, ""))) { + // only update the file name field if it was not edited by the user + + switch (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()) { + case R.id.audio_button: + case R.id.video_button: + if (!prevFileName.equals(fileName)) { + // since the user might have switched between audio and video, the correct + // text might already be in place, so avoid resetting the cursor position + dialogBinding.fileName.setText(fileName); + } + break; + + case R.id.subtitle_button: + final String setSubtitleLanguageCode = subtitleStreamsAdapter + .getItem(selectedSubtitleIndex).getLanguageTag(); + // this will reset the cursor position, which is bad UX, but it can't be avoided + dialogBinding.fileName.setText(getString( + R.string.caption_file_name, fileName, setSubtitleLanguageCode)); + break; + } } } From b6e6d39985b34ac318258ce5e894ae06abf51208 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 12 Jan 2023 11:39:25 +0100 Subject: [PATCH 35/84] Fix toast crash on API 33 You shouldn't call getView() on toasts. Also simplified some duplicate code. --- .../org/schabi/newpipe/RouterActivity.java | 3 +- .../fragments/detail/VideoDetailFragment.java | 3 +- .../newpipe/player/PlayQueueActivity.java | 4 +-- .../schabi/newpipe/util/NavigationHelper.java | 6 ++-- .../schabi/newpipe/util/PermissionHelper.java | 29 ++++++++++--------- 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 2567df993..e9c19a22d 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -631,8 +631,7 @@ public class RouterActivity extends AppCompatActivity { } if (selectedChoiceKey.equals(getString(R.string.popup_player_key)) - && !PermissionHelper.isPopupEnabled(this)) { - PermissionHelper.showPopupEnablementToast(this); + && !PermissionHelper.isPopupEnabledElseAsk(this)) { finish(); return; } 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 601135cbb..6f4439ee9 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 @@ -1066,8 +1066,7 @@ public final class VideoDetailFragment } private void openPopupPlayer(final boolean append) { - if (!PermissionHelper.isPopupEnabled(activity)) { - PermissionHelper.showPopupEnablementToast(activity); + if (!PermissionHelper.isPopupEnabledElseAsk(activity)) { return; } diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java index 94de7fef3..9ce99c15b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java @@ -143,11 +143,9 @@ public final class PlayQueueActivity extends AppCompatActivity NavigationHelper.playOnMainPlayer(this, player.getPlayQueue(), true); return true; case R.id.action_switch_popup: - if (PermissionHelper.isPopupEnabled(this)) { + if (PermissionHelper.isPopupEnabledElseAsk(this)) { this.player.setRecovery(); NavigationHelper.playOnPopupPlayer(this, player.getPlayQueue(), true); - } else { - PermissionHelper.showPopupEnablementToast(this); } return true; case R.id.action_switch_background: 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 483f5067a..b4556507c 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -156,8 +156,7 @@ public final class NavigationHelper { public static void playOnPopupPlayer(final Context context, final PlayQueue queue, final boolean resumePlayback) { - if (!PermissionHelper.isPopupEnabled(context)) { - PermissionHelper.showPopupEnablementToast(context); + if (!PermissionHelper.isPopupEnabledElseAsk(context)) { return; } @@ -183,8 +182,7 @@ public final class NavigationHelper { public static void enqueueOnPlayer(final Context context, final PlayQueue queue, final PlayerType playerType) { - if ((playerType == PlayerType.POPUP) && !PermissionHelper.isPopupEnabled(context)) { - PermissionHelper.showPopupEnablementToast(context); + if (playerType == PlayerType.POPUP && !PermissionHelper.isPopupEnabledElseAsk(context)) { return; } diff --git a/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java b/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java index f47494770..55193599e 100644 --- a/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java @@ -9,8 +9,6 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.provider.Settings; -import android.view.Gravity; -import android.widget.TextView; import android.widget.Toast; import androidx.annotation.RequiresApi; @@ -128,18 +126,21 @@ public final class PermissionHelper { } } - public static boolean isPopupEnabled(final Context context) { - return Build.VERSION.SDK_INT < Build.VERSION_CODES.M - || checkSystemAlertWindowPermission(context); - } - - public static void showPopupEnablementToast(final Context context) { - final Toast toast = - Toast.makeText(context, R.string.msg_popup_permission, Toast.LENGTH_LONG); - final TextView messageView = toast.getView().findViewById(android.R.id.message); - if (messageView != null) { - messageView.setGravity(Gravity.CENTER); + /** + * Determines whether the popup is enabled, and if it is not, starts the system activity to + * request the permission with {@link #checkSystemAlertWindowPermission(Context)} and shows a + * toast to the user explaining why the permission is needed. + * + * @param context the Android context + * @return whether the popup is enabled + */ + public static boolean isPopupEnabledElseAsk(final Context context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M + || checkSystemAlertWindowPermission(context)) { + return true; + } else { + Toast.makeText(context, R.string.msg_popup_permission, Toast.LENGTH_LONG).show(); + return false; } - toast.show(); } } From 9514316be3f392f6cd84b94af6d68f4650707486 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 27 Aug 2022 11:55:31 +0530 Subject: [PATCH 36/84] Remove Runnable variables for Handlers. --- .../gesture/BasePlayerGestureListener.kt | 22 +++++++------ .../giga/ui/adapter/MissionAdapter.java | 19 ++++++----- .../us/shandian/giga/ui/common/Deleter.java | 33 +++++++++---------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/gesture/BasePlayerGestureListener.kt b/app/src/main/java/org/schabi/newpipe/player/gesture/BasePlayerGestureListener.kt index 555c34f96..0453f297a 100644 --- a/app/src/main/java/org/schabi/newpipe/player/gesture/BasePlayerGestureListener.kt +++ b/app/src/main/java/org/schabi/newpipe/player/gesture/BasePlayerGestureListener.kt @@ -6,6 +6,7 @@ import android.util.Log import android.view.GestureDetector import android.view.MotionEvent import android.view.View +import androidx.core.os.postDelayed import org.schabi.newpipe.databinding.PlayerBinding import org.schabi.newpipe.player.Player import org.schabi.newpipe.player.ui.VideoPlayerUi @@ -132,13 +133,6 @@ abstract class BasePlayerGestureListener( private var doubleTapDelay = DOUBLE_TAP_DELAY private val doubleTapHandler: Handler = Handler(Looper.getMainLooper()) - private val doubleTapRunnable = Runnable { - if (DEBUG) - Log.d(TAG, "doubleTapRunnable called") - - isDoubleTapping = false - doubleTapControls?.onDoubleTapFinished() - } private fun startMultiDoubleTap(e: MotionEvent) { if (!isDoubleTapping) { @@ -155,8 +149,15 @@ abstract class BasePlayerGestureListener( Log.d(TAG, "keepInDoubleTapMode called") isDoubleTapping = true - doubleTapHandler.removeCallbacks(doubleTapRunnable) - doubleTapHandler.postDelayed(doubleTapRunnable, doubleTapDelay) + doubleTapHandler.removeCallbacksAndMessages(DOUBLE_TAP) + doubleTapHandler.postDelayed(DOUBLE_TAP_DELAY, DOUBLE_TAP) { + if (DEBUG) { + Log.d(TAG, "doubleTapRunnable called") + } + + isDoubleTapping = false + doubleTapControls?.onDoubleTapFinished() + } } fun endMultiDoubleTap() { @@ -164,7 +165,7 @@ abstract class BasePlayerGestureListener( Log.d(TAG, "endMultiDoubleTap called") isDoubleTapping = false - doubleTapHandler.removeCallbacks(doubleTapRunnable) + doubleTapHandler.removeCallbacksAndMessages(DOUBLE_TAP) doubleTapControls?.onDoubleTapFinished() } @@ -181,6 +182,7 @@ abstract class BasePlayerGestureListener( private const val TAG = "BasePlayerGestListener" private val DEBUG = Player.DEBUG + private const val DOUBLE_TAP = "doubleTap" private const val DOUBLE_TAP_DELAY = 550L } } diff --git a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java index 26eb2f3b0..bfb6a15e2 100644 --- a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java +++ b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java @@ -48,6 +48,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; import androidx.core.content.FileProvider; +import androidx.core.os.HandlerCompat; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.Adapter; @@ -91,6 +92,10 @@ public class MissionAdapter extends Adapter implements Handler.Callb private static final String UNDEFINED_PROGRESS = "--.-%"; private static final String DEFAULT_MIME_TYPE = "*/*"; private static final String UNDEFINED_ETA = "--:--"; + + private static final String UPDATER = "updater"; + private static final String DELETE = "deleteFinishedDownloads"; + private static final int HASH_NOTIFICATION_ID = 123790; private final Context mContext; @@ -110,9 +115,6 @@ public class MissionAdapter extends Adapter implements Handler.Callb private final ArrayList mHidden; private Snackbar mSnackbar; - private final Runnable rUpdater = this::updater; - private final Runnable rDelete = this::deleteFinishedDownloads; - private final CompositeDisposable compositeDisposable = new CompositeDisposable(); public MissionAdapter(Context context, @NonNull DownloadManager downloadManager, View emptyMessage, View root) { @@ -595,12 +597,12 @@ public class MissionAdapter extends Adapter implements Handler.Callb i.remove(); } applyChanges(); - mHandler.removeCallbacks(rDelete); + mHandler.removeCallbacksAndMessages(DELETE); }); mSnackbar.setActionTextColor(Color.YELLOW); mSnackbar.show(); - mHandler.postDelayed(rDelete, 5000); + HandlerCompat.postDelayed(mHandler, this::deleteFinishedDownloads, DELETE, 5000); } else if (!delete) { mDownloadManager.forgetFinishedDownloads(); applyChanges(); @@ -786,15 +788,14 @@ public class MissionAdapter extends Adapter implements Handler.Callb public void onResume() { mDeleter.resume(); - mHandler.post(rUpdater); + HandlerCompat.postDelayed(mHandler, this::updater, UPDATER, 0); } public void onPaused() { mDeleter.pause(); - mHandler.removeCallbacks(rUpdater); + mHandler.removeCallbacksAndMessages(UPDATER); } - public void recoverMission(DownloadMission mission) { ViewHolderItem h = getViewHolder(mission); if (h == null) return; @@ -817,7 +818,7 @@ public class MissionAdapter extends Adapter implements Handler.Callb updateProgress(h); } - mHandler.postDelayed(rUpdater, 1000); + HandlerCompat.postDelayed(mHandler, this::updater, UPDATER, 1000); } private boolean isNotFinite(double value) { diff --git a/app/src/main/java/us/shandian/giga/ui/common/Deleter.java b/app/src/main/java/us/shandian/giga/ui/common/Deleter.java index c554766ff..1902076d6 100644 --- a/app/src/main/java/us/shandian/giga/ui/common/Deleter.java +++ b/app/src/main/java/us/shandian/giga/ui/common/Deleter.java @@ -6,6 +6,8 @@ import android.graphics.Color; import android.os.Handler; import android.view.View; +import androidx.core.os.HandlerCompat; + import com.google.android.material.snackbar.Snackbar; import org.schabi.newpipe.R; @@ -19,6 +21,10 @@ import us.shandian.giga.service.DownloadManager.MissionIterator; import us.shandian.giga.ui.adapter.MissionAdapter; public class Deleter { + private static final String COMMIT = "commit"; + private static final String NEXT = "next"; + private static final String SHOW = "show"; + private static final int TIMEOUT = 5000;// ms private static final int DELAY = 350;// ms private static final int DELAY_RESUME = 400;// ms @@ -34,10 +40,6 @@ public class Deleter { private final Handler mHandler; private final View mView; - private final Runnable rShow; - private final Runnable rNext; - private final Runnable rCommit; - public Deleter(View v, Context c, MissionAdapter a, DownloadManager d, MissionIterator i, Handler h) { mView = v; mContext = c; @@ -46,21 +48,15 @@ public class Deleter { mIterator = i; mHandler = h; - // use variables to know the reference of the lambdas - rShow = this::show; - rNext = this::next; - rCommit = this::commit; - items = new ArrayList<>(2); } public void append(Mission item) { - /* If a mission is removed from the list while the Snackbar for a previously * removed item is still showing, commit the action for the previous item * immediately. This prevents Snackbars from stacking up in reverse order. */ - mHandler.removeCallbacks(rCommit); + mHandler.removeCallbacksAndMessages(COMMIT); commit(); mIterator.hide(item); @@ -82,7 +78,7 @@ public class Deleter { pause(); running = true; - mHandler.postDelayed(rNext, DELAY); + HandlerCompat.postDelayed(mHandler, this::next, NEXT, DELAY); } private void next() { @@ -95,7 +91,7 @@ public class Deleter { snackbar.setActionTextColor(Color.YELLOW); snackbar.show(); - mHandler.postDelayed(rCommit, TIMEOUT); + HandlerCompat.postDelayed(mHandler, this::commit, COMMIT, TIMEOUT); } private void commit() { @@ -124,15 +120,16 @@ public class Deleter { public void pause() { running = false; - mHandler.removeCallbacks(rNext); - mHandler.removeCallbacks(rShow); - mHandler.removeCallbacks(rCommit); + mHandler.removeCallbacksAndMessages(NEXT); + mHandler.removeCallbacksAndMessages(SHOW); + mHandler.removeCallbacksAndMessages(COMMIT); if (snackbar != null) snackbar.dismiss(); } public void resume() { - if (running) return; - mHandler.postDelayed(rShow, DELAY_RESUME); + if (!running) { + HandlerCompat.postDelayed(mHandler, this::show, SHOW, DELAY_RESUME); + } } public void dispose() { From 38c4a1ed859b67d753a81a4611e259dc65495769 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Tue, 22 Nov 2022 15:36:57 +0100 Subject: [PATCH 37/84] Fixed the "Remove Watched" bug Reverted changes and fixed bug in a different way --- .../local/playlist/LocalPlaylistFragment.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index d584ceefb..68a35e72b 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -404,7 +404,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment { // Remove Watched, Functionality data - final List notWatchedItems = new ArrayList<>(); + final List itemsToKeep = new ArrayList<>(); final boolean isThumbnailPermanent = playlistManager .getIsPlaylistThumbnailPermanent(playlistId); boolean thumbnailVideoRemoved = false; @@ -415,7 +415,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment(notWatchedItems, thumbnailVideoRemoved); + return new Pair<>(itemsToKeep, thumbnailVideoRemoved); }); disposables.add(streamsMaybe.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(flow -> { - final List notWatchedItems = flow.first; + final List itemsToKeep = flow.first; final boolean thumbnailVideoRemoved = flow.second; itemListAdapter.clearStreamItemList(); - itemListAdapter.addItems(notWatchedItems); + itemListAdapter.addItems(itemsToKeep); saveChanges(); if (thumbnailVideoRemoved) { From 5e3caf68a54b0b30808a31499049600800f6df39 Mon Sep 17 00:00:00 2001 From: ge78fug Date: Fri, 13 Jan 2023 16:33:45 +0100 Subject: [PATCH 38/84] Chenged the What's New icon --- app/src/main/java/org/schabi/newpipe/MainActivity.java | 2 +- .../schabi/newpipe/local/subscription/FeedGroupIcon.kt | 3 ++- .../newpipe/local/subscription/SubscriptionFragment.kt | 4 ++-- .../java/org/schabi/newpipe/settings/tabs/Tab.java | 2 +- app/src/main/res/drawable/ic_whats_new.xml | 10 ++++++++++ 5 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/drawable/ic_whats_new.xml diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 73a81450e..d05f3616d 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -235,7 +235,7 @@ public class MainActivity extends AppCompatActivity { .setIcon(R.drawable.ic_tv); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_feed_title) - .setIcon(R.drawable.ic_rss_feed); + .setIcon(R.drawable.ic_whats_new); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_BOOKMARKS, ORDER, R.string.tab_bookmarks) .setIcon(R.drawable.ic_bookmark); diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/FeedGroupIcon.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/FeedGroupIcon.kt index ac7197b48..23718fa53 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/FeedGroupIcon.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/FeedGroupIcon.kt @@ -51,7 +51,8 @@ enum class FeedGroupIcon( WORLD(34, R.drawable.ic_public), STAR(35, R.drawable.ic_stars), SUN(36, R.drawable.ic_wb_sunny), - RSS(37, R.drawable.ic_rss_feed); + RSS(37, R.drawable.ic_rss_feed), + WHATS_NEW(38, R.drawable.ic_whats_new); @DrawableRes fun getDrawableRes(): Int { diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index 9e1e19fff..7146a18d6 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -433,10 +433,10 @@ class SubscriptionFragment : BaseStateFragment() { clear() if (listViewMode) { add(FeedGroupAddNewItem()) - add(FeedGroupCardItem(GROUP_ALL_ID, getString(R.string.all), FeedGroupIcon.RSS)) + add(FeedGroupCardItem(GROUP_ALL_ID, getString(R.string.all), FeedGroupIcon.WHATS_NEW)) } else { add(FeedGroupAddNewGridItem()) - add(FeedGroupCardGridItem(GROUP_ALL_ID, getString(R.string.all), FeedGroupIcon.RSS)) + add(FeedGroupCardGridItem(GROUP_ALL_ID, getString(R.string.all), FeedGroupIcon.WHATS_NEW)) } addAll(groups) } diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java index 6b1d70a86..a08fe6ef6 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java @@ -248,7 +248,7 @@ public abstract class Tab { @DrawableRes @Override public int getTabIconRes(final Context context) { - return R.drawable.ic_rss_feed; + return R.drawable.ic_whats_new; } @Override diff --git a/app/src/main/res/drawable/ic_whats_new.xml b/app/src/main/res/drawable/ic_whats_new.xml new file mode 100644 index 000000000..f2ac7bec2 --- /dev/null +++ b/app/src/main/res/drawable/ic_whats_new.xml @@ -0,0 +1,10 @@ + + + From 223150aa423fdb988dbd3233f11770459d110c2d Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 14 Jan 2023 11:00:00 +0530 Subject: [PATCH 39/84] Update desugar_jdk_libs to 2.0.0. --- 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 6066bce43..79e07a190 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -179,7 +179,7 @@ sonar { dependencies { /** Desugaring **/ - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.0' /** 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 d2f1dc4c5..1384d0a9c 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.android.tools.build:gradle:7.4.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong From 31396a632fb1693a6413a30ed9f0c7fd15b37de7 Mon Sep 17 00:00:00 2001 From: ge78fug Date: Sat, 14 Jan 2023 09:21:37 +0100 Subject: [PATCH 40/84] Chenged the name of the icon --- app/src/main/java/org/schabi/newpipe/MainActivity.java | 2 +- .../java/org/schabi/newpipe/local/subscription/FeedGroupIcon.kt | 2 +- app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java | 2 +- .../res/drawable/{ic_whats_new.xml => ic_subscriptions.xml} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename app/src/main/res/drawable/{ic_whats_new.xml => ic_subscriptions.xml} (100%) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index d05f3616d..ee2bb3f05 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -235,7 +235,7 @@ public class MainActivity extends AppCompatActivity { .setIcon(R.drawable.ic_tv); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_feed_title) - .setIcon(R.drawable.ic_whats_new); + .setIcon(R.drawable.ic_subscriptions); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_BOOKMARKS, ORDER, R.string.tab_bookmarks) .setIcon(R.drawable.ic_bookmark); diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/FeedGroupIcon.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/FeedGroupIcon.kt index 23718fa53..1fa70e4d8 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/FeedGroupIcon.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/FeedGroupIcon.kt @@ -52,7 +52,7 @@ enum class FeedGroupIcon( STAR(35, R.drawable.ic_stars), SUN(36, R.drawable.ic_wb_sunny), RSS(37, R.drawable.ic_rss_feed), - WHATS_NEW(38, R.drawable.ic_whats_new); + WHATS_NEW(38, R.drawable.ic_subscriptions); @DrawableRes fun getDrawableRes(): Int { diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java index a08fe6ef6..7e3f5d0c8 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java @@ -248,7 +248,7 @@ public abstract class Tab { @DrawableRes @Override public int getTabIconRes(final Context context) { - return R.drawable.ic_whats_new; + return R.drawable.ic_subscriptions; } @Override diff --git a/app/src/main/res/drawable/ic_whats_new.xml b/app/src/main/res/drawable/ic_subscriptions.xml similarity index 100% rename from app/src/main/res/drawable/ic_whats_new.xml rename to app/src/main/res/drawable/ic_subscriptions.xml From fdfeac081ad9fe6094582d29a8df72d00e7d2271 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Mon, 5 Dec 2022 00:15:05 +0100 Subject: [PATCH 41/84] Implemented a warning before adding duplicate to playlist. --- .../playlist/dao/PlaylistStreamDAO.java | 11 +++++++ .../local/dialog/PlaylistAppendDialog.java | 32 ++++++++++++++++++- .../local/playlist/LocalPlaylistManager.java | 4 +++ app/src/main/res/values/strings.xml | 3 ++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index 2036dc205..911baf7f3 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -26,6 +26,7 @@ import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.PL import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_ID; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_THUMBNAIL_URL; +import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_URL; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID_ALIAS; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE; @@ -49,6 +50,16 @@ public interface PlaylistStreamDAO extends BasicDAO { + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") void deleteBatch(long playlistId); + @Query("SELECT COALESCE(COUNT(*), 0)" + + " FROM " + STREAM_TABLE + + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE + + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID + + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId " + + " AND " + STREAM_URL + " = :streamURL" + ) + Flowable getDuplicates(long playlistId, String streamURL); + + @Query("SELECT COALESCE(MAX(" + JOIN_INDEX + "), -1)" + " FROM " + PLAYLIST_STREAM_JOIN_TABLE + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 88dec3911..c80e919bf 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.local.dialog; +import android.app.AlertDialog; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -128,6 +129,19 @@ public final class PlaylistAppendDialog extends PlaylistDialog { private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager, @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { + + final int numOfDuplicates = manager.getPlaylistDuplicates(playlist.uid, + streams.get(0).getUrl()).blockingFirst(); + if (numOfDuplicates > 0) { + createDuplicateDialog(numOfDuplicates, manager, playlist, streams); + } else { + addStreamToPlaylist(manager, playlist, streams); + } + } + + private void addStreamToPlaylist(@NonNull final LocalPlaylistManager manager, + @NonNull final PlaylistMetadataEntry playlist, + @NonNull final List streams) { final Toast successToast = Toast.makeText(getContext(), R.string.playlist_add_stream_success, Toast.LENGTH_SHORT); @@ -142,7 +156,23 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistDisposables.add(manager.appendToPlaylist(playlist.uid, streams) .observeOn(AndroidSchedulers.mainThread()) .subscribe(ignored -> successToast.show())); - requireDialog().dismiss(); } + + private void createDuplicateDialog(final int duplicates, + @NonNull final LocalPlaylistManager manager, + @NonNull final PlaylistMetadataEntry playlist, + @NonNull final List streams) { + //TODO: change color + final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); + builder.setTitle(R.string.duplicate_stream_in_playlist_title); + builder.setMessage(getString(R.string.duplicate_stream_in_playlist_description, + duplicates)); + + builder.setPositiveButton(android.R.string.yes, (dialog, i) -> { + addStreamToPlaylist(manager, playlist, streams); + }); + builder.setNeutralButton(R.string.cancel, null); + builder.create().show(); + } } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index 4007d0e09..807c3c051 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -91,6 +91,10 @@ public class LocalPlaylistManager { return playlistStreamTable.getOrderedStreamsOf(playlistId).subscribeOn(Schedulers.io()); } + public Flowable getPlaylistDuplicates(final long playlistId, final String streamURL) { + return playlistStreamTable.getDuplicates(playlistId, streamURL); + } + public Single deletePlaylist(final long playlistId) { return Single.fromCallable(() -> playlistTable.deletePlaylist(playlistId)) .subscribeOn(Schedulers.io()); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c9e0bb492..5b398abd1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -447,6 +447,9 @@ Playlisted Playlist thumbnail changed. Auto-generated (no uploader found) + Duplicated Video Found + The playlist contains this stream + already %d time(s).\nDo you want to add it one more time? No Captions Fit From ac15339911a86399903c9bd974d6632c2b3088b6 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sat, 10 Dec 2022 13:15:49 +0100 Subject: [PATCH 42/84] Started working on a way to show that items are already in a playlist --- .../playlist/dao/PlaylistStreamDAO.java | 8 +++++ .../newpipe/local/LocalItemListAdapter.java | 11 +++++++ .../local/dialog/PlaylistAppendDialog.java | 32 ++++++++++++++++++- .../local/playlist/LocalPlaylistManager.java | 4 +++ .../res/layout/list_playlist_mini_item.xml | 12 +++++++ 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index 911baf7f3..a9719c9fa 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -59,6 +59,14 @@ public interface PlaylistStreamDAO extends BasicDAO { ) Flowable getDuplicates(long playlistId, String streamURL); + @Query("SELECT " + JOIN_PLAYLIST_ID + + " FROM " + STREAM_TABLE + + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE + + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID + + " WHERE " + STREAM_URL + " = :streamURL" + ) + Flowable> getDuplicatePlaylists(String streamURL); + @Query("SELECT COALESCE(MAX(" + JOIN_INDEX + "), -1)" + " FROM " + PLAYLIST_STREAM_JOIN_TABLE diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java index 05e2fdac0..93ea12b97 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java @@ -11,6 +11,7 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import org.schabi.newpipe.database.LocalItem; +import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.stream.model.StreamStateEntity; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.holder.LocalItemHolder; @@ -344,6 +345,16 @@ public class LocalItemListAdapter extends RecyclerView.Adapter { final List entities = getStreamEntities(); if (selectedItem instanceof PlaylistMetadataEntry && entities != null) { @@ -123,6 +125,35 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistAdapter.clearStreamItemList(); playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); + + final LocalPlaylistManager playlistManager = + new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); + final List duplicateIds = playlistManager.getDuplicatePlaylist(getStreamEntities() + .get(0).getUrl()).blockingFirst(); + + final HashMap map = new HashMap<>(); + for (int i = 0; i < playlists.size(); i++) { + map.put(i, playlists.get(i).uid); + } + + playlistRecyclerView.postDelayed(new Runnable() { + @Override + public void run() { + if (playlistRecyclerView.getAdapter() == null) { + return; + } + final int count = playlistRecyclerView.getAdapter().getItemCount(); + System.out.println(" kasjdflkalk" + playlistRecyclerView.getAdapter() + .getItemId(0)); + for (int i = 0; i < count; i++) { + if (playlistRecyclerView.findViewHolderForAdapterPosition(i) != null + && duplicateIds.contains(playlistAdapter.getItemId(i))) { + playlistRecyclerView.findViewHolderForAdapterPosition(i).itemView + .findViewById(R.id.checkmark2).setVisibility(View.VISIBLE); + } + } + } + }, 1000); } } @@ -163,7 +194,6 @@ public final class PlaylistAppendDialog extends PlaylistDialog { @NonNull final LocalPlaylistManager manager, @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { - //TODO: change color final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); builder.setTitle(R.string.duplicate_stream_in_playlist_title); builder.setMessage(getString(R.string.duplicate_stream_in_playlist_description, diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index 807c3c051..d017eac6c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -95,6 +95,10 @@ public class LocalPlaylistManager { return playlistStreamTable.getDuplicates(playlistId, streamURL); } + public Flowable> getDuplicatePlaylist(final String streamURL) { + return playlistStreamTable.getDuplicatePlaylists(streamURL); + } + public Single deletePlaylist(final long playlistId) { return Single.fromCallable(() -> playlistTable.deletePlaylist(playlistId)) .subscribeOn(Schedulers.io()); diff --git a/app/src/main/res/layout/list_playlist_mini_item.xml b/app/src/main/res/layout/list_playlist_mini_item.xml index a1f70144d..1b7065f23 100644 --- a/app/src/main/res/layout/list_playlist_mini_item.xml +++ b/app/src/main/res/layout/list_playlist_mini_item.xml @@ -1,5 +1,6 @@ + + + Date: Sat, 10 Dec 2022 16:54:46 +0100 Subject: [PATCH 43/84] Continued working on a way to show that items are already in a playlist --- .../newpipe/local/LocalItemListAdapter.java | 2 +- .../local/dialog/PlaylistAppendDialog.java | 62 +++++++++++-------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java index 93ea12b97..ea7bc290d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java @@ -347,7 +347,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter duplicateIds = playlistManager.getDuplicatePlaylist(getStreamEntities() - .get(0).getUrl()).blockingFirst(); + playlistRecyclerView.addOnScrollListener(new DefaultItemListOnScrolledDownListener()); + initDuplicateIndicators(playlistRecyclerView); + } + } - final HashMap map = new HashMap<>(); - for (int i = 0; i < playlists.size(); i++) { - map.put(i, playlists.get(i).uid); + public class DefaultItemListOnScrolledDownListener extends OnScrollBelowItemsListener { + @Override + public void onScrolledDown(final RecyclerView recyclerView) { + showDuplicateIndicators(recyclerView); + } + } + + public void initDuplicateIndicators(@NonNull final RecyclerView view) { + view.postDelayed(new Runnable() { + @Override + public void run() { + showDuplicateIndicators(view); } + }, 50); + } - playlistRecyclerView.postDelayed(new Runnable() { - @Override - public void run() { - if (playlistRecyclerView.getAdapter() == null) { - return; - } - final int count = playlistRecyclerView.getAdapter().getItemCount(); - System.out.println(" kasjdflkalk" + playlistRecyclerView.getAdapter() - .getItemId(0)); - for (int i = 0; i < count; i++) { - if (playlistRecyclerView.findViewHolderForAdapterPosition(i) != null - && duplicateIds.contains(playlistAdapter.getItemId(i))) { - playlistRecyclerView.findViewHolderForAdapterPosition(i).itemView - .findViewById(R.id.checkmark2).setVisibility(View.VISIBLE); - } - } - } - }, 1000); + public void showDuplicateIndicators(final RecyclerView view) { + final LocalPlaylistManager playlistManager = + new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); + final List duplicateIds = playlistManager.getDuplicatePlaylist(getStreamEntities() + .get(0).getUrl()).blockingFirst(); + + if (view.getAdapter() == null) { + return; + } + + final int count = view.getAdapter().getItemCount(); + for (int i = 0; i < count; i++) { + if (view.findViewHolderForAdapterPosition(i) != null + && duplicateIds.contains(playlistAdapter.getItemId(i))) { + view.findViewHolderForAdapterPosition(i).itemView + .findViewById(R.id.checkmark2).setVisibility(View.VISIBLE); + } } } From 8b6e110635a0404a1faea8bba252823fffa49f31 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Mon, 12 Dec 2022 20:12:06 +0100 Subject: [PATCH 44/84] Fixed the functionality, improved performance & general code cleanup --- .../playlist/dao/PlaylistStreamDAO.java | 3 +- .../local/dialog/PlaylistAppendDialog.java | 68 +++++++++++-------- .../local/playlist/LocalPlaylistManager.java | 7 +- app/src/main/res/layout/dialog_playlists.xml | 17 ++++- .../res/layout/list_playlist_mini_item.xml | 12 ---- app/src/main/res/values/strings.xml | 1 + 6 files changed, 60 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index a9719c9fa..27eb34b90 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -57,7 +57,7 @@ public interface PlaylistStreamDAO extends BasicDAO { + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId " + " AND " + STREAM_URL + " = :streamURL" ) - Flowable getDuplicates(long playlistId, String streamURL); + Flowable getDuplicateCount(long playlistId, String streamURL); @Query("SELECT " + JOIN_PLAYLIST_ID + " FROM " + STREAM_TABLE @@ -67,7 +67,6 @@ public interface PlaylistStreamDAO extends BasicDAO { ) Flowable> getDuplicatePlaylists(String streamURL); - @Query("SELECT COALESCE(MAX(" + JOIN_INDEX + "), -1)" + " FROM " + PLAYLIST_STREAM_JOIN_TABLE + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 9616b06b3..5767d6163 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -16,7 +16,6 @@ import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.R; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.stream.model.StreamEntity; -import org.schabi.newpipe.fragments.OnScrollBelowItemsListener; import org.schabi.newpipe.local.LocalItemListAdapter; import org.schabi.newpipe.local.playlist.LocalPlaylistManager; @@ -28,8 +27,12 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable; public final class PlaylistAppendDialog extends PlaylistDialog { private static final String TAG = PlaylistAppendDialog.class.getCanonicalName(); + private static final float DEFAULT_ALPHA = 1f; + private static final float GRAYED_OUT_ALPHA = 0.3f; + private RecyclerView playlistRecyclerView; private LocalItemListAdapter playlistAdapter; + private List duplicateIds; private final CompositeDisposable playlistDisposables = new CompositeDisposable(); @@ -62,6 +65,9 @@ public final class PlaylistAppendDialog extends PlaylistDialog { final LocalPlaylistManager playlistManager = new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); + duplicateIds = playlistManager.getDuplicatePlaylists(getStreamEntities().get(0).getUrl()) + .blockingFirst(); + playlistAdapter = new LocalItemListAdapter(getActivity()); playlistAdapter.setHasStableIds(true); playlistAdapter.setSelectedListener(selectedItem -> { @@ -126,43 +132,43 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); - playlistRecyclerView.addOnScrollListener(new DefaultItemListOnScrolledDownListener()); + playlistRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, + final int dy) { + showDuplicateIndicators(recyclerView); + } + }); initDuplicateIndicators(playlistRecyclerView); } } - public class DefaultItemListOnScrolledDownListener extends OnScrollBelowItemsListener { - @Override - public void onScrolledDown(final RecyclerView recyclerView) { - showDuplicateIndicators(recyclerView); + public void initDuplicateIndicators(@NonNull final RecyclerView view) { + showDuplicateIndicators(view); + + if (!duplicateIds.isEmpty()) { + final View indicatorExplanation = getView() + .findViewById(R.id.playlist_duplicate); + indicatorExplanation.setVisibility(View.VISIBLE); } } - public void initDuplicateIndicators(@NonNull final RecyclerView view) { - view.postDelayed(new Runnable() { - @Override - public void run() { - showDuplicateIndicators(view); - } - }, 50); - } - - public void showDuplicateIndicators(final RecyclerView view) { - final LocalPlaylistManager playlistManager = - new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); - final List duplicateIds = playlistManager.getDuplicatePlaylist(getStreamEntities() - .get(0).getUrl()).blockingFirst(); - + public void showDuplicateIndicators(@NonNull final RecyclerView view) { if (view.getAdapter() == null) { return; } final int count = view.getAdapter().getItemCount(); for (int i = 0; i < count; i++) { - if (view.findViewHolderForAdapterPosition(i) != null - && duplicateIds.contains(playlistAdapter.getItemId(i))) { - view.findViewHolderForAdapterPosition(i).itemView - .findViewById(R.id.checkmark2).setVisibility(View.VISIBLE); + + final RecyclerView.ViewHolder viewHolder = view.findViewHolderForAdapterPosition(i); + if (viewHolder != null) { + if (duplicateIds.contains(view.getAdapter().getItemId(i))) { + viewHolder.itemView.setAlpha(GRAYED_OUT_ALPHA); + } else { + viewHolder.itemView.setAlpha(DEFAULT_ALPHA); + } + } } } @@ -171,10 +177,10 @@ public final class PlaylistAppendDialog extends PlaylistDialog { @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { - final int numOfDuplicates = manager.getPlaylistDuplicates(playlist.uid, + final int numberOfDuplicates = manager.getPlaylistDuplicateCount(playlist.uid, streams.get(0).getUrl()).blockingFirst(); - if (numOfDuplicates > 0) { - createDuplicateDialog(numOfDuplicates, manager, playlist, streams); + if (numberOfDuplicates > 0) { + createDuplicateDialog(numberOfDuplicates, manager, playlist, streams); } else { addStreamToPlaylist(manager, playlist, streams); } @@ -197,22 +203,24 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistDisposables.add(manager.appendToPlaylist(playlist.uid, streams) .observeOn(AndroidSchedulers.mainThread()) .subscribe(ignored -> successToast.show())); + requireDialog().dismiss(); } - private void createDuplicateDialog(final int duplicates, + private void createDuplicateDialog(final int numberOfDuplicates, @NonNull final LocalPlaylistManager manager, @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); builder.setTitle(R.string.duplicate_stream_in_playlist_title); builder.setMessage(getString(R.string.duplicate_stream_in_playlist_description, - duplicates)); + numberOfDuplicates)); builder.setPositiveButton(android.R.string.yes, (dialog, i) -> { addStreamToPlaylist(manager, playlist, streams); }); builder.setNeutralButton(R.string.cancel, null); + builder.create().show(); } } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index d017eac6c..eaccb1e71 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -91,11 +91,12 @@ public class LocalPlaylistManager { return playlistStreamTable.getOrderedStreamsOf(playlistId).subscribeOn(Schedulers.io()); } - public Flowable getPlaylistDuplicates(final long playlistId, final String streamURL) { - return playlistStreamTable.getDuplicates(playlistId, streamURL); + public Flowable getPlaylistDuplicateCount(final long playlistId, + final String streamURL) { + return playlistStreamTable.getDuplicateCount(playlistId, streamURL); } - public Flowable> getDuplicatePlaylist(final String streamURL) { + public Flowable> getDuplicatePlaylists(final String streamURL) { return playlistStreamTable.getDuplicatePlaylists(streamURL); } diff --git a/app/src/main/res/layout/dialog_playlists.xml b/app/src/main/res/layout/dialog_playlists.xml index 18b08d93c..5771b400f 100644 --- a/app/src/main/res/layout/dialog_playlists.xml +++ b/app/src/main/res/layout/dialog_playlists.xml @@ -34,11 +34,26 @@ tools:ignore="RtlHardcoded" /> + + diff --git a/app/src/main/res/layout/list_playlist_mini_item.xml b/app/src/main/res/layout/list_playlist_mini_item.xml index 1b7065f23..a1f70144d 100644 --- a/app/src/main/res/layout/list_playlist_mini_item.xml +++ b/app/src/main/res/layout/list_playlist_mini_item.xml @@ -1,6 +1,5 @@ - - - "Loading requested content" New Playlist + The playlists that are grayed out already contain this item. Rename Name Add to playlist From 5fb7b3266b965cd725b0b4f72cb43e3f4427f3d6 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 16 Dec 2022 00:29:22 +0100 Subject: [PATCH 45/84] Removed the duplicate dialog and added another toast option --- .../local/dialog/PlaylistAppendDialog.java | 39 ++++--------------- app/src/main/res/values/strings.xml | 4 +- 2 files changed, 9 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 5767d6163..3414d95ab 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -1,6 +1,5 @@ package org.schabi.newpipe.local.dialog; -import android.app.AlertDialog; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -177,20 +176,15 @@ public final class PlaylistAppendDialog extends PlaylistDialog { @NonNull final PlaylistMetadataEntry playlist, @NonNull final List streams) { - final int numberOfDuplicates = manager.getPlaylistDuplicateCount(playlist.uid, - streams.get(0).getUrl()).blockingFirst(); - if (numberOfDuplicates > 0) { - createDuplicateDialog(numberOfDuplicates, manager, playlist, streams); - } else { - addStreamToPlaylist(manager, playlist, streams); - } - } + final int numOfDuplicates = manager.getPlaylistDuplicateCount(playlist.uid, + streams.get(0).getUrl()).blockingFirst(); + String toastText = getString(R.string.playlist_add_stream_success); - private void addStreamToPlaylist(@NonNull final LocalPlaylistManager manager, - @NonNull final PlaylistMetadataEntry playlist, - @NonNull final List streams) { - final Toast successToast = Toast.makeText(getContext(), - R.string.playlist_add_stream_success, Toast.LENGTH_SHORT); + if (numOfDuplicates > 0) { + toastText = getString(R.string.playlist_add_stream_success_duplicate); + } + + final Toast successToast = Toast.makeText(getContext(), toastText, Toast.LENGTH_SHORT); if (playlist.thumbnailUrl .equals("drawable://" + R.drawable.placeholder_thumbnail_playlist)) { @@ -206,21 +200,4 @@ public final class PlaylistAppendDialog extends PlaylistDialog { requireDialog().dismiss(); } - - private void createDuplicateDialog(final int numberOfDuplicates, - @NonNull final LocalPlaylistManager manager, - @NonNull final PlaylistMetadataEntry playlist, - @NonNull final List streams) { - final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); - builder.setTitle(R.string.duplicate_stream_in_playlist_title); - builder.setMessage(getString(R.string.duplicate_stream_in_playlist_description, - numberOfDuplicates)); - - builder.setPositiveButton(android.R.string.yes, (dialog, i) -> { - addStreamToPlaylist(manager, playlist, streams); - }); - builder.setNeutralButton(R.string.cancel, null); - - builder.create().show(); - } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 70687b8f4..4067381f4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -446,11 +446,9 @@ Delete this playlist\? Playlist created Playlisted + Playlisted duplicate Playlist thumbnail changed. Auto-generated (no uploader found) - Duplicated Video Found - The playlist contains this stream - already %d time(s).\nDo you want to add it one more time? No Captions Fit From b3554a6a49206f35197341308aab26380667af96 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 30 Dec 2022 16:36:33 +0100 Subject: [PATCH 46/84] Added the number of duplicates to the toast text. --- .../org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java | 2 +- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 3414d95ab..85bce7784 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -181,7 +181,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog { String toastText = getString(R.string.playlist_add_stream_success); if (numOfDuplicates > 0) { - toastText = getString(R.string.playlist_add_stream_success_duplicate); + toastText = getString(R.string.playlist_add_stream_success_duplicate, numOfDuplicates); } final Toast successToast = Toast.makeText(getContext(), toastText, Toast.LENGTH_SHORT); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4067381f4..cf4039262 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -446,7 +446,7 @@ Delete this playlist\? Playlist created Playlisted - Playlisted duplicate + Duplicate added %d time(s) Playlist thumbnail changed. Auto-generated (no uploader found) From ef4a6238c88f26e50ba794caa071432a08da66e7 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 14 Jan 2023 18:00:40 +0100 Subject: [PATCH 47/84] See if playlists already contain a stream from db --- .../playlist/PlaylistDuplicatesEntry.java | 24 +++++++ .../playlist/dao/PlaylistStreamDAO.java | 39 +++++----- .../local/dialog/PlaylistAppendDialog.java | 72 ++++--------------- .../local/holder/LocalPlaylistItemHolder.java | 11 +++ .../local/playlist/LocalPlaylistManager.java | 22 +++--- 5 files changed, 84 insertions(+), 84 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistDuplicatesEntry.java diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistDuplicatesEntry.java b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistDuplicatesEntry.java new file mode 100644 index 000000000..0fcb4ced4 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistDuplicatesEntry.java @@ -0,0 +1,24 @@ +package org.schabi.newpipe.database.playlist; + +import androidx.room.ColumnInfo; + +/** + * This class adds a field to {@link PlaylistMetadataEntry} that contains an integer representing + * how many times a specific stream is already contained inside a local playlist. Used to be able + * to grey out playlists which already contain the current stream in the playlist append dialog. + * @see org.schabi.newpipe.local.playlist.LocalPlaylistManager#getPlaylistDuplicates(String) + */ +public class PlaylistDuplicatesEntry extends PlaylistMetadataEntry { + public static final String PLAYLIST_TIMES_STREAM_IS_CONTAINED = "timesStreamIsContained"; + @ColumnInfo(name = PLAYLIST_TIMES_STREAM_IS_CONTAINED) + public final long timesStreamIsContained; + + public PlaylistDuplicatesEntry(final long uid, + final String name, + final String thumbnailUrl, + final long streamCount, + final long timesStreamIsContained) { + super(uid, name, thumbnailUrl, streamCount); + this.timesStreamIsContained = timesStreamIsContained; + } +} diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index 27eb34b90..f173ab0bc 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -6,6 +6,7 @@ import androidx.room.RewriteQueriesToDropUnusedColumns; import androidx.room.Transaction; import org.schabi.newpipe.database.BasicDAO; +import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity; @@ -14,6 +15,7 @@ import java.util.List; import io.reactivex.rxjava3.core.Flowable; +import static org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry.PLAYLIST_TIMES_STREAM_IS_CONTAINED; import static org.schabi.newpipe.database.playlist.PlaylistMetadataEntry.PLAYLIST_STREAM_COUNT; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_ID; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_NAME; @@ -50,23 +52,6 @@ public interface PlaylistStreamDAO extends BasicDAO { + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") void deleteBatch(long playlistId); - @Query("SELECT COALESCE(COUNT(*), 0)" - + " FROM " + STREAM_TABLE - + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE - + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID - + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId " - + " AND " + STREAM_URL + " = :streamURL" - ) - Flowable getDuplicateCount(long playlistId, String streamURL); - - @Query("SELECT " + JOIN_PLAYLIST_ID - + " FROM " + STREAM_TABLE - + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE - + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID - + " WHERE " + STREAM_URL + " = :streamURL" - ) - Flowable> getDuplicatePlaylists(String streamURL); - @Query("SELECT COALESCE(MAX(" + JOIN_INDEX + "), -1)" + " FROM " + PLAYLIST_STREAM_JOIN_TABLE + " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId") @@ -111,4 +96,24 @@ public interface PlaylistStreamDAO extends BasicDAO { + " GROUP BY " + PLAYLIST_ID + " ORDER BY " + PLAYLIST_NAME + " COLLATE NOCASE ASC") Flowable> getPlaylistMetadata(); + + @Transaction + @Query("SELECT " + PLAYLIST_TABLE + "." + PLAYLIST_ID + ", " + + PLAYLIST_NAME + ", " + + PLAYLIST_TABLE + "." + PLAYLIST_THUMBNAIL_URL + ", " + + "COALESCE(COUNT(" + JOIN_PLAYLIST_ID + "), 0) AS " + PLAYLIST_STREAM_COUNT + ", " + + "COALESCE(SUM(" + STREAM_URL + " = :streamUrl), 0) AS " + + PLAYLIST_TIMES_STREAM_IS_CONTAINED + + + " FROM " + PLAYLIST_TABLE + + " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE + + " ON " + PLAYLIST_TABLE + "." + PLAYLIST_ID + " = " + JOIN_PLAYLIST_ID + + + " LEFT JOIN " + STREAM_TABLE + + " ON " + STREAM_TABLE + "." + STREAM_ID + " = " + JOIN_STREAM_ID + + " AND :streamUrl = :streamUrl" + + + " GROUP BY " + JOIN_PLAYLIST_ID + + " ORDER BY " + PLAYLIST_NAME + " COLLATE NOCASE ASC") + Flowable> getPlaylistDuplicatesMetadata(String streamUrl); } diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 85bce7784..79a355f52 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -13,7 +13,7 @@ import androidx.recyclerview.widget.RecyclerView; import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.R; -import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; +import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.local.LocalItemListAdapter; import org.schabi.newpipe.local.playlist.LocalPlaylistManager; @@ -26,12 +26,8 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable; public final class PlaylistAppendDialog extends PlaylistDialog { private static final String TAG = PlaylistAppendDialog.class.getCanonicalName(); - private static final float DEFAULT_ALPHA = 1f; - private static final float GRAYED_OUT_ALPHA = 0.3f; - private RecyclerView playlistRecyclerView; private LocalItemListAdapter playlistAdapter; - private List duplicateIds; private final CompositeDisposable playlistDisposables = new CompositeDisposable(); @@ -64,15 +60,13 @@ public final class PlaylistAppendDialog extends PlaylistDialog { final LocalPlaylistManager playlistManager = new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); - duplicateIds = playlistManager.getDuplicatePlaylists(getStreamEntities().get(0).getUrl()) - .blockingFirst(); - playlistAdapter = new LocalItemListAdapter(getActivity()); playlistAdapter.setHasStableIds(true); playlistAdapter.setSelectedListener(selectedItem -> { final List entities = getStreamEntities(); - if (selectedItem instanceof PlaylistMetadataEntry && entities != null) { - onPlaylistSelected(playlistManager, (PlaylistMetadataEntry) selectedItem, entities); + if (selectedItem instanceof PlaylistDuplicatesEntry && entities != null) { + onPlaylistSelected(playlistManager, + (PlaylistDuplicatesEntry) selectedItem, entities); } }); @@ -83,7 +77,8 @@ public final class PlaylistAppendDialog extends PlaylistDialog { final View newPlaylistButton = view.findViewById(R.id.newPlaylist); newPlaylistButton.setOnClickListener(ignored -> openCreatePlaylistDialog()); - playlistDisposables.add(playlistManager.getPlaylists() + playlistDisposables.add(playlistManager + .getPlaylistDuplicates(getStreamEntities().get(0).getUrl()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::onPlaylistsReceived)); } @@ -125,63 +120,24 @@ public final class PlaylistAppendDialog extends PlaylistDialog { requireDialog().dismiss(); } - private void onPlaylistsReceived(@NonNull final List playlists) { + private void onPlaylistsReceived(@NonNull final List playlists) { if (playlistAdapter != null && playlistRecyclerView != null) { playlistAdapter.clearStreamItemList(); playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); - - playlistRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, - final int dy) { - showDuplicateIndicators(recyclerView); - } - }); - initDuplicateIndicators(playlistRecyclerView); - } - } - - public void initDuplicateIndicators(@NonNull final RecyclerView view) { - showDuplicateIndicators(view); - - if (!duplicateIds.isEmpty()) { - final View indicatorExplanation = getView() - .findViewById(R.id.playlist_duplicate); - indicatorExplanation.setVisibility(View.VISIBLE); - } - } - - public void showDuplicateIndicators(@NonNull final RecyclerView view) { - if (view.getAdapter() == null) { - return; - } - - final int count = view.getAdapter().getItemCount(); - for (int i = 0; i < count; i++) { - - final RecyclerView.ViewHolder viewHolder = view.findViewHolderForAdapterPosition(i); - if (viewHolder != null) { - if (duplicateIds.contains(view.getAdapter().getItemId(i))) { - viewHolder.itemView.setAlpha(GRAYED_OUT_ALPHA); - } else { - viewHolder.itemView.setAlpha(DEFAULT_ALPHA); - } - - } } } private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager, - @NonNull final PlaylistMetadataEntry playlist, + @NonNull final PlaylistDuplicatesEntry playlist, @NonNull final List streams) { - final int numOfDuplicates = manager.getPlaylistDuplicateCount(playlist.uid, - streams.get(0).getUrl()).blockingFirst(); - String toastText = getString(R.string.playlist_add_stream_success); - - if (numOfDuplicates > 0) { - toastText = getString(R.string.playlist_add_stream_success_duplicate, numOfDuplicates); + final String toastText; + if (playlist.timesStreamIsContained > 0) { + toastText = getString(R.string.playlist_add_stream_success_duplicate, + playlist.timesStreamIsContained); + } else { + toastText = getString(R.string.playlist_add_stream_success); } final Toast successToast = Toast.makeText(getContext(), toastText, Toast.LENGTH_SHORT); diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java index f8c5176ec..240ca0462 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java @@ -4,6 +4,7 @@ import android.view.View; import android.view.ViewGroup; import org.schabi.newpipe.database.LocalItem; +import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; @@ -13,6 +14,9 @@ import org.schabi.newpipe.util.Localization; import java.time.format.DateTimeFormatter; public class LocalPlaylistItemHolder extends PlaylistItemHolder { + + private static final float GRAYED_OUT_ALPHA = 0.6f; + public LocalPlaylistItemHolder(final LocalItemBuilder infoItemBuilder, final ViewGroup parent) { super(infoItemBuilder, parent); } @@ -38,6 +42,13 @@ public class LocalPlaylistItemHolder extends PlaylistItemHolder { PicassoHelper.loadPlaylistThumbnail(item.thumbnailUrl).into(itemThumbnailView); + if (item instanceof PlaylistDuplicatesEntry + && ((PlaylistDuplicatesEntry) item).timesStreamIsContained > 0) { + itemView.setAlpha(GRAYED_OUT_ALPHA); + } else { + itemView.setAlpha(1.0f); + } + super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter); } } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index eaccb1e71..8ea64f343 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -4,6 +4,7 @@ import androidx.annotation.Nullable; import org.schabi.newpipe.R; import org.schabi.newpipe.database.AppDatabase; +import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.playlist.dao.PlaylistDAO; @@ -87,19 +88,22 @@ public class LocalPlaylistManager { return playlistStreamTable.getPlaylistMetadata().subscribeOn(Schedulers.io()); } + /** + * Get playlists with attached information about how many times the provided stream is already + * contained in each playlist. + * + * @param streamUrl the stream url for which to check for duplicates + * @return a list of {@link PlaylistDuplicatesEntry} + */ + public Flowable> getPlaylistDuplicates(final String streamUrl) { + return playlistStreamTable.getPlaylistDuplicatesMetadata(streamUrl) + .subscribeOn(Schedulers.io()); + } + public Flowable> getPlaylistStreams(final long playlistId) { return playlistStreamTable.getOrderedStreamsOf(playlistId).subscribeOn(Schedulers.io()); } - public Flowable getPlaylistDuplicateCount(final long playlistId, - final String streamURL) { - return playlistStreamTable.getDuplicateCount(playlistId, streamURL); - } - - public Flowable> getDuplicatePlaylists(final String streamURL) { - return playlistStreamTable.getDuplicatePlaylists(streamURL); - } - public Single deletePlaylist(final long playlistId) { return Single.fromCallable(() -> playlistTable.deletePlaylist(playlistId)) .subscribeOn(Schedulers.io()); From f766ef2033f9e9f43c59feb0bb70d3a61620c96a Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sun, 28 Aug 2022 06:41:38 +0530 Subject: [PATCH 48/84] Replace the system UI visibility flags with WindowCompat calls. --- .../fragments/detail/VideoDetailFragment.java | 55 ++++++++----------- .../newpipe/player/ui/MainPlayerUi.java | 11 ++-- 2 files changed, 29 insertions(+), 37 deletions(-) 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 679084bdf..df0e0e537 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 @@ -27,7 +27,6 @@ import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -55,6 +54,9 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.content.ContextCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.core.view.WindowInsetsControllerCompat; import androidx.preference.PreferenceManager; import com.google.android.exoplayer2.PlaybackException; @@ -1962,15 +1964,17 @@ public final class VideoDetailFragment return; } - // Prevent jumping of the player on devices with cutout - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - activity.getWindow().getAttributes().layoutInDisplayCutoutMode = - WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; - } - activity.getWindow().getDecorView().setSystemUiVisibility(0); - activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - activity.getWindow().setStatusBarColor(ThemeHelper.resolveColorFromAttr( - requireContext(), android.R.attr.colorPrimary)); + final var window = activity.getWindow(); + final var windowInsetsController = WindowCompat.getInsetsController(window, + window.getDecorView()); + + WindowCompat.setDecorFitsSystemWindows(window, true); + windowInsetsController.setSystemBarsBehavior(WindowInsetsControllerCompat + .BEHAVIOR_SHOW_BARS_BY_TOUCH); + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()); + + window.setStatusBarColor(ThemeHelper.resolveColorFromAttr(requireContext(), + android.R.attr.colorPrimary)); } private void hideSystemUi() { @@ -1982,30 +1986,19 @@ public final class VideoDetailFragment return; } - // Prevent jumping of the player on devices with cutout - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - activity.getWindow().getAttributes().layoutInDisplayCutoutMode = - WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; - } - int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + final var window = activity.getWindow(); + final var windowInsetsController = WindowCompat.getInsetsController(window, + window.getDecorView()); - // In multiWindow mode status bar is not transparent for devices with cutout - // if I include this flag. So without it is better in this case - final boolean isInMultiWindow = DeviceUtils.isInMultiWindow(activity); - if (!isInMultiWindow) { - visibility |= View.SYSTEM_UI_FLAG_FULLSCREEN; - } - activity.getWindow().getDecorView().setSystemUiVisibility(visibility); + WindowCompat.setDecorFitsSystemWindows(window, false); + windowInsetsController.setSystemBarsBehavior(WindowInsetsControllerCompat + .BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); - if (isInMultiWindow || isFullscreen()) { - activity.getWindow().setStatusBarColor(Color.TRANSPARENT); - activity.getWindow().setNavigationBarColor(Color.TRANSPARENT); + if (DeviceUtils.isInMultiWindow(activity) || isFullscreen()) { + window.setStatusBarColor(Color.TRANSPARENT); + window.setNavigationBarColor(Color.TRANSPARENT); } - activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); } // Listener implementation diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java index 6226900f6..58729ace2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java @@ -32,7 +32,6 @@ import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; -import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.LinearLayout; @@ -40,6 +39,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.content.res.AppCompatResources; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; @@ -451,11 +452,9 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh getParentActivity().map(Activity::getWindow).ifPresent(window -> { window.setStatusBarColor(Color.TRANSPARENT); window.setNavigationBarColor(Color.TRANSPARENT); - final int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; - window.getDecorView().setSystemUiVisibility(visibility); - window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + WindowCompat.setDecorFitsSystemWindows(window, false); + WindowCompat.getInsetsController(window, window.getDecorView()) + .show(WindowInsetsCompat.Type.systemBars()); }); } } From 764b6aa2b1284b8c48a9280eb93c17254cceeb37 Mon Sep 17 00:00:00 2001 From: ge78fug Date: Sat, 17 Dec 2022 00:01:18 +0100 Subject: [PATCH 49/84] Made the channel-images in the grid list bigger Also improved the handling of additional information (expanded description, video count, subscriber count) --- .../holder/ChannelInfoItemHolder.java | 38 -------------- .../holder/ChannelMiniInfoItemHolder.java | 50 ++++++++++++++++--- .../res/layout/list_channel_grid_item.xml | 16 +++++- app/src/main/res/values/dimens.xml | 2 +- 4 files changed, 57 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelInfoItemHolder.java index cf1ed255b..f8133d3de 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelInfoItemHolder.java @@ -1,14 +1,9 @@ package org.schabi.newpipe.info_list.holder; import android.view.ViewGroup; -import android.widget.TextView; import org.schabi.newpipe.R; -import org.schabi.newpipe.extractor.InfoItem; -import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.info_list.InfoItemBuilder; -import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.util.Localization; /* * Created by Christian Schabesberger on 12.02.17. @@ -31,40 +26,7 @@ import org.schabi.newpipe.util.Localization; */ public class ChannelInfoItemHolder extends ChannelMiniInfoItemHolder { - private final TextView itemChannelDescriptionView; - public ChannelInfoItemHolder(final InfoItemBuilder infoItemBuilder, final ViewGroup parent) { super(infoItemBuilder, R.layout.list_channel_item, parent); - itemChannelDescriptionView = itemView.findViewById(R.id.itemChannelDescriptionView); - } - - @Override - public void updateFromItem(final InfoItem infoItem, - final HistoryRecordManager historyRecordManager) { - super.updateFromItem(infoItem, historyRecordManager); - - if (!(infoItem instanceof ChannelInfoItem)) { - return; - } - final ChannelInfoItem item = (ChannelInfoItem) infoItem; - - itemChannelDescriptionView.setText(item.getDescription()); - } - - @Override - protected String getDetailLine(final ChannelInfoItem item) { - String details = super.getDetailLine(item); - - if (item.getStreamCount() >= 0) { - final String formattedVideoAmount = Localization.localizeStreamCount( - itemBuilder.getContext(), item.getStreamCount()); - - if (!details.isEmpty()) { - details += " • " + formattedVideoAmount; - } else { - details = formattedVideoAmount; - } - } - return details; } } diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java index 89398a1e5..c625c3c5c 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java @@ -1,21 +1,26 @@ package org.schabi.newpipe.info_list.holder; +import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.Nullable; + import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; +import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.Localization; public class ChannelMiniInfoItemHolder extends InfoItemHolder { - public final ImageView itemThumbnailView; - public final TextView itemTitleView; + private final ImageView itemThumbnailView; + private final TextView itemTitleView; private final TextView itemAdditionalDetailView; + private final TextView itemChannelDescriptionView; ChannelMiniInfoItemHolder(final InfoItemBuilder infoItemBuilder, final int layoutId, final ViewGroup parent) { @@ -24,6 +29,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder { itemThumbnailView = itemView.findViewById(R.id.itemThumbnailView); itemTitleView = itemView.findViewById(R.id.itemTitleView); itemAdditionalDetailView = itemView.findViewById(R.id.itemAdditionalDetails); + itemChannelDescriptionView = itemView.findViewById(R.id.itemChannelDescriptionView); } public ChannelMiniInfoItemHolder(final InfoItemBuilder infoItemBuilder, @@ -40,7 +46,14 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder { final ChannelInfoItem item = (ChannelInfoItem) infoItem; itemTitleView.setText(item.getName()); - itemAdditionalDetailView.setText(getDetailLine(item)); + + final String detailLine = getDetailLine(item); + if (detailLine == null) { + itemAdditionalDetailView.setVisibility(View.GONE); + } else { + itemAdditionalDetailView.setVisibility(View.VISIBLE); + itemAdditionalDetailView.setText(getDetailLine(item)); + } PicassoHelper.loadAvatar(item.getThumbnailUrl()).into(itemThumbnailView); @@ -56,14 +69,35 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder { } return true; }); + + if (itemChannelDescriptionView != null) { + // itemChannelDescriptionView will be null in the mini variant + if (Utils.isBlank(item.getDescription())) { + itemChannelDescriptionView.setVisibility(View.GONE); + } else { + itemChannelDescriptionView.setVisibility(View.VISIBLE); + itemChannelDescriptionView.setText(item.getDescription()); + itemChannelDescriptionView.setMaxLines(detailLine == null ? 3 : 2); + } + } } - protected String getDetailLine(final ChannelInfoItem item) { - String details = ""; - if (item.getSubscriberCount() >= 0) { - details += Localization.shortSubscriberCount(itemBuilder.getContext(), + @Nullable + private String getDetailLine(final ChannelInfoItem item) { + if (item.getStreamCount() >= 0 && item.getSubscriberCount() >= 0) { + return Localization.concatenateStrings( + Localization.shortSubscriberCount(itemBuilder.getContext(), + item.getSubscriberCount()), + Localization.localizeStreamCount(itemBuilder.getContext(), + item.getStreamCount())); + } else if (item.getStreamCount() >= 0) { + return Localization.localizeStreamCount(itemBuilder.getContext(), + item.getStreamCount()); + } else if (item.getSubscriberCount() >= 0) { + return Localization.shortSubscriberCount(itemBuilder.getContext(), item.getSubscriberCount()); + } else { + return null; } - return details; } } diff --git a/app/src/main/res/layout/list_channel_grid_item.xml b/app/src/main/res/layout/list_channel_grid_item.xml index 3112a849f..0aec4e6e0 100644 --- a/app/src/main/res/layout/list_channel_grid_item.xml +++ b/app/src/main/res/layout/list_channel_grid_item.xml @@ -39,12 +39,24 @@ android:id="@+id/itemAdditionalDetails" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_below="@+id/itemTitleView" + android:layout_below="@id/itemTitleView" android:layout_centerHorizontal="true" android:lines="1" android:textAppearance="?android:attr/textAppearanceSmall" android:textSize="@dimen/video_item_search_upload_date_text_size" tools:ignore="RtlHardcoded" - tools:text="10M subscribers" /> + tools:text="10M subscribers • 100 videos" /> + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 9f7e50c19..5693ec7c4 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -30,7 +30,7 @@ 164dp 92dp - 42dp + 92dp 128dp 96dp From cdd5e89b863a86ad1425883589946c5c35bb20ee Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Sat, 16 Jul 2022 13:33:25 +0200 Subject: [PATCH 50/84] Add ability to copy hashtags, URLs and timestamps in descriptions on long-press This commit adds the ability to copy to clipboard hashtags, URLs and timestamps when long-pressing them. Some changes in our TextView class related to text setting have been required and metadata items are now using a NewPipeTextView instead of a standard TextView. Six new classes have been added: - a custom LinkMovementMethod class; - a custom ClickableSpan class, LongPressClickableSpan, in order to set a long press event; - a class to avoid code duplication in CommentTextOnTouchListener, TouchUtils; - three implementations of LongPressClickableSpan used when linkifying text: - HashtagLongPressClickableSpan for hashtags; - TimestampLongPressClickableSpan for timestamps; - UrlLongPressClickableSpan for URLs. --- .../fragments/detail/DescriptionFragment.java | 45 +-- .../util/CommentTextOnTouchListener.java | 26 +- .../org/schabi/newpipe/util/TouchUtils.java | 38 ++ .../HashtagLongPressClickableSpan.java | 38 ++ .../external_communication/ShareUtils.java | 13 +- .../external_communication/TextLinkifier.java | 337 +++++++++--------- .../TimestampExtractor.java | 20 +- .../TimestampLongPressClickableSpan.java | 75 ++++ .../UrlLongPressClickableSpan.java | 41 +++ .../newpipe/views/LongPressClickableSpan.java | 12 + .../views/LongPressLinkMovementMethod.java | 77 ++++ .../schabi/newpipe/views/NewPipeEditText.java | 5 +- .../schabi/newpipe/views/NewPipeTextView.java | 17 +- app/src/main/res/layout/item_metadata.xml | 4 +- app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 16 files changed, 524 insertions(+), 226 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/util/TouchUtils.java create mode 100644 app/src/main/java/org/schabi/newpipe/util/external_communication/HashtagLongPressClickableSpan.java create mode 100644 app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampLongPressClickableSpan.java create mode 100644 app/src/main/java/org/schabi/newpipe/util/external_communication/UrlLongPressClickableSpan.java create mode 100644 app/src/main/java/org/schabi/newpipe/views/LongPressClickableSpan.java create mode 100644 app/src/main/java/org/schabi/newpipe/views/LongPressLinkMovementMethod.java diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index bf7f8fa5d..96e01c622 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -3,6 +3,7 @@ package org.schabi.newpipe.fragments.detail; import static android.text.TextUtils.isEmpty; import static org.schabi.newpipe.extractor.stream.StreamExtractor.NO_AGE_LIMIT; import static org.schabi.newpipe.extractor.utils.Utils.isBlank; +import static org.schabi.newpipe.util.Localization.getAppLocale; import android.os.Bundle; import android.view.LayoutInflater; @@ -134,7 +135,8 @@ public class DescriptionFragment extends BaseFragment { TextLinkifier.createLinksFromMarkdownText(binding.detailDescriptionView, description.getContent(), streamInfo, descriptionDisposables); break; - case Description.PLAIN_TEXT: default: + case Description.PLAIN_TEXT: + default: TextLinkifier.createLinksFromPlainText(binding.detailDescriptionView, description.getContent(), streamInfo, descriptionDisposables); break; @@ -144,30 +146,30 @@ public class DescriptionFragment extends BaseFragment { private void setupMetadata(final LayoutInflater inflater, final LinearLayout layout) { - addMetadataItem(inflater, layout, false, - R.string.metadata_category, streamInfo.getCategory()); + addMetadataItem(inflater, layout, false, R.string.metadata_category, + streamInfo.getCategory()); - addMetadataItem(inflater, layout, false, - R.string.metadata_licence, streamInfo.getLicence()); + addMetadataItem(inflater, layout, false, R.string.metadata_licence, + streamInfo.getLicence()); addPrivacyMetadataItem(inflater, layout); if (streamInfo.getAgeLimit() != NO_AGE_LIMIT) { - addMetadataItem(inflater, layout, false, - R.string.metadata_age_limit, String.valueOf(streamInfo.getAgeLimit())); + addMetadataItem(inflater, layout, false, R.string.metadata_age_limit, + String.valueOf(streamInfo.getAgeLimit())); } if (streamInfo.getLanguageInfo() != null) { - addMetadataItem(inflater, layout, false, - R.string.metadata_language, streamInfo.getLanguageInfo().getDisplayLanguage()); + addMetadataItem(inflater, layout, false, R.string.metadata_language, + streamInfo.getLanguageInfo().getDisplayLanguage(getAppLocale(getContext()))); } - addMetadataItem(inflater, layout, true, - R.string.metadata_support, streamInfo.getSupportInfo()); - addMetadataItem(inflater, layout, true, - R.string.metadata_host, streamInfo.getHost()); - addMetadataItem(inflater, layout, true, - R.string.metadata_thumbnail_url, streamInfo.getThumbnailUrl()); + addMetadataItem(inflater, layout, true, R.string.metadata_support, + streamInfo.getSupportInfo()); + addMetadataItem(inflater, layout, true, R.string.metadata_host, + streamInfo.getHost()); + addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url, + streamInfo.getThumbnailUrl()); addTagsMetadataItem(inflater, layout); } @@ -191,12 +193,14 @@ public class DescriptionFragment extends BaseFragment { }); if (linkifyContent) { - TextLinkifier.createLinksFromPlainText(itemBinding.metadataContentView, content, null, - descriptionDisposables); + TextLinkifier.createLinksFromPlainText(itemBinding.metadataContentView, content, + null, descriptionDisposables); } else { itemBinding.metadataContentView.setText(content); } + itemBinding.metadataContentView.setClickable(true); + layout.addView(itemBinding.getRoot()); } @@ -245,14 +249,15 @@ public class DescriptionFragment extends BaseFragment { case INTERNAL: contentRes = R.string.metadata_privacy_internal; break; - case OTHER: default: + case OTHER: + default: contentRes = 0; break; } if (contentRes != 0) { - addMetadataItem(inflater, layout, false, - R.string.metadata_privacy, getString(contentRes)); + addMetadataItem(inflater, layout, false, R.string.metadata_privacy, + getString(contentRes)); } } } diff --git a/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java b/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java index 7c87e664b..ff8875e5a 100644 --- a/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java +++ b/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java @@ -1,6 +1,7 @@ package org.schabi.newpipe.util; -import android.text.Layout; +import static org.schabi.newpipe.util.TouchUtils.getOffsetForHorizontalLine; + import android.text.Selection; import android.text.Spannable; import android.text.Spanned; @@ -30,23 +31,9 @@ public class CommentTextOnTouchListener implements View.OnTouchListener { final int action = event.getAction(); - if (action == MotionEvent.ACTION_UP - || action == MotionEvent.ACTION_DOWN) { - int x = (int) event.getX(); - int y = (int) event.getY(); - - x -= widget.getTotalPaddingLeft(); - y -= widget.getTotalPaddingTop(); - - x += widget.getScrollX(); - y += widget.getScrollY(); - - final Layout layout = widget.getLayout(); - final int line = layout.getLineForVertical(y); - final int off = layout.getOffsetForHorizontal(line, x); - - final ClickableSpan[] link = buffer.getSpans(off, off, - ClickableSpan.class); + if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { + final int offset = getOffsetForHorizontalLine(widget, event); + final ClickableSpan[] link = buffer.getSpans(offset, offset, ClickableSpan.class); if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { @@ -58,8 +45,7 @@ public class CommentTextOnTouchListener implements View.OnTouchListener { } } } else if (action == MotionEvent.ACTION_DOWN) { - Selection.setSelection(buffer, - buffer.getSpanStart(link[0]), + Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); } return true; diff --git a/app/src/main/java/org/schabi/newpipe/util/TouchUtils.java b/app/src/main/java/org/schabi/newpipe/util/TouchUtils.java new file mode 100644 index 000000000..23bc5a401 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/TouchUtils.java @@ -0,0 +1,38 @@ +package org.schabi.newpipe.util; + +import android.text.Layout; +import android.view.MotionEvent; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +public final class TouchUtils { + + private TouchUtils() { + } + + /** + * Get the character offset on the closest line to the position pressed by the user of a + * {@link TextView} from a {@link MotionEvent} which was fired on this {@link TextView}. + * + * @param textView the {@link TextView} on which the {@link MotionEvent} was fired + * @param event the {@link MotionEvent} which was fired + * @return the character offset on the closest line to the position pressed by the user + */ + public static int getOffsetForHorizontalLine(@NonNull final TextView textView, + @NonNull final MotionEvent event) { + + int x = (int) event.getX(); + int y = (int) event.getY(); + + x -= textView.getTotalPaddingLeft(); + y -= textView.getTotalPaddingTop(); + + x += textView.getScrollX(); + y += textView.getScrollY(); + + final Layout layout = textView.getLayout(); + final int line = layout.getLineForVertical(y); + return layout.getOffsetForHorizontal(line, x); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/HashtagLongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/HashtagLongPressClickableSpan.java new file mode 100644 index 000000000..9acedc12b --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/HashtagLongPressClickableSpan.java @@ -0,0 +1,38 @@ +package org.schabi.newpipe.util.external_communication; + +import android.content.Context; +import android.view.View; + +import androidx.annotation.NonNull; + +import org.schabi.newpipe.extractor.Info; +import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.views.LongPressClickableSpan; + +final class HashtagLongPressClickableSpan extends LongPressClickableSpan { + + @NonNull + private final Context context; + @NonNull + private final String parsedHashtag; + @NonNull + private final Info relatedInfo; + + HashtagLongPressClickableSpan(@NonNull final Context context, + @NonNull final String parsedHashtag, + @NonNull final Info relatedInfo) { + this.context = context; + this.parsedHashtag = parsedHashtag; + this.relatedInfo = relatedInfo; + } + + @Override + public void onClick(@NonNull final View view) { + NavigationHelper.openSearch(context, relatedInfo.getServiceId(), parsedHashtag); + } + + @Override + public void onLongClick(@NonNull final View view) { + ShareUtils.copyToClipboard(context, parsedHashtag); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java index 9829ddd2e..332298b22 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java @@ -313,10 +313,15 @@ public final class ShareUtils { return; } - clipboardManager.setPrimaryClip(ClipData.newPlainText(null, text)); - if (Build.VERSION.SDK_INT < 33) { - // Android 13 has its own "copied to clipboard" dialog - Toast.makeText(context, R.string.msg_copied, Toast.LENGTH_SHORT).show(); + try { + clipboardManager.setPrimaryClip(ClipData.newPlainText(null, text)); + if (Build.VERSION.SDK_INT < 33) { + // Android 13 has its own "copied to clipboard" dialog + Toast.makeText(context, R.string.msg_copied, Toast.LENGTH_SHORT).show(); + } + } catch (final Exception e) { + Log.e(TAG, "Error when trying to copy text to clipboard", e); + Toast.makeText(context, R.string.msg_failed_to_copy, Toast.LENGTH_SHORT).show(); } } diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java index 8b8eb265b..1bbd37cf5 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java @@ -2,8 +2,6 @@ package org.schabi.newpipe.util.external_communication; import android.content.Context; import android.text.SpannableStringBuilder; -import android.text.method.LinkMovementMethod; -import android.text.style.ClickableSpan; import android.text.style.URLSpan; import android.text.util.Linkify; import android.util.Log; @@ -17,6 +15,8 @@ import androidx.core.text.HtmlCompat; import org.schabi.newpipe.extractor.Info; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.views.LongPressClickableSpan; +import org.schabi.newpipe.views.LongPressLinkMovementMethod; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -28,27 +28,26 @@ import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.schedulers.Schedulers; -import static org.schabi.newpipe.util.external_communication.InternalUrlsHandler.playOnPopup; - public final class TextLinkifier { public static final String TAG = TextLinkifier.class.getSimpleName(); // Looks for hashtags with characters from any language (\p{L}), numbers, or underscores - private static final Pattern HASHTAGS_PATTERN = - Pattern.compile("(#[\\p{L}0-9_]+)"); + private static final Pattern HASHTAGS_PATTERN = Pattern.compile("(#[\\p{L}0-9_]+)"); private TextLinkifier() { } /** - * Create web links for contents with an HTML description. - *

- * This will call {@link TextLinkifier#changeIntentsOfDescriptionLinks(TextView, CharSequence, - * Info, CompositeDisposable)} after having linked the URLs with - * {@link HtmlCompat#fromHtml(String, int)}. + * Create links for contents with an HTML description. * - * @param textView the TextView to set the htmlBlock linked - * @param htmlBlock the htmlBlock to be linked + *

+ * This method will call {@link #changeIntentsOfDescriptionLinks(TextView, CharSequence, Info, + * CompositeDisposable)} after having linked the URLs with + * {@link HtmlCompat#fromHtml(String, int)}. + *

+ * + * @param textView the {@link TextView} to set the 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 * @param relatedInfo if given, handle timestamps to open the stream in the popup player at @@ -58,50 +57,55 @@ public final class TextLinkifier { * should be handled by the calling class */ public static void createLinksFromHtmlBlock(@NonNull final TextView textView, - final String htmlBlock, + @NonNull final String htmlBlock, final int htmlCompatFlag, @Nullable final Info relatedInfo, - final CompositeDisposable disposables) { - changeIntentsOfDescriptionLinks( - textView, HtmlCompat.fromHtml(htmlBlock, htmlCompatFlag), relatedInfo, disposables); + @NonNull final CompositeDisposable disposables) { + changeIntentsOfDescriptionLinks(textView, HtmlCompat.fromHtml(htmlBlock, htmlCompatFlag), + relatedInfo, disposables); } /** - * Create web links for contents with a plain text description. - *

- * This will call {@link TextLinkifier#changeIntentsOfDescriptionLinks(TextView, CharSequence, - * Info, CompositeDisposable)} after having linked the URLs with - * {@link TextView#setAutoLinkMask(int)} and - * {@link TextView#setText(CharSequence, TextView.BufferType)}. + * Create links for contents with a plain text description. * - * @param textView the TextView to set the plain text block linked + *

+ * This method will call {@link #changeIntentsOfDescriptionLinks(TextView, CharSequence, Info, + * CompositeDisposable)} after having linked the URLs with {@link TextView#setAutoLinkMask(int)} + * and {@link TextView#setText(CharSequence, TextView.BufferType)}. + *

+ * + * @param textView the {@link TextView} to set the plain text block linked * @param plainTextBlock the block of plain text to be linked - * @param relatedInfo if given, handle timestamps to open the stream in the popup player at - * the specific time, and hashtags to search for the term in the correct + * @param relatedInfo if given, handle timestamps to open the stream in the popup player, at + * the specified time, and hashtags to search for the term in the correct * service * @param disposables disposables created by the method are added here and their lifecycle * should be handled by the calling class */ public static void createLinksFromPlainText(@NonNull final TextView textView, - final String plainTextBlock, + @NonNull final String plainTextBlock, @Nullable final Info relatedInfo, - final CompositeDisposable disposables) { + @NonNull final CompositeDisposable disposables) { textView.setAutoLinkMask(Linkify.WEB_URLS); textView.setText(plainTextBlock, TextView.BufferType.SPANNABLE); - changeIntentsOfDescriptionLinks(textView, textView.getText(), relatedInfo, disposables); + changeIntentsOfDescriptionLinks(textView, textView.getText(), relatedInfo, disposables + ); } /** - * Create web links for contents with a markdown description. - *

- * This will call {@link TextLinkifier#changeIntentsOfDescriptionLinks(TextView, CharSequence, - * Info, CompositeDisposable)} after creating an {@link Markwon} object and using - * {@link Markwon#setMarkdown(TextView, String)}. + * Create links for contents with a markdown description. * - * @param textView the TextView to set the plain text block linked + *

+ * This method will call {@link #changeIntentsOfDescriptionLinks(TextView, CharSequence, Info, + * CompositeDisposable)} after creating a {@link Markwon} object and using + * {@link Markwon#setMarkdown(TextView, String)}. + *

+ * + * @param textView the {@link TextView} to set the plain text block linked * @param markdownBlock the block of markdown text to be linked * @param relatedInfo if given, handle timestamps to open the stream in the popup player at * the specific time, and hashtags to search for the term in the correct + * service * @param disposables disposables created by the method are added here and their lifecycle * should be handled by the calling class */ @@ -115,161 +119,78 @@ public final class TextLinkifier { disposables); } - /** - * Add click listeners which opens a search on hashtags in a plain text. - *

- * This method finds all timestamps in the {@link SpannableStringBuilder} of the description - * using a regular expression, adds for each a {@link ClickableSpan} which opens - * {@link NavigationHelper#openSearch(Context, int, String)} and makes a search on the hashtag, - * in the service of the content. - * - * @param context the context to use - * @param spannableDescription the SpannableStringBuilder with the text of the - * content description - * @param relatedInfo used to search for the term in the correct service - */ - private static void addClickListenersOnHashtags(final Context context, - @NonNull final SpannableStringBuilder - spannableDescription, - final Info relatedInfo) { - final String descriptionText = spannableDescription.toString(); - final Matcher hashtagsMatches = HASHTAGS_PATTERN.matcher(descriptionText); - - while (hashtagsMatches.find()) { - final int hashtagStart = hashtagsMatches.start(1); - final int hashtagEnd = hashtagsMatches.end(1); - final String parsedHashtag = descriptionText.substring(hashtagStart, hashtagEnd); - - // don't add a ClickableSpan if there is already one, which should be a part of an URL, - // already parsed before - if (spannableDescription.getSpans(hashtagStart, hashtagEnd, - ClickableSpan.class).length == 0) { - spannableDescription.setSpan(new ClickableSpan() { - @Override - public void onClick(@NonNull final View view) { - NavigationHelper.openSearch(context, relatedInfo.getServiceId(), - parsedHashtag); - } - }, hashtagStart, hashtagEnd, 0); - } - } - } - - /** - * Add click listeners which opens the popup player on timestamps in a plain text. - *

- * This method finds all timestamps in the {@link SpannableStringBuilder} of the description - * using a regular expression, adds for each a {@link ClickableSpan} which opens the popup - * player at the time indicated in the timestamps. - * - * @param context the context to use - * @param spannableDescription the SpannableStringBuilder with the text of the - * content description - * @param relatedInfo what to open in the popup player when timestamps are clicked - * @param disposables disposables created by the method are added here and their - * lifecycle should be handled by the calling class - */ - private static void addClickListenersOnTimestamps(final Context context, - @NonNull final SpannableStringBuilder - spannableDescription, - final Info relatedInfo, - final CompositeDisposable disposables) { - final String descriptionText = spannableDescription.toString(); - final Matcher timestampsMatches = - TimestampExtractor.TIMESTAMPS_PATTERN.matcher(descriptionText); - - while (timestampsMatches.find()) { - final TimestampExtractor.TimestampMatchDTO timestampMatchDTO = - TimestampExtractor.getTimestampFromMatcher( - timestampsMatches, - descriptionText); - - if (timestampMatchDTO == null) { - continue; - } - - spannableDescription.setSpan( - new ClickableSpan() { - @Override - public void onClick(@NonNull final View view) { - playOnPopup( - context, - relatedInfo.getUrl(), - relatedInfo.getService(), - timestampMatchDTO.seconds(), - disposables); - } - }, - timestampMatchDTO.timestampStart(), - timestampMatchDTO.timestampEnd(), - 0); - } - } - /** * Change links generated by libraries in the description of a content to a custom link action * and add click listeners on timestamps in this description. + * *

* Instead of using an {@link android.content.Intent#ACTION_VIEW} intent in the description of * a content, this method will parse the {@link CharSequence} and replace all current web links * with {@link ShareUtils#openUrlInBrowser(Context, String, boolean)}. + *

+ * + *

* This method will also add click listeners on timestamps in this description, which will play * the content in the popup player at the time indicated in the timestamp, by using - * {@link TextLinkifier#addClickListenersOnTimestamps(Context, SpannableStringBuilder, Info, - * CompositeDisposable)} method and click listeners on hashtags, by using - * {@link TextLinkifier#addClickListenersOnHashtags(Context, SpannableStringBuilder, Info)}, + * {@link TextLinkifier#addClickListenersOnTimestamps(Context, SpannableStringBuilder, + * StreamInfo, CompositeDisposable)} method and click listeners on hashtags, by using + * {@link TextLinkifier#addClickListenersOnHashtags(Context, SpannableStringBuilder, Info)})}, * which will open a search on the current service with the hashtag. + *

+ * *

* This method is required in order to intercept links and e.g. show a confirmation dialog * before opening a web link. + *

* - * @param textView the TextView in which the converted CharSequence will be applied - * @param chars the CharSequence to be parsed - * @param relatedInfo if given, handle timestamps to open the stream in the popup player at - * the specific time, and hashtags to search for the term in the correct - * service + * @param textView the {@link TextView} in which the converted {@link CharSequence} will be + * applied + * @param chars the {@link CharSequence} to be parsed + * @param relatedInfo if given, handle timestamps to open the stream in the popup player at the + * specific time, and hashtags to search for the term in the correct service * @param disposables disposables created by the method are added here and their lifecycle * should be handled by the calling class */ - private static void changeIntentsOfDescriptionLinks(final TextView textView, - final CharSequence chars, - @Nullable final Info relatedInfo, - final CompositeDisposable disposables) { + private static void changeIntentsOfDescriptionLinks( + @NonNull final TextView textView, + @NonNull final CharSequence chars, + @Nullable final Info relatedInfo, + @NonNull final CompositeDisposable disposables) { + textView.setMovementMethod(LongPressLinkMovementMethod.getInstance()); disposables.add(Single.fromCallable(() -> { - final Context context = textView.getContext(); + final Context context = textView.getContext(); - // add custom click actions on web links - final SpannableStringBuilder textBlockLinked = new SpannableStringBuilder(chars); - final URLSpan[] urls = textBlockLinked.getSpans(0, chars.length(), URLSpan.class); + // add custom click actions on web links + final SpannableStringBuilder textBlockLinked = + new SpannableStringBuilder(chars); + final URLSpan[] urls = textBlockLinked.getSpans(0, chars.length(), + URLSpan.class); - for (final URLSpan span : urls) { - final String url = span.getURL(); - final ClickableSpan clickableSpan = new ClickableSpan() { - public void onClick(@NonNull final View view) { - if (!InternalUrlsHandler.handleUrlDescriptionTimestamp( - new CompositeDisposable(), context, url)) { - ShareUtils.openUrlInBrowser(context, url, false); - } + for (final URLSpan span : urls) { + final String url = span.getURL(); + final LongPressClickableSpan longPressClickableSpan = + new UrlLongPressClickableSpan(context, disposables, url); + + textBlockLinked.setSpan(longPressClickableSpan, + textBlockLinked.getSpanStart(span), + textBlockLinked.getSpanEnd(span), + textBlockLinked.getSpanFlags(span)); + textBlockLinked.removeSpan(span); } - }; - textBlockLinked.setSpan(clickableSpan, textBlockLinked.getSpanStart(span), - textBlockLinked.getSpanEnd(span), textBlockLinked.getSpanFlags(span)); - textBlockLinked.removeSpan(span); - } + if (relatedInfo != null) { + // add click actions on plain text timestamps only for description of + // contents, unneeded for meta-info or other TextViews + if (relatedInfo instanceof StreamInfo) { + addClickListenersOnTimestamps(context, textBlockLinked, + (StreamInfo) relatedInfo, disposables); + } - // add click actions on plain text timestamps only for description of contents, - // unneeded for meta-info or other TextViews - if (relatedInfo != null) { - if (relatedInfo instanceof StreamInfo) { - addClickListenersOnTimestamps(context, textBlockLinked, relatedInfo, - disposables); - } - addClickListenersOnHashtags(context, textBlockLinked, relatedInfo); - } + addClickListenersOnHashtags(context, textBlockLinked, relatedInfo); + } - return textBlockLinked; - }).subscribeOn(Schedulers.computation()) + return textBlockLinked; + }).subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( textBlockLinked -> setTextViewCharSequence(textView, textBlockLinked), @@ -280,10 +201,90 @@ public final class TextLinkifier { })); } + /** + * Add click listeners which opens a search on hashtags in a plain text. + * + *

+ * This method finds all timestamps in the {@link SpannableStringBuilder} of the description + * using a regular expression, adds for each a {@link LongPressClickableSpan} which opens + * {@link NavigationHelper#openSearch(Context, int, String)} and makes a search on the hashtag, + * in the service of the content when pressed, and copy the hashtag to clipboard when + * long-pressed, if allowed by the caller method (parameter {@code addLongClickCopyListener}). + *

+ * + * @param context the {@link Context} to use + * @param spannableDescription the {@link SpannableStringBuilder} with the text of the + * content description + * @param relatedInfo used to search for the term in the correct service + */ + private static void addClickListenersOnHashtags( + @NonNull final Context context, + @NonNull final SpannableStringBuilder spannableDescription, + @NonNull final Info relatedInfo) { + final String descriptionText = spannableDescription.toString(); + final Matcher hashtagsMatches = HASHTAGS_PATTERN.matcher(descriptionText); + + while (hashtagsMatches.find()) { + final int hashtagStart = hashtagsMatches.start(1); + final int hashtagEnd = hashtagsMatches.end(1); + final String parsedHashtag = descriptionText.substring(hashtagStart, hashtagEnd); + + // Don't add a LongPressClickableSpan if there is already one, which should be a part + // of an URL, already parsed before + if (spannableDescription.getSpans(hashtagStart, hashtagEnd, + LongPressClickableSpan.class).length == 0) { + spannableDescription.setSpan( + new HashtagLongPressClickableSpan(context, parsedHashtag, relatedInfo), + hashtagStart, hashtagEnd, 0); + } + } + } + + /** + * Add click listeners which opens the popup player on timestamps in a plain text. + * + *

+ * This method finds all timestamps in the {@link SpannableStringBuilder} of the description + * using a regular expression, adds for each a {@link LongPressClickableSpan} which opens the + * popup player at the time indicated in the timestamps and copy the timestamp in clipboard + * when long-pressed. + *

+ * + * @param context the {@link Context} to use + * @param spannableDescription the {@link SpannableStringBuilder} with the text of the + * content description + * @param streamInfo what to open in the popup player when timestamps are clicked + * @param disposables disposables created by the method are added here and their + * lifecycle should be handled by the calling class + */ + private static void addClickListenersOnTimestamps( + @NonNull final Context context, + @NonNull final SpannableStringBuilder spannableDescription, + @NonNull final StreamInfo streamInfo, + @NonNull final CompositeDisposable disposables) { + final String descriptionText = spannableDescription.toString(); + final Matcher timestampsMatches = TimestampExtractor.TIMESTAMPS_PATTERN.matcher( + descriptionText); + + while (timestampsMatches.find()) { + final TimestampExtractor.TimestampMatchDTO timestampMatchDTO = + TimestampExtractor.getTimestampFromMatcher(timestampsMatches, descriptionText); + + if (timestampMatchDTO == null) { + continue; + } + + spannableDescription.setSpan(new TimestampLongPressClickableSpan( + context, descriptionText, disposables, streamInfo, timestampMatchDTO), + timestampMatchDTO.timestampStart(), + timestampMatchDTO.timestampEnd(), + 0); + } + } + private static void setTextViewCharSequence(@NonNull final TextView textView, - final CharSequence charSequence) { + @Nullable final CharSequence charSequence) { textView.setText(charSequence); - textView.setMovementMethod(LinkMovementMethod.getInstance()); textView.setVisibility(View.VISIBLE); } } diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampExtractor.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampExtractor.java index a13c66402..d0862b750 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampExtractor.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampExtractor.java @@ -1,5 +1,8 @@ package org.schabi.newpipe.util.external_communication; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -15,17 +18,18 @@ public final class TimestampExtractor { } /** - * Get's a single timestamp from a matcher. + * Gets a single timestamp from a matcher. * - * @param timestampMatches The matcher which was created using {@link #TIMESTAMPS_PATTERN} - * @param baseText The text where the pattern was applied to / - * where the matcher is based upon - * @return If a match occurred: a {@link TimestampMatchDTO} filled with information.
- * If not null. + * @param timestampMatches the matcher which was created using {@link #TIMESTAMPS_PATTERN} + * @param baseText the text where the pattern was applied to / where the matcher is + * based upon + * @return if a match occurred, a {@link TimestampMatchDTO} filled with information, otherwise + * {@code null}. */ + @Nullable public static TimestampMatchDTO getTimestampFromMatcher( - final Matcher timestampMatches, - final String baseText) { + @NonNull final Matcher timestampMatches, + @NonNull final String baseText) { int timestampStart = timestampMatches.start(1); if (timestampStart == -1) { timestampStart = timestampMatches.start(2); diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampLongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampLongPressClickableSpan.java new file mode 100644 index 000000000..0ecbc8367 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampLongPressClickableSpan.java @@ -0,0 +1,75 @@ +package org.schabi.newpipe.util.external_communication; + +import static org.schabi.newpipe.util.external_communication.InternalUrlsHandler.playOnPopup; + +import android.content.Context; +import android.view.View; + +import androidx.annotation.NonNull; + +import org.schabi.newpipe.extractor.ServiceList; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.stream.StreamInfo; +import org.schabi.newpipe.views.LongPressClickableSpan; + +import io.reactivex.rxjava3.disposables.CompositeDisposable; + +final class TimestampLongPressClickableSpan extends LongPressClickableSpan { + + @NonNull + private final Context context; + @NonNull + private final String descriptionText; + @NonNull + private final CompositeDisposable disposables; + @NonNull + private final StreamInfo streamInfo; + @NonNull + private final TimestampExtractor.TimestampMatchDTO timestampMatchDTO; + + TimestampLongPressClickableSpan( + @NonNull final Context context, + @NonNull final String descriptionText, + @NonNull final CompositeDisposable disposables, + @NonNull final StreamInfo streamInfo, + @NonNull final TimestampExtractor.TimestampMatchDTO timestampMatchDTO) { + this.context = context; + this.descriptionText = descriptionText; + this.disposables = disposables; + this.streamInfo = streamInfo; + this.timestampMatchDTO = timestampMatchDTO; + } + + @Override + public void onClick(@NonNull final View view) { + playOnPopup(context, streamInfo.getUrl(), streamInfo.getService(), + timestampMatchDTO.seconds(), disposables); + } + + @Override + public void onLongClick(@NonNull final View view) { + ShareUtils.copyToClipboard(context, + getTimestampTextToCopy(streamInfo, descriptionText, timestampMatchDTO)); + } + + @NonNull + private static String getTimestampTextToCopy( + @NonNull final StreamInfo relatedInfo, + @NonNull final String descriptionText, + @NonNull final TimestampExtractor.TimestampMatchDTO timestampMatchDTO) { + // TODO: use extractor methods to get timestamps when this feature will be implemented in it + final StreamingService streamingService = relatedInfo.getService(); + if (streamingService == ServiceList.YouTube) { + return relatedInfo.getUrl() + "&t=" + timestampMatchDTO.seconds(); + } else if (streamingService == ServiceList.SoundCloud + || streamingService == ServiceList.MediaCCC) { + return relatedInfo.getUrl() + "#t=" + timestampMatchDTO.seconds(); + } else if (streamingService == ServiceList.PeerTube) { + return relatedInfo.getUrl() + "?start=" + timestampMatchDTO.seconds(); + } + + // Return timestamp text for other services + return descriptionText.subSequence(timestampMatchDTO.timestampStart(), + timestampMatchDTO.timestampEnd()).toString(); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/UrlLongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/UrlLongPressClickableSpan.java new file mode 100644 index 000000000..f6cee708f --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/UrlLongPressClickableSpan.java @@ -0,0 +1,41 @@ +package org.schabi.newpipe.util.external_communication; + +import android.content.Context; +import android.view.View; + +import androidx.annotation.NonNull; + +import org.schabi.newpipe.views.LongPressClickableSpan; + +import io.reactivex.rxjava3.disposables.CompositeDisposable; + +final class UrlLongPressClickableSpan extends LongPressClickableSpan { + + @NonNull + private final Context context; + @NonNull + private final CompositeDisposable disposables; + @NonNull + private final String url; + + UrlLongPressClickableSpan(@NonNull final Context context, + @NonNull final CompositeDisposable disposables, + @NonNull final String url) { + this.context = context; + this.disposables = disposables; + this.url = url; + } + + @Override + public void onClick(@NonNull final View view) { + if (!InternalUrlsHandler.handleUrlDescriptionTimestamp( + disposables, context, url)) { + ShareUtils.openUrlInBrowser(context, url, false); + } + } + + @Override + public void onLongClick(@NonNull final View view) { + ShareUtils.copyToClipboard(context, url); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/views/LongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/views/LongPressClickableSpan.java new file mode 100644 index 000000000..d6b927a30 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/views/LongPressClickableSpan.java @@ -0,0 +1,12 @@ +package org.schabi.newpipe.views; + +import android.text.style.ClickableSpan; +import android.view.View; + +import androidx.annotation.NonNull; + +public abstract class LongPressClickableSpan extends ClickableSpan { + + public abstract void onLongClick(@NonNull View view); + +} diff --git a/app/src/main/java/org/schabi/newpipe/views/LongPressLinkMovementMethod.java b/app/src/main/java/org/schabi/newpipe/views/LongPressLinkMovementMethod.java new file mode 100644 index 000000000..5f90284fc --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/views/LongPressLinkMovementMethod.java @@ -0,0 +1,77 @@ +package org.schabi.newpipe.views; + +import static org.schabi.newpipe.util.TouchUtils.getOffsetForHorizontalLine; + +import android.os.Handler; +import android.os.Looper; +import android.text.Selection; +import android.text.Spannable; +import android.text.method.LinkMovementMethod; +import android.text.method.MovementMethod; +import android.view.MotionEvent; +import android.view.ViewConfiguration; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +// Class adapted from https://stackoverflow.com/a/31786969 + +public class LongPressLinkMovementMethod extends LinkMovementMethod { + + private static final int LONG_PRESS_TIME = ViewConfiguration.getLongPressTimeout(); + + private static LongPressLinkMovementMethod instance; + + private Handler longClickHandler; + private boolean isLongPressed = false; + + @Override + public boolean onTouchEvent(@NonNull final TextView widget, + @NonNull final Spannable buffer, + @NonNull final MotionEvent event) { + final int action = event.getAction(); + + if (action == MotionEvent.ACTION_CANCEL && longClickHandler != null) { + longClickHandler.removeCallbacksAndMessages(null); + } + + if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { + final int offset = getOffsetForHorizontalLine(widget, event); + final LongPressClickableSpan[] link = buffer.getSpans(offset, offset, + LongPressClickableSpan.class); + + if (link.length != 0) { + if (action == MotionEvent.ACTION_UP) { + if (longClickHandler != null) { + longClickHandler.removeCallbacksAndMessages(null); + } + if (!isLongPressed) { + link[0].onClick(widget); + } + isLongPressed = false; + } else { + Selection.setSelection(buffer, buffer.getSpanStart(link[0]), + buffer.getSpanEnd(link[0])); + if (longClickHandler != null) { + longClickHandler.postDelayed(() -> { + link[0].onLongClick(widget); + isLongPressed = true; + }, LONG_PRESS_TIME); + } + } + return true; + } + } + + return super.onTouchEvent(widget, buffer, event); + } + + public static MovementMethod getInstance() { + if (instance == null) { + instance = new LongPressLinkMovementMethod(); + instance.longClickHandler = new Handler(Looper.myLooper()); + } + + return instance; + } +} diff --git a/app/src/main/java/org/schabi/newpipe/views/NewPipeEditText.java b/app/src/main/java/org/schabi/newpipe/views/NewPipeEditText.java index 2adc28d0e..f0993055e 100644 --- a/app/src/main/java/org/schabi/newpipe/views/NewPipeEditText.java +++ b/app/src/main/java/org/schabi/newpipe/views/NewPipeEditText.java @@ -13,9 +13,10 @@ import org.schabi.newpipe.util.external_communication.ShareUtils; /** * An {@link AppCompatEditText} which uses {@link ShareUtils#shareText(Context, String, String)} * when sharing selected text by using the {@code Share} command of the floating actions. + * *

- * This allows NewPipe to show Android share sheet instead of EMUI share sheet when sharing text - * from {@link AppCompatEditText} on EMUI devices. + * This class allows NewPipe to show Android share sheet instead of EMUI share sheet when sharing + * text from {@link AppCompatEditText} on EMUI devices. *

*/ public class NewPipeEditText extends AppCompatEditText { diff --git a/app/src/main/java/org/schabi/newpipe/views/NewPipeTextView.java b/app/src/main/java/org/schabi/newpipe/views/NewPipeTextView.java index 8fdac32db..dd3f20f40 100644 --- a/app/src/main/java/org/schabi/newpipe/views/NewPipeTextView.java +++ b/app/src/main/java/org/schabi/newpipe/views/NewPipeTextView.java @@ -1,6 +1,7 @@ package org.schabi.newpipe.views; import android.content.Context; +import android.text.method.MovementMethod; import android.util.AttributeSet; import androidx.annotation.NonNull; @@ -13,9 +14,11 @@ import org.schabi.newpipe.util.external_communication.ShareUtils; /** * An {@link AppCompatTextView} which uses {@link ShareUtils#shareText(Context, String, String)} * when sharing selected text by using the {@code Share} command of the floating actions. + * *

- * This allows NewPipe to show Android share sheet instead of EMUI share sheet when sharing text - * from {@link AppCompatTextView} on EMUI devices. + * This class allows NewPipe to show Android share sheet instead of EMUI share sheet when sharing + * text from {@link AppCompatTextView} on EMUI devices and also to keep movement method set when a + * text change occurs, if the text cannot be selected and text links are clickable. *

*/ public class NewPipeTextView extends AppCompatTextView { @@ -34,6 +37,16 @@ public class NewPipeTextView extends AppCompatTextView { super(context, attrs, defStyleAttr); } + @Override + public void setText(final CharSequence text, final BufferType type) { + // We need to set again the movement method after a text change because Android resets the + // movement method to the default one in the case where the text cannot be selected and + // text links are clickable (which is the default case in NewPipe). + final MovementMethod movementMethod = this.getMovementMethod(); + super.setText(text, type); + setMovementMethod(movementMethod); + } + @Override public boolean onTextContextMenuItem(final int id) { if (id == android.R.id.shareText) { diff --git a/app/src/main/res/layout/item_metadata.xml b/app/src/main/res/layout/item_metadata.xml index 31dedd880..251b9e832 100644 --- a/app/src/main/res/layout/item_metadata.xml +++ b/app/src/main/res/layout/item_metadata.xml @@ -6,7 +6,7 @@ android:layout_height="wrap_content" android:paddingVertical="6dp"> - - Importer ou exporter des abonnements à partir du menu
Vous utilisez la dernière version de NewPipe Appuyez pour télécharger %s + Échec de la copie dans le presse-papiers \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c9e0bb492..2deb14d8d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -327,6 +327,7 @@ Calculating hash Please wait… Copied to clipboard + Failed to copy to clipboard Please define a download folder later in settings No download folder set yet, choose the default download folder now This permission is needed to\nopen in popup mode From 22c201be3967cf98e9c9a0a0f9463d5ec3737e0f Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 15 Jan 2023 11:51:07 +0100 Subject: [PATCH 51/84] Create text subpackage in util --- .../newpipe/fragments/detail/DescriptionFragment.java | 2 +- .../info_list/holder/CommentsMiniInfoItemHolder.java | 4 ++-- .../java/org/schabi/newpipe/util/ExtractorHelper.java | 2 +- .../util/{ => text}/CommentTextOnTouchListener.java | 5 ++--- .../HashtagLongPressClickableSpan.java | 4 ++-- .../InternalUrlsHandler.java | 2 +- .../{views => util/text}/LongPressClickableSpan.java | 2 +- .../{views => util/text}/LongPressLinkMovementMethod.java | 4 ++-- .../{external_communication => text}/TextLinkifier.java | 8 +++----- .../TimestampExtractor.java | 2 +- .../TimestampLongPressClickableSpan.java | 6 +++--- .../org/schabi/newpipe/util/{ => text}/TouchUtils.java | 2 +- .../UrlLongPressClickableSpan.java | 4 ++-- .../external_communication/TimestampExtractorTest.java | 1 + 14 files changed, 23 insertions(+), 25 deletions(-) rename app/src/main/java/org/schabi/newpipe/util/{ => text}/CommentTextOnTouchListener.java (91%) rename app/src/main/java/org/schabi/newpipe/util/{external_communication => text}/HashtagLongPressClickableSpan.java (90%) rename app/src/main/java/org/schabi/newpipe/util/{external_communication => text}/InternalUrlsHandler.java (99%) rename app/src/main/java/org/schabi/newpipe/{views => util/text}/LongPressClickableSpan.java (86%) rename app/src/main/java/org/schabi/newpipe/{views => util/text}/LongPressLinkMovementMethod.java (95%) rename app/src/main/java/org/schabi/newpipe/util/{external_communication => text}/TextLinkifier.java (98%) rename app/src/main/java/org/schabi/newpipe/util/{external_communication => text}/TimestampExtractor.java (98%) rename app/src/main/java/org/schabi/newpipe/util/{external_communication => text}/TimestampLongPressClickableSpan.java (93%) rename app/src/main/java/org/schabi/newpipe/util/{ => text}/TouchUtils.java (96%) rename app/src/main/java/org/schabi/newpipe/util/{external_communication => text}/UrlLongPressClickableSpan.java (90%) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index 96e01c622..ea89424ec 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -29,7 +29,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; 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.external_communication.TextLinkifier; +import org.schabi.newpipe.util.text.TextLinkifier; import icepick.State; import io.reactivex.rxjava3.disposables.CompositeDisposable; diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index 92e37afd8..69aba8c4f 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -20,13 +20,13 @@ import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.comments.CommentsInfoItem; import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.util.CommentTextOnTouchListener; +import org.schabi.newpipe.util.text.CommentTextOnTouchListener; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; -import org.schabi.newpipe.util.external_communication.TimestampExtractor; +import org.schabi.newpipe.util.text.TimestampExtractor; import java.util.Objects; 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 27009efd1..2123010aa 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -51,7 +51,7 @@ import org.schabi.newpipe.extractor.search.SearchInfo; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor; -import org.schabi.newpipe.util.external_communication.TextLinkifier; +import org.schabi.newpipe.util.text.TextLinkifier; import java.util.Collections; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java b/app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java similarity index 91% rename from app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java rename to app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java index ff8875e5a..4ced4be77 100644 --- a/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java @@ -1,6 +1,6 @@ -package org.schabi.newpipe.util; +package org.schabi.newpipe.util.text; -import static org.schabi.newpipe.util.TouchUtils.getOffsetForHorizontalLine; +import static org.schabi.newpipe.util.text.TouchUtils.getOffsetForHorizontalLine; import android.text.Selection; import android.text.Spannable; @@ -12,7 +12,6 @@ import android.view.View; import android.widget.TextView; import org.schabi.newpipe.util.external_communication.ShareUtils; -import org.schabi.newpipe.util.external_communication.InternalUrlsHandler; import io.reactivex.rxjava3.disposables.CompositeDisposable; diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/HashtagLongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/util/text/HashtagLongPressClickableSpan.java similarity index 90% rename from app/src/main/java/org/schabi/newpipe/util/external_communication/HashtagLongPressClickableSpan.java rename to app/src/main/java/org/schabi/newpipe/util/text/HashtagLongPressClickableSpan.java index 9acedc12b..4ca6c326e 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/HashtagLongPressClickableSpan.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/HashtagLongPressClickableSpan.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.util.external_communication; +package org.schabi.newpipe.util.text; import android.content.Context; import android.view.View; @@ -7,7 +7,7 @@ import androidx.annotation.NonNull; import org.schabi.newpipe.extractor.Info; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.views.LongPressClickableSpan; +import org.schabi.newpipe.util.external_communication.ShareUtils; final class HashtagLongPressClickableSpan extends LongPressClickableSpan { diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/InternalUrlsHandler.java b/app/src/main/java/org/schabi/newpipe/util/text/InternalUrlsHandler.java similarity index 99% rename from app/src/main/java/org/schabi/newpipe/util/external_communication/InternalUrlsHandler.java rename to app/src/main/java/org/schabi/newpipe/util/text/InternalUrlsHandler.java index c46e6636d..b87618922 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/InternalUrlsHandler.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/InternalUrlsHandler.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.util.external_communication; +package org.schabi.newpipe.util.text; import android.content.Context; import android.util.Log; diff --git a/app/src/main/java/org/schabi/newpipe/views/LongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/util/text/LongPressClickableSpan.java similarity index 86% rename from app/src/main/java/org/schabi/newpipe/views/LongPressClickableSpan.java rename to app/src/main/java/org/schabi/newpipe/util/text/LongPressClickableSpan.java index d6b927a30..5c94a5850 100644 --- a/app/src/main/java/org/schabi/newpipe/views/LongPressClickableSpan.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/LongPressClickableSpan.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.views; +package org.schabi.newpipe.util.text; import android.text.style.ClickableSpan; import android.view.View; diff --git a/app/src/main/java/org/schabi/newpipe/views/LongPressLinkMovementMethod.java b/app/src/main/java/org/schabi/newpipe/util/text/LongPressLinkMovementMethod.java similarity index 95% rename from app/src/main/java/org/schabi/newpipe/views/LongPressLinkMovementMethod.java rename to app/src/main/java/org/schabi/newpipe/util/text/LongPressLinkMovementMethod.java index 5f90284fc..bd57621cb 100644 --- a/app/src/main/java/org/schabi/newpipe/views/LongPressLinkMovementMethod.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/LongPressLinkMovementMethod.java @@ -1,6 +1,6 @@ -package org.schabi.newpipe.views; +package org.schabi.newpipe.util.text; -import static org.schabi.newpipe.util.TouchUtils.getOffsetForHorizontalLine; +import static org.schabi.newpipe.util.text.TouchUtils.getOffsetForHorizontalLine; import android.os.Handler; import android.os.Looper; diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java b/app/src/main/java/org/schabi/newpipe/util/text/TextLinkifier.java similarity index 98% rename from app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java rename to app/src/main/java/org/schabi/newpipe/util/text/TextLinkifier.java index 1bbd37cf5..b7220d22f 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/TextLinkifier.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.util.external_communication; +package org.schabi.newpipe.util.text; import android.content.Context; import android.text.SpannableStringBuilder; @@ -15,8 +15,7 @@ import androidx.core.text.HtmlCompat; import org.schabi.newpipe.extractor.Info; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.views.LongPressClickableSpan; -import org.schabi.newpipe.views.LongPressLinkMovementMethod; +import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -88,8 +87,7 @@ public final class TextLinkifier { @NonNull final CompositeDisposable disposables) { textView.setAutoLinkMask(Linkify.WEB_URLS); textView.setText(plainTextBlock, TextView.BufferType.SPANNABLE); - changeIntentsOfDescriptionLinks(textView, textView.getText(), relatedInfo, disposables - ); + changeIntentsOfDescriptionLinks(textView, textView.getText(), relatedInfo, disposables); } /** diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampExtractor.java b/app/src/main/java/org/schabi/newpipe/util/text/TimestampExtractor.java similarity index 98% rename from app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampExtractor.java rename to app/src/main/java/org/schabi/newpipe/util/text/TimestampExtractor.java index d0862b750..be603f41a 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampExtractor.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/TimestampExtractor.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.util.external_communication; +package org.schabi.newpipe.util.text; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampLongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/util/text/TimestampLongPressClickableSpan.java similarity index 93% rename from app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampLongPressClickableSpan.java rename to app/src/main/java/org/schabi/newpipe/util/text/TimestampLongPressClickableSpan.java index 0ecbc8367..48110312d 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/TimestampLongPressClickableSpan.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/TimestampLongPressClickableSpan.java @@ -1,6 +1,6 @@ -package org.schabi.newpipe.util.external_communication; +package org.schabi.newpipe.util.text; -import static org.schabi.newpipe.util.external_communication.InternalUrlsHandler.playOnPopup; +import static org.schabi.newpipe.util.text.InternalUrlsHandler.playOnPopup; import android.content.Context; import android.view.View; @@ -10,7 +10,7 @@ import androidx.annotation.NonNull; import org.schabi.newpipe.extractor.ServiceList; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.stream.StreamInfo; -import org.schabi.newpipe.views.LongPressClickableSpan; +import org.schabi.newpipe.util.external_communication.ShareUtils; import io.reactivex.rxjava3.disposables.CompositeDisposable; diff --git a/app/src/main/java/org/schabi/newpipe/util/TouchUtils.java b/app/src/main/java/org/schabi/newpipe/util/text/TouchUtils.java similarity index 96% rename from app/src/main/java/org/schabi/newpipe/util/TouchUtils.java rename to app/src/main/java/org/schabi/newpipe/util/text/TouchUtils.java index 23bc5a401..5c0db20a3 100644 --- a/app/src/main/java/org/schabi/newpipe/util/TouchUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/TouchUtils.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.util; +package org.schabi.newpipe.util.text; import android.text.Layout; import android.view.MotionEvent; diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/UrlLongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/util/text/UrlLongPressClickableSpan.java similarity index 90% rename from app/src/main/java/org/schabi/newpipe/util/external_communication/UrlLongPressClickableSpan.java rename to app/src/main/java/org/schabi/newpipe/util/text/UrlLongPressClickableSpan.java index f6cee708f..eb0d7425e 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/UrlLongPressClickableSpan.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/UrlLongPressClickableSpan.java @@ -1,11 +1,11 @@ -package org.schabi.newpipe.util.external_communication; +package org.schabi.newpipe.util.text; import android.content.Context; import android.view.View; import androidx.annotation.NonNull; -import org.schabi.newpipe.views.LongPressClickableSpan; +import org.schabi.newpipe.util.external_communication.ShareUtils; import io.reactivex.rxjava3.disposables.CompositeDisposable; diff --git a/app/src/test/java/org/schabi/newpipe/util/external_communication/TimestampExtractorTest.java b/app/src/test/java/org/schabi/newpipe/util/external_communication/TimestampExtractorTest.java index 10e23883f..47853bd7f 100644 --- a/app/src/test/java/org/schabi/newpipe/util/external_communication/TimestampExtractorTest.java +++ b/app/src/test/java/org/schabi/newpipe/util/external_communication/TimestampExtractorTest.java @@ -3,6 +3,7 @@ package org.schabi.newpipe.util.external_communication; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import org.schabi.newpipe.util.text.TimestampExtractor; import java.time.Duration; import java.util.Arrays; From 7924bb5b6b039509931d5035c172645495f5391d Mon Sep 17 00:00:00 2001 From: Mahendran Date: Thu, 3 Nov 2022 00:26:10 +0530 Subject: [PATCH 52/84] Thumbnails used in NewPipe are small (list/grid) mode. This PR facilitates full width thumbnails and dubbed as card mode. --- .../fragments/list/BaseListFragment.java | 31 +++--- .../list/comments/CommentsFragment.java | 5 +- .../list/playlist/PlaylistFragment.java | 2 + .../list/videos/RelatedItemsFragment.java | 10 +- .../newpipe/info_list/InfoListAdapter.java | 46 +++++++-- .../newpipe/info_list/ItemViewMode.java | 23 +++++ .../holder/PlaylistCardInfoItemHolder.java | 17 ++++ .../holder/StreamCardInfoItemHolder.java | 16 +++ .../newpipe/local/BaseLocalListFragment.java | 24 +++-- .../newpipe/local/LocalItemListAdapter.java | 69 ++++++++++--- .../schabi/newpipe/local/feed/FeedFragment.kt | 11 ++- .../newpipe/local/feed/item/StreamItem.kt | 3 +- .../holder/LocalPlaylistCardItemHolder.java | 17 ++++ .../LocalPlaylistStreamCardItemHolder.java | 17 ++++ .../LocalStatisticStreamCardItemHolder.java | 13 +++ .../holder/RemotePlaylistCardItemHolder.java | 17 ++++ .../org/schabi/newpipe/util/ThemeHelper.java | 47 ++++++--- .../res/layout/list_playlist_card_item.xml | 92 +++++++++++++++++ .../main/res/layout/list_stream_card_item.xml | 99 +++++++++++++++++++ .../layout/list_stream_playlist_card_item.xml | 96 ++++++++++++++++++ app/src/main/res/values-w820dp/dimens.xml | 3 + app/src/main/res/values/dimens.xml | 8 ++ app/src/main/res/values/settings_keys.xml | 3 + app/src/main/res/values/strings.xml | 1 + 24 files changed, 601 insertions(+), 69 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/info_list/ItemViewMode.java create mode 100644 app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistCardInfoItemHolder.java create mode 100644 app/src/main/java/org/schabi/newpipe/info_list/holder/StreamCardInfoItemHolder.java create mode 100644 app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistCardItemHolder.java create mode 100644 app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamCardItemHolder.java create mode 100644 app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamCardItemHolder.java create mode 100644 app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistCardItemHolder.java create mode 100644 app/src/main/res/layout/list_playlist_card_item.xml create mode 100644 app/src/main/res/layout/list_stream_card_item.xml create mode 100644 app/src/main/res/layout/list_stream_playlist_card_item.xml diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index 1212cf4ad..0b0acff86 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -26,6 +26,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.fragments.BaseStateFragment; import org.schabi.newpipe.fragments.OnScrollBelowItemsListener; import org.schabi.newpipe.info_list.InfoListAdapter; +import org.schabi.newpipe.info_list.ItemViewMode; import org.schabi.newpipe.info_list.dialog.InfoItemDialog; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.OnClickGesture; @@ -91,11 +92,7 @@ public abstract class BaseListFragment extends BaseStateFragment if (updateFlags != 0) { if ((updateFlags & LIST_MODE_UPDATE_FLAG) != 0) { - final boolean useGrid = isGridLayout(); - itemsList.setLayoutManager(useGrid - ? getGridLayoutManager() : getListLayoutManager()); - infoListAdapter.setUseGridVariant(useGrid); - infoListAdapter.notifyDataSetChanged(); + refreshItemViewMode(); } updateFlags = 0; } @@ -221,15 +218,23 @@ public abstract class BaseListFragment extends BaseStateFragment return lm; } + /** + * Updates the item view mode based on user preference. + */ + private void refreshItemViewMode() { + final ItemViewMode itemViewMode = getItemViewMode(); + itemsList.setLayoutManager((itemViewMode == ItemViewMode.GRID) + ? getGridLayoutManager() : getListLayoutManager()); + infoListAdapter.setItemViewMode(itemViewMode); + infoListAdapter.notifyDataSetChanged(); + } + @Override protected void initViews(final View rootView, final Bundle savedInstanceState) { super.initViews(rootView, savedInstanceState); - final boolean useGrid = isGridLayout(); itemsList = rootView.findViewById(R.id.items_list); - itemsList.setLayoutManager(useGrid ? getGridLayoutManager() : getListLayoutManager()); - - infoListAdapter.setUseGridVariant(useGrid); + refreshItemViewMode(); final Supplier listHeaderSupplier = getListHeaderSupplier(); if (listHeaderSupplier != null) { @@ -474,7 +479,11 @@ public abstract class BaseListFragment extends BaseStateFragment } } - protected boolean isGridLayout() { - return ThemeHelper.shouldUseGridLayout(activity); + /** + * Returns preferred item view mode. + * @return ItemViewMode + */ + protected ItemViewMode getItemViewMode() { + return ThemeHelper.getItemViewMode(requireContext()); } } 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 3b092cc28..5a5f84968 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 @@ -17,6 +17,7 @@ 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.ktx.ViewUtils; import org.schabi.newpipe.util.ExtractorHelper; @@ -106,7 +107,7 @@ public class CommentsFragment extends BaseListInfoFragment headerSupplier = null; public InfoListAdapter(final Context context) { @@ -114,8 +119,8 @@ public class InfoListAdapter extends RecyclerView.Adapter data) { @@ -234,14 +239,33 @@ public class InfoListAdapter extends RecyclerView.Adapter extends BaseStateFragment super.onResume(); if (updateFlags != 0) { if ((updateFlags & LIST_MODE_UPDATE_FLAG) != 0) { - final boolean useGrid = shouldUseGridLayout(requireContext()); - itemsList.setLayoutManager( - useGrid ? getGridLayoutManager() : getListLayoutManager()); - itemListAdapter.setUseGridVariant(useGrid); - itemListAdapter.notifyDataSetChanged(); + refreshItemViewMode(); } updateFlags = 0; } } + /** + * Updates the item view mode based on user preference. + */ + private void refreshItemViewMode() { + final ItemViewMode itemViewMode = getItemViewMode(requireContext()); + itemsList.setLayoutManager((itemViewMode == ItemViewMode.GRID) + ? getGridLayoutManager() : getListLayoutManager()); + itemListAdapter.setItemViewMode(itemViewMode); + itemListAdapter.notifyDataSetChanged(); + } + /*////////////////////////////////////////////////////////////////////////// // Lifecycle - View //////////////////////////////////////////////////////////////////////////*/ @@ -120,11 +128,9 @@ public abstract class BaseLocalListFragment extends BaseStateFragment itemListAdapter = new LocalItemListAdapter(activity); - final boolean useGrid = shouldUseGridLayout(requireContext()); itemsList = rootView.findViewById(R.id.items_list); - itemsList.setLayoutManager(useGrid ? getGridLayoutManager() : getListLayoutManager()); + refreshItemViewMode(); - itemListAdapter.setUseGridVariant(useGrid); headerRootBinding = getListHeader(); if (headerRootBinding != null) { itemListAdapter.setHeader(headerRootBinding.getRoot()); diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java index 05e2fdac0..b9409cb9d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java @@ -12,14 +12,19 @@ import androidx.recyclerview.widget.RecyclerView; import org.schabi.newpipe.database.LocalItem; import org.schabi.newpipe.database.stream.model.StreamStateEntity; +import org.schabi.newpipe.info_list.ItemViewMode; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.holder.LocalItemHolder; +import org.schabi.newpipe.local.holder.LocalPlaylistCardItemHolder; import org.schabi.newpipe.local.holder.LocalPlaylistGridItemHolder; import org.schabi.newpipe.local.holder.LocalPlaylistItemHolder; +import org.schabi.newpipe.local.holder.LocalPlaylistStreamCardItemHolder; import org.schabi.newpipe.local.holder.LocalPlaylistStreamGridItemHolder; import org.schabi.newpipe.local.holder.LocalPlaylistStreamItemHolder; +import org.schabi.newpipe.local.holder.LocalStatisticStreamCardItemHolder; import org.schabi.newpipe.local.holder.LocalStatisticStreamGridItemHolder; import org.schabi.newpipe.local.holder.LocalStatisticStreamItemHolder; +import org.schabi.newpipe.local.holder.RemotePlaylistCardItemHolder; import org.schabi.newpipe.local.holder.RemotePlaylistGridItemHolder; import org.schabi.newpipe.local.holder.RemotePlaylistItemHolder; import org.schabi.newpipe.util.FallbackViewHolder; @@ -61,11 +66,17 @@ public class LocalItemListAdapter extends RecyclerView.Adapter localItems; @@ -73,9 +84,9 @@ public class LocalItemListAdapter extends RecyclerView.Adapter() { @SuppressLint("StringFormatMatches") private fun handleLoadedState(loadedState: FeedState.LoadedState) { - - val itemVersion = if (shouldUseGridLayout(context)) { - StreamItem.ItemVersion.GRID - } else { - StreamItem.ItemVersion.NORMAL + val itemVersion = when (getItemViewMode(requireContext())) { + ItemViewMode.GRID -> StreamItem.ItemVersion.GRID + ItemViewMode.CARD -> StreamItem.ItemVersion.CARD + else -> StreamItem.ItemVersion.NORMAL } loadedState.items.forEach { it.itemVersion = itemVersion } diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt index 96d395aa5..d795dcb08 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt @@ -42,12 +42,13 @@ data class StreamItem( override fun getId(): Long = stream.uid - enum class ItemVersion { NORMAL, MINI, GRID } + enum class ItemVersion { NORMAL, MINI, GRID, CARD } override fun getLayout(): Int = when (itemVersion) { ItemVersion.NORMAL -> R.layout.list_stream_item ItemVersion.MINI -> R.layout.list_stream_mini_item ItemVersion.GRID -> R.layout.list_stream_grid_item + ItemVersion.CARD -> R.layout.list_stream_card_item } override fun initializeViewBinding(view: View) = ListStreamItemBinding.bind(view) diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistCardItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistCardItemHolder.java new file mode 100644 index 000000000..33418ec98 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistCardItemHolder.java @@ -0,0 +1,17 @@ +package org.schabi.newpipe.local.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.local.LocalItemBuilder; + +/** + * Playlist card layout. + */ +public class LocalPlaylistCardItemHolder extends LocalPlaylistItemHolder { + + public LocalPlaylistCardItemHolder(final LocalItemBuilder infoItemBuilder, + final ViewGroup parent) { + super(infoItemBuilder, R.layout.list_playlist_card_item, parent); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamCardItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamCardItemHolder.java new file mode 100644 index 000000000..7f81a527f --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamCardItemHolder.java @@ -0,0 +1,17 @@ +package org.schabi.newpipe.local.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.local.LocalItemBuilder; + +/** + * Local playlist stream UI. This also includes a handle to rearrange the videos. + */ +public class LocalPlaylistStreamCardItemHolder extends LocalPlaylistStreamItemHolder { + + public LocalPlaylistStreamCardItemHolder(final LocalItemBuilder infoItemBuilder, + final ViewGroup parent) { + super(infoItemBuilder, R.layout.list_stream_playlist_card_item, parent); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamCardItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamCardItemHolder.java new file mode 100644 index 000000000..4e03d5fb1 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamCardItemHolder.java @@ -0,0 +1,13 @@ +package org.schabi.newpipe.local.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.local.LocalItemBuilder; + +public class LocalStatisticStreamCardItemHolder extends LocalStatisticStreamItemHolder { + public LocalStatisticStreamCardItemHolder(final LocalItemBuilder infoItemBuilder, + final ViewGroup parent) { + super(infoItemBuilder, R.layout.list_stream_card_item, parent); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistCardItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistCardItemHolder.java new file mode 100644 index 000000000..74a67c3db --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistCardItemHolder.java @@ -0,0 +1,17 @@ +package org.schabi.newpipe.local.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.local.LocalItemBuilder; + +/** + * Playlist card UI for list item. + */ +public class RemotePlaylistCardItemHolder extends RemotePlaylistItemHolder { + + public RemotePlaylistCardItemHolder(final LocalItemBuilder infoItemBuilder, + final ViewGroup parent) { + super(infoItemBuilder, R.layout.list_playlist_card_item, parent); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java index ea22e9368..ab74e0305 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java @@ -41,6 +41,7 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.exceptions.ExtractionException; +import org.schabi.newpipe.info_list.ItemViewMode; public final class ThemeHelper { private ThemeHelper() { @@ -332,7 +333,6 @@ public final class ThemeHelper { } } - /** * Returns whether the grid layout or the list layout should be used. If the user set "auto" * mode in settings, decides based on screen orientation (landscape) and size. @@ -341,19 +341,8 @@ public final class ThemeHelper { * @return true:use grid layout, false:use list layout */ public static boolean shouldUseGridLayout(final Context context) { - final String listMode = PreferenceManager.getDefaultSharedPreferences(context) - .getString(context.getString(R.string.list_view_mode_key), - context.getString(R.string.list_view_mode_value)); - - if (listMode.equals(context.getString(R.string.list_view_mode_list_key))) { - return false; - } else if (listMode.equals(context.getString(R.string.list_view_mode_grid_key))) { - return true; - } else /* listMode.equals("auto") */ { - final Configuration configuration = context.getResources().getConfiguration(); - return configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - && configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE); - } + final ItemViewMode mode = getItemViewMode(context); + return mode == ItemViewMode.GRID; } /** @@ -367,6 +356,36 @@ public final class ThemeHelper { context.getResources().getDimensionPixelSize(R.dimen.channel_item_grid_min_width)); } + /** + * Returns item view mode. + * @param context to read preference and parse string + * @return Returns one of ItemViewMode + */ + public static ItemViewMode getItemViewMode(final Context context) { + final String listMode = PreferenceManager.getDefaultSharedPreferences(context) + .getString(context.getString(R.string.list_view_mode_key), + context.getString(R.string.list_view_mode_value)); + final ItemViewMode result; + if (listMode.equals(context.getString(R.string.list_view_mode_list_key))) { + result = ItemViewMode.LIST; + } else if (listMode.equals(context.getString(R.string.list_view_mode_grid_key))) { + result = ItemViewMode.GRID; + } else if (listMode.equals(context.getString(R.string.list_view_mode_card_key))) { + result = ItemViewMode.CARD; + } else { + // Auto mode - evaluate whether to use Grid based on screen real estate. + final Configuration configuration = context.getResources().getConfiguration(); + final boolean useGrid = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + && configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE); + if (useGrid) { + result = ItemViewMode.GRID; + } else { + result = ItemViewMode.LIST; + } + } + return result; + } + /** * Calculates the number of grid stream info items that can fit horizontally on the screen. The * width of a grid stream info item is obtained from the thumbnail width plus the right and left diff --git a/app/src/main/res/layout/list_playlist_card_item.xml b/app/src/main/res/layout/list_playlist_card_item.xml new file mode 100644 index 000000000..c7dd4f17c --- /dev/null +++ b/app/src/main/res/layout/list_playlist_card_item.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/list_stream_card_item.xml b/app/src/main/res/layout/list_stream_card_item.xml new file mode 100644 index 000000000..968dca082 --- /dev/null +++ b/app/src/main/res/layout/list_stream_card_item.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/list_stream_playlist_card_item.xml b/app/src/main/res/layout/list_stream_playlist_card_item.xml new file mode 100644 index 000000000..9cc6b326c --- /dev/null +++ b/app/src/main/res/layout/list_stream_playlist_card_item.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml index 63fc81644..817cd8f85 100644 --- a/app/src/main/res/values-w820dp/dimens.xml +++ b/app/src/main/res/values-w820dp/dimens.xml @@ -3,4 +3,7 @@ (such as screen margins) for screens with more than 820dp of available width. This would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> 64dp + + 280dp + 160dp diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 5693ec7c4..679dc05eb 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,5 +1,13 @@ + + 16dp + 8dp + 32dp + 8dp + 4dp + 2dp + 120dp 16dp diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 17ed547a0..1a711ad17 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -1263,16 +1263,19 @@ auto list grid + card @string/list_view_mode_auto_key @string/list_view_mode_list_key @string/list_view_mode_grid_key + @string/list_view_mode_card_key @string/auto @string/list @string/grid + @string/card tablet_mode diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2deb14d8d..5a4ce92f2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -550,6 +550,7 @@ List view mode List Grid + Card Auto Seekbar thumbnail preview From 489df0ed7deb3f3f008e9d74e194d381f3b5880b Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 5 Jan 2023 19:01:38 +0100 Subject: [PATCH 53/84] Update NewPipeExtractor and properly linkify comments --- app/build.gradle | 2 +- .../fragments/detail/DescriptionFragment.java | 31 +-- .../holder/CommentsMiniInfoItemHolder.java | 134 +++++----- .../schabi/newpipe/util/ExtractorHelper.java | 6 +- .../util/text/CommentTextOnTouchListener.java | 30 +-- .../text/HashtagLongPressClickableSpan.java | 10 +- .../newpipe/util/text/TextLinkifier.java | 247 ++++++++++++------ .../text/TimestampLongPressClickableSpan.java | 35 +-- 8 files changed, 278 insertions(+), 217 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 6066bce43..a76d986fb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -187,7 +187,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:2211a24b6934a8a8cdf5547ea1b52daa4cb5de6c' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:ff94e9f30bc5d7831734cc85ecebe7d30ac9c040' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index ea89424ec..d364c0c0f 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -4,6 +4,7 @@ import static android.text.TextUtils.isEmpty; import static org.schabi.newpipe.extractor.stream.StreamExtractor.NO_AGE_LIMIT; import static org.schabi.newpipe.extractor.utils.Utils.isBlank; import static org.schabi.newpipe.util.Localization.getAppLocale; +import static org.schabi.newpipe.util.text.TextLinkifier.SET_LINK_MOVEMENT_METHOD; import android.os.Bundle; import android.view.LayoutInflater; @@ -112,7 +113,10 @@ public class DescriptionFragment extends BaseFragment { private void disableDescriptionSelection() { // show description content again, otherwise some links are not clickable - loadDescriptionContent(); + TextLinkifier.fromDescription(binding.detailDescriptionView, + streamInfo.getDescription(), HtmlCompat.FROM_HTML_MODE_LEGACY, + streamInfo.getService(), streamInfo.getUrl(), + descriptionDisposables, SET_LINK_MOVEMENT_METHOD); binding.detailDescriptionNoteView.setVisibility(View.GONE); binding.detailDescriptionView.setTextIsSelectable(false); @@ -123,27 +127,6 @@ public class DescriptionFragment extends BaseFragment { binding.detailSelectDescriptionButton.setImageResource(R.drawable.ic_select_all); } - private void loadDescriptionContent() { - final Description description = streamInfo.getDescription(); - switch (description.getType()) { - case Description.HTML: - TextLinkifier.createLinksFromHtmlBlock(binding.detailDescriptionView, - description.getContent(), HtmlCompat.FROM_HTML_MODE_LEGACY, streamInfo, - descriptionDisposables); - break; - case Description.MARKDOWN: - TextLinkifier.createLinksFromMarkdownText(binding.detailDescriptionView, - description.getContent(), streamInfo, descriptionDisposables); - break; - case Description.PLAIN_TEXT: - default: - TextLinkifier.createLinksFromPlainText(binding.detailDescriptionView, - description.getContent(), streamInfo, descriptionDisposables); - break; - } - } - - private void setupMetadata(final LayoutInflater inflater, final LinearLayout layout) { addMetadataItem(inflater, layout, false, R.string.metadata_category, @@ -193,8 +176,8 @@ public class DescriptionFragment extends BaseFragment { }); if (linkifyContent) { - TextLinkifier.createLinksFromPlainText(itemBinding.metadataContentView, content, - null, descriptionDisposables); + TextLinkifier.fromPlainText(itemBinding.metadataContentView, content, null, null, + descriptionDisposables, SET_LINK_MOVEMENT_METHOD); } else { itemBinding.metadataContentView.setText(content); } diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index 69aba8c4f..fe04ac7ee 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -1,9 +1,10 @@ package org.schabi.newpipe.info_list.holder; +import android.graphics.Paint; +import android.text.Layout; import android.text.TextUtils; import android.text.method.LinkMovementMethod; import android.text.style.URLSpan; -import android.text.util.Linkify; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -11,33 +12,43 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import androidx.core.text.util.LinkifyCompat; +import androidx.core.text.HtmlCompat; import org.schabi.newpipe.R; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.extractor.InfoItem; +import org.schabi.newpipe.extractor.NewPipe; +import org.schabi.newpipe.extractor.ServiceList; +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.stream.Description; import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.util.text.CommentTextOnTouchListener; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; -import org.schabi.newpipe.util.text.TimestampExtractor; +import org.schabi.newpipe.util.text.CommentTextOnTouchListener; +import org.schabi.newpipe.util.text.TextLinkifier; -import java.util.Objects; +import java.util.function.Consumer; + +import io.reactivex.rxjava3.disposables.CompositeDisposable; public class CommentsMiniInfoItemHolder extends InfoItemHolder { private static final String TAG = "CommentsMiniIIHolder"; + 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 float ellipsisWidthPx; private final RelativeLayout itemRoot; private final ImageView itemThumbnailView; @@ -45,7 +56,9 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { private final TextView itemLikesCountView; private final TextView itemPublishedTime; - private String commentText; + private final CompositeDisposable disposables = new CompositeDisposable(); + private Description commentText; + private StreamingService streamService; private String streamUrl; CommentsMiniInfoItemHolder(final InfoItemBuilder infoItemBuilder, final int layoutId, @@ -62,6 +75,10 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { .getResources().getDimension(R.dimen.comments_horizontal_padding); commentVerticalPadding = (int) infoItemBuilder.getContext() .getResources().getDimension(R.dimen.comments_vertical_padding); + + final Paint paint = new Paint(); + paint.setTextSize(itemContentView.getTextSize()); + ellipsisWidthPx = paint.measureText(ELLIPSIS); } public CommentsMiniInfoItemHolder(final InfoItemBuilder infoItemBuilder, @@ -91,18 +108,20 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { itemThumbnailView.setOnClickListener(view -> openCommentAuthor(item)); - streamUrl = item.getUrl(); - - itemContentView.setLines(COMMENT_DEFAULT_LINES); - commentText = item.getCommentText(); - itemContentView.setText(commentText, TextView.BufferType.SPANNABLE); - itemContentView.setOnTouchListener(CommentTextOnTouchListener.INSTANCE); - - if (itemContentView.getLineCount() == 0) { - itemContentView.post(this::ellipsize); - } else { - ellipsize(); + try { + streamService = NewPipe.getService(item.getServiceId()); + } catch (final ExtractionException e) { + // should never happen + ErrorUtil.showUiErrorSnackbar(itemBuilder.getContext(), "Getting StreamingService", e); + Log.w(TAG, "Cannot obtain service from comment service id, defaulting to YouTube", e); + streamService = ServiceList.YouTube; } + streamUrl = item.getUrl(); + commentText = item.getCommentText(); + ellipsize(); + + //noinspection ClickableViewAccessibility + itemContentView.setOnTouchListener(CommentTextOnTouchListener.INSTANCE); if (item.getLikeCount() >= 0) { itemLikesCountView.setText( @@ -132,7 +151,8 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { if (DeviceUtils.isTv(itemBuilder.getContext())) { openCommentAuthor(item); } else { - ShareUtils.copyToClipboard(itemBuilder.getContext(), commentText); + ShareUtils.copyToClipboard(itemBuilder.getContext(), + itemContentView.getText().toString()); } return true; }); @@ -172,7 +192,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { return urls != null && urls.length != 0; } - private void determineLinkFocus() { + private void determineMovementMethod() { if (shouldFocusLinks()) { allowLinkFocus(); } else { @@ -181,63 +201,51 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { } private void ellipsize() { - boolean hasEllipsis = false; + linkifyCommentContentView(v -> { + boolean hasEllipsis = false; - if (itemContentView.getLineCount() > COMMENT_DEFAULT_LINES) { - final int endOfLastLine = itemContentView - .getLayout() - .getLineEnd(COMMENT_DEFAULT_LINES - 1); - int end = itemContentView.getText().toString().lastIndexOf(' ', endOfLastLine - 2); - if (end == -1) { - end = Math.max(endOfLastLine - 2, 0); + if (itemContentView.getLineCount() > COMMENT_DEFAULT_LINES) { + final int endOfLastLine = itemContentView + .getLayout() + .getLineEnd(COMMENT_DEFAULT_LINES - 1); + int end = itemContentView.getText().toString().lastIndexOf(' ', endOfLastLine - 2); + if (end == -1) { + end = Math.max(endOfLastLine - 2, 0); + } + final String newVal = itemContentView.getText().subSequence(0, end) + " …"; + itemContentView.setText(newVal); + hasEllipsis = true; } - final String newVal = itemContentView.getText().subSequence(0, end) + " …"; - itemContentView.setText(newVal); - hasEllipsis = true; - } - linkify(); - - if (hasEllipsis) { - denyLinkFocus(); - } else { - determineLinkFocus(); - } + itemContentView.setMaxLines(COMMENT_DEFAULT_LINES); + if (hasEllipsis) { + denyLinkFocus(); + } else { + determineMovementMethod(); + } + }); } private void toggleEllipsize() { - if (itemContentView.getText().toString().equals(commentText)) { - if (itemContentView.getLineCount() > COMMENT_DEFAULT_LINES) { - ellipsize(); - } - } else { + final CharSequence text = itemContentView.getText(); + if (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); - itemContentView.setText(commentText); - linkify(); - determineLinkFocus(); + linkifyCommentContentView(v -> determineMovementMethod()); } - private void linkify() { - LinkifyCompat.addLinks(itemContentView, Linkify.WEB_URLS); - LinkifyCompat.addLinks(itemContentView, TimestampExtractor.TIMESTAMPS_PATTERN, null, null, - (match, url) -> { - try { - final var timestampMatch = TimestampExtractor - .getTimestampFromMatcher(match, commentText); - if (timestampMatch == null) { - return url; - } - return streamUrl + url.replace(Objects.requireNonNull(match.group(0)), - "#timestamp=" + timestampMatch.seconds()); - } catch (final Exception ex) { - Log.e(TAG, "Unable to process url='" + url + "' as timestampLink", ex); - return url; - } - }); + 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/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java index 2123010aa..d5d472d6f 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -20,6 +20,7 @@ package org.schabi.newpipe.util; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; +import static org.schabi.newpipe.util.text.TextLinkifier.SET_LINK_MOVEMENT_METHOD; import android.content.Context; import android.util.Log; @@ -319,8 +320,9 @@ public final class ExtractorHelper { } metaInfoSeparator.setVisibility(View.VISIBLE); - TextLinkifier.createLinksFromHtmlBlock(metaInfoTextView, stringBuilder.toString(), - HtmlCompat.FROM_HTML_SEPARATOR_LINE_BREAK_HEADING, null, disposables); + TextLinkifier.fromHtml(metaInfoTextView, stringBuilder.toString(), + HtmlCompat.FROM_HTML_SEPARATOR_LINE_BREAK_HEADING, null, null, disposables, + SET_LINK_MOVEMENT_METHOD); } } diff --git a/app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java b/app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java index 4ced4be77..5018a6120 100644 --- a/app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java @@ -2,51 +2,37 @@ package org.schabi.newpipe.util.text; import static org.schabi.newpipe.util.text.TouchUtils.getOffsetForHorizontalLine; -import android.text.Selection; -import android.text.Spannable; +import android.annotation.SuppressLint; import android.text.Spanned; import android.text.style.ClickableSpan; -import android.text.style.URLSpan; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; -import org.schabi.newpipe.util.external_communication.ShareUtils; - -import io.reactivex.rxjava3.disposables.CompositeDisposable; - public class CommentTextOnTouchListener implements View.OnTouchListener { public static final CommentTextOnTouchListener INSTANCE = new CommentTextOnTouchListener(); + @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(final View v, final MotionEvent event) { if (!(v instanceof TextView)) { return false; } final TextView widget = (TextView) v; - final Object text = widget.getText(); + final CharSequence text = widget.getText(); if (text instanceof Spanned) { - final Spannable buffer = (Spannable) text; - + final Spanned buffer = (Spanned) text; final int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { final int offset = getOffsetForHorizontalLine(widget, event); - final ClickableSpan[] link = buffer.getSpans(offset, offset, ClickableSpan.class); + final ClickableSpan[] links = buffer.getSpans(offset, offset, ClickableSpan.class); - if (link.length != 0) { + if (links.length != 0) { if (action == MotionEvent.ACTION_UP) { - if (link[0] instanceof URLSpan) { - final String url = ((URLSpan) link[0]).getURL(); - if (!InternalUrlsHandler.handleUrlCommentsTimestamp( - new CompositeDisposable(), v.getContext(), url)) { - ShareUtils.openUrlInBrowser(v.getContext(), url, false); - } - } - } else if (action == MotionEvent.ACTION_DOWN) { - Selection.setSelection(buffer, buffer.getSpanStart(link[0]), - buffer.getSpanEnd(link[0])); + links[0].onClick(widget); } + // we handle events that intersect links, so return true return true; } } diff --git a/app/src/main/java/org/schabi/newpipe/util/text/HashtagLongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/util/text/HashtagLongPressClickableSpan.java index 4ca6c326e..8a0363ecb 100644 --- a/app/src/main/java/org/schabi/newpipe/util/text/HashtagLongPressClickableSpan.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/HashtagLongPressClickableSpan.java @@ -5,7 +5,6 @@ import android.view.View; import androidx.annotation.NonNull; -import org.schabi.newpipe.extractor.Info; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; @@ -15,20 +14,19 @@ final class HashtagLongPressClickableSpan extends LongPressClickableSpan { private final Context context; @NonNull private final String parsedHashtag; - @NonNull - private final Info relatedInfo; + private final int relatedInfoServiceId; HashtagLongPressClickableSpan(@NonNull final Context context, @NonNull final String parsedHashtag, - @NonNull final Info relatedInfo) { + final int relatedInfoServiceId) { this.context = context; this.parsedHashtag = parsedHashtag; - this.relatedInfo = relatedInfo; + this.relatedInfoServiceId = relatedInfoServiceId; } @Override public void onClick(@NonNull final View view) { - NavigationHelper.openSearch(context, relatedInfo.getServiceId(), parsedHashtag); + NavigationHelper.openSearch(context, relatedInfoServiceId, parsedHashtag); } @Override 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 b7220d22f..e59a3dc05 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 @@ -12,11 +12,12 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.text.HtmlCompat; -import org.schabi.newpipe.extractor.Info; -import org.schabi.newpipe.extractor.stream.StreamInfo; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; +import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -33,88 +34,155 @@ public final class TextLinkifier { // Looks for hashtags with characters from any language (\p{L}), numbers, or underscores private static final Pattern HASHTAGS_PATTERN = Pattern.compile("(#[\\p{L}0-9_]+)"); + public static final Consumer SET_LINK_MOVEMENT_METHOD = + v -> v.setMovementMethod(LongPressLinkMovementMethod.getInstance()); + private TextLinkifier() { } + /** + * Create links for contents with an {@link Description} in the various possible formats. + *

+ * This will call one of these three functions based on the format: {@link #fromHtml}, + * {@link #fromMarkdown} or {@link #fromPlainText}. + * + * @param textView the TextView to set the htmlBlock linked + * @param description the htmlBlock to be linked + * @param htmlCompatFlag the int flag to be set if {@link HtmlCompat#fromHtml(String, int)} + * will be called (not used for formats different than HTML) + * @param relatedInfoService if given, handle hashtags to search for the term in the correct + * service + * @param relatedStreamUrl if given, used alongside {@code relatedInfoService} to handle + * timestamps to open the stream in the popup player at the specific + * time + * @param disposables disposables created by the method are added here and their + * lifecycle should be handled by the calling class + * @param onCompletion will be run when setting text to the textView completes; use {@link + * #SET_LINK_MOVEMENT_METHOD} to make links clickable and focusable + */ + public static void fromDescription(@NonNull final TextView textView, + @NonNull final Description description, + final int htmlCompatFlag, + @Nullable final StreamingService relatedInfoService, + @Nullable final String relatedStreamUrl, + @NonNull final CompositeDisposable disposables, + @Nullable final Consumer onCompletion) { + switch (description.getType()) { + case Description.HTML: + TextLinkifier.fromHtml(textView, description.getContent(), htmlCompatFlag, + relatedInfoService, relatedStreamUrl, disposables, onCompletion); + break; + case Description.MARKDOWN: + TextLinkifier.fromMarkdown(textView, description.getContent(), + relatedInfoService, relatedStreamUrl, disposables, onCompletion); + break; + case Description.PLAIN_TEXT: default: + TextLinkifier.fromPlainText(textView, description.getContent(), + relatedInfoService, relatedStreamUrl, disposables, onCompletion); + break; + } + } + /** * Create links for contents with an HTML description. * *

- * This method will call {@link #changeIntentsOfDescriptionLinks(TextView, CharSequence, Info, - * CompositeDisposable)} after having linked the URLs with + * This method will call {@link #changeLinkIntents(TextView, CharSequence, StreamingService, + * String, CompositeDisposable, Consumer)} after having linked the URLs with * {@link HtmlCompat#fromHtml(String, int)}. *

* - * @param textView the {@link TextView} to set the 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 - * @param relatedInfo if given, handle timestamps to open the stream in the popup player at - * the specific time, and hashtags to search for the term in the correct - * service - * @param disposables disposables created by the method are added here and their lifecycle - * should be handled by the calling class + * @param textView the {@link TextView} to set the 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 + * @param relatedInfoService if given, handle hashtags to search for the term in the correct + * service + * @param relatedStreamUrl if given, used alongside {@code relatedInfoService} to handle + * timestamps to open the stream in the popup player at the specific + * time + * @param disposables disposables created by the method are added here and their + * lifecycle should be handled by the calling class + * @param onCompletion will be run when setting text to the textView completes; use {@link + * #SET_LINK_MOVEMENT_METHOD} to make links clickable and focusable */ - public static void createLinksFromHtmlBlock(@NonNull final TextView textView, - @NonNull final String htmlBlock, - final int htmlCompatFlag, - @Nullable final Info relatedInfo, - @NonNull final CompositeDisposable disposables) { - changeIntentsOfDescriptionLinks(textView, HtmlCompat.fromHtml(htmlBlock, htmlCompatFlag), - relatedInfo, disposables); + public static void fromHtml(@NonNull final TextView textView, + @NonNull final String htmlBlock, + final int htmlCompatFlag, + @Nullable final StreamingService relatedInfoService, + @Nullable final String relatedStreamUrl, + @NonNull final CompositeDisposable disposables, + @Nullable final Consumer onCompletion) { + changeLinkIntents( + textView, HtmlCompat.fromHtml(htmlBlock, htmlCompatFlag), relatedInfoService, + relatedStreamUrl, disposables, onCompletion); } /** * Create links for contents with a plain text description. * *

- * This method will call {@link #changeIntentsOfDescriptionLinks(TextView, CharSequence, Info, - * CompositeDisposable)} after having linked the URLs with {@link TextView#setAutoLinkMask(int)} - * and {@link TextView#setText(CharSequence, TextView.BufferType)}. + * This method will call {@link #changeLinkIntents(TextView, CharSequence, StreamingService, + * String, CompositeDisposable, Consumer)} after having linked the URLs with + * {@link TextView#setAutoLinkMask(int)} and + * {@link TextView#setText(CharSequence, TextView.BufferType)}. *

* - * @param textView the {@link TextView} to set the plain text block linked - * @param plainTextBlock the block of plain text to be linked - * @param relatedInfo if given, handle timestamps to open the stream in the popup player, at - * the specified time, and hashtags to search for the term in the correct - * service - * @param disposables disposables created by the method are added here and their lifecycle - * should be handled by the calling class + * @param textView the {@link TextView} to set the plain text block linked + * @param plainTextBlock the block of plain text to be linked + * @param relatedInfoService if given, handle hashtags to search for the term in the correct + * service + * @param relatedStreamUrl if given, used alongside {@code relatedInfoService} to handle + * timestamps to open the stream in the popup player at the specific + * time + * @param disposables disposables created by the method are added here and their + * lifecycle should be handled by the calling class + * @param onCompletion will be run when setting text to the textView completes; use {@link + * #SET_LINK_MOVEMENT_METHOD} to make links clickable and focusable */ - public static void createLinksFromPlainText(@NonNull final TextView textView, - @NonNull final String plainTextBlock, - @Nullable final Info relatedInfo, - @NonNull final CompositeDisposable disposables) { + public static void fromPlainText(@NonNull final TextView textView, + @NonNull final String plainTextBlock, + @Nullable final StreamingService relatedInfoService, + @Nullable final String relatedStreamUrl, + @NonNull final CompositeDisposable disposables, + @Nullable final Consumer onCompletion) { textView.setAutoLinkMask(Linkify.WEB_URLS); textView.setText(plainTextBlock, TextView.BufferType.SPANNABLE); - changeIntentsOfDescriptionLinks(textView, textView.getText(), relatedInfo, disposables); + changeLinkIntents(textView, textView.getText(), relatedInfoService, + relatedStreamUrl, disposables, onCompletion); } /** * Create links for contents with a markdown description. * *

- * This method will call {@link #changeIntentsOfDescriptionLinks(TextView, CharSequence, Info, - * CompositeDisposable)} after creating a {@link Markwon} object and using + * This method will call {@link #changeLinkIntents(TextView, CharSequence, StreamingService, + * String, CompositeDisposable, Consumer)} after creating a {@link Markwon} object and using * {@link Markwon#setMarkdown(TextView, String)}. *

* - * @param textView the {@link TextView} to set the plain text block linked - * @param markdownBlock the block of markdown text to be linked - * @param relatedInfo if given, handle timestamps to open the stream in the popup player at - * the specific time, and hashtags to search for the term in the correct - * service - * @param disposables disposables created by the method are added here and their lifecycle - * should be handled by the calling class + * @param textView the {@link TextView} to set the plain text block linked + * @param markdownBlock the block of markdown text to be linked + * @param relatedInfoService if given, handle hashtags to search for the term in the correct + * service + * @param relatedStreamUrl if given, used alongside {@code relatedInfoService} to handle + * timestamps to open the stream in the popup player at the specific + * time + * @param disposables disposables created by the method are added here and their + * lifecycle should be handled by the calling class + * @param onCompletion will be run when setting text to the textView completes; use {@link + * #SET_LINK_MOVEMENT_METHOD} to make links clickable and focusable */ - public static void createLinksFromMarkdownText(@NonNull final TextView textView, - final String markdownBlock, - @Nullable final Info relatedInfo, - final CompositeDisposable disposables) { + public static void fromMarkdown(@NonNull final TextView textView, + @NonNull final String markdownBlock, + @Nullable final StreamingService relatedInfoService, + @Nullable final String relatedStreamUrl, + @NonNull final CompositeDisposable disposables, + @Nullable final Consumer onCompletion) { final Markwon markwon = Markwon.builder(textView.getContext()) .usePlugin(LinkifyPlugin.create()).build(); - changeIntentsOfDescriptionLinks(textView, markwon.toMarkdown(markdownBlock), relatedInfo, - disposables); + changeLinkIntents(textView, markwon.toMarkdown(markdownBlock), + relatedInfoService, relatedStreamUrl, disposables, onCompletion); } /** @@ -131,9 +199,9 @@ public final class TextLinkifier { * This method will also add click listeners on timestamps in this description, which will play * the content in the popup player at the time indicated in the timestamp, by using * {@link TextLinkifier#addClickListenersOnTimestamps(Context, SpannableStringBuilder, - * StreamInfo, CompositeDisposable)} method and click listeners on hashtags, by using - * {@link TextLinkifier#addClickListenersOnHashtags(Context, SpannableStringBuilder, Info)})}, - * which will open a search on the current service with the hashtag. + * StreamingService, String, CompositeDisposable)} method and click listeners on hashtags, by + * using {@link TextLinkifier#addClickListenersOnHashtags(Context, SpannableStringBuilder, + * StreamingService)}, which will open a search on the current service with the hashtag. *

* *

@@ -141,20 +209,25 @@ public final class TextLinkifier { * before opening a web link. *

* - * @param textView the {@link TextView} in which the converted {@link CharSequence} will be - * applied - * @param chars the {@link CharSequence} to be parsed - * @param relatedInfo if given, handle timestamps to open the stream in the popup player at the - * specific time, and hashtags to search for the term in the correct service - * @param disposables disposables created by the method are added here and their lifecycle - * should be handled by the calling class + * @param textView the {@link TextView} to which the converted {@link CharSequence} + * will be applied + * @param chars the {@link CharSequence} to be parsed + * @param relatedInfoService if given, handle hashtags to search for the term in the correct + * service + * @param relatedStreamUrl if given, used alongside {@code relatedInfoService} to handle + * timestamps to open the stream in the popup player at the specific + * time + * @param disposables disposables created by the method are added here and their + * lifecycle should be handled by the calling class + * @param onCompletion will be run when setting text to the textView completes; use {@link + * #SET_LINK_MOVEMENT_METHOD} to make links clickable and focusable */ - private static void changeIntentsOfDescriptionLinks( - @NonNull final TextView textView, - @NonNull final CharSequence chars, - @Nullable final Info relatedInfo, - @NonNull final CompositeDisposable disposables) { - textView.setMovementMethod(LongPressLinkMovementMethod.getInstance()); + private static void changeLinkIntents(@NonNull final TextView textView, + @NonNull final CharSequence chars, + @Nullable final StreamingService relatedInfoService, + @Nullable final String relatedStreamUrl, + @NonNull final CompositeDisposable disposables, + @Nullable final Consumer onCompletion) { disposables.add(Single.fromCallable(() -> { final Context context = textView.getContext(); @@ -176,26 +249,26 @@ public final class TextLinkifier { textBlockLinked.removeSpan(span); } - if (relatedInfo != null) { - // add click actions on plain text timestamps only for description of - // contents, unneeded for meta-info or other TextViews - if (relatedInfo instanceof StreamInfo) { + // add click actions on plain text timestamps only for description of contents, + // unneeded for meta-info or other TextViews + if (relatedInfoService != null) { + if (relatedStreamUrl != null) { addClickListenersOnTimestamps(context, textBlockLinked, - (StreamInfo) relatedInfo, disposables); + relatedInfoService, relatedStreamUrl, disposables); } - - addClickListenersOnHashtags(context, textBlockLinked, relatedInfo); + addClickListenersOnHashtags(context, textBlockLinked, relatedInfoService); } return textBlockLinked; }).subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( - textBlockLinked -> setTextViewCharSequence(textView, textBlockLinked), + textBlockLinked -> + setTextViewCharSequence(textView, textBlockLinked, onCompletion), throwable -> { Log.e(TAG, "Unable to linkify text", throwable); // this should never happen, but if it does, just fallback to it - setTextViewCharSequence(textView, chars); + setTextViewCharSequence(textView, chars, onCompletion); })); } @@ -213,12 +286,12 @@ public final class TextLinkifier { * @param context the {@link Context} to use * @param spannableDescription the {@link SpannableStringBuilder} with the text of the * content description - * @param relatedInfo used to search for the term in the correct service + * @param relatedInfoService used to search for the term in the correct service */ private static void addClickListenersOnHashtags( @NonNull final Context context, @NonNull final SpannableStringBuilder spannableDescription, - @NonNull final Info relatedInfo) { + @NonNull final StreamingService relatedInfoService) { final String descriptionText = spannableDescription.toString(); final Matcher hashtagsMatches = HASHTAGS_PATTERN.matcher(descriptionText); @@ -231,8 +304,9 @@ public final class TextLinkifier { // of an URL, already parsed before if (spannableDescription.getSpans(hashtagStart, hashtagEnd, LongPressClickableSpan.class).length == 0) { + final int serviceId = relatedInfoService.getServiceId(); spannableDescription.setSpan( - new HashtagLongPressClickableSpan(context, parsedHashtag, relatedInfo), + new HashtagLongPressClickableSpan(context, parsedHashtag, serviceId), hashtagStart, hashtagEnd, 0); } } @@ -251,14 +325,16 @@ public final class TextLinkifier { * @param context the {@link Context} to use * @param spannableDescription the {@link SpannableStringBuilder} with the text of the * content description - * @param streamInfo what to open in the popup player when timestamps are clicked + * @param relatedInfoService the service of the {@code relatedStreamUrl} + * @param relatedStreamUrl what to open in the popup player when timestamps are clicked * @param disposables disposables created by the method are added here and their * lifecycle should be handled by the calling class */ private static void addClickListenersOnTimestamps( @NonNull final Context context, @NonNull final SpannableStringBuilder spannableDescription, - @NonNull final StreamInfo streamInfo, + @NonNull final StreamingService relatedInfoService, + @NonNull final String relatedStreamUrl, @NonNull final CompositeDisposable disposables) { final String descriptionText = spannableDescription.toString(); final Matcher timestampsMatches = TimestampExtractor.TIMESTAMPS_PATTERN.matcher( @@ -272,8 +348,9 @@ public final class TextLinkifier { continue; } - spannableDescription.setSpan(new TimestampLongPressClickableSpan( - context, descriptionText, disposables, streamInfo, timestampMatchDTO), + spannableDescription.setSpan( + new TimestampLongPressClickableSpan(context, descriptionText, disposables, + relatedInfoService, relatedStreamUrl, timestampMatchDTO), timestampMatchDTO.timestampStart(), timestampMatchDTO.timestampEnd(), 0); @@ -281,8 +358,12 @@ public final class TextLinkifier { } private static void setTextViewCharSequence(@NonNull final TextView textView, - @Nullable final CharSequence charSequence) { + @Nullable final CharSequence charSequence, + @Nullable final Consumer onCompletion) { textView.setText(charSequence); textView.setVisibility(View.VISIBLE); + if (onCompletion != null) { + onCompletion.accept(textView); + } } } diff --git a/app/src/main/java/org/schabi/newpipe/util/text/TimestampLongPressClickableSpan.java b/app/src/main/java/org/schabi/newpipe/util/text/TimestampLongPressClickableSpan.java index 48110312d..f5864794a 100644 --- a/app/src/main/java/org/schabi/newpipe/util/text/TimestampLongPressClickableSpan.java +++ b/app/src/main/java/org/schabi/newpipe/util/text/TimestampLongPressClickableSpan.java @@ -9,7 +9,6 @@ import androidx.annotation.NonNull; import org.schabi.newpipe.extractor.ServiceList; import org.schabi.newpipe.extractor.StreamingService; -import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.external_communication.ShareUtils; import io.reactivex.rxjava3.disposables.CompositeDisposable; @@ -23,7 +22,9 @@ final class TimestampLongPressClickableSpan extends LongPressClickableSpan { @NonNull private final CompositeDisposable disposables; @NonNull - private final StreamInfo streamInfo; + private final StreamingService relatedInfoService; + @NonNull + private final String relatedStreamUrl; @NonNull private final TimestampExtractor.TimestampMatchDTO timestampMatchDTO; @@ -31,41 +32,43 @@ final class TimestampLongPressClickableSpan extends LongPressClickableSpan { @NonNull final Context context, @NonNull final String descriptionText, @NonNull final CompositeDisposable disposables, - @NonNull final StreamInfo streamInfo, + @NonNull final StreamingService relatedInfoService, + @NonNull final String relatedStreamUrl, @NonNull final TimestampExtractor.TimestampMatchDTO timestampMatchDTO) { this.context = context; this.descriptionText = descriptionText; this.disposables = disposables; - this.streamInfo = streamInfo; + this.relatedInfoService = relatedInfoService; + this.relatedStreamUrl = relatedStreamUrl; this.timestampMatchDTO = timestampMatchDTO; } @Override public void onClick(@NonNull final View view) { - playOnPopup(context, streamInfo.getUrl(), streamInfo.getService(), + playOnPopup(context, relatedStreamUrl, relatedInfoService, timestampMatchDTO.seconds(), disposables); } @Override public void onLongClick(@NonNull final View view) { - ShareUtils.copyToClipboard(context, - getTimestampTextToCopy(streamInfo, descriptionText, timestampMatchDTO)); + ShareUtils.copyToClipboard(context, getTimestampTextToCopy( + relatedInfoService, relatedStreamUrl, descriptionText, timestampMatchDTO)); } @NonNull private static String getTimestampTextToCopy( - @NonNull final StreamInfo relatedInfo, + @NonNull final StreamingService relatedInfoService, + @NonNull final String relatedStreamUrl, @NonNull final String descriptionText, @NonNull final TimestampExtractor.TimestampMatchDTO timestampMatchDTO) { // TODO: use extractor methods to get timestamps when this feature will be implemented in it - final StreamingService streamingService = relatedInfo.getService(); - if (streamingService == ServiceList.YouTube) { - return relatedInfo.getUrl() + "&t=" + timestampMatchDTO.seconds(); - } else if (streamingService == ServiceList.SoundCloud - || streamingService == ServiceList.MediaCCC) { - return relatedInfo.getUrl() + "#t=" + timestampMatchDTO.seconds(); - } else if (streamingService == ServiceList.PeerTube) { - return relatedInfo.getUrl() + "?start=" + timestampMatchDTO.seconds(); + if (relatedInfoService == ServiceList.YouTube) { + return relatedStreamUrl + "&t=" + timestampMatchDTO.seconds(); + } else if (relatedInfoService == ServiceList.SoundCloud + || relatedInfoService == ServiceList.MediaCCC) { + return relatedStreamUrl + "#t=" + timestampMatchDTO.seconds(); + } else if (relatedInfoService == ServiceList.PeerTube) { + return relatedStreamUrl + "?start=" + timestampMatchDTO.seconds(); } // Return timestamp text for other services From 6e73c489dee61f4364f0fa4faf0702f0d3374b34 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 15 Jan 2023 14:57:34 +0100 Subject: [PATCH 54/84] Improve ellipsizing comments --- .../holder/CommentsMiniInfoItemHolder.java | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index fe04ac7ee..799aee8ba 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -48,6 +48,8 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { private final int commentHorizontalPadding; private final int commentVerticalPadding; + + private final Paint paintAtContentSize; private final float ellipsisWidthPx; private final RelativeLayout itemRoot; @@ -76,9 +78,9 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { commentVerticalPadding = (int) infoItemBuilder.getContext() .getResources().getDimension(R.dimen.comments_vertical_padding); - final Paint paint = new Paint(); - paint.setTextSize(itemContentView.getTextSize()); - ellipsisWidthPx = paint.measureText(ELLIPSIS); + paintAtContentSize = new Paint(); + paintAtContentSize.setTextSize(itemContentView.getTextSize()); + ellipsisWidthPx = paintAtContentSize.measureText(ELLIPSIS); } public CommentsMiniInfoItemHolder(final InfoItemBuilder infoItemBuilder, @@ -201,18 +203,40 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { } private void ellipsize() { + itemContentView.setMaxLines(COMMENT_EXPANDED_LINES); linkifyCommentContentView(v -> { boolean hasEllipsis = false; if (itemContentView.getLineCount() > COMMENT_DEFAULT_LINES) { - final int endOfLastLine = itemContentView - .getLayout() - .getLineEnd(COMMENT_DEFAULT_LINES - 1); - int end = itemContentView.getText().toString().lastIndexOf(' ', endOfLastLine - 2); - if (end == -1) { - end = Math.max(endOfLastLine - 2, 0); + // 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 = itemContentView.getText().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)); } - final String newVal = itemContentView.getText().subSequence(0, end) + " …"; + + // 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; } From dba24ec1f95b2e1fc6aafae84aee14a9f4ef1fdb Mon Sep 17 00:00:00 2001 From: GET100PERCENT <116144024+GET100PERCENT@users.noreply.github.com> Date: Mon, 16 Jan 2023 01:54:01 +0530 Subject: [PATCH 55/84] Added Odia language to language selector (#9651) --- app/src/main/res/values/settings_keys.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 1a711ad17..c2819feea 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -443,6 +443,7 @@ no nn uz + or pl pt-PT pt @@ -522,6 +523,7 @@ Norsk Nynorsk O‘zbek + ଓଡ଼ିଆ Polski Português Português (Brasil) @@ -1129,6 +1131,7 @@ nl nl-be oc + or pa pl pt @@ -1211,6 +1214,7 @@ Nederlands (NL) Nederlands (BE) Occitan + ଓଡ଼ିଆ ਪੰਜਾਬੀ Polski Português From e4641cd427556ead9c866076bfae6e5b65f25f2d Mon Sep 17 00:00:00 2001 From: Tobi Date: Sun, 15 Jan 2023 21:53:52 +0100 Subject: [PATCH 56/84] Update translations (#9688) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Translated using Weblate (Hebrew) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (German) Currently translated at 100.0% (650 of 650 strings) Added translation using Weblate (Assamese) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Polish) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Czech) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Greek) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Korean) Currently translated at 100.0% (650 of 650 strings) Translated using Weblate (Odia) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (German) Currently translated at 72.2% (52 of 72 strings) Translated using Weblate (Danish) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Catalan) Currently translated at 95.5% (620 of 649 strings) Translated using Weblate (Persian) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Italian) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Norwegian Nynorsk) Currently translated at 10.6% (69 of 649 strings) Translated using Weblate (Polish) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Polish) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Arabic) Currently translated at 51.3% (37 of 72 strings) Translated using Weblate (Bengali) Currently translated at 89.9% (584 of 649 strings) Translated using Weblate (Sardinian) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Thai) Currently translated at 32.2% (209 of 649 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Romanian) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Italian) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Japanese) Currently translated at 99.6% (647 of 649 strings) Translated using Weblate (Odia) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (German) Currently translated at 66.6% (48 of 72 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Galician) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Azerbaijani) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Polish) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Czech) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Greek) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (French) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (German) Currently translated at 100.0% (649 of 649 strings) Translated using Weblate (Hindi) Currently translated at 19.4% (14 of 72 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (72 of 72 strings) Translated using Weblate (Korean) Currently translated at 100.0% (648 of 648 strings) Co-authored-by: Abhilash Co-authored-by: Agnieszka C Co-authored-by: Ahmad0a Co-authored-by: Ajeje Brazorf Co-authored-by: Alex25820 Co-authored-by: Danial Behzadi Co-authored-by: ERYpTION Co-authored-by: Edward Co-authored-by: Eric Co-authored-by: Fjuro Co-authored-by: GET100PERCENT Co-authored-by: GnuPGを使うべきだ Co-authored-by: Hoseok Seo Co-authored-by: Hosted Weblate Co-authored-by: Ihor Hordiichuk Co-authored-by: JY3 Co-authored-by: Jeff Huang Co-authored-by: Linerly Co-authored-by: Nidi Co-authored-by: Nikodem Zawirski Co-authored-by: Oymate Co-authored-by: Oğuz Ersen Co-authored-by: Priit Jõerüüt Co-authored-by: RSoulwin Co-authored-by: Retrial Co-authored-by: Rex_sa Co-authored-by: Ricardo Co-authored-by: SalusVF Co-authored-by: ShareASmile Co-authored-by: Translator Co-authored-by: Vasilis K Co-authored-by: VfBFan Co-authored-by: Yaron Shahrabani Co-authored-by: bowornsin Co-authored-by: gallegonovato Co-authored-by: nautilusx Co-authored-by: pjammo Co-authored-by: random r Co-authored-by: ssantos Co-authored-by: tryvseu Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pa/ Translation: NewPipe/Metadata * Translated using Weblate (Slovenian) Currently translated at 63.6% (414 of 650 strings) * Translated using Weblate (Azerbaijani) Currently translated at 100.0% (650 of 650 strings) * Translated using Weblate (Assamese) Currently translated at 3.6% (24 of 650 strings) Co-authored-by: Hosted Weblate Co-authored-by: Abhilash Co-authored-by: Agnieszka C Co-authored-by: Ahmad0a Co-authored-by: Ajeje Brazorf Co-authored-by: Alex25820 Co-authored-by: Danial Behzadi Co-authored-by: ERYpTION Co-authored-by: Edward Co-authored-by: Eric Co-authored-by: Fjuro Co-authored-by: GET100PERCENT Co-authored-by: GnuPGを使うべきだ Co-authored-by: Hoseok Seo Co-authored-by: Ihor Hordiichuk Co-authored-by: JY3 Co-authored-by: Jeff Huang Co-authored-by: Linerly Co-authored-by: Nidi Co-authored-by: Nikodem Zawirski Co-authored-by: Oymate Co-authored-by: Oğuz Ersen Co-authored-by: Priit Jõerüüt Co-authored-by: RSoulwin Co-authored-by: Retrial Co-authored-by: Rex_sa Co-authored-by: Ricardo Co-authored-by: SalusVF Co-authored-by: ShareASmile Co-authored-by: Translator Co-authored-by: Vasilis K Co-authored-by: VfBFan Co-authored-by: Yaron Shahrabani Co-authored-by: bowornsin Co-authored-by: gallegonovato Co-authored-by: nautilusx Co-authored-by: pjammo Co-authored-by: random r Co-authored-by: ssantos Co-authored-by: tryvseu Co-authored-by: HudobniVolk --- app/src/main/res/values-ar/strings.xml | 2 + app/src/main/res/values-as/strings.xml | 28 ++++ app/src/main/res/values-az/strings.xml | 2 + app/src/main/res/values-bn/strings.xml | 1 + app/src/main/res/values-ca/strings.xml | 2 + app/src/main/res/values-cs/strings.xml | 4 +- app/src/main/res/values-da/strings.xml | 134 ++++++++++++++---- app/src/main/res/values-de/strings.xml | 2 + app/src/main/res/values-el/strings.xml | 2 + app/src/main/res/values-es/strings.xml | 2 + app/src/main/res/values-et/strings.xml | 1 + app/src/main/res/values-fa/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-gl/strings.xml | 1 + app/src/main/res/values-he/strings.xml | 2 + app/src/main/res/values-hi/strings.xml | 1 + app/src/main/res/values-in/strings.xml | 2 + app/src/main/res/values-it/strings.xml | 1 + app/src/main/res/values-ja/strings.xml | 11 +- app/src/main/res/values-ko/strings.xml | 6 + app/src/main/res/values-nn/strings.xml | 9 +- app/src/main/res/values-or/strings.xml | 3 +- app/src/main/res/values-pa/strings.xml | 1 + app/src/main/res/values-pl/strings.xml | 4 +- app/src/main/res/values-pt-rBR/strings.xml | 2 + app/src/main/res/values-pt-rPT/strings.xml | 1 + app/src/main/res/values-pt/strings.xml | 1 + app/src/main/res/values-ro/strings.xml | 25 ++-- app/src/main/res/values-sc/strings.xml | 5 + app/src/main/res/values-sl/strings.xml | 10 +- app/src/main/res/values-sv/strings.xml | 1 + app/src/main/res/values-th/strings.xml | 3 + app/src/main/res/values-tr/strings.xml | 2 + app/src/main/res/values-uk/strings.xml | 2 + app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values-zh-rTW/strings.xml | 1 + .../metadata/android/ar/changelogs/71.txt | 18 +-- .../metadata/android/ar/changelogs/991.txt | 13 ++ .../metadata/android/de/changelogs/975.txt | 16 +++ .../metadata/android/de/changelogs/976.txt | 10 ++ .../metadata/android/de/changelogs/977.txt | 9 ++ .../metadata/android/de/changelogs/988.txt | 2 + .../metadata/android/de/changelogs/989.txt | 3 + .../metadata/android/de/changelogs/990.txt | 15 ++ .../metadata/android/de/changelogs/991.txt | 13 ++ .../metadata/android/hi/changelogs/991.txt | 1 + .../metadata/android/pa/changelogs/65.txt | 1 + .../metadata/android/pa/changelogs/66.txt | 1 + .../metadata/android/pa/changelogs/68.txt | 1 + .../metadata/android/pa/changelogs/69.txt | 1 + .../metadata/android/pa/changelogs/70.txt | 1 + .../metadata/android/pa/changelogs/71.txt | 1 + .../metadata/android/pa/changelogs/730.txt | 2 + .../metadata/android/pa/changelogs/740.txt | 1 + .../metadata/android/pa/changelogs/750.txt | 1 + .../metadata/android/pa/changelogs/760.txt | 1 + .../metadata/android/pa/changelogs/770.txt | 4 + .../metadata/android/pa/changelogs/780.txt | 1 + .../metadata/android/pa/changelogs/790.txt | 1 + .../metadata/android/pa/changelogs/800.txt | 1 + .../metadata/android/pa/changelogs/810.txt | 1 + .../metadata/android/pa/changelogs/820.txt | 1 + .../metadata/android/pa/changelogs/830.txt | 1 + .../metadata/android/pa/changelogs/840.txt | 1 + .../metadata/android/pa/changelogs/850.txt | 1 + .../metadata/android/pa/changelogs/860.txt | 1 + .../metadata/android/pa/changelogs/870.txt | 2 + .../metadata/android/pa/changelogs/900.txt | 1 + .../metadata/android/pa/changelogs/910.txt | 1 + .../metadata/android/pa/changelogs/920.txt | 1 + .../metadata/android/pa/changelogs/930.txt | 1 + .../metadata/android/pa/changelogs/940.txt | 1 + .../metadata/android/pa/changelogs/950.txt | 4 + .../metadata/android/pa/changelogs/951.txt | 13 ++ .../metadata/android/pa/changelogs/952.txt | 7 + .../metadata/android/pa/changelogs/953.txt | 1 + .../metadata/android/pa/changelogs/954.txt | 8 ++ .../metadata/android/pa/changelogs/955.txt | 3 + .../metadata/android/pa/changelogs/956.txt | 1 + .../metadata/android/pa/changelogs/957.txt | 10 ++ .../metadata/android/pa/changelogs/958.txt | 1 + .../metadata/android/pa/changelogs/959.txt | 3 + .../metadata/android/pa/changelogs/960.txt | 4 + .../metadata/android/pa/changelogs/961.txt | 1 + .../metadata/android/pa/changelogs/962.txt | 2 + .../metadata/android/pa/changelogs/963.txt | 1 + .../metadata/android/pa/changelogs/964.txt | 1 + .../metadata/android/pa/changelogs/965.txt | 1 + .../metadata/android/pa/changelogs/966.txt | 1 + .../metadata/android/pa/changelogs/967.txt | 1 + .../metadata/android/pa/changelogs/968.txt | 1 + .../metadata/android/pa/changelogs/969.txt | 1 + .../metadata/android/pa/changelogs/970.txt | 1 + .../metadata/android/pa/changelogs/971.txt | 3 + .../metadata/android/pa/changelogs/972.txt | 13 ++ .../metadata/android/pa/changelogs/973.txt | 4 + .../metadata/android/pa/changelogs/974.txt | 5 + .../metadata/android/pa/changelogs/975.txt | 16 +++ .../metadata/android/pa/changelogs/976.txt | 10 ++ .../metadata/android/pa/changelogs/977.txt | 10 ++ .../metadata/android/pa/changelogs/978.txt | 1 + .../metadata/android/pa/changelogs/979.txt | 2 + .../metadata/android/pa/changelogs/980.txt | 12 ++ .../metadata/android/pa/changelogs/981.txt | 2 + .../metadata/android/pa/changelogs/982.txt | 1 + .../metadata/android/pa/changelogs/983.txt | 9 ++ .../metadata/android/pa/changelogs/984.txt | 7 + .../metadata/android/pa/changelogs/985.txt | 1 + .../metadata/android/pa/changelogs/986.txt | 15 ++ .../metadata/android/pa/changelogs/987.txt | 11 ++ .../metadata/android/pa/changelogs/988.txt | 2 + .../metadata/android/pa/changelogs/989.txt | 3 + .../metadata/android/pa/changelogs/990.txt | 13 ++ 113 files changed, 556 insertions(+), 61 deletions(-) create mode 100644 app/src/main/res/values-as/strings.xml create mode 100644 fastlane/metadata/android/ar/changelogs/991.txt create mode 100644 fastlane/metadata/android/de/changelogs/975.txt create mode 100644 fastlane/metadata/android/de/changelogs/976.txt create mode 100644 fastlane/metadata/android/de/changelogs/977.txt create mode 100644 fastlane/metadata/android/de/changelogs/988.txt create mode 100644 fastlane/metadata/android/de/changelogs/989.txt create mode 100644 fastlane/metadata/android/de/changelogs/990.txt create mode 100644 fastlane/metadata/android/de/changelogs/991.txt create mode 100644 fastlane/metadata/android/hi/changelogs/991.txt create mode 100644 fastlane/metadata/android/pa/changelogs/65.txt create mode 100644 fastlane/metadata/android/pa/changelogs/66.txt create mode 100644 fastlane/metadata/android/pa/changelogs/68.txt create mode 100644 fastlane/metadata/android/pa/changelogs/69.txt create mode 100644 fastlane/metadata/android/pa/changelogs/70.txt create mode 100644 fastlane/metadata/android/pa/changelogs/71.txt create mode 100644 fastlane/metadata/android/pa/changelogs/730.txt create mode 100644 fastlane/metadata/android/pa/changelogs/740.txt create mode 100644 fastlane/metadata/android/pa/changelogs/750.txt create mode 100644 fastlane/metadata/android/pa/changelogs/760.txt create mode 100644 fastlane/metadata/android/pa/changelogs/770.txt create mode 100644 fastlane/metadata/android/pa/changelogs/780.txt create mode 100644 fastlane/metadata/android/pa/changelogs/790.txt create mode 100644 fastlane/metadata/android/pa/changelogs/800.txt create mode 100644 fastlane/metadata/android/pa/changelogs/810.txt create mode 100644 fastlane/metadata/android/pa/changelogs/820.txt create mode 100644 fastlane/metadata/android/pa/changelogs/830.txt create mode 100644 fastlane/metadata/android/pa/changelogs/840.txt create mode 100644 fastlane/metadata/android/pa/changelogs/850.txt create mode 100644 fastlane/metadata/android/pa/changelogs/860.txt create mode 100644 fastlane/metadata/android/pa/changelogs/870.txt create mode 100644 fastlane/metadata/android/pa/changelogs/900.txt create mode 100644 fastlane/metadata/android/pa/changelogs/910.txt create mode 100644 fastlane/metadata/android/pa/changelogs/920.txt create mode 100644 fastlane/metadata/android/pa/changelogs/930.txt create mode 100644 fastlane/metadata/android/pa/changelogs/940.txt create mode 100644 fastlane/metadata/android/pa/changelogs/950.txt create mode 100644 fastlane/metadata/android/pa/changelogs/951.txt create mode 100644 fastlane/metadata/android/pa/changelogs/952.txt create mode 100644 fastlane/metadata/android/pa/changelogs/953.txt create mode 100644 fastlane/metadata/android/pa/changelogs/954.txt create mode 100644 fastlane/metadata/android/pa/changelogs/955.txt create mode 100644 fastlane/metadata/android/pa/changelogs/956.txt create mode 100644 fastlane/metadata/android/pa/changelogs/957.txt create mode 100644 fastlane/metadata/android/pa/changelogs/958.txt create mode 100644 fastlane/metadata/android/pa/changelogs/959.txt create mode 100644 fastlane/metadata/android/pa/changelogs/960.txt create mode 100644 fastlane/metadata/android/pa/changelogs/961.txt create mode 100644 fastlane/metadata/android/pa/changelogs/962.txt create mode 100644 fastlane/metadata/android/pa/changelogs/963.txt create mode 100644 fastlane/metadata/android/pa/changelogs/964.txt create mode 100644 fastlane/metadata/android/pa/changelogs/965.txt create mode 100644 fastlane/metadata/android/pa/changelogs/966.txt create mode 100644 fastlane/metadata/android/pa/changelogs/967.txt create mode 100644 fastlane/metadata/android/pa/changelogs/968.txt create mode 100644 fastlane/metadata/android/pa/changelogs/969.txt create mode 100644 fastlane/metadata/android/pa/changelogs/970.txt create mode 100644 fastlane/metadata/android/pa/changelogs/971.txt create mode 100644 fastlane/metadata/android/pa/changelogs/972.txt create mode 100644 fastlane/metadata/android/pa/changelogs/973.txt create mode 100644 fastlane/metadata/android/pa/changelogs/974.txt create mode 100644 fastlane/metadata/android/pa/changelogs/975.txt create mode 100644 fastlane/metadata/android/pa/changelogs/976.txt create mode 100644 fastlane/metadata/android/pa/changelogs/977.txt create mode 100644 fastlane/metadata/android/pa/changelogs/978.txt create mode 100644 fastlane/metadata/android/pa/changelogs/979.txt create mode 100644 fastlane/metadata/android/pa/changelogs/980.txt create mode 100644 fastlane/metadata/android/pa/changelogs/981.txt create mode 100644 fastlane/metadata/android/pa/changelogs/982.txt create mode 100644 fastlane/metadata/android/pa/changelogs/983.txt create mode 100644 fastlane/metadata/android/pa/changelogs/984.txt create mode 100644 fastlane/metadata/android/pa/changelogs/985.txt create mode 100644 fastlane/metadata/android/pa/changelogs/986.txt create mode 100644 fastlane/metadata/android/pa/changelogs/987.txt create mode 100644 fastlane/metadata/android/pa/changelogs/988.txt create mode 100644 fastlane/metadata/android/pa/changelogs/989.txt create mode 100644 fastlane/metadata/android/pa/changelogs/990.txt diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index d7bbcd9c0..2fbe794a3 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -778,4 +778,6 @@ انقر للتنزيل %s الوضع السريع استيراد الاشتراكات أو تصديرها من القائمة المكونة من 3 نقاط + هذا الخيار متاح فقط إذا تم تحديد %s للسمة + إلغاء تعيين الصورة المصغرة الدائمة
\ No newline at end of file diff --git a/app/src/main/res/values-as/strings.xml b/app/src/main/res/values-as/strings.xml new file mode 100644 index 000000000..578213394 --- /dev/null +++ b/app/src/main/res/values-as/strings.xml @@ -0,0 +1,28 @@ + + + কোনো ষ্ট্ৰিম প্লেয়াৰ পোৱা নগ\'ল (আপুনি ইয়াক বজাবলৈ VLC ইনষ্টল কৰিব পাৰে)। + ইনষ্টল + বাতিল কৰক + ঠিক আছে + ব্ৰাউজাৰত খোলক + POPUP অৱস্থাত খোলক + ...ৰ সৈতে খোলক + চেয়াৰ + %1$s ত প্ৰকাশ কৰা হৈছে + কোনো ষ্ট্ৰিম প্লেয়াৰ পোৱা নগ\'ল। VLC ইনষ্টল কৰক\? + ডাউনল’ড + ষ্ট্ৰিম কৰা ফাইল ডাউনলোড কৰক + সন্ধান কৰক + ছেটিংছ + %s ৰ বাবে ফলাফল দেখুৱা হৈছে + চেয়াৰ কৰক + কিছু ৰিজ’লিউচনত অডিঅ’ আঁতৰাওক + চাবস্ক্ৰাইব কৰা হ\'ল + আনচাবস্ক্ৰাইব + আৰম্ভ কৰিবলৈ মেগনিফাইং গ্লাছৰ চিহ্নত টিপক। + চাবস্ক্ৰাইব + চোৱা হ\'ল (চিহ্নিত কৰক) + আপুনি \"%1$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 22f3ba5e5..cd18e8d93 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -726,4 +726,6 @@ Sürətli rejim 3 nöqtə menyudan abunələri idxal və ya ixrac et %s endirmək üçün toxun + Bu seçim yalnız tema üçün %s seçildikdə əlçatandır + Daimi miniatürü ləğv et \ No newline at end of file diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 899103c9d..46d12a8b6 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -644,4 +644,5 @@ ভুক্তি মুছতে ডানে-বামে সরাও সম্প্রচার বিষয়ক তথ্য প্রক্রিয়ারত… ভবিষ্যৎ ভুক্তি দেখাও + প্লেব্যাক লোড বিরতির আকার \ No newline at end of file diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index ae4e4f018..fc9abd891 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -701,4 +701,6 @@ Format desconegut 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. \ 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 fdbc81d43..637678c23 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -598,7 +598,7 @@ Vypnout pro skrytí popisu videa a doplňkové informace Zbořit aplikaci Stahování bylo zahájeno - Můžete si zvolit svůj oblíbený motiv níže + Níže si můžete zvolit svůj oblíbený motiv Zvolte si svůj oblíbený noční motiv - %s Automatický (motiv zařízení) Radio @@ -739,4 +739,6 @@ Rychlý režim Používáte nejnovější verzi NewPipe Import nebo export odběrů z 3-tečkové nabídky + Tato možnost je dostupná pouze při vybraném motivu %s + Zrušení nastavení trvalého náhledu \ 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 96ae5299d..f4601ec2d 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -32,12 +32,12 @@ Baggrund Pop op Føj til - Placering af videodownloads + Mappe til download af video Downloadede videoer gemmes her - Angiv downloadmappe for videofiler - Downloadmappe for lydfiler + Angiv download-mappe for videofiler + Download-mappe for lydfiler Downloadede lydfiler gemmes her - Angiv downloadmappe for lydfiler + Angiv download-mappe for lydfiler Standardopløsning Standardopløsning for pop op Vis højere opløsninger @@ -45,7 +45,7 @@ Afspil med Kodi Installer manglede Kore-app\? Vis valgmuligheden \"Afspil med Kodi\" - Vis en knap til at afspille en video via Kodi + Vis en knap til at afspille en video via Kodi-mediecenteret Lyd Standardformat for lydfiler Standardformat for videofiler @@ -56,7 +56,7 @@ Husk størrelse og placering af pop op Husk sidste størrelse og placering af pop op-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 + 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 Indlæs miniaturebilleder Slå fra for at undgå indlæsning af billeder, hvorved der spares data og hukommelse. Ændringer sletter billedcachen i både ram og lager Billedcache slettet @@ -64,7 +64,7 @@ Slet alle websidedata fra cachen Metadata-cache slettet Føj automatisk næste stream til køen - Fortsæt nedlukningen af en (ikke-gentagende) playback kø ved at tilføje et relateret stream + Fortsæt en afspilningskø, der afsluttes (ikke-gentagende), ved at tilføje en lignende stream Juster lydstyrke ved hjælp af fingerbevægelser Brug fingerbevægelser til at kontrollere afspillerens lydstyrke Styr lysstyrken med fingerbevægelser @@ -101,7 +101,7 @@ Fejlrapport Alle Kanaler - Playlister + Spillelister Én video %s videoer @@ -130,7 +130,7 @@ Overskriver din nuværende historik, abonnementer, spillelister og (hvis det ønskes) indstillinger Eksporter historik, abonnementer, spillelister og indstillinger Slet visningshistorik - Sletter historikken og positioner af tidligere viste videoer + Sletter historikken over afspillede streams og afspilningspositionerne Slet hele visningshistorikken\? Visningshistorikken blev slettet Slet søgehistorik @@ -217,7 +217,7 @@ Om NewPipe Tredjepartslicenser © %1$s af %2$s under %3$s - Om + Om & Ofte stillede spørgsmål Licenser Åben letvægtsstreaming på Android. Bidrag til projektet @@ -330,7 +330,7 @@ Luk skuffe Hvad:\\nForespørgsel:\\nIndholdssprog:\\nIndholdsland:\\nAppsprog:\\nTjeneste:\\nGMT-tid:\\nPakke:\\nVersion:\\nOS-version: Standardhandling når indhold åbnes – %s - Anvend som playlistens miniature + Anvend som spillelistens miniaturebillede Bogmærk spilleliste Fjern bogmærke Føjet til spillelisten @@ -386,7 +386,7 @@ Afspil automatisk Ryd data Positioner i lister - Genopret forrige afspilningsposition + Gendan sidste afspilningsposition Fortsæt afspilning Slå fra for at skjule kommentarer Vis kommentarer @@ -398,7 +398,7 @@ Anden handlingstast Tredje handlingstast Viser resultater for: %s - Åben med + Åbn med LeakCanary er ikke tilgængelig Markér som set Beskrivelse @@ -447,7 +447,7 @@ Nye streams Notifikationer om nye streams fra abonnementer reCAPTCHA cookies er ryddet - Slet alle playback positioner\? + Slet alle afspilningspositioner\? Filen er flyttet eller slettet NewPipe stødte ind i en fejl, tryk for at rapportere Rapporter på GitHub @@ -463,9 +463,9 @@ Download fuldført %s downloads fuldført - Lav indlæsningsintervallets størrelse, (som nu ligger på %s) om. En højere værdi kan øge videoindlæsningshastigheden. Ændringer af værdien kræver genstart. + Ændr indlæsningsintervallets størrelse (som nu er på %s). En lavere værdi kan øge videoindlæsningshastigheden. Ændringer kræver en genstart af afspiller Den aktive spilleliste bliver udskiftet - At skifte fra en afspiller til en anden kan udskifte din kø + Hvis du skifter fra en spiller til en anden, kan din kø blive erstattet Vis metainformation Lokale søgeforslag Fjerne søgeforslag @@ -475,8 +475,8 @@ Notifikationer om videohashfunktioners status Fejlrapport-notifikation Notifikationer for at rapportere fejl - Slet playback positioner - Sletter alle playback positioner + Slet afspilningspositioner + Sletter alle afspilningspositioner Spørg hvor filen skal downloades Et download ad gangen Slet downloadede filer @@ -487,23 +487,23 @@ \nNewPipes fortrolighedspolitik forklarer i detaljer, hvilke data der bliver sendt og opbevaret når du sender en nedbrudsrapport.
Kopier en formatteret rapport Giv tilladelse til at vise over andre apps - Vis playback positionsvisere i lister - Playback positioner slettet + Vis indikatorer for afspilningsposition i lister + Afspilningspositioner slettet Ryd reCAPTCHA cookies Der er en afventende download med dette navn Start downloads - Skaler miniaturebilledet til 1:1 format - Skaler notifikationsminiaturebillederne fra 16:9 til 1:1 format (dette kan medføre forvrængninger) - 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 kasserne til højre + 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 Du kan kun vælge op til tre handlinger som kan vises i den lille notifikation! Buffer Få Android til at vælge notifikationens farve ud fra den primære farve i miniaturebilledet (virker ikke på alle enheder) - Nattetema + Nattema Frem- og tilbagesøgningstid Denne video er aldersbegrænset. \nPga. YouTubes politik om aldersbegrænsede videoer har NewPipe ikke adgang til videoen. Crash afspilleren - Spørg om bekræftelse før du tømmer 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 @@ -514,8 +514,8 @@ Kommentarer Relaterede objekter Stryg på elementer for at fjerne dem - Vælg en playliste - Ingen playliste bogmærker endnu + Vælg en spilleliste + Ingen spilleliste-bogmærker endnu Sproget ændres når appen genstarter Spillekø Vis kanalens detaljer @@ -530,7 +530,7 @@ Alle netværk Kontrolfrekvens Notifikationer ved nye streams - Notifikationer om ny streams fra abonnomenter + Giv besked om nye streams fra abonnementer Tjek manuelt efter opdateringer Tjekker efter opdateringer… Gendanner @@ -555,8 +555,8 @@ Vis sete elementer Dette indhold er ikke tilgængeligt i dit land. Af %s - Videoer på playlisten som allerede er blevet set fjernes. -\nDette kan ikke fortrydes! + Videoer, der er blevet set før og efter, at de er blevet tilføjet til spillelisten, vil blive fjernet. +\nEr du sikker\? Dette kan ikke gøres om! Vis miniaturebillede Tags Aldersbegrænsning @@ -653,4 +653,78 @@ Vis et crash alternativ når afspilleren er i brug Vis en fejl snackbar Brug system mappevælger (SAF) + Kanalens avatar-miniaturebillede + Dette er et SoundCloud Go+-nummer, i hvert fald i dit land, så det kan ikke streames eller downloades af NewPipe. + Der blev ikke fundet nogen passende filhåndtering til denne handling. +\nInstaller en Storage Access Framework-kompatibel filhåndtering + Der blev ikke fundet nogen passende filhåndtering til denne handling. +\nInstaller et filhåndteringsprogram eller prøv at deaktivere \'%s\' i download-indstillingerne + Aktivér valg af tekst i beskrivelsen + Automatisk (enhedstema) + Deaktiver valg af tekst i beskrivelsen + Fastgjort kommentar + Du abonnerer nu på denne kanal + , + Få besked + Du vil blive spurgt, hvor du vil gemme hver enkelt download + Den er tilgængelig i nogle tjenester og er normalt meget hurtigere, men kan returnere et begrænset antal elementer og ofte ufuldstændige oplysninger (f.eks. ingen varighed, elementtype, ingen live-status) + Ukendt format + Ukendt kvalitet + Hjertemarkeret af indholdsskaberen + Intervalstørrelse for afspilningsindlæsning + ExoPlayer-standard + Tomt gruppenavn + Du vil blive spurgt, hvor du vil gemme hver enkelt download. +\nAktiver systemet mappevælger (SAF), hvis du vil downloade til et eksternt SD-kort + Originaltekster fra tjenester vil være synlige i stream-emner + Ingen videostreams er tilgængelige for eksterne afspillere + URL til miniaturebillede + Fra + Tablet-tilstand + Skjul fremtidige elementer + Denne video er kun tilgængelig for YouTube Music Premium-medlemmer, så den kan ikke streames eller downloades af NewPipe. + \"Storage Access Framework\" gør det muligt at downloade til et eksternt SD-kort + Fremtving indberetning af ikke-leverbare Rx-undtagelser uden for fragmentets eller aktivitetens livscyklus efter bortskaffelse + Tryk for at downloade %s + Fra og med Android 10 understøttes kun \"Storage Access Framework\" + Synes du, at feed-indlæsning er for langsom\? Hvis det er tilfældet, så prøv at aktivere hurtig indlæsning (du kan ændre det i indstillingerne eller ved at trykke på knappen nedenfor). +\n +\nNewPipe tilbyder to strategier til feed-indlæsning: +\n- Hentning af hele abonnementskanalen, hvilket er langsomt, men komplet. +\n- Brug af et dedikeret service endpoint, hvilket er hurtigt, men normalt ikke komplet. +\n +\nForskellen mellem de to er, at den hurtige metode normalt mangler nogle oplysninger, f.eks. elementets varighed eller type (kan ikke skelne mellem livevideoer og normale videoer), og den returnerer muligvis færre elementer. +\n +\nYouTube er et eksempel på en tjeneste, der tilbyder denne hurtige metode med sit RSS-feed. +\n +\nValget er altså et spørgsmål om, hvad du foretrækker: hastighed eller præcise oplysninger. + Den valgte stream er ikke understøttet af eksterne afspillere + Denne indstilling er kun tilgængelig, hvis %s er valgt som tema + Du kan nu vælge tekst i beskrivelsen. Bemærk, at siden kan flimre, og at links muligvis ikke kan klikkes på, mens du er i valgtilstand. + Streams, som endnu ikke understøttes af downloaderen, vises ikke + Hurtig tilstand + Importér eller eksportér abonnementer fra 3-punktsmenuen + Ofte stillede spørgsmål + Hvis du har problemer med at bruge appen, bør du tjekke disse svar på almindelige spørgsmål! + Se på hjemmeside + Vis Picasso-farvede bånd oven på billeder, der angiver deres kilde: rød for netværk, blå for disk og grøn for hukommelse + Du kører den nyeste version af NewPipe + På grund af ExoPlayer-begrænsninger blev søgetiden sat til %d sekunder + Vis kun ikke-grupperede abonnementer + Skjul sete elementer + Side med spillelister + Du kan vælge dit foretrukne nattema nedenfor + Vælg dit foretrukne nattema - %s + Support + Host + Offentlig + Ikke oplyst + Privat + Intern + Til + Skift alle + Ingen lydstreams er tilgængelige for eksterne afspillere + Vælg kvalitet til eksterne afspillere + Vis fremtidige elementer + Sortér \ 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 7d8e64475..d02b276cd 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -726,4 +726,6 @@ Du verwendest die neueste Version von NewPipe Antippen um %s herunterzuladen Importieren oder Exportieren von Abonnements über das 3-Punkte-Menü + Diese Option ist nur verfügbar, wenn %s als Design ausgewählt wird + Dauerhaftes Vorschaubild aufheben \ 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 ae9571aa1..cf3c0576b 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -726,4 +726,6 @@ Εισάγετε ή εξάγετε συνδρομές από το μενού 3 κουκκίδων Πατήστε για λήψη %s Έχετε την πιο πρόσφατη έκδοση του NewPipe + Αυτή η επιλογή είναι διαθέσιμη μόνο εάν έχει επιλεγεί %s για Θέμα + Κατάργηση μόνιμης μικρογραφίας \ 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 48e96ebec..f92ad9128 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -742,4 +742,6 @@ Importa o exporta las suscripciones desde el menú con los tres puntos Está ejecutando la última versión de NewPipe Pulsa para descargar %s + Esta opción sólo está disponible si %s está seleccionado para el tema + Desactivar las miniaturas permanente \ 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 7f2691b77..87beff94f 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -726,4 +726,5 @@ Kiirrežiim Tellimusi saad importida või eksportida 3 punktiga menüüst Sa kasutad NewPipe\'i uusimat versiooni + See valik on kasutusel vaid %s teema puhul \ No newline at end of file diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 123c3b201..f22200c06 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -726,4 +726,5 @@ حالت سریع ضربه برای بارگیری %s از جدیدترین نگارش نیوپایپ استفاده می‌کنید + این گزینه تنها هنگامی موجود است که %s به عنوان زمینه گزیده باشد \ 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 fd2f027f8..a3373ca6e 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -742,4 +742,5 @@ Vous utilisez la dernière version de NewPipe Appuyez pour télécharger %s Échec de la copie dans le presse-papiers + Cette option est disponible seulement si %s est sélectionné pour le thème \ No newline at end of file diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index fcabbd95b..65d5ce204 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -726,4 +726,5 @@ Estás executandola última versión de NewPipe Toca para descargar %s Importa ou exporta subscricións dende o menú dos 3 puntos + Esta opción só está dispoñible se %s está seleccionado para o tema \ 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 6d21a5943..67e6d45ad 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -752,4 +752,6 @@ נגיעה כאן תוריד את %s מצב מהיר זאת הגרסה העדכנית ביותר של NewPipe + אפשרות זאת זמינה רק אם נבחרה ערכת נושא %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 b4f9fadc0..7c9ebf231 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -726,4 +726,5 @@ 3-बिंदु वाले मेन्यू से सब्सक्रिप्शनस आयात या निर्यात करें आप न्यूपाइप का नवीनतम संस्करण चला रहे हैं %s डाउनलोड करने के लिए टैप करें + यह विकल्प केवल तभी उपलब्ध होता है जब थीम के लिए %s का चयन किया जाता है \ 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 a5b9a3ff2..af8781a23 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -713,4 +713,6 @@ Impor atau ekspor langganan dari menu 3 titik Anda menjalankan NewPipe versi terkini Ketuk untuk mengunduh %s + Opsi ini hanya tersedia jika %s dipilih untuk Tema + Batalkan penetapan gambar kecil permanen \ 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 d2b0d10fe..3304321d8 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -739,4 +739,5 @@ Premi per scaricare %s L\'ultima versione di NewPipe è già in esecuzione Importa o esporta iscrizioni dal menu a 3 punti + Questa opzione è disponibile solo se %s è selezionato come Tema \ 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 fcf2d3c94..480d869e5 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -108,7 +108,7 @@ NewPipe について サードパーティー ライセンス © %1$s 作者 %2$s ライセンス %3$s - このアプリについて + バージョン情報とよくある質問 ライセンス Android 向けのフリーで軽量なストリーミング。 GitHub で表示 @@ -176,7 +176,7 @@ 一度だけ データベースをインポート データベースをエクスポート - 既存の履歴、登録リスト、プレイリストおよび (任意) 設定は上書きされます + 既存の履歴、登録チャンネル一覧、プレイリストおよび (任意) 設定は上書きされます 再生履歴、登録チャンネル一覧、プレイリストおよび設定をエクスポートします エラーから回復中です 外部プレイヤーは、これらのタイプのリンクをサポートしていません @@ -705,4 +705,11 @@ 次のアイテムを表示する 再生済みを隠す 次のアイテムを隠す + 並び替え + ウェブサイトを表示 + タップして%sをダウンロード + あなたはNewPipeの最新版を起動しています + よくある質問 + アプリの使い方に困ったときは、よくある質問に答えていますので、ぜひご覧ください! + %sがテーマに選択された場合のみ、この選択肢が利用可能です \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index d7503a941..95df1e9a4 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -709,4 +709,10 @@ 자주 묻는 질문 웹사이트에서 보기 정렬 + 빠른 모드 + 점 3개 메뉴에서 구독 가져오기 또는 내보내기 + 최신 버전의 NewPipe를 실행 중입니다. + %s를 다운로드하려면 탭하세요. + 영구 썸네일 설정 해제 + 이 옵션은 테마로 %s를 선택한 경우에만 사용할 수 있음 \ No newline at end of file diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml index d937b6a69..f7d4eec86 100644 --- a/app/src/main/res/values-nn/strings.xml +++ b/app/src/main/res/values-nn/strings.xml @@ -14,7 +14,7 @@ Del Søk Innstillingar - Tenkte du på «%1$s»\? + Meinte du «%1$s»\? Del med Nytta ytre videospelar Tek bort ljod ved somme oppløysingar @@ -63,4 +63,11 @@ Straumar som ikkje enno er stødde av hentaren, er ikkje synlege Ukjend kvalitet Ukjend format + Forvald oppløysing + Forvald oppsprettsoppløysing + Vis eit val om å spela av ein video med mediasamlestaden Kodi + Skjer småbiletet til storleikshøvet 1:1 + Skjer videosmåbiletet som vert vist i varselet, ifrå storleikshøvet 16:9 til 1:1 + Fyrste gjerdknapp + Andre gjerdknapp \ 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 7497e5e48..0ad616d01 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -74,7 +74,7 @@ ଭିଡିଓ ବର୍ଣ୍ଣନା ଏବଂ ଅତିରିକ୍ତ ସୂଚନା ଲୁଚାଇବାକୁ ବନ୍ଦ କରନ୍ତୁ ଅଡିଓ ବାହ୍ୟ ଅଡିଓ ପ୍ଲେୟାର ବ୍ୟବହାର କରନ୍ତୁ - ସବସ୍କ୍ରାଇବ କରନ୍ତୁ + ସଦସ୍ୟତା ଯୋଡ଼ନ୍ତୁ ସଦସ୍ୟତା ଅଦ୍ୟତନ କରିପାରିଲା ନାହିଁ ଟ୍ୟାବ୍ ବାଛନ୍ତୁ ଅଡିଓ ଡାଉନଲୋଡ୍ ଫୋଲ୍ଡର୍ @@ -726,4 +726,5 @@ 3-ଡଟ୍ ମେନୁରୁ ସଦସ୍ୟତା ଆମଦାନୀ କିମ୍ବା ରପ୍ତାନି କରନ୍ତୁ ଆପଣ NewPipe ର ସର୍ବଶେଷ ସଂସ୍କରଣ ଚଳାଉଛନ୍ତି %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 08c7e47c9..169d45dad 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -726,4 +726,5 @@ 3-ਡੌਟ ਮੀਨੂ ਤੋਂ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਨੂੰ ਆਯਾਤ ਜਾਂ ਨਿਰਯਾਤ ਕਰੋ ਤੁਸੀਂ ਨਿਊਪਾਈਪ ਦਾ ਨਵੀਨਤਮ ਸੰਸਕਰਣ ਚਲਾ ਰਹੇ ਹੋ %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 a24be6b94..ab1e0aa72 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -618,7 +618,7 @@ Automatyczny (motyw urządzenia) Motyw nocny Pokaż szczegóły kanału - Wyłącz tunelowanie multimediów, jeśli zaobserwowałeś czarny ekran bądź brak płynności odtwarzania wideo + Wyłącz tunelowanie multimediów, jeśli zaobserwowałeś(-aś) czarny ekran bądź brak płynności odtwarzania wideo Wyłącz tunelowanie multimediów Ograniczenie wiekowe Wyłącz zaznaczanie tekstu w opisie @@ -747,4 +747,6 @@ Tryb szybki Importuj lub eksportuj subskrypcje z menu z trzema kropkami. Używasz najnowszej wersji NewPipe + Ta opcja jest dostępna tylko wtedy, gdy %s jest wybrany jako motyw + Usuń stałą miniaturę \ 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 be1f732d1..1929df070 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -739,4 +739,6 @@ Importar ou exportar inscrições do menu de 3 pontos Toque para baixar %s Você está executando a versão mais recente do NewPipe + Esta opção só está disponível se %s for selecionado para Tema + Desativar miniatura permanente \ 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 0a2205eee..5a0d19285 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -726,4 +726,5 @@ Já está a executar a versão mais recente do NewPipe Toque para descarregar %s Ordenação + Esta opção só está disponível se %s for selecionado como tema \ 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 862d6e383..e993da934 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -739,4 +739,5 @@ Importar ou exportar subscrições do menu de 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 %s for selecionado para o tema \ 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 636c617b2..2dc847daf 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -1,11 +1,11 @@ - Încărcat pe %1$s + Publicat pe %1$s Niciun player pentru streaming găsit. Instalați VLC\? Instalare Anulare Deschidere în browser - Distribuiți + Distribuire Descărcare Căutare Setări @@ -78,7 +78,7 @@ Vă rugăm așteptați… Copiat în clipboard Vă rugăm să definiți un folder de descărcare mai târziu în setări - Deschide în modul popup + Deschidere în modul popup Această permisiune este necesară pentru a \ndeschide în mod pop-up Provocare reCAPTCHA @@ -105,7 +105,7 @@ Alegeți sugestiile care vor fi afișate la căutare Ștergeți Rezoluție maximă - Abonează-te + Abonare Abonat(ă) Canal dezabonat Nu s-a putut modifica abonamentul @@ -176,9 +176,9 @@ Noi și populare Niciun player pentru streaming găsit. (Totuși, puteți instala VLC). Descărcați fișierul de flux - Arată informații + Afișare informații Playlist-uri salvate - Salvează în + 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 Încarcă miniaturi @@ -276,7 +276,7 @@ Viteză Acceptați Refuzați - Dezabonează-te + Dezabonare Alegeți fila Controlul prin gesturi al volumului Utilizați gesturi pentru a controla volumul @@ -367,9 +367,9 @@ Faceți ca Android să personalizeze culoarea notificării în funcție de culoarea principală din miniatură (rețineți că aceasta nu este disponibilă pe toate dispozitivele) Colorează notificarea Nimic - Tamponare + Se încarcă Redare aleatorie - Repetaţi + 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 Al cincilea buton de acțiune @@ -379,7 +379,7 @@ Primul buton de acțiune Tăiați miniatura video afișată în notificare de la raportul de aspect 16:9 la 1:1 (poate introduce distorsiuni) Tăiere miniatură la raportul de aspect 1:1 - Se arată rezultate pentru:%s + Se arată rezultate pentru: %s Nicio aplicație de pe dispozitivul dvs. nu poate deschide acesta Capitole Recente @@ -595,7 +595,7 @@ Dezactivați pentru a ascunde casetele de informații meta cu informații suplimentare despre creatorul fluxului, conținutul fluxului sau o cerere de căutare Dezactivați pentru a ascunde descrierea videoclipului și informațiile suplimentare Arată descrierea - Deschideți cu + Deschidere cu Blocați aplicația Rezolvați Evidențiate @@ -733,10 +733,11 @@ Ascunde elementele din viitor Vezi pe website Dacă întâmpinați probleme cu utilizarea aplicației, nu uitați să consultați aceste răspunsuri la întrebări frecvente! - Întrebări puse frecvent + Întrebări frecvente Sortează Modul rapid Importați sau exportați abonamente din meniul cu 3 puncte Rulați cea mai recentă versiune NewPipe Atingeți pentru a descărca %s + Această opțiune este disponibilă numai dacă %s este selectată ca temă \ No newline at end of file diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index c3051300f..bdae4fd37 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -722,4 +722,9 @@ Si ses tenende problemas impreende s\'aplicatzione assegura·ti de consultare custas rispostas a preguntas fitianas! Pòmpia in su situ web Òrdina + Toca pro iscarrigare %s + Modalidade lestra + Importa o esporta iscritziones dae su menù a 3 puntos + Ses impreende s\'ùrtima versione de NewPipe + Custa optzione est a disponimentu petzi si %s est seletzionadu comente tema \ No newline at end of file diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index ea2a9dbb5..222b4b137 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -61,7 +61,7 @@ Poskusi znova Opomba (v angleščini): v živo - Začnite z iskanjem + Pritisnite lupo in začnite z iskanjem. Začni Premor Izbriši @@ -320,13 +320,13 @@ Naključno Ponovi Izberete lahko največ 3 dejanja, ki se bodo prikazala v kompaktnem obvestilu! - Uredite vsako obvestilo z klikom na obvestilo. Izberite do 3 obvestila, ki se bodo prikazala v kompaktnem obvestilu z uporabo potrditvenega polja na desni. + Uredite vsako dejanje obvestila z klikom na posamezno dejanje. Z uporabo potrditvenega polja na desni izberite do 3 dejanja obvestil, ki se bodo prikazala v kompaktnem obvestilu Gumb za peto dejanje Gumb za četrto dejanje Gumb za tretje dejanje Gumb za drugo dejanje Gumb za prvo dejanje - Povečaj sličico videa, ki je prikazana v obvestilu iz razmerja 16:9 v razmerje 1:1 (lahko pride do popačenja) + Povečaj sličico videa, ki je prikazana v obvestilu iz razmerja 16:9 v razmerje 1:1 Zruši aplikacijo Spremeni velikost besedila podnapisov in stil ozadja v predvajalniku. Zahteva ponovni zagon aplikacije, da učinkuje. Podnapisi @@ -464,4 +464,8 @@ Prikaži puščanje pomnilnika Prikaži detajle kanala Nočna tema + Povečaj sličico na razmerje 1:1 + Označi kot že ogledano + Uporabite hitro nenatančno iskanje + Sesuj predvajalnik \ 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 3bdb388c4..fbe793569 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -726,4 +726,5 @@ Snabbt läge Du använder den senaste versionen av NewPipe Tryck för att ladda ner %s + Det här alternativet är endast tillgängligt om %s har valts som Tema \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index af5bb73ef..12effb9e2 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -366,4 +366,7 @@ แสดงตำแหน่งวีดิโอที่เล่นในรายการ ล้างข้อมูล กำลังแสดงผลลัพธ์สำหรับ: %s + เปิดด้วย + ทำเครื่องหมายว่าดูแล้ว + ตกลง \ 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 5c3d07204..c9718d0b0 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -726,4 +726,6 @@ NewPipe güncellemesi var! %s indirmek için dokunun 3-nokta menüsünden abonelikleri içe veya dışa aktarın + Bu seçenek yalnızca tema için %s seçildiğinde kullanılabilir + Kalıcı küçük resmin ayarını kaldır \ 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 9c4ec3957..e812e8e4f 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -743,4 +743,6 @@ Торкніться, щоб завантажити %s Імпорт або експорт підписок з 3-крапкового меню Швидкий режим + Ця опція доступна, лише якщо темою обрано %s + Прибрати постійну мініатюру \ 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 e43581523..c3ada7180 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -164,7 +164,7 @@ reCAPTCHA 验证 已请求新的 reCAPTCHA 验证 在悬浮窗中播放 - 默认分辨率(悬浮窗模式) + 悬浮窗默认分辨率 使用更高的分辨率 仅部分设备支持播放 2K 或 4K 视频 清除 @@ -713,4 +713,6 @@ 从三点菜单导入或导出订阅 你正在运行最新版的 NewPipe 轻按下载 %s + 只有在主题中选择了 %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 be81c294f..1ed552ab8 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -713,4 +713,5 @@ 輕點以下載 %s 快速模式 從三點式選單匯入或匯出訂閱 + 此選項僅在主題選擇為 %s 時可用 \ No newline at end of file diff --git a/fastlane/metadata/android/ar/changelogs/71.txt b/fastlane/metadata/android/ar/changelogs/71.txt index 6c02247bb..338ab17c5 100644 --- a/fastlane/metadata/android/ar/changelogs/71.txt +++ b/fastlane/metadata/android/ar/changelogs/71.txt @@ -1,10 +1,10 @@ -### تحسينات -* إضافة إشعار تحديث التطبيق لبناء GitHub (#1608 بواسطة krtkush) -* تحسينات مختلفة على برنامج التنزيل (# 1944 بواسطة kapodamy): - * إضافة الرموز البيضاء المفقودة واستخدام طريقة hardcored لتغيير ألوان الرمز - * تحقق مما إذا كان المكرر قد تمت تهيئته (إصلاحات #2031) - * السماح بإعادة المحاولة مع ظهور خطأ "فشلت المعالجة اللاحقة" في muxer الجديد - * MPEG-4 muxer الجديد الذي يعمل على تثبيت تدفقات الفيديو والصوت غير المتزامنة (#2039) +تحسين +*إضافة إشعار تحديث التطبيق لبناء GitHub (#1608 بواسطة krtkush) +*تحسينات مختلفة على برنامج التنزيل(#1944 بواسطة kapodamy): + *إضافة الرموز البيضاء المفقودة واستخدام طريقة hardcored لتغيير ألوان الرمز + *تحقق مما إذا كان المكرر قد تمت تهيئته(إصلاحات #2031) + *السماح بإعادة المحاولة مع ظهور خطأ "فشلت المعالجة اللاحقة" في muxer الجديد + *MPEG-4 muxer جديد يعمل على تثبيت تدفقات الفيديو والصوت غير المتزامنة(#2039) -### ثابت -* توقف البث المباشر على YouTube عن التشغيل بعد وقت قصير (#1996 by @yausername) +تصليح +*توقف البث المباشر على يوتيوب عن التشغيل بعد وقت قصير(#1996 by @yausername) diff --git a/fastlane/metadata/android/ar/changelogs/991.txt b/fastlane/metadata/android/ar/changelogs/991.txt new file mode 100644 index 000000000..5eaebe7a9 --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/991.txt @@ -0,0 +1,13 @@ +جديد +• إضافة زر "فتح في المتصفح" على واجهة الخطأ +• إضافة خيار لعرض مجموعات القنوات على شكل قائمة +• [YouTube] ضغطة مطولة على مقاطع الدفق لمشاركة رابط URL مع الطابع الزمني +• إضافة زر قائمة انتظار التشغيل للمشغل الصغير + +تحسينات +• إضافة الترجمة الأيسلندية وتحديث العديد من الترجمات الأخرى +• العديد من التحسينات الداخلية + +تصليحات +• إصلاح أعطاب متعددة +• [YouTube] إصلاح مشكلات تحميل القنوات، وتحميل التغذية غير المخصصة، والتشغيل البديل في بعض البلدان diff --git a/fastlane/metadata/android/de/changelogs/975.txt b/fastlane/metadata/android/de/changelogs/975.txt new file mode 100644 index 000000000..de60202d1 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/975.txt @@ -0,0 +1,16 @@ +Neu +- Anzeige eines Vorschaubilds während der Suche +- Deaktivierte Kommentare erkennen +- Erlaubt das Markieren eines Feed-Elements als beobachtet +- Kommentarherzen anzeigen + +Verbessert +- Verbessertes Layout von Metadaten und Tags +- Dienstfarbe auf UI-Komponenten anwenden + +Behoben +- Korrektur des Vorschaubilds im Mini-Player +- Behebung der endlosen Pufferung bei doppelten Warteschlangenelementen +- Einige Player-Fixes wie Rotation und schnelleres Schließen +- Behebung von ReCAPTCHA +... diff --git a/fastlane/metadata/android/de/changelogs/976.txt b/fastlane/metadata/android/de/changelogs/976.txt new file mode 100644 index 000000000..a70829150 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/976.txt @@ -0,0 +1,10 @@ +- Option zum direkten Öffnen des Players im Vollbildmodus hinzugefügt +- Auswahl der anzuzeigenden Suchvorschläge möglich +- Dunkles Theme jetzt dunkler + dunkler Splash-Screen hinzugefügt +- Verbesserte Dateiauswahl, um unerwünschte Dateien auszugrauen +- Import von YouTube-Abonnements behoben +- Das Wiederholen eines Streams erfordert ein erneutes Tippen auf die Wiedergabetaste +- Behoben: Audio-Sitzung schließen +... + +Änderungen finden Sie im Changelog (und im Blogbeitrag) auf dem Links-Tab unten. diff --git a/fastlane/metadata/android/de/changelogs/977.txt b/fastlane/metadata/android/de/changelogs/977.txt new file mode 100644 index 000000000..54c3d72f6 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/977.txt @@ -0,0 +1,9 @@ +- Die Schaltfläche "Weiter abspielen" wurde dem Langdruckmenü hinzugefügt +- YouTube Shorts Pfadpräfix zum Absichtsfilter hinzugefügt +- Import von Einstellungen behoben +- Position der Suchleiste mit Player-Schaltflächen im Warteschlangen-Bildschirm vertauscht +- Verschiedene Korrekturen im Zusammenhang mit MediasessionManager +- Die Suchleiste wurde nach dem Ende des Videos nicht abgeschlossen +... + +Weitere Änderungen finden Sie im Changelog (und im Blogbeitrag) auf der Registerkarte Links unten. diff --git a/fastlane/metadata/android/de/changelogs/988.txt b/fastlane/metadata/android/de/changelogs/988.txt new file mode 100644 index 000000000..bde54eda1 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/988.txt @@ -0,0 +1,2 @@ +[YouTube] Fehler „Konnte keinen Stream abrufen“ behoben beim Versuch, ein Video abzuspielen +[YouTube] "Der folgende Inhalt ist in dieser App nicht verfügbar." anstelle des angeforderten Videos behoben diff --git a/fastlane/metadata/android/de/changelogs/989.txt b/fastlane/metadata/android/de/changelogs/989.txt new file mode 100644 index 000000000..40e38f43e --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/989.txt @@ -0,0 +1,3 @@ +• [YouTube] Unendliches Laden behoben beim Versuch, ein Video abzuspielen +• [YouTube] Drosselung bei einigen Videos behoben +• Aktualisierung der jsoup-Bibliothek auf 1.15.3, die einen Sicherheitsfix enthält diff --git a/fastlane/metadata/android/de/changelogs/990.txt b/fastlane/metadata/android/de/changelogs/990.txt new file mode 100644 index 000000000..f1273a211 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/990.txt @@ -0,0 +1,15 @@ +Ab sofort entfällt die Unterstützung für Android 4.4 KitKat, die Mindestversion ist Android 5 Lollipop! + +Neu +- Herunterladen aus dem Langdruck-Menü +- Zukünftige Videos im Feed ausblenden +... + +Verbessert +- Refaktorierung des Player-Codes in kleine Komponenten: weniger RAM-Verbrauch, weniger Bugs +- Verbesserter Skalierungsmodus für Miniaturansichten +... + +Behoben +- Behebung verschiedener Probleme mit der Player-Benachrichtigung: veraltete/fehlende Medieninformationen, verzerrte Miniaturansicht +... diff --git a/fastlane/metadata/android/de/changelogs/991.txt b/fastlane/metadata/android/de/changelogs/991.txt new file mode 100644 index 000000000..3a8cae2cb --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/991.txt @@ -0,0 +1,13 @@ +Neu +- Schaltfläche "Im Browser öffnen" im Fehlerbedienfeld hinzugefügt +- Option zur Anzeige von Kanalgruppen als Liste hinzugefügt +- [YouTube] Langes Klicken auf Streamsegmente zum Teilen der Zeitstempel-URL +- Schaltfläche "Warteschlange abspielen" zum Mini-Player hinzugefügt + +Verbessert +- Isländische Lokalisierung hinzugefügt, viele Übersetzungen aktualisiert +- Viele interne Verbesserungen + +Behoben +- Mehrere Abstürze behoben +- [YouTube] Behebung von Problemen beim Laden von Kanälen... diff --git a/fastlane/metadata/android/hi/changelogs/991.txt b/fastlane/metadata/android/hi/changelogs/991.txt new file mode 100644 index 000000000..46ca2ebb6 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/991.txt @@ -0,0 +1 @@ +नया • त्रुटि पैनल में "ब्राउज़र में खोलें" बटन जोड़ें • चैनल समूहों को सूची के रूप में प्रदर्शित करने का विकल्प जोड़ें • [यूट्यूब] टाइमस्टैम्प यूआरएल साझा करने के लिए स्ट्रीम सेगमेंट पर लंबे समय तक क्लिक करें • मिनी प्लेयर में क्यू प्ले बटन जोड़ें उन्नत • आइसलैंडिक स्थानीयकरण जोड़ें और कई अन्य अनुवादों को अपडेट करें • कई आंतरिक सुधार हल किया गया • एकाधिक दुर्घटनाओं को ठीक करें • [यूट्यूब] कुछ देशों में लोडिंग चैनल, गैर-समर्पित फ़ीड और प्लेबैक समस्याओं को ठीक करें diff --git a/fastlane/metadata/android/pa/changelogs/65.txt b/fastlane/metadata/android/pa/changelogs/65.txt new file mode 100644 index 000000000..0fbf1147e --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/65.txt @@ -0,0 +1 @@ +### ਸੁਧਾਰ - ਬਰਗਰਮੇਨੂ ਆਈਕਨ ਐਨੀਮੇਸ਼ਨ #1486 ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ - ਡਾਉਨਲੋਡਸ #1472 ਨੂੰ ਮਿਟਾਉਣ ਨੂੰ ਅਨਡੂ ਕਰੋ - ਸ਼ੇਅਰ ਮੀਨੂ #1498 ਵਿੱਚ ਡਾਊਨਲੋਡ ਵਿਕਲਪ - ਲੰਬੇ ਟੈਪ ਮੀਨੂ #1454 ਵਿੱਚ ਸ਼ੇਅਰ ਵਿਕਲਪ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ - ਨਿਕਾਸ #1354 'ਤੇ ਮੁੱਖ ਪਲੇਅਰ ਨੂੰ ਛੋਟਾ ਕਰੋ - ਲਾਇਬ੍ਰੇਰੀ ਸੰਸਕਰਣ ਅਪਡੇਟ ਅਤੇ ਡੇਟਾਬੇਸ ਬੈਕਅਪ ਫਿਕਸ #1510 - ExoPlayer 2.8.2 ਅੱਪਡੇਟ #1392 - ਤੇਜ਼ ਗਤੀ ਤਬਦੀਲੀ ਲਈ ਵੱਖ-ਵੱਖ ਸਟੈਪ ਸਾਈਜ਼ ਦਾ ਸਮਰਥਨ ਕਰਨ ਲਈ ਪਲੇਬੈਕ ਸਪੀਡ ਕੰਟਰੋਲ ਡਾਇਲਾਗ ਨੂੰ ਦੁਬਾਰਾ ਬਣਾਇਆ ਗਿਆ। - ਪਲੇਬੈਕ ਸਪੀਡ ਨਿਯੰਤਰਣ ਵਿੱਚ ਚੁੱਪ ਦੌਰਾਨ ਫਾਸਟ-ਫਾਰਵਰਡ ਕਰਨ ਲਈ ਇੱਕ ਟੌਗਲ ਜੋੜਿਆ ਗਿਆ। ਇਹ ਆਡੀਓਬੁੱਕਾਂ ਅਤੇ ਕੁਝ ਸੰਗੀਤ ਸ਼ੈਲੀਆਂ ਲਈ ਮਦਦਗਾਰ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ, ਅਤੇ ਇੱਕ ਸੱਚਾ ਸਹਿਜ ਅਨੁਭਵ ਲਿਆ ਸਕਦਾ ਹੈ (ਅਤੇ ਬਹੁਤ ਸਾਰੀਆਂ ਚੁੱਪ =\\ ਨਾਲ ਗੀਤ ਤੋੜ ਸਕਦਾ ਹੈ)। - ਹੱਥੀਂ ਅਜਿਹਾ ਕਰਨ ਦੀ ਬਜਾਏ, ਪਲੇਅਰ ਵਿੱਚ ਅੰਦਰੂਨੀ ਤੌਰ 'ਤੇ ਮੀਡੀਆ ਦੇ ਨਾਲ-ਨਾਲ ਮੈਟਾਡੇਟਾ ਪਾਸ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣ ਲਈ ਰੀਫੈਕਟਰਡ ਮੀਡੀਆ ਸਰੋਤ ਰੈਜ਼ੋਲਿਊਸ਼ਨ। ਹੁਣ ਸਾਡੇ ਕੋਲ ਮੈਟਾਡੇਟਾ ਦਾ ਇੱਕ ਸਿੰਗਲ ਸਰੋਤ ਹੈ ਅਤੇ ਪਲੇਬੈਕ ਸ਼ੁਰੂ ਹੋਣ 'ਤੇ ਸਿੱਧਾ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ। - ਸਥਿਰ ਰਿਮੋਟ ਪਲੇਲਿਸਟ ਮੈਟਾਡੇਟਾ ਅੱਪਡੇਟ ਨਹੀਂ ਹੋ ਰਿਹਾ ਹੈ ਜਦੋਂ ਪਲੇਲਿਸਟ ਫਰੈਗਮੈਂਟ ਖੋਲ੍ਹਿਆ ਜਾਂਦਾ ਹੈ ਤਾਂ ਨਵਾਂ ਮੈਟਾਡੇਟਾ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ। - ਕਈ UI ਫਿਕਸ: #1383, ਬੈਕਗਰਾਊਂਡ ਪਲੇਅਰ ਨੋਟੀਫਿਕੇਸ਼ਨ ਕੰਟਰੋਲ ਹੁਣ ਹਮੇਸ਼ਾ ਸਫੈਦ, ਫਲਿੰਗਿੰਗ ਰਾਹੀਂ ਪੌਪਅੱਪ ਪਲੇਅਰ ਨੂੰ ਬੰਦ ਕਰਨਾ ਆਸਾਨ - ਮਲਟੀਸਰਵਿਸ ਲਈ ਰੀਫੈਕਟਰਡ ਆਰਕੀਟੈਕਚਰ ਦੇ ਨਾਲ ਨਵੇਂ ਐਕਸਟਰੈਕਟਰ ਦੀ ਵਰਤੋਂ ਕਰੋ ### ਫਿਕਸ - #1440 ਟੁੱਟੇ ਹੋਏ ਵੀਡੀਓ ਜਾਣਕਾਰੀ ਲੇਆਉਟ #1491 ਨੂੰ ਠੀਕ ਕਰੋ - ਇਤਿਹਾਸ ਫਿਕਸ #1497 ਦੇਖੋ - #1495, ਜਿਵੇਂ ਹੀ ਉਪਭੋਗਤਾ ਪਲੇਲਿਸਟ ਤੱਕ ਪਹੁੰਚ ਕਰਦਾ ਹੈ, ਮੈਟਾਡੇਟਾ (ਥੰਬਨੇਲ, ਸਿਰਲੇਖ ਅਤੇ ਵੀਡੀਓ ਗਿਣਤੀ) ਨੂੰ ਅਪਡੇਟ ਕਰਕੇ। - #1475, ਜਦੋਂ ਉਪਭੋਗਤਾ ਵੇਰਵੇ ਦੇ ਟੁਕੜੇ 'ਤੇ ਬਾਹਰੀ ਪਲੇਅਰ 'ਤੇ ਵੀਡੀਓ ਸ਼ੁਰੂ ਕਰਦਾ ਹੈ ਤਾਂ ਡੇਟਾਬੇਸ ਵਿੱਚ ਇੱਕ ਦ੍ਰਿਸ਼ ਨੂੰ ਰਜਿਸਟਰ ਕਰਕੇ। - ਪੌਪਅੱਪ ਮੋਡ ਦੇ ਮਾਮਲੇ ਵਿੱਚ ਕ੍ਰੀਨ ਟਾਈਮਆਊਟ ਫਿਕਸ ਕਰੋ। #1463 (ਸਥਿਰ #640) - ਮੁੱਖ ਵੀਡੀਓ ਪਲੇਅਰ ਫਿਕਸ #1509 - [#1412] ਫਿਕਸਡ ਰੀਪੀਟ ਮੋਡ ਜਿਸ ਨਾਲ ਪਲੇਅਰ ਐਨਪੀਈ ਦਾ ਕਾਰਨ ਬਣਦਾ ਹੈ ਜਦੋਂ ਪਲੇਅਰ ਦੀ ਗਤੀਵਿਧੀ ਬੈਕਗ੍ਰਾਉਂਡ ਵਿੱਚ ਹੁੰਦੀ ਹੈ ਤਾਂ ਨਵਾਂ ਇਰਾਦਾ ਪ੍ਰਾਪਤ ਹੁੰਦਾ ਹੈ। - ਪੌਪਅੱਪ ਲਈ ਫਿਕਸਡ ਮਿਨੀਮਾਈਜ਼ਿੰਗ ਪਲੇਅਰ ਪਲੇਅਰ ਨੂੰ ਨਸ਼ਟ ਨਹੀਂ ਕਰਦਾ ਹੈ ਜਦੋਂ ਪੌਪਅੱਪ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ। diff --git a/fastlane/metadata/android/pa/changelogs/66.txt b/fastlane/metadata/android/pa/changelogs/66.txt new file mode 100644 index 000000000..aecf80cbc --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/66.txt @@ -0,0 +1 @@ +# v0.13.7 ਦਾ ਚੇਂਜਲਾਗ ### ਸਥਿਰ - v0.13.6 ਦੇ ਕ੍ਰਮਬੱਧ ਫਿਲਟਰ ਮੁੱਦਿਆਂ ਨੂੰ ਠੀਕ ਕਰੋ # v0.13.6 ਦਾ ਚੇਂਜਲਾਗ ### ਸੁਧਾਰ - ਬਰਗਰਮੇਨੂ ਆਈਕਨ ਐਨੀਮੇਸ਼ਨ #1486 ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ - ਡਾਉਨਲੋਡਸ #1472 ਨੂੰ ਮਿਟਾਉਣ ਨੂੰ ਅਨਡੂ ਕਰੋ - ਸ਼ੇਅਰ ਮੀਨੂ #1498 ਵਿੱਚ ਡਾਊਨਲੋਡ ਵਿਕਲਪ - ਲੰਬੇ ਟੈਪ ਮੀਨੂ #1454 ਵਿੱਚ ਸ਼ੇਅਰ ਵਿਕਲਪ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ - ਨਿਕਾਸ #1354 'ਤੇ ਮੁੱਖ ਪਲੇਅਰ ਨੂੰ ਛੋਟਾ ਕਰੋ - ਲਾਇਬ੍ਰੇਰੀ ਸੰਸਕਰਣ ਅਪਡੇਟ ਅਤੇ ਡੇਟਾਬੇਸ ਬੈਕਅਪ ਫਿਕਸ #1510 - ExoPlayer 2.8.2 ਅੱਪਡੇਟ #1392 - ਤੇਜ਼ ਗਤੀ ਤਬਦੀਲੀ ਲਈ ਵੱਖ-ਵੱਖ ਸਟੈਪ ਸਾਈਜ਼ ਦਾ ਸਮਰਥਨ ਕਰਨ ਲਈ ਪਲੇਬੈਕ ਸਪੀਡ ਕੰਟਰੋਲ ਡਾਇਲਾਗ ਨੂੰ ਦੁਬਾਰਾ ਬਣਾਇਆ ਗਿਆ। - ਪਲੇਬੈਕ ਸਪੀਡ ਨਿਯੰਤਰਣ ਵਿੱਚ ਚੁੱਪ ਦੌਰਾਨ ਫਾਸਟ-ਫਾਰਵਰਡ ਕਰਨ ਲਈ ਇੱਕ ਟੌਗਲ ਜੋੜਿਆ ਗਿਆ। ਇਹ ਆਡੀਓਬੁੱਕਾਂ ਅਤੇ ਕੁਝ ਸੰਗੀਤ ਸ਼ੈਲੀਆਂ ਲਈ ਮਦਦਗਾਰ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ, ਅਤੇ ਇੱਕ ਸੱਚਾ ਸਹਿਜ ਅਨੁਭਵ ਲਿਆ ਸਕਦਾ ਹੈ (ਅਤੇ ਬਹੁਤ ਸਾਰੀਆਂ ਚੁੱਪ =\\ ਨਾਲ ਗੀਤ ਤੋੜ ਸਕਦਾ ਹੈ)। - ਹੱਥੀਂ ਅਜਿਹਾ ਕਰਨ ਦੀ ਬਜਾਏ, ਪਲੇਅਰ ਵਿੱਚ ਅੰਦਰੂਨੀ ਤੌਰ 'ਤੇ ਮੀਡੀਆ ਦੇ ਨਾਲ-ਨਾਲ ਮੈਟਾਡੇਟਾ ਪਾਸ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣ ਲਈ ਰੀਫੈਕਟਰਡ ਮੀਡੀਆ ਸਰੋਤ ਰੈਜ਼ੋਲਿਊਸ਼ਨ। ਹੁਣ ਸਾਡੇ ਕੋਲ ਮੈਟਾਡੇਟਾ ਦਾ ਇੱਕ ਸਿੰਗਲ ਸਰੋਤ ਹੈ ਅਤੇ ਪਲੇਬੈਕ ਸ਼ੁਰੂ ਹੋਣ 'ਤੇ ਸਿੱਧਾ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ। - ਸਥਿਰ ਰਿਮੋਟ ਪਲੇਲਿਸਟ ਮੈਟਾਡੇਟਾ ਅੱਪਡੇਟ ਨਹੀਂ ਹੋ ਰਿਹਾ ਹੈ ਜਦੋਂ ਪਲੇਲਿਸਟ ਫਰੈਗਮੈਂਟ ਖੋਲ੍ਹਿਆ ਜਾਂਦਾ ਹੈ ਤਾਂ ਨਵਾਂ ਮੈਟਾਡੇਟਾ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ। - ਕਈ UI ਫਿਕਸ: #1383, ਬੈਕਗਰਾਊਂਡ ਪਲੇਅਰ ਨੋਟੀਫਿਕੇਸ਼ਨ ਕੰਟਰੋਲ ਹੁਣ ਹਮੇਸ਼ਾ ਸਫੈਦ, ਫਲਿੰਗਿੰਗ ਰਾਹੀਂ ਪੌਪਅੱਪ ਪਲੇਅਰ ਨੂੰ ਬੰਦ ਕਰਨਾ ਆਸਾਨ - ਮਲਟੀਸਰਵਿਸ ਲਈ ਰੀਫੈਕਟਰਡ ਆਰਕੀਟੈਕਚਰ ਦੇ ਨਾਲ ਨਵੇਂ ਐਕਸਟਰੈਕਟਰ ਦੀ ਵਰਤੋਂ ਕਰੋ ### ਫਿਕਸ - #1440 ਟੁੱਟੇ ਹੋਏ ਵੀਡੀਓ ਜਾਣਕਾਰੀ ਲੇਆਉਟ #1491 ਨੂੰ ਠੀਕ ਕਰੋ - ਇਤਿਹਾਸ ਫਿਕਸ #1497 ਦੇਖੋ - #1495, ਜਿਵੇਂ ਹੀ ਉਪਭੋਗਤਾ ਪਲੇਲਿਸਟ ਤੱਕ ਪਹੁੰਚ ਕਰਦਾ ਹੈ, ਮੈਟਾਡੇਟਾ (ਥੰਬਨੇਲ, ਸਿਰਲੇਖ ਅਤੇ ਵੀਡੀਓ ਗਿਣਤੀ) ਨੂੰ ਅਪਡੇਟ ਕਰਕੇ। - #1475, ਜਦੋਂ ਉਪਭੋਗਤਾ ਵੇਰਵੇ ਦੇ ਟੁਕੜੇ 'ਤੇ ਬਾਹਰੀ ਪਲੇਅਰ 'ਤੇ ਵੀਡੀਓ ਸ਼ੁਰੂ ਕਰਦਾ ਹੈ ਤਾਂ ਡੇਟਾਬੇਸ ਵਿੱਚ ਇੱਕ ਦ੍ਰਿਸ਼ ਨੂੰ ਰਜਿਸਟਰ ਕਰਕੇ। - ਪੌਪਅੱਪ ਮੋਡ ਦੇ ਮਾਮਲੇ ਵਿੱਚ ਕ੍ਰੀਨ ਟਾਈਮਆਊਟ ਫਿਕਸ ਕਰੋ। #1463 (ਸਥਿਰ #640) - ਮੁੱਖ ਵੀਡੀਓ ਪਲੇਅਰ ਫਿਕਸ #1509 - [#1412] ਫਿਕਸਡ ਰੀਪੀਟ ਮੋਡ ਜਿਸ ਨਾਲ ਪਲੇਅਰ ਐਨਪੀਈ ਦਾ ਕਾਰਨ ਬਣਦਾ ਹੈ ਜਦੋਂ ਪਲੇਅਰ ਦੀ ਗਤੀਵਿਧੀ ਬੈਕਗ੍ਰਾਉਂਡ ਵਿੱਚ ਹੁੰਦੀ ਹੈ ਤਾਂ ਨਵਾਂ ਇਰਾਦਾ ਪ੍ਰਾਪਤ ਹੁੰਦਾ ਹੈ। - ਪੌਪਅੱਪ ਲਈ ਫਿਕਸਡ ਮਿਨੀਮਾਈਜ਼ਿੰਗ ਪਲੇਅਰ ਪਲੇਅਰ ਨੂੰ ਨਸ਼ਟ ਨਹੀਂ ਕਰਦਾ ਹੈ ਜਦੋਂ ਪੌਪਅੱਪ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ। diff --git a/fastlane/metadata/android/pa/changelogs/68.txt b/fastlane/metadata/android/pa/changelogs/68.txt new file mode 100644 index 000000000..e8e54ea4f --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/68.txt @@ -0,0 +1 @@ +v0.14.1 ਦੇ # ਬਦਲਾਅ ### ਸਥਿਰ - ਵੀਡੀਓ url #1659 ਨੂੰ ਡੀਕ੍ਰਿਪਟ ਕਰਨ ਵਿੱਚ ਅਸਫਲ ਰਿਹਾ - ਸਥਿਰ ਵਰਣਨ ਲਿੰਕ #1657 ਨੂੰ ਚੰਗੀ ਤਰ੍ਹਾਂ ਐਕਸਟਰੈਕਟ ਨਹੀਂ ਕਰਦਾ ਹੈ v0.14.0 ਦੀਆਂ # ਤਬਦੀਲੀਆਂ ### ਨਵਾਂ - ਨਵਾਂ ਦਰਾਜ਼ ਡਿਜ਼ਾਈਨ #1461 - ਨਵਾਂ ਅਨੁਕੂਲਿਤ ਫਰੰਟ ਪੇਜ #1461 ### ਸੁਧਾਰ - ਮੁੜ ਕੰਮ ਕੀਤਾ ਸੰਕੇਤ ਨਿਯੰਤਰਣ #1604 - ਪੌਪਅੱਪ ਪਲੇਅਰ #1597 ਨੂੰ ਬੰਦ ਕਰਨ ਦਾ ਨਵਾਂ ਤਰੀਕਾ ### ਸਥਿਰ - ਗਾਹਕੀ ਦੀ ਗਿਣਤੀ ਉਪਲਬਧ ਨਾ ਹੋਣ 'ਤੇ ਗਲਤੀ ਨੂੰ ਠੀਕ ਕਰੋ। #1649 ਬੰਦ ਹੁੰਦਾ ਹੈ। - ਉਹਨਾਂ ਮਾਮਲਿਆਂ ਵਿੱਚ "ਗਾਹਕ ਗਿਣਤੀ ਉਪਲਬਧ ਨਹੀਂ" ਦਿਖਾਓ - YouTube ਪਲੇਲਿਸਟ ਖਾਲੀ ਹੋਣ 'ਤੇ NPE ਨੂੰ ਠੀਕ ਕਰੋ - SoundCloud ਵਿੱਚ ਕਿਓਸਕ ਲਈ ਤੁਰੰਤ ਫਿਕਸ - ਰਿਫੈਕਟਰ ਅਤੇ ਬੱਗਫਿਕਸ #1623 - ਚੱਕਰੀ ਖੋਜ ਨਤੀਜੇ #1562 ਨੂੰ ਠੀਕ ਕਰੋ - ਸੀਕ ਬਾਰ ਨੂੰ ਸਥਿਰ ਤੌਰ 'ਤੇ ਬਾਹਰ ਨਾ ਕੱਢੋ - ਫਿਕਸ YT ਪ੍ਰੀਮੀਅਮ ਵੀਡੀਓ ਨੂੰ ਸਹੀ ਢੰਗ ਨਾਲ ਬਲੌਕ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ - ਕਈ ਵਾਰ ਲੋਡ ਨਾ ਹੋਣ ਵਾਲੇ ਵੀਡੀਓ ਨੂੰ ਠੀਕ ਕਰੋ (DASH ਪਾਰਸਿੰਗ ਦੇ ਕਾਰਨ) - ਵੀਡੀਓ ਵਰਣਨ ਵਿੱਚ ਲਿੰਕ ਫਿਕਸ ਕਰੋ - ਜਦੋਂ ਕੋਈ ਬਾਹਰੀ sdcard 'ਤੇ ਡਾਊਨਲੋਡ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ ਤਾਂ ਚੇਤਾਵਨੀ ਦਿਖਾਓ - ਅਪਵਾਦ ਟਰਿੱਗਰ ਰਿਪੋਰਟ ਦਿਖਾਈ ਗਈ ਕੁਝ ਵੀ ਠੀਕ ਨਾ ਕਰੋ - ਐਂਡਰਾਇਡ 8.1 ਲਈ ਬੈਕਗ੍ਰਾਉਂਡ ਪਲੇਅਰ ਵਿੱਚ ਥੰਬਨੇਲ ਨਹੀਂ ਦਿਖਾਇਆ ਗਿਆ [ਇੱਥੇ ਦੇਖੋ](https://github.com/TeamNewPipe/NewPipe/issues/943) - ਪ੍ਰਸਾਰਣ ਪ੍ਰਾਪਤ ਕਰਨ ਵਾਲੇ ਦੀ ਰਜਿਸਟਰੇਸ਼ਨ ਨੂੰ ਠੀਕ ਕਰੋ। #1641 ਬੰਦ ਹੁੰਦਾ ਹੈ। diff --git a/fastlane/metadata/android/pa/changelogs/69.txt b/fastlane/metadata/android/pa/changelogs/69.txt new file mode 100644 index 000000000..b6358991b --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/69.txt @@ -0,0 +1 @@ +### ਨਵਾਂ - ਮਿਟਾਓ ਅਤੇ ਸਬਸਕ੍ਰਿਪਸ਼ਨ #1516 ਵਿੱਚ ਸਾਂਝਾ ਕਰੋ - ਟੈਬਲੇਟ UI ਅਤੇ ਗਰਿੱਡ ਸੂਚੀ ਖਾਕਾ #1617 ### ਸੁਧਾਰ - ਆਖਰੀ ਵਰਤੇ ਗਏ ਆਸਪੈਕਟ ਰੇਸ਼ੋ #1748 ਨੂੰ ਸਟੋਰ ਅਤੇ ਰੀਲੋਡ ਕਰੋ - ਪੂਰੇ ਵੀਡੀਓ ਨਾਮ #1771 ਦੇ ਨਾਲ ਡਾਊਨਲੋਡ ਗਤੀਵਿਧੀ ਵਿੱਚ ਲੀਨੀਅਰ ਲੇਆਉਟ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ - ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਟੈਬ #1516 ਦੇ ਅੰਦਰੋਂ ਸਿੱਧਾ ਗਾਹਕੀਆਂ ਨੂੰ ਮਿਟਾਓ ਅਤੇ ਸਾਂਝਾ ਕਰੋ - ਜੇਕਰ ਪਲੇ ਕਤਾਰ ਪਹਿਲਾਂ ਹੀ #1783 ਖਤਮ ਹੋ ਗਈ ਹੈ ਤਾਂ ਹੁਣ ਏਨਕਿਊ ਕਰਨਾ ਵੀਡੀਓ ਚਲਾਉਣ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ - ਵਾਲੀਅਮ ਅਤੇ ਚਮਕ ਸੰਕੇਤ #1644 ਲਈ ਵੱਖਰੀ ਸੈਟਿੰਗ - ਸਥਾਨਕਕਰਨ #1792 ਲਈ ਸਮਰਥਨ ਸ਼ਾਮਲ ਕਰੋ ### ਫਿਕਸ - ਲਈ ਪਾਰਸਿੰਗ ਸਮਾਂ ਫਿਕਸ ਕਰੋ। ਫਾਰਮੈਟ, ਇਸ ਲਈ ਨਿਊ ਪਾਈਪ ਨੂੰ ਫਿਨਲੈਂਡ ਵਿੱਚ ਵਰਤਿਆ ਜਾ ਸਕਦਾ ਹੈ - ਗਾਹਕੀ ਦੀ ਗਿਣਤੀ ਨੂੰ ਠੀਕ ਕਰੋ - API 28+ ਡਿਵਾਈਸਾਂ #1830 ਲਈ ਫੋਰਗਰਾਉਂਡ ਸੇਵਾ ਅਨੁਮਤੀ ਸ਼ਾਮਲ ਕਰੋ ### ਜਾਣੇ-ਪਛਾਣੇ ਬੱਗ - ਐਂਡ੍ਰਾਇਡ ਪੀ 'ਤੇ ਪਲੇਬੈਕ ਸਟੇਟ ਨੂੰ ਸੇਵ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ diff --git a/fastlane/metadata/android/pa/changelogs/70.txt b/fastlane/metadata/android/pa/changelogs/70.txt new file mode 100644 index 000000000..97d781d4a --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/70.txt @@ -0,0 +1 @@ +ਧਿਆਨ ਦਿਓ: ਇਹ ਸੰਸਕਰਣ ਸ਼ਾਇਦ ਇੱਕ ਬੱਗਫੈਸਟ ਹੈ, ਬਿਲਕੁਲ ਪਿਛਲੇ ਇੱਕ ਵਾਂਗ। ਹਾਲਾਂਕਿ 17 ਤੋਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਬੰਦ ਹੋਣ ਦੇ ਕਾਰਨ. ਇੱਕ ਟੁੱਟਿਆ ਹੋਇਆ ਸੰਸਕਰਣ ਕੋਈ ਸੰਸਕਰਣ ਨਾਲੋਂ ਬਿਹਤਰ ਹੈ. ਸਹੀ? ¯\_(ツ)_/¯ ### ਸੁਧਾਰ * ਡਾਊਨਲੋਡ ਕੀਤੀਆਂ ਫਾਈਲਾਂ ਨੂੰ ਹੁਣ ਇੱਕ ਕਲਿੱਕ ਨਾਲ ਖੋਲ੍ਹਿਆ ਜਾ ਸਕਦਾ ਹੈ #1879 * ਐਂਡਰਾਇਡ 4.1 - 4.3 #1884 ਲਈ ਸਹਾਇਤਾ ਛੱਡੋ * ਪੁਰਾਣੇ ਪਲੇਅਰ #1884 ਨੂੰ ਹਟਾਓ * ਮੌਜੂਦਾ ਪਲੇ ਕਤਾਰ ਤੋਂ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਸੱਜੇ #1915 'ਤੇ ਸਵਾਈਪ ਕਰਕੇ ਹਟਾਓ * ਆਟੋ ਕਤਾਰਬੱਧ ਸਟ੍ਰੀਮ ਨੂੰ ਹਟਾਓ ਜਦੋਂ ਇੱਕ ਨਵੀਂ ਸਟ੍ਰੀਮ ਹੱਥੀਂ ਕਤਾਰਬੱਧ ਹੁੰਦੀ ਹੈ #1878 * @kapodamy ਦੁਆਰਾ ਡਾਉਨਲੋਡ ਕਰਨ ਅਤੇ ਗੁੰਮ ਹੋਈਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ #1759 ਨੂੰ ਲਾਗੂ ਕਰਨ ਲਈ ਪੋਸਟ ਪ੍ਰੋਸੈਸਿੰਗ * ਪੋਸਟ-ਪ੍ਰੋਸੈਸਿੰਗ ਬੁਨਿਆਦੀ ਢਾਂਚਾ * "ਬੁਨਿਆਦੀ ਢਾਂਚੇ" ਨੂੰ ਸੰਭਾਲਣ ਲਈ ਸਹੀ ਤਰੁੱਟੀ (ਡਾਊਨਲੋਡਰ ਲਈ) * ਮਲਟੀਪਲ ਡਾਉਨਲੋਡਸ ਦੀ ਬਜਾਏ ਕਤਾਰ * ਲੜੀਬੱਧ ਲੰਬਿਤ ਡਾਉਨਲੋਡਸ (`ਗੀਗਾ` ਫਾਈਲਾਂ) ਨੂੰ ਐਪ ਡੇਟਾ ਵਿੱਚ ਮੂਵ ਕਰੋ * ਅਧਿਕਤਮ ਡਾਊਨਲੋਡ ਦੀ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਨੂੰ ਲਾਗੂ ਕਰੋ * ਉਚਿਤ ਮਲਟੀ-ਥ੍ਰੈਡ ਡਾਊਨਲੋਡ ਵਿਰਾਮ * ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ 'ਤੇ ਜਾਣ ਵੇਲੇ ਡਾਊਨਲੋਡ ਬੰਦ ਕਰੋ (ਕਦੇ ਕੰਮ ਨਹੀਂ ਕਰਦਾ, ਦੂਜਾ ਪੁਆਇੰਟ ਦੇਖੋ) * ਅਗਲੇ ਡਾਉਨਲੋਡਸ ਲਈ ਥਰਿੱਡ ਗਿਣਤੀ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰੋ * ਬਹੁਤ ਸਾਰੀਆਂ ਅਸੰਗਤੀਆਂ ਹੱਲ ਕੀਤੀਆਂ ਗਈਆਂ ### ਸਥਿਰ * ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਨਾਲ ਕਰੈਸ਼ ਨੂੰ ਬਿਹਤਰ ਅਤੇ ਸੀਮਤ ਮੋਬਾਈਲ ਡਾਟਾ ਰੈਜ਼ੋਲਿਊਸ਼ਨ #1835 'ਤੇ ਸੈੱਟ ਕਰੋ * ਪੌਪ-ਅੱਪ ਪਲੇਅਰ ਕਰੈਸ਼ ਫਿਕਸਡ #1874 * ਬੈਕਗਰਾਊਂਡ ਪਲੇਅਰ #1901 ਨੂੰ ਖੋਲ੍ਹਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਸਮੇਂ NPE * ਜਦੋਂ ਆਟੋ ਕਤਾਰ ਯੋਗ ਹੁੰਦੀ ਹੈ ਤਾਂ ਨਵੀਆਂ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਸੰਮਿਲਿਤ ਕਰਨ ਲਈ ਠੀਕ ਕਰੋ #1878 * ਡੀਸਾਈਪਰਿੰਗ ਸ਼ੱਟਟਾਊਨ ਮੁੱਦੇ ਨੂੰ ਹੱਲ ਕੀਤਾ ਗਿਆ diff --git a/fastlane/metadata/android/pa/changelogs/71.txt b/fastlane/metadata/android/pa/changelogs/71.txt new file mode 100644 index 000000000..bafa26f8c --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/71.txt @@ -0,0 +1 @@ +### ਸੁਧਾਰ * GitHub ਬਿਲਡ ਲਈ ਐਪ ਅਪਡੇਟ ਨੋਟੀਫਿਕੇਸ਼ਨ ਸ਼ਾਮਲ ਕਰੋ (@krtkush ਦੁਆਰਾ #1608) * ਡਾਊਨਲੋਡਰ ਵਿੱਚ ਕਈ ਸੁਧਾਰ (@kapodamy ਦੁਆਰਾ #1944): * ਗੁੰਮ ਹੋਏ ਚਿੱਟੇ ਆਈਕਨ ਸ਼ਾਮਲ ਕਰੋ ਅਤੇ ਆਈਕਨ ਦੇ ਰੰਗਾਂ ਨੂੰ ਬਦਲਣ ਲਈ ਹਾਰਡਕੋਰਡ ਤਰੀਕੇ ਦੀ ਵਰਤੋਂ ਕਰੋ * ਜਾਂਚ ਕਰੋ ਕਿ ਕੀ ਇਟਰੇਟਰ ਸ਼ੁਰੂ ਕੀਤਾ ਗਿਆ ਹੈ (ਫਿਕਸ #2031) * ਨਵੇਂ ਮੁਕਸਰ ਵਿੱਚ "ਪੋਸਟ-ਪ੍ਰੋਸੈਸਿੰਗ ਫੇਲ੍ਹ" ਗਲਤੀ ਦੇ ਨਾਲ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ * ਨਵਾਂ MPEG-4 ਮੁਕਸਰ ਫਿਕਸਿੰਗ ਗੈਰ-ਸਿੰਕਰੋਨਸ ਵੀਡੀਓ ਅਤੇ ਆਡੀਓ ਸਟ੍ਰੀਮਜ਼ (#2039) ### ਸਥਿਰ * YouTube ਲਾਈਵ ਸਟ੍ਰੀਮਾਂ ਥੋੜ੍ਹੇ ਸਮੇਂ ਬਾਅਦ ਚੱਲਣੀਆਂ ਬੰਦ ਹੋ ਜਾਂਦੀਆਂ ਹਨ (@yausername ਦੁਆਰਾ #1996) diff --git a/fastlane/metadata/android/pa/changelogs/730.txt b/fastlane/metadata/android/pa/changelogs/730.txt new file mode 100644 index 000000000..56f5a7d32 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/730.txt @@ -0,0 +1,2 @@ +# ਠੀਕ ਕੀਤਾ +- ਹੌਟ ਫਿਕਸ ਦੁਬਾਰਾ ਗਲਤ ਹੋਇਆ ਡੀਕ੍ਰਿਪਟ ਫੰਕਸ਼ਨ ਠੀਕ । diff --git a/fastlane/metadata/android/pa/changelogs/740.txt b/fastlane/metadata/android/pa/changelogs/740.txt new file mode 100644 index 000000000..6a2dbdc86 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/740.txt @@ -0,0 +1 @@ +ਬਦਲਾਅ ਸੂਚੀ ਅਨੁਵਾਦ ਕਰਣਯੋਗ ਨਹੀਂ। ਬਿਲਕੁਲ ਬਕਵਾਸ diff --git a/fastlane/metadata/android/pa/changelogs/750.txt b/fastlane/metadata/android/pa/changelogs/750.txt new file mode 100644 index 000000000..0b875b705 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/750.txt @@ -0,0 +1 @@ +ਨਵਾਂ ਪਲੇਬੈਕ ਰੈਜ਼ਿਊਮੇ #2288 • ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਮੁੜ ਸ਼ੁਰੂ ਕਰੋ ਜਿੱਥੇ ਤੁਸੀਂ ਪਿਛਲੀ ਵਾਰ ਰੁਕੇ ਸੀ ਡਾਊਨਲੋਡਰ ਸੁਧਾਰ #2149 • ਬਾਹਰੀ SD-ਕਾਰਡਾਂ 'ਤੇ ਡਾਊਨਲੋਡ ਸਟੋਰ ਕਰਨ ਲਈ ਸਟੋਰੇਜ਼ ਐਕਸੈਸ ਫਰੇਮਵਰਕ ਦੀ ਵਰਤੋਂ ਕਰੋ • ਨਵਾਂ mp4 muxer • ਡਾਊਨਲੋਡ ਸ਼ੁਰੂ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਵਿਕਲਪਿਕ ਤੌਰ 'ਤੇ ਡਾਉਨਲੋਡ ਡਾਇਰੈਕਟਰੀ ਨੂੰ ਬਦਲੋ • ਮੀਟਰਡ ਨੈੱਟਵਰਕਾਂ ਦਾ ਆਦਰ ਕਰੋ ਸੁਧਾਰ • gema ਸਤਰ #2295 ਨੂੰ ਹਟਾਇਆ • ਗਤੀਵਿਧੀ ਜੀਵਨ ਚੱਕਰ #2444 ਦੌਰਾਨ ਹੈਂਡਲ (ਆਟੋ) ਰੋਟੇਸ਼ਨ ਤਬਦੀਲੀਆਂ • ਲੰਬੇ-ਦਬਾਓ ਮੀਨੂ ਨੂੰ ਇਕਸਾਰ #2368 ਬਣਾਓ ਸਥਿਰ • ਫਿਕਸਡ ਚੁਣਿਆ ਹੋਇਆ ਉਪਸਿਰਲੇਖ ਟਰੈਕ ਨਾਮ #2394 ਨਹੀਂ ਦਿਖਾਇਆ ਜਾ ਰਿਹਾ ਹੈ • ਐਪ ਅੱਪਡੇਟ ਦੀ ਜਾਂਚ ਅਸਫਲ ਹੋਣ 'ਤੇ ਕ੍ਰੈਸ਼ ਨਾ ਹੋਵੋ (GitHub ਸੰਸਕਰਣ) #2423 • ਸਥਿਰ ਡਾਊਨਲੋਡ 99.9% #2440 'ਤੇ ਅਟਕ ਗਏ • ਪਲੇ ਕਤਾਰ ਮੈਟਾਡੇਟਾ #2453 ਨੂੰ ਅੱਪਡੇਟ ਕਰੋ • [SoundCloud] ਪਲੇਲਿਸਟਸ ਲੋਡ ਕਰਨ ਵੇਲੇ ਸਥਿਰ ਕਰੈਸ਼ TeamNewPipe/NewPipeExtractor#170 • [YouTube] ਸਥਿਰ ਅਵਧੀ ਨੂੰ ਪਾਰਸਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ TeamNewPipe/NewPipeExtractor#177 diff --git a/fastlane/metadata/android/pa/changelogs/760.txt b/fastlane/metadata/android/pa/changelogs/760.txt new file mode 100644 index 000000000..fd4b8f2a4 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/760.txt @@ -0,0 +1 @@ +0.17.1 ਵਿੱਚ ਬਦਲਾਅ ਨਵਾਂ • ਥਾਈ ਸਥਾਨਕਕਰਨ ਸੁਧਾਰ • ਦੁਬਾਰਾ #2518 ਪਲੇਲਿਸਟਾਂ ਲਈ ਲੰਬੇ-ਦਬਾਓ ਮੀਨੂ ਵਿੱਚ ਇੱਥੇ ਪਲੇ ਸ਼ੁਰੂ ਕਰੋ ਐਕਸ਼ਨ ਸ਼ਾਮਲ ਕਰੋ • SAF / ਪੁਰਾਤਨ ਫਾਈਲ ਪਿਕਰ #2521 ਲਈ ਸਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ ਸਥਿਰ • ਐਪਸ #2487 ਨੂੰ ਬਦਲਦੇ ਸਮੇਂ ਡਾਊਨਲੋਡ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਗਾਇਬ ਹੋਣ ਵਾਲੇ ਬਟਨਾਂ ਨੂੰ ਠੀਕ ਕਰੋ • ਫਿਕਸ ਪਲੇਬੈਕ ਸਥਿਤੀ ਸਟੋਰ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਹਾਲਾਂਕਿ ਦੇਖਣ ਦਾ ਇਤਿਹਾਸ ਅਯੋਗ ਹੈ • ਸੂਚੀ ਦ੍ਰਿਸ਼ #2517 ਵਿੱਚ ਪਲੇਬੈਕ ਸਥਿਤੀ ਦੇ ਕਾਰਨ ਘਟੇ ਪ੍ਰਦਰਸ਼ਨ ਨੂੰ ਠੀਕ ਕਰੋ • [ਐਕਸਟ੍ਰੈਕਟਰ] ReCaptchaActivity #2527, TeamNewPipe/NewPipeExtractor#186 ਫਿਕਸ • [ਐਕਸਟ੍ਰੈਕਟਰ] [YouTube] ਜਦੋਂ ਪਲੇਲਿਸਟਾਂ ਨਤੀਜੇ ਵਿੱਚ ਹੋਣ ਤਾਂ ਆਮ ਖੋਜ ਗਲਤੀ ਨੂੰ ਠੀਕ ਕਰੋ TeamNewPipe/NewPipeExtractor#185 0.17.0 ਵਿੱਚ ਬਦਲਾਅ ਨਵਾਂ ਪਲੇਬੈਕ ਰੈਜ਼ਿਊਮੇ #2288 • ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਮੁੜ ਸ਼ੁਰੂ ਕਰੋ ਜਿੱਥੇ ਤੁਸੀਂ ਪਿਛਲੀ ਵਾਰ ਰੁਕੇ ਸੀ ਡਾਊਨਲੋਡਰ ਸੁਧਾਰ #2149 • ਬਾਹਰੀ SD-ਕਾਰਡਾਂ 'ਤੇ ਡਾਊਨਲੋਡ ਸਟੋਰ ਕਰਨ ਲਈ ਸਟੋਰੇਜ਼ ਐਕਸੈਸ ਫਰੇਮਵਰਕ ਦੀ ਵਰਤੋਂ ਕਰੋ • ਨਵਾਂ mp4 muxer • ਡਾਊਨਲੋਡ ਸ਼ੁਰੂ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਵਿਕਲਪਿਕ ਤੌਰ 'ਤੇ ਡਾਉਨਲੋਡ ਡਾਇਰੈਕਟਰੀ ਨੂੰ ਬਦਲੋ • ਮੀਟਰਡ ਨੈੱਟਵਰਕਾਂ ਦਾ ਆਦਰ ਕਰੋ ਸੁਧਾਰ • gema ਸਤਰ #2295 ਨੂੰ ਹਟਾਇਆ • ਗਤੀਵਿਧੀ ਜੀਵਨ ਚੱਕਰ #2444 ਦੌਰਾਨ ਹੈਂਡਲ (ਆਟੋ) ਰੋਟੇਸ਼ਨ ਤਬਦੀਲੀਆਂ • ਲੰਬੇ-ਦਬਾਓ ਮੀਨੂ ਨੂੰ ਇਕਸਾਰ #2368 ਬਣਾਓ ਸਥਿਰ • ਫਿਕਸਡ ਚੁਣਿਆ ਹੋਇਆ ਉਪਸਿਰਲੇਖ ਟਰੈਕ ਨਾਮ #2394 ਨਹੀਂ ਦਿਖਾਇਆ ਜਾ ਰਿਹਾ ਹੈ • ਐਪ ਅੱਪਡੇਟ ਦੀ ਜਾਂਚ ਅਸਫਲ ਹੋਣ 'ਤੇ ਕ੍ਰੈਸ਼ ਨਾ ਹੋਵੋ (GitHub ਸੰਸਕਰਣ) #2423 • ਸਥਿਰ ਡਾਊਨਲੋਡ 99.9% #2440 'ਤੇ ਅਟਕ ਗਏ • ਪਲੇ ਕਤਾਰ ਮੈਟਾਡੇਟਾ #2453 ਨੂੰ ਅੱਪਡੇਟ ਕਰੋ • [SoundCloud] ਪਲੇਲਿਸਟਸ ਲੋਡ ਕਰਨ ਵੇਲੇ ਸਥਿਰ ਕਰੈਸ਼ TeamNewPipe/NewPipeExtractor#170 • [YouTube] ਸਥਿਰ ਅਵਧੀ ਨੂੰ ਪਾਰਸਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ TeamNewPipe/NewPipeExtractor#177 diff --git a/fastlane/metadata/android/pa/changelogs/770.txt b/fastlane/metadata/android/pa/changelogs/770.txt new file mode 100644 index 000000000..03903c011 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/770.txt @@ -0,0 +1,4 @@ +0.17.2 ਵਿੱਚ ਬਦਲਾਅ + +ਠੀਕ ਕਰੋ +• ਫਿਕਸ ਕੋਈ ਵੀ ਵੀਡੀਓ ਉਪਲਬਧ ਨਹੀਂ ਸੀ diff --git a/fastlane/metadata/android/pa/changelogs/780.txt b/fastlane/metadata/android/pa/changelogs/780.txt new file mode 100644 index 000000000..999a24468 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/780.txt @@ -0,0 +1 @@ +0.17.3 ਵਿੱਚ ਬਦਲਾਅ ਸੁਧਾਰ • ਪਲੇਬੈਕ ਸਥਿਤੀਆਂ #2550 ਨੂੰ ਸਾਫ਼ ਕਰਨ ਲਈ ਵਿਕਲਪ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ • ਫਾਈਲ ਪਿਕਰ #2591 ਵਿੱਚ ਲੁਕੀਆਂ ਹੋਈਆਂ ਡਾਇਰੈਕਟਰੀਆਂ ਦਿਖਾਓ • NewPipe #2488 ਨਾਲ ਖੋਲ੍ਹੇ ਜਾਣ ਵਾਲੇ `invidio.us` ਉਦਾਹਰਨਾਂ ਤੋਂ ਸਮਰਥਨ URL • `music.youtube.com` URLs TeamNewPipe/NewPipeExtractor#194 ਲਈ ਸਮਰਥਨ ਸ਼ਾਮਲ ਕਰੋ ਸਥਿਰ • [YouTube] ਸਥਿਰ 'java.lang.IllegalArgumentException #192 • [YouTube] ਸਥਿਰ ਲਾਈਵ ਸਟ੍ਰੀਮਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੀਆਂ TeamNewPipe/NewPipeExtractor#195 • ਇੱਕ ਸਟ੍ਰੀਮ #2592 ਨੂੰ ਡਾਊਨਲੋਡ ਕਰਨ ਵੇਲੇ ਐਂਡਰੌਇਡ ਪਾਈ ਵਿੱਚ ਸਥਿਰ ਪ੍ਰਦਰਸ਼ਨ ਸਮੱਸਿਆ diff --git a/fastlane/metadata/android/pa/changelogs/790.txt b/fastlane/metadata/android/pa/changelogs/790.txt new file mode 100644 index 000000000..f841801eb --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/790.txt @@ -0,0 +1 @@ +ਸੁਧਾਰ • ਅੰਨ੍ਹੇ ਲੋਕਾਂ #2655 ਲਈ ਪਹੁੰਚਯੋਗਤਾ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ ਹੋਰ ਸਿਰਲੇਖ ਸ਼ਾਮਲ ਕਰੋ • ਡਾਉਨਲੋਡ ਫੋਲਡਰ ਸੈਟਿੰਗ ਦੀ ਭਾਸ਼ਾ ਨੂੰ ਵਧੇਰੇ ਇਕਸਾਰ ਅਤੇ ਘੱਟ ਅਸਪਸ਼ਟ #2637 ਬਣਾਓ ਸਥਿਰ • ਜਾਂਚ ਕਰੋ ਕਿ ਕੀ ਬਲਾਕ ਵਿੱਚ ਆਖਰੀ ਬਾਈਟ #2646 ਡਾਊਨਲੋਡ ਕੀਤੀ ਗਈ ਹੈ • ਵੀਡੀਓ ਡਿਟੇਲ ਫਰੈਗਮੈਂਟ #2672 ਵਿੱਚ ਸਥਿਰ ਸਕ੍ਰੋਲਿੰਗ • ਡਬਲ ਸਰਚ ਕਲੀਅਰ ਬਾਕਸ ਐਨੀਮੇਸ਼ਨ ਨੂੰ ਇੱਕ #2695 ਵਿੱਚ ਹਟਾਓ • [SoundCloud] ਕਲਾਇਟ_ਆਈਡੀ ਐਕਸਟਰੈਕਸ਼ਨ #2745 ਨੂੰ ਠੀਕ ਕਰੋ ਵਿਕਾਸ • NewPipeExtractor ਤੋਂ ਵਿਰਾਸਤ ਵਿੱਚ ਮਿਲੀ ਗੁੰਮ ਨਿਰਭਰਤਾ ਨੂੰ NewPipe #2535 ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ • AndroidX #2685 'ਤੇ ਮਾਈਗ੍ਰੇਟ ਕਰੋ • ExoPlayer 2.10.6 #2697, #2736 ਨੂੰ ਅੱਪਡੇਟ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/800.txt b/fastlane/metadata/android/pa/changelogs/800.txt new file mode 100644 index 000000000..53868c894 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/800.txt @@ -0,0 +1 @@ +ਨਵਾਂ • P2P (#2201) [ਬੀਟਾ] ਤੋਂ ਬਿਨਾਂ PeerTube ਸਮਰਥਨ: ◦ PeerTube ਉਦਾਹਰਨਾਂ ਤੋਂ ਵੀਡੀਓ ਦੇਖੋ ਅਤੇ ਡਾਊਨਲੋਡ ਕਰੋ ◦ ਪੂਰੀ PeerTube ਸੰਸਾਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਉਦਾਹਰਨਾਂ ਸ਼ਾਮਲ ਕਰੋ ◦ Android 4.4 ਅਤੇ 7.1 'ਤੇ SSL ਹੈਂਡਸ਼ੇਕ ਨਾਲ ਸਮੱਸਿਆਵਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ ਜਦੋਂ ਕੁਝ ਖਾਸ ਮੌਕਿਆਂ 'ਤੇ ਪਹੁੰਚ ਕਰਦੇ ਸਮੇਂ ਨੈੱਟਵਰਕ ਗੜਬੜ ਹੋ ਜਾਂਦੀ ਹੈ। • ਡਾਊਨਲੋਡਰ (#2679): ◦ ਡਾਊਨਲੋਡ ETA ਦੀ ਗਣਨਾ ਕਰੋ ◦ ਓਪਸ (ਵੈਬ ਫਾਈਲਾਂ) ਨੂੰ ogg ਵਜੋਂ ਡਾਊਨਲੋਡ ਕਰੋ ◦ ਲੰਬੇ ਵਿਰਾਮ ਤੋਂ ਬਾਅਦ ਡਾਊਨਲੋਡ ਮੁੜ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਮਿਆਦ ਪੁੱਗ ਚੁੱਕੇ ਡਾਊਨਲੋਡ ਲਿੰਕਾਂ ਨੂੰ ਮੁੜ-ਹਾਸਲ ਕਰੋ ਸੁਧਾਰ • ਕਿਓਸਕਫ੍ਰੈਗਮੈਂਟ ਨੂੰ ਤਰਜੀਹੀ ਸਮਗਰੀ ਵਾਲੇ ਦੇਸ਼ ਵਿੱਚ ਤਬਦੀਲੀਆਂ ਤੋਂ ਜਾਣੂ ਕਰਵਾਓ ਅਤੇ ਸਾਰੀਆਂ ਮੁੱਖ ਟੈਬਾਂ #2742 ਦੀ ਕਾਰਗੁਜ਼ਾਰੀ ਵਿੱਚ ਸੁਧਾਰ ਕਰੋ। • ਐਕਸਟਰੈਕਟਰ #2713 ਤੋਂ ਨਵੇਂ ਸਥਾਨਕਕਰਨ ਅਤੇ ਡਾਉਨਲੋਡਰ ਲਾਗੂਕਰਨ ਦੀ ਵਰਤੋਂ ਕਰੋ • "ਡਿਫੌਲਟ ਕਿਓਸਕ" ਸਤਰ ਨੂੰ ਅਨੁਵਾਦਯੋਗ ਬਣਾਓ • ਬਲੈਕ ਥੀਮ #2569 ਲਈ ਬਲੈਕ ਨੈਵੀਗੇਸ਼ਨ ਪੱਟੀ ਸਥਿਰ • ਇੱਕ ਬੱਗ ਫਿਕਸ ਕੀਤਾ ਗਿਆ ਹੈ ਜੋ ਪੌਪਅੱਪ ਪਲੇਅਰ ਨੂੰ ਹਿਲਾ ਨਹੀਂ ਸਕਦਾ ਸੀ ਜੇਕਰ ਪੌਪਅੱਪ ਪਲੇਅਰ #2772 ਨੂੰ ਹਿਲਾਉਂਦੇ ਸਮੇਂ ਕੋਈ ਹੋਰ ਉਂਗਲ ਰੱਖੀ ਜਾਂਦੀ ਹੈ • ਪਲੇਲਿਸਟਾਂ ਨੂੰ ਅਪਲੋਡਰ ਦੀ ਗੁੰਮਸ਼ੁਦਗੀ ਦੀ ਆਗਿਆ ਦਿਓ ਅਤੇ ਇਸ ਸਮੱਸਿਆ ਨਾਲ ਸਬੰਧਤ ਕ੍ਰੈਸ਼ਾਂ ਨੂੰ ਠੀਕ ਕਰੋ #2724, TeamNewPipe/NewPipeExtractor#219 • MediaCCC ਅਤੇ ਕੁਝ PeerTube ਉਦਾਹਰਨਾਂ #2792 ਨਾਲ TLS ਹੈਂਡਸ਼ੇਕ ਨੂੰ ਠੀਕ ਕਰਨ ਲਈ Android 4.4 ਡਿਵਾਈਸਾਂ (API 19/KitKat) 'ਤੇ TLS1.1/1.2 ਨੂੰ ਸਮਰੱਥ ਕਰਨਾ • [SoundCloud] ਫਿਕਸਡ ਕਲਾਈਂਟ_ਆਈਡੀ ਐਕਸਟ੍ਰੈਕਸ਼ਨ TeamNewPipe/NewPipeExtractor#217 • [SoundCloud] ਆਡੀਓ ਸਟ੍ਰੀਮ ਕੱਢਣ ਨੂੰ ਠੀਕ ਕਰੋ ਵਿਕਾਸ • ExoPlayer ਨੂੰ 2.10.8 #2791, #2816 'ਤੇ ਅੱਪਡੇਟ ਕਰੋ • Gradle ਨੂੰ 3.5.1 ਵਿੱਚ ਅੱਪਡੇਟ ਕਰੋ ਅਤੇ Kotlin ਸਹਿਯੋਗ #2714 ਸ਼ਾਮਲ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/810.txt b/fastlane/metadata/android/pa/changelogs/810.txt new file mode 100644 index 000000000..96a2b9da5 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/810.txt @@ -0,0 +1 @@ +ਨਵਾਂ • ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਦੇ ਸਮੇਂ ਲੌਕ ਸਕ੍ਰੀਨ 'ਤੇ ਵੀਡੀਓ ਥੰਬਨੇਲ ਦਿਖਾਓ ਸੁਧਾਰ • ਬੈਕਗ੍ਰਾਉਂਡ / ਪੌਪਅੱਪ ਬਟਨ 'ਤੇ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਦਬਾਉਣ 'ਤੇ ਕਤਾਰ ਵਿੱਚ ਸਥਾਨਕ ਪਲੇਲਿਸਟ ਸ਼ਾਮਲ ਕਰੋ • ਮੁੱਖ ਪੰਨਾ ਟੈਬਾਂ ਨੂੰ ਸਕ੍ਰੋਲ ਕਰਨ ਯੋਗ ਬਣਾਓ ਅਤੇ ਸਿਰਫ਼ ਇੱਕ ਟੈਬ ਹੋਣ 'ਤੇ ਲੁਕਾਓ • ਬੈਕਗ੍ਰਾਉਂਡ ਪਲੇਅਰ ਵਿੱਚ ਸੂਚਨਾ ਥੰਬਨੇਲ ਅੱਪਡੇਟ ਦੀ ਸੀਮਾ ਮਾਤਰਾ • ਖਾਲੀ ਸਥਾਨਕ ਪਲੇਲਿਸਟਾਂ ਲਈ ਡਮੀ ਥੰਬਨੇਲ ਸ਼ਾਮਲ ਕਰੋ • *.webm ਦੀ ਬਜਾਏ *.opus ਫਾਈਲ ਐਕਸਟੈਂਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰੋ ਅਤੇ ਡਾਊਨਲੋਡ ਡ੍ਰੌਪਡਾਉਨ ਵਿੱਚ "WebM Opus" ਦੀ ਬਜਾਏ ਫਾਰਮੈਟ ਲੇਬਲ ਵਿੱਚ "opus" ਦਿਖਾਓ • "ਡਾਊਨਲੋਡ" ਵਿੱਚ ਡਾਊਨਲੋਡ ਕੀਤੀਆਂ ਫ਼ਾਈਲਾਂ ਜਾਂ ਡਾਊਨਲੋਡ ਇਤਿਹਾਸ ਨੂੰ ਮਿਟਾਉਣ ਲਈ ਬਟਨ ਸ਼ਾਮਲ ਕਰੋ • [YouTube] /c/shortened_url ਚੈਨਲ ਲਿੰਕਾਂ ਲਈ ਸਮਰਥਨ ਸ਼ਾਮਲ ਕਰੋ ਸਥਿਰ • NewPipe ਨਾਲ ਵੀਡੀਓ ਸਾਂਝਾ ਕਰਨ ਅਤੇ ਇਸ ਦੀਆਂ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਸਿੱਧੇ ਡਾਊਨਲੋਡ ਕਰਨ ਵੇਲੇ ਕਈ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਹੱਲ ਕੀਤਾ ਗਿਆ • ਇਸ ਦੇ ਸਿਰਜਣ ਥ੍ਰੈਡ ਤੋਂ ਬਾਹਰ ਸਥਿਰ ਪਲੇਅਰ ਪਹੁੰਚ • ਸਥਿਰ ਖੋਜ ਨਤੀਜੇ ਪੇਜਿੰਗ • [YouTube] ਨਿਸ਼ਚਤ ਸਵਿਚਿੰਗ ਚਾਲੂ ਕਰਨ ਨਾਲ NPE ਹੁੰਦਾ ਹੈ • [YouTube] ਇੱਕ invidio.us url ਖੋਲ੍ਹਣ ਵੇਲੇ ਟਿੱਪਣੀਆਂ ਦੇਖਣ ਲਈ ਸਥਿਰ • [SoundCloud] ਅੱਪਡੇਟ ਕੀਤਾ client_id diff --git a/fastlane/metadata/android/pa/changelogs/820.txt b/fastlane/metadata/android/pa/changelogs/820.txt new file mode 100644 index 000000000..aa3554698 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/820.txt @@ -0,0 +1 @@ +ਸਥਿਰ ਡੀਕ੍ਰਿਪਟ ਫੰਕਸ਼ਨ ਨਾਮ regex YouTube ਨੂੰ ਵਰਤੋਂਯੋਗ ਨਹੀਂ ਬਣਾਉਂਦਾ। diff --git a/fastlane/metadata/android/pa/changelogs/830.txt b/fastlane/metadata/android/pa/changelogs/830.txt new file mode 100644 index 000000000..6bd990808 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/830.txt @@ -0,0 +1 @@ +SoundCloud ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਠੀਕ ਕਰਨ ਲਈ SoundCloud client_id ਨੂੰ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ। diff --git a/fastlane/metadata/android/pa/changelogs/840.txt b/fastlane/metadata/android/pa/changelogs/840.txt new file mode 100644 index 000000000..745098496 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/840.txt @@ -0,0 +1 @@ +ਨਵਾਂ • ਐਪ ਦੀ ਭਾਸ਼ਾ ਬਦਲਣ ਲਈ ਭਾਸ਼ਾ ਚੋਣਕਾਰ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ • ਪਲੇਅਰ ਸਮੇਟਣਯੋਗ ਮੀਨੂ ਵਿੱਚ ਕੋਡੀ ਬਟਨ 'ਤੇ ਭੇਜੋ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ • ਲੰਬੀ ਪ੍ਰੈਸ 'ਤੇ ਟਿੱਪਣੀਆਂ ਨੂੰ ਕਾਪੀ ਕਰਨ ਦੀ ਸਮਰੱਥਾ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ ਹੈ ਸੁਧਾਰ • ਰੀਕੈਪਚਾ ਗਤੀਵਿਧੀ ਨੂੰ ਠੀਕ ਕਰੋ ਅਤੇ ਪ੍ਰਾਪਤ ਕੀਤੀਆਂ ਕੂਕੀਜ਼ ਨੂੰ ਸਹੀ ਢੰਗ ਨਾਲ ਸੁਰੱਖਿਅਤ ਕਰੋ • ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਦੇਖਣ ਦਾ ਇਤਿਹਾਸ ਚਾਲੂ ਨਾ ਹੋਣ 'ਤੇ ਦਰਾਜ਼ ਦੇ ਹੱਕ ਵਿੱਚ ਡਾਟ-ਮੀਨੂ ਨੂੰ ਹਟਾਇਆ ਗਿਆ ਅਤੇ ਇਤਿਹਾਸ ਨੂੰ ਲੁਕਾਓ ਬਟਨ • Android 6 ਅਤੇ ਬਾਅਦ ਵਾਲੇ 'ਤੇ ਸਹੀ ਢੰਗ ਨਾਲ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਹੋਰ ਐਪਾਂ ਦੀ ਇਜਾਜ਼ਤ ਦੇ ਉੱਪਰ ਡਿਸਪਲੇ ਲਈ ਪੁੱਛੋ • BookmarkFragment ਵਿੱਚ ਲੰਮਾ-ਕਲਿੱਕ ਕਰਕੇ ਸਥਾਨਕ ਪਲੇਲਿਸਟ ਦਾ ਨਾਮ ਬਦਲੋ • ਕਈ PeerTube ਸੁਧਾਰ • ਕਈ ਅੰਗਰੇਜ਼ੀ ਸਰੋਤ ਸਤਰਾਂ ਨੂੰ ਸੁਧਾਰਿਆ ਗਿਆ ਹੈ ਸਥਿਰ • ਫਿਕਸਡ ਪਲੇਅਰ ਦੁਬਾਰਾ ਸ਼ੁਰੂ ਹੋ ਰਿਹਾ ਹੈ ਹਾਲਾਂਕਿ ਇਹ ਉਦੋਂ ਰੋਕਿਆ ਜਾਂਦਾ ਹੈ ਜਦੋਂ ਵਿਕਲਪ "ਐਪ ਸਵਿੱਚ 'ਤੇ ਛੋਟਾ ਕਰੋ" ਯੋਗ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ ਨਿਊ ਪਾਈਪ ਨੂੰ ਛੋਟਾ ਕੀਤਾ ਜਾਂਦਾ ਹੈ • ਸੰਕੇਤ ਲਈ ਸ਼ੁਰੂਆਤੀ ਚਮਕ ਮੁੱਲ ਨੂੰ ਠੀਕ ਕਰੋ • ਸਥਿਰ .srt ਉਪਸਿਰਲੇਖ ਡਾਉਨਲੋਡ ਜਿਸ ਵਿੱਚ ਸਾਰੇ ਲਾਈਨ ਬ੍ਰੇਕ ਨਹੀਂ ਹਨ • SD ਕਾਰਡ 'ਤੇ ਸਥਿਰ ਡਾਊਨਲੋਡ ਅਸਫਲ ਹੋ ਰਿਹਾ ਹੈ ਕਿਉਂਕਿ ਕੁਝ Android 5 ਡਿਵਾਈਸਾਂ CTF ਅਨੁਕੂਲ ਨਹੀਂ ਹਨ • Android KitKat 'ਤੇ ਸਥਿਰ ਡਾਊਨਲੋਡਿੰਗ • ਸਥਿਰ ਭ੍ਰਿਸ਼ਟ ਵੀਡੀਓ .mp4 ਫਾਈਲ ਨੂੰ ਆਡੀਓ ਫਾਈਲ ਵਜੋਂ ਮਾਨਤਾ ਦਿੱਤੀ ਜਾ ਰਹੀ ਹੈ • ਗਲਤ ਚੀਨੀ ਭਾਸ਼ਾ ਕੋਡ ਸਮੇਤ, ਮਲਟੀਪਲ ਸਥਾਨੀਕਰਨ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਹੱਲ ਕੀਤਾ ਗਿਆ ਹੈ • [YouTube] ਵਰਣਨ ਵਿੱਚ ਟਾਈਮਸਟੈਂਪ ਦੁਬਾਰਾ ਕਲਿੱਕ ਕਰਨ ਯੋਗ ਹਨ diff --git a/fastlane/metadata/android/pa/changelogs/850.txt b/fastlane/metadata/android/pa/changelogs/850.txt new file mode 100644 index 000000000..561cdec62 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/850.txt @@ -0,0 +1 @@ +ਇਸ ਰੀਲੀਜ਼ ਵਿੱਚ YouTube ਵੈੱਬਸਾਈਟ ਸੰਸਕਰਣ ਨੂੰ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ ਸੀ। ਪੁਰਾਣਾ ਵੈੱਬਸਾਈਟ ਸੰਸਕਰਣ ਮਾਰਚ ਵਿੱਚ ਬੰਦ ਹੋਣ ਜਾ ਰਿਹਾ ਹੈ ਅਤੇ ਇਸ ਲਈ ਤੁਹਾਨੂੰ ਨਿਊ ਪਾਈਪ ਨੂੰ ਅਪਗ੍ਰੇਡ ਕਰਨ ਦੀ ਲੋੜ ਹੈ। diff --git a/fastlane/metadata/android/pa/changelogs/860.txt b/fastlane/metadata/android/pa/changelogs/860.txt new file mode 100644 index 000000000..900671ab8 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/860.txt @@ -0,0 +1 @@ +ਸੁਧਾਰ • ਸੇਵ ਕਰੋ ਅਤੇ ਰੀਸਟੋਰ ਕਰੋ ਕਿ ਕੀ ਪਿੱਚ ਅਤੇ ਟੈਂਪੋ ਅਣਹੁੱਕ ਹਨ ਜਾਂ ਨਹੀਂ • ਪਲੇਅਰ ਵਿੱਚ ਡਿਸਪਲੇ ਕੱਟਆਊਟ ਦਾ ਸਮਰਥਨ ਕਰੋ • ਗੋਲ ਦ੍ਰਿਸ਼ ਅਤੇ ਗਾਹਕਾਂ ਦੀ ਗਿਣਤੀ • ਘੱਟ ਡਾਟਾ ਵਰਤਣ ਲਈ YouTube ਨੂੰ ਅਨੁਕੂਲ ਬਣਾਇਆ ਗਿਆ ਇਸ ਰੀਲੀਜ਼ ਵਿੱਚ 15 ਤੋਂ ਵੱਧ YouTube-ਸਬੰਧਤ ਬੱਗ ਫਿਕਸ ਕੀਤੇ ਗਏ ਸਨ। diff --git a/fastlane/metadata/android/pa/changelogs/870.txt b/fastlane/metadata/android/pa/changelogs/870.txt new file mode 100644 index 000000000..3656c86fc --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/870.txt @@ -0,0 +1,2 @@ +ਇਹ ਇੱਕ ਹੌਟਫਿਕਸ ਰੀਲੀਜ਼ ਹੈ ਜੋ ਨਿਊਪਾਈਪ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਰਿਹਾ ਹੈ ਤਾਂ ਜੋ ਦੁਬਾਰਾ ਵੱਡੀਆਂ ਮੁਸ਼ਕਲਾਂ ਤੋਂ ਬਿਨਾਂ ਸਾਉਂਡ ਕਲਾਉਡ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੱਤੀ ਜਾ ਸਕੇ। +SoundCloud ਦਾ v2 API ਹੁਣ ਐਕਸਟਰੈਕਟਰ ਵਿੱਚ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ ਅਤੇ ਅਵੈਧ ਕਲਾਇੰਟ ਆਈਡੀ ਦੀ ਖੋਜ ਵਿੱਚ ਸੁਧਾਰ ਕੀਤਾ ਗਿਆ ਹੈ। diff --git a/fastlane/metadata/android/pa/changelogs/900.txt b/fastlane/metadata/android/pa/changelogs/900.txt new file mode 100644 index 000000000..f9a004a0d --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/900.txt @@ -0,0 +1 @@ +ਨਵਾਂ • ਗਾਹਕੀ ਸਮੂਹ ਅਤੇ ਕ੍ਰਮਬੱਧ ਫੀਡ • ਖਿਡਾਰੀਆਂ ਵਿੱਚ ਮਿਊਟ ਬਟਨ ਸੁਧਾਰ • NewPipe ਵਿੱਚ music.youtube.com ਅਤੇ media.ccc.de ਲਿੰਕ ਖੋਲ੍ਹਣ ਦਿਓ • ਦਿੱਖ ਤੋਂ ਸਮੱਗਰੀ ਤੱਕ ਦੋ ਸੈਟਿੰਗਾਂ ਨੂੰ ਮੁੜ-ਸਥਾਪਿਤ ਕਰੋ • 5, 15, 25 ਸਕਿੰਟ ਦੇ ਸੀਕ ਵਿਕਲਪਾਂ ਨੂੰ ਲੁਕਾਓ ਜੇਕਰ ਅਢੁੱਕਵੀਂ ਖੋਜ ਸਮਰਥਿਤ ਹੈ ਸਥਿਰ • ਕੁਝ WebM ਵੀਡੀਓ ਖੋਜਣ ਯੋਗ ਨਹੀਂ ਹਨ • Android P 'ਤੇ ਡਾਟਾਬੇਸ ਬੈਕਅੱਪ • ਡਾਉਨਲੋਡ ਕੀਤੀ ਫਾਈਲ ਨੂੰ ਸਾਂਝਾ ਕਰਦੇ ਸਮੇਂ ਕਰੈਸ਼ • ਬਹੁਤ ਸਾਰੇ YouTube ਐਕਸਟਰੈਕਸ਼ਨ ਮੁੱਦੇ ਅਤੇ ਹੋਰ... diff --git a/fastlane/metadata/android/pa/changelogs/910.txt b/fastlane/metadata/android/pa/changelogs/910.txt new file mode 100644 index 000000000..1cc2a1432 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/910.txt @@ -0,0 +1 @@ +ਸਥਿਰ ਡੇਟਾਬੇਸ ਮਾਈਗ੍ਰੇਸ਼ਨ ਜਿਸ ਨੇ ਕੁਝ ਦੁਰਲੱਭ ਮਾਮਲਿਆਂ ਵਿੱਚ ਨਿਊਪਾਈਪ ਨੂੰ ਸ਼ੁਰੂ ਹੋਣ ਤੋਂ ਰੋਕਿਆ। diff --git a/fastlane/metadata/android/pa/changelogs/920.txt b/fastlane/metadata/android/pa/changelogs/920.txt new file mode 100644 index 000000000..04fc07937 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/920.txt @@ -0,0 +1 @@ +ਸੁਧਾਰ • ਸਟ੍ਰੀਮ ਗਰਿੱਡ ਆਈਟਮਾਂ 'ਤੇ ਅੱਪਲੋਡ ਦੀ ਮਿਤੀ ਅਤੇ ਦੇਖਣ ਦੀ ਗਿਣਤੀ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ • ਦਰਾਜ਼ ਹੈਡਰ ਲੇਆਉਟ ਲਈ ਸੁਧਾਰ ਸਥਿਰ • ਏਪੀਆਈ 19 'ਤੇ ਕ੍ਰੈਸ਼ ਹੋਣ ਕਾਰਨ ਫਿਕਸਡ ਮਿਊਟ ਬਟਨ • ਲੰਬੇ 1080p 60fps ਵੀਡੀਓ ਦੀ ਸਥਿਰ ਡਾਊਨਲੋਡਿੰਗ diff --git a/fastlane/metadata/android/pa/changelogs/930.txt b/fastlane/metadata/android/pa/changelogs/930.txt new file mode 100644 index 000000000..a067bfb58 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/930.txt @@ -0,0 +1 @@ +ਨਵਾਂ • YouTube ਸੰਗੀਤ 'ਤੇ ਖੋਜੋ • ਬੁਨਿਆਦੀ Android TV ਸਮਰਥਨ ਸੁਧਾਰ • ਇੱਕ ਸਥਾਨਕ ਪਲੇਲਿਸਟ ਤੋਂ ਸਾਰੇ ਦੇਖੇ ਗਏ ਵੀਡੀਓ ਨੂੰ ਹਟਾਉਣ ਦੀ ਯੋਗਤਾ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ ਹੈ • ਕ੍ਰੈਸ਼ ਹੋਣ ਦੀ ਬਜਾਏ ਜਦੋਂ ਸਮੱਗਰੀ ਅਜੇ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ ਤਾਂ ਸੁਨੇਹਾ ਦਿਖਾਓ • ਚੁਟਕੀ ਇਸ਼ਾਰਿਆਂ ਨਾਲ ਪੌਪਅੱਪ ਪਲੇਅਰ ਦਾ ਆਕਾਰ ਬਦਲਿਆ ਗਿਆ ਹੈ • ਬੈਕਗ੍ਰਾਊਂਡ 'ਤੇ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਦਬਾਉਣ ਅਤੇ ਚੈਨਲ ਵਿੱਚ ਪੌਪਅੱਪ ਬਟਨਾਂ 'ਤੇ ਸਟ੍ਰੀਮ ਨੂੰ ਐਨਕਿਊ ਕਰੋ • ਦਰਾਜ਼ ਸਿਰਲੇਖ ਦੇ ਸਿਰਲੇਖ ਦੇ ਆਕਾਰ ਨੂੰ ਸੰਭਾਲਣ ਵਿੱਚ ਸੁਧਾਰ ਕੀਤਾ ਗਿਆ ਹੈ ਸਥਿਰ • ਨਿਸ਼ਚਿਤ ਉਮਰ ਪ੍ਰਤਿਬੰਧਿਤ ਸਮੱਗਰੀ ਸੈਟਿੰਗ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੀ • ਕੁਝ ਖਾਸ ਕਿਸਮ ਦੇ reCAPTCHA ਫਿਕਸ ਕੀਤੇ ਗਏ ਹਨ • ਪਲੇਲਿਸਟ `ਨੱਲ` ਹੋਣ 'ਤੇ ਬੁੱਕਮਾਰਕ ਖੋਲ੍ਹਣ ਵੇਲੇ ਸਥਿਰ ਕਰੈਸ਼ • ਨੈੱਟਵਰਕ ਸੰਬੰਧੀ ਅਪਵਾਦਾਂ ਦੀ ਸਥਿਰ ਖੋਜ • ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਫਰੈਗਮੈਂਟ ਵਿੱਚ ਗਰੁੱਪ ਸੌਰਟ ਬਟਨ ਦੀ ਸਥਿਰ ਦਿੱਖ ਅਤੇ ਹੋਰ diff --git a/fastlane/metadata/android/pa/changelogs/940.txt b/fastlane/metadata/android/pa/changelogs/940.txt new file mode 100644 index 000000000..b9d9b3fdf --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/940.txt @@ -0,0 +1 @@ +ਨਵਾਂ • SoundCloud ਟਿੱਪਣੀਆਂ ਲਈ ਸਮਰਥਨ ਸ਼ਾਮਲ ਕਰੋ • YouTube ਪ੍ਰਤਿਬੰਧਿਤ ਮੋਡ ਸੈਟਿੰਗ ਸ਼ਾਮਲ ਕਰੋ • PeerTube ਮੂਲ ਚੈਨਲ ਦੇ ਵੇਰਵੇ ਦਿਖਾਓ ਸੁਧਾਰ • ਸਿਰਫ਼ ਸਮਰਥਿਤ ਸੇਵਾਵਾਂ ਲਈ ਕੋਰ ਬਟਨ ਦਿਖਾਓ • ਨੈਵੀਗੇਸ਼ਨਬਾਰ ਜਾਂ ਸਟੇਟਸਬਾਰ ਤੋਂ ਸ਼ੁਰੂ ਹੋਣ ਵਾਲੇ ਪਲੇਅਰ ਸੰਕੇਤਾਂ ਨੂੰ ਬਲਾਕ ਕਰੋ • ਸੇਵਾ ਦੇ ਰੰਗ ਦੇ ਆਧਾਰ 'ਤੇ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਅਤੇ ਗਾਹਕ ਬਣੋ ਬਟਨਾਂ ਦਾ ਪਿਛੋਕੜ ਰੰਗ ਬਦਲੋ ਸਥਿਰ • ਡਾਉਨਲੋਡ ਡਾਇਲਾਗ ਫ੍ਰੀਜ਼ ਨੂੰ ਠੀਕ ਕਰੋ • ਬ੍ਰਾਊਜ਼ਰ ਵਿੱਚ ਖੋਲ੍ਹੋ ਬਟਨ ਹੁਣ ਅਸਲ ਵਿੱਚ ਬ੍ਰਾਊਜ਼ਰ ਵਿੱਚ ਖੁੱਲ੍ਹਦਾ ਹੈ • ਵੀਡੀਓ ਖੋਲ੍ਹਣ 'ਤੇ ਕ੍ਰੈਸ਼ ਨੂੰ ਠੀਕ ਕਰੋ ਅਤੇ "ਇਸ ਸਟ੍ਰੀਮ ਨੂੰ ਚਲਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ" ਅਤੇ ਹੋਰ diff --git a/fastlane/metadata/android/pa/changelogs/950.txt b/fastlane/metadata/android/pa/changelogs/950.txt new file mode 100644 index 000000000..454a34bd4 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/950.txt @@ -0,0 +1,4 @@ +ਇਹ ਰੀਲੀਜ਼ ਤਿੰਨ ਛੋਟੇ ਫਿਕਸ ਲਿਆਉਂਦਾ ਹੈ: +• Adroid 10+ 'ਤੇ ਸਥਿਰ ਸਟੋਰੇਜ ਪਹੁੰਚ +• ਫਿਕਸਡ ਓਪਨਿੰਗ ਕਿਓਸਕ +• ਲੰਬੇ ਵੀਡੀਓਜ਼ ਦੀ ਸਥਿਰ ਮਿਆਦ ਪਾਰਸਿੰਗ diff --git a/fastlane/metadata/android/pa/changelogs/951.txt b/fastlane/metadata/android/pa/changelogs/951.txt new file mode 100644 index 000000000..2b1cd7933 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/951.txt @@ -0,0 +1,13 @@ +ਨਵਾਂ +• ਫੀਡ ਗਰੁੱਪ ਡਾਇਲਾਗ ਵਿੱਚ ਗਾਹਕੀ ਚੋਣਕਾਰ ਲਈ ਖੋਜ ਸ਼ਾਮਲ ਕਰੋ +• ਸਿਰਫ਼ ਗੈਰ-ਗਰੁੱਪ ਕੀਤੀਆਂ ਗਾਹਕੀਆਂ ਨੂੰ ਦਿਖਾਉਣ ਲਈ ਫੀਡ ਗਰੁੱਪ ਡਾਇਲਾਗ ਵਿੱਚ ਫਿਲਟਰ ਸ਼ਾਮਲ ਕਰੋ +• ਪਲੇਲਿਸਟ ਟੈਬ ਨੂੰ ਮੁੱਖ ਪੰਨੇ 'ਤੇ ਸ਼ਾਮਲ ਕਰੋ +• ਬੈਕਗ੍ਰਾਊਂਡ/ਪੌਪ-ਅੱਪ ਪਲੇਅਰ ਕਤਾਰ ਵਿੱਚ ਤੇਜ਼ੀ ਨਾਲ ਅੱਗੇ/ਰਿਵਾਈਂਡ ਕਰੋ +• ਖੋਜ ਸੁਝਾਅ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ: ਕੀ ਤੁਹਾਡਾ ਮਤਲਬ ਹੈ ਅਤੇ ਇਸ ਲਈ ਨਤੀਜਾ ਦਿਖਾ ਰਿਹਾ ਹੈ +ਸੁਧਾਰ +• ਮਿਕਸਡ ਫਾਈਲਾਂ ਵਿੱਚ ਐਪਲੀਕੇਸ਼ਨ ਮੈਟਾਡੇਟਾ ਲਿਖਣਾ ਛੱਡੋ • ਕਤਾਰ ਤੋਂ ਅਸਫਲ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਨਾ ਹਟਾਓ +• ਟੂਲਬਾਰ ਦੇ ਰੰਗ ਨਾਲ ਮੇਲ ਕਰਨ ਲਈ ਸਥਿਤੀ ਪੱਟੀ ਦਾ ਰੰਗ ਅੱਪਡੇਟ ਕਰੋ + +ਠੀਕ ਕੀਤਾ +• ਫਲੋਟਿੰਗ ਪੁਆਇੰਟ ਸੰਚਤ ਤਰੁੱਟੀਆਂ ਦੇ ਕਾਰਨ ਫਿਕਸਡ ਆਡੀਓ/ਵੀਡੀਓ ਡੀਸਿੰਕ +• [PeerTube] ਮਿਟਾਈਆਂ ਗਈਆਂ ਟਿੱਪਣੀਆਂ ਨੂੰ ਸੰਭਾਲੋ ਅਤੇ ਹੋਰ diff --git a/fastlane/metadata/android/pa/changelogs/952.txt b/fastlane/metadata/android/pa/changelogs/952.txt new file mode 100644 index 000000000..dda91ee55 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/952.txt @@ -0,0 +1,7 @@ +ਸੁਧਾਰ +• ਆਟੋ-ਪਲੇ ਸਾਰੀਆਂ ਸੇਵਾਵਾਂ ਲਈ ਉਪਲਬਧ ਹੈ (ਸਿਰਫ਼ YouTube ਦੀ ਬਜਾਏ) + +ਠੀਕ ਕੀਤਾ +• YouTube ਦੀਆਂ ਨਵੀਆਂ ਨਿਰੰਤਰਤਾਵਾਂ ਦਾ ਸਮਰਥਨ ਕਰਕੇ ਸੰਬੰਧਿਤ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਸਥਿਰ ਕੀਤਾ ਗਿਆ +• ਨਿਸ਼ਚਿਤ ਉਮਰ ਪ੍ਰਤਿਬੰਧਿਤ YouTube ਵੀਡੀਓ +• [Android TV] ਸਥਿਰ ਲੰਮੀ ਫੋਕਸ ਹਾਈਲਾਈਟ ਓਵਰਲੇ diff --git a/fastlane/metadata/android/pa/changelogs/953.txt b/fastlane/metadata/android/pa/changelogs/953.txt new file mode 100644 index 000000000..5d5672ad2 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/953.txt @@ -0,0 +1 @@ +YouTube ਦੇ ਡੀਕ੍ਰਿਪਸ਼ਨ ਫੰਕਸ਼ਨ ਦੇ ਐਕਸਟਰੈਕਸ਼ਨ ਨੂੰ ਠੀਕ ਕਰੋ। diff --git a/fastlane/metadata/android/pa/changelogs/954.txt b/fastlane/metadata/android/pa/changelogs/954.txt new file mode 100644 index 000000000..3eb8dd68b --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/954.txt @@ -0,0 +1,8 @@ +• ਨਵਾਂ ਐਪਲੀਕੇਸ਼ਨ ਵਰਕਫਲੋ: ਵੇਰਵੇ ਵਾਲੇ ਪੰਨੇ 'ਤੇ ਵੀਡੀਓ ਚਲਾਓ, ਪਲੇਅਰ ਨੂੰ ਛੋਟਾ ਕਰਨ ਲਈ ਹੇਠਾਂ ਵੱਲ ਸਵਾਈਪ ਕਰੋ +• ਮੀਡੀਆ ਸਟਾਈਲ ਸੂਚਨਾਵਾਂ: ਸੂਚਨਾਵਾਂ ਵਿੱਚ ਅਨੁਕੂਲਿਤ ਕਾਰਵਾਈਆਂ, ਪ੍ਰਦਰਸ਼ਨ ਸੁਧਾਰ +• ਡੈਸਕਟੌਪ ਐਪ ਦੇ ਤੌਰ 'ਤੇ NewPipe ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਮੂਲ ਰੀਸਾਈਜ਼ ਕਰਨਾ + +• ਇੱਕ ਅਸਮਰਥਿਤ URL ਟੋਸਟ ਦੇ ਮਾਮਲੇ ਵਿੱਚ ਖੁੱਲੇ ਵਿਕਲਪਾਂ ਨਾਲ ਡਾਇਲਾਗ ਦਿਖਾਓ +• ਜਦੋਂ ਰਿਮੋਟ ਨੂੰ ਪ੍ਰਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ ਤਾਂ ਖੋਜ ਸੁਝਾਅ ਅਨੁਭਵ ਨੂੰ ਬਿਹਤਰ ਬਣਾਓ +• ਡਿਫ਼ਾਲਟ ਵੀਡੀਓ ਗੁਣਵੱਤਾ ਨੂੰ 720p60 (ਇਨ-ਐਪ ਪਲੇਅਰ) ਅਤੇ 480p (ਪੌਪ-ਅੱਪ ਪਲੇਅਰ) ਤੱਕ ਵਧਾ ਦਿੱਤਾ ਗਿਆ ਹੈ +• ਬਹੁਤ ਸਾਰੇ ਬੱਗ ਫਿਕਸ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ diff --git a/fastlane/metadata/android/pa/changelogs/955.txt b/fastlane/metadata/android/pa/changelogs/955.txt new file mode 100644 index 000000000..ea480cb5a --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/955.txt @@ -0,0 +1,3 @@ +[YouTube] ਕੁਝ ਉਪਭੋਗਤਾਵਾਂ ਲਈ ਖੋਜ ਨੂੰ ਠੀਕ ਕਰੋ +[YouTube] ਬੇਤਰਤੀਬੇ ਡੀਕ੍ਰਿਪਸ਼ਨ ਅਪਵਾਦਾਂ ਨੂੰ ਠੀਕ ਕਰੋ +[SoundCloud] ਸਲੈਸ਼ ਨਾਲ ਖਤਮ ਹੋਣ ਵਾਲੇ URL ਹੁਣ ਸਹੀ ਤਰ੍ਹਾਂ ਪਾਰਸ ਕੀਤੇ ਗਏ ਹਨ diff --git a/fastlane/metadata/android/pa/changelogs/956.txt b/fastlane/metadata/android/pa/changelogs/956.txt new file mode 100644 index 000000000..897a5bf2a --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/956.txt @@ -0,0 +1 @@ +[YouTube] ਕਿਸੇ ਵੀ ਵੀਡੀਓ ਨੂੰ ਲੋਡ ਕਰਨ ਵੇਲੇ ਸਥਿਰ ਕਰੈਸ਼ diff --git a/fastlane/metadata/android/pa/changelogs/957.txt b/fastlane/metadata/android/pa/changelogs/957.txt new file mode 100644 index 000000000..eb66dacbc --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/957.txt @@ -0,0 +1,10 @@ +• ਖਾਸ ਐਨਕਿਊ ਕਿਰਿਆਵਾਂ ਨੂੰ ਇੱਕ ਵਿੱਚ ਜੋੜੋ +• ਪਲੇਅਰ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਦੋ ਉਂਗਲਾਂ ਦੇ ਸੰਕੇਤ +• reCAPTCHA ਕੂਕੀਜ਼ ਨੂੰ ਕਲੀਅਰ ਕਰਨ ਦਿਓ +• ਨੋਟੀਫਿਕੇਸ਼ਨ ਨੂੰ ਰੰਗ ਨਾ ਕਰਨ ਦਾ ਵਿਕਲਪ +• ਅਨੰਤ ਬਫਰਿੰਗ ਨੂੰ ਠੀਕ ਕਰਨ ਲਈ ਵਿਡੀਓ ਵੇਰਵਿਆਂ ਨੂੰ ਕਿਵੇਂ ਖੋਲ੍ਹਿਆ ਜਾਂਦਾ ਹੈ ਇਸ ਵਿੱਚ ਸੁਧਾਰ ਕਰੋ, ਨਿਊਪਾਈਪ ਨਾਲ ਸਾਂਝਾ ਕਰਨ ਵੇਲੇ ਬੱਗੀ ਵਿਵਹਾਰ ਅਤੇ ਹੋਰ ਅਸੰਗਤਤਾਵਾਂ +• YouTube ਵੀਡੀਓਜ਼ ਦੀ ਗਤੀ ਵਧਾਓ ਅਤੇ ਉਮਰ ਪ੍ਰਤੀਬੰਧਿਤ ਵੀਡੀਓ ਨੂੰ ਠੀਕ ਕਰੋ +• ਫਾਸਟ ਫਾਰਵਰਡ/ਰਿਵਾਇੰਡ 'ਤੇ ਕਰੈਸ਼ ਨੂੰ ਠੀਕ ਕਰੋ +• ਥੰਬਨੇਲ ਖਿੱਚ ਕੇ ਸੂਚੀਆਂ ਨੂੰ ਮੁੜ ਵਿਵਸਥਿਤ ਨਾ ਕਰੋ +• ਪੌਪਅੱਪ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਹਮੇਸ਼ਾ ਯਾਦ ਰੱਖੋ +• ਸੰਤਾਲੀ ਭਾਸ਼ਾ ਸ਼ਾਮਲ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/958.txt b/fastlane/metadata/android/pa/changelogs/958.txt new file mode 100644 index 000000000..66c2ae763 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/958.txt @@ -0,0 +1 @@ +ਨਵਾਂ ਅਤੇ ਸੁਧਾਰਿਆ ਗਿਆ: • ਲੌਕ ਸਕ੍ਰੀਨ 'ਤੇ ਥੰਬਨੇਲ ਨੂੰ ਲੁਕਾਉਣ ਲਈ ਮੁੜ-ਜੋੜਿਆ ਗਿਆ ਵਿਕਲਪ • ਫੀਡ ਨੂੰ ਤਾਜ਼ਾ ਕਰਨ ਲਈ ਖਿੱਚੋ • ਸਥਾਨਕ ਸੂਚੀਆਂ ਪ੍ਰਾਪਤ ਕਰਨ ਵੇਲੇ ਬਿਹਤਰ ਕਾਰਗੁਜ਼ਾਰੀ ਸਥਿਰ: • ਰੈਮ ਤੋਂ ਹਟਾਏ ਜਾਣ ਤੋਂ ਬਾਅਦ ਨਿਊਪਾਈਪ ਨੂੰ ਚਾਲੂ ਕਰਨ ਵੇਲੇ ਸਥਿਰ ਕਰੈਸ਼ • ਕੋਈ ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਨਾ ਹੋਣ 'ਤੇ ਸਟਾਰਟਅਪ 'ਤੇ ਸਥਿਰ ਕਰੈਸ਼ • ਚਮਕ- ਅਤੇ ਵੌਲਯੂਮ-ਇਸ਼ਾਰਾ ਸੈਟਿੰਗਾਂ ਦਾ ਆਦਰ ਕਰਦੇ ਹੋਏ ਸਥਿਰ • [YouTube] ਸਥਿਰ ਲੰਬੀਆਂ ਪਲੇਲਿਸਟਾਂ ਹੋਰ: • ਕੋਡ ਕਲੀਨਅੱਪ ਅਤੇ ਕਈ ਅੰਦਰੂਨੀ ਸੁਧਾਰ • ਨਿਰਭਰਤਾ ਅੱਪਡੇਟ • ਅਨੁਵਾਦ ਅੱਪਡੇਟ diff --git a/fastlane/metadata/android/pa/changelogs/959.txt b/fastlane/metadata/android/pa/changelogs/959.txt new file mode 100644 index 000000000..5ababff32 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/959.txt @@ -0,0 +1,3 @@ +ਗਲਤੀ ਰਿਪੋਰਟਰ ਨੂੰ ਖੋਲ੍ਹਣ ਤੋਂ ਬਾਅਦ ਕਰੈਸ਼ਾਂ ਦਾ ਬੇਅੰਤ ਲੂਪ ਸਥਿਰ ਕੀਤਾ ਗਿਆ। +PeerTube ਉਦਾਹਰਨਾਂ ਦੀ ਅੱਪਡੇਟ ਕੀਤੀ ਸੂਚੀ ਜੋ +NewPipe ਦੁਆਰਾ ਆਪਣੇ ਆਪ ਖੋਲ੍ਹੀ ਜਾ ਸਕਦੀ ਹੈ। ਅੱਪਡੇਟ ਕੀਤੇ ਅਨੁਵਾਦ। diff --git a/fastlane/metadata/android/pa/changelogs/960.txt b/fastlane/metadata/android/pa/changelogs/960.txt new file mode 100644 index 000000000..8527ebd2d --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/960.txt @@ -0,0 +1,4 @@ +• ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਨਿਰਯਾਤ ਡੇਟਾਬੇਸ ਵਿਕਲਪ ਦਾ ਸੁਧਾਰਿਆ ਗਿਆ ਵਰਣਨ। +• ਸਥਿਰ YouTube ਟਿੱਪਣੀਆਂ ਪਾਰਸਿੰਗ। +• media.ccc.de ਸੇਵਾ ਦਾ ਸਥਿਰ ਡਿਸਪਲੇ ਨਾਮ। +• ਅੱਪਡੇਟ ਕੀਤੇ ਅਨੁਵਾਦ। diff --git a/fastlane/metadata/android/pa/changelogs/961.txt b/fastlane/metadata/android/pa/changelogs/961.txt new file mode 100644 index 000000000..069b08239 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/961.txt @@ -0,0 +1 @@ +• [YouTube] ਮਿਕਸ ਸਮਰਥਨ • [YouTube] ਜਨਤਕ ਪ੍ਰਸਾਰਕਾਂ ਅਤੇ ਕੋਵਿਡ-19 ਬਾਰੇ ਜਾਣਕਾਰੀ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ • [media.ccc.de] ਜੋੜੇ ਗਏ ਹਾਲੀਆ ਵੀਡੀਓ • ਸੋਮਾਲੀ ਅਨੁਵਾਦ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ • ਬਹੁਤ ਸਾਰੇ ਅੰਦਰੂਨੀ ਸੁਧਾਰ • ਪਲੇਅਰ ਦੇ ਅੰਦਰੋਂ ਸਥਿਰ ਸ਼ੇਅਰਿੰਗ ਵੀਡੀਓ • ਸਥਿਰ ਖਾਲੀ ReCaptcha ਵੈਬਵਿਊ • ਇੱਕ ਸੂਚੀ ਵਿੱਚੋਂ ਇੱਕ ਸਟ੍ਰੀਮ ਨੂੰ ਹਟਾਉਣ ਵੇਲੇ ਆਈ ਕ੍ਰੈਸ਼ ਦਾ ਹੱਲ • [PeerTube] ਸਥਿਰ ਸੰਬੰਧਿਤ ਸਟ੍ਰੀਮਾਂ • [YouTube] ਸਥਿਰ YouTube ਸੰਗੀਤ ਖੋਜ diff --git a/fastlane/metadata/android/pa/changelogs/962.txt b/fastlane/metadata/android/pa/changelogs/962.txt new file mode 100644 index 000000000..3676cf31b --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/962.txt @@ -0,0 +1,2 @@ +media.ccc.de ਸੇਵਾ ਵਿੱਚ "ਹਾਲੀਆ" ਵਿਡੀਓਜ਼ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ। +media.ccc.de ਸੇਵਾ ਵਿੱਚ ਲਾਈਵ ਸਟ੍ਰੀਮਾਂ ਸ਼ਾਮਲ ਕੀਤੀਆਂ ਗਈਆਂ ਅਤੇ ਲਾਈਵ ਸਟ੍ਰੀਮ ਸਮਰਥਨ ਵੀ। diff --git a/fastlane/metadata/android/pa/changelogs/963.txt b/fastlane/metadata/android/pa/changelogs/963.txt new file mode 100644 index 000000000..f0bc9b09c --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/963.txt @@ -0,0 +1 @@ +• [YouTube] ਸਥਿਰ ਚੈਨਲ ਨਿਰੰਤਰਤਾ diff --git a/fastlane/metadata/android/pa/changelogs/964.txt b/fastlane/metadata/android/pa/changelogs/964.txt new file mode 100644 index 000000000..85dc2c151 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/964.txt @@ -0,0 +1 @@ +• ਪਲੇਅਰ ਨਿਯੰਤਰਣ ਵਿੱਚ ਅਧਿਆਵਾਂ ਲਈ ਸਮਰਥਨ ਜੋੜਿਆ ਗਿਆ • [PeerTube] ਸੇਪੀਆ ਖੋਜ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ • ਵੀਡੀਓ ਵੇਰਵੇ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਸ਼ੇਅਰ ਬਟਨ ਨੂੰ ਮੁੜ-ਜੋੜਿਆ ਗਿਆ ਅਤੇ ਟੈਬ ਲੇਆਉਟ ਵਿੱਚ ਸਟ੍ਰੀਮ ਵਰਣਨ ਨੂੰ ਤਬਦੀਲ ਕੀਤਾ ਗਿਆ • ਜੇਕਰ ਚਮਕ ਦਾ ਸੰਕੇਤ ਅਸਮਰੱਥ ਹੈ ਤਾਂ ਚਮਕ ਨੂੰ ਬਹਾਲ ਕਰਨਾ ਬੰਦ ਕਰੋ • ਕੋਡੀ 'ਤੇ ਵੀਡੀਓ ਚਲਾਉਣ ਲਈ ਸੂਚੀ ਆਈਟਮ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ • ਕੁਝ ਡਿਵਾਈਸਾਂ 'ਤੇ ਕੋਈ ਡਿਫੌਲਟ ਬ੍ਰਾਊਜ਼ਰ ਸੈੱਟ ਨਾ ਹੋਣ 'ਤੇ ਕ੍ਰੈਸ਼ ਦਾ ਹੱਲ ਕੀਤਾ ਗਿਆ ਹੈ ਅਤੇ ਸ਼ੇਅਰ ਡਾਇਲਾਗਸ ਨੂੰ ਬਿਹਤਰ ਬਣਾਓ • ਫੁੱਲਸਕ੍ਰੀਨ ਪਲੇਅਰ ਵਿੱਚ ਹਾਰਡਵੇਅਰ ਸਪੇਸ ਬਟਨ ਨਾਲ ਪਲੇ/ਪੌਜ਼ ਨੂੰ ਟੌਗਲ ਕਰੋ • [media.ccc.de] ਕਈ ਫਿਕਸ ਅਤੇ ਸੁਧਾਰ diff --git a/fastlane/metadata/android/pa/changelogs/965.txt b/fastlane/metadata/android/pa/changelogs/965.txt new file mode 100644 index 000000000..83e28b707 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/965.txt @@ -0,0 +1 @@ +ਸਥਿਰ ਕਰੈਸ਼ ਜੋ ਚੈਨਲ ਸਮੂਹਾਂ ਨੂੰ ਮੁੜ ਕ੍ਰਮਬੱਧ ਕਰਨ ਵੇਲੇ ਵਾਪਰਿਆ ਸੀ। ਚੈਨਲਾਂ ਅਤੇ ਪਲੇਲਿਸਟਾਂ ਤੋਂ ਹੋਰ YouTube ਵੀਡੀਓ ਪ੍ਰਾਪਤ ਕਰਨਾ ਸਥਿਰ ਕੀਤਾ ਗਿਆ ਹੈ। YouTube ਟਿੱਪਣੀਆਂ ਪ੍ਰਾਪਤ ਕਰਨਾ ਸਥਿਰ ਹੈ। YouTube URL ਵਿੱਚ /watch/, /v/ ਅਤੇ /w/ ਸਬਪਾਥ ਲਈ ਸਮਰਥਨ ਜੋੜਿਆ ਗਿਆ। SoundCloud ਕਲਾਇੰਟ ਆਈਡੀ ਅਤੇ ਭੂ-ਪ੍ਰਤੀਬੰਧਿਤ ਸਮਗਰੀ ਦਾ ਸਥਿਰ ਐਕਸਟਰੈਕਸ਼ਨ। ਉੱਤਰੀ ਕੁਰਦਿਸ਼ ਸਥਾਨਕਕਰਨ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ। diff --git a/fastlane/metadata/android/pa/changelogs/966.txt b/fastlane/metadata/android/pa/changelogs/966.txt new file mode 100644 index 000000000..61afac503 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/966.txt @@ -0,0 +1 @@ +ਨਵਾਂ: • ਇੱਕ ਨਵੀਂ ਸੇਵਾ ਸ਼ਾਮਲ ਕਰੋ: Bandcamp ਸੁਧਾਰ: • ਐਪ ਨੂੰ ਡਿਵਾਈਸ ਥੀਮ ਦਾ ਅਨੁਸਰਣ ਕਰਨ ਲਈ ਇੱਕ ਵਿਕਲਪ ਸ਼ਾਮਲ ਕਰੋ • ਇੱਕ ਸੁਧਾਰਿਆ ਹੋਇਆ ਗਲਤੀ ਪੈਨਲ ਦਿਖਾ ਕੇ ਕੁਝ ਕਰੈਸ਼ਾਂ ਨੂੰ ਰੋਕੋ • ਇਸ ਬਾਰੇ ਹੋਰ ਜਾਣਕਾਰੀ ਦਿਖਾਓ ਕਿ ਸਮੱਗਰੀ ਕਿਉਂ ਉਪਲਬਧ ਨਹੀਂ ਹੈ • ਹਾਰਡਵੇਅਰ ਸਪੇਸ ਬਟਨ ਪਲੇ/ਪੌਜ਼ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ • "ਡਾਊਨਲੋਡ ਸ਼ੁਰੂ" ਟੋਸਟ ਦਿਖਾਓ ਸਥਿਰ: • ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਦੇ ਸਮੇਂ ਵੀਡੀਓ ਵੇਰਵਿਆਂ ਵਿੱਚ ਬਹੁਤ ਛੋਟੇ ਥੰਬਨੇਲ ਨੂੰ ਠੀਕ ਕਰੋ • ਨਿਊਨਤਮ ਪਲੇਅਰ ਵਿੱਚ ਖਾਲੀ ਸਿਰਲੇਖ ਨੂੰ ਠੀਕ ਕਰੋ • ਪਿਛਲੇ ਰੀਸਾਈਜ਼ ਮੋਡ ਨੂੰ ਠੀਕ ਤਰ੍ਹਾਂ ਰੀਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ diff --git a/fastlane/metadata/android/pa/changelogs/967.txt b/fastlane/metadata/android/pa/changelogs/967.txt new file mode 100644 index 000000000..8b63f43e7 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/967.txt @@ -0,0 +1 @@ +ਸਥਿਰ YouTube EU ਵਿੱਚ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ। ਇਹ ਇੱਕ ਨਵੀਂ ਕੂਕੀ ਅਤੇ ਗੋਪਨੀਯਤਾ ਸਹਿਮਤੀ ਪ੍ਰਣਾਲੀ ਦੇ ਕਾਰਨ ਹੋਇਆ ਸੀ ਜਿਸ ਲਈ ਇੱਕ CONSENT ਕੂਕੀ ਸੈੱਟ ਕਰਨ ਲਈ NewPipe ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। diff --git a/fastlane/metadata/android/pa/changelogs/968.txt b/fastlane/metadata/android/pa/changelogs/968.txt new file mode 100644 index 000000000..3e3909022 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/968.txt @@ -0,0 +1 @@ +ਲੰਬੇ ਸਮੇਂ ਲਈ ਦਬਾਓ ਮੀਨੂ ਵਿੱਚ ਚੈਨਲ ਵੇਰਵੇ ਵਿਕਲਪ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ। ਪਲੇਲਿਸਟ ਇੰਟਰਫੇਸ ਤੋਂ ਪਲੇਲਿਸਟ ਨਾਮ ਦਾ ਨਾਮ ਬਦਲਣ ਲਈ ਕਾਰਜਸ਼ੀਲਤਾ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ। ਵੀਡੀਓ ਬਫਰਿੰਗ ਹੋਣ 'ਤੇ ਵਰਤੋਂਕਾਰ ਨੂੰ ਰੁਕਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ। ਚਿੱਟੇ ਥੀਮ ਨੂੰ ਪਾਲਿਸ਼ ਕੀਤਾ। ਇੱਕ ਵੱਡੇ ਫੌਂਟ ਆਕਾਰ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਓਵਰਲੈਪਿੰਗ ਫੌਂਟਾਂ ਨੂੰ ਸਥਿਰ ਕੀਤਾ ਗਿਆ ਹੈ। ਫਾਰਮੂਲਰ ਅਤੇ ਜ਼ੇਫੀਅਰ ਡਿਵਾਈਸਾਂ 'ਤੇ ਕੋਈ ਵੀਡੀਓ ਫਿਕਸ ਨਹੀਂ ਕੀਤਾ ਗਿਆ। ਵੱਖ-ਵੱਖ ਕਰੈਸ਼ਾਂ ਨੂੰ ਸਥਿਰ ਕੀਤਾ। diff --git a/fastlane/metadata/android/pa/changelogs/969.txt b/fastlane/metadata/android/pa/changelogs/969.txt new file mode 100644 index 000000000..4708c4a13 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/969.txt @@ -0,0 +1 @@ +• ਬਾਹਰੀ ਸਟੋਰੇਜ 'ਤੇ ਇੰਸਟਾਲੇਸ਼ਨ ਦੀ ਆਗਿਆ ਦਿਓ • [ਬੈਂਡਕੈਂਪ] ਇੱਕ ਸਟ੍ਰੀਮ 'ਤੇ ਪਹਿਲੀਆਂ ਤਿੰਨ ਟਿੱਪਣੀਆਂ ਨੂੰ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰਨ ਲਈ ਸਮਰਥਨ ਜੋੜਿਆ ਗਿਆ • ਡਾਊਨਲੋਡ ਸ਼ੁਰੂ ਹੋਣ 'ਤੇ ਸਿਰਫ਼ 'ਡਾਊਨਲੋਡ ਸ਼ੁਰੂ ਹੋ ਗਿਆ ਹੈ' ਟੋਸਟ ਦਿਖਾਓ • ਜਦੋਂ ਕੋਈ ਕੂਕੀ ਸਟੋਰ ਨਾ ਹੋਵੇ ਤਾਂ ਰੀਕੈਪਚਾ ਕੂਕੀ ਸੈਟ ਨਾ ਕਰੋ • [ਖਿਡਾਰੀ] ਕੈਸ਼ ਪ੍ਰਦਰਸ਼ਨ ਵਿੱਚ ਸੁਧਾਰ ਕਰੋ • [ਖਿਡਾਰੀ] ਫਿਕਸਡ ਪਲੇਅਰ ਆਟੋਮੈਟਿਕ ਨਹੀਂ ਚੱਲ ਰਿਹਾ • ਡਾਊਨਲੋਡਾਂ ਨੂੰ ਮਿਟਾਉਣ ਵੇਲੇ ਪਿਛਲੀਆਂ ਸਨੈਕਬਾਰਾਂ ਨੂੰ ਖਾਰਜ ਕਰੋ • ਸੂਚੀ ਵਿੱਚ ਨਾ ਹੋਣ ਵਾਲੀ ਵਸਤੂ ਨੂੰ ਮਿਟਾਉਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਗਈ diff --git a/fastlane/metadata/android/pa/changelogs/970.txt b/fastlane/metadata/android/pa/changelogs/970.txt new file mode 100644 index 000000000..679c9dae3 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/970.txt @@ -0,0 +1 @@ +ਨਵਾਂ • ਵਰਣਨ ਦੇ ਹੇਠਾਂ ਸਮੱਗਰੀ ਮੈਟਾਡੇਟਾ (ਟੈਗ, ਸ਼੍ਰੇਣੀਆਂ, ਲਾਇਸੰਸ, ...) ਦਿਖਾਓ • ਰਿਮੋਟ (ਗੈਰ-ਸਥਾਨਕ) ਪਲੇਲਿਸਟਾਂ ਵਿੱਚ "ਚੈਨਲ ਵੇਰਵੇ ਦਿਖਾਓ" ਵਿਕਲਪ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ • ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਦਬਾਉਣ ਵਾਲੇ ਮੀਨੂ ਵਿੱਚ "ਬ੍ਰਾਊਜ਼ਰ ਵਿੱਚ ਖੋਲ੍ਹੋ" ਵਿਕਲਪ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਸਥਿਰ • ਵੀਡੀਓ ਵੇਰਵੇ ਪੰਨੇ 'ਤੇ ਸਥਿਰ ਰੋਟੇਸ਼ਨ ਕਰੈਸ਼ • ਪਲੇਅਰ ਵਿੱਚ ਸਥਿਰ "ਕੋਡੀ ਨਾਲ ਖੇਡੋ" ਬਟਨ ਹਮੇਸ਼ਾ ਕੋਰ ਨੂੰ ਸਥਾਪਤ ਕਰਨ ਲਈ ਪ੍ਰੇਰਦਾ ਹੈ • ਸਥਿਰ ਅਤੇ ਸੁਧਾਰੀ ਸੈਟਿੰਗ ਆਯਾਤ ਅਤੇ ਨਿਰਯਾਤ ਮਾਰਗ • [YouTube] ਸਥਿਰ ਟਿੱਪਣੀ ਪਸੰਦ ਗਿਣਤੀ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ diff --git a/fastlane/metadata/android/pa/changelogs/971.txt b/fastlane/metadata/android/pa/changelogs/971.txt new file mode 100644 index 000000000..d3dbe862f --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/971.txt @@ -0,0 +1,3 @@ +ਹੌਟਫਿਕਸ +• ਰੀਬਫਰ ਤੋਂ ਬਾਅਦ ਪਲੇਬੈਕ ਲਈ ਬਫਰ ਵਧਾਓ +• ਪਲੇਅਰ ਵਿੱਚ ਪਲੇ-ਕਿਊ ਆਈਕਨ 'ਤੇ ਕਲਿੱਕ ਕਰਨ ਵੇਲੇ ਟੈਬਲੈੱਟਾਂ ਅਤੇ ਟੀਵੀ 'ਤੇ ਸਥਿਰ ਕਰੈਸ਼ diff --git a/fastlane/metadata/android/pa/changelogs/972.txt b/fastlane/metadata/android/pa/changelogs/972.txt new file mode 100644 index 000000000..9cf290198 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/972.txt @@ -0,0 +1,13 @@ +ਨਵਾਂ +ਵਰਣਨ ਵਿੱਚ ਟਾਈਮਸਟੈਂਪਾਂ ਅਤੇ ਹੈਸ਼ਟੈਗਾਂ ਨੂੰ ਪਛਾਣੋ +ਮੈਨੂਅਲ ਟੈਬਲੇਟ ਮੋਡ ਸੈਟਿੰਗ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ +ਇੱਕ ਫੀਡ ਵਿੱਚ ਖੇਡੀਆਂ ਗਈਆਂ ਆਈਟਮਾਂ ਨੂੰ ਲੁਕਾਉਣ ਦੀ ਸਮਰੱਥਾ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ + +ਸੁਧਾਰ +ਸਟੋਰੇਜ਼ ਐਕਸੈਸ ਫਰੇਮਵਰਕ ਦਾ ਸਹੀ ਢੰਗ ਨਾਲ ਸਮਰਥਨ ਕਰੋ +ਅਣਉਪਲਬਧ ਅਤੇ ਬੰਦ ਕੀਤੇ ਚੈਨਲਾਂ ਦੀ ਬਿਹਤਰ ਗਲਤੀ ਹੈਂਡਲਿੰਗ +Android 10+ ਉਪਭੋਗਤਾਵਾਂ ਲਈ Android ਸ਼ੇਅਰ ਸ਼ੀਟ ਹੁਣ ਸਮੱਗਰੀ ਦਾ ਸਿਰਲੇਖ ਦਿਖਾਉਂਦੀ ਹੈ। +ਅੱਪਡੇਟ ਕੀਤਾ Invidious ਮੌਕੇ ਅਤੇ ਸਹਿਯੋਗ ਪਾਈਪ ਲਿੰਕ. + +ਠੀਕ ਕੀਤਾ +[YouTube] ਉਮਰ ਪ੍ਰਤਿਬੰਧਿਤ ਸਮੱਗਰੀ ਚੋਣ ਡਾਇਲਾਗ ਖੋਲ੍ਹਣ ਵੇਲੇ ਲੀਕ ਵਿੰਡੋ ਅਪਵਾਦ ਨੂੰ ਰੋਕੋ diff --git a/fastlane/metadata/android/pa/changelogs/973.txt b/fastlane/metadata/android/pa/changelogs/973.txt new file mode 100644 index 000000000..3afd456da --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/973.txt @@ -0,0 +1,4 @@ +ਹੌਟਫਿਕਸ +• ਇੱਕ ਕਤਾਰ ਵਿੱਚ ਕਿੰਨੇ ਵਿਡੀਓ ਫਿੱਟ ਹੋ ਸਕਦੇ ਹਨ ਦੀ ਗਲਤ ਗਣਨਾ ਕਰਕੇ, ਗਰਿੱਡ ਲੇਆਉਟ ਵਿੱਚ ਕੱਟੇ ਜਾ ਰਹੇ ਥੰਬਨੇਲ ਅਤੇ ਸਿਰਲੇਖਾਂ ਨੂੰ ਠੀਕ ਕਰੋ +• ਸ਼ੇਅਰ ਮੀਨੂ ਤੋਂ ਖੋਲ੍ਹੇ ਜਾਣ 'ਤੇ ਬਿਨਾਂ ਕੁਝ ਕੀਤੇ ਗਾਇਬ ਹੋ ਰਹੇ ਡਾਉਨਲੋਡ ਡਾਇਲੌਗ ਨੂੰ ਠੀਕ ਕਰੋ +• ਬਾਹਰੀ ਗਤੀਵਿਧੀਆਂ ਜਿਵੇਂ ਕਿ ਸਟੋਰੇਜ਼ ਐਕਸੈਸ ਫਰੇਮਵਰਕ ਫਾਈਲ ਪਿਕਰ ਖੋਲ੍ਹਣ ਨਾਲ ਸਬੰਧਤ ਇੱਕ ਲਾਇਬ੍ਰੇਰੀ ਨੂੰ ਅੱਪਡੇਟ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/974.txt b/fastlane/metadata/android/pa/changelogs/974.txt new file mode 100644 index 000000000..563a9768a --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/974.txt @@ -0,0 +1,5 @@ +ਹੌਟਫਿਕਸ +• YouTube ਥ੍ਰੋਟਲਿੰਗ ਦੇ ਕਾਰਨ ਬਫਰਿੰਗ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਠੀਕ ਕਰੋ +• ਬੰਦ ਕੀਤੀਆਂ ਟਿੱਪਣੀਆਂ ਨਾਲ ਕ੍ਰੈਸ਼ਾਂ ਨੂੰ ਠੀਕ ਕਰੋ ਅਤੇ YouTube ਟਿੱਪਣੀਆਂ ਕੱਢਣ +• YouTube ਸੰਗੀਤ ਖੋਜ ਨੂੰ ਠੀਕ ਕਰੋ +• PeerTube ਲਾਈਵਸਟ੍ਰੀਮਾਂ ਨੂੰ ਠੀਕ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/975.txt b/fastlane/metadata/android/pa/changelogs/975.txt new file mode 100644 index 000000000..c866df1e2 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/975.txt @@ -0,0 +1,16 @@ +ਨਵਾਂ +• ਸੀਕ ਕਰਨ ਵੇਲੇ ਇੱਕ ਥੰਮਨੇਲ ਪੂਰਵਦਰਸ਼ਨ ਦਿਖਾਓ +• ਅਯੋਗ ਟਿੱਪਣੀਆਂ ਦਾ ਪਤਾ ਲਗਾਓ +• ਫੀਡ ਆਈਟਮ ਨੂੰ ਦੇਖੇ ਗਏ ਵਜੋਂ ਨਿਸ਼ਾਨਬੱਧ ਕਰਨ ਦਿਓ +• ਟਿੱਪਣੀ ਦਿਲ ਦਿਖਾਓ + +ਸੁਧਾਰ +• ਮੈਟਾਡੇਟਾ ਅਤੇ ਟੈਗਸ ਲੇਆਉਟ ਵਿੱਚ ਸੁਧਾਰ ਕਰੋ +• UI ਭਾਗਾਂ 'ਤੇ ਸੇਵਾ ਰੰਗ ਲਾਗੂ ਕਰੋ +ਠੀਕ ਕੀਤਾ +• ਮਿੰਨੀ ਪਲੇਅਰ ਵਿੱਚ ਥੰਬਨੇਲ ਠੀਕ ਕਰੋ +• ਡੁਪਲੀਕੇਟ ਕਤਾਰ ਆਈਟਮਾਂ 'ਤੇ ਬੇਅੰਤ ਬਫਰਿੰਗ ਨੂੰ ਠੀਕ ਕਰੋ +• ਕੁਝ ਪਲੇਅਰ ਫਿਕਸ ਜਿਵੇਂ ਰੋਟੇਸ਼ਨ ਅਤੇ ਤੇਜ਼ੀ ਨਾਲ ਬੰਦ ਹੋਣਾ +• ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਲੋਡ ਕੀਤੇ ਬਾਕੀ ਬਚੇ ReCAPTCHA ਨੂੰ ਠੀਕ ਕਰੋ +• ਫੀਡ ਨੂੰ ਤਾਜ਼ਾ ਕਰਨ ਵੇਲੇ ਕਲਿੱਕਾਂ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ +• ਕੁਝ ਡਾਊਨਲੋਡਰ ਕਰੈਸ਼ਾਂ ਨੂੰ ਠੀਕ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/976.txt b/fastlane/metadata/android/pa/changelogs/976.txt new file mode 100644 index 000000000..a1a1354ca --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/976.txt @@ -0,0 +1,10 @@ +• ਪੂਰੀ ਸਕ੍ਰੀਨ ਵਿੱਚ ਪਲੇਅਰ ਨੂੰ ਸਿੱਧਾ ਖੋਲ੍ਹਣ ਲਈ ਵਿਕਲਪ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ +• ਇਹ ਚੁਣਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ ਕਿ ਕਿਸ ਕਿਸਮ ਦੇ ਖੋਜ ਸੁਝਾਅ ਦਿਖਾਉਣੇ ਹਨ +• ਗੂੜ੍ਹਾ ਥੀਮ ਹੁਣ ਗਹਿਰਾ ਗੂੜ੍ਹਾ + ਗੂੜ੍ਹਾ ਸਪਲੈਸ਼ ਸਕ੍ਰੀਨ ਜੋੜਿਆ ਗਿਆ ਹੈ +• ਅਣਚਾਹੀਆਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਸਲੇਟੀ ਕਰਨ ਲਈ ਬਿਹਤਰ ਫ਼ਾਈਲ ਚੋਣਕਾਰ +• ਸਥਿਰ YouTube ਗਾਹਕੀ ਆਯਾਤ + +• ਇੱਕ ਸਟ੍ਰੀਮ ਨੂੰ ਮੁੜ ਚਲਾਉਣ ਲਈ ਮੁੜ-ਪਲੇਅ ਬਟਨ 'ਤੇ ਟੈਪ ਕਰਨ ਦੀ ਲੋੜ ਹੈ +• ਸਥਿਰ ਸਮਾਪਤੀ ਆਡੀਓ ਸੈਸ਼ਨ +• [Android TV] DPad ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਸਥਿਰ ਲੰਬੀ ਸੀਕਬਾਰ ਜੰਪ +ਹੋਰ ਤਬਦੀਲੀਆਂ ਦੇਖਣ ਲਈ, ਹੇਠਾਂ ਦਿੱਤੇ ਲਿੰਕ ਟੈਬ ਤੋਂ ਚੇਂਜਲੌਗ (ਅਤੇ ਬਲੌਗ ਪੋਸਟ) ਦੇਖੋ। diff --git a/fastlane/metadata/android/pa/changelogs/977.txt b/fastlane/metadata/android/pa/changelogs/977.txt new file mode 100644 index 000000000..95d779a80 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/977.txt @@ -0,0 +1,10 @@ +• ਲੰਬੇ ਪ੍ਰੈਸ ਮੀਨੂ ਵਿੱਚ "ਅਗਲਾ ਚਲਾਓ" ਬਟਨ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ +• ਇੰਟੈਂਟ ਫਿਲਟਰ ਵਿੱਚ YouTube ਸ਼ਾਰਟਸ ਪਾਥ ਪ੍ਰੀਫਿਕਸ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ +• ਸਥਿਰ ਸੈਟਿੰਗਾਂ ਆਯਾਤ +• ਕਤਾਰ ਸਕ੍ਰੀਨ ਵਿੱਚ ਪਲੇਅਰ ਬਟਨਾਂ ਨਾਲ ਸੀਕਬਾਰ ਸਥਿਤੀ ਨੂੰ ਸਵੈਪ ਕਰੋ +• MediasessionManager ਨਾਲ ਸੰਬੰਧਿਤ ਕਈ ਫਿਕਸ +• ਵੀਡੀਓ ਖਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ ਸਥਿਰ ਸੀਕਬਾਰ ਪੂਰਾ ਨਹੀਂ ਹੋਇਆ +• RealtekATV 'ਤੇ ਅਯੋਗ ਮੀਡੀਆ ਟਨਲਿੰਗ +• ਵਿਸਤ੍ਰਿਤ ਨਿਊਨਤਮ ਪਲੇਅਰ ਬਟਨ ਕਲਿੱਕ ਕਰਨ ਯੋਗ ਖੇਤਰ + +ਹੋਰ ਤਬਦੀਲੀਆਂ ਦੇਖਣ ਲਈ, ਹੇਠਾਂ ਦਿੱਤੇ ਲਿੰਕ ਟੈਬ ਤੋਂ ਚੇਂਜਲੌਗ (ਅਤੇ ਬਲੌਗ ਪੋਸਟ) ਦੇਖੋ। diff --git a/fastlane/metadata/android/pa/changelogs/978.txt b/fastlane/metadata/android/pa/changelogs/978.txt new file mode 100644 index 000000000..683f43ecc --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/978.txt @@ -0,0 +1 @@ +ਇੱਕ ਨਵੇਂ ਨਿਊਪਾਈਪ ਸੰਸਕਰਣ ਲਈ ਜਾਂਚ ਨੂੰ ਲਾਗੂ ਕਰਨਾ ਸਥਿਰ ਹੈ। ਇਹ ਜਾਂਚ ਕਈ ਵਾਰ ਬਹੁਤ ਜਲਦੀ ਕੀਤੀ ਗਈ ਸੀ ਅਤੇ ਇਸਲਈ ਐਪ ਕਰੈਸ਼ ਹੋ ਜਾਂਦੀ ਹੈ। ਇਸ ਨੂੰ ਹੁਣ ਠੀਕ ਕੀਤਾ ਜਾਣਾ ਗਿਆ ਹੈ। diff --git a/fastlane/metadata/android/pa/changelogs/979.txt b/fastlane/metadata/android/pa/changelogs/979.txt new file mode 100644 index 000000000..61a432f20 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/979.txt @@ -0,0 +1,2 @@ +- ਠੀਕ ਕੀਤਾ ਪਲੇਬੈਕ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰਨਾ +- ਇਹ ਯਕੀਨੀ ਬਣਾਉਣ ਲਈ ਸੁਧਾਰ ਕੀਤੇ ਗਏ ਹਨ ਕਿ ਸੇਵਾ ਜੋ ਇਹ ਨਿਰਧਾਰਤ ਕਰਦੀ ਹੈ ਕਿ ਕੀ NewPipe ਨੂੰ ਨਵੇਂ ਸੰਸਕਰਣ ਦੀ ਜਾਂਚ ਲਈ ਜਾਂਚ ਕਰਨੀ ਚਾਹੀਦੀ ਹੈ, ਬੈਕਗ੍ਰਾਉਂਡ ਵਿੱਚ ਸ਼ੁਰੂ ਨਹੀਂ ਹੋਈ ਹੈ diff --git a/fastlane/metadata/android/pa/changelogs/980.txt b/fastlane/metadata/android/pa/changelogs/980.txt new file mode 100644 index 000000000..cc1b47f26 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/980.txt @@ -0,0 +1,12 @@ +ਨਵਾਂ +• ਸ਼ੇਅਰ ਮੀਨੂ ਲਈ "ਪਲੇਲਿਸਟ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ" ਵਿਕਲਪ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ +• y2u.be ਅਤੇ PeerTube ਛੋਟੇ ਲਿੰਕਾਂ ਲਈ ਸਮਰਥਨ ਜੋੜਿਆ ਗਿਆ + +ਸੁਧਾਰ +• ਪਲੇਬੈਕ-ਸਪੀਡ-ਕੰਟਰੋਲਾਂ ਨੂੰ ਵਧੇਰੇ ਸੰਖੇਪ ਬਣਾਇਆ ਗਿਆ ਹੈ +• ਫੀਡ ਹੁਣ ਨਵੀਆਂ ਆਈਟਮਾਂ ਨੂੰ ਉਜਾਗਰ ਕਰਦੀ ਹੈ +• ਫੀਡ ਵਿੱਚ "ਦੇਖੀਆਂ ਆਈਟਮਾਂ ਦਿਖਾਓ" ਵਿਕਲਪ ਹੁਣ ਸੁਰੱਖਿਅਤ ਹੈ + +ਠੀਕ ਕੀਤਾ +• ਸਥਿਰ YouTube ਪਸੰਦਾਂ ਅਤੇ ਨਾਪਸੰਦਾਂ ਨੂੰ ਕੱਢਣਾ +• ਬੈਕਗ੍ਰਾਊਂਡ ਤੋਂ ਵਾਪਸ ਆਉਣ ਤੋਂ ਬਾਅਦ ਸਥਿਰ ਆਟੋਮੈਟਿਕ ਰੀਪਲੇਅ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ diff --git a/fastlane/metadata/android/pa/changelogs/981.txt b/fastlane/metadata/android/pa/changelogs/981.txt new file mode 100644 index 000000000..36f141586 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/981.txt @@ -0,0 +1,2 @@ +ਐਂਡਰਾਇਡ 11+ 'ਤੇ ਬਫਰਿੰਗ ਤੋਂ ਬਾਅਦ ਅਸਫਲ ਪਲੇਬੈਕ ਰੀਜ਼ਿਊਮ ਨੂੰ ਠੀਕ ਕਰਨ ਲਈ ਮੀਡੀਆ ਪਾਰਸਰ ਸਮਰਥਨ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ। +ਪਲੇਬੈਕ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਠੀਕ ਕਰਨ ਲਈ ਫਿਲਿਪਸ QM16XE 'ਤੇ ਮੀਡੀਆ ਟਨਲਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ। diff --git a/fastlane/metadata/android/pa/changelogs/982.txt b/fastlane/metadata/android/pa/changelogs/982.txt new file mode 100644 index 000000000..829c85851 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/982.txt @@ -0,0 +1 @@ +ਸਥਿਰ YouTube ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਚਲਾ ਰਿਹਾ। diff --git a/fastlane/metadata/android/pa/changelogs/983.txt b/fastlane/metadata/android/pa/changelogs/983.txt new file mode 100644 index 000000000..c3797c649 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/983.txt @@ -0,0 +1,9 @@ +ਨਵਾਂ ਡਬਲ-ਟੈਪ-ਟੂ-ਸੀਕ UI ਅਤੇ ਵਿਵਹਾਰ ਸ਼ਾਮਲ ਕਰੋ +ਸੈਟਿੰਗਾਂ ਨੂੰ ਖੋਜਣਯੋਗ ਬਣਾਓ +ਪਿੰਨ ਕੀਤੀਆਂ ਟਿੱਪਣੀਆਂ ਨੂੰ ਇਸ ਤਰ੍ਹਾਂ ਹਾਈਲਾਈਟ ਕਰੋ +FSFE ਦੇ PeerTube ਉਦਾਹਰਨ ਲਈ ਓਪਨ-ਵਿਦ-ਐਪ ਸਮਰਥਨ ਸ਼ਾਮਲ ਕਰੋ +ਗਲਤੀ ਸੂਚਨਾਵਾਂ ਸ਼ਾਮਲ ਕਰੋ +ਪਲੇਅਰ ਬਦਲਣ 'ਤੇ ਪਹਿਲੀ ਕਤਾਰ ਆਈਟਮ ਦੇ ਰੀਪਲੇਅ ਨੂੰ ਠੀਕ ਕਰੋ +ਫੇਲ ਹੋਣ ਤੋਂ ਪਹਿਲਾਂ ਲਾਈਵਸਟ੍ਰੀਮ ਦੇ ਦੌਰਾਨ ਬਫਰਿੰਗ ਕਰਦੇ ਸਮੇਂ ਜ਼ਿਆਦਾ ਉਡੀਕ ਕਰੋ +ਸਥਾਨਕ ਖੋਜ ਨਤੀਜਿਆਂ ਦਾ ਕ੍ਰਮ ਠੀਕ ਕਰੋ +ਪਲੇ ਕਤਾਰ ਵਿੱਚ ਖਾਲੀ ਆਈਟਮ ਖੇਤਰਾਂ ਨੂੰ ਠੀਕ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/984.txt b/fastlane/metadata/android/pa/changelogs/984.txt new file mode 100644 index 000000000..068d56d59 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/984.txt @@ -0,0 +1,7 @@ +ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਭਰਨ ਅਤੇ ਟੈਬਲੇਟਾਂ ਅਤੇ ਟੀਵੀ 'ਤੇ ਸਕ੍ਰੋਲਿੰਗ ਨੂੰ ਠੀਕ ਕਰਨ ਲਈ ਸੂਚੀਆਂ ਵਿੱਚ ਲੋੜੀਂਦੀਆਂ ਸ਼ੁਰੂਆਤੀ ਆਈਟਮਾਂ ਲੋਡ ਕਰੋ +ਸੂਚੀਆਂ ਰਾਹੀਂ ਸਕ੍ਰੋਲ ਕਰਦੇ ਸਮੇਂ ਬੇਤਰਤੀਬੇ ਕਰੈਸ਼ਾਂ ਨੂੰ ਠੀਕ ਕਰੋ +ਪਲੇਅਰ ਨੂੰ ਸਿਸਟਮ UI ਦੇ ਅਧੀਨ ਤੇਜ਼ੀ ਨਾਲ ਸੀਕ ਓਵਰਲੇ ਆਰਕ ਜਾਣ ਦਿਓ +ਮਲਟੀ ਵਿੰਡੋ ਵਿੱਚ ਖੇਡਦੇ ਸਮੇਂ ਕਟਆਊਟਾਂ ਵਿੱਚ ਬਦਲਾਵ ਵਾਪਸ ਲਿਆਓ, ਜਿਸ ਨਾਲ ਕੁਝ ਫ਼ੋਨਾਂ 'ਤੇ ਪਲੇਅਰ ਰੀਗਰੈਸ਼ਨ ਦਾ ਕਾਰਨ ਬਣਦੇ ਹਨ। +compileSdk ਨੂੰ 30 ਤੋਂ 31 ਤੱਕ ਵਧਾਓ +ਅਸ਼ੁੱਧੀ ਰਿਪੋਰਟਿੰਗ ਲਾਇਬ੍ਰੇਰੀ ਨੂੰ ਅੱਪਡੇਟ ਕਰੋ +ਪਲੇਅਰ ਵਿੱਚ ਕੁਝ ਕੋਡ ਰੀਫੈਕਟਰ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/985.txt b/fastlane/metadata/android/pa/changelogs/985.txt new file mode 100644 index 000000000..fe62a1330 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/985.txt @@ -0,0 +1 @@ +ਸਥਿਰ YouTube ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਚਲਾ ਰਿਹਾ diff --git a/fastlane/metadata/android/pa/changelogs/986.txt b/fastlane/metadata/android/pa/changelogs/986.txt new file mode 100644 index 000000000..c9ab694a4 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/986.txt @@ -0,0 +1,15 @@ +ਨਵਾਂ +• ਨਵੀਆਂ ਸਟ੍ਰੀਮਾਂ ਲਈ ਸੂਚਨਾਵਾਂ +• ਬੈਕਗ੍ਰਾਊਂਡ ਅਤੇ ਵੀਡੀਓ ਪਲੇਅਰਾਂ ਵਿਚਕਾਰ ਅਰਾਮ ਨਾਲ ਤਬਦੀਲੀ +• ਸੈਮੀਟੋਨਸ ਦੁਆਰਾ ਪਿੱਚ ਬਦਲੋ +• ਇੱਕ ਪਲੇਲਿਸਟ ਵਿੱਚ ਮੁੱਖ ਪਲੇਅਰ ਕਤਾਰ ਜੋੜੋ + +ਸੁਧਾਰ +• ਸਪੀਡ/ਪਿਚ ਸਟੈਪ ਦਾ ਆਕਾਰ ਯਾਦ ਰੱਖੋ +• ਵੀਡੀਓ ਪਲੇਅਰ ਵਿੱਚ ਸ਼ੁਰੂਆਤੀ ਲੰਬੇ ਬਫਰਿੰਗ ਨੂੰ ਘੱਟ ਕਰੋ • Android TV ਲਈ ਪਲੇਅਰ UI ਵਿੱਚ ਸੁਧਾਰ ਕਰੋ +• ਸਾਰੀਆਂ ਡਾਊਨਲੋਡ ਕੀਤੀਆਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਉਣ ਤੋਂ ਪਹਿਲਾਂ ਪੁਸ਼ਟੀ ਕਰੋ + +ਠੀਕ ਕੀਤਾ +• ਮੀਡੀਆ ਬਟਨ ਨੂੰ ਫਿਕਸ ਕਰੋ ਜੋ ਪਲੇਅਰ ਨਿਯੰਤਰਣਾਂ ਨੂੰ ਨਹੀਂ ਲੁਕਾਉਂਦਾ ਹੈ +• ਪਲੇਅਰ ਦੀ ਕਿਸਮ ਬਦਲਣ 'ਤੇ ਪਲੇਬੈਕ ਰੀਸੈਟ ਨੂੰ ਠੀਕ ਕਰੋ +• ਪਲੇਲਿਸਟ ਡਾਇਲਾਗ ਨੂੰ ਘੁੰਮਾਉਣ ਨੂੰ ਠੀਕ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/987.txt b/fastlane/metadata/android/pa/changelogs/987.txt new file mode 100644 index 000000000..93fc77a77 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/987.txt @@ -0,0 +1,11 @@ +ਨਵਾਂ +• ਪ੍ਰਗਤੀਸ਼ੀਲ HTTP ਤੋਂ ਇਲਾਵਾ ਸਪੋਰਟ ਡਿਲੀਵਰੀ ਵਿਧੀਆਂ: ਤੇਜ਼ ਪਲੇਬੈਕ ਲੋਡ ਹੋਣ ਦਾ ਸਮਾਂ, PeerTube ਅਤੇ SoundCloud ਲਈ ਫਿਕਸ, ਹਾਲ ਹੀ ਵਿੱਚ ਖਤਮ ਹੋਈਆਂ YouTube ਲਾਈਵਸਟ੍ਰੀਮਾਂ ਦਾ ਪਲੇਬੈਕ +• ਇੱਕ ਸਥਾਨਕ ਪਲੇਲਿਸਟ ਵਿੱਚ ਰਿਮੋਟ ਪਲੇਲਿਸਟ ਜੋੜਨ ਲਈ ਬਟਨ ਸ਼ਾਮਲ ਕਰੋ +• Android 10+ ਸ਼ੇਅਰ ਸ਼ੀਟ ਵਿੱਚ ਚਿੱਤਰ ਦੀ ਪੂਰਵ-ਝਲਕ + + ਸੁਧਾਰ +• ਪਲੇਬੈਕ ਪੈਰਾਮੀਟਰ ਡਾਇਲਾਗ ਵਿੱਚ ਸੁਧਾਰ ਕਰੋ +• ਗਾਹਕੀ ਆਯਾਤ/ਨਿਰਯਾਤ ਬਟਨਾਂ ਨੂੰ ਤਿੰਨ-ਬਿੰਦੀਆਂ ਵਾਲੇ ਮੀਨੂ ਵਿੱਚ ਲੈ ਜਾਓ + +ਠੀਕ ਕੀਤਾ +• ਪਲੇਲਿਸਟ ਤੋਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਦੇਖੇ ਗਏ ਵੀਡੀਓ ਨੂੰ ਹਟਾਉਣਾ ਠੀਕ ਕਰੋ • ਸ਼ੇਅਰ ਮੀਨੂ ਥੀਮ ਅਤੇ "ਪਲੇਲਿਸਟ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ" ਐਂਟਰੀ ਨੂੰ ਠੀਕ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/988.txt b/fastlane/metadata/android/pa/changelogs/988.txt new file mode 100644 index 000000000..a50bcc144 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/988.txt @@ -0,0 +1,2 @@ +[YouTube] ਕਿਸੇ ਵੀ ਵੀਡੀਓ ਨੂੰ ਚਲਾਉਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਸਮੇਂ "ਕੋਈ ਸਟ੍ਰੀਮ ਪ੍ਰਾਪਤ ਨਹੀਂ ਕਰ ਸਕਿਆ" ਗਲਤੀ ਨੂੰ ਠੀਕ ਕਰੋ +[YouTube] ਫਿਕਸ "ਹੇਠ ਦਿੱਤੀ ਸਮੱਗਰੀ ਇਸ ਐਪ 'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।" ਬੇਨਤੀ ਕੀਤੀ ਵੀਡੀਓ ਦੀ ਬਜਾਏ ਸੁਨੇਹਾ ਵਿਖਾਇਆ ਗਿਆ diff --git a/fastlane/metadata/android/pa/changelogs/989.txt b/fastlane/metadata/android/pa/changelogs/989.txt new file mode 100644 index 000000000..9c00f845d --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/989.txt @@ -0,0 +1,3 @@ +• [YouTube] ਕਿਸੇ ਵੀ ਵੀਡੀਓ ਨੂੰ ਚਲਾਉਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਸਮੇਂ ਅਨੰਤ ਲੋਡਿੰਗ ਨੂੰ ਠੀਕ ਕਰੋ +• [YouTube] ਕੁਝ ਵੀਡੀਓਜ਼ 'ਤੇ ਥ੍ਰੋਟਲਿੰਗ ਨੂੰ ਠੀਕ ਕਰੋ +• jsoup ਲਾਇਬ੍ਰੇਰੀ ਨੂੰ 1.15.3 ਵਿੱਚ ਅੱਪਗ੍ਰੇਡ ਕਰੋ, ਜਿਸ ਵਿੱਚ ਸੁਰੱਖਿਆ ਫਿਕਸ ਸ਼ਾਮਲ ਹੈ diff --git a/fastlane/metadata/android/pa/changelogs/990.txt b/fastlane/metadata/android/pa/changelogs/990.txt new file mode 100644 index 000000000..ce82cbdd6 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/990.txt @@ -0,0 +1,13 @@ +ਇਹ ਰੀਲੀਜ਼ Android 4.4 ਕਿਟਕੈਟ ਲਈ ਸਮਰਥਨ ਛੱਡਦੀ ਹੈ, ਹੁਣ ਘੱਟੋ-ਘੱਟ ਸੰਸਕਰਣ Android 5 Lollipop ਹੈ! +ਨਵਾਂ +• ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਦਬਾਉਣ ਵਾਲੇ ਮੀਨੂ ਤੋਂ ਡਾਊਨਲੋਡ ਕਰੋ +• ਫੀਡ ਵਿੱਚ ਭਵਿੱਖ ਦੇ ਵੀਡੀਓ ਲੁਕਾਓ +• ਸਥਾਨਕ ਪਲੇਲਿਸਟਾਂ ਨੂੰ ਸਾਂਝਾ ਕਰੋ +ਸੁਧਾਰ +• ਪਲੇਅਰ ਕੋਡ ਨੂੰ ਛੋਟੇ ਹਿੱਸਿਆਂ ਵਿੱਚ ਰੀਫੈਕਟਰ ਕਰੋ: ਘੱਟ RAM ਵਰਤੀ ਗਈ, ਘੱਟ ਬੱਗ +• ਥੰਮਨੇਲ ਦੇ ਸਕੇਲ ਮੋਡ ਵਿੱਚ ਸੁਧਾਰ ਕਰੋ +• ਚਿੱਤਰ ਪਲੇਸਹੋਲਡਰ ਨੂੰ ਵੈਕਟਰਾਈਜ਼ ਕਰੋ + +ਠੀਕ ਕੀਤਾ +• ਪਲੇਅਰ ਨੋਟੀਫਿਕੇਸ਼ਨ ਨਾਲ ਵੱਖ-ਵੱਖ ਮੁੱਦਿਆਂ ਨੂੰ ਹੱਲ ਕਰੋ: ਪੁਰਾਣੀ/ਗੁੰਮ ਮੀਡੀਆ ਜਾਣਕਾਰੀ, ਵਿਗੜਿਆ ਥੰਮਨੇਲ +• ਪੂਰੀ ਸਕ੍ਰੀਨ ਦੀ ਥਾਂ ਉਸਦੇ 1/4 ਹਿੱਸੇ ਦੀ ਵਰਤੋਂ ਨੂੰ ਠੀਕ ਕਰੋ From 9ecd5dff09d98aaa70ef71dc9bdb8c24ccf8313c Mon Sep 17 00:00:00 2001 From: Robin Date: Mon, 16 Jan 2023 13:56:45 +0100 Subject: [PATCH 57/84] Orientation is locked if there is no sensor for it --- .../java/org/schabi/newpipe/player/helper/PlayerHelper.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index abde7c3d1..8d8e0414e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -14,6 +14,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.provider.Settings; import android.view.accessibility.CaptioningManager; @@ -382,8 +383,11 @@ public final class PlayerHelper { public static boolean globalScreenOrientationLocked(final Context context) { // 1: Screen orientation changes using accelerometer // 0: Screen orientation is locked + // if the accelerometer sensor is missing completely, assume locked orientation return android.provider.Settings.System.getInt( - context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 0; + context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 0 + || !context.getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER); } public static int getProgressiveLoadIntervalBytes(@NonNull final Context context) { From abb6b4282d3ac97c90fb822d1666d43922ffd2b2 Mon Sep 17 00:00:00 2001 From: ge78fug Date: Mon, 16 Jan 2023 15:13:34 +0100 Subject: [PATCH 58/84] Chenged the chapter icon --- app/src/main/res/drawable/ic_menu_book.xml | 12 ++++++++++++ app/src/main/res/layout/player.xml | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/drawable/ic_menu_book.xml diff --git a/app/src/main/res/drawable/ic_menu_book.xml b/app/src/main/res/drawable/ic_menu_book.xml new file mode 100644 index 000000000..4cd4fb3a4 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_book.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/app/src/main/res/layout/player.xml b/app/src/main/res/layout/player.xml index 60cbcf7c4..a3f039412 100644 --- a/app/src/main/res/layout/player.xml +++ b/app/src/main/res/layout/player.xml @@ -216,7 +216,7 @@ android:paddingEnd="6dp" android:paddingBottom="3dp" android:scaleType="fitCenter" - android:src="@drawable/ic_format_list_numbered" + android:src="@drawable/ic_menu_book" android:visibility="gone" app:tint="@color/white" tools:ignore="ContentDescription,RtlHardcoded" /> From b9378a7c1fedee40ec0ba16a42aba113f0659cc7 Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 16 Jan 2023 22:30:28 +0100 Subject: [PATCH 59/84] Fix NPEs after OnSharedPreferenceChangeListener changes Apps targeting {@link android.os.Build.VERSION_CODES#R} on devices running OS versions {@link android.os.Build.VERSION_CODES#R Android R} or later, will receive a {@code null} value when preferences are cleared. --- .../newpipe/fragments/detail/VideoDetailFragment.java | 6 +++--- .../newpipe/fragments/list/BaseListFragment.java | 2 +- .../fragments/list/videos/RelatedItemsFragment.java | 8 +++----- .../schabi/newpipe/local/BaseLocalListFragment.java | 2 +- .../org/schabi/newpipe/settings/tabs/TabsManager.java | 2 +- .../shandian/giga/service/DownloadManagerService.java | 10 +++++----- 6 files changed, 14 insertions(+), 16 deletions(-) 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 e46c054e5..917d89e09 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 @@ -172,13 +172,13 @@ public final class VideoDetailFragment private final SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener = (sharedPreferences, key) -> { - if (key.equals(getString(R.string.show_comments_key))) { + if (getString(R.string.show_comments_key).equals(key)) { showComments = sharedPreferences.getBoolean(key, true); tabSettingsChanged = true; - } else if (key.equals(getString(R.string.show_next_video_key))) { + } else if (getString(R.string.show_next_video_key).equals(key)) { showRelatedItems = sharedPreferences.getBoolean(key, true); tabSettingsChanged = true; - } else if (key.equals(getString(R.string.show_description_key))) { + } else if (getString(R.string.show_description_key).equals(key)) { showDescription = sharedPreferences.getBoolean(key, true); tabSettingsChanged = true; } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index 0b0acff86..8a117a47a 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -474,7 +474,7 @@ public abstract class BaseListFragment extends BaseStateFragment @Override public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { - if (key.equals(getString(R.string.list_view_mode_key))) { + if (getString(R.string.list_view_mode_key).equals(key)) { updateFlags |= LIST_MODE_UPDATE_FLAG; } } 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 dc5dbd74f..65664e0e3 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 @@ -159,11 +159,9 @@ public class RelatedItemsFragment extends BaseListInfoFragment extends BaseStateFragment @Override public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { - if (key.equals(getString(R.string.list_view_mode_key))) { + if (getString(R.string.list_view_mode_key).equals(key)) { updateFlags |= LIST_MODE_UPDATE_FLAG; } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsManager.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsManager.java index 2836fe52b..c885b803c 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsManager.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsManager.java @@ -73,7 +73,7 @@ public final class TabsManager { private SharedPreferences.OnSharedPreferenceChangeListener getPreferenceChangeListener() { return (sp, key) -> { - if (key.equals(savedTabsKey)) { + if (savedTabsKey.equals(key)) { if (savedTabsChangeListener != null) { savedTabsChangeListener.onTabsChanged(); } 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 dc56ee205..edc6bb6fd 100755 --- a/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java +++ b/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java @@ -310,7 +310,7 @@ public class DownloadManagerService extends Service { } private void handlePreferenceChange(SharedPreferences prefs, @NonNull String key) { - if (key.equals(getString(R.string.downloads_maximum_retry))) { + if (getString(R.string.downloads_maximum_retry).equals(key)) { try { String value = prefs.getString(key, getString(R.string.downloads_maximum_retry_default)); mManager.mPrefMaxRetry = value == null ? 0 : Integer.parseInt(value); @@ -318,13 +318,13 @@ public class DownloadManagerService extends Service { mManager.mPrefMaxRetry = 0; } mManager.updateMaximumAttempts(); - } else if (key.equals(getString(R.string.downloads_cross_network))) { + } else if (getString(R.string.downloads_cross_network).equals(key)) { mManager.mPrefMeteredDownloads = prefs.getBoolean(key, false); - } else if (key.equals(getString(R.string.downloads_queue_limit))) { + } else if (getString(R.string.downloads_queue_limit).equals(key)) { mManager.mPrefQueueLimit = prefs.getBoolean(key, true); - } else if (key.equals(getString(R.string.download_path_video_key))) { + } else if (getString(R.string.download_path_video_key).equals(key)) { mManager.mMainStorageVideo = loadMainVideoStorage(); - } else if (key.equals(getString(R.string.download_path_audio_key))) { + } else if (getString(R.string.download_path_audio_key).equals(key)) { mManager.mMainStorageAudio = loadMainAudioStorage(); } } From 640d4b0280d06f3b3a107a56d3357def3af2b5ed Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 16 Jan 2023 23:05:29 +0100 Subject: [PATCH 60/84] Fix more NPEs after OnSharedPreferenceChangeListener changes --- .../java/org/schabi/newpipe/local/feed/FeedFragment.kt | 2 +- .../newpipe/settings/VideoAudioSettingsFragment.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index c1ee4e558..26ad1cc38 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -122,7 +122,7 @@ class FeedFragment : BaseStateFragment() { groupName = arguments?.getString(KEY_GROUP_NAME) ?: "" onSettingsChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { _, key -> - if (key.equals(getString(R.string.list_view_mode_key))) { + if (getString(R.string.list_view_mode_key).equals(key)) { updateListViewModeOnResume = true } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java index 039f00c1d..aae9cfca5 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java @@ -27,14 +27,14 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment { updateSeekOptions(); - listener = (sharedPreferences, s) -> { + listener = (sharedPreferences, key) -> { // on M and above, if user chooses to minimise to popup player on exit // and the app doesn't have display over other apps permission, // show a snackbar to let the user give permission if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M - && s.equals(getString(R.string.minimize_on_exit_key))) { - final String newSetting = sharedPreferences.getString(s, null); + && getString(R.string.minimize_on_exit_key).equals(key)) { + final String newSetting = sharedPreferences.getString(key, null); if (newSetting != null && newSetting.equals(getString(R.string.minimize_on_exit_popup_key)) && !Settings.canDrawOverlays(getContext())) { @@ -46,7 +46,7 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment { .show(); } - } else if (s.equals(getString(R.string.use_inexact_seek_key))) { + } else if (getString(R.string.use_inexact_seek_key).equals(key)) { updateSeekOptions(); } }; From e9fcad4787c0c0efdf502c910ca8d3c8a4480b04 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 16 Jan 2023 23:20:50 +0100 Subject: [PATCH 61/84] Fix SonarLint --- .../main/java/org/schabi/newpipe/local/feed/FeedFragment.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index 26ad1cc38..2bb2f9986 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -36,7 +36,6 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.Button -import androidx.annotation.Nullable import androidx.appcompat.app.AlertDialog import androidx.appcompat.content.res.AppCompatResources import androidx.core.content.edit @@ -500,7 +499,7 @@ class FeedFragment : BaseStateFragment() { private fun handleFeedNotAvailable( subscriptionEntity: SubscriptionEntity, - @Nullable cause: Throwable?, + cause: Throwable?, nextItemsErrors: List ) { val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) From a6021730cd7f0a5b7786130dfe2268f1f287d723 Mon Sep 17 00:00:00 2001 From: ge78fug Date: Tue, 17 Jan 2023 10:50:13 +0100 Subject: [PATCH 62/84] Removed format_list_numbered --- app/src/main/res/drawable/ic_format_list_numbered.xml | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 app/src/main/res/drawable/ic_format_list_numbered.xml diff --git a/app/src/main/res/drawable/ic_format_list_numbered.xml b/app/src/main/res/drawable/ic_format_list_numbered.xml deleted file mode 100644 index b11666c56..000000000 --- a/app/src/main/res/drawable/ic_format_list_numbered.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - From ddda80a5779d705fb6e8d29505b4b267cd372d79 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Tue, 17 Jan 2023 22:31:22 +0100 Subject: [PATCH 63/84] Fixed the bug --- .../java/org/schabi/newpipe/player/playqueue/PlayQueue.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java index edf5a771c..f809e0db9 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java @@ -527,6 +527,9 @@ public abstract class PlayQueue implements Serializable { if (size() != other.size()) { return false; } + if (other.getIndex() != getIndex()) { + return false; + } for (int i = 0; i < size(); i++) { final PlayQueueItem stream = streams.get(i); final PlayQueueItem otherStream = other.streams.get(i); From f88c1e1e8bd41f555e7636256ae05bf3dc6e5355 Mon Sep 17 00:00:00 2001 From: ge78fug Date: Thu, 19 Jan 2023 21:15:09 +0100 Subject: [PATCH 64/84] Changed the position --- app/src/main/res/layout/player.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/layout/player.xml b/app/src/main/res/layout/player.xml index a3f039412..011c54147 100644 --- a/app/src/main/res/layout/player.xml +++ b/app/src/main/res/layout/player.xml @@ -212,7 +212,6 @@ android:clickable="true" android:focusable="true" android:paddingStart="6dp" - android:paddingTop="5dp" android:paddingEnd="6dp" android:paddingBottom="3dp" android:scaleType="fitCenter" From 6e1ffb4e52b06067c562446500f34f76369f32f1 Mon Sep 17 00:00:00 2001 From: ge78fug Date: Thu, 19 Jan 2023 23:24:25 +0100 Subject: [PATCH 65/84] Centered the icon --- app/src/main/res/layout/player.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/player.xml b/app/src/main/res/layout/player.xml index 011c54147..b528e4e9b 100644 --- a/app/src/main/res/layout/player.xml +++ b/app/src/main/res/layout/player.xml @@ -214,6 +214,7 @@ android:paddingStart="6dp" android:paddingEnd="6dp" android:paddingBottom="3dp" + android:paddingTop="3dp" android:scaleType="fitCenter" android:src="@drawable/ic_menu_book" android:visibility="gone" From 52e39c340238f47d0a11da39a6975892b1a20564 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 20 Jan 2023 11:12:32 +0100 Subject: [PATCH 66/84] Fixed tests --- .../java/org/schabi/newpipe/player/playqueue/PlayQueueTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/test/java/org/schabi/newpipe/player/playqueue/PlayQueueTest.java b/app/src/test/java/org/schabi/newpipe/player/playqueue/PlayQueueTest.java index a130359a3..b8989b8fc 100644 --- a/app/src/test/java/org/schabi/newpipe/player/playqueue/PlayQueueTest.java +++ b/app/src/test/java/org/schabi/newpipe/player/playqueue/PlayQueueTest.java @@ -177,7 +177,7 @@ public class PlayQueueTest { final List streams = Collections.nCopies(5, item1); final PlayQueue queue1 = makePlayQueue(1, streams); final PlayQueue queue2 = makePlayQueue(4, streams); - assertEquals(queue1, queue2); + assertNotEquals(queue1, queue2); } @Test From a69f74f51bf49d0bdbfd83502d0a01ebc1d1752e Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 20 Jan 2023 18:39:16 +0100 Subject: [PATCH 67/84] Add snippet to ensure baseline.profm file is sorted Thanks to obfusk, see https://issuetracker.google.com/issues/231837768 and #6486 --- app/build.gradle | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index 79e07a190..2c0f03e38 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,3 +1,7 @@ +import com.android.tools.profgen.ArtProfileKt +import com.android.tools.profgen.ArtProfileSerializer +import com.android.tools.profgen.DexFile + plugins { id "com.android.application" id "kotlin-android" @@ -308,3 +312,24 @@ static String getGitWorkingBranch() { return "" } } + +project.afterEvaluate { + tasks.compileReleaseArtProfile.doLast { + outputs.files.each { file -> + if (file.toString().endsWith(".profm")) { + println("Sorting ${file} ...") + def version = ArtProfileSerializer.valueOf("METADATA_0_0_2") + def profile = ArtProfileKt.ArtProfile(file) + def keys = new ArrayList(profile.profileData.keySet()) + def sortedData = new LinkedHashMap() + Collections.sort keys, new DexFile.Companion() + keys.each { key -> sortedData[key] = profile.profileData[key] } + new FileOutputStream(file).with { + write(version.magicBytes$profgen) + write(version.versionBytes$profgen) + version.write$profgen(it, sortedData, "") + } + } + } + } +} From fceec71ad3d6541d1dc0f8e7e44a5797ccc8a662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C4=B1la?= <121803062+Ilhamiii@users.noreply.github.com> Date: Sat, 21 Jan 2023 16:13:15 +0400 Subject: [PATCH 68/84] Corrected language names --- app/src/main/res/values/settings_keys.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index c2819feea..126818969 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -495,7 +495,7 @@ @string/systems_language Afrikaans - Azərbaycan + Azərbaycanca Bahasa Indonesia Bahasa Malaysia Català @@ -1165,7 +1165,7 @@ Basa Acèh العربية العربية (ليبيا) - Azərbaycan dili + Azərbaycanca Asturianu Беларуская ⵜⴰⵎⴰⵣⵉⵖⵜ @@ -1221,7 +1221,7 @@ Português (BR) Português (PT) Română - русский язык + Pусский ᱥᱟᱱᱛᱟᱲᱤ sardu Slovenčina From 5b3f8a3d307145124273f1493e035e2dac17e072 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sat, 21 Jan 2023 14:56:55 +0100 Subject: [PATCH 69/84] Replaced the equals method --- .../fragments/detail/VideoDetailFragment.java | 11 ++++++----- .../java/org/schabi/newpipe/player/Player.java | 2 +- .../newpipe/player/playqueue/PlayQueue.java | 17 +++++++---------- .../newpipe/player/playqueue/PlayQueueTest.java | 11 ++++++----- 4 files changed, 20 insertions(+), 21 deletions(-) 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 679084bdf..95853e550 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 @@ -864,7 +864,8 @@ public final class VideoDetailFragment if (playQueue == null) { playQueue = new SinglePlayQueue(result); } - if (stack.isEmpty() || !stack.peek().getPlayQueue().equals(playQueue)) { + if (stack.isEmpty() || !stack.peek().getPlayQueue() + .equalStreams(playQueue)) { stack.push(new StackItem(serviceId, url, title, playQueue)); } } @@ -1780,7 +1781,7 @@ public final class VideoDetailFragment // deleted/added items inside Channel/Playlist queue and makes possible to have // a history of played items @Nullable final StackItem stackPeek = stack.peek(); - if (stackPeek != null && !stackPeek.getPlayQueue().equals(queue)) { + if (stackPeek != null && !stackPeek.getPlayQueue().equalStreams(queue)) { @Nullable final PlayQueueItem playQueueItem = queue.getItem(); if (playQueueItem != null) { stack.push(new StackItem(playQueueItem.getServiceId(), playQueueItem.getUrl(), @@ -1846,7 +1847,7 @@ public final class VideoDetailFragment // They are not equal when user watches something in popup while browsing in fragment and // then changes screen orientation. In that case the fragment will set itself as // a service listener and will receive initial call to onMetadataUpdate() - if (!queue.equals(playQueue)) { + if (!queue.equalStreams(playQueue)) { return; } @@ -2113,7 +2114,7 @@ public final class VideoDetailFragment final Iterator iterator = stack.descendingIterator(); while (iterator.hasNext()) { final StackItem next = iterator.next(); - if (next.getPlayQueue().equals(queue)) { + if (next.getPlayQueue().equalStreams(queue)) { item = next; break; } @@ -2128,7 +2129,7 @@ public final class VideoDetailFragment if (isClearingQueueConfirmationRequired(activity) && playerIsNotStopped() && activeQueue != null - && !activeQueue.equals(playQueue)) { + && !activeQueue.equalStreams(playQueue)) { showClearingQueueConfirmation(onAllow); } else { onAllow.run(); diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 95520ba1e..caaa01440 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -348,7 +348,7 @@ public final class Player implements PlaybackListener, Listener { final boolean playbackSkipSilence = getPrefs().getBoolean(getContext().getString( R.string.playback_skip_silence_key), getPlaybackSkipSilence()); - final boolean samePlayQueue = playQueue != null && playQueue.equals(newQueue); + final boolean samePlayQueue = playQueue != null && playQueue.equalStreamsAndIndex(newQueue); final int repeatMode = intent.getIntExtra(REPEAT_MODE, getRepeatMode()); final boolean playWhenReady = intent.getBooleanExtra(PLAY_WHEN_READY, true); final boolean isMuted = intent.getBooleanExtra(IS_MUTED, isMuted()); diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java index f809e0db9..4c6230964 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java @@ -518,18 +518,13 @@ public abstract class PlayQueue implements Serializable { * This method also gives a chance to track history of items in a queue in * VideoDetailFragment without duplicating items from two identical queues */ - @Override - public boolean equals(@Nullable final Object obj) { - if (!(obj instanceof PlayQueue)) { + public boolean equalStreams(@Nullable final PlayQueue other) { + if (other == null) { return false; } - final PlayQueue other = (PlayQueue) obj; if (size() != other.size()) { return false; } - if (other.getIndex() != getIndex()) { - return false; - } for (int i = 0; i < size(); i++) { final PlayQueueItem stream = streams.get(i); final PlayQueueItem otherStream = other.streams.get(i); @@ -542,9 +537,11 @@ public abstract class PlayQueue implements Serializable { return true; } - @Override - public int hashCode() { - return streams.hashCode(); + public boolean equalStreamsAndIndex(@Nullable final PlayQueue other) { + if (equalStreams(other)) { + return other.getIndex() == getIndex(); + } + return false; } public boolean isDisposed() { diff --git a/app/src/test/java/org/schabi/newpipe/player/playqueue/PlayQueueTest.java b/app/src/test/java/org/schabi/newpipe/player/playqueue/PlayQueueTest.java index b8989b8fc..022089f37 100644 --- a/app/src/test/java/org/schabi/newpipe/player/playqueue/PlayQueueTest.java +++ b/app/src/test/java/org/schabi/newpipe/player/playqueue/PlayQueueTest.java @@ -13,7 +13,6 @@ import java.util.Objects; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -169,7 +168,8 @@ public class PlayQueueTest { final List streams = Collections.nCopies(5, item1); final PlayQueue queue1 = makePlayQueue(0, streams); final PlayQueue queue2 = makePlayQueue(0, streams); - assertEquals(queue1, queue2); + assertTrue(queue1.equalStreams(queue2)); + assertTrue(queue1.equalStreamsAndIndex(queue2)); } @Test @@ -177,7 +177,8 @@ public class PlayQueueTest { final List streams = Collections.nCopies(5, item1); final PlayQueue queue1 = makePlayQueue(1, streams); final PlayQueue queue2 = makePlayQueue(4, streams); - assertNotEquals(queue1, queue2); + assertTrue(queue1.equalStreams(queue2)); + assertFalse(queue1.equalStreamsAndIndex(queue2)); } @Test @@ -186,7 +187,7 @@ public class PlayQueueTest { final List streams2 = Collections.nCopies(5, item2); final PlayQueue queue1 = makePlayQueue(0, streams1); final PlayQueue queue2 = makePlayQueue(0, streams2); - assertNotEquals(queue1, queue2); + assertFalse(queue1.equalStreams(queue2)); } @Test @@ -195,7 +196,7 @@ public class PlayQueueTest { final List streams2 = Collections.nCopies(6, item2); final PlayQueue queue1 = makePlayQueue(0, streams1); final PlayQueue queue2 = makePlayQueue(0, streams2); - assertNotEquals(queue1, queue2); + assertFalse(queue1.equalStreams(queue2)); } } } From 34e6e70be960f18653c15d37c676af7c335c02d5 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sun, 22 Jan 2023 05:12:39 +0100 Subject: [PATCH 70/84] Translated using Weblate (Azerbaijani) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Lithuanian) Currently translated at 99.3% (648 of 652 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Assamese) Currently translated at 15.0% (98 of 652 strings) Translated using Weblate (Odia) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Slovenian) Currently translated at 2.7% (2 of 72 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Sardinian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Galician) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Azerbaijani) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Lithuanian) Currently translated at 99.3% (648 of 652 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Persian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Polish) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Czech) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Greek) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Italian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Italian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Japanese) Currently translated at 99.8% (651 of 652 strings) Translated using Weblate (Russian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (German) Currently translated at 100.0% (652 of 652 strings) Co-authored-by: Abhilash Co-authored-by: Agnieszka C Co-authored-by: Ahmad0a Co-authored-by: AioiLight Co-authored-by: Ajeje Brazorf Co-authored-by: Danial Behzadi Co-authored-by: Eric Co-authored-by: ErnestasKaralius Co-authored-by: Fjuro Co-authored-by: Francesco Saltori Co-authored-by: GET100PERCENT Co-authored-by: Hosted Weblate Co-authored-by: HudobniVolk Co-authored-by: Igor Nedoboy Co-authored-by: Igor Rückert Co-authored-by: Ihor Hordiichuk Co-authored-by: Jeff Huang Co-authored-by: Linerly Co-authored-by: Nidi Co-authored-by: Oğuz Ersen Co-authored-by: Pieter van der Razemond Co-authored-by: Priit Jõerüüt Co-authored-by: RSoulwin Co-authored-by: Ray Co-authored-by: Retrial Co-authored-by: Yaron Shahrabani Co-authored-by: gallegonovato Co-authored-by: nautilusx Co-authored-by: random r Co-authored-by: ssantos Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sl/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar/strings.xml | 2 + app/src/main/res/values-as/strings.xml | 73 +++++++++++++++++++ app/src/main/res/values-az/strings.xml | 10 ++- app/src/main/res/values-cs/strings.xml | 2 + app/src/main/res/values-de/strings.xml | 2 + app/src/main/res/values-el/strings.xml | 2 + app/src/main/res/values-es/strings.xml | 2 + app/src/main/res/values-et/strings.xml | 3 + app/src/main/res/values-fa/strings.xml | 3 + app/src/main/res/values-gl/strings.xml | 3 + app/src/main/res/values-he/strings.xml | 2 + app/src/main/res/values-hi/strings.xml | 3 + app/src/main/res/values-in/strings.xml | 2 + app/src/main/res/values-it/strings.xml | 5 +- app/src/main/res/values-ja/strings.xml | 4 + app/src/main/res/values-lt/strings.xml | 16 ++-- app/src/main/res/values-nl/strings.xml | 4 + app/src/main/res/values-or/strings.xml | 3 + app/src/main/res/values-pa/strings.xml | 3 + app/src/main/res/values-pl/strings.xml | 2 + app/src/main/res/values-pt-rBR/strings.xml | 2 + app/src/main/res/values-pt-rPT/strings.xml | 3 + app/src/main/res/values-pt/strings.xml | 3 + app/src/main/res/values-ru/strings.xml | 12 ++- app/src/main/res/values-sc/strings.xml | 3 + app/src/main/res/values-tr/strings.xml | 2 + app/src/main/res/values-uk/strings.xml | 2 + app/src/main/res/values-zh-rCN/strings.xml | 2 + app/src/main/res/values-zh-rHK/strings.xml | 6 +- app/src/main/res/values-zh-rTW/strings.xml | 3 + .../metadata/android/sl/changelogs/991.txt | 13 ++++ .../metadata/android/sl/short_description.txt | 1 + 32 files changed, 180 insertions(+), 18 deletions(-) create mode 100644 fastlane/metadata/android/sl/changelogs/991.txt create mode 100644 fastlane/metadata/android/sl/short_description.txt diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 2fbe794a3..cbd3ade35 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -780,4 +780,6 @@ استيراد الاشتراكات أو تصديرها من القائمة المكونة من 3 نقاط هذا الخيار متاح فقط إذا تم تحديد %s للسمة إلغاء تعيين الصورة المصغرة الدائمة + فشل النسخ إلى الحافظة + البطاقة \ No newline at end of file diff --git a/app/src/main/res/values-as/strings.xml b/app/src/main/res/values-as/strings.xml index 578213394..be845845a 100644 --- a/app/src/main/res/values-as/strings.xml +++ b/app/src/main/res/values-as/strings.xml @@ -25,4 +25,77 @@ আপুনি \"%1$s\" বুজাইছিল নেকি\? বাহ্যিক ভিডিঅ’ প্লেয়াৰ ব্যৱহাৰ কৰক বাহ্যিক অডিঅ’ প্লেয়াৰ ব্যৱহাৰ কৰক + Channel আনচাবস্ক্ৰাইব কৰা হ\'ল + subscription সলনি কৰিব পৰা নগ\'ল + subscription আপডেট কৰিব পৰা নগ\'ল + তথ্য দেখুৱাওক + চাবস্ক্ৰিপচন + বুকমাৰ্ক কৰা প্লেলিষ্ট + টেব নিৰ্বাচন কৰক + বেকগ্ৰাউণ্ড + পপ-আপ + স্থায়ী ৰিজ\'লিউচন + স্থায়ী পপআপ ৰিজোলিউচন + উচ্চ ৰিজ\'লিউচন দেখুৱাওক + কেৱল কিছুমান ডিভাইচেহে 2K/4K ভিডিঅ’ বজাব পাৰে + Kodi ৰ সৈতে বজাওক + Kore এপ ইনষ্টল\? + \"Kodi ৰ সৈতে খোলক\" বিকল্প দেখুৱাওক + Kodi মিডিয়া চেণ্টাৰৰ জৰিয়তে এটা ভিডিঅ\' চলাবলৈ এটা বিকল্প প্ৰদৰ্শন কৰক + প্লেয়াৰটো ক্ৰেচ কৰক + বাফাৰিং + নথিং + জাননী ৰ‌ঙিণ কৰক + অডিঅ\' + অডিঅ\' ৰ প্ৰকাৰ + ভিডিঅ\'ৰ প্ৰকাৰ + থিম + নিশাৰ থিম + পোহৰ + অন্ধকাৰ + ক\'লা + পপ-আপ বৈশিষ্ট্যসমূহ মনত ৰাখিব + পপ-আপৰ অন্তিম আকাৰ আৰু অৱস্থান মনত ৰাখিব + Inexact seek য়ে প্লেয়াৰটোক দ্ৰুত গতিত স্থান সলনি কৰিবলৈ অনুমতি দিয়ে। ৫, ১৫ বা ২৫ ছেকেণ্ড সলনি কৰিবলৈ বিচাৰিলে ইয়াৰ প্ৰয়োজন নহয় + ফাষ্ট-ফৰৱাৰ্ড/-ৰিৱাইণ্ড কৰিবলৈ বিচৰা সময়সীমা + প্লেবেক লোড কৰাৰ ব্যৱধানৰ আকাৰ + লোড ব্যৱধানৰ আকাৰ সলনি কৰক (বৰ্তমানে %s) । এটা কম মানে প্ৰাৰম্ভিক ভিডিঅ\' লোডিং দ্ৰুত কৰিব পাৰে। পৰিৱৰ্তনৰ বাবে এটা খেলুৱৈ পুনৰাৰম্ভৰ প্ৰয়োজন + থাম্বনেইলত থকা মূল ৰং অনুসৰি এণ্ড্ৰইডক জাননীৰ ৰং কাষ্টমাইজ কৰিবলৈ কওক (মন কৰিব যে এইটো সকলো ডিভাইচতে উপলব্ধ নহয়) + সক্ৰিয় প্লেয়াৰৰ queue সলনি কৰা হ’ব + থাম্বনেইল লোড কৰক + মন্তব্য দেখুৱাওক + বিৱৰণ দেখুৱাওক + মেটা তথ্য দেখুৱাওক + সংৰক্ষিত ছবি মচি পেলোৱা হ\'ল + সংৰক্ষিত কৰি থোৱা মেটাডাটা মচি পেলাওক + সকলো সংৰক্ষণ কৰি ৰখা ৱেবপেজৰ তথ্য আঁতৰাওক + সংৰক্ষণ কৰি থোৱা মেটাডাটা মচি পেলোৱা হ\'ল + পৰৱৰ্তী ষ্ট্ৰিম স্বয়ংক্ৰিয়ভাৱে enque কৰক + সজোৱা + ভিডিঅ\' ডাউনলোড folder + যোগ কৰক + ডাউনলোড কৰা অডিঅ\' ফাইলসমূহ ইয়াত সংৰক্ষণ কৰা হয় + থাম্বনেইলক ১:১ অনুপাত লৈ ক্ৰপ কৰক + ডাউনলোড কৰা ভিডিঅ’ ফাইলসমূহ ইয়াত সংৰক্ষণ কৰা হয় + ভিডিঅ\' ফাইলসমূহৰ বাবে ডাউনলোড folder বাছক + অডিঅ\' ডাউনলোড folder + অডিঅ\' ফাইলসমূহৰ বাবে ডাউনলোড folder নিৰ্বাচন কৰক + জাননীত দেখুওৱা ভিডিঅ’ থাম্বনেইলটো ১৬:৯ৰ পৰা ১:১ অনুপাতলৈ ক্ৰপ কৰক + First 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 + Second action button + You can select at most three actions to show in the compact notification! + পুনৰাবৃত্তি + শ্বাফেল + দ্ৰুত inexact seek ব্যৱহাৰ কৰক + এটা queue বিলুপ্তি কৰাৰ আগতে নিশ্চিতকৰণৰ বাবে সুধিব + এটা প্লেয়াৰ পৰা আন এটালৈ সলনি কৰিলে আপোনাৰ queue সলনি হ\'ব পাৰে + Fourth action button + Third action button + ভিডিঅ\'ৰ বিৱৰণ আৰু অতিৰিক্ত তথ্য লুকুৱাবলৈ বন্ধ কৰক + মন্তব্য লুকুৱাবলৈ বন্ধ কৰক + \'পৰৱৰ্তী\' আৰু \'সাদৃশ্য থকা\' ভিডিঅ\' দেখুৱাওক + থাম্বনেইলসমূহ লোড কৰা, তথ্য আৰু মেমৰি ব্যৱহাৰ সংৰক্ষণ কৰা ৰোধ কৰিবলে বন্ধ কৰক। পৰিবৰ্তনসমূহে ইন-মেমৰি আৰু অন-ডিস্ক কেশ্ব দুয়োটা পৰিষ্কাৰ কৰে + ষ্ট্ৰিমৰ সৃষ্টিকৰ্তা, ষ্ট্ৰিমৰ বিষয়বস্তু বা এটা সন্ধান অনুৰোধৰ বিষয়ে অতিৰিক্ত তথ্যৰ সৈতে মেটা তথ্যৰ বাকচসমূহ লুকুৱাবলৈ বন্ধ কৰক \ 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 cd18e8d93..d8d88bd6d 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -1,8 +1,8 @@ - Başlamaq üçün böyüdücüyə toxun. + Başlamaq üçün böyüdücü güzgüyə toxun. %1$s tarixində yayımlanıb - Yayım oynadıcı tapılmadı. \"VLC\" yüklənilsin\? + Yayım oynadıcı tapılmadı. \"VLC\" quraşdırılsın\? Yayım oynadıcı tapılmadı (Oynatmaq üçün VLC\'ni quraşdıra bilərsiniz). Yüklə Ləğv et @@ -45,7 +45,7 @@ Qaranlıq Qara Abunəlikdən çıxın - Ani pəncərə rejimində aç + Ani görüntü rejimində aç Avtomatik oynat Endir Fasilələrdən sonra (məsələn, telefon zəngləri) oynatmağa davam etdir @@ -613,7 +613,7 @@ Xəta baş verdi: %1$s Fayl mövcud deyil, yaxud oxumaq və ya yazmaq icazəsi yoxdur Veb saytı təhlil etmək alınmadı - Səs ucalığı + Ucalıq Radio \"Oynadıcını çökdür\" Göstər Oynadıcıdan istifadə edərkən çökdürmə seçimini göstər @@ -728,4 +728,6 @@ %s endirmək üçün toxun Bu seçim yalnız tema üçün %s seçildikdə əlçatandır Daimi miniatürü ləğv et + Kart + Buferə kopyalamaq alınmadı \ 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 637678c23..adf6601a8 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -741,4 +741,6 @@ Import nebo export odběrů z 3-tečkové nabídky Tato možnost je dostupná pouze při vybraném motivu %s Zrušení nastavení trvalého náhledu + Karta + Kopírování do schránky se nezdařilo \ 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 d02b276cd..3b1959a69 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -728,4 +728,6 @@ Importieren oder Exportieren von Abonnements über das 3-Punkte-Menü Diese Option ist nur verfügbar, wenn %s als Design ausgewählt wird Dauerhaftes Vorschaubild aufheben + Kopieren in die Zwischenablage fehlgeschlagen + Karte \ 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 cf3c0576b..78d89cc59 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -728,4 +728,6 @@ Έχετε την πιο πρόσφατη έκδοση του NewPipe Αυτή η επιλογή είναι διαθέσιμη μόνο εάν έχει επιλεγεί %s για Θέμα Κατάργηση μόνιμης μικρογραφίας + Αποτυχία αντιγραφής στο πρόχειρο + Κάρτα \ 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 f92ad9128..9d68c28a9 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -744,4 +744,6 @@ Pulsa para descargar %s Esta opción sólo está disponible si %s está seleccionado para el tema Desactivar las miniaturas permanente + Error al copiar al portapapeles + Tarjeta \ 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 87beff94f..986de133b 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -727,4 +727,7 @@ Tellimusi saad importida või eksportida 3 punktiga menüüst Sa kasutad NewPipe\'i uusimat versiooni See valik on kasutusel vaid %s teema puhul + Lõikelauale kopeerimine ei õnnestunud + Eemalda püsiv pisipilt + Kaart \ No newline at end of file diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index f22200c06..72dc77660 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -727,4 +727,7 @@ ضربه برای بارگیری %s از جدیدترین نگارش نیوپایپ استفاده می‌کنید این گزینه تنها هنگامی موجود است که %s به عنوان زمینه گزیده باشد + کارت + شکست در رونوشت به تخته‌گیره + ناتنظیم بندانگشتی ثابت \ No newline at end of file diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 65d5ce204..a8cf01ef0 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -727,4 +727,7 @@ Toca para descargar %s Importa ou exporta subscricións dende o menú dos 3 puntos Esta opción só está dispoñible se %s está seleccionado para o tema + Produciuse un erro ao copiar no portapapeis + Desactivala miniatura permanente + Tarxeta \ 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 67e6d45ad..35dc19c8c 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -754,4 +754,6 @@ זאת הגרסה העדכנית ביותר של NewPipe אפשרות זאת זמינה רק אם נבחרה ערכת נושא %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 7c9ebf231..dc08899ed 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -727,4 +727,7 @@ आप न्यूपाइप का नवीनतम संस्करण चला रहे हैं %s डाउनलोड करने के लिए टैप करें यह विकल्प केवल तभी उपलब्ध होता है जब थीम के लिए %s का चयन किया जाता है + स्थायी थंमनेल अनसेट करें + कार्ड + क्लिपबोर्ड पर कॉपी करने में विफल \ 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 af8781a23..c195d62e1 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -715,4 +715,6 @@ Ketuk untuk mengunduh %s Opsi ini hanya tersedia jika %s dipilih untuk Tema Batalkan penetapan gambar kecil permanen + Gagal menyalin ke papan klip + Kartu \ 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 3304321d8..bf20d2be4 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -737,7 +737,10 @@ Visualizza sul sito Recupero veloce Premi per scaricare %s - L\'ultima versione di NewPipe è già in esecuzione + Stai già usando l\'ultima versione di NewPipe Importa o esporta iscrizioni dal menu a 3 punti Questa opzione è disponibile solo se %s è selezionato come Tema + Copia negli appunti non riuscita + Schede + Disattiva la miniatura permanente \ 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 480d869e5..d02b56e75 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -712,4 +712,8 @@ よくある質問 アプリの使い方に困ったときは、よくある質問に答えていますので、ぜひご覧ください! %sがテーマに選択された場合のみ、この選択肢が利用可能です + 高速モード + 3 点メニューから登録チャンネルをインポートまたはエクスポートします + カード + クリップボードへのコピーに失敗しました \ No newline at end of file diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 0da729ba8..bb45a0970 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -97,14 +97,14 @@ Pradėti Pauzė - Ištrinti + Naikinti Kontrolinė suma Gerai Failo pavadinimas Gijos Klaida - NewPipe Atsiunčiama - Palieskite, kad peržiūrėtumėte išsamią informaciją + NewPipe atsisiunčiama + Bakstelėkite, kad peržiūrėtumėte išsamią informaciją Prašome palaukti… Nukopijuota į iškarpinę Prašome pasirinkti galimą atsisiuntimų aplankalą @@ -212,9 +212,9 @@ Nerasta video srautų Nerasta audio srautų Tempti kad perrūšiuoti - Sukurti + Kurti Nutraukti - Pervadinti + Pervardyti Vėliausiai žiūrėta Dažniausiai žiūrėta Eksportavimas baigtas @@ -230,7 +230,7 @@ Visada klausti Gauname informaciją… Įkeliamas pasirinktas turinys - Naujas grojaraštį + Naujas grojaraštis Pervadinti Pavadinimas Pridėti į grojaraštį @@ -311,7 +311,7 @@ Pranešimas apie naują NewPipe versiją Programos atnaujinimo pranešimas Failą - Failas pašalintas + Failas panaikintas Atlikėjai Albumai Dainos @@ -686,7 +686,7 @@ \nĮdiekite „Storage Access Framework“ suderinamą su šia failų tvarkykle
Pranešimai pranešimui apie klaidas Rodyti „Grotuvas užlūžo“ - Sukurti klaidos pranešimą + Kurti klaidos pranešimą NewPipe susidūrė su klaida, paspauskite norėdami pranešti Šiam veiksmui nebuvo rasta tinkama failų tvarkyklė. \nĮdiekite failų tvarkyklę arba pabandykite išjungti \"%s\" atsisiuntimo nustatymuose diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 2390f8e69..c5e77b29f 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -726,4 +726,8 @@ Importeer of exporteer abonnementen vanuit het 3-punten menu U heeft de laatste versie van NewPipe Klik om %s te downloaden + Kon niet naar klembord kopiëren + Deze instelling is alleen beschikbaar als %s als thema ingesteld is + Kaart + Miniatuur niet ingesteld \ 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 0ad616d01..bc8d9fcee 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -727,4 +727,7 @@ ଆପଣ NewPipe ର ସର୍ବଶେଷ ସଂସ୍କରଣ ଚଳାଉଛନ୍ତି %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 169d45dad..2dcac20ab 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -727,4 +727,7 @@ ਤੁਸੀਂ ਨਿਊਪਾਈਪ ਦਾ ਨਵੀਨਤਮ ਸੰਸਕਰਣ ਚਲਾ ਰਹੇ ਹੋ %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 ab1e0aa72..e7ae07c85 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -749,4 +749,6 @@ Używasz najnowszej wersji NewPipe Ta opcja jest dostępna tylko wtedy, gdy %s jest wybrany jako motyw Usuń stałą miniaturę + Nie udało się skopiować do schowka + Karta \ 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 1929df070..fc02f29d7 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -741,4 +741,6 @@ Você está executando a versão mais recente do NewPipe Esta opção só está disponível se %s for selecionado para Tema Desativar miniatura permanente + Cartão + Falha ao copiar para a área de transferência \ 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 5a0d19285..4c2593330 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -727,4 +727,7 @@ Toque para descarregar %s Ordenação Esta opção só está disponível se %s for selecionado como tema + Desativar miniatura permanente + Não foi possível copiar para a área de transferência + Cartão \ 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 e993da934..c47241dcc 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -740,4 +740,7 @@ Já está a executar a versão mais recente do NewPipe Toque para descarregar %s Esta opção só está disponível se %s for selecionado para o tema + Desativar miniatura permanente + Não foi possível copiar para a área de transferência + Cartão \ 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 159b27a2a..50376dc03 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -692,8 +692,8 @@ Новые видео Уведомления о новых видео в подписках Частота проверки - Уведомлять о новых видео - Получать уведомления о новых видео из каналов, на которые Вы подписаны + Новые видео + Уведомлять о новых видео в подписках Тип подключения Любая сеть Уведомления отключены @@ -720,7 +720,7 @@ Загрузка сведений о трансляции… Проверить наличие новых трансляций Удалить все загруженные файлы\? - Уведомления плеера + Уведомление плеера , Полутон Проценты @@ -736,11 +736,15 @@ Скрыть проигранные Скрывать будущие видео Ответы на частые вопросы - Если у вас возникли проблемы с использованием приложения, обязательно ознакомьтесь с ответами на распространенные вопросы! + Если у вас возникли проблемы с использованием приложения, обязательно ознакомьтесь с ответами на распространённые вопросы! Посмотреть на веб-сайте Сортировка У вас последняя версия Быстрый режим Импорт и экспорт подписок в меню с 3-мя точками Нажмите для загрузки %s + Карта + Не удалось скопировать в буфер обмена + Доступно, когда Тема установлена в %s + Убрать постоянную миниатюру \ No newline at end of file diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index bdae4fd37..e649cfac2 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -727,4 +727,7 @@ Importa o esporta iscritziones dae su menù a 3 puntos Ses impreende s\'ùrtima versione de NewPipe Custa optzione est a disponimentu petzi si %s est seletzionadu comente tema + Carta + Còpia in punta de billete fallida + Disativa sa miniadura permanente \ 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 c9718d0b0..aeeb9bdc3 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -728,4 +728,6 @@ 3-nokta menüsünden abonelikleri içe veya dışa aktarın Bu seçenek yalnızca tema için %s seçildiğinde kullanılabilir Kalıcı küçük resmin ayarını kaldır + Kart + Panoya kopyalanamadı \ 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 e812e8e4f..16b48fc57 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -745,4 +745,6 @@ Швидкий режим Ця опція доступна, лише якщо темою обрано %s Прибрати постійну мініатюру + Картки + Не вдалося скопіювати до буфера обміну \ 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 c3ada7180..029aa8343 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -715,4 +715,6 @@ 轻按下载 %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 ab902d373..dc7d589b8 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -510,7 +510,7 @@ 自動 (跟返部機嘅主題色系) 精選 廣播 - 您而家可以揀選喺描述入面嘅文字喇。不過要單聲,喺揀選模式嘅時候,個頁面可能眨眨下,同埋啲連結會撳唔到。 + 您而家可以揀選喺描述入面嘅文字喇。不過要單聲,喺揀選模式嘅時候,版面可能會有啲眨,同埋啲連結會撳唔到。 啟用揀選描述入面嘅文字 版權協議 分類 @@ -713,4 +713,8 @@ 右上角嘅選單有得匯入或匯出訂閱 您已經用緊最新版本嘅 NewPipe 撳一下去下載 %s + 唔再揀定封面縮圖 + 色系揀做%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 1ed552ab8..ab975bff1 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -714,4 +714,7 @@ 快速模式 從三點式選單匯入或匯出訂閱 此選項僅在主題選擇為 %s 時可用 + 卡片 + 取消設定永久縮圖 + 無法複製到剪貼簿 \ No newline at end of file diff --git a/fastlane/metadata/android/sl/changelogs/991.txt b/fastlane/metadata/android/sl/changelogs/991.txt new file mode 100644 index 000000000..14f174a5a --- /dev/null +++ b/fastlane/metadata/android/sl/changelogs/991.txt @@ -0,0 +1,13 @@ +Novo +- Dodajanje gumba "Odpri v brskalniku" v podoknu z napakami +- Dodana možnost za prikaz skupin kanalov kot seznam +- [YouTube] Dolgi pritisk na segmente video pretoka za deljenje časovnega žiga URL-ja +- Dodajte gumb za predvajanje v vrsti v mini predvajalnik + +Izboljšave +- Dodana islandska lokalizacija ter posodobitev številnih drugih prevodov +- Številne notranje izboljšave + +Popravki +- Odprava večih sesutij +- [YouTube] Odprava težave z nalaganjem kanalov, nenamenskimi viri ter predvajanjem v nekaterih državah diff --git a/fastlane/metadata/android/sl/short_description.txt b/fastlane/metadata/android/sl/short_description.txt new file mode 100644 index 000000000..8826524fc --- /dev/null +++ b/fastlane/metadata/android/sl/short_description.txt @@ -0,0 +1 @@ +Brezplačen in enostaven YouTube "frontend" za Android. From b6bf0ffc40bade004b1cef8cec1eeb487d39618b Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 22 Jan 2023 08:56:29 +0100 Subject: [PATCH 71/84] Add changelog for v0.25.0 (992) --- .../metadata/android/en-US/changelogs/992.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/992.txt diff --git a/fastlane/metadata/android/en-US/changelogs/992.txt b/fastlane/metadata/android/en-US/changelogs/992.txt new file mode 100644 index 000000000..807411d50 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/992.txt @@ -0,0 +1,17 @@ +New +• Subscriber count in video details +• Download from the queue +• Permanently set a playlist thumbnail +• Long-press hashtags and links +• Card view mode + +Improved +• Larger mini-player close button +• Smoother thumbnail downscaling +• Target Android 13 (API 33) +• Seeking no longer pauses the player + +Fixed +• Fix overlay on DeX/mouse +• Allow background player with no separate audio streams +• Various YouTube fixes and more… \ No newline at end of file From b9228df32c9e23f21e4d69abe5f7f61d03796803 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 22 Jan 2023 08:59:21 +0100 Subject: [PATCH 72/84] Release v0.25.0 (992) --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 79e07a190..97d8e8553 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { resValue "string", "app_name", "NewPipe" minSdk 21 targetSdk 33 - versionCode 991 - versionName "0.24.1" + versionCode 992 + versionName "0.25.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From c70ce791dbfb659cd45d4a91a5de5a23e9eaa9ac Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Fri, 27 Jan 2023 15:37:33 +0100 Subject: [PATCH 73/84] Added the duplicate indicator explanation & removed some unnecessary functions --- .../schabi/newpipe/local/LocalItemListAdapter.java | 11 ----------- .../newpipe/local/dialog/PlaylistAppendDialog.java | 13 ++++++++++++- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java index ea7bc290d..05e2fdac0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java @@ -11,7 +11,6 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import org.schabi.newpipe.database.LocalItem; -import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.stream.model.StreamStateEntity; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.holder.LocalItemHolder; @@ -345,16 +344,6 @@ public class LocalItemListAdapter extends RecyclerView.Adapter { final List entities = getStreamEntities(); if (selectedItem instanceof PlaylistDuplicatesEntry && entities != null) { @@ -125,8 +124,20 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistAdapter.clearStreamItemList(); playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); + setDuplicateIndicatorExplanation(playlists); } } + private void setDuplicateIndicatorExplanation(final List playlists) { + for (final PlaylistDuplicatesEntry entry : playlists) { + if (entry.timesStreamIsContained > 0) { + final View indicatorExplanation = getView() + .findViewById(R.id.playlist_duplicate); + indicatorExplanation.setVisibility(View.VISIBLE); + return; + } + } + + } private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager, @NonNull final PlaylistDuplicatesEntry playlist, From 102975aeb3fabb18f2a87811d51aef463b30c5a0 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 29 Jan 2023 10:32:32 +0100 Subject: [PATCH 74/84] Improve handling playlist duplicate indicator --- .../local/dialog/PlaylistAppendDialog.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index b45f6bd9c..5aeca06ed 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -4,6 +4,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -28,6 +29,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog { private RecyclerView playlistRecyclerView; private LocalItemListAdapter playlistAdapter; + private TextView playlistDuplicateIndicator; private final CompositeDisposable playlistDisposables = new CompositeDisposable(); @@ -73,6 +75,8 @@ public final class PlaylistAppendDialog extends PlaylistDialog { playlistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); playlistRecyclerView.setAdapter(playlistAdapter); + playlistDuplicateIndicator = view.findViewById(R.id.playlist_duplicate); + final View newPlaylistButton = view.findViewById(R.id.newPlaylist); newPlaylistButton.setOnClickListener(ignored -> openCreatePlaylistDialog()); @@ -120,23 +124,20 @@ public final class PlaylistAppendDialog extends PlaylistDialog { } private void onPlaylistsReceived(@NonNull final List playlists) { - if (playlistAdapter != null && playlistRecyclerView != null) { + if (playlistAdapter != null + && playlistRecyclerView != null + && playlistDuplicateIndicator != null) { playlistAdapter.clearStreamItemList(); playlistAdapter.addItems(playlists); playlistRecyclerView.setVisibility(View.VISIBLE); - setDuplicateIndicatorExplanation(playlists); + playlistDuplicateIndicator.setVisibility( + anyPlaylistContainsDuplicates(playlists) ? View.VISIBLE : View.GONE); } } - private void setDuplicateIndicatorExplanation(final List playlists) { - for (final PlaylistDuplicatesEntry entry : playlists) { - if (entry.timesStreamIsContained > 0) { - final View indicatorExplanation = getView() - .findViewById(R.id.playlist_duplicate); - indicatorExplanation.setVisibility(View.VISIBLE); - return; - } - } + private boolean anyPlaylistContainsDuplicates(final List playlists) { + return playlists.stream() + .anyMatch(playlist -> playlist.timesStreamIsContained > 0); } private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager, From 711345eff7c46269797de66e61f030cfbc72fa1c Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 29 Jan 2023 10:32:44 +0100 Subject: [PATCH 75/84] Improve playlist duplicate indicator layout --- app/src/main/res/layout/dialog_playlists.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/res/layout/dialog_playlists.xml b/app/src/main/res/layout/dialog_playlists.xml index 5771b400f..ab4691fa9 100644 --- a/app/src/main/res/layout/dialog_playlists.xml +++ b/app/src/main/res/layout/dialog_playlists.xml @@ -37,17 +37,17 @@ + android:gravity="center" + android:text="@string/duplicate_in_playlist" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textSize="13sp" + android:visibility="gone" + tools:text="@tools:sample/lorem[20]" + tools:visibility="visible" /> Date: Sun, 29 Jan 2023 00:45:57 +0100 Subject: [PATCH 76/84] [YouTube] Add support for live links The addition of this support requires an extractor update. --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index dcfbd2ed6..53b1ef04e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -187,7 +187,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:ff94e9f30bc5d7831734cc85ecebe7d30ac9c040' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:999fb7f812f8f39712dda88cf5ff4db3ee877fdc' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3e987abdb..d839efbe0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -165,6 +165,7 @@ + From d1aed94d2713583e9c54697b07aeac6533e50df3 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 29 Jan 2023 11:28:00 +0100 Subject: [PATCH 77/84] Fix opening urls in browser on API 30+ See https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9 and https://github.com/TeamNewPipe/NewPipe/issues/9615 --- app/src/main/AndroidManifest.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d839efbe0..1fb20ef0e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,14 @@ + + + + + + + + From e0ba872b66701abfdeaef02773f026ab7fe62658 Mon Sep 17 00:00:00 2001 From: Tobi Date: Fri, 3 Feb 2023 18:31:07 +0100 Subject: [PATCH 78/84] Revert "Update ExoPlayer to 2.18.2" This commit reverts 1bb166a --- app/build.gradle | 2 +- .../player/mediasource/LoadedMediaSource.java | 63 +++++++++++++++++-- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 53b1ef04e..cb619763b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -102,7 +102,7 @@ ext { androidxWorkVersion = '2.7.1' icepickVersion = '3.2.0' - exoPlayerVersion = '2.18.2' + exoPlayerVersion = '2.18.1' googleAutoServiceVersion = '1.0.1' groupieVersion = '2.10.1' markwonVersion = '4.6.2' diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java b/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java index 817b048f2..95524cf69 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java @@ -1,21 +1,27 @@ package org.schabi.newpipe.player.mediasource; -import androidx.annotation.NonNull; - import com.google.android.exoplayer2.MediaItem; +import com.google.android.exoplayer2.Timeline; +import com.google.android.exoplayer2.source.CompositeMediaSource; +import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaSource; -import com.google.android.exoplayer2.source.WrappingMediaSource; +import com.google.android.exoplayer2.upstream.Allocator; +import com.google.android.exoplayer2.upstream.TransferListener; import org.schabi.newpipe.player.mediaitem.MediaItemTag; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -public class LoadedMediaSource extends WrappingMediaSource implements ManagedMediaSource { +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public class LoadedMediaSource extends CompositeMediaSource implements ManagedMediaSource { + private final MediaSource source; private final PlayQueueItem stream; private final MediaItem mediaItem; private final long expireTimestamp; /** - * Uses a {@link WrappingMediaSource} to wrap one child {@link MediaSource} + * Uses a {@link CompositeMediaSource} to wrap one or more child {@link MediaSource}s * containing actual media. This wrapper {@link LoadedMediaSource} holds the expiration * timestamp as a {@link ManagedMediaSource} to allow explicit playlist management under * {@link ManagedMediaSourcePlaylist}. @@ -30,7 +36,7 @@ public class LoadedMediaSource extends WrappingMediaSource implements ManagedMed @NonNull final MediaItemTag tag, @NonNull final PlayQueueItem stream, final long expireTimestamp) { - super(source); + this.source = source; this.stream = stream; this.expireTimestamp = expireTimestamp; @@ -45,6 +51,51 @@ public class LoadedMediaSource extends WrappingMediaSource implements ManagedMed return System.currentTimeMillis() >= expireTimestamp; } + /** + * Delegates the preparation of child {@link MediaSource}s to the + * {@link CompositeMediaSource} wrapper. Since all {@link LoadedMediaSource}s use only + * a single child media, the child id of 0 is always used (sonar doesn't like null as id here). + * + * @param mediaTransferListener A data transfer listener that will be registered by the + * {@link CompositeMediaSource} for child source preparation. + */ + @Override + protected void prepareSourceInternal(@Nullable final TransferListener mediaTransferListener) { + super.prepareSourceInternal(mediaTransferListener); + prepareChildSource(0, source); + } + + /** + * When any child {@link MediaSource} is prepared, the refreshed {@link Timeline} can + * be listened to here. But since {@link LoadedMediaSource} has only a single child source, + * this method is called only once until {@link #releaseSourceInternal()} is called. + *

+ * On refresh, the {@link CompositeMediaSource} delegate will be notified with the + * new {@link Timeline}, otherwise {@link #createPeriod(MediaPeriodId, Allocator, long)} + * will not be called and playback may be stalled. + * + * @param id The unique id used to prepare the child source. + * @param mediaSource The child source whose source info has been refreshed. + * @param timeline The new timeline of the child source. + */ + @Override + protected void onChildSourceInfoRefreshed(final Integer id, + final MediaSource mediaSource, + final Timeline timeline) { + refreshSourceInfo(timeline); + } + + @Override + public MediaPeriod createPeriod(final MediaPeriodId id, final Allocator allocator, + final long startPositionUs) { + return source.createPeriod(id, allocator, startPositionUs); + } + + @Override + public void releasePeriod(final MediaPeriod mediaPeriod) { + source.releasePeriod(mediaPeriod); + } + @NonNull @Override public MediaItem getMediaItem() { From 1db1a0058106af6b4b2c7e850a370c32f899e019 Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 20 Jan 2023 18:39:16 +0100 Subject: [PATCH 79/84] Add snippet to ensure baseline.profm file is sorted Thanks to obfusk, see https://issuetracker.google.com/issues/231837768 and #6486 --- app/build.gradle | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index 53b1ef04e..69484304c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,3 +1,7 @@ +import com.android.tools.profgen.ArtProfileKt +import com.android.tools.profgen.ArtProfileSerializer +import com.android.tools.profgen.DexFile + plugins { id "com.android.application" id "kotlin-android" @@ -308,3 +312,24 @@ static String getGitWorkingBranch() { return "" } } + +project.afterEvaluate { + tasks.compileReleaseArtProfile.doLast { + outputs.files.each { file -> + if (file.toString().endsWith(".profm")) { + println("Sorting ${file} ...") + def version = ArtProfileSerializer.valueOf("METADATA_0_0_2") + def profile = ArtProfileKt.ArtProfile(file) + def keys = new ArrayList(profile.profileData.keySet()) + def sortedData = new LinkedHashMap() + Collections.sort keys, new DexFile.Companion() + keys.each { key -> sortedData[key] = profile.profileData[key] } + new FileOutputStream(file).with { + write(version.magicBytes$profgen) + write(version.versionBytes$profgen) + version.write$profgen(it, sortedData, "") + } + } + } + } +} From 812efca08e9887f763ae1ce957343cad9f2ce6df Mon Sep 17 00:00:00 2001 From: TobiGr Date: Fri, 3 Feb 2023 18:42:12 +0100 Subject: [PATCH 80/84] Update core libraray desugaring libs from 2.0.0 to 2.0.2 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 69484304c..7f51f8582 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -183,7 +183,7 @@ sonar { dependencies { /** Desugaring **/ - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.0' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2' /** NewPipe libraries **/ // You can use a local version by uncommenting a few lines in settings.gradle From 4cc653fdf1313a3998bf816059cdeb9abab187ea Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 7 Feb 2023 22:39:12 +0100 Subject: [PATCH 81/84] Fix opening links on Android 12+ --- .../external_communication/ShareUtils.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java index 332298b22..06dd3f945 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java @@ -90,19 +90,16 @@ public final class ShareUtils { // No browser set as default (doesn't work on some devices) openAppChooser(context, intent, true); } else { - if (defaultPackageName.isEmpty()) { - // No app installed to open a web url - Toast.makeText(context, R.string.no_app_to_open_intent, Toast.LENGTH_LONG).show(); - return false; - } else { - try { + try { + // will be empty on Android 12+ + if (!defaultPackageName.isEmpty()) { intent.setPackage(defaultPackageName); - context.startActivity(intent); - } catch (final ActivityNotFoundException e) { - // Not a browser but an app chooser because of OEMs changes - intent.setPackage(null); - openAppChooser(context, intent, true); } + context.startActivity(intent); + } catch (final ActivityNotFoundException e) { + // Not a browser but an app chooser because of OEMs changes + intent.setPackage(null); + openAppChooser(context, intent, true); } } From 63375627e956c039739302ab2d83a0ced8af6202 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 8 Feb 2023 22:22:48 +0100 Subject: [PATCH 82/84] Translated using Weblate (Bengali) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 21.9% (16 of 73 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 69.8% (51 of 73 strings) Translated using Weblate (Portuguese) Currently translated at 69.8% (51 of 73 strings) Translated using Weblate (Italian) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Odia) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Dutch) Currently translated at 65.7% (48 of 73 strings) Translated using Weblate (Italian) Currently translated at 100.0% (73 of 73 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 28.7% (21 of 73 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Galician) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Azerbaijani) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Italian) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Korean) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Japanese) Currently translated at 99.8% (653 of 654 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (73 of 73 strings) Translated using Weblate (Basque) Currently translated at 45.2% (33 of 73 strings) Translated using Weblate (German) Currently translated at 73.9% (54 of 73 strings) Translated using Weblate (Sardinian) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Polish) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Czech) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Greek) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Basque) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Portuguese) Currently translated at 99.8% (653 of 654 strings) Translated using Weblate (Russian) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (French) Currently translated at 99.6% (652 of 654 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (German) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 15.0% (11 of 73 strings) Translated using Weblate (German) Currently translated at 73.9% (54 of 73 strings) Translated using Weblate (Thai) Currently translated at 32.0% (209 of 652 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Azerbaijani) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Italian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 15.0% (11 of 73 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (73 of 73 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Romanian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Russian) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Polish) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 64.3% (47 of 73 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (73 of 73 strings) Translated using Weblate (Indonesian) Currently translated at 76.7% (56 of 73 strings) Translated using Weblate (Polish) Currently translated at 60.2% (44 of 73 strings) Translated using Weblate (Hindi) Currently translated at 21.9% (16 of 73 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (73 of 73 strings) Translated using Weblate (Czech) Currently translated at 100.0% (73 of 73 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (73 of 73 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 17.8% (13 of 73 strings) Translated using Weblate (Polish) Currently translated at 100.0% (652 of 652 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (652 of 652 strings) Co-authored-by: Agnieszka C Co-authored-by: Aitor Salaberria Co-authored-by: Ajeje Brazorf Co-authored-by: Allan Nordhøy Co-authored-by: Emin Tufan Çetin Co-authored-by: Eric Co-authored-by: Fjuro Co-authored-by: Florian Co-authored-by: GET100PERCENT Co-authored-by: GnuPGを使うべきだ Co-authored-by: Hoseok Seo Co-authored-by: Hosted Weblate Co-authored-by: Igor Nedoboy Co-authored-by: Igor Rückert Co-authored-by: Igor Sorocean Co-authored-by: Ihor Hordiichuk Co-authored-by: Issa1553 Co-authored-by: JY3 Co-authored-by: Jeff Huang Co-authored-by: Jonatan Nyberg Co-authored-by: Linerly Co-authored-by: Marian Hanzel Co-authored-by: Massimo Pissarello Co-authored-by: Mateus Co-authored-by: Nidi Co-authored-by: Phahim Hasan Co-authored-by: Priit Jõerüüt Co-authored-by: Ray Co-authored-by: Retrial Co-authored-by: Rex_sa Co-authored-by: S3aBreeze Co-authored-by: SC Co-authored-by: ShareASmile Co-authored-by: VfBFan Co-authored-by: Yaron Shahrabani Co-authored-by: bowornsin Co-authored-by: gallegonovato Co-authored-by: petlyh <88139840+petlyh@users.noreply.github.com> Co-authored-by: pjammo Co-authored-by: random r Co-authored-by: ssantos 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/es/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/eu/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/ 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/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/nl/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pa/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pl/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_PT/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant_HK/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar/strings.xml | 2 + app/src/main/res/values-az/strings.xml | 188 +++++++++--------- app/src/main/res/values-cs/strings.xml | 18 +- app/src/main/res/values-de/strings.xml | 2 + app/src/main/res/values-el/strings.xml | 2 + app/src/main/res/values-es/strings.xml | 2 + app/src/main/res/values-et/strings.xml | 2 + app/src/main/res/values-eu/strings.xml | 16 +- app/src/main/res/values-fr/strings.xml | 2 + app/src/main/res/values-gl/strings.xml | 2 + app/src/main/res/values-he/strings.xml | 2 + app/src/main/res/values-in/strings.xml | 2 + app/src/main/res/values-it/strings.xml | 4 +- app/src/main/res/values-ja/strings.xml | 2 + app/src/main/res/values-ko/strings.xml | 4 + app/src/main/res/values-nb-rNO/strings.xml | 76 +++---- app/src/main/res/values-nl/strings.xml | 4 +- app/src/main/res/values-or/strings.xml | 2 + app/src/main/res/values-pl/strings.xml | 8 +- app/src/main/res/values-pt-rBR/strings.xml | 2 + app/src/main/res/values-pt-rPT/strings.xml | 2 + app/src/main/res/values-pt/strings.xml | 4 +- app/src/main/res/values-ro/strings.xml | 3 + app/src/main/res/values-ru/strings.xml | 4 +- app/src/main/res/values-sc/strings.xml | 2 + app/src/main/res/values-sk/strings.xml | 10 + app/src/main/res/values-sv/strings.xml | 3 + app/src/main/res/values-th/strings.xml | 13 +- app/src/main/res/values-tr/strings.xml | 2 + app/src/main/res/values-uk/strings.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 6 +- app/src/main/res/values-zh-rHK/strings.xml | 2 + app/src/main/res/values-zh-rTW/strings.xml | 2 + .../metadata/android/bn/changelogs/68.txt | 1 + .../metadata/android/cs/changelogs/992.txt | 17 ++ .../metadata/android/de/changelogs/900.txt | 24 +-- .../metadata/android/de/changelogs/958.txt | 26 +-- .../metadata/android/de/changelogs/970.txt | 12 +- .../metadata/android/de/changelogs/975.txt | 29 +-- .../metadata/android/de/changelogs/976.txt | 16 +- .../metadata/android/de/changelogs/977.txt | 16 +- .../metadata/android/de/changelogs/980.txt | 20 +- .../metadata/android/de/changelogs/986.txt | 16 ++ .../metadata/android/de/changelogs/987.txt | 20 +- .../metadata/android/de/changelogs/990.txt | 24 +-- .../metadata/android/de/changelogs/991.txt | 22 +- .../metadata/android/de/changelogs/992.txt | 17 ++ .../metadata/android/es/changelogs/992.txt | 17 ++ .../metadata/android/eu/changelogs/992.txt | 17 ++ .../metadata/android/hi/changelogs/64.txt | 8 + .../metadata/android/hi/changelogs/65.txt | 26 +++ .../metadata/android/hi/changelogs/66.txt | 33 +++ .../metadata/android/hi/changelogs/68.txt | 31 +++ .../metadata/android/hi/changelogs/69.txt | 19 ++ .../metadata/android/hi/changelogs/70.txt | 25 +++ .../metadata/android/hi/changelogs/71.txt | 10 + .../metadata/android/hi/changelogs/730.txt | 2 + .../metadata/android/hi/changelogs/740.txt | 23 +++ .../metadata/android/hi/changelogs/750.txt | 22 ++ .../metadata/android/hi/changelogs/760.txt | 43 ++++ .../metadata/android/hi/changelogs/770.txt | 4 + .../metadata/android/hi/changelogs/780.txt | 12 ++ .../metadata/android/hi/changelogs/790.txt | 14 ++ .../metadata/android/hi/changelogs/800.txt | 27 +++ .../metadata/android/hi/changelogs/810.txt | 19 ++ .../metadata/android/hi/changelogs/820.txt | 1 + .../metadata/android/hi/changelogs/830.txt | 1 + .../metadata/android/hi/changelogs/840.txt | 22 ++ .../metadata/android/hi/changelogs/850.txt | 1 + .../metadata/android/hi/changelogs/860.txt | 7 + .../metadata/android/hi/changelogs/870.txt | 2 + .../metadata/android/hi/changelogs/900.txt | 14 ++ .../metadata/android/hi/changelogs/910.txt | 1 + .../metadata/android/hi/changelogs/920.txt | 9 + .../metadata/android/hi/changelogs/930.txt | 19 ++ .../metadata/android/hi/changelogs/940.txt | 16 ++ .../metadata/android/hi/changelogs/950.txt | 4 + .../metadata/android/hi/changelogs/951.txt | 17 ++ .../metadata/android/hi/changelogs/952.txt | 7 + .../metadata/android/hi/changelogs/954.txt | 7 +- .../metadata/android/hi/changelogs/959.txt | 4 +- .../metadata/android/hi/changelogs/963.txt | 1 + .../metadata/android/hi/changelogs/964.txt | 8 + .../metadata/android/hi/changelogs/965.txt | 6 + .../metadata/android/hi/changelogs/966.txt | 14 ++ .../metadata/android/hi/changelogs/967.txt | 1 + .../metadata/android/hi/changelogs/968.txt | 7 + .../metadata/android/hi/changelogs/969.txt | 8 + .../metadata/android/hi/changelogs/970.txt | 11 + .../metadata/android/hi/changelogs/971.txt | 3 + .../metadata/android/hi/changelogs/972.txt | 14 ++ .../metadata/android/hi/changelogs/973.txt | 4 + .../metadata/android/hi/changelogs/974.txt | 5 + .../metadata/android/hi/changelogs/975.txt | 17 ++ .../metadata/android/hi/changelogs/976.txt | 10 + .../metadata/android/hi/changelogs/977.txt | 10 + .../metadata/android/hi/changelogs/978.txt | 1 + .../metadata/android/hi/changelogs/979.txt | 2 + .../metadata/android/hi/changelogs/980.txt | 13 ++ .../metadata/android/hi/changelogs/981.txt | 2 + .../metadata/android/hi/changelogs/982.txt | 1 + .../metadata/android/hi/changelogs/983.txt | 9 + .../metadata/android/hi/changelogs/984.txt | 7 + .../metadata/android/hi/changelogs/985.txt | 1 + .../metadata/android/hi/changelogs/986.txt | 16 ++ .../metadata/android/hi/changelogs/987.txt | 12 ++ .../metadata/android/hi/changelogs/988.txt | 2 + .../metadata/android/hi/changelogs/989.txt | 3 + .../metadata/android/hi/changelogs/990.txt | 15 ++ .../metadata/android/hi/changelogs/991.txt | 14 +- .../metadata/android/hi/changelogs/992.txt | 17 ++ .../metadata/android/id/changelogs/972.txt | 14 ++ .../metadata/android/id/changelogs/973.txt | 4 + .../metadata/android/id/changelogs/992.txt | 17 ++ .../metadata/android/it/changelogs/992.txt | 17 ++ .../metadata/android/nb-NO/changelogs/992.txt | 17 ++ .../android/nb-NO/full_description.txt | 6 +- .../android/nb-NO/short_description.txt | 2 +- .../metadata/android/nl/changelogs/65.txt | 26 +++ .../metadata/android/pa/changelogs/992.txt | 15 ++ .../metadata/android/pl/changelogs/992.txt | 17 ++ .../metadata/android/pt-BR/changelogs/770.txt | 4 + .../metadata/android/pt-PT/changelogs/992.txt | 17 ++ .../metadata/android/pt/changelogs/992.txt | 17 ++ .../metadata/android/uk/changelogs/992.txt | 17 ++ .../android/zh-Hant/changelogs/992.txt | 17 ++ .../android/zh_Hant_HK/changelogs/992.txt | 17 ++ 127 files changed, 1336 insertions(+), 265 deletions(-) create mode 100644 fastlane/metadata/android/bn/changelogs/68.txt create mode 100644 fastlane/metadata/android/cs/changelogs/992.txt create mode 100644 fastlane/metadata/android/de/changelogs/986.txt create mode 100644 fastlane/metadata/android/de/changelogs/992.txt create mode 100644 fastlane/metadata/android/es/changelogs/992.txt create mode 100644 fastlane/metadata/android/eu/changelogs/992.txt create mode 100644 fastlane/metadata/android/hi/changelogs/64.txt create mode 100644 fastlane/metadata/android/hi/changelogs/65.txt create mode 100644 fastlane/metadata/android/hi/changelogs/66.txt create mode 100644 fastlane/metadata/android/hi/changelogs/68.txt create mode 100644 fastlane/metadata/android/hi/changelogs/69.txt create mode 100644 fastlane/metadata/android/hi/changelogs/70.txt create mode 100644 fastlane/metadata/android/hi/changelogs/71.txt create mode 100644 fastlane/metadata/android/hi/changelogs/730.txt create mode 100644 fastlane/metadata/android/hi/changelogs/740.txt create mode 100644 fastlane/metadata/android/hi/changelogs/750.txt create mode 100644 fastlane/metadata/android/hi/changelogs/760.txt create mode 100644 fastlane/metadata/android/hi/changelogs/770.txt create mode 100644 fastlane/metadata/android/hi/changelogs/780.txt create mode 100644 fastlane/metadata/android/hi/changelogs/790.txt create mode 100644 fastlane/metadata/android/hi/changelogs/800.txt create mode 100644 fastlane/metadata/android/hi/changelogs/810.txt create mode 100644 fastlane/metadata/android/hi/changelogs/820.txt create mode 100644 fastlane/metadata/android/hi/changelogs/830.txt create mode 100644 fastlane/metadata/android/hi/changelogs/840.txt create mode 100644 fastlane/metadata/android/hi/changelogs/850.txt create mode 100644 fastlane/metadata/android/hi/changelogs/860.txt create mode 100644 fastlane/metadata/android/hi/changelogs/870.txt create mode 100644 fastlane/metadata/android/hi/changelogs/900.txt create mode 100644 fastlane/metadata/android/hi/changelogs/910.txt create mode 100644 fastlane/metadata/android/hi/changelogs/920.txt create mode 100644 fastlane/metadata/android/hi/changelogs/930.txt create mode 100644 fastlane/metadata/android/hi/changelogs/940.txt create mode 100644 fastlane/metadata/android/hi/changelogs/950.txt create mode 100644 fastlane/metadata/android/hi/changelogs/951.txt create mode 100644 fastlane/metadata/android/hi/changelogs/952.txt create mode 100644 fastlane/metadata/android/hi/changelogs/963.txt create mode 100644 fastlane/metadata/android/hi/changelogs/964.txt create mode 100644 fastlane/metadata/android/hi/changelogs/965.txt create mode 100644 fastlane/metadata/android/hi/changelogs/966.txt create mode 100644 fastlane/metadata/android/hi/changelogs/967.txt create mode 100644 fastlane/metadata/android/hi/changelogs/968.txt create mode 100644 fastlane/metadata/android/hi/changelogs/969.txt create mode 100644 fastlane/metadata/android/hi/changelogs/970.txt create mode 100644 fastlane/metadata/android/hi/changelogs/971.txt create mode 100644 fastlane/metadata/android/hi/changelogs/972.txt create mode 100644 fastlane/metadata/android/hi/changelogs/973.txt create mode 100644 fastlane/metadata/android/hi/changelogs/974.txt create mode 100644 fastlane/metadata/android/hi/changelogs/975.txt create mode 100644 fastlane/metadata/android/hi/changelogs/976.txt create mode 100644 fastlane/metadata/android/hi/changelogs/977.txt create mode 100644 fastlane/metadata/android/hi/changelogs/978.txt create mode 100644 fastlane/metadata/android/hi/changelogs/979.txt create mode 100644 fastlane/metadata/android/hi/changelogs/980.txt create mode 100644 fastlane/metadata/android/hi/changelogs/981.txt create mode 100644 fastlane/metadata/android/hi/changelogs/982.txt create mode 100644 fastlane/metadata/android/hi/changelogs/983.txt create mode 100644 fastlane/metadata/android/hi/changelogs/984.txt create mode 100644 fastlane/metadata/android/hi/changelogs/985.txt create mode 100644 fastlane/metadata/android/hi/changelogs/986.txt create mode 100644 fastlane/metadata/android/hi/changelogs/987.txt create mode 100644 fastlane/metadata/android/hi/changelogs/988.txt create mode 100644 fastlane/metadata/android/hi/changelogs/989.txt create mode 100644 fastlane/metadata/android/hi/changelogs/990.txt create mode 100644 fastlane/metadata/android/hi/changelogs/992.txt create mode 100644 fastlane/metadata/android/id/changelogs/972.txt create mode 100644 fastlane/metadata/android/id/changelogs/973.txt create mode 100644 fastlane/metadata/android/id/changelogs/992.txt create mode 100644 fastlane/metadata/android/it/changelogs/992.txt create mode 100644 fastlane/metadata/android/nb-NO/changelogs/992.txt create mode 100644 fastlane/metadata/android/nl/changelogs/65.txt create mode 100644 fastlane/metadata/android/pa/changelogs/992.txt create mode 100644 fastlane/metadata/android/pl/changelogs/992.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/770.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/992.txt create mode 100644 fastlane/metadata/android/pt/changelogs/992.txt create mode 100644 fastlane/metadata/android/uk/changelogs/992.txt create mode 100644 fastlane/metadata/android/zh-Hant/changelogs/992.txt create mode 100644 fastlane/metadata/android/zh_Hant_HK/changelogs/992.txt diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index cbd3ade35..02c471d63 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -782,4 +782,6 @@ إلغاء تعيين الصورة المصغرة الدائمة فشل النسخ إلى الحافظة البطاقة + تمت إضافة وقت (أوقات) مكررة %d + تحتوي قوائم التشغيل رمادية اللون بالفعل على هذا العنصر. \ 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 d8d88bd6d..0cce71fb0 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -3,7 +3,7 @@ Başlamaq üçün böyüdücü güzgüyə toxun. %1$s tarixində yayımlanıb Yayım oynadıcı tapılmadı. \"VLC\" quraşdırılsın\? - Yayım oynadıcı tapılmadı (Oynatmaq üçün VLC\'ni quraşdıra bilərsiniz). + Yayım oynadıcı tapılmadı (Oynatmaq üçün VLC quraşdıra bilərsiniz). Yüklə Ləğv et Brauzerdə aç @@ -12,59 +12,59 @@ Yayım faylını endir Axtarış Tənzimləmələr - Bunu nəzərdə tuturdunuz: \"%1$s\"\? + Bunu demək istəyirdiniz: \"%1$s\"\? ilə paylaş Xarici video oynadıcı istifadə et - Bəzi qətnamələrdə səsi silir + Bəzi ayırdetmələrdə səsi silir Xarici səs oynadıcı istifadə et Abunə Ol Abunə olundu Kanal abunəliyi ləğv edildi Məlumat göstər - Abunəliklər + Abunələr Əlfəcinlənmiş Pleylistlər Yeniliklər Fon Video endirmə qovluğu Endirilmiş video fayllar burada saxlanılır - Video faylları üçün endirmə qovluğunu seç + Video fayllar üçün endirmə qovluğu seç Səs endirmə qovluğu Endirilmiş səs faylları burada saxlanılır Səs faylları üçün endirmə qovluğu seç - Defolt keyfiyyət - Daha böyük keyfiyyət seçimləri göstər + Standart ayırdetmə + Daha böyük ayırdetmələr göstər \"Kodi\" ilə Oynat Çatışmayan \"Kore\" tətbiqi yüklənilsin\? \"Kodi ilə Oynat\" seçimini göstər - Videonu Kodi media mərkəzi ilə oynatmaq üçün seçim göstər + Kodi media mərkəzindən video oynatmaq üçün seçim göstər Səs - Defolt səs formatı - Defolt video formatı + Standart səs formatı + Standart video formatı Tema İşıqlı Qaranlıq Qara - Abunəlikdən çıxın + Abunə olma Ani görüntü rejimində aç Avtomatik oynat - Endir - Fasilələrdən sonra (məsələn, telefon zəngləri) oynatmağa davam etdir + Yüklə + Fasilələr ardınca (məsələn, telefon zəngləri) oynatmağa davam etdir Oynatmanı davam etdir Baxılmış videoların saxlanılması Məlumat təmizlə - Siyahılarda oynatma mövqelərini göstər + Siyahılarda oynatma mövqe göstəricilərini göstər Siyahılardakı mövqelər Son oynatma mövqeyini qaytar Oynatmanı davam etdir Baxış tarixçəsi Axtarış sorğularını yerli olaraq saxla Axtarış tarixçəsi - Axtarış edərkən göstəriləcək təklifləri seç + Axtarış zamanı göstərmək üçün təklifləri seç Axtarış təklifləri - Oynadıcının parlaqlığını nizamlamaq üçün jestləri istifadə et - Parlaqlığı jestlə nizamlamaq - Oynadıcı səsini nizamlamaq üçün jestləri istifadə et - Səsi jestlə idarə etmək + Oynadıcı parlaqlığını nizamlamaq üçün jestlər istifadə et + Parlaqlıq jesti idarəetməsi + Oynadıcı səsini nizamlamaq üçün jestlər istifadə et + Səs səviyyəsi jesti idarəetməsi Avto-növbələ Növbəti Yayımı Avto-növbələ Üst məlumat keşi silindi @@ -73,10 +73,10 @@ Şəkil keşi silindi Şərhləri gizlətmək üçün bağla Şərhləri göstər - Aktiv oynadıcının növbəsi dəyişdiriləcək + Aktiv oynadıcı növbəsi dəyişdiriləcək Bir oynadıcıdan digərinə keçid növbənizi dəyişdirə bilər Növbəni təmizləməzdən əvvəl təsdiq üçün soruş - Sürətli qeyri-dəqiq axtarışdan istifadə et + Sürətli qeyri-dəqiq axtarış istifadə et Qeyri-dəqiq axtarış oynadıcıya azaldılmış dəqiqliklə mövqeləri daha sürətli axtarmağa imkan verir. 5, 15 və ya 25 saniyəlik axtarış bununla işləmir Sürətli irəli/geri çəkmə axtarış müddəti Heç nə @@ -89,9 +89,9 @@ İkinci fəaliyyət düyməsi Birinci fəaliyyət düyməsi Yalnız bəzi cihazlar 2K/4K videoları oynada bilir - Defolt ani pəncərə keyfiyyəti + Standart ani görüntü ayırdetməsi Əlavə Et - Ani Pəncərə + Ani Görüntü Paneli Seç Abunəliyi yeniləmək alınmadı Abunəliyi dəyişmək alınmadı @@ -102,7 +102,7 @@ Yaş həddi səbəbiylə (məsələn, 18+) uşaqlar üçün uyğun olmayan məzmunu göstər Yaş məhdudiyyətli məzmunu göstər Məzmun - Ani pəncərə rejimində oynadılır + Ani görüntü rejimində oynadılır Fonda oynadılır Yeniləmələr Sazlama @@ -111,23 +111,23 @@ Video və səs Davranış Oynadıcı - Defolt məzmun dili - Defolt məzmun ölkəsi + Cari məzmun dili + Cari məzmun ölkəsi URL\'i tanımaq olmadı. Başqa tətbiqlə açılsın\? Dəstəklənməyən URL\'i \"Növbələmək üçün basılı saxla\" tövsiyəsin göstər \"Növbəti\" və \"Bənzər\" videoları göstər - Tarixçəni, abunəlikləri, pleylistləri və tənzimləmələri ixrac edin + Tarixçəni, abunəlikləri, pleylistləri və tənzimləmələri ixrac et Cari tarixçənizi, abunəliklərinizi, pleylistlərinizi və (könüllü) tənzimləmələrinizi etibarsız edir - reCAPTCHA kukiləri təmizləndi - reCAPTCHA kukilərini təmizlə + reCAPTCHA bazaları təmizləndi + reCAPTCHA bazalarını təmizlə Məlumat bazasını ixrac et Məlumat bazasını idxal et Əsas Görünüşə Keçid - Ani Pəncərəyə Keçid + Ani Görüntüyə Keçid Fona Keçid [Naməlum] - Yeni \"NewPipe\" versiyası üçün bildirişlər + Yeni \"NewPipe\" versiyaları üçün bildirişlər Tətbiq yeniləmə bildirişi NewPipe oynadıcısı üçün bildirişlər Hamısı @@ -141,7 +141,7 @@ YouTube potensial yetkin məzmunu gizlədən \"Məhdud Rejim\" təmin edir \"PeerTube\" nümunələri Miniatürləri yüklə - Siz yığcam bildirişdə göstərilməsi üçün ən çoxu üç fəaliyyət seçə bilərsiniz! + Yığcam bildirişdə göstərmək üçün ən çoxu üç fəaliyyət seçə bilərsiniz! Həmişə yenilə Axın Yalnız qruplaşdırılmamış abunəlikləri göstər @@ -153,7 +153,7 @@ %d seçildi Abunəlik seçilməyib - Abunəlikləri seçin + Abunəlikləri seç Axın emal edilir… Axın yüklənir… Yüklənmədi: %d @@ -179,8 +179,8 @@ Xəta Axtarış tarixçəsi silindi Bütün axtarış tarixçəsi silinsin\? - Açar sözləri axtarışının tarixçəsini silir - Axtarış tarixçəsini silin + Açar sözləri axtarışı tarixçəsini silir + Axtarış tarixçəsini sil Oynatma mövqeləri silindi Bütün oynatma mövqeləri silinsin\? Bütün oynatma mövqelərini silir @@ -188,7 +188,7 @@ Baxış tarixçəsi silindi Bütün baxış tarixçəsi silinsin\? Baxış tarixçəsini təmizlə - reCAPTCHA həll edərkən NewPipe\'ın saxladığı kukiləri silin + reCAPTCHA həll edərkən NewPipe saxladığı bazaları sil %s tərəfindən yaradıldı Yaxınlaşdır Doldur @@ -198,22 +198,22 @@ Hələ ki, kanal abunəliyi yoxdur Kanal seç Kanal Səhifəsi - Defolt Köşk - Köşk Səhifəsi + Standart Köşk + Köşk Səhifə Boş Səhifə Əsas səhifədə hansı tablar göstərilir - Əsas səhifənin məzmunu + Əsas səhifə məzmunu Yeni versiya mövcud olduqda tətbiq yeniləməsini xatırlatmaq üçün bildiriş göstər Yeniləmələr - Mobil internet istifadə edərkən görüntü keyfiyyətini məhdudlaşdır + Mobil internet istifadə edərkən ayırdetməni məhdudlaşdır Limitsiz 1 element silindi. Nümunə əlavə et Sevimli \"PeerTube\" nümunələrinizi seçin - Endirilmiş faylları silin - Endirmə tarixçənizi təmizləmək və ya endirilmiş bütün faylları silmək istəyirsiniz\? + Endirilmiş faylları sil + Endirmə tarixçənizi təmizləmək və ya bütün endirilmiş faylları silmək istəyirsiniz\? Endirmə tarixçəsini təmizlə - Endirmələrə başla + Endirmələri başlat Endirmələri dayandır Haraya endiriləcəyini soruş Sizdən hər endirmənin harada saxlanılacağı soruşulacaq. @@ -241,13 +241,13 @@ Axın yeniləmə astanası Sürətli rejimi aktivləşdir Sürətli rejimi deaktiv et - Axının çox yavaş yükləndiyini düşünürsünüz\? Əgər elədirsə, sürətli yükləməni işə salmağı sınayın (tənzimləmələrdən dəyişə və ya aşağıdakı düyməni basa bilərsiniz). + Axının çox yavaş yükləndiyini düşünürsünüz\? Əgər elədirsə, sürətli yükləməni işə salmağı sınayın (tənzimləmələrdə dəyişə və ya aşağıdakı düyməni basa bilərsiniz). \n \nNewPipe axını yükləmək üçün 2 metod təklif edir: \n• Bütün abunəlik kanallarını gətirtmək, bu yavaş olsa da tamdır; \n• Ayrılmış xidmət uc nöqtəsi istifadə etmək, bu sürətlidir, amma tam deyil. \n -\nBu ikisi arasında fərq odur ki, sürətlisində, adətən elementin müddəti və növü kimi bəzi məlumatlar çatışmır (canlı video ilə adisini ayırd edə bilmir) və daha az element gətirir. +\nBu ikisi arasında fərq odur ki, sürətlisində, adətən elementin müddəti və növü kimi bəzi məlumatlar çatışmır (canlı video ilə adisini ayırd edə bilmir) və daha az elementlər gətirir. \n \nYouTube öz RSS axını ilə bu sürətli metodu təklif edən xidmətlərdən biridir. \n @@ -262,9 +262,9 @@ Xarici yaddaş əlçatan deyil Oynadılmış yayımlar tarixçəsini və oynatma mövqelərini silir Üst məlumatı göstər - Video açıqlamasını və əlavə məlumatı gizlətmək üçün bağla + Video açıqlamanı və əlavə məlumatı gizlətmək üçün bağla Açıqlamanı göstər - Bildirişi rəngləndir + Bildirişi rənglə Belə qovluq yoxdur Əsas oynadıcını tam ekranda başlat Xarici oynadıcılar bu cür linkləri dəstəkləmir @@ -281,7 +281,7 @@ Açıqlama Burada kriketlərdən başqa heç nə yoxdur Nəticə yoxdur - İlkin tənzimləmələri qaytar + Standartları qaytar Fayl köçürüldü və ya silindi Oynadıcı xətası bərpa edilir Bərpa olunmayan oynatma xətası baş verdi @@ -291,28 +291,28 @@ Səs yayımı tapılmadı Digər tətbiqlərin üzərində göstərməyə icazə ver İlkin tənzimləmələri qaytarmaq istəyirsiniz\? - Miniatürlərin yüklənməsini, dataya qənaət etmək və yaddaşdan istifadəni azaltmaq üçün söndürün. Dəyişikliklər həm yaddaşdaxili, həm də diskdə olan təsvir keşini təmizləyir + Miniatürləri yükləməyi, məlumata qənaət və yaddaş istifadəsin azaltmaq üçün söndür. Dəyişikliklər həm yaddaşdaxilində, həm də diskdə təsvir keşini təmizləyir Növbətini növbələ - Yenidən Cəhd Et + Təkrar Cəhd Et Cari oynatma yayımı bildirişini konfiqurasiya et Bildirişlər Video fayl xülasəsi bildirişi Abunəliklər üçün yeni yayımlar haqqında bildirişlər Xəta hesabatları üçün bildirişlər Fayl adı boş ola bilməz - Yadda saxlanmış tabları oxumaq mümkün olmadı, buna görə defolt tablardan istifadə edin + Saxlanmış tabları oxumaq mümkün olmadı, buna görə standart tabları istifadə et NewPipe xəta ilə qarşılaşdı, bildirmək üçün toxun - Bağışlayın, o baş verməməli idi. - Bu xətanı e-poçt vasitəsilə bildirin - GitHub\'da Hesabat Ver + Bağışla, o baş verməməli idi. + Bu xətanı e-poçt-dan bildir + GitHub\'da Məlumat Ver Zəhmət olmasa, xətanızı müzakirə edən məsələnin mövcud olub-olmadığını yoxlayın. Dublikat biletləri yaradarkən, bizdən faktiki səhvi düzəltməyə sərf edəcəyimiz vaxt alırsınız. - Hesabat Bildir + Məlumat Ver Məlumat: Nə baş verdi: Yükləyənin avatar miniatürü Bəyən Bəyənmə - Yenidən sıralamaq üçün sürüşdür + Yenidən sıralamaq üçün sürüklə min Mln Mlrd @@ -324,13 +324,13 @@ Video yoxdur Şərhlər qeyri-aktivdir Başlat - Fasilə + Dayandır Təsdiqləmə İmtina Xəta Detallar üçün toxun Zəhmət olmasa, gözləyin… - Hələ endirmə qovluğu təyin edilməyib, indi defolt endirmə qovluğunu seç + Hələ endirmə qovluğu təyin edilməyib, indi standart endirmə qovluğu seç reCAPTCHA çağırışı reCAPTCHA sorğusu göndərildi Bitdi @@ -340,15 +340,15 @@ Üçüncü Tərəf Lisenziyaları Haqqında & T-TSS Töhfə Ver - Fikirlərinizin olub-olmaması, tərcümə, dizayn dəyişiklikləri, kodun təmizlənməsi və ya real ağırlıqlı kod dəyişiklikləri və.s kömək həmişə xoşdur. Nə qədər çox edilsə, bir o qədər yaxşı olar! + Fikirlərinizin olub-olmaması, tərcümə, dizayn dəyişiklikləri, kod təmizlənməsi və ya real ağır kod dəyişiklikləri və.s kömək həmişə xoşdur. Nə qədər çox edilsə, bir o qədər yaxşı olar! İanə Et Veb sayt - Əlavə məlumat və xəbərlər üçün NewPipe Veb saytına daxil olun. - NewPipe\'ın Məxfilik Siyasəti - NewPipe layihəsi məxfiliyinizə çox ciddi yanaşır. Buna görə də, tətbiq sizin razılığınız olmadan heç bir məlumat toplamır. -\nNewPipe\'ın məxfilik siyasəti qəza hesabatı göndərdiyiniz zaman hansı məlumatların göndərildiyini və saxlanıldığını ətraflı izah edir. - Məxfilik siyasətini oxu - NewPipe\'ın Lisenziyası + Əlavə məlumat və xəbərlər üçün NewPipe Veb saytını ziyarət et. + NewPipe Məxfilik Siyasəti + NewPipe layihəsi məxfiliyinizə çox ciddi yanaşır. Nəticə etibarı ilə, tətbiq sizin razılığınız olmadan heç bir məlumat toplamır. +\nNewPipe məxfilik siyasəti xəta məlumatı göndərdiyiniz zaman hansı məlumatların göndərildiyini və saxlanıldığını ətraflı izah edir. + Məxfilik Siyasətini Oxu + NewPipe Lisenziyası Tarixçə Bu elementi axtarış tarixçəsindən silmək istəyirsiniz\? Son Oynadılan @@ -367,7 +367,7 @@ Oynatma növbəsi Detallar Kanal təfərrüatlarını göstər - Ani pəncərədə oynatmağa başla + Ani görüntüdə oynatmağa başla \"Açıq\" fəaliyyətə üstünlük verilir Fon oynadıcı Həmişə soruş @@ -403,7 +403,7 @@ \nDavam etmək istəyirsiniz\? Səssizlik zamanı sürətlə irəli Yeni yayım bildirişləri - Abunəliklərdən yeni yayımlar haqqında bildiriş göndər + Abunəliklərdən yeni yayımlar haqqında bildir Yoxlama tezliyi Tələb olunan şəbəkə bağlantısı İstənilən şəbəkə @@ -426,7 +426,7 @@ Bu məzmun hələ NewPipe tərəfindən dəstəklənmir. \n \nÜmid edirik ki, gələcək versiyada dəstəklənəcək. - Həm kilid ekranı fonu, həm də bildirişlər üçün miniatürdən istifadə et + Həm kilid ekranı fonu, həm də bildirişlər üçün miniatür istifadə et Ən Yeni Bu məzmun ölkənizdə mövcud deyil. Bu məzmun yalnız ödəniş etmiş istifadəçilər üçün əlçatandır, ona görə də NewPipe tərəfindən yayımlana və ya endirilə bilməz. @@ -468,10 +468,10 @@ Android\'in bildiriş rəngini miniatürdəki əsas rəngə uyğun fərdiləşdirməsini təmin et (qeyd edək ki, bu, bütün cihazlarda mövcud deyil) GitHub\'da Bax İanə Et - NewPipe, sizə ən yaxşı istifadəçi təcrübəsini göstərmək üçün boş vaxtlarını sərf edən könüllülər tərəfindən hazırlanmışdır. Tərtibatçılara bir fincan qəhvə içərkən NewPipe-ı daha da yaxşılaşdırmağa ianə etməklə kömək edin. + NewPipe, sizə ən yaxşı istifadəçi təcrübəsi göstərmək üçün boş vaxtlarını sərf edən könüllülər tərəfindən hazırlanmışdır. Tərtibatçılara bir fincan qəhvə içərkən NewPipe-ı daha da yaxşılaşdırmağa ianə etməklə kömək edin. Ən çox bəyənildi Növbəyə salındı - Məzmunu açarkən defolt hərəkət — %s + Məzmunu açarkən standart hərəkət — %s Ad Pleylist miniatürü kimi təyin et Yalnız Wi-Fi\'da @@ -488,7 +488,7 @@ Lisenziya Müəllifin hesabı bağlanıb. \nNewPipe gələcəkdə bu axını yükləyə bilməyəcək. -\nBu kanala abunəlikdən çıxmaq istəyirsiniz\? +\nBu kanaldan abunəliyi çıxarmaq istəyirsiniz\? Baxılan elementləri göstər Seçilmiş Çəkməcəni Bağla @@ -496,12 +496,12 @@ Video fayl xülasəsi prosesi üçün bildirişlər Miniatürü 1:1 görünüş nisbətinə kəs - Yükləmə intervalının həcmini dəyişdir (hazırda %s). Daha aşağı dəyər ilkin video yükləməni sürətləndirə bilər. Dəyişikliklər oynadıcının yenidən başladılmasını tələb edir - Yayım yaradıcısı, məzmunu və ya axtarış sorğusu haqqında əlavə məlumat olan üst məlumat qutularını gizlətmək üçün söndürün + Yükləmə intervalı həcmini dəyişdir (hazırda %s). Daha aşağı dəyər ilkin video yükləməni sürətləndirə bilər. Dəyişikliklər oynadıcını yenidən başlatmağı tələb edir + Yayım yaradıcısı, məzmunu və ya axtarış sorğusu haqqında əlavə məlumat olan üst məlumat qutularını gizlətmək üçün söndür Əlaqəli yayımı əlavə etməklə (təkrarlanmayan) sonlanacaq oynatma növbəsini davam etdir Kənar axtarış təklifləri Nümunə artıq mövcuddur - Videoları mini oynadıcıda başlatma, avtomatik fırlatma kilidlidirsə, birbaşa tam ekran rejiminə keçid. Siz hələ də tam ekrandan çıxmaqla mini oynadıcıya daxil ola bilərsiniz + Videoları kiçik oynadıcıda başlatma, avtomatik fırlatma kilidlidirsə, birbaşa tam ekran rejiminə keçid. Siz hələ də tam ekrandan çıxmaqla mini oynadıcıya daxil ola bilərsiniz 100+ video ∞ video Şərhlər yoxdur @@ -532,7 +532,7 @@ Etiketlər Planşet rejimi Bağla - Müəllifə ürəkləndi + Müəllifdən ürəkləndi Veb saytı aç %s baxış @@ -550,11 +550,11 @@ Endirmə tamamlandı %s endirmə tamamlandı - Defolt ExoPlayer + Standart ExoPlayer Mövcud olduqda xüsusi axından al Baxılmış videolar silinsin\? İzləniləni sil - Sistem qovluğu seçicisini (SAF) istifadə edin + Sistem qovluğu seçicisini (SAF) istifadə et Bağlantı fasiləsi Cihazda yer qalmayıb Fayl üzərində işləyərkən NewPipe bağlandı @@ -582,7 +582,7 @@ İdxal edilir… Pleylistə salındı Səsi bağla - Ani pəncərə oynadıcı + Ani görüntü oynadıcı Çəkməcəni Aç Növbələşdirmək üçün basılı tut Sil @@ -590,7 +590,7 @@ © %1$s, %2$s tərəfindən %3$s altında Bu faylı oynatmaq üçün heç bir tətbiq quraşdırılmayıb Endirmə - Bu icazə, ani pəncərə rejimində + Bu icazə, ani görüntü rejimində \naçmaq üçün lazımdır Buferə kopyalandı Parçalar @@ -608,22 +608,22 @@ Nümunə URL\'sini daxil et Nümunəni doğrulamaq mümkün olmadı %s-də bəyəndiyiniz nümunələri tapın - Video \"Təfsilatlar:\"səhifəsində fon və ya ani pəncərə düyməsini basarkən ipucu göstər - Oynadıcı altyazı mətn miqyasını və arxa fon üslublarını dəyişdirin. Effektiv olması üçün tətbiqi yenidən başlatmaq tələb olunur + Video \"Təfsilatlar:\"səhifəsində fon və ya ani görüntü düyməsin basarkən ipucu göstər + Oynadıcı altyazı mətn miqyasını və arxa fon üslublarını dəyişdir. Effektiv olması üçün tətbiqi yenidən başlatmaq tələb olunur Xəta baş verdi: %1$s Fayl mövcud deyil, yaxud oxumaq və ya yazmaq icazəsi yoxdur Veb saytı təhlil etmək alınmadı Ucalıq Radio \"Oynadıcını çökdür\" Göstər - Oynadıcıdan istifadə edərkən çökdürmə seçimini göstər + Oynadıcını istifadə edərkən çökdürmə seçimini göstər Xəta balonu göstər Xəta bildirişi yarat - Burdan idxal edin - Bura ixrac edin + Burdan idxal et + Bura ixrac et Faylı idxal et Abunəlikləri idxal etmək mümkün olmadı - Avropa Ümumi Məlumat Mühafizəsi Qaydasına (GDPR) riayət etmək üçün diqqətinizi NewPipe\'ın məxfilik siyasətinə cəlb edirik. Zəhmət olmasa, diqqətlə oxuyun. Xəta hesabatını bizə göndərmək üçün onu qəbul etməlisiniz. + Avropa Ümumi Məlumat Mühafizəsi Qaydasına (GDPR) riayət etmək üçün diqqətinizi NewPipe məxfilik siyasətinə cəlb edirik. Zəhmət olmasa, diqqətlə oxuyun. Xəta hesabatın bizə göndərmək üçün qəbul etməlisiniz. Bu adda fayl artıq mövcuddur Bu adla gözlənilən bir endirmə var Təyinat qovluğu yaradıla bilməz @@ -643,7 +643,7 @@ Dil İctimai Abunəçi sayı əlçatan deyil - Lisenziyanı oxuyun + Lisenziyanı Oxu Tarixçə Hərflər və rəqəmlər Oynadıcını çökdür @@ -651,18 +651,18 @@ Oynadıcı bildirişi Yeni yayımlar Xəta hesabatı bildirişi - Video URL\'i imzasının şifrəsi qırılmadı - Endirmək üçün heç bir yayım yoxdur - Xəta baş verdi, bildirişə baxın + Video URL\'i imzası şifrəsi qırılmadı + Endirmək üçün yayım mövcud deyil + Xəta baş verdi, bildirişi gör Şərhiniz (İngiliscə): Video oynat, müddət: - Zəhmət olmasa, daha sonra tənzimləmələrdə endirmə qovluğunu təyin et + Zəhmət olmasa, endirmə qovluğunu daha sonra tənzimləmələrdə təyin et NewPipe Endirilir Hash hesablanır Fayl adlarında icazə verilən simvollar NewPipe Haqqında Lisenziyalar - NewPipe müəllif hüquqlu sərbəst tətbiqdir: Siz onu istədiyiniz zaman istifadə edə, öyrənə, paylaşa və təkmilləşdirə bilərsiniz. Xüsusilə, siz Lisenziyanın 3-cü versiyası və ya (seçiminizə görə) hər hansı sonrakı versiyada Azad Proqram Təminatı Fondu tərəfindən dərc edilən GNU Ümumi İctimai Lisenziyanın şərtlərinə uyğun olaraq onu yenidən paylaya və/yaxud dəyişdirə bilərsiniz. + NewPipe müəllif hüquqlu sərbəst tətbiqdir: Siz onu istədiyiniz zaman istifadə edə, öyrənə, paylaşa və təkmilləşdirə bilərsiniz. Xüsusilə, siz Lisenziyanın 3-cü versiyası və ya (seçiminizə görə) hər hansı sonrakı versiyada Azad Proqram Təminatı Fondu tərəfindən dərc edilən GNU Ümumi İctimai Lisenziya şərtlərinə uyğun olaraq onu yenidən paylaya və/yaxud dəyişdirə bilərsiniz. İxrac edildi Elementləri silmək üçün sürüşdür Hələ,əlfəcinlənmiş pleylistlər yoxdur @@ -705,7 +705,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ə keçidlə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ı bildiriş fəaliyyətini hər birinin üzərinə toxunaraq redaktə edin. Sağdakı təsdiq qutularından istifadə edərək yığcam bildirişdə göstərilməsi üçün onların üçə qədərini seç + 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ç Belə fayl/məzmun mənbəyi yoxdur Seçilmiş 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 @@ -718,7 +718,7 @@ Gələcək elementləri göstər Baxılan elementləri gizlət Gələcək elementləri gizlət - Tətbiqdən istifadə etməkdə çətinlik çəkirsinizsə, ümumi suallara bu cavabların yoxlanıldığına əmin olun! + Tətbiqi istifadə etməkdə çətinlik çəkirsinizsə, ümumi suallara bu cavabları yoxladığınıza əmin olun! Tez-tez soruşulan suallar Veb Saytında bax Çeşidlə @@ -730,4 +730,6 @@ Daimi miniatürü ləğv et Kart Buferə kopyalamaq alınmadı + Boz rəngdə olan pleylistlərdə artıq bu element var. + Dublikat %d dəfə əlavə edildi \ 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 adf6601a8..abc77e66c 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -11,16 +11,16 @@ Nastavení Mysleli jste „%1$s“\? Sdílet s - Použít externí video přehrávač + Použít externí přehrávač videí Použít externí audio přehrávač - Stažené audio je uloženo zde + Sem bude ukládáno stažené audio Zvolte adresář pro stažené audio soubory Adresář pro stažené audio Výchozí rozlišení Přehrát pomocí Kodi Nainstalovat chybějící aplikaci Kore\? Adresář pro stažená videa - Stažená videa jsou uložena tady + Sem budou ukládána stažená videa Zvolte adresář pro stažená videa Zobrazit možnost „Přehrát pomocí Kodi“ Zobrazit možnost přehrání videa pomocí multimediálního centra Kodi @@ -213,7 +213,7 @@ Žádný platný soubor ZIP Upozornění: Nelze importovat všechny soubory. Tímto se anuluje vaše aktuální nastavení. - Video přehrávač + Přehrávač videa Přehrávač na pozadí Přehrávač v okně Získávám informace… @@ -298,7 +298,7 @@ Výška tónu Odpojit (může způsobit zkreslení) Ke stažení nejsou dostupné žádné streamy - Preferovaná \'otevřít\' akce + Preferovaná akce „otevření“ Výchozí chování při otevírání obsahu — %s Titulky Upravuje velikost textu titulků a styly pozadí. Změny se projeví po restartu aplikace @@ -550,7 +550,7 @@ Ukazuji výsledky pro: %s Nikdy Pouze na Wi-Fi - Zahájit playback automaticky — %s + Automaticky zahájit přehrávání — %s Přehrát frontu Nelze rozpoznat zadané URL. Otevřít pomocí jiné aplikace\? Auto-fronta @@ -668,7 +668,7 @@ Ukázat indikátory obrázků Vzdálené návrhy vyhledávání Lokální návrhy vyhledávání - Pokud je vypnuté automatické otáčení, nespouštějte video v mini přehrávači, ale přepněte se přímo do režimu celé obrazovky. Do mini přehrávače se lze i nadále dostat ukončením režimu celé obrazovky + Pokud je vypnuté automatické otáčení, nespouštět video v mini přehrávači, ale přepnout se přímo do režimu celé obrazovky. Do mini přehrávače se lze i nadále dostat ukončením režimu celé obrazovky Další ve frontě Přidat do fronty (další) Tažením položky odstraníte @@ -728,7 +728,7 @@ Zobrazit nadcházející položky Streamy, které zatím nejsou podporovány systémem stahování, nebudou zobrazeny Vyberte kvalitu pro externí přehrávače - U externích přehrávačů nejsou dostupné žádné video streamy + U externích přehrávačů nejsou k dispozici žádné videostreamy Skrýt zhlédnuté položky Skrýt nadcházející položky Často kladené dotazy @@ -743,4 +743,6 @@ Zrušení nastavení trvalého náhledu Karta Kopírování do schránky se nezdařilo + Zašedlé playlisty již obsahují tuto položku. + Duplikát přidán %dkrát \ 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 3b1959a69..2aff15046 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -730,4 +730,6 @@ Dauerhaftes Vorschaubild aufheben Kopieren in die Zwischenablage fehlgeschlagen Karte + Duplikat %d mal hinzugefügt + Die ausgegrauten Wiedergabelisten enthalten dieses Element bereits. \ 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 78d89cc59..d19b5731f 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -730,4 +730,6 @@ Κατάργηση μόνιμης μικρογραφίας Αποτυχία αντιγραφής στο πρόχειρο Κάρτα + Οι λίστες αναπαραγωγής που είναι γκριζαρισμένες περιέχουν ήδη αυτό το στοιχείο. + Προστέθηκε διπλότυπο %d φορά(ες) \ 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 9d68c28a9..1ea514868 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -746,4 +746,6 @@ Desactivar las miniaturas permanente Error al copiar al portapapeles Tarjeta + Duplicado añadido %d vez/veces + Las listas de reproducción que están en gris ya contienen este elemento. \ 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 986de133b..b9114c4d3 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -730,4 +730,6 @@ Lõikelauale kopeerimine ei õnnestunud Eemalda püsiv pisipilt Kaart + Hallina kuvatud esitusloendid juba sisaldavad seda kirjet. + Topeltkirje lisatud %d kord(a) \ No newline at end of file diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 4bbacf7b5..6b35b7316 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -108,7 +108,7 @@ NewPipe aplikazioari buruz Hirugarrengoen lizentziak © %1$s %2$s. %3$s - Honi buruz + Honi buruz eta ohiko galderak Lizentziak Androiderako streaming libre eta arina. Ikusi GitHub zerbitzarian @@ -718,4 +718,18 @@ Hautatu kanpoko erreproduzigailuen kalitatea Ezkutatu etorkizuneko elementuak Ezkutatu ikusitako elementuak + Grisez idatzitako erreprodukzio-zerrendek jada badute elementu hau. + Webgunean ikusi + Akatsa arbelera kopiatzean + Arazoren bat baduzu aplikazioa erabiltzerakoan, irakur itzazu ohiko galdera hauen erantzunak! + Betiko miniatura kendu + NewPipe-en azken bertsioa erabiltzen ari zara + Sakatu %s deskargatzeko + Kopia %d behin/aldiz gehitua + Txartela + Aukera hau Gaiarako %s aukeratua badago soilik dago erabilgarri + Ordenatu + Modu azkarra + Hiru-puntutako menutik harpidetzak inportatu edo esportatu + Maiz galdetutako galderak \ 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 a3373ca6e..77b4f09bb 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -743,4 +743,6 @@ Appuyez pour télécharger %s Échec de la copie dans le presse-papiers Cette option est disponible seulement si %s est sélectionné pour le thème + Les listes de lecture grisées contiennent déjà cet élément. + Carte \ No newline at end of file diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index a8cf01ef0..b70f6266f 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -730,4 +730,6 @@ Produciuse un erro ao copiar no portapapeis Desactivala miniatura permanente Tarxeta + As listas de reprodución que se atopan atenuadas xa conteñen este elemento. + Duplicado engadido %d vez/veces \ 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 35dc19c8c..6be8c1073 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -756,4 +756,6 @@ ביטול הגדרת תמונה ייצוגית קבועה כרטיס ההעתקה ללוח הגזירים נכשלה + רשימות הנגינה שבוטלו וסומנו באפור כבר מכילות את הפריט הזה. + הכפיל נוסף %d פעמים \ 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 c195d62e1..cc5f6dd3b 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -717,4 +717,6 @@ Batalkan penetapan gambar kecil permanen Gagal menyalin ke papan klip Kartu + Daftar putar yang bewarna abu-abu sudah berisi item ini. + Duplikat ditambahkan %d kali \ 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 bf20d2be4..ccaf93510 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -742,5 +742,7 @@ Questa opzione è disponibile solo se %s è selezionato come Tema Copia negli appunti non riuscita Schede - Disattiva la miniatura permanente + Disattiva copertina permanente + Le playlist in grigio contengono già questo elemento. + Doppione aggiunto %d volta/e \ 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 d02b56e75..e320649a3 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -716,4 +716,6 @@ 3 点メニューから登録チャンネルをインポートまたはエクスポートします カード クリップボードへのコピーに失敗しました + 灰色で表示されているプレイリストには、すでにこのアイテムが含まれています。 + %d 回重複追加されました \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 95df1e9a4..6011432b1 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -715,4 +715,8 @@ %s를 다운로드하려면 탭하세요. 영구 썸네일 설정 해제 이 옵션은 테마로 %s를 선택한 경우에만 사용할 수 있음 + 중복 추가 %d 번 + 회색으로 표시된 재생 목록에 이미 이 항목이 포함되어 있습니다. + 카드 + 클립보드 복사 실패 \ 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 15bb21633..79bfa710a 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -21,18 +21,18 @@ Velg nedlastingsmappe for lydfiler Forvalgt oppløsning Spill av med Kodi - Installer manglende Kore-program\? + Installer manglende Kore-app\? Vis \"Spill av med Kodi\"-valg Vis valg for avspilling via Kodi mediasenter Lyd Forvalgt lydformat - Drakt + Tema Mørk Lys Last ned Vis \"Neste\" og \"Lignende\" -videoer Nettadressen støttes ikke - Foretrukket innholdsspråk + Forvalgt innholdsspråk Video og lyd Utseende Spiller i bakgrunnen @@ -65,7 +65,7 @@ Nedlastinger Nedlastinger Feilrapport - Program/brukergrensesnitt krasjet + App/brukergrensesnitt krasjet Pause Slett Sjekksum @@ -77,7 +77,7 @@ Trykk for detaljer Vent… Kopiert til utklippstavle - Hva:\\nForespørsel:\\nInnholdsspråk:\\nInnholdsland:\\nProgramspråk:\\nTjeneste:\\nGMT-tid:\\nPakke:\\nVersjon:\\nOS-versjon: + Hva:\\nForespørsel:\\nInnholdsspråk:\\nInnholdsland:\\nAppspråk:\\nTjeneste:\\nGMT-tid:\\nPakke:\\nVersjon:\\nOS-versjon: Start Definer en nedlastingsmappe senere i innstillingene reCAPTCHA-oppgave @@ -241,15 +241,15 @@ Tilpass Fyll Forstørr - Bruk rask unøyaktig blafring - Feilretting + Bruk rask unøyaktig spoling + Feilsøking Fil Ingen slik mappe Ingen slik fil/innholdskilde Filen finnes ikke eller så har du ikke tilgang til å lese eller skrive til den Filnavn kan ikke være tomt En feil inntraff: %1$s - Auto-generert + Autogenerert Importer Importer fra Eksporter til @@ -282,10 +282,10 @@ Slett hele søkehistorikken\? Søkehistorikken er slettet Ett element slettet. - Inget program installert for avspilling av denne filen + Ingen app installert for å spille av denne filen Undertekster Endre spillerens undertekststørrelse og bakgrunnsstiler. Krever omstart av appen for å tre i kraft - NewPipe er copyleft-fri programvare: Du kan bruke, studere og forbedre den etter egen vilje. Spesifikt kan du redistribuere og/eller modifisere den i henhold til vilkårene gitt i GNU General Public-lisensen, som er publisert av Free Software Foundation, enten versjon 3 av lisensen, eller (etter eget ønske) enhver senere versjon. + NewPipe er copyleft fri programvare: Du kan bruke, studere og forbedre den etter egen vilje. Spesifikt kan du redistribuere og/eller modifisere den i henhold til vilkårene gitt i GNU General Public-lisensen, som er publisert av Free Software Foundation, enten versjon 3 av lisensen, eller (etter eget ønske) enhver senere versjon. Ønsker du også å importere innstillinger? Kunne ikke importere abonnementer Kunne ikke eksportere abonnementer @@ -295,7 +295,7 @@ \n2. Logg inn når forespurt \n3. Klikk på \"All data inkludert\", så på \"Fjern merket for alle\", så på kun \"Abonnementer\", og klikk så \"OK\" \n4. Klikk på \"Neste steg\" og så på \"Opprett eksport\" -\n5. Klikk på \"Last ned\"-knappen etter den vises%1$s +\n5. Klikk på \"Last ned\"-knappen etter den vises \n6. Klikk på IMPORTER FIL under og velg den nedlastede .zip filen \n7. [Dersom .zip importen feiler] Pakk ut .csv filen (vanligvis under \"YouTube og YouTube Music/subscriptions/subscriptions.csv\"), klikk på IMPORTER FIL under og velg den utpakkede csv filen Importer en SoundCloud-profil ved å skrive enten nettadressen eller din ID: @@ -304,15 +304,15 @@ \n2. Gå til denne nettadressen: %1$s \n3. Logg inn når forespurt \n4. Kopier profil-nettadressen du ble videresendt til. - Unøyaktig blafring lar spilleren søke posisjoner raskere med redusert presisjon. Å søke i 5, 15 eller 25 sekunder fungerer ikke med dette + Unøyaktig spoling lar spilleren søke posisjoner raskere med redusert presisjon. Å søke i 5, 15 eller 25 sekunder fungerer ikke med dette Skru av for å stoppe innlasting av miniatyrbilder, noe som sparer data- og minnebruk. Endring av dette vil tømme både disk- og minne-hurtiglager Fortsett fullendt (ikke-repeterende) avspillingskø ved å legge til en relatert strøm - Minnelekkasjeoppsyn kan forårsake programmet å opptre uresponsivt under haugdumping + Overvåkning av minnelekkasjer kan forårsake at appen ikke svarer under heap dumping Rapporter feil utenfor livssyklusen Tving rapportering av uleverbare Rx-unntak utenom fragment eller aktivitetslevetid etter forkastelse Avhekt (kan forårsake forvrenging) NewPipes personvernspraksis - NewPipe-prosjektet tar ditt personvern veldig alvorlig. Derfor samler ikke programmet inn data uten ditt samtykke. + NewPipe-prosjektet tar ditt personvern veldig alvorlig. Derfor samler ikke appen inn data uten ditt samtykke. \nNewPipes personvernspraksis forklarer i detalj hvilken data som sendes og lagres når du sender en krasjrapport. Les personvernspraksis For å overholde EUs personvernforordning (GDPR), vil vi rette oppmerksomheten din mot NewPipe sin personvernerklæring. Vennligst les den nøye. @@ -321,8 +321,8 @@ Avslå Ubegrenset Begrens oppløsning når mobildata brukes - Minimer ved programbytte - Handling ved bytting til annet program fra hovedspiller — %s + Minimer ved appbytte + Handling ved bytting til annen app fra hovedspiller — %s Ingen Minimer til bakgrunnsspiller Minimer til oppsprettsspiller @@ -342,7 +342,7 @@ Oppdateringer Hendelser Fil slettet - Programoppgraderingsmerknad + Varsel om appoppdatering Merknader for nye NewPipe-versjoner Ekstern lagring utilgjengelig Nedlasting til eksternt SD-kort er ikke mulig. Tilbakestill plassering av nedlastingsmappe\? @@ -353,11 +353,11 @@ Hvilke faner vises på hovedsiden Konferanser Oppdatering - Varsle om programoppdatering når en ny versjon er tilgjengelig - Listevisningmodus + Vis varsel om appoppdatering når en ny versjon er tilgjengelig + Listevisningsmodus Liste Rutenett - Auto + Automatisk Ny NewPipe-versjon er tilgjengelig! Fullført pauset @@ -430,7 +430,7 @@ %s lytter %s lyttere - Språket vil først bli endret etter at programmet har blitt omstartet + Språket vil endres etter at appen har startet på nytt Standard kiosk PeerTube-instanser Lokal @@ -449,7 +449,7 @@ Autogenerert (fant ingen opplaster) gjenoppretter Kan ikke gjenopprette denne nedlastingen - Hurtigframoverspoling/-tilbakeblafringsvarighet + Hurtigframoverspoling/-tilbakespolingsvarighet Gi tillatelse til å vise over andre apper Programspråk Systemforvalg @@ -486,7 +486,7 @@ Ingen abonnement valgt Velg abonnementer Kanalgrupper - Skru av raskt modus + Skru av hurtigmodus Strømoppdateringsterskel Strøm Behandler strøm… @@ -505,7 +505,7 @@ Fjern sette Opprettet av %s Av %s - Slå på YouTubes \"begrensede modus\" + Slå på YouTubes \"Begrenset modus\" Aldri Kun på Wi-Fi Velg en spilleliste @@ -524,7 +524,7 @@ \n• Hent hele abonnementskanalen, noe som er tregt, men fullstendig. \n• Bruk av et dedikert tjenesteendepunkt, noe som er raskt men vanligvis ikke fullstendig. \n -\nForskjellen mellom dem er at den raske vanligvis mangler info, som elementers varighet eller type (kan ikke skjelne mellom sanntidsvideoer og normale) og det kan gi færre elementer. +\nForskjellen mellom dem er at den raske vanligvis mangler info, som elementers varighet eller type (kan ikke skille mellom direktesendinger og normale videoer) og det kan gi færre elementer. \n \nYouTube er et eksempel på en tjeneste som tilbyr denne raske metoden med sin RSS-informasjonskanal. \n @@ -537,17 +537,17 @@ Tilgjengelig i noen tjenester, det er vanligvis mye raskere, men kan gi et begrenset antall elementer, og ofte ufullstendig informasjon (f.eks. ingen varighet, elementtype, eller sanntidsstatus) Hent fra dedikert strøm når tilgjengelig Tid siden siste oppdatering før et abonnement vurderes utdatert — %s - Som følge av begrensninger i ExoPlayer er blafringsdistansen begrenset til %d sekunder + Som følge av begrensninger i ExoPlayer er blafringsdistansen kun %d sekunder Videoer som har blitt sett før og etter at de er lagt til spillelisten, vil bli fjernet. \nEr du sikker\? Dette kan ikke angres! Start avspilling automatisk — %s - Kunne ikke gjenkjenne angitt nettadresse. Åpne den med annet program\? + Kunne ikke gjenkjenne angitt nettadresse. Åpne den med et annet program\? Innholdet støttes ikke enda av NewPipe. \n \nStøtte vil forhåpentligvis komme til i en senere versjon. Spillelisteside Kanalens avatar-miniatyrbilde - Skru på raskt modus + Skru på hurtigmodus Vis kun ugrupperte abonnementer Spill kø Ingen spillelistebokmerker enda @@ -595,18 +595,18 @@ Dette er et spor fra SoundCloud Go+, ihvertfall i ditt land, så det kan ikke strømmes eller lastes ned av NewPipe. Innholdet er ikke tilgjengelig i din region. Nedlastingen har startet - Du kan velge din favorittnattdrakt nedenfor - Velg din favorittnattdrakt — %s - Automatisk (enhetsdrakt) + Du kan velge ditt favorittnattema nedenfor + Velg ditt favorittnattema — %s + Automatisk (enhetstema) Radio Framhevet Løs - Nattdrakt + Nattema Vis kanaldetaljer Skru av media-tunnelering hvis du opplever svart skjerm eller videohakking Skru av media-tunnelering Du kan nå velge tekst inne i beskrivelsen. Merk at siden kan flimre og lenker er kanskje ikke klikkbare i utvalgsmodus. - Raskt modus for informasjonskanal tilbyr ikke mer info om dette. + Hurtigmodus for informasjonskanal tilbyr ikke mer info om dette. Skaperens konto har blitt terminert. \nNewPipe vil ikke kunne laste inn denne informasjonskanalen i fremtiden. \nØnsker du å oppheve ditt abonnement på denne kanalen\? @@ -619,7 +619,7 @@ Kunne ikke laste inn informasjonskanal Fra Android 10 er kun «lagringstilgangsrammeverk» støttet Du vil bli spurt om hvor du vil lagre hver nedlastning - Forhåndsvisning av miniatyrbilde i søkefelt + Forhåndsvisning av miniatyrbilde på spolelinjen Ingen nedlastingsmappe er satt ennå, velg en standard nedlastingsmappe nå Av @@ -722,4 +722,12 @@ Sorter Velg alle Hvis du har problemer med å bruke appen, så bør du sjekke ut disse svarene fra generelle spørsmål! + Skru av vedvarende miniatyrbilde + Dette valget er kun tilgjengelig dersom %s er valgt som tema + Klarte ikke å kopiere til utklippstavlen + Trykk for å laste ned %s + Du bruker den nyeste versjonen av NewPipe + Kort + Importer eller eksporter fra trepunktsmenyen + Hurtigmodus \ 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 c5e77b29f..ab73b602f 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -727,7 +727,9 @@ U heeft de laatste versie van NewPipe Klik om %s te downloaden Kon niet naar klembord kopiëren - Deze instelling is alleen beschikbaar als %s als thema ingesteld is + Deze instelling is alleen beschikbaar als %s als Thema ingesteld is Kaart Miniatuur niet ingesteld + De afspeellijsten die grijs zijn, bevatten dit item al. + Duplicaat is %d tijd(en) toegevoegd \ 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 bc8d9fcee..31a53a6b3 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -730,4 +730,6 @@ କାର୍ଡ କ୍ଲିପବୋର୍ଡରେ କପି କରିବାରେ ବିଫଳ ସ୍ଥାୟୀ ଥମ୍ୱନେଲ୍ ସେଟ୍ କରନ୍ତୁ + ଧୂସର ହୋଇଯାଇଥିବା ପ୍ଲେଲିଷ୍ଟଗୁଡିକ ପୂର୍ବରୁ ଏହି ଆଇଟମ୍ ଧାରଣ କରିଥାଏ । + ନକଲ %d ସମୟ (ମୋଟ) ଯୋଡି ହୋଇଛି \ 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 e7ae07c85..4f5ae1448 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -422,7 +422,7 @@ Minął czas połączenia Używaj systemowego selektora folderów (SAF) Systemowy selektor folderów (SAF) umożliwia pobieranie na kartę pamięci - Usuń pozycje odtwarzania + Wyczyść pozycje odtwarzania Usuwa wszystkie pozycje odtwarzania Usunąć wszystkie pozycje odtwarzania\? Przełącz usługę, aktualnie wybrana: @@ -531,7 +531,7 @@ Artyści Albumy Piosenki - To wideo ma ograniczenia wiekowe. + To wideo jest objęte ograniczeniem wiekowym. \n \nWłącz „%1$s” w ustawieniach, jeśli chcesz je zobaczyć. Tak, i częściowo obejrzane wideo @@ -578,7 +578,7 @@ Dodano do kolejki Dodaj do kolejki Pokaż wycieki pamięci - Wyczyść ciasteczka, które NewPipe przechowuje po rozwiązaniu reCAPTCHA + Usuwa ciasteczka, które NewPipe przechowuje po rozwiązaniu reCAPTCHA Ciasteczka reCAPTCHA zostały wyczyszczone Wyczyść ciasteczka reCAPTCHA YouTube udostępnia „Tryb ograniczonego dostępu”, który ukrywa potencjalne treści dla dorosłych @@ -751,4 +751,6 @@ Usuń stałą miniaturę Nie udało się skopiować do schowka Karta + Wyszarzone playlisty zawierają już tę pozycję + Dodano duplikat %d raz(y) \ 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 fc02f29d7..f9b3ac196 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -743,4 +743,6 @@ Desativar miniatura permanente Cartão Falha ao copiar para a área de transferência + Duplicata adicionada %d vez(es) + As playlists em cinza já contêm este item. \ 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 4c2593330..80f6331e3 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -730,4 +730,6 @@ Desativar miniatura permanente 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) \ 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 c47241dcc..36528078c 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -739,8 +739,10 @@ Importar ou exportar subscrições do menu de 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 %s for selecionado para o tema + Esta opção só está disponível se estiver selecionado %s para o tema Desativar miniatura permanente 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) \ 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 2dc847daf..5eae3876f 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -740,4 +740,7 @@ Rulați cea mai recentă versiune NewPipe Atingeți pentru a descărca %s Această opțiune este disponibilă numai dacă %s este selectată ca temă + Cartelă + Nu s-a reușit copierea în clipboard + Dezactivare miniatură permanentă \ 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 50376dc03..999e9b2fe 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -661,7 +661,7 @@ Высокое качество (крупнее) Миниатюра над полосой прокрутки Автору видео понравилось это - Пометить просмотренными + Пометить проигранным Picasso: указать цветом источник изображений (красный — сеть, синий — диск, зелёный — память) Цветные метки на изображениях Серверные предложения поиска @@ -747,4 +747,6 @@ Не удалось скопировать в буфер обмена Доступно, когда Тема установлена в %s Убрать постоянную миниатюру + Дубликат добавлен %d раз(а) + Плейлисты, выделенные серым уже содержат этот объект. \ No newline at end of file diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index e649cfac2..68c6fd5c1 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -730,4 +730,6 @@ Carta Còpia in punta de billete fallida Disativa sa miniadura permanente + Sas iscalitas in colore murru tenent giai custu elementu. + Duplicadu annantu %d borta(s) \ 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 c45086ee0..f8340b47b 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -735,4 +735,14 @@ Pozrieť na webovej stránke Usporiadať Ak máte problémy s používaním aplikácie, určite si prečítajte tieto odpovede na časté otázky! + Vypnutie trvalého náhľadu + Kopírovanie do schránky zlyhalo + Zoznamy zobrazené šedou farbou už obsahujú danú položku. + Karta + Dotykom stiahnite %s + Duplikát bol pridaný %d-krát + Používate najnovšiu verziu NewPipe + Táto možnosť je dostupná len pre motív %s + Rýchly režim + Import alebo export odberov z 3-bodkovej ponuky \ 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 fbe793569..a64bbf555 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -727,4 +727,7 @@ Du använder den senaste versionen av NewPipe Tryck för att ladda ner %s Det här alternativet är endast tillgängligt om %s har valts som Tema + Inaktivera permanent miniatyrbild + Det gick inte att kopiera till urklipp + Kort \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 12effb9e2..fd7e457bf 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -15,7 +15,7 @@ ตั้งค่า หรือคุณหมายถึง \"%1$s\"\? แชร์ด้วย - Use external video player + ใช้เครื่องเล่นวีดิโอภายนอก ใช้แอปเล่นเสียงภายนอก ติดตาม ติดตามแล้ว @@ -357,7 +357,7 @@ หยุดชั่วคราวเมื่อเปลี่ยนเป็นข้อมูลมือถือ การดาวน์โหลดที่ไม่สามารถหยุดพักได้จะเริ่มต้นใหม่ ปิด - Removes audio at some resolutions + บางความละเอียดอาจไม่มีเสียง แคช metadate ถูกลบแล้ว เล่นต่อหลังจากการขัดจังหวะ เล่นต่อ @@ -369,4 +369,13 @@ เปิดด้วย ทำเครื่องหมายว่าดูแล้ว ตกลง + ปุ่มการกระทำที่สี่ + ปุ่มการกระทำแรก + ปุ่มการกระทำที่สาม + ปุ่มการกระทำที่ห้า + แก้ไขการกระทำของการแต่การแจ้งเตือนด้วยการแตะไปที่มัน เลือกสามรายการที่จะแสดงในการแจ้งเตือนในการแจ้งเตือนแบบกระทัดรัดโดยใช้ปุ่มกาเครื่องหมายทางขวา + ครอบตัดตัวอย่างภาพเป็นอัตราส่วน 1:1 + ครอบตัดตัวอย่างภาพที่แสดงในการแจ้งเตือนจากอัตราส่วน 16:9 เป็น 1:1 + ทำเครื่องเล่นพัง + ปุ่มการกระทำรอง \ 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 aeeb9bdc3..898256031 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -730,4 +730,6 @@ Kalıcı küçük resmin ayarını kaldır Kart Panoya kopyalanamadı + %d kez kopyası eklendi + Gri oynatma listeleri halihazırda bu ögeyi içeriyor. \ 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 16b48fc57..a8904c05e 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -52,7 +52,7 @@ Звіт Інформація: Що сталося: - Натисніть на «лупу», щоб почати. + Торкніться лупи, щоб розпочати. Чорна Завантаження Завантаження @@ -747,4 +747,6 @@ Прибрати постійну мініатюру Картки Не вдалося скопіювати до буфера обміну + Дублікат додано %d раз(ів) + У виділених сірим кольором добірках цей елемент уже є. \ 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 029aa8343..06ae30657 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -605,7 +605,7 @@ 支持 语言 年龄限制 - 私有性 + 私密性 许可 标签 类别 @@ -716,5 +716,7 @@ 只有在主题中选择了 %s 该选项才可用 取消设置永久缩略图 卡片 - 未能复制到剪贴板 + 无法复制到剪贴板 + 变灰的播放列表已经包含此项目。 + 重复添加了 %d 次 \ 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 dc7d589b8..42661322f 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -717,4 +717,6 @@ 色系揀做%s嘅時候至有得揀 複製唔到去剪貼簿 一張張 + 灰咗嘅播放清單,即係已經有呢個項目。 + 重複加入咗 %d 次 \ 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 ab975bff1..0b5112e18 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -717,4 +717,6 @@ 卡片 取消設定永久縮圖 無法複製到剪貼簿 + 重複新增 %d 次 + 變灰的播放清單已經包含此項目。 \ No newline at end of file diff --git a/fastlane/metadata/android/bn/changelogs/68.txt b/fastlane/metadata/android/bn/changelogs/68.txt new file mode 100644 index 000000000..8f6742e84 --- /dev/null +++ b/fastlane/metadata/android/bn/changelogs/68.txt @@ -0,0 +1 @@ +https://hosted.weblate.org/translate/newpipe/metadata/bn/?checksum=2a64aca6716bd69b diff --git a/fastlane/metadata/android/cs/changelogs/992.txt b/fastlane/metadata/android/cs/changelogs/992.txt new file mode 100644 index 000000000..b45f8f73a --- /dev/null +++ b/fastlane/metadata/android/cs/changelogs/992.txt @@ -0,0 +1,17 @@ +Novinky +• Počet odběratelů v podrobnostech videa +• Stahování z fronty +• Permanentní nastavení náhledu playlistu +• Dlouhé podržení hashtagů a odkazů +• Režim zobrazení v kartách + +Vylepšení +• Větší tlačítko k zavření minipřehrávače +• Jemnější zmenšování náhledů +• Cíl Android 13 (API 33) +• Posouvání v přehrávači jej již nezastaví + +Opravy +• Oprava překrytí s DeX/myší +• Povolení přehrávače na pozadí bez oddělených streamů zvuku +• Různé opravy YouTube a další… diff --git a/fastlane/metadata/android/de/changelogs/900.txt b/fastlane/metadata/android/de/changelogs/900.txt index a4a8a1253..58fc1e05d 100644 --- a/fastlane/metadata/android/de/changelogs/900.txt +++ b/fastlane/metadata/android/de/changelogs/900.txt @@ -1,14 +1,14 @@ -Neu -- Abonnementgruppen und sortierte Feeds -- Stummschalttaste in Playern +Neu: +• Abonnementgruppen und sortierte Feeds +• Stummschalttaste in Playern -Verbessert -- Das Öffnen von music.youtube.com und media.ccc.de Links in NewPipe erlaubt -- Zwei Einstellungen wurden von "Erscheinungsbild" zu "Inhalt" verschoben -- Ausblenden der Suchoptionen 5, 15 und 25 Sekunden, wenn die ungenaue Suche aktiviert ist +Verbessert: +• Öffnen von music.youtube.com und media.ccc.de Links in NewPipe erlaubt +• Zwei Einstellungen von „Erscheinungsbild“ zu „Inhalt“ verschoben +• Ausblenden der Suchoptionen 5, 15 und 25 Sekunden, wenn die ungenaue Suche aktiviert ist -Behoben -- einige WebM-Videos sind nicht suchbar -- Datenbank-Backup auf Android P -- Absturz beim Teilen einer heruntergeladenen Datei -- YouTube-Extraktionsprobleme, ... +Behoben: +• Einige WebM-Videos sind nicht suchbar +• Datenbank-Backup auf Android P +• Absturz beim Teilen einer heruntergeladenen Datei +• YouTube-Extraktionsprobleme und mehr … diff --git a/fastlane/metadata/android/de/changelogs/958.txt b/fastlane/metadata/android/de/changelogs/958.txt index 4b41f7d70..96b0629d2 100644 --- a/fastlane/metadata/android/de/changelogs/958.txt +++ b/fastlane/metadata/android/de/changelogs/958.txt @@ -1,15 +1,15 @@ -Neu+verbessert -•Option Miniansicht Ausblenden auf Sperrbildschirm wieder hinzugefügt -•Ziehen zum Feed aktualisieren -•Verbesserte Leistung beim Abruf lokaler Listen +Neu und verbessert: +• Option Vorschaubild auf Sperrbildschirm ausblenden wieder hinzugefügt +• Ziehen zum Feed aktualisieren +• Verbesserte Leistung beim Abruf lokaler Listen -Behoben -•Absturz, Start von NewPipe, nachdem es aus dem RAM entfernt wurde -•Absturz, Starten von NewPipe ohne Internetverbindung -•Einstellungen Helligkeits- und Lautstärkegesten -•[YT] Lange Wiedergabelisten +Behoben: +• Absturz, NewPipe-Start nachdem es aus dem RAM entfernt wurde +• Absturz, NewPipe-Start ohne Internetverbindung +• Einstellungen Helligkeits- und Lautstärkegesten +• [YT] Lange Wiedergabelisten -Sonstiges -•Codebereinigung, verschiedene interne Verbesserungen -•Aktualisierung Abhängigkeiten -•Aktualisierte Übersetzungen +Sonstiges: +• Codebereinigung, etliche interne Verbesserungen +• Abhängigkeiten aktualisiert +• Übersetzungen aktualisiert diff --git a/fastlane/metadata/android/de/changelogs/970.txt b/fastlane/metadata/android/de/changelogs/970.txt index 301ea1e3f..53f80fed1 100644 --- a/fastlane/metadata/android/de/changelogs/970.txt +++ b/fastlane/metadata/android/de/changelogs/970.txt @@ -1,11 +1,11 @@ -Neu -• Inhaltsmetadaten (Tags, Kategorien, Lizenz, ...) unter der Beschreibung anzeigen -• Option "Kanaldetails anzeigen" in remote (nicht lokalen) Wiedergabelisten hinzugefügt -• Option "Im Browser öffnen" zum Langdruck-Menü hinzugefügt +Neu: +• Inhaltsmetadaten (Tags, Kategorien, Lizenz, …) unter der Beschreibung anzeigen +• Option „Kanaldetails anzeigen“ in remote (nicht lokalen) Wiedergabelisten hinzugefügt +• Option „Im Browser öffnen“ zum Langdruck-Menü hinzugefügt -Behoben +Behoben: • Rotationsabsturz auf der Videodetailseite -• "Mit Kodi spielen"-Button im Player fordert immer auf, Kore zu installieren +• „Mit Kodi spielen“-Button im Player fordert immer auf, Kore zu installieren • Setzen von Import- und Exportpfaden wurde behoben und verbessert • [YouTube] Anzahl Kommentar-Likes korrigiert Und vieles mehr diff --git a/fastlane/metadata/android/de/changelogs/975.txt b/fastlane/metadata/android/de/changelogs/975.txt index de60202d1..7b56b45c2 100644 --- a/fastlane/metadata/android/de/changelogs/975.txt +++ b/fastlane/metadata/android/de/changelogs/975.txt @@ -1,16 +1,17 @@ -Neu -- Anzeige eines Vorschaubilds während der Suche -- Deaktivierte Kommentare erkennen -- Erlaubt das Markieren eines Feed-Elements als beobachtet -- Kommentarherzen anzeigen +Neu: +• Vorschaubild-Anzeige während der Suche +• Deaktivierte Kommentare erkennen +• Feed-Element als beobachtet markieren +• Kommentarherzen anzeigen -Verbessert -- Verbessertes Layout von Metadaten und Tags -- Dienstfarbe auf UI-Komponenten anwenden +Verbessert: +• Layout von Metadaten und Tags +• Dienstfarbe für UI-Komponenten -Behoben -- Korrektur des Vorschaubilds im Mini-Player -- Behebung der endlosen Pufferung bei doppelten Warteschlangenelementen -- Einige Player-Fixes wie Rotation und schnelleres Schließen -- Behebung von ReCAPTCHA -... +Behoben: +• Vorschaubild im Mini-Player +• Endlose Pufferung bei doppelten Warteschlangenelementen +• Einige Player-Fixes wie Rotation und schnelleres Schließen +• ReCAPTCHA lädt im Hintergrund +• Klicks bei Feed-Aktualisierung deaktivieren +• Einige Downloader-Abstürze diff --git a/fastlane/metadata/android/de/changelogs/976.txt b/fastlane/metadata/android/de/changelogs/976.txt index a70829150..296d9ab4b 100644 --- a/fastlane/metadata/android/de/changelogs/976.txt +++ b/fastlane/metadata/android/de/changelogs/976.txt @@ -1,10 +1,10 @@ -- Option zum direkten Öffnen des Players im Vollbildmodus hinzugefügt -- Auswahl der anzuzeigenden Suchvorschläge möglich -- Dunkles Theme jetzt dunkler + dunkler Splash-Screen hinzugefügt -- Verbesserte Dateiauswahl, um unerwünschte Dateien auszugrauen -- Import von YouTube-Abonnements behoben -- Das Wiederholen eines Streams erfordert ein erneutes Tippen auf die Wiedergabetaste -- Behoben: Audio-Sitzung schließen -... +• Option zum direkten Öffnen des Players im Vollbildmodus hinzugefügt +• Auswahl der anzuzeigenden Suchvorschläge möglich +• Dunkles Design nun dunkler + dunkler Splash-Screen hinzugefügt +• Verbesserte Dateiauswahl, um unerwünschte Dateien auszugrauen +• Import von YouTube-Abonnements behoben +• Das Wiederholen eines Streams erfordert ein erneutes Tippen auf die Wiedergabetaste +• Behoben: Audio-Sitzung schließen +… Änderungen finden Sie im Changelog (und im Blogbeitrag) auf dem Links-Tab unten. diff --git a/fastlane/metadata/android/de/changelogs/977.txt b/fastlane/metadata/android/de/changelogs/977.txt index 54c3d72f6..fffd6c9ad 100644 --- a/fastlane/metadata/android/de/changelogs/977.txt +++ b/fastlane/metadata/android/de/changelogs/977.txt @@ -1,9 +1,9 @@ -- Die Schaltfläche "Weiter abspielen" wurde dem Langdruckmenü hinzugefügt -- YouTube Shorts Pfadpräfix zum Absichtsfilter hinzugefügt -- Import von Einstellungen behoben -- Position der Suchleiste mit Player-Schaltflächen im Warteschlangen-Bildschirm vertauscht -- Verschiedene Korrekturen im Zusammenhang mit MediasessionManager -- Die Suchleiste wurde nach dem Ende des Videos nicht abgeschlossen -... +• Die Schaltfläche „Weiter abspielen“ wurde dem Langdruckmenü hinzugefügt +• YouTube Shorts Pfadpräfix zum Absichtsfilter hinzugefügt +• Import von Einstellungen behoben +• Position der Suchleiste mit Player-Schaltflächen im Warteschlangen-Bildschirm vertauscht +• Verschiedene Korrekturen im Zusammenhang mit MediasessionManager +• Die Suchleiste wurde nach dem Ende des Videos nicht abgeschlossen +… -Weitere Änderungen finden Sie im Changelog (und im Blogbeitrag) auf der Registerkarte Links unten. +Weitere Änderungen finden Sie im Changelog (und im Blogbeitrag) auf dem Links-Tab unten. diff --git a/fastlane/metadata/android/de/changelogs/980.txt b/fastlane/metadata/android/de/changelogs/980.txt index 3e32d136b..dc69300f3 100644 --- a/fastlane/metadata/android/de/changelogs/980.txt +++ b/fastlane/metadata/android/de/changelogs/980.txt @@ -1,13 +1,13 @@ -Neu -- Option "Zur Wiedergabeliste hinzufügen" zum Freigabemenü hinzugefügt -- Unterstützung für y2u.be und PeerTube Kurzlinks hinzugefügt +Neu: +• Option „Zur Wiedergabeliste hinzufügen“ zum Freigabemenü hinzugefügt +• Unterstützung für y2u.be- und PeerTube-Kurzlinks hinzugefügt -Verbessert -- Playback-Speed-Controls kompakter gemacht -- Feed hebt jetzt neue Elemente hervor -- "Beobachtete Artikel anzeigen" Option im Feed wird nun gespeichert +Verbessert: +• Playback-Speed-Controls kompakter gemacht +• Feed hebt jetzt neue Elemente hervor +• „Beobachtete Artikel anzeigen“-Option im Feed wird nun gespeichert -Behoben -- Extraktion von YouTube Likes und Dislikes behoben -- Automatische Wiederholung nach Rückkehr aus dem Hintergrund behoben +Behoben: +• Extraktion von YouTube Likes und Dislikes behoben +• Automatische Wiederholung nach Rückkehr aus dem Hintergrund behoben Und vieles mehr diff --git a/fastlane/metadata/android/de/changelogs/986.txt b/fastlane/metadata/android/de/changelogs/986.txt new file mode 100644 index 000000000..044365eb8 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/986.txt @@ -0,0 +1,16 @@ +Neu: +• Benachrichtigungen für neue Streams +• Nahtloser Übergang zwischen Hintergrund- und Videoplayer +• Änderung der Tonhöhe um Halbtöne +• Warteschlange des Hauptplayers an Wiedergabeliste anfügen + +Verbessert: +• Geschwindigkeit/Tonhöhenschrittgröße speichern +• Anfängliche lange Videoplayer-Pufferung verringert +• Player-UI für Android TV +• Löschbestätigung für alle heruntergeladenen Dateien + +Behoben: +• Medienschaltfläche blendet die Steuerelemente des Players nicht aus +• Rücksetzung der Wiedergabe bei Änderung des Playertyps +• Drehung des Wiedergabelisten-Dialogs diff --git a/fastlane/metadata/android/de/changelogs/987.txt b/fastlane/metadata/android/de/changelogs/987.txt index a857b1caa..f7bc9bd80 100644 --- a/fastlane/metadata/android/de/changelogs/987.txt +++ b/fastlane/metadata/android/de/changelogs/987.txt @@ -1,12 +1,12 @@ -Neu -- Unterstützung anderer Übertragungsmethoden als progressives HTTP: schnellere Ladezeit der Wiedergabe, Korrekturen für PeerTube und SoundCloud, Wiedergabe von kürzlich beendeten YouTube-Livestreams -- Schaltfläche "Hinzufügen" zum Hinzufügen einer entfernten Wiedergabeliste zu einer lokalen Wiedergabeliste -- Bildvorschau im Android 10+ Teilen-Dialog +Neu: +• Unterstützung anderer Übertragungsmethoden als progressives HTTP: schnellere Ladezeit der Wiedergabe, Korrekturen für PeerTube und SoundCloud, Wiedergabe von kürzlich beendeten YouTube-Livestreams +• Schaltfläche um entfernte Wiedergabeliste einer lokalen Wiedergabeliste hinzuzufügen +• Bildvorschau im Android 10+ Teilen-Dialog -Verbesserte -- Verbesserung des Dialogs für Wiedergabewerte -- Import/Export-Schaltflächen für Abonnements in das Drei-Punkte-Menü verschieben +Verbessert: +• Wiedergabewerte-Dialog +• Import/Export-Schaltflächen für Abonnements in das Drei-Punkte-Menü verschoben -Behoben -- Fix: Entfernen vollständig angesehener Videos aus der Wiedergabeliste -- Repariert das Thema des Freigabemenüs und den Eintrag "Zur Wiedergabeliste hinzufügen" +Behoben: +• Entfernung von vollständig angesehenen Videos aus der Wiedergabeliste +• Freigabemenü-Design und „Zur Wiedergabeliste hinzufügen“-Eintrag diff --git a/fastlane/metadata/android/de/changelogs/990.txt b/fastlane/metadata/android/de/changelogs/990.txt index f1273a211..a629c8654 100644 --- a/fastlane/metadata/android/de/changelogs/990.txt +++ b/fastlane/metadata/android/de/changelogs/990.txt @@ -1,15 +1,15 @@ -Ab sofort entfällt die Unterstützung für Android 4.4 KitKat, die Mindestversion ist Android 5 Lollipop! +Mit dieser Version entfällt die Unterstützung für Android 4.4 KitKat, die Mindestversion ist nun Android 5 Lollipop! -Neu -- Herunterladen aus dem Langdruck-Menü -- Zukünftige Videos im Feed ausblenden -... +Neu: +• Herunterladen aus dem Langdruckmenü +• Zukünftige Videos im Feed ausblenden +• Lokale Wiedergabelisten teilen -Verbessert -- Refaktorierung des Player-Codes in kleine Komponenten: weniger RAM-Verbrauch, weniger Bugs -- Verbesserter Skalierungsmodus für Miniaturansichten -... +Verbessert: +• Player-Code in kleine Komponenten refaktorisiert: weniger RAM-Verbrauch, weniger Bugs +• Skalierungsmodus für Miniaturansicht +… -Behoben -- Behebung verschiedener Probleme mit der Player-Benachrichtigung: veraltete/fehlende Medieninformationen, verzerrte Miniaturansicht -... +Behoben: +• Verschiedene Probleme mit Player-Benachrichtigung: veraltete/fehlende Medieninfos, verzerrte Miniaturansicht +… diff --git a/fastlane/metadata/android/de/changelogs/991.txt b/fastlane/metadata/android/de/changelogs/991.txt index 3a8cae2cb..d2faadae7 100644 --- a/fastlane/metadata/android/de/changelogs/991.txt +++ b/fastlane/metadata/android/de/changelogs/991.txt @@ -1,13 +1,13 @@ -Neu -- Schaltfläche "Im Browser öffnen" im Fehlerbedienfeld hinzugefügt -- Option zur Anzeige von Kanalgruppen als Liste hinzugefügt -- [YouTube] Langes Klicken auf Streamsegmente zum Teilen der Zeitstempel-URL -- Schaltfläche "Warteschlange abspielen" zum Mini-Player hinzugefügt +Neu: +• Neue Schaltfläche "Im Browser öffnen" im Fehler-Fenster +• Anzeigeoption von Kanalgruppen als Liste +• [YouTube] Langer Klick auf Streamsegmente um Zeitstempel-URL zu teilen +• Schaltfläche „Warteschlange abspielen“ im Mini-Player -Verbessert -- Isländische Lokalisierung hinzugefügt, viele Übersetzungen aktualisiert -- Viele interne Verbesserungen +Verbessert: +• Isländische Lokalisierung hinzugefügt, viele Übersetzungen aktualisiert +• Viele interne Verbesserungen -Behoben -- Mehrere Abstürze behoben -- [YouTube] Behebung von Problemen beim Laden von Kanälen... +Behoben: +• Mehrere Abstürze behoben +• [YouTube] Fehlerbehebung für Laden von Kanälen, nicht zugeordnete Feeds und Wiedergabe in einigen Ländern diff --git a/fastlane/metadata/android/de/changelogs/992.txt b/fastlane/metadata/android/de/changelogs/992.txt new file mode 100644 index 000000000..f0993d993 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/992.txt @@ -0,0 +1,17 @@ +Neu: +• Anzahl der Abonnenten in den Videodetails +• Herunterladen aus der Warteschlange +• Dauerhaftes Einstellen einer Wiedergabelisten-Miniaturansicht +• Hashtags und Links lang drücken +• Kartenansicht-Modus + +Verbessert: +• Größere Schaltfläche um Mini-Player zu schließen +• Glattere Miniaturansicht-Skalierung +• Android 13 (API 33) +• Suchen hält den Player nicht mehr an + +Behoben: +• Overlay auf DeX/Maus +• Hintergrundplayer ohne separate Audiostreams +• YouTube-Korrekturen und mehr… diff --git a/fastlane/metadata/android/es/changelogs/992.txt b/fastlane/metadata/android/es/changelogs/992.txt new file mode 100644 index 000000000..bdbd0ccba --- /dev/null +++ b/fastlane/metadata/android/es/changelogs/992.txt @@ -0,0 +1,17 @@ +Nuevo +• Número de suscriptores en los detalles del video +• Descarga desde la cola +• Establecer permanentemente una miniatura de lista de reproducción +• Hashtags y enlaces con pulsación de larga duración +• Modo de vista de tarjeta + +Mejorado +• Botón de cierre del minirreproductor más grande +• Reducción de escala de miniaturas más suave +• Objetivo Android 13 (API 33) +• Buscar ya no detiene el reproductor + +Arreglos +• Solucionar superposición en DeX/ratón +• Permitir reproductor de fondo sin transmisiones de audio separadas +• Varias correcciones de YouTube y más… diff --git a/fastlane/metadata/android/eu/changelogs/992.txt b/fastlane/metadata/android/eu/changelogs/992.txt new file mode 100644 index 000000000..5b0dd96ba --- /dev/null +++ b/fastlane/metadata/android/eu/changelogs/992.txt @@ -0,0 +1,17 @@ +Zer berri +• Harpidetza kopurua bideoen xehetasunetan +• Ilaratik deskargatu +• Erreprodukzio-zerrendei betirako izango den miniatura ezarri +• Luze sakatu traola eta estekentzako +• Txartel-bista modua + +Hobekuntzak +• Mini-erreproduzitzailearen ixteko botoi handiago bat +• Miniaturen eskala murrizketa arinagoa +• Android 13 (API 33) +• Bilaketak ez du erreprodukzioa geldiaraziko + +Konponketak +• DeX/saguaren gainezarpena konpondua +• Bigarren planoko erreprodukzioa baimendu bereizitako bi audio-jariorik gabe +• YouTube-kin zeuden arazoak konpondu eta are gehiago… diff --git a/fastlane/metadata/android/hi/changelogs/64.txt b/fastlane/metadata/android/hi/changelogs/64.txt new file mode 100644 index 000000000..65e1f16a7 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/64.txt @@ -0,0 +1,8 @@ +### सुधार +- मोबाइल डेटा का उपयोग करते समय वीडियो की गुणवत्ता को सीमित करने की क्षमता को जोड़ा गया। #1339 +- सत्र # 1442 के लिए चमक याद रखें +- कमजोर सीपीयू # 1431 के लिए डाउनलोड प्रदर्शन में सुधार +- मीडिया सत्र # 1433 के लिए समर्थन जोड़ें (काम कर रहा है) + +### फिक्स +- डाउनलोड खोलने पर क्रैश ठीक करें (रिलीज बिल्ड के लिए अब उपलब्ध है) # 1441 diff --git a/fastlane/metadata/android/hi/changelogs/65.txt b/fastlane/metadata/android/hi/changelogs/65.txt new file mode 100644 index 000000000..8570a056a --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/65.txt @@ -0,0 +1,26 @@ +### Improvements + +- Disable burgermenu icon animation #1486 +- undo delete of downloads #1472 +- Download option in share menu #1498 +- Added share option to long tap menu #1454 +- Minimize main player on exit #1354 +- Library version update and database backup fix #1510 +- ExoPlayer 2.8.2 Update #1392 + - Reworked the playback speed control dialog to support different step sizes for faster speed change. + - Added a toggle to fast-forward during silences in playback speed control. This should be helpful for audiobooks and certain music genres, and can bring a true seamless experience (and can break a song with lots of silences =\\). + - Refactored media source resolution to allow passing metadata alongside media internally in the player, rather than doing so manually. Now we have a single source of metadata and is directly available when playback starts. + - Fixed remote playlist metadata not updating when new metadata is available when playlist fragment is opened. + - Various UI fixes: #1383, background player notification controls now always white, easier to shutdown popup player through flinging +- Use new extractor with refactored architecture for multiservice + +### Fixes + +- Fix #1440 Broken Video Info Layout #1491 +- View history fix #1497 + - #1495, by updating the metadata (thumbnail, title and video count) as soon as the user access the playlist. + - #1475, by registering a view in the database when the user starts a video on external player on detail fragment. +- Fix creen timeout in case of popup mode. #1463 (Fixed #640) +- Main video player fix #1509 + - [#1412] Fixed repeat mode causing player NPE when new intent is received while player activity is in background. + - Fixed minimizing player to popup does not destroy player when popup permission is not granted. diff --git a/fastlane/metadata/android/hi/changelogs/66.txt b/fastlane/metadata/android/hi/changelogs/66.txt new file mode 100644 index 000000000..30c20b0e8 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/66.txt @@ -0,0 +1,33 @@ +# Changelog of v0.13.7 + +### Fixed +- Fix sort filter issues of v0.13.6 + +# Changelog of v0.13.6 + +### Improvements + +- Disable burgermenu icon animation #1486 +- undo delete of downloads #1472 +- Download option in share menu #1498 +- Added share option to long tap menu #1454 +- Minimize main player on exit #1354 +- Library version update and database backup fix #1510 +- ExoPlayer 2.8.2 Update #1392 + - Reworked the playback speed control dialog to support different step sizes for faster speed change. + - Added a toggle to fast-forward during silences in playback speed control. This should be helpful for audiobooks and certain music genres, and can bring a true seamless experience (and can break a song with lots of silences =\\). + - Refactored media source resolution to allow passing metadata alongside media internally in the player, rather than doing so manually. Now we have a single source of metadata and is directly available when playback starts. + - Fixed remote playlist metadata not updating when new metadata is available when playlist fragment is opened. + - Various UI fixes: #1383, background player notification controls now always white, easier to shutdown popup player through flinging +- Use new extractor with refactored architecture for multiservice + +### Fixes + +- Fix #1440 Broken Video Info Layout #1491 +- View history fix #1497 + - #1495, by updating the metadata (thumbnail, title and video count) as soon as the user access the playlist. + - #1475, by registering a view in the database when the user starts a video on external player on detail fragment. +- Fix creen timeout in case of popup mode. #1463 (Fixed #640) +- Main video player fix #1509 + - [#1412] Fixed repeat mode causing player NPE when new intent is received while player activity is in background. + - Fixed minimizing player to popup does not destroy player when popup permission is not granted. diff --git a/fastlane/metadata/android/hi/changelogs/68.txt b/fastlane/metadata/android/hi/changelogs/68.txt new file mode 100644 index 000000000..238b1e0b1 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/68.txt @@ -0,0 +1,31 @@ +# changes of v0.14.1 + +### Fixed +- Fixed failed to decrypt video url #1659 +- Fixed description link not extract well #1657 + +# changes of v0.14.0 + +### New +- New Drawer design #1461 +- New customizable front page #1461 + +### Improvements +- Reworked Gesture controls #1604 +- New way to close the popup player #1597 + +### Fixed +- Fix error when subscription count is not available. Closes #1649. + - Show "Subscriber count not available" in those cases +- Fix NPE when a YouTube playlist is empty +- Quick fix for the kiosks in SoundCloud +- Refactor and bugfix #1623 + - Fix Cyclic search result #1562 + - Fix Seek bar not statically lay outed + - Fix YT Premium video are not blocked correctly + - Fix Videos sometimes not loading (due to DASH parsing) + - Fix links in video description + - Show warning when someone tries to download to external sdcard + - fix nothing shown exception triggers report + - thumbnail not shown in background player for android 8.1 [see here](https://github.com/TeamNewPipe/NewPipe/issues/943) +- Fix registering of broadcast receiver. Closes #1641. diff --git a/fastlane/metadata/android/hi/changelogs/69.txt b/fastlane/metadata/android/hi/changelogs/69.txt new file mode 100644 index 000000000..c8262d1b0 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/69.txt @@ -0,0 +1,19 @@ +### New +- Long-tap delete and share in subscriptions #1516 +- Tablet UI and grid list layout #1617 + +### Improvements +- store and reload the last used aspect ratio #1748 +- Enable linear layout in Downloads activity with full video names #1771 +- Delete and share subscriptions directly from within the subscriptions tab #1516 +- Enqueuing now triggers video playing if the play queue has already ended #1783 +- Separate settings for volume and brightness gestures #1644 +- Add support for Localization #1792 + +### Fixes +- Fix time parsing for . format, so NewPipe can be used in Finland +- Fix subscription count +- Add foreground service permission for API 28+ devices #1830 + +### Known Bugs +- Playback state can not be saved on Android P diff --git a/fastlane/metadata/android/hi/changelogs/70.txt b/fastlane/metadata/android/hi/changelogs/70.txt new file mode 100644 index 000000000..ad87a4409 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/70.txt @@ -0,0 +1,25 @@ +ATTENTION: This version probably is a bugfest, just like the last one. However due to the full shutdown since the 17. a broken version is better then no version. Right? ¯\_(ツ)_/¯ + +### Improvements +* downloaded files can now be opened with one click #1879 +* drop support for android 4.1 - 4.3 #1884 +* remove old player #1884 +* remove streams from current play queue by swiping them to the right #1915 +* remove auto queued stream when a new stream is enqueued manually #1878 +* Postprocessing for downloads and implement missing features #1759 by @kapodamy + * Post-processing infrastructure + * Proper error handling "infrastructure" (for downloader) + * Queue instead of multiple downloads + * Move serialized pending downloads (`.giga` files) to app data + * Implement max download retry + * Proper multi-thread download pausing + * Stop downloads when swicthing to mobile network (never works, see 2nd point) + * Save the thread count for next downloads + * A lot of incoherences fixed + +### Fixed +* Fix crash with default resolution set to best and limited mobile data resolution #1835 +* pop-up player crash fixed #1874 +* NPE when trying to open background player #1901 +* Fix for inserting new streams when auto queuing is enabled #1878 +* Fixed the decypering shuttown issue diff --git a/fastlane/metadata/android/hi/changelogs/71.txt b/fastlane/metadata/android/hi/changelogs/71.txt new file mode 100644 index 000000000..5facfc05f --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/71.txt @@ -0,0 +1,10 @@ +### Improvements +* Add app update notification for GitHub build (#1608 by @krtkush) +* Various improvements to the downloader (#1944 by @kapodamy): + * add missing white icons and use hardcored way for change the icon colors + * check if the iterator is initialized (fixes #2031) + * allow retry downloads with "post-processing failed" error in the new muxer + * new MPEG-4 muxer fixing non-synchronous video and audio streams (#2039) + +### Fixed +* YouTube live streams stop playing after a short time (#1996 by @yausername) diff --git a/fastlane/metadata/android/hi/changelogs/730.txt b/fastlane/metadata/android/hi/changelogs/730.txt new file mode 100644 index 000000000..e4f260cd2 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/730.txt @@ -0,0 +1,2 @@ +# हल किया गया +- हॉट फिक्स डिक्रिप्ट फ़ंक्शन त्रुटि फिर से। diff --git a/fastlane/metadata/android/hi/changelogs/740.txt b/fastlane/metadata/android/hi/changelogs/740.txt new file mode 100644 index 000000000..c795978a8 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/740.txt @@ -0,0 +1,23 @@ +

Improvements

+
    +
  • make links in comments clickable, increase text size
  • +
  • seek on clicking timestamp links in comments
  • +
  • show preferred tab based on recently selected state
  • +
  • add playlist to queue when long clicking on 'Background' in playlist window
  • +
  • search for shared text when it is not an URL
  • +
  • add "share at current time" button to the main video player
  • +
  • add close button to main player when video queue is finished
  • +
  • add "Play directly in Background" to longpress menu for video list items
  • +
  • improve English translations for Play/Enqueue commands
  • +
  • small performance improvements
  • +
  • remove unused files
  • +
  • update ExoPlayer to 2.9.6
  • +
  • add support for Invidious links
  • +
+

Fixed

+
    +
  • fixed scroll w/ comments and related streams disabled
  • +
  • fixed CheckForNewAppVersionTask being executed when it shouldn't
  • +
  • fixed youtube subscription import: ignore ones with invalid url and keep ones with empty title
  • +
  • fix invalid YouTube url: signature tag name is not always "signature" preventing streams from loading
  • +
diff --git a/fastlane/metadata/android/hi/changelogs/750.txt b/fastlane/metadata/android/hi/changelogs/750.txt new file mode 100644 index 000000000..39b77f7c3 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/750.txt @@ -0,0 +1,22 @@ +New +Playback resume #2288 +• Resume streams where you stopped last time +Downloader Enhancements #2149 +• Use Storage Access Framework to store downloads on external SD-cards +• New mp4 muxer +• Optionally change the download directory before starting a download +• Respect metered networks + + +Improved +• Removed gema strings #2295 +• Handle (auto)rotation changes during activity lifecycle #2444 +• Make long-press menus consistent #2368 + +Fixed +• Fixed selected subtitle track name not being shown #2394 +• Do not crash when check for app update fails (GitHub version) #2423 +• Fixed downloads stuck at 99.9% #2440 +• Update play queue metadata #2453 +• [SoundCloud] Fixed crash when loading playlists TeamNewPipe/NewPipeExtractor#170 +• [YouTube] Fixed duration can not be paresd TeamNewPipe/NewPipeExtractor#177 diff --git a/fastlane/metadata/android/hi/changelogs/760.txt b/fastlane/metadata/android/hi/changelogs/760.txt new file mode 100644 index 000000000..6e000f6d9 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/760.txt @@ -0,0 +1,43 @@ +Changes in 0.17.1 + +New +• Thai localization + + +Improved +• Add start playing here action in long-press menus for playlists again #2518 +• Add switch for SAF / legacy file picker #2521 + +Fixed +• Fix disappearing buttons in downloads view when switching apps #2487 +• Fix playback position is stored although watch history is disabled +• Fix reduced performance caused by playback position in list views #2517 +• [Extractor] Fix ReCaptchaActivity #2527, TeamNewPipe/NewPipeExtractor#186 +• [Extractor] [YouTube] Fix casual search error when playlists are in results TeamNewPipe/NewPipeExtractor#185 + + + +Changes in 0.17.0 + +New +Playback resume #2288 +• Resume streams where you stopped last time +Downloader Enhancements #2149 +• Use Storage Access Framework to store downloads on external SD-cards +• New mp4 muxer +• Optionally change the download directory before starting a download +• Respect metered networks + + +Improved +• Removed gema strings #2295 +• Handle (auto)rotation changes during activity lifecycle #2444 +• Make long-press menus consistent #2368 + +Fixed +• Fixed selected subtitle track name not being shown #2394 +• Do not crash when check for app update fails (GitHub version) #2423 +• Fixed downloads stuck at 99.9% #2440 +• Update play queue metadata #2453 +• [SoundCloud] Fixed crash when loading playlists TeamNewPipe/NewPipeExtractor#170 +• [YouTube] Fixed duration can not be paresd TeamNewPipe/NewPipeExtractor#177 diff --git a/fastlane/metadata/android/hi/changelogs/770.txt b/fastlane/metadata/android/hi/changelogs/770.txt new file mode 100644 index 000000000..c775d63fc --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/770.txt @@ -0,0 +1,4 @@ +0.17.2 में परिवर्तन + +फिक्स +• फिक्स कोई वीडियो उपलब्ध नहीं था diff --git a/fastlane/metadata/android/hi/changelogs/780.txt b/fastlane/metadata/android/hi/changelogs/780.txt new file mode 100644 index 000000000..9100d7335 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/780.txt @@ -0,0 +1,12 @@ +Changes in 0.17.3 + +Improved +• Added option to clear playback states #2550 +• Show hidden directories in the file picker #2591 +• Support URLs from `invidio.us` instances to be opened with NewPipe #2488 +• Add support for `music.youtube.com` URLs TeamNewPipe/NewPipeExtractor#194 + +Fixed +• [YouTube] Fixed 'java.lang.IllegalArgumentException #192 +• [YouTube] Fixed live streams not working TeamNewPipe/NewPipeExtractor#195 +• Fixed performance problem in android pie when downloading a stream #2592 diff --git a/fastlane/metadata/android/hi/changelogs/790.txt b/fastlane/metadata/android/hi/changelogs/790.txt new file mode 100644 index 000000000..ec77b2acb --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/790.txt @@ -0,0 +1,14 @@ +Improved +• Add more titles to improve accessibility for blind people #2655 +• Make language of download folder setting more consistent and less ambiguous #2637 + +Fixed +• Check if last byte in the block is downloaded #2646 +• Fixed scrolling in video detail fragment #2672 +• Remove double search clear box animations to one #2695 +• [SoundCloud] Fix client_id extraction #2745 + +Development +• Add missing dependencies inherited from NewPipeExtractor into NewPipe #2535 +• Migrate to AndroidX #2685 +• Update to ExoPlayer 2.10.6 #2697, #2736 diff --git a/fastlane/metadata/android/hi/changelogs/800.txt b/fastlane/metadata/android/hi/changelogs/800.txt new file mode 100644 index 000000000..332b5c994 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/800.txt @@ -0,0 +1,27 @@ +New +• PeerTube support without P2P (#2201) [Beta]: + ◦ Watch and download videos from PeerTube instances + ◦ Add instances in the settings to access the complete PeerTube world + ◦ There might be problems with SSL handshakes on Android 4.4 and 7.1 when accessing certain instances resulting in a network error. + +• Downloader (#2679): + ◦ Calculate download ETA + ◦ Download opus (webm files) as ogg + ◦ Recover expired download links to resume downloads after a long pause + +Improved +• Make the KioskFragment aware of changes in the preferred content country and improve performance of all main tabs #2742 +• Use new Localization and Downloader implementations from extractor #2713 +• Make "Default kiosk" string translatable +• Black navigation bar for black theme #2569 + +Fixed +• Fixed a bug that could not move the popup player if another finger was placed while moving the popup player #2772 +• Allow playlists missing an uploader and fix crashes related to this problem #2724, TeamNewPipe/NewPipeExtractor#219 +• Enabling TLS1.1/1.2 on Android 4.4 devices (API 19/KitKat) to fix TLS handshake with MediaCCC and some PeerTube instances #2792 +• [SoundCloud] Fixed client_id extraction TeamNewPipe/NewPipeExtractor#217 +• [SoundCloud] Fix audio stream extraction + +Development +• Update ExoPlayer to 2.10.8 #2791, #2816 +• Update Gradle to 3.5.1 and add Kotlin support #2714 diff --git a/fastlane/metadata/android/hi/changelogs/810.txt b/fastlane/metadata/android/hi/changelogs/810.txt new file mode 100644 index 000000000..c75855fd1 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/810.txt @@ -0,0 +1,19 @@ +New +• Show video thumbnail on the lock screen when playing in the background + +Improved +• Add local playlist to queue when long pressing on background / popup button +• Make main page tabs scrollable and hide when there is only a single tab +• Limit amount of notification thumbnail updates in background player +• Add dummy thumbnail for empty local playlists +• Use *.opus file extension instead of *.webm and show "opus" in format label instead of "WebM Opus" in the download dropdown +• Add button to delete downloaded files or download history in "Downloads" +• [YouTube] Add support to /c/shortened_url channel links + +Fixed +• Fixed multiple issues when sharing a video to NewPipe and downloading its streams directly +• Fixed player access out of its creation thread +• Fixed search result paging +• [YouTube] Fixed switching on null causing NPE +• [YouTube] Fixed viewing comments when opening an invidio.us url +• [SoundCloud] Updated client_id diff --git a/fastlane/metadata/android/hi/changelogs/820.txt b/fastlane/metadata/android/hi/changelogs/820.txt new file mode 100644 index 000000000..d99e5f004 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/820.txt @@ -0,0 +1 @@ +फिक्स्ड डिक्रिप्ट फ़ंक्शन नाम रेगेक्स YouTube को अनुपयोगी बना रहा। diff --git a/fastlane/metadata/android/hi/changelogs/830.txt b/fastlane/metadata/android/hi/changelogs/830.txt new file mode 100644 index 000000000..b8c338f9a --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/830.txt @@ -0,0 +1 @@ +साउंडक्लाउड समस्याओं को ठीक करने के लिए साउंडक्लाउड क्लाइंट_आईडी अपडेट किया गया। diff --git a/fastlane/metadata/android/hi/changelogs/840.txt b/fastlane/metadata/android/hi/changelogs/840.txt new file mode 100644 index 000000000..95dc80844 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/840.txt @@ -0,0 +1,22 @@ +New +• Added language selector to change the app language +• Added send to Kodi button to player collapsible menu +• Added ability to copy comments on long press + +Improved +• Fix ReCaptcha activity and correctly save obtained cookies +• Removed dot-menu in favour of drawer and hide history button when watch history is not enabled in settings +• Ask for display over other apps permission in settings correctly on Android 6 and later +• Rename local playlist by long-clicking in BookmarkFragment +• Various PeerTube improvements +• Improved several English source strings + +Fixed +• Fixed player starting again although it is paused when option "minimize on app switch" enabled and NewPipe is minimized +• Fix initial brightness value for gesture +• Fixed .srt subtitle downloads containing not all line breaks +• Fixed download to SD card failing because some Android 5 devices are not CTF compliant +• Fixed downloading on Android KitKat +• Fixed corrupt video .mp4 file being recognized as audio file +• Fixed multiple localization problems, including wrong Chinese language codes +• [YouTube] Timestamps in description are clickable again diff --git a/fastlane/metadata/android/hi/changelogs/850.txt b/fastlane/metadata/android/hi/changelogs/850.txt new file mode 100644 index 000000000..09f564614 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/850.txt @@ -0,0 +1 @@ +इस रिलीज़ में YouTube वेबसाइट संस्करण अपडेट किया गया था। पुराना वेबसाइट संस्करण मार्च में बंद होने जा रहा है और इसलिए आपको न्यूपाइप को अपग्रेड करना होगा। diff --git a/fastlane/metadata/android/hi/changelogs/860.txt b/fastlane/metadata/android/hi/changelogs/860.txt new file mode 100644 index 000000000..24a2297a7 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/860.txt @@ -0,0 +1,7 @@ +उन्नत +• सेव करें और रिस्टोर करें कि क्या पिच और टेंपो अनहुक हैं या नहीं +• प्लेयर में सपोर्ट डिस्प्ले कटआउट +• गोल दृश्य और ग्राहकों की संख्या +• कम डेटा का उपयोग करने के लिए YouTube को अनुकूलित किया गया + +इस रिलीज़ में YouTube से संबंधित 15 से अधिक बग ठीक किए गए थे। diff --git a/fastlane/metadata/android/hi/changelogs/870.txt b/fastlane/metadata/android/hi/changelogs/870.txt new file mode 100644 index 000000000..849cc317d --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/870.txt @@ -0,0 +1,2 @@ +यह एक हॉटफिक्स रिलीज़ है जो न्यूपाइप को बिना किसी बड़ी परेशानी के फिर से साउंडक्लाउड का उपयोग करने की अनुमति देता है। +साउंडक्लाउड के v2 एपीआई का उपयोग अब एक्सट्रैक्टर में किया जाता है और अमान्य क्लाइंट आईडी का पता लगाने में सुधार किया गया है। diff --git a/fastlane/metadata/android/hi/changelogs/900.txt b/fastlane/metadata/android/hi/changelogs/900.txt new file mode 100644 index 000000000..78a617e47 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/900.txt @@ -0,0 +1,14 @@ +New +• Subscription groups and sorted feeds +• Mute button in players + +Improved +• Allow opening music.youtube.com and media.ccc.de links in NewPipe +• Relocate two settings from Appearance to Content +• Hide 5, 15, 25 second seek options if inexact seek is enabled + +Fixed +• some WebM videos are not seekable +• database backup on Android P +• crash when sharing a downloaded file +• tons of YouTube extraction issue and more ... diff --git a/fastlane/metadata/android/hi/changelogs/910.txt b/fastlane/metadata/android/hi/changelogs/910.txt new file mode 100644 index 000000000..18cf51131 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/910.txt @@ -0,0 +1 @@ +फिक्स्ड डेटाबेस माइग्रेशन जो न्यूपाइप को कुछ दुर्लभ मामलों में शुरू होने से रोकता है। diff --git a/fastlane/metadata/android/hi/changelogs/920.txt b/fastlane/metadata/android/hi/changelogs/920.txt new file mode 100644 index 000000000..1484a6bd0 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/920.txt @@ -0,0 +1,9 @@ +Improved + +• Added upload date and view count on stream grid items +• Improvements for the drawer header layout + +Fixed + +• Fixed mute button causing crashes on API 19 +• Fixed downloading of long 1080p 60fps videos diff --git a/fastlane/metadata/android/hi/changelogs/930.txt b/fastlane/metadata/android/hi/changelogs/930.txt new file mode 100644 index 000000000..b23b01ea8 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/930.txt @@ -0,0 +1,19 @@ +New +• Search on YouTube Music +• Basic Android TV support + +Improved +• Added the ability to remove all watched videos from a local playlist +• Show message when content isn't supported yet instead of crashing +• Improved popup player resize with pinch gestures +• Enqueue streams on long press on background and popup buttons in channel +• Improved size handling of the drawer header title + +Fixed +• Fixed age restricted content setting not working +• Fixed certain kinds of reCAPTCHAs +• Fixed crash when opening bookmarks while playlist is `null` +• Fixed detection of network related exceptions +• Fixed visibility of group sort button in the subscriptions fragment + +and more diff --git a/fastlane/metadata/android/hi/changelogs/940.txt b/fastlane/metadata/android/hi/changelogs/940.txt new file mode 100644 index 000000000..f9530bc68 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/940.txt @@ -0,0 +1,16 @@ +New +• Add support for SoundCloud comments +• Add YouTube restricted mode setting +• Show PeerTube parent channel details + +Improved +• Show Kore button only for supported services +• Block player gestures that begin at the NavigationBar or StatusBar +• Change retry & subscribe buttons background color based on service color + +Fixed +• Fix download dialog freeze +• Open in browser button now really opens in browser +• Fix crash on opening videos and "Could not play this stream" + +and more diff --git a/fastlane/metadata/android/hi/changelogs/950.txt b/fastlane/metadata/android/hi/changelogs/950.txt new file mode 100644 index 000000000..4f47a9959 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/950.txt @@ -0,0 +1,4 @@ +यह रिलीज़ तीन छोटे सुधार लाता है: +• Android 10+ पर फिक्स्ड स्टोरेज एक्सेस +• फिक्स्ड ओपनिंग कियोस्क +• लंबे वीडियो की निश्चित अवधि पार्सिंग diff --git a/fastlane/metadata/android/hi/changelogs/951.txt b/fastlane/metadata/android/hi/changelogs/951.txt new file mode 100644 index 000000000..e933e5cbd --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/951.txt @@ -0,0 +1,17 @@ +New +• Add search for subscription picker in the feed group dialog +• Add filter to the feed group dialog to show only ungrouped subscriptions +• Add playlist tab to main page +• Fast forward/rewind in background/pop-up player queue +• Display search suggestion: did you mean & showing result for + +Improved +• Drop writing application metadata in muxed files +• Do not remove failed streams from the queue +• Update status bar color to match toolbar color + +Fixed +• Fixed audio/video desync caused by floating point cumulative errors +• [PeerTube] Handle deleted comments + +and more diff --git a/fastlane/metadata/android/hi/changelogs/952.txt b/fastlane/metadata/android/hi/changelogs/952.txt new file mode 100644 index 000000000..d228e3a2d --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/952.txt @@ -0,0 +1,7 @@ +Improved +• Auto-play is available for all services (instead of only for YouTube) + +Fixed +• Fixed related streams by supporting YouTube's new continuations +• Fixed age restricted YouTube videos +• [Android TV] Fixed lingering focus highlight overlay diff --git a/fastlane/metadata/android/hi/changelogs/954.txt b/fastlane/metadata/android/hi/changelogs/954.txt index 36536b8c7..87df3fb9c 100644 --- a/fastlane/metadata/android/hi/changelogs/954.txt +++ b/fastlane/metadata/android/hi/changelogs/954.txt @@ -1,8 +1,9 @@ • नए एप्लिकेशन वर्कफ़्लो: विस्तार पृष्ठ पर वीडियो चलाएं, प्लेयर को छोटा करने के लिए नीचे स्वाइप करें -• मीडियास्टाइल सूचनाएँ: सूचनाएँ, प्रदर्शन सुधार में अनुकूलन योग्य क्रियाएँ +• मीडियास्टाइल सूचनाएँ: सूचनाओं में अनुकूलन योग्य क्रियाएं, प्रदर्शन सुधार • डेस्कटॉप ऐप के रूप में न्यूपाइप का उपयोग करते समय मूल आकार परिवर्तन + • असमर्थित यूआरएल टोस्ट के मामले में खुले विकल्पों के साथ संवाद दिखाएं • रिमोट सुझावों के अनुपलब्धता पर अनुभव में सुधार • 720p60 (इन-ऐप प्लेयर) और 480p (पॉप-अप प्लेयर) के लिए डिफ़ॉल्ट वीडियो की गुणवत्ता वृद्धि - -• त्रुटियों में सुधार और बोहोत कुछ + +• त्रुटियों में सुधार और बहुत कुछ diff --git a/fastlane/metadata/android/hi/changelogs/959.txt b/fastlane/metadata/android/hi/changelogs/959.txt index 601c655ac..a8879fec2 100644 --- a/fastlane/metadata/android/hi/changelogs/959.txt +++ b/fastlane/metadata/android/hi/changelogs/959.txt @@ -1,5 +1,3 @@ त्रुटि रिपोर्टर खोलने के बाद क्रैश का निश्चित अंतहीन लूप। -पीयरट्यूब उदाहरणों की अद्यतन सूची जो न्यूपाइप द्वारा स्वचालित रूप से खोली जा सकती है। -अपडेट किए गए अनुवाद।त्रुटि रिपोर्टर खोलने के बाद क्रैश का निश्चित अंतहीन लूप। -पीयरट्यूब उदाहरणों की अद्यतन सूची जो न्यूपाइप द्वारा स्वचालित रूप से खोली जा सकती है। +पीरट्यूब इंस्टेंस सूची जो निऊपाईप द्वारा स्वचालित रूप से खोली जा सकती है। अपडेट किए गए अनुवाद। diff --git a/fastlane/metadata/android/hi/changelogs/963.txt b/fastlane/metadata/android/hi/changelogs/963.txt new file mode 100644 index 000000000..06ca8b0e2 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/963.txt @@ -0,0 +1 @@ +• [यूट्यूब] फिक्स्ड निश्चित चैनल निरंतरता diff --git a/fastlane/metadata/android/hi/changelogs/964.txt b/fastlane/metadata/android/hi/changelogs/964.txt new file mode 100644 index 000000000..1238eb876 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/964.txt @@ -0,0 +1,8 @@ +• Added support for chapters in player controls +• [PeerTube] Added Sepia search +• Re-added share button in video detail view and moved stream description into the tab layout +• Disable restoring brightness if brightness gesture is disabled +• Added list item to play video on kodi +• Fixed crash when no default browser is set on some devices and improve share dialogs +• Toggle play/pause with hardware space button in fullscreen player +• [media.ccc.de] Various fixes and improvements diff --git a/fastlane/metadata/android/hi/changelogs/965.txt b/fastlane/metadata/android/hi/changelogs/965.txt new file mode 100644 index 000000000..eaed8c847 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/965.txt @@ -0,0 +1,6 @@ +Fixed crash which occurred when reordering channel groups. +Fixed getting more YouTube videos from channels and playlists. +Fixed getting YouTube comments. +Added support for /watch/, /v/ and /w/ subpaths in YouTube URLs. +Fixed extraction of SoundCloud client id and geo-restricted content. +Added Northern Kurdish localization. diff --git a/fastlane/metadata/android/hi/changelogs/966.txt b/fastlane/metadata/android/hi/changelogs/966.txt new file mode 100644 index 000000000..b7fdc182f --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/966.txt @@ -0,0 +1,14 @@ +New: +• Add a new service: Bandcamp + +Improved: +• Add an option to have the app follow the device theme +• Prevent some crashes by showing an improved error panel +• Show more information on why content in unavailable +• Hardware space button triggers play/pause +• Show "Download started" toast + +Fixed: +• Fix very small thumbnail in video details while playing in the background +• Fix empty title in minimized player +• Fix last resize mode not being restored correctly diff --git a/fastlane/metadata/android/hi/changelogs/967.txt b/fastlane/metadata/android/hi/changelogs/967.txt new file mode 100644 index 000000000..ba416b621 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/967.txt @@ -0,0 +1 @@ +यूरोपीय संघ में YouTube ठीक से काम नहीं कर रहा है। यह एक नई कुकी और गोपनीयता सहमति प्रणाली के कारण हुआ था जिसके लिए न्यूपाइप को एक सहमति कुकी सेट करने की आवश्यकता होती है। diff --git a/fastlane/metadata/android/hi/changelogs/968.txt b/fastlane/metadata/android/hi/changelogs/968.txt new file mode 100644 index 000000000..3972a96c1 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/968.txt @@ -0,0 +1,7 @@ +Added channel details option to long-press menu. +Added functionality to rename Playlist Name from playlist interface. +Allow the user to pause while a video is buffering. +Polished the white theme. +Fixed overlapping fonts when using a larger font size. +Fixed no video on Formuler and Zephier devices. +Fixed various crashes. diff --git a/fastlane/metadata/android/hi/changelogs/969.txt b/fastlane/metadata/android/hi/changelogs/969.txt new file mode 100644 index 000000000..59b2488e9 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/969.txt @@ -0,0 +1,8 @@ +• Allow installation on external storage +• [Bandcamp] Added support for displaying the first three comments on a stream +• Only show 'download has started' toast when download is started +• Do not set reCaptcha cookie when there is no cookie stored +• [Player] Improve cache performance +• [Player] Fixed player not automatically playing +• Dismiss previous Snackbars when deleting downloads +• Fixed trying to delete object not in list diff --git a/fastlane/metadata/android/hi/changelogs/970.txt b/fastlane/metadata/android/hi/changelogs/970.txt new file mode 100644 index 000000000..f4ff5fe34 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/970.txt @@ -0,0 +1,11 @@ +New +• Show content metadata (tags, categories, license, ...) below the description +• Added "Show channel details" option in remote (non-local) playlists +• Added "Open in browser" option to long-press menu + +Fixed +• Fixed rotation crash on video detail page +• Fixed "Play with Kodi" button in player always prompts to install Kore +• Fixed and improved setting import and export paths +• [YouTube] Fixed comment like count +And much more diff --git a/fastlane/metadata/android/hi/changelogs/971.txt b/fastlane/metadata/android/hi/changelogs/971.txt new file mode 100644 index 000000000..48e9ddaa0 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/971.txt @@ -0,0 +1,3 @@ +हॉटफिक्स +• रिबफर के बाद प्लेबैक के लिए बफर बढ़ाएं +• प्लेयर में प्ले-क्यू आइकन पर क्लिक करने पर टैबलेट और टीवी पर क्रैश ठीक किया गया diff --git a/fastlane/metadata/android/hi/changelogs/972.txt b/fastlane/metadata/android/hi/changelogs/972.txt new file mode 100644 index 000000000..318890d60 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/972.txt @@ -0,0 +1,14 @@ +New +Recognize timestamps and hashtags in description +Added manual tablet mode setting +Added ability to hide played items in a feed + +Improved +Support Storage Access Framework properly +Better error handling of unavailable and terminated channels +The Android share sheet for Android 10+ users now shows the content title. +Updated Invidious instances and support Piped links. + +Fixed +[YouTube] Age restricted content +Prevent leaked window Exception when opening choice dialog diff --git a/fastlane/metadata/android/hi/changelogs/973.txt b/fastlane/metadata/android/hi/changelogs/973.txt new file mode 100644 index 000000000..120359a24 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/973.txt @@ -0,0 +1,4 @@ +Hotfix +• Fix thumbnails and titles being trimmed in grid layout, due to a wrong calculation of how many videos can fit in one row +• Fix download dialog disappearing without doing anything if opened from the share menu +• Update a library related to opening external activities such as the Storage Access Framework file picker diff --git a/fastlane/metadata/android/hi/changelogs/974.txt b/fastlane/metadata/android/hi/changelogs/974.txt new file mode 100644 index 000000000..e028a5e0b --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/974.txt @@ -0,0 +1,5 @@ +Hotfix +• Fix buffering issues caused by YouTube throttling +• Fix YouTube comments extraction and crashes with disabled comments +• Fix YouTube music search +• Fix PeerTube livestreams diff --git a/fastlane/metadata/android/hi/changelogs/975.txt b/fastlane/metadata/android/hi/changelogs/975.txt new file mode 100644 index 000000000..8a35a7e28 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/975.txt @@ -0,0 +1,17 @@ +New +• Show a thumbnail preview while seeking +• Detect disabled comments +• Allow marking a feed item as watched +• Show comment hearts + +Improved +• Improve metadata and tags layout +• Apply service color to UI components + +Fixed +• Fix thumbnail in mini player +• Fix endless buffering on duplicate queue items +• Some player fixes like rotation and faster closing +• Fix ReCAPTCHA remaining loaded in background +• Disable clicks while refreshing feed +• Fix some downloader crashes diff --git a/fastlane/metadata/android/hi/changelogs/976.txt b/fastlane/metadata/android/hi/changelogs/976.txt new file mode 100644 index 000000000..4f868872b --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/976.txt @@ -0,0 +1,10 @@ +• Added option to directly open player in fullscreen +• Allow choosing which types of search suggestions to show +• Dark theme now darker + dark splash screen added +• Improved file picker to gray out unwanted files +• Fixed importing YouTube subscriptions +• Replaying a stream requires on tap on the replay button again +• Fixed closing audio session +• [Android TV] Fixed long seekbar jumps when using a DPad + +To see further changes, view the changelog (and blog post) from the Links tab below. diff --git a/fastlane/metadata/android/hi/changelogs/977.txt b/fastlane/metadata/android/hi/changelogs/977.txt new file mode 100644 index 000000000..df2eb6c9e --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/977.txt @@ -0,0 +1,10 @@ +• Added a "play next" button to the long press menu +• Added YouTube shorts path prefix to intent filter +• Fixed Settings import +• Swap seekbar position with player buttons in Queue screen +• Various fixes related to MediasessionManager +• Fixed seekbar not completed after video end +• Disabled media tunneling on RealtekATV +• Expanded minimized player buttons clickable area + +To see further changes, view the changelog (and blog post) from the Links tab below. diff --git a/fastlane/metadata/android/hi/changelogs/978.txt b/fastlane/metadata/android/hi/changelogs/978.txt new file mode 100644 index 000000000..bb032f753 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/978.txt @@ -0,0 +1 @@ +एक नए न्यूपाइप संस्करण के लिए चेक को ठीक किया गया। यह चेक कभी-कभी बहुत जल्दी निष्पादित किया गया था और इसलिए ऐप क्रैश हो गया। इसे अभी ठीक किया जाना चाहिए। diff --git a/fastlane/metadata/android/hi/changelogs/979.txt b/fastlane/metadata/android/hi/changelogs/979.txt new file mode 100644 index 000000000..f6cec22ce --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/979.txt @@ -0,0 +1,2 @@ +- प्लेबैक फिर से शुरू करना +- यह सुनिश्चित करने के लिए सुधार कि सेवा जो यह निर्धारित करती है कि न्यूपाइप को नए संस्करण की जांच करनी चाहिए या नहीं, पृष्ठभूमि में शुरू नहीं हुई है diff --git a/fastlane/metadata/android/hi/changelogs/980.txt b/fastlane/metadata/android/hi/changelogs/980.txt new file mode 100644 index 000000000..bd3086c68 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/980.txt @@ -0,0 +1,13 @@ +New +• Added "Add to playlist" option to share menu +• Added support for y2u.be and PeerTube short links + +Improved +• Made Playback-Speed-Controls more compact +• Feed highlights new items now +• "Show watched items" option in the feed is now saved + +Fixed +• Fixed YouTube likes and dislikes extraction +• Fixed automatic replay after returning from the background +And much more diff --git a/fastlane/metadata/android/hi/changelogs/981.txt b/fastlane/metadata/android/hi/changelogs/981.txt new file mode 100644 index 000000000..a2c1b19b2 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/981.txt @@ -0,0 +1,2 @@ +Android 11+ पर बफ़रिंग के बाद विफल प्लेबैक रिज्यूमे को ठीक करने के लिए MediaParser समर्थन को हटा दिया गया। +प्लेबैक समस्याओं को ठीक करने के लिए Philips QM16XE पर मीडिया टनलिंग अक्षम की गई। diff --git a/fastlane/metadata/android/hi/changelogs/982.txt b/fastlane/metadata/android/hi/changelogs/982.txt new file mode 100644 index 000000000..953fcd801 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/982.txt @@ -0,0 +1 @@ +फिक्स्ड YouTube कोई स्ट्रीम नहीं चला रहा है। diff --git a/fastlane/metadata/android/hi/changelogs/983.txt b/fastlane/metadata/android/hi/changelogs/983.txt new file mode 100644 index 000000000..efbd0557c --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/983.txt @@ -0,0 +1,9 @@ +Add new double-tap-to-seek UI and behaviour +Make settings searchable +Highlight pinned comments as such +Add open-with-app support for FSFE's PeerTube instance +Add error notifications +Fix replay of first queue item on player change +Wait longer when buffering during livestreams before failing +Fix order of local search results +Fix empty item fields in play queue diff --git a/fastlane/metadata/android/hi/changelogs/984.txt b/fastlane/metadata/android/hi/changelogs/984.txt new file mode 100644 index 000000000..3b18b4665 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/984.txt @@ -0,0 +1,7 @@ +Load enough initial items in lists to fill the whole screen and to fix scrolling on tablets and TVs +Fix random crashes while scrolling through lists +Have the player fast seek overlay arc go under the system UI +Revert changes to cutouts when playing in multi window, causing the misplaced player regression on some phones +Increase compileSdk from 30 to 31 +Update error reporting library +Refactor some code in the player diff --git a/fastlane/metadata/android/hi/changelogs/985.txt b/fastlane/metadata/android/hi/changelogs/985.txt new file mode 100644 index 000000000..071ab64e3 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/985.txt @@ -0,0 +1 @@ +फिक्स्ड YouTube कोई स्ट्रीम नहीं चला रहा है diff --git a/fastlane/metadata/android/hi/changelogs/986.txt b/fastlane/metadata/android/hi/changelogs/986.txt new file mode 100644 index 000000000..49f7478e6 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/986.txt @@ -0,0 +1,16 @@ +New +• Notifications for new streams +• Seamless transition between background and video players +• Change pitch by semitones +• Append the main player queue to a playlist + +Improved +• Remember speed/pitch step size +• Mitigate initial long buffering in the video player +• Improve player UI for Android TV +• Confirm before deleting all downloaded files + +Fixed +• Fix media button not hiding player controls +• Fix playback reset on player type change +• Fix rotating the playlist dialog diff --git a/fastlane/metadata/android/hi/changelogs/987.txt b/fastlane/metadata/android/hi/changelogs/987.txt new file mode 100644 index 000000000..c3404e2a2 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/987.txt @@ -0,0 +1,12 @@ +New +• Support delivery methods other than progressive HTTP: faster playback loading time, fixes for PeerTube and SoundCloud, playback of recently-ended YouTube livestreams +• Add button to add a remote playlist to a local one +• Image preview in Android 10+ share sheet + +Improved +• Improve playback parameters dialog +• Move subscription import/export buttons to three-dot menu + +Fixed +• Fix removing fully watched videos from playlist +• Fix share menu theme and "add to playlist" entry diff --git a/fastlane/metadata/android/hi/changelogs/988.txt b/fastlane/metadata/android/hi/changelogs/988.txt new file mode 100644 index 000000000..5689958ad --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/988.txt @@ -0,0 +1,2 @@ +[यूट्यूब] किसी भी वीडियो को चलाने का प्रयास करते समय "कोई स्ट्रीम नहीं मिल सका" त्रुटि को ठीक करें +[यूट्यूब] ठीक करें "निम्न सामग्री इस ऐप पर उपलब्ध नहीं है।" अनुरोधित वीडियो के बजाय दिखाया गया संदेश diff --git a/fastlane/metadata/android/hi/changelogs/989.txt b/fastlane/metadata/android/hi/changelogs/989.txt new file mode 100644 index 000000000..d868b7fa5 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/989.txt @@ -0,0 +1,3 @@ +• [यूट्यूब] किसी भी वीडियो को चलाने का प्रयास करते समय असीमित लोडिंग को ठीक करें +• [यूट्यूब] कुछ वीडियो पर थ्रॉटलिंग ठीक करें +• jsoup लाइब्रेरी को 1.15.3 में अपग्रेड करें, जिसमें सुरक्षा समाधान शामिल है diff --git a/fastlane/metadata/android/hi/changelogs/990.txt b/fastlane/metadata/android/hi/changelogs/990.txt new file mode 100644 index 000000000..e12c20ba5 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/990.txt @@ -0,0 +1,15 @@ +This release drops support for Android 4.4 KitKat, now the minimum version is Android 5 Lollipop! + +New +• Download from long-press menu +• Hide future videos in feed +• Share local playlists + +Improved +• Refactor the player code into small components: less RAM used, less bugs +• Improve thumbnails' scale mode +• Vector-ize image placeholders + +Fixed +• Fix various issues with the player notification: outdated/missing media info, distorted thumbnail +• Fix fullscreen using 1/4 of screen diff --git a/fastlane/metadata/android/hi/changelogs/991.txt b/fastlane/metadata/android/hi/changelogs/991.txt index 46ca2ebb6..a365d5c44 100644 --- a/fastlane/metadata/android/hi/changelogs/991.txt +++ b/fastlane/metadata/android/hi/changelogs/991.txt @@ -1 +1,13 @@ -नया • त्रुटि पैनल में "ब्राउज़र में खोलें" बटन जोड़ें • चैनल समूहों को सूची के रूप में प्रदर्शित करने का विकल्प जोड़ें • [यूट्यूब] टाइमस्टैम्प यूआरएल साझा करने के लिए स्ट्रीम सेगमेंट पर लंबे समय तक क्लिक करें • मिनी प्लेयर में क्यू प्ले बटन जोड़ें उन्नत • आइसलैंडिक स्थानीयकरण जोड़ें और कई अन्य अनुवादों को अपडेट करें • कई आंतरिक सुधार हल किया गया • एकाधिक दुर्घटनाओं को ठीक करें • [यूट्यूब] कुछ देशों में लोडिंग चैनल, गैर-समर्पित फ़ीड और प्लेबैक समस्याओं को ठीक करें +नया +• त्रुटि पैनल में "ब्राउज़र में खोलें" बटन जोड़ें +• चैनल समूहों को सूची के रूप में प्रदर्शित करने का विकल्प जोड़ें +• [यूट्यूब] टाइमस्टैम्प यूआरएल साझा करने के लिए स्ट्रीम सेगमेंट पर लंबे समय तक क्लिक करें +• मिनी प्लेयर में क्यू प्ले बटन जोड़ें + +उन्नत +• आइसलैंडिक स्थानीयकरण जोड़ें और कई अन्य अनुवादों को अपडेट करें +• कई आंतरिक सुधार + +हल किया गया +• कई सारे क्रैश को ठीक करें +• [यूट्यूब] कुछ देशों में लोडिंग चैनल, गैर-समर्पित फ़ीड और प्लेबैक समस्याओं को ठीक करें diff --git a/fastlane/metadata/android/hi/changelogs/992.txt b/fastlane/metadata/android/hi/changelogs/992.txt new file mode 100644 index 000000000..d4024fd02 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/992.txt @@ -0,0 +1,17 @@ +नया +• वीडियो विवरण में सब्सक्राइबर गिनती +• कतार से डाउनलोड करें +• स्थायी रूप से एक प्लेलिस्ट थंबनेल सेट करें +• लंबे समय तक प्रेस हैशटैग और लिंक +• कार्ड दृश्य मोड + +बेहतर +• बड़ा मिनी-प्लेयर बंद बटन +• चिकना थंबनेल डाउनस्केलिंग +• लक्ष्य Android 13 (API 33) +• अब मांगने से खिलाड़ी रुक जाता है + +सही किए +• DeX/माउस पर ओवरले ठीक करें +• बिना किसी अलग ऑडियो स्ट्रीम के पृष्ठभूमि प्लेयर की अनुमति दें +• विभिन्न यूट्यूब फिक्स और अधिक… diff --git a/fastlane/metadata/android/id/changelogs/972.txt b/fastlane/metadata/android/id/changelogs/972.txt new file mode 100644 index 000000000..e6b705eeb --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/972.txt @@ -0,0 +1,14 @@ +Baru +Mengenali stempel waktu dan hashtag dalam deskripsi +Menambahkan pengaturan mode tablet manual +Menambahkan kemampuan untuk menyembunyikan item yang diputar di feed + +Ditingkatkan +Mendukung Kerangka Akses Penyimpanan dengan benar +Penanganan kesalahan yang lebih baik untuk saluran yang tidak tersedia dan dihentikan +Lembar berbagi Android untuk pengguna Android 10+ sekarang menampilkan judul konten. +Memperbarui instance Invidious dan mendukung tautan Piped. + +Diperbaiki +[YouTube] Konten yang dibatasi usia +Cegah jendela bocor Pengecualian saat membuka dialog pilihan diff --git a/fastlane/metadata/android/id/changelogs/973.txt b/fastlane/metadata/android/id/changelogs/973.txt new file mode 100644 index 000000000..3ba7d9f05 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/973.txt @@ -0,0 +1,4 @@ +Perbaikan terbaru +- Memperbaiki thumbnail dan judul yang terpotong dalam tata letak grid, karena perhitungan yang salah tentang berapa banyak video yang dapat ditampung dalam satu baris +- Memperbaiki dialog unduhan yang menghilang tanpa melakukan apa pun jika dibuka dari menu berbagi +- Memperbarui pustaka yang terkait dengan membuka aktivitas eksternal seperti pemilih file Storage Access Framework diff --git a/fastlane/metadata/android/id/changelogs/992.txt b/fastlane/metadata/android/id/changelogs/992.txt new file mode 100644 index 000000000..507334743 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/992.txt @@ -0,0 +1,17 @@ +Baru +- Jumlah pelanggan dalam detail video +- Unduh dari antrean +- Mengatur gambar mini daftar putar secara permanen +- Tekan lama tagar dan tautan +- Mode tampilan kartu + +Lebih baik +- Tombol tutup pemutar mini yang lebih besar +- Pengecilan ukuran gambar mini yang lebih halus +- Target Android 13 (API 33) +- Mencari tidak lagi menjeda pemain + +Diperbaiki +- Perbaiki overlay pada DeX/mouse +- Izinkan pemutar latar belakang tanpa aliran audio terpisah +- Berbagai perbaikan YouTube dan banyak lagi… diff --git a/fastlane/metadata/android/it/changelogs/992.txt b/fastlane/metadata/android/it/changelogs/992.txt new file mode 100644 index 000000000..b11e7249e --- /dev/null +++ b/fastlane/metadata/android/it/changelogs/992.txt @@ -0,0 +1,17 @@ +Nuovo +• Numero di iscritti nei dettagli del video +• Scarica dalla coda +• Impostare in modo permanente una miniatura della playlist +• Premi a lungo hashtag e link +• Modalità di visualizzazione scheda + +Migliorato +• Pulsante di chiusura mini-player più grande +• Downscaling delle miniature più agevole +• Target Android 13 (API 33) +• La ricerca non mette più in pausa il lettore + +Corretto +• Corretto l'overlay su DeX/mouse +• Consenti lettore in background senza flussi audio separati +• Varie correzioni di YouTube e altro… diff --git a/fastlane/metadata/android/nb-NO/changelogs/992.txt b/fastlane/metadata/android/nb-NO/changelogs/992.txt new file mode 100644 index 000000000..02605fc2c --- /dev/null +++ b/fastlane/metadata/android/nb-NO/changelogs/992.txt @@ -0,0 +1,17 @@ +Nytt +• Antall abonnenter i videodetaljene +• Last ned fra køen +• Sett miniatyrbilde for spilleliste +• Langtrykk på emneknagger og linker +• Kortvisningsmodus + +Forbedret +• Større lukkenapp på minispilleren +• Bedre nedskalering av miniatyrbilder +• Målversjon er nå Android 13 (API 33) +• Blafring pauser ikke lenger spilleren + +Fikset +• Fiks overlay for DeX/mus +• Tillat bakgrunnsspiller med ingen separate lydstrømmer +• Diverse YouTube-fikser, med mer … diff --git a/fastlane/metadata/android/nb-NO/full_description.txt b/fastlane/metadata/android/nb-NO/full_description.txt index 6fc7e0fbd..0ffda33f8 100644 --- a/fastlane/metadata/android/nb-NO/full_description.txt +++ b/fastlane/metadata/android/nb-NO/full_description.txt @@ -1,5 +1 @@ -Gemenhetslig fri programvare. -Bruker ingen av Google-rammeverksbibliotekene, eller YouTube-API-et. -Det tolker kun nettsiden for å hente infoen som trengs. -Derfor kan dette programmet brukes på enheter der Google-tjenestene ikke er installert. -Du trenger heller ikke en YouTube-konto for å bruke installere det. +NewPipe bruker ikke noen av Googles rammeverksbiblioteker, eller YouTube-API-et. Den bare tolker nettsiden for å hente informasjonen den trenger. Programmet kan derfor brukes på enheter uten Google-tjenester, og du trenger ikke en YouTube-konto for å bruke det. I tillegg er det er gemenfrihetslig fritt. diff --git a/fastlane/metadata/android/nb-NO/short_description.txt b/fastlane/metadata/android/nb-NO/short_description.txt index feaf8f8ba..c19a75993 100644 --- a/fastlane/metadata/android/nb-NO/short_description.txt +++ b/fastlane/metadata/android/nb-NO/short_description.txt @@ -1 +1 @@ -En fri og lett mediaplattformsavspiller. +En fri og lett YouTube-skjermflate for Android. diff --git a/fastlane/metadata/android/nl/changelogs/65.txt b/fastlane/metadata/android/nl/changelogs/65.txt new file mode 100644 index 000000000..79a6c4928 --- /dev/null +++ b/fastlane/metadata/android/nl/changelogs/65.txt @@ -0,0 +1,26 @@ +### Verbeteringen + +- Burgermenu icoon animatie uitschakelen #1486 +- Verwijderen van downloads ongedaan maken #1472 +- Downloadoptie in aandelenmenu #1498 +- Deeloptie toegevoegd aan menu met lange tikken #1454 +- Hoofdspeler minimaliseren bij afsluiten #1354 +- Bibliotheek versie update en database back-up fix #1510 +- ExoPlayer 2.8.2 Update #1392 + - De afspeelsnelheidsdialoog herwerkt om verschillende stapgrootten te ondersteunen voor snellere snelheidsverandering. + - Een schakelaar toegevoegd om snel vooruit te spoelen tijdens stiltes in de afspeelsnelheidcontrole. Dit zou handig moeten zijn voor luisterboeken en bepaalde muziekgenres, en kan een echte naadloze ervaring opleveren (en kan een nummer met veel stiltes = breken). + - Verfijnde mediabronresolutie zodat metadata naast media intern in de speler kunnen worden doorgegeven, in plaats van dit handmatig te doen. Nu hebben we een enkele bron van metadata en deze is direct beschikbaar wanneer het afspelen begint. + - Metagegevens van afspeellijst op afstand niet bijgewerkt wanneer nieuwe metagegevens beschikbaar zijn wanneer afspeellijstfragment wordt geopend. + - Diverse UI fixes: #1383, achtergrondspeler meldingselementen nu altijd wit, makkelijker uitschakelen van popup speler door gooien +- Gebruik nieuwe extractor met refactored architectuur voor multiservice + +### Fixes + +- Fix #1440 Gebroken video-info-indeling #1491 +- Geschiedenis bekijken fix #1497 + - #1495, door de metadata (thumbnail, titel en videotelling) bij te werken zodra de gebruiker de afspeellijst opent. + - #1475, door een weergave in de database te registreren wanneer de gebruiker een video start op externe speler op detailfragment. +- Fix creen timeout bij popup modus. #1463 (Fixed #640) +- Hoofd video speler fix #1509 + - #1412] Fixed repeat mode veroorzaakt speler NPE wanneer nieuwe intentie wordt ontvangen terwijl speler activiteit op de achtergrond is. + - Fixed minimaliseren van speler naar popup vernietigt speler niet wanneer popup toestemming niet is verleend. diff --git a/fastlane/metadata/android/pa/changelogs/992.txt b/fastlane/metadata/android/pa/changelogs/992.txt new file mode 100644 index 000000000..de71db154 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/992.txt @@ -0,0 +1,15 @@ +ਨਵਾਂ +• ਵੀਡੀਓ ਵੇਰਵਿਆਂ ਵਿੱਚ ਗਾਹਕਾਂ ਦੀ ਗਿਣਤੀ +• ਕਤਾਰ ਤੋਂ ਡਾਊਨਲੋਡ ਕਰੋ +• ਇੱਕ ਪਲੇਅਲਿਸਟ ਥੰਮਨੇਲ ਪੱਕੇ ਤੌਰ 'ਤੇ ਸੈੱਟ ਕਰੋ +• ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਪ੍ਰੈੱਸ ਕਰਨ ਵਾਲੇ ਹੈਸ਼ਟੈਗ ਅਤੇ ਲਿੰਕ +• ਕਾਰਡ ਦ੍ਰਿਸ਼ ਮੋਡ + +ਸੁਧਾਰ +• ਵੱਡਾ ਮਿੰਨੀ-ਪਲੇਅਰ ਬੰਦ ਬਟਨ +• ਮੁਲਾਇਮ ਥੰਮਨੇਲ ਡਾਊਨਸਕੇਲਿੰਗ +• ਟਾਰਗੇਟ ਐਂਡਰਾਇਡ 13 (ਏਪੀਆਈ 33) +• ਹੁਣ ਪਲੇਅਰ ਸੀਕ ਕਰਨ ਤੇ ਰੁਕਦਾ ਨਹੀਂ +• DeX/ਮਾਊਸ 'ਤੇ ਓਵਰਲੇਅ ਨੂੰ ਫਿਕਸ ਕਰੋ +• ਬਿਨਾਂ ਕਿਸੇ ਵੱਖਰੇ ਆਡੀਓ ਸਟ੍ਰੀਮ ਦੇ ਬੈਕਗ੍ਰਾਉਂਡ ਪਲੇਅਰ ਨੂੰ ਚਲਾਉਣ ਦਿਓ +• ਵੱਖ-ਵੱਖ ਯੂਟਿਊਬ ਫਿਕਸ ਅਤੇ ਹੋਰ… diff --git a/fastlane/metadata/android/pl/changelogs/992.txt b/fastlane/metadata/android/pl/changelogs/992.txt new file mode 100644 index 000000000..98d0d1773 --- /dev/null +++ b/fastlane/metadata/android/pl/changelogs/992.txt @@ -0,0 +1,17 @@ +Nowe +• Liczba subskrybentów w szczegółach wideo +• Pobieranie z kolejki +• Ustawianie stałej miniatury playlisty +• Długie naciśnięcie hashtagów i linków +• Tryb widoku karty + +Ulepszone +• Większy przycisk zamykania miniodtwarzacza +• Płynniejsze zmniejszanie miniatur +• Docelowy system Android 13 (API 33) +• Przewijanie nie wstrzymuje już odtwarzacza + +Naprawione +• Nakładka dla DeX/myszy +• Zezwalanie na odtwarzanie w tle bez oddzielnych strumieni audio +• Różne poprawki YouTube i więcej… diff --git a/fastlane/metadata/android/pt-BR/changelogs/770.txt b/fastlane/metadata/android/pt-BR/changelogs/770.txt new file mode 100644 index 000000000..d53963daa --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/770.txt @@ -0,0 +1,4 @@ +Mudanças no 0.47.2 + +Consertado +• Consertado, nenhum vídeo estava disponível diff --git a/fastlane/metadata/android/pt-PT/changelogs/992.txt b/fastlane/metadata/android/pt-PT/changelogs/992.txt new file mode 100644 index 000000000..2da819beb --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/992.txt @@ -0,0 +1,17 @@ +Novo +- Contagem de subscritores em detalhes de vídeo +- Descarregar da fila +- Uma miniatura permanente de listas de reprodução +- Hashtags e ligações de imprensa longa +- Modo de visualização de cartões + +Melhorado +- Botão de fecho de mini-reprodutor maior +- Redução mais suave das miniaturas +- Alvo Android 13 (API 33) +- Procurar não pausa o reprodutor + +Fixa +- Corrigido sobreposições no DeX/rato +- Permitir um leitor de fundo sem fluxo de áudio separados +- Várias correções do YouTube… diff --git a/fastlane/metadata/android/pt/changelogs/992.txt b/fastlane/metadata/android/pt/changelogs/992.txt new file mode 100644 index 000000000..2da819beb --- /dev/null +++ b/fastlane/metadata/android/pt/changelogs/992.txt @@ -0,0 +1,17 @@ +Novo +- Contagem de subscritores em detalhes de vídeo +- Descarregar da fila +- Uma miniatura permanente de listas de reprodução +- Hashtags e ligações de imprensa longa +- Modo de visualização de cartões + +Melhorado +- Botão de fecho de mini-reprodutor maior +- Redução mais suave das miniaturas +- Alvo Android 13 (API 33) +- Procurar não pausa o reprodutor + +Fixa +- Corrigido sobreposições no DeX/rato +- Permitir um leitor de fundo sem fluxo de áudio separados +- Várias correções do YouTube… diff --git a/fastlane/metadata/android/uk/changelogs/992.txt b/fastlane/metadata/android/uk/changelogs/992.txt new file mode 100644 index 000000000..4efccccb4 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/992.txt @@ -0,0 +1,17 @@ +Нове +• Кількість підписників у поробицях відео +• Завантаження з черги +• Постійна мініатюра добірки +• Затискання хештегів і посилань +• Картковий режим перегляду + +Удосконалено +• Більша кнопка закриття мініпрогравача +• Плавніше зменшення масштабу мініатюр +• Цільова версія Android 13 (API 33) +• Пошук більше не призупиняє програвач + +Виправлено +• Виправлено накладання на DeX/миша +• Дозволено фоновий програвач без окремих аудіопотоків +• Різні виправлення YouTube тощо… diff --git a/fastlane/metadata/android/zh-Hant/changelogs/992.txt b/fastlane/metadata/android/zh-Hant/changelogs/992.txt new file mode 100644 index 000000000..97bc793b2 --- /dev/null +++ b/fastlane/metadata/android/zh-Hant/changelogs/992.txt @@ -0,0 +1,17 @@ +新增 +• 影片詳細資訊的訂閱者人數 +• 佇列功能表的下載按鈕 +• 永久設定播放清單的縮圖 +• 主題標籤和連結的長按動作 +• 卡片檢視模式 + +改進 +• 迷你播放器的關閉按鈕略為放大 +• 縮圖縮小時較順滑 +• 目標版本現為 Android 13 (API 33) +• 快轉時不再暫停播放器 + +修正 +• 修正 DeX/滑鼠的覆蓋 +• 背景播放器允許無獨立音訊串流 +• 若干 YouTube 修正及其他… diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/992.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/992.txt new file mode 100644 index 000000000..bfe34c021 --- /dev/null +++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/992.txt @@ -0,0 +1,17 @@ +新嘢 +• 影片詳情騷埋訂閱人數 +• 排隊播整埋個下載掣 +• 自選播放清單封面縮圖 +• 撳實主題標籤同連結有得複製 +• 有得以一張張白紙舉起一條條片 + +進步 +• 袖珍播放器個閂埋掣大粒啲 +• 縮圖縮細時幼細啲 +• 編譯目標版本訂為 Android 13 (API 33) +• 條片快轉時唔再暫停播放器 + +執漏 +• 修正三星 DeX/滑鼠覆蓋 +• 無獨立聲音串流都有得幕後播 +• 若干 YouTube 修正、等等… From 8d43499e5bea402ea85aa5c7ab7477765deaac01 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 8 Feb 2023 22:27:49 +0100 Subject: [PATCH 83/84] Update NewPipeExtractor again --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 917bf5356..165511816 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -191,7 +191,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:999fb7f812f8f39712dda88cf5ff4db3ee877fdc' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:e920ab3f5f40fe1f669735d717135c83141be2dd' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From d2f8f31d1f21bcb97b7a9417a210b5da5311e4d9 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 8 Feb 2023 22:37:17 +0100 Subject: [PATCH 84/84] Update NewPipeExtractor again, because of JitPack problems --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 165511816..0afdc3ce8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -191,7 +191,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:e920ab3f5f40fe1f669735d717135c83141be2dd' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:7e793c11aec46358ccbfd8bcfcf521105f4f093a' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/