From 2339f51ad4707367a98c844840dd4f5f7295675f Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Fri, 14 Feb 2025 21:14:42 -0300 Subject: [PATCH 01/21] [#11930] Share as YouTube temporary playlist Initial commit. --- .../local/playlist/LocalPlaylistFragment.java | 100 +++++++++++++----- .../local/playlist/PlayListShareMode.java | 8 ++ .../playlist/LocalPlaylistFragmentTest.java | 55 ++++++++++ 3 files changed, 138 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java create mode 100644 app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java 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 c87d9cccc..3e99b01c4 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 @@ -2,6 +2,9 @@ package org.schabi.newpipe.local.playlist; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.ktx.ViewUtils.animate; +import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; +import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES; +import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout; import android.content.Context; @@ -64,12 +67,14 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; +import java.util.stream.Stream; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.schedulers.Schedulers; +import okhttp3.HttpUrl; public class LocalPlaylistFragment extends BaseLocalListFragment, Void> implements PlaylistControlViewHolder, DebounceSavable { @@ -385,34 +390,76 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Single.just(playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(streamEntity -> { - if (shouldSharePlaylistDetails) { - return context.getString(R.string.video_details_list_item, - streamEntity.getTitle(), streamEntity.getUrl()); - } else { - return streamEntity.getUrl(); - } - }) - .collect(Collectors.joining("\n")))) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(urlsText -> ShareUtils.shareText( - context, name, shouldSharePlaylistDetails - ? context.getString(R.string.share_playlist_content_details, - name, urlsText) : urlsText), - throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable))); + .flatMapSingle(playlist -> Single.just(export( shareMode + , playlist.stream().map(PlaylistStreamEntry::getStreamEntity) + , context + ) + )) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( urlsText -> ShareUtils.shareText( context + , name + , shareMode == JUST_URLS ? urlsText + : context.getString(R.string.share_playlist_content_details, name, urlsText)) + , throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable)) + ); + } + + static String export(PlayListShareMode shareMode, Stream entityStream, Context context) { + + return switch(shareMode) { + + case WITH_TITLES -> exportWithTitles(entityStream, context); + case JUST_URLS -> exportJustUrls(entityStream); + case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(entityStream); + }; + } + + static String exportWithTitles(Stream entityStream, Context context) { + + return entityStream + .map(entity -> context.getString(R.string.video_details_list_item, entity.getTitle(), entity.getUrl())) + .collect(Collectors.joining("\n")); + } + + static String exportJustUrls(Stream entityStream) { + + return entityStream + .map(StreamEntity::getUrl) + .collect(Collectors.joining("\n")); + } + + static String exportAsYoutubeTempPlaylist(Stream entityStream) { + + String videoIDs = entityStream + .map(entity -> getYouTubeId(entity.getUrl())) + .collect(Collectors.joining(",")); + + return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; + } + + /** + * Gets the video id from a YouTube URL + */ + static String getYouTubeId(String url) { + + HttpUrl httpUrl = HttpUrl.parse(url); + + return httpUrl == null ? null + : httpUrl.queryParameter("v") + ; } public void removeWatchedStreams(final boolean removePartiallyWatched) { @@ -875,10 +922,13 @@ public class LocalPlaylistFragment extends BaseLocalListFragment - sharePlaylist(/* shouldSharePlaylistDetails= */ true) + sharePlaylist(WITH_TITLES) + ) + .setNeutralButton("Share as YouTube temporary playlist", (dialog, which) -> // TODO R.string.share_playlist_as_YouTube_temporary_playlist + sharePlaylist(YOUTUBE_TEMP_PLAYLIST) ) .setNegativeButton(R.string.share_playlist_with_list, (dialog, which) -> - sharePlaylist(/* shouldSharePlaylistDetails= */ false) + sharePlaylist(JUST_URLS) ) .show(); } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java b/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java new file mode 100644 index 000000000..3de1effc9 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java @@ -0,0 +1,8 @@ +package org.schabi.newpipe.local.playlist; + +public enum PlayListShareMode { + + JUST_URLS + ,WITH_TITLES + ,YOUTUBE_TEMP_PLAYLIST +} diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java new file mode 100644 index 000000000..41e1f6091 --- /dev/null +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -0,0 +1,55 @@ +package org.schabi.newpipe.local.playlist; + +import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; + +import androidx.annotation.NonNull; + +import org.junit.Assert; +import org.junit.Test; +import org.schabi.newpipe.database.stream.model.StreamEntity; +import org.schabi.newpipe.extractor.stream.StreamType; + +import java.util.List; +import java.util.stream.Stream; + +public class LocalPlaylistFragmentTest { + + @Test + public void youTubeTempPlaylist() { + + Stream entityStream = List.of( + + "https://www.youtube.com/watch?v=1" + ,"https://www.youtube.com/watch?v=2" + ,"https://www.youtube.com/watch?v=3" + ) + .stream() + .map(LocalPlaylistFragmentTest::newStreamEntity) + ; + + String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + + Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); + } + + @NonNull + static StreamEntity newStreamEntity(String url) { + + return new StreamEntity( + + 0 + , 1 + , url + , "Title" + , StreamType.VIDEO_STREAM + , 100 + , "Uploader" + , null + , null + , null + , null + , null + , null + ); + } +} From 94d4c21cc7ec018d86525c839525d9c2aad6fbca Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 18 Feb 2025 17:47:22 -0300 Subject: [PATCH 02/21] [#11930] @Test export_justUrls() --- .../playlist/LocalPlaylistFragmentTest.java | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index 41e1f6091..12242ad1d 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.local.playlist; +import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import androidx.annotation.NonNull; @@ -15,23 +16,45 @@ import java.util.stream.Stream; public class LocalPlaylistFragmentTest { @Test - public void youTubeTempPlaylist() { + public void export_asYouTubeTempPlaylist() { - Stream entityStream = List.of( + Stream entityStream = asStreamEntityStream( "https://www.youtube.com/watch?v=1" ,"https://www.youtube.com/watch?v=2" ,"https://www.youtube.com/watch?v=3" - ) - .stream() - .map(LocalPlaylistFragmentTest::newStreamEntity) - ; + ); String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } + @Test + public void export_justUrls() { + + Stream entityStream = asStreamEntityStream( + + "https://www.youtube.com/watch?v=1" + ,"https://www.youtube.com/watch?v=2" + ,"https://www.youtube.com/watch?v=3" + ); + + String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); + + Assert.assertEquals(""" + https://www.youtube.com/watch?v=1 + https://www.youtube.com/watch?v=2 + https://www.youtube.com/watch?v=3""", exported); + } + + @NonNull + private static Stream asStreamEntityStream(String... urls) { + + return Stream.of(urls) + .map(LocalPlaylistFragmentTest::newStreamEntity); + } + @NonNull static StreamEntity newStreamEntity(String url) { From c6b87cd3169056b1feb301d26763918ea0caa2e7 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 18 Feb 2025 20:59:13 -0300 Subject: [PATCH 03/21] [#11930] Making CheckStyle happy --- .../local/playlist/LocalPlaylistFragment.java | 69 ++++++++++++------- .../local/playlist/PlayListShareMode.java | 6 +- .../playlist/LocalPlaylistFragmentTest.java | 55 ++++++++------- 3 files changed, 74 insertions(+), 56 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 3e99b01c4..354985b85 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 @@ -399,27 +399,39 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Single.just(export( shareMode - , playlist.stream().map(PlaylistStreamEntry::getStreamEntity) - , context - ) - )) + .flatMapSingle(playlist -> Single.just(export( + + shareMode, + playlist.stream().map(PlaylistStreamEntry::getStreamEntity), + context + ))) .observeOn(AndroidSchedulers.mainThread()) - .subscribe( urlsText -> ShareUtils.shareText( context - , name - , shareMode == JUST_URLS ? urlsText - : context.getString(R.string.share_playlist_content_details, name, urlsText)) - , throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable)) - ); + .subscribe( + urlsText -> { + + final String content = shareMode == JUST_URLS + ? urlsText + : context.getString(R.string.share_playlist_content_details, + name, + urlsText + ); + + ShareUtils.shareText(context, name, content); + }, + throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable) + ) + ); } - static String export(PlayListShareMode shareMode, Stream entityStream, Context context) { + static String export(final PlayListShareMode shareMode, + final Stream entityStream, + final Context context) { - return switch(shareMode) { + return switch (shareMode) { case WITH_TITLES -> exportWithTitles(entityStream, context); case JUST_URLS -> exportJustUrls(entityStream); @@ -427,23 +439,27 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream, Context context) { + static String exportWithTitles(final Stream entityStream, final Context context) { return entityStream - .map(entity -> context.getString(R.string.video_details_list_item, entity.getTitle(), entity.getUrl())) + .map(entity -> context.getString(R.string.video_details_list_item, + entity.getTitle(), + entity.getUrl() + ) + ) .collect(Collectors.joining("\n")); } - static String exportJustUrls(Stream entityStream) { + static String exportJustUrls(final Stream entityStream) { return entityStream .map(StreamEntity::getUrl) .collect(Collectors.joining("\n")); } - static String exportAsYoutubeTempPlaylist(Stream entityStream) { + static String exportAsYoutubeTempPlaylist(final Stream entityStream) { - String videoIDs = entityStream + final String videoIDs = entityStream .map(entity -> getYouTubeId(entity.getUrl())) .collect(Collectors.joining(",")); @@ -451,15 +467,17 @@ public class LocalPlaylistFragment extends BaseLocalListFragment sharePlaylist(WITH_TITLES) ) - .setNeutralButton("Share as YouTube temporary playlist", (dialog, which) -> // TODO R.string.share_playlist_as_YouTube_temporary_playlist + // TODO R.string.share_playlist_as_YouTube_temporary_playlist + .setNeutralButton("Share as YouTube temporary playlist", (dialog, which) -> sharePlaylist(YOUTUBE_TEMP_PLAYLIST) ) .setNegativeButton(R.string.share_playlist_with_list, (dialog, which) -> diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java b/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java index 3de1effc9..f0433aba8 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java @@ -2,7 +2,7 @@ package org.schabi.newpipe.local.playlist; public enum PlayListShareMode { - JUST_URLS - ,WITH_TITLES - ,YOUTUBE_TEMP_PLAYLIST + JUST_URLS, + WITH_TITLES, + YOUTUBE_TEMP_PLAYLIST } diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index 12242ad1d..170193155 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -10,37 +10,36 @@ import org.junit.Test; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.extractor.stream.StreamType; -import java.util.List; import java.util.stream.Stream; public class LocalPlaylistFragmentTest { @Test - public void export_asYouTubeTempPlaylist() { + public void exportAsYouTubeTempPlaylist() { - Stream entityStream = asStreamEntityStream( + final Stream entityStream = asStreamEntityStream( - "https://www.youtube.com/watch?v=1" - ,"https://www.youtube.com/watch?v=2" - ,"https://www.youtube.com/watch?v=3" + "https://www.youtube.com/watch?v=1", + "https://www.youtube.com/watch?v=2", + "https://www.youtube.com/watch?v=3" ); - String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } @Test - public void export_justUrls() { + public void exportJustUrls() { - Stream entityStream = asStreamEntityStream( + final Stream entityStream = asStreamEntityStream( - "https://www.youtube.com/watch?v=1" - ,"https://www.youtube.com/watch?v=2" - ,"https://www.youtube.com/watch?v=3" + "https://www.youtube.com/watch?v=1", + "https://www.youtube.com/watch?v=2", + "https://www.youtube.com/watch?v=3" ); - String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); + final String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); Assert.assertEquals(""" https://www.youtube.com/watch?v=1 @@ -49,30 +48,30 @@ public class LocalPlaylistFragmentTest { } @NonNull - private static Stream asStreamEntityStream(String... urls) { + private static Stream asStreamEntityStream(final String... urls) { return Stream.of(urls) .map(LocalPlaylistFragmentTest::newStreamEntity); } @NonNull - static StreamEntity newStreamEntity(String url) { + static StreamEntity newStreamEntity(final String url) { return new StreamEntity( - 0 - , 1 - , url - , "Title" - , StreamType.VIDEO_STREAM - , 100 - , "Uploader" - , null - , null - , null - , null - , null - , null + 0, + 1, + url, + "Title", + StreamType.VIDEO_STREAM, + 100, + "Uploader", + null, + null, + null, + null, + null, + null ); } } From acac50a1d1a66a4bd12e87573478d4532ed7ab50 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Wed, 19 Feb 2025 16:29:34 -0300 Subject: [PATCH 04/21] [#11930] Non-Youtube URLs should be ignored --- .../schabi/newpipe/local/playlist/LocalPlaylistFragment.java | 2 ++ .../newpipe/local/playlist/LocalPlaylistFragmentTest.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) 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 354985b85..cb47c2199 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 @@ -65,6 +65,7 @@ import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -461,6 +462,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment getYouTubeId(entity.getUrl())) + .filter(Objects::nonNull) .collect(Collectors.joining(",")); return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index 170193155..fb93a9e86 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -20,7 +20,8 @@ public class LocalPlaylistFragmentTest { final Stream entityStream = asStreamEntityStream( "https://www.youtube.com/watch?v=1", - "https://www.youtube.com/watch?v=2", + "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be + "https://www.youtube.com/watch?v=2", // ignored "https://www.youtube.com/watch?v=3" ); From b1f995a78c6ed792296d35969afcd118c97584a1 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Thu, 20 Feb 2025 16:26:03 -0300 Subject: [PATCH 05/21] [#11930] Playlist with more than 50 items --- app/build.gradle | 3 ++ .../local/playlist/LocalPlaylistFragment.java | 14 +++++-- .../playlist/LocalPlaylistFragmentTest.java | 37 +++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d03bd64e3..2cdc952af 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -255,6 +255,9 @@ dependencies { // HTTP client implementation "com.squareup.okhttp3:okhttp:4.12.0" + // Apache Commons Collections + implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.4' + // Media player implementation "com.google.android.exoplayer:exoplayer-core:${exoPlayerVersion}" implementation "com.google.android.exoplayer:exoplayer-dash:${exoPlayerVersion}" 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 cb47c2199..008dc4a9c 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 @@ -31,6 +31,7 @@ import androidx.viewbinding.ViewBinding; import com.evernote.android.state.State; +import org.apache.commons.collections4.queue.CircularFifoQueue; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import org.schabi.newpipe.NewPipeDatabase; @@ -460,10 +461,15 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream) { - final String videoIDs = entityStream - .map(entity -> getYouTubeId(entity.getUrl())) - .filter(Objects::nonNull) - .collect(Collectors.joining(",")); + final CircularFifoQueue last50 = new CircularFifoQueue<>(50); + + entityStream + .map(entity -> getYouTubeId(entity.getUrl())) + .filter(Objects::nonNull) + .forEachOrdered(last50::add); + + final String videoIDs = last50.stream() + .collect(Collectors.joining(",")); return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; } diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index fb93a9e86..eca798a24 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -10,6 +10,7 @@ import org.junit.Test; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.extractor.stream.StreamType; +import java.util.List; import java.util.stream.Stream; public class LocalPlaylistFragmentTest { @@ -30,6 +31,42 @@ public class LocalPlaylistFragmentTest { Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } + @Test + public void exportMoreThan50Items() { + /* + * Playlist has more than 50 items => take the last 50 + * (YouTube limitation) + */ + + final List ids = List.of( + + -1, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 + ); + + final Stream entityStream = ids.stream() + .map(id -> "https://www.youtube.com/watch?v=" + id) + .map(LocalPlaylistFragmentTest::newStreamEntity); + + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + + Assert.assertEquals( + + "http://www.youtube.com/watch_videos?video_ids=" + + "1,2,3,4,5,6,7,8,9,10," + + "11,12,13,14,15,16,17,18,19,20," + + "21,22,23,24,25,26,27,28,29,30," + + "31,32,33,34,35,36,37,38,39,40," + + "41,42,43,44,45,46,47,48,49,50", + + url + ); + } + @Test public void exportJustUrls() { From 24bb71a23f0df82866f7525f5def7e638ae6f6cd Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Mon, 24 Feb 2025 19:22:36 -0300 Subject: [PATCH 06/21] [#11930] Making it more efficient: Reverse iteration + limit(50) + reverse --- .../local/playlist/LocalPlaylistFragment.java | 45 ++++++++++++------- .../playlist/LocalPlaylistFragmentTest.java | 38 +++++++++++----- 2 files changed, 55 insertions(+), 28 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 008dc4a9c..e8d8573a1 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 @@ -1,5 +1,7 @@ package org.schabi.newpipe.local.playlist; +import static com.google.common.collect.Streams.stream; +import static org.apache.commons.collections4.IterableUtils.reversedIterable; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.ktx.ViewUtils.animate; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; @@ -7,6 +9,8 @@ import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout; +import static java.util.Collections.reverse; + import android.content.Context; import android.os.Bundle; import android.os.Parcelable; @@ -30,7 +34,9 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.viewbinding.ViewBinding; import com.evernote.android.state.State; +import com.google.common.collect.Streams; +import org.apache.commons.collections4.IterableUtils; import org.apache.commons.collections4.queue.CircularFifoQueue; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; @@ -408,7 +414,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Single.just(export( shareMode, - playlist.stream().map(PlaylistStreamEntry::getStreamEntity), + playlist, context ))) .observeOn(AndroidSchedulers.mainThread()) @@ -430,20 +436,21 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream, + final List playlist, final Context context) { return switch (shareMode) { - case WITH_TITLES -> exportWithTitles(entityStream, context); - case JUST_URLS -> exportJustUrls(entityStream); - case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(entityStream); + case WITH_TITLES -> exportWithTitles(playlist, context); + case JUST_URLS -> exportJustUrls(playlist); + case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist); }; } - static String exportWithTitles(final Stream entityStream, final Context context) { + static String exportWithTitles(final List playlist, final Context context) { - return entityStream + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) .map(entity -> context.getString(R.string.video_details_list_item, entity.getTitle(), entity.getUrl() @@ -452,26 +459,30 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream) { + static String exportJustUrls(final List playlist) { - return entityStream + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) .map(StreamEntity::getUrl) .collect(Collectors.joining("\n")); } - static String exportAsYoutubeTempPlaylist(final Stream entityStream) { + static String exportAsYoutubeTempPlaylist(final List playlist) { - final CircularFifoQueue last50 = new CircularFifoQueue<>(50); - - entityStream + final List videoIDs = + stream(reversedIterable(playlist)) + .map(PlaylistStreamEntry::getStreamEntity) .map(entity -> getYouTubeId(entity.getUrl())) .filter(Objects::nonNull) - .forEachOrdered(last50::add); + .limit(50) + .collect(Collectors.toList()); - final String videoIDs = last50.stream() - .collect(Collectors.joining(",")); + reverse(videoIDs); - return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; + final String commaSeparatedVideoIDs = videoIDs.stream() + .collect(Collectors.joining(",")); + + return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs; } /** diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index eca798a24..1d5d4a6a0 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; import org.junit.Assert; import org.junit.Test; +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.extractor.stream.StreamType; @@ -18,7 +19,7 @@ public class LocalPlaylistFragmentTest { @Test public void exportAsYouTubeTempPlaylist() { - final Stream entityStream = asStreamEntityStream( + final List playlist = asPlaylist( "https://www.youtube.com/watch?v=1", "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be @@ -26,7 +27,7 @@ public class LocalPlaylistFragmentTest { "https://www.youtube.com/watch?v=3" ); - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } @@ -48,11 +49,13 @@ public class LocalPlaylistFragmentTest { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 ); - final Stream entityStream = ids.stream() - .map(id -> "https://www.youtube.com/watch?v=" + id) - .map(LocalPlaylistFragmentTest::newStreamEntity); + final List playlist = asPlaylist( - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + ids.stream() + .map(id -> "https://www.youtube.com/watch?v=" + id) + ); + + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals( @@ -70,14 +73,14 @@ public class LocalPlaylistFragmentTest { @Test public void exportJustUrls() { - final Stream entityStream = asStreamEntityStream( + final List playlist = asPlaylist( "https://www.youtube.com/watch?v=1", "https://www.youtube.com/watch?v=2", "https://www.youtube.com/watch?v=3" ); - final String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); + final String exported = LocalPlaylistFragment.export(JUST_URLS, playlist, null); Assert.assertEquals(""" https://www.youtube.com/watch?v=1 @@ -86,10 +89,23 @@ public class LocalPlaylistFragmentTest { } @NonNull - private static Stream asStreamEntityStream(final String... urls) { + static List asPlaylist(final String... urls) { - return Stream.of(urls) - .map(LocalPlaylistFragmentTest::newStreamEntity); + return asPlaylist(Stream.of(urls)); + } + + @NonNull + static List asPlaylist(final Stream urls) { + + return urls + .map(LocalPlaylistFragmentTest::newPlaylistStreamEntry) + .toList(); + } + + @NonNull + private static PlaylistStreamEntry newPlaylistStreamEntry(final String url) { + + return new PlaylistStreamEntry(newStreamEntity(url), 0, 0, 0); } @NonNull From 76a02d5858d99e72a410431e54ad3a0e055c7285 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Mon, 24 Feb 2025 20:16:40 -0300 Subject: [PATCH 07/21] [#11930] Extracting to a separate file --- .../local/playlist/ExportPlaylist.java | 90 +++++++++++++++++++ .../local/playlist/LocalPlaylistFragment.java | 75 +--------------- ...gmentTest.java => ExportPlaylistTest.java} | 11 +-- 3 files changed, 97 insertions(+), 79 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java rename app/src/test/java/org/schabi/newpipe/local/playlist/{LocalPlaylistFragmentTest.java => ExportPlaylistTest.java} (89%) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java new file mode 100644 index 000000000..94002dd5b --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java @@ -0,0 +1,90 @@ +package org.schabi.newpipe.local.playlist; + +import static com.google.common.collect.Streams.stream; +import static org.apache.commons.collections4.IterableUtils.reversedIterable; +import static java.util.Collections.reverse; + +import android.content.Context; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; +import org.schabi.newpipe.database.stream.model.StreamEntity; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import okhttp3.HttpUrl; + + + +final class ExportPlaylist { + + private ExportPlaylist() { + } + + static String export(final PlayListShareMode shareMode, + final List playlist, + final Context context) { + + return switch (shareMode) { + + case WITH_TITLES -> exportWithTitles(playlist, context); + case JUST_URLS -> exportJustUrls(playlist); + case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist); + }; + } + + static String exportWithTitles(final List playlist, + final Context context) { + + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) + .map(entity -> context.getString(R.string.video_details_list_item, + entity.getTitle(), + entity.getUrl() + ) + ) + .collect(Collectors.joining("\n")); + } + + static String exportJustUrls(final List playlist) { + + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) + .map(StreamEntity::getUrl) + .collect(Collectors.joining("\n")); + } + + static String exportAsYoutubeTempPlaylist(final List playlist) { + + final List videoIDs = + stream(reversedIterable(playlist)) + .map(PlaylistStreamEntry::getStreamEntity) + .map(entity -> getYouTubeId(entity.getUrl())) + .filter(Objects::nonNull) + .limit(50) + .collect(Collectors.toList()); + + reverse(videoIDs); + + final String commaSeparatedVideoIDs = videoIDs.stream() + .collect(Collectors.joining(",")); + + return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs; + } + + /** + * Gets the video id from a YouTube URL. + * + * @param url YouTube URL + * @return the video id + */ + static String getYouTubeId(final String url) { + + final HttpUrl httpUrl = HttpUrl.parse(url); + + return httpUrl == null ? null + : httpUrl.queryParameter("v"); + } +} 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 e8d8573a1..812d9fb38 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 @@ -1,15 +1,13 @@ package org.schabi.newpipe.local.playlist; -import static com.google.common.collect.Streams.stream; -import static org.apache.commons.collections4.IterableUtils.reversedIterable; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.ktx.ViewUtils.animate; +import static org.schabi.newpipe.local.playlist.ExportPlaylist.export; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout; -import static java.util.Collections.reverse; import android.content.Context; import android.os.Bundle; @@ -34,10 +32,6 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.viewbinding.ViewBinding; import com.evernote.android.state.State; -import com.google.common.collect.Streams; - -import org.apache.commons.collections4.IterableUtils; -import org.apache.commons.collections4.queue.CircularFifoQueue; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import org.schabi.newpipe.NewPipeDatabase; @@ -72,17 +66,14 @@ import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; -import java.util.stream.Stream; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.schedulers.Schedulers; -import okhttp3.HttpUrl; public class LocalPlaylistFragment extends BaseLocalListFragment, Void> implements PlaylistControlViewHolder, DebounceSavable { @@ -435,70 +426,6 @@ public class LocalPlaylistFragment extends BaseLocalListFragment playlist, - final Context context) { - - return switch (shareMode) { - - case WITH_TITLES -> exportWithTitles(playlist, context); - case JUST_URLS -> exportJustUrls(playlist); - case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist); - }; - } - - static String exportWithTitles(final List playlist, final Context context) { - - return playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(entity -> context.getString(R.string.video_details_list_item, - entity.getTitle(), - entity.getUrl() - ) - ) - .collect(Collectors.joining("\n")); - } - - static String exportJustUrls(final List playlist) { - - return playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(StreamEntity::getUrl) - .collect(Collectors.joining("\n")); - } - - static String exportAsYoutubeTempPlaylist(final List playlist) { - - final List videoIDs = - stream(reversedIterable(playlist)) - .map(PlaylistStreamEntry::getStreamEntity) - .map(entity -> getYouTubeId(entity.getUrl())) - .filter(Objects::nonNull) - .limit(50) - .collect(Collectors.toList()); - - reverse(videoIDs); - - final String commaSeparatedVideoIDs = videoIDs.stream() - .collect(Collectors.joining(",")); - - return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs; - } - - /** - * Gets the video id from a YouTube URL. - * - * @param url YouTube URL - * @return the video id - */ - static String getYouTubeId(final String url) { - - final HttpUrl httpUrl = HttpUrl.parse(url); - - return httpUrl == null ? null - : httpUrl.queryParameter("v"); - } - public void removeWatchedStreams(final boolean removePartiallyWatched) { if (isRewritingPlaylist) { return; diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java similarity index 89% rename from app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java rename to app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java index 1d5d4a6a0..f90fd78bb 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.local.playlist; +import static org.schabi.newpipe.local.playlist.ExportPlaylist.export; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; @@ -14,7 +15,7 @@ import org.schabi.newpipe.extractor.stream.StreamType; import java.util.List; import java.util.stream.Stream; -public class LocalPlaylistFragmentTest { +public class ExportPlaylistTest { @Test public void exportAsYouTubeTempPlaylist() { @@ -27,7 +28,7 @@ public class LocalPlaylistFragmentTest { "https://www.youtube.com/watch?v=3" ); - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); + final String url = export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } @@ -55,7 +56,7 @@ public class LocalPlaylistFragmentTest { .map(id -> "https://www.youtube.com/watch?v=" + id) ); - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); + final String url = export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals( @@ -80,7 +81,7 @@ public class LocalPlaylistFragmentTest { "https://www.youtube.com/watch?v=3" ); - final String exported = LocalPlaylistFragment.export(JUST_URLS, playlist, null); + final String exported = export(JUST_URLS, playlist, null); Assert.assertEquals(""" https://www.youtube.com/watch?v=1 @@ -98,7 +99,7 @@ public class LocalPlaylistFragmentTest { static List asPlaylist(final Stream urls) { return urls - .map(LocalPlaylistFragmentTest::newPlaylistStreamEntry) + .map(ExportPlaylistTest::newPlaylistStreamEntry) .toList(); } From 998d84de6c0f1ea707f9efda1ba1ac3a8bab4229 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Mon, 24 Feb 2025 20:57:06 -0300 Subject: [PATCH 08/21] [#11930] Converting to Kotlin --- .../local/playlist/ExportPlaylist.java | 90 ------------ .../newpipe/local/playlist/ExportPlaylist.kt | 72 ++++++++++ .../local/playlist/LocalPlaylistFragment.java | 2 +- .../local/playlist/ExportPlaylistTest.java | 132 ------------------ .../local/playlist/ExportPlaylistTest.kt | 110 +++++++++++++++ 5 files changed, 183 insertions(+), 223 deletions(-) delete mode 100644 app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java create mode 100644 app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt delete mode 100644 app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java create mode 100644 app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java deleted file mode 100644 index 94002dd5b..000000000 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.schabi.newpipe.local.playlist; - -import static com.google.common.collect.Streams.stream; -import static org.apache.commons.collections4.IterableUtils.reversedIterable; -import static java.util.Collections.reverse; - -import android.content.Context; - -import org.schabi.newpipe.R; -import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; -import org.schabi.newpipe.database.stream.model.StreamEntity; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -import okhttp3.HttpUrl; - - - -final class ExportPlaylist { - - private ExportPlaylist() { - } - - static String export(final PlayListShareMode shareMode, - final List playlist, - final Context context) { - - return switch (shareMode) { - - case WITH_TITLES -> exportWithTitles(playlist, context); - case JUST_URLS -> exportJustUrls(playlist); - case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist); - }; - } - - static String exportWithTitles(final List playlist, - final Context context) { - - return playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(entity -> context.getString(R.string.video_details_list_item, - entity.getTitle(), - entity.getUrl() - ) - ) - .collect(Collectors.joining("\n")); - } - - static String exportJustUrls(final List playlist) { - - return playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(StreamEntity::getUrl) - .collect(Collectors.joining("\n")); - } - - static String exportAsYoutubeTempPlaylist(final List playlist) { - - final List videoIDs = - stream(reversedIterable(playlist)) - .map(PlaylistStreamEntry::getStreamEntity) - .map(entity -> getYouTubeId(entity.getUrl())) - .filter(Objects::nonNull) - .limit(50) - .collect(Collectors.toList()); - - reverse(videoIDs); - - final String commaSeparatedVideoIDs = videoIDs.stream() - .collect(Collectors.joining(",")); - - return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs; - } - - /** - * Gets the video id from a YouTube URL. - * - * @param url YouTube URL - * @return the video id - */ - static String getYouTubeId(final String url) { - - final HttpUrl httpUrl = HttpUrl.parse(url); - - return httpUrl == null ? null - : httpUrl.queryParameter("v"); - } -} diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt new file mode 100644 index 000000000..953cb7d17 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -0,0 +1,72 @@ +package org.schabi.newpipe.local.playlist + +import android.content.Context +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull +import org.schabi.newpipe.R +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry +import org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS +import org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES +import org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST +import java.util.Objects.nonNull + +fun export( + shareMode: PlayListShareMode, + playlist: List, + context: Context +): String { + return when (shareMode) { + WITH_TITLES -> exportWithTitles(playlist, context) + JUST_URLS -> exportJustUrls(playlist) + YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist) + } +} + +fun exportWithTitles( + playlist: List, + context: Context +): String { + + return playlist.asSequence() + .map { it.streamEntity } + .map { entity -> + context.getString( + R.string.video_details_list_item, + entity.title, + entity.url + ) + } + .joinToString(separator = "\n") +} + +fun exportJustUrls(playlist: List): String { + + return playlist.asSequence() + .map { it.streamEntity.url } + .joinToString(separator = "\n") +} + +fun exportAsYoutubeTempPlaylist(playlist: List): String { + + val videoIDs = playlist.asReversed().asSequence() + .map { it.streamEntity } + .map { getYouTubeId(it.url) } + .filter(::nonNull) + .take(50) + .toList() + .asReversed() + .joinToString(separator = ",") + + return "http://www.youtube.com/watch_videos?video_ids=$videoIDs" +} + +/** + * Gets the video id from a YouTube URL. + * + * @param url YouTube URL + * @return the video id + */ +fun getYouTubeId(url: String): String? { + val httpUrl = url.toHttpUrlOrNull() + + return httpUrl?.queryParameter("v") +} 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 812d9fb38..61c12bfd4 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 @@ -2,7 +2,7 @@ package org.schabi.newpipe.local.playlist; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.ktx.ViewUtils.animate; -import static org.schabi.newpipe.local.playlist.ExportPlaylist.export; +import static org.schabi.newpipe.local.playlist.ExportPlaylistKt.export; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java deleted file mode 100644 index f90fd78bb..000000000 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.schabi.newpipe.local.playlist; - -import static org.schabi.newpipe.local.playlist.ExportPlaylist.export; -import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; -import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; - -import androidx.annotation.NonNull; - -import org.junit.Assert; -import org.junit.Test; -import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; -import org.schabi.newpipe.database.stream.model.StreamEntity; -import org.schabi.newpipe.extractor.stream.StreamType; - -import java.util.List; -import java.util.stream.Stream; - -public class ExportPlaylistTest { - - @Test - public void exportAsYouTubeTempPlaylist() { - - final List playlist = asPlaylist( - - "https://www.youtube.com/watch?v=1", - "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be - "https://www.youtube.com/watch?v=2", // ignored - "https://www.youtube.com/watch?v=3" - ); - - final String url = export(YOUTUBE_TEMP_PLAYLIST, playlist, null); - - Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); - } - - @Test - public void exportMoreThan50Items() { - /* - * Playlist has more than 50 items => take the last 50 - * (YouTube limitation) - */ - - final List ids = List.of( - - -1, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 - ); - - final List playlist = asPlaylist( - - ids.stream() - .map(id -> "https://www.youtube.com/watch?v=" + id) - ); - - final String url = export(YOUTUBE_TEMP_PLAYLIST, playlist, null); - - Assert.assertEquals( - - "http://www.youtube.com/watch_videos?video_ids=" - + "1,2,3,4,5,6,7,8,9,10," - + "11,12,13,14,15,16,17,18,19,20," - + "21,22,23,24,25,26,27,28,29,30," - + "31,32,33,34,35,36,37,38,39,40," - + "41,42,43,44,45,46,47,48,49,50", - - url - ); - } - - @Test - public void exportJustUrls() { - - final List playlist = asPlaylist( - - "https://www.youtube.com/watch?v=1", - "https://www.youtube.com/watch?v=2", - "https://www.youtube.com/watch?v=3" - ); - - final String exported = export(JUST_URLS, playlist, null); - - Assert.assertEquals(""" - https://www.youtube.com/watch?v=1 - https://www.youtube.com/watch?v=2 - https://www.youtube.com/watch?v=3""", exported); - } - - @NonNull - static List asPlaylist(final String... urls) { - - return asPlaylist(Stream.of(urls)); - } - - @NonNull - static List asPlaylist(final Stream urls) { - - return urls - .map(ExportPlaylistTest::newPlaylistStreamEntry) - .toList(); - } - - @NonNull - private static PlaylistStreamEntry newPlaylistStreamEntry(final String url) { - - return new PlaylistStreamEntry(newStreamEntity(url), 0, 0, 0); - } - - @NonNull - static StreamEntity newStreamEntity(final String url) { - - return new StreamEntity( - - 0, - 1, - url, - "Title", - StreamType.VIDEO_STREAM, - 100, - "Uploader", - null, - null, - null, - null, - null, - null - ); - } -} diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt new file mode 100644 index 000000000..42622fe9c --- /dev/null +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt @@ -0,0 +1,110 @@ +package org.schabi.newpipe.local.playlist + +import android.content.Context +import org.junit.Assert.assertEquals +import org.junit.Test +import org.mockito.Mockito.mock +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry +import org.schabi.newpipe.database.stream.model.StreamEntity +import org.schabi.newpipe.extractor.stream.StreamType +import org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS +import org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST +import java.util.stream.Stream + +class ExportPlaylistTest { + + @Test + fun exportAsYouTubeTempPlaylist() { + val playlist = asPlaylist( + "https://www.youtube.com/watch?v=1", + "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be ignored + "https://www.youtube.com/watch?v=2", + "https://www.youtube.com/watch?v=3" + ) + + val url = export(YOUTUBE_TEMP_PLAYLIST, playlist, mock(Context::class.java)) + + assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url) + } + + @Test + fun exportMoreThan50Items() { + /* + * Playlist has more than 50 items => take the last 50 + * (YouTube limitation) + */ + + val ids = listOf( + -1, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 + ) + + val playlist = asPlaylist( + ids.stream() + .map { id: Int -> "https://www.youtube.com/watch?v=$id" } + ) + + val url = export(YOUTUBE_TEMP_PLAYLIST, playlist, mock(Context::class.java)) + + assertEquals( + "http://www.youtube.com/watch_videos?video_ids=" + + "1,2,3,4,5,6,7,8,9,10," + + "11,12,13,14,15,16,17,18,19,20," + + "21,22,23,24,25,26,27,28,29,30," + + "31,32,33,34,35,36,37,38,39,40," + + "41,42,43,44,45,46,47,48,49,50", + + url + ) + } + + @Test + fun exportJustUrls() { + val playlist = asPlaylist( + "https://www.youtube.com/watch?v=1", + "https://www.youtube.com/watch?v=2", + "https://www.youtube.com/watch?v=3" + ) + + val exported = export(JUST_URLS, playlist, mock(Context::class.java)) + + assertEquals( + """ + https://www.youtube.com/watch?v=1 + https://www.youtube.com/watch?v=2 + https://www.youtube.com/watch?v=3 + """.trimIndent(), + exported + ) + } +} + +fun asPlaylist(vararg urls: String): List { + return asPlaylist(Stream.of(*urls)) +} + +fun asPlaylist(urls: Stream): List { + return urls + .map { url: String -> newPlaylistStreamEntry(url) } + .toList() +} + +fun newPlaylistStreamEntry(url: String): PlaylistStreamEntry { + return PlaylistStreamEntry(newStreamEntity(url), 0, 0, 0) +} + +fun newStreamEntity(url: String): StreamEntity { + return StreamEntity( + 0, + 1, + url, + "Title", + StreamType.VIDEO_STREAM, + 100, + "Uploader" + ) +} From 3c7b026d7d9afbb90ea41fd99bd093396d0e1e91 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 25 Feb 2025 20:23:07 -0300 Subject: [PATCH 09/21] [#11930] Updating javadoc --- .../local/playlist/LocalPlaylistFragment.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 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 61c12bfd4..de1aabb9c 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 @@ -388,16 +388,15 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Date: Wed, 26 Feb 2025 21:25:39 -0300 Subject: [PATCH 10/21] [#11930] Removing Apache Commons Collections It's no longer needed after the conversion to Kotlin. --- app/build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 2cdc952af..d03bd64e3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -255,9 +255,6 @@ dependencies { // HTTP client implementation "com.squareup.okhttp3:okhttp:4.12.0" - // Apache Commons Collections - implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.4' - // Media player implementation "com.google.android.exoplayer:exoplayer-core:${exoPlayerVersion}" implementation "com.google.android.exoplayer:exoplayer-dash:${exoPlayerVersion}" From d81244e77ce6f311520b4db63ba1984c59290a3c Mon Sep 17 00:00:00 2001 From: tfga Date: Mon, 10 Mar 2025 19:11:20 -0300 Subject: [PATCH 11/21] YT temp playlist URL: http => https Co-authored-by: Stypox --- .../java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt index 953cb7d17..226d4a8b0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -56,7 +56,7 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { .asReversed() .joinToString(separator = ",") - return "http://www.youtube.com/watch_videos?video_ids=$videoIDs" + return "https://www.youtube.com/watch_videos?video_ids=$videoIDs" } /** From c28478ae53a0380f0f053440c187769dd11219d2 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 11 Mar 2025 19:44:04 -0300 Subject: [PATCH 12/21] getYouTubeId(): Changing implementation to use YoutubeStreamLinkHandler (PR review from @Stypox) --- .../newpipe/local/playlist/ExportPlaylist.kt | 14 +++---- .../local/playlist/ExportPlaylistTest.kt | 38 ++++++++----------- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt index 226d4a8b0..72540d9d2 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -1,13 +1,13 @@ package org.schabi.newpipe.local.playlist import android.content.Context -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.schabi.newpipe.R import org.schabi.newpipe.database.playlist.PlaylistStreamEntry +import org.schabi.newpipe.extractor.exceptions.ParsingException +import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory import org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS import org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES import org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST -import java.util.Objects.nonNull fun export( shareMode: PlayListShareMode, @@ -48,9 +48,8 @@ fun exportJustUrls(playlist: List): String { fun exportAsYoutubeTempPlaylist(playlist: List): String { val videoIDs = playlist.asReversed().asSequence() - .map { it.streamEntity } - .map { getYouTubeId(it.url) } - .filter(::nonNull) + .map { it.streamEntity.url } + .mapNotNull(::getYouTubeId) .take(50) .toList() .asReversed() @@ -59,6 +58,8 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { return "https://www.youtube.com/watch_videos?video_ids=$videoIDs" } +val linkHandler: YoutubeStreamLinkHandlerFactory = YoutubeStreamLinkHandlerFactory.getInstance() + /** * Gets the video id from a YouTube URL. * @@ -66,7 +67,6 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { * @return the video id */ fun getYouTubeId(url: String): String? { - val httpUrl = url.toHttpUrlOrNull() - return httpUrl?.queryParameter("v") + return try { linkHandler.getId(url) } catch (e: ParsingException) { null } } diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt index 42622fe9c..50db490bd 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt @@ -16,15 +16,21 @@ class ExportPlaylistTest { @Test fun exportAsYouTubeTempPlaylist() { val playlist = asPlaylist( - "https://www.youtube.com/watch?v=1", + "https://www.youtube.com/watch?v=10000000000", "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be ignored - "https://www.youtube.com/watch?v=2", - "https://www.youtube.com/watch?v=3" + "https://www.youtube.com/watch?v=20000000000", + "https://www.youtube.com/watch?v=30000000000" ) val url = export(YOUTUBE_TEMP_PLAYLIST, playlist, mock(Context::class.java)) - assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url) + assertEquals( + "https://www.youtube.com/watch_videos?video_ids=" + + "10000000000," + + "20000000000," + + "30000000000", + url + ) } @Test @@ -34,30 +40,18 @@ class ExportPlaylistTest { * (YouTube limitation) */ - val ids = listOf( - -1, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 - ) - val playlist = asPlaylist( - ids.stream() - .map { id: Int -> "https://www.youtube.com/watch?v=$id" } + (10..70) + .map { id -> "https://www.youtube.com/watch?v=aaaaaaaaa$id" } // YouTube video IDs are 11 characters long + .stream() ) val url = export(YOUTUBE_TEMP_PLAYLIST, playlist, mock(Context::class.java)) - assertEquals( - "http://www.youtube.com/watch_videos?video_ids=" + - "1,2,3,4,5,6,7,8,9,10," + - "11,12,13,14,15,16,17,18,19,20," + - "21,22,23,24,25,26,27,28,29,30," + - "31,32,33,34,35,36,37,38,39,40," + - "41,42,43,44,45,46,47,48,49,50", + val videoIDs = (21..70).map { id -> "aaaaaaaaa$id" }.joinToString(",") + assertEquals( + "https://www.youtube.com/watch_videos?video_ids=$videoIDs", url ) } From f96b8f7b2a68ef0a17de762487e06c29fb315554 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 11 Mar 2025 20:19:54 -0300 Subject: [PATCH 13/21] Comment: maximum length of 50 items (PR review from @Stypox) --- .../java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt index 72540d9d2..cb619c7cc 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -50,7 +50,7 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { val videoIDs = playlist.asReversed().asSequence() .map { it.streamEntity.url } .mapNotNull(::getYouTubeId) - .take(50) + .take(50) // YouTube limitation: temp playlists can't have more than 50 items .toList() .asReversed() .joinToString(separator = ",") From 8830e87242367124d2618db9a56376761ffe20e1 Mon Sep 17 00:00:00 2001 From: tfga Date: Tue, 11 Mar 2025 20:35:18 -0300 Subject: [PATCH 14/21] YouTube video IDs are 11 characters long Co-authored-by: Stypox --- .../org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt index 50db490bd..41577742d 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt @@ -59,9 +59,9 @@ class ExportPlaylistTest { @Test fun exportJustUrls() { val playlist = asPlaylist( - "https://www.youtube.com/watch?v=1", - "https://www.youtube.com/watch?v=2", - "https://www.youtube.com/watch?v=3" + "https://www.youtube.com/watch?v=10000000000", + "https://www.youtube.com/watch?v=20000000000", + "https://www.youtube.com/watch?v=30000000000" ) val exported = export(JUST_URLS, playlist, mock(Context::class.java)) From 587df093ea66e413cecdcf5143d2453e1e3a9cbe Mon Sep 17 00:00:00 2001 From: tfga Date: Tue, 11 Mar 2025 20:35:41 -0300 Subject: [PATCH 15/21] YouTube video IDs are 11 characters long Co-authored-by: Stypox --- .../org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt index 41577742d..d9be2271e 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt @@ -68,9 +68,9 @@ class ExportPlaylistTest { assertEquals( """ - https://www.youtube.com/watch?v=1 - https://www.youtube.com/watch?v=2 - https://www.youtube.com/watch?v=3 + https://www.youtube.com/watch?v=10000000000 + https://www.youtube.com/watch?v=20000000000 + https://www.youtube.com/watch?v=30000000000 """.trimIndent(), exported ) From 599d86151a80da945c2f4ebd68c96ab04c2334e6 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 11 Mar 2025 21:26:58 -0300 Subject: [PATCH 16/21] Making ktLint happy --- .../java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt index cb619c7cc..0d4dcbfd0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -50,7 +50,7 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { val videoIDs = playlist.asReversed().asSequence() .map { it.streamEntity.url } .mapNotNull(::getYouTubeId) - .take(50) // YouTube limitation: temp playlists can't have more than 50 items + .take(50) // YouTube limitation: temp playlists can't have more than 50 items .toList() .asReversed() .joinToString(separator = ",") From f3b3d5c3e7e546e9885e0fb836674c97b67a4d14 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Wed, 12 Mar 2025 19:08:09 -0300 Subject: [PATCH 17/21] R.string.share_playlist_as_youtube_temporary_playlist --- .../schabi/newpipe/local/playlist/LocalPlaylistFragment.java | 5 ++--- app/src/main/res/values/strings.xml | 1 + 2 files changed, 3 insertions(+), 3 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 de1aabb9c..0cdc74abb 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 @@ -887,9 +887,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment sharePlaylist(WITH_TITLES) ) - // TODO R.string.share_playlist_as_YouTube_temporary_playlist - .setNeutralButton("Share as YouTube temporary playlist", (dialog, which) -> - sharePlaylist(YOUTUBE_TEMP_PLAYLIST) + .setNeutralButton(R.string.share_playlist_as_youtube_temporary_playlist, + (dialog, which) -> sharePlaylist(YOUTUBE_TEMP_PLAYLIST) ) .setNegativeButton(R.string.share_playlist_with_list, (dialog, which) -> sharePlaylist(JUST_URLS) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2c27e6cbb..7c9637f31 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -849,6 +849,7 @@ Share playlist with details such as playlist name and video titles or as a simple list of video URLs Share with Titles Share URL list + Share as YouTube temporary playlist - %1$s: %2$s %1$s\n%2$s From eb0568044ae4bdc76061281bc4351877c2cb55af Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Wed, 12 Mar 2025 19:09:31 -0300 Subject: [PATCH 18/21] R.string.share_playlist_as_youtube_temporary_playlist: pt-BR + Minor fixes to related translations --- app/src/main/res/values-pt-rBR/strings.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 9f464a11c..d7942aa99 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -791,8 +791,9 @@ Ao vivo Qualidade da imagem \? - Compartilhar URL - Compartilhar com título + Compartilhar URLs + Compartilhar com títulos + Compartilhar como playlist temporária do YouTube %1$s \n%2$s Alternar orientação da tela From 098f60d59301efebdaa014446091a4fd4970fc71 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Thu, 13 Mar 2025 18:16:09 -0300 Subject: [PATCH 19/21] Don't add the title when sharing as YouTube temp playlist --- .../newpipe/local/playlist/LocalPlaylistFragment.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 0cdc74abb..1d08bef81 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 @@ -411,12 +411,12 @@ public class LocalPlaylistFragment extends BaseLocalListFragment { - final String content = shareMode == JUST_URLS - ? urlsText - : context.getString(R.string.share_playlist_content_details, + final String content = shareMode == WITH_TITLES + ? context.getString(R.string.share_playlist_content_details, name, urlsText - ); + ) + : urlsText; ShareUtils.shareText(context, name, content); }, From be097f26c8bfdec006376c22dfc679cad66b3866 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Thu, 13 Mar 2025 19:10:26 -0300 Subject: [PATCH 20/21] Deleting the "explanatory text" bellow the title Share playlist with details such as playlist name and video titles or as a simple list of video URLs Share playlist with details such as playlist name and video titles or as a simple list of video URLs (Discussion: https://github.com/TeamNewPipe/NewPipe/pull/12065#discussion_r1994349485) --- .../org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java | 1 - app/src/main/res/values-ar-rLY/strings.xml | 1 - app/src/main/res/values-ar/strings.xml | 1 - app/src/main/res/values-az/strings.xml | 1 - app/src/main/res/values-be/strings.xml | 1 - app/src/main/res/values-bg/strings.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-da/strings.xml | 1 - app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-el/strings.xml | 1 - app/src/main/res/values-eo/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-et/strings.xml | 1 - app/src/main/res/values-eu/strings.xml | 1 - app/src/main/res/values-fi/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 | 1 - app/src/main/res/values-hi/strings.xml | 1 - app/src/main/res/values-hr/strings.xml | 1 - app/src/main/res/values-hu/strings.xml | 1 - app/src/main/res/values-in/strings.xml | 1 - app/src/main/res/values-is/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-ko/strings.xml | 1 - app/src/main/res/values-lt/strings.xml | 1 - app/src/main/res/values-lv/strings.xml | 1 - app/src/main/res/values-mk/strings.xml | 1 - app/src/main/res/values-ms/strings.xml | 1 - app/src/main/res/values-nl/strings.xml | 1 - app/src/main/res/values-or/strings.xml | 1 - app/src/main/res/values-pa/strings.xml | 1 - app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - 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 | 1 - app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values-ryu/strings.xml | 1 - app/src/main/res/values-sat/strings.xml | 1 - app/src/main/res/values-sc/strings.xml | 1 - app/src/main/res/values-sk/strings.xml | 1 - app/src/main/res/values-sr/strings.xml | 1 - app/src/main/res/values-sv/strings.xml | 1 - app/src/main/res/values-ta/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-uk/strings.xml | 1 - app/src/main/res/values-vi/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rHK/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - 53 files changed, 53 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 1d08bef81..f40e6672c 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 @@ -882,7 +882,6 @@ public class LocalPlaylistFragment extends BaseLocalListFragment sharePlaylist(WITH_TITLES) diff --git a/app/src/main/res/values-ar-rLY/strings.xml b/app/src/main/res/values-ar-rLY/strings.xml index 26c1c8b47..fa19afe78 100644 --- a/app/src/main/res/values-ar-rLY/strings.xml +++ b/app/src/main/res/values-ar-rLY/strings.xml @@ -856,6 +856,5 @@ %1$s \n%2$s شارِك قائمة التشغيل - شارِك قائمة التشغيل بتفاصيليها مثل اسم قائمة التشغيل وعناوين الفيديو أو كقائمة بسيطة من عناوين تشعّبيّة للفيديوهات - %1$s: %2$s diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 5946b6b16..8df5771d7 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -856,7 +856,6 @@ %1$s \n%2$s مشاركة قائمة التشغيل - شارك تفاصيل قائمة التشغيل مثل اسم قائمة التشغيل وعناوين الفيديو أو كقائمة بسيطة من عناوين URL للفيديو - %1$s: %2$s رد %s diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index f9be4bf46..7fe5bf335 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -787,7 +787,6 @@ Yüksək keyfiyyət \? Oynatma siyahısın paylaş - Pleylist adı və video başlıqları kimi təfsilatlar və ya video URL-lərin sadə siyahısı olaraq pleylist paylaş Başlıqlarla paylaşın - %1$s: %2$s %1$s diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index b15060e36..132bfc954 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -781,7 +781,6 @@ Пераматаць назад Паўтарыць Атрыманыя ўкладкі пры абнаўленні стужкі. Гэты параметр не прымяняецца, калі канал абнаўляецца ў хуткім рэжыме. - Абагуліць плэйліст, перадаецца назва плэйліста і назвы відэа або просты спіс URL-адрасоў відэа Сярэдняя якасць Загрузнік аватараў Банеры diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index fe0376cda..c91d00327 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -714,7 +714,6 @@ Повторение Превъртане назад Напред - Споделете плейлист с подробности, като име на плейлист и заглавия на видеоклипове или като обикновен списък с URL адреси на видеоклипове Споделяне на списък с URL Изтрии всички позиции на възпроизвеждане? Позициите за възпроизвеждане са изтрити diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index e0c92119e..c9d2e1e94 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -806,7 +806,6 @@ Alba Přetočení zpět Znovu přehrát - Sdílejte playlist s podrobnostmi jako je jeho název a názvy videí, nebo jako jednoduchý seznam adres videí Střední kvalita Bannery Playlisty diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index b7925f3a4..f1afafa5f 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -772,7 +772,6 @@ Indlæs ikke billeder Lav kvalitet Del Playliste - Del playliste med detajler såsom playlistenavn og videotitler eller som en simpel liste over video-URL\'er Del med Titler Del URL-liste diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d246233e3..a7c3f044d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s Wiedergabeliste teilen - Teile die Wiedergabeliste mit Details wie dem Namen der Wiedergabeliste und den Videotiteln oder als einfache Liste von Video-URLs - %1$s: %2$s %s Antwort diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 5d89408df..66c16c0b9 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s Κοινοποίηση λίστας - Μοιραστείτε τη λίστα αναπαραγωγής με λεπτομέρειες όπως το όνομα της λίστας αναπαραγωγής και τους τίτλους βίντεο ή ως μια απλή λίστα διευθύνσεων URL βίντεο - %1$s: %2$s %s απάντηση diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 28bc57358..66e2c4d10 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -616,7 +616,6 @@ Neniu filmofluo ludeblas por ekstera ludilo Filmetoj Filmetoj kiuj spektiĝis antaŭ aŭ post sia aldoniĝo al la ludlisto foriĝus.. \nĈu vi certas? Ĉi tio nemalfareblus! - Kunhavigus ludliston inkluzivante informojn kiel la nomoj de listeroj, aŭ kiel simpla listo de ligiloj Restarigi implicitajn agordojn Jes, kaj ankaŭ parte spektitajn filmetojn diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 5cceeff41..8e0de7864 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -818,7 +818,6 @@ %1$s \n%2$s Compartir la lista de reproducción - Compartir las listas de reproducción con los detalles como el nombre de la lista y los títulos de los vídeos o como una simple lista de una dirección URL con los vídeos - %1$s: %2$s %s respuesta diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index a002c9a0d..1758092c2 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s Jaga esitusloendit - Jaga esitusloendit kas väga detailse teabega palade kohta või lihtsa url\'ide loendina - %1$s: %2$s Näita veel diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index f38181f64..b1c393db7 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -774,7 +774,6 @@ Editatu beheko jakinarazpen ekintza bakoitza gainean sakatuz. Lehen hiru ekintzak (erreproduzitu/pausatu, aurrekoa eta hurrengoa) sistemarengatik ezarrita daude eta ezin dira pertsonalizatu. Atzera egin Irudiaren kalitatea - Partekatu erreprodukzio-zerrenda xehetasunekin, esate baterako, erreprodukzio-zerrendaren izena eta bideo-izenburuak edo bideo-URLen zerrenda soil gisa Aukera gehiago Iraupena Aurrera egin diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 889b51152..3aae66640 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -759,7 +759,6 @@ Kelaa taaksepäin Noudettavat välilehdet syötettä päivitettäessä. Tällä valinnalla ei ole vaikutusta, jos kanava päivitetään käyttämällä nopeaa tilaa. Poistetaanko kaikki ladatut tiedostot levyltä\? - Jaa soittolista, jossa on tietoja, kuten soittolistan nimi ja videon nimi, tai yksinkertainen luettelo videoiden URL-osoitteista Keskilaatu Lataajan avatarit Prosentti diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index a2ab6db1b..9c8a36557 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -817,7 +817,6 @@ Avancer Rembobiner Rejouer - Partager la liste de lecture avec des détails tel que son nom et le titre de ses vidéos ou simplement la liste des URLs des vidéos Avatars du téléverseur Sélectionnez la qualité des images et si les images doivent être chargées, pour réduire l\'utilisation de la mémoire et de données. Les modifications vident à la fois le cache des images en mémoire et sur le disque — %s Lire diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 40482eaea..84bbbb338 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -815,7 +815,6 @@ Encabezados Lapelas a mostrar nas páxinas das canles Escolla da calidade das imaxes e se cargar as imaxes na súa totalidade, para reducir o uso de datos e memoria. Os cambios limpan a caché das imaxes na memoria e no disco - %s - Compartir a lista de reprodución con detalles como o nome da lista e os títulos dos videos ou como unha lista sinxela cos enlaces URL dos videos Compartir lista de URLs A configuración da exportación a ser importada emprega un formato vulnerable que fica obsoleto dende NewPipe 0.27.0. Comprobe que a exportación que está a importar proveña dunha fonte fiable e preferibelmente empregue exportacións de NewPipe 0.27.0 ou posterior. A compatibilidade coa importación deste formato vulnerable será eliminada por completo próximamente e as versión antigas de NewPipe non poderán importar configuracións de exportacións dende novas versións. Pistas diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 45f1d0b50..def09a450 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -830,7 +830,6 @@ %1$s \n%2$s שיתוף רשימת נגינה - שיתוף רשימת נגינה עם פרטים כגון שם רשימת נגינה וכותרות סרטונים או כרשימה פשוטה של כתובות סרטונים - %1$s: %2$s להציג עוד להציג פחות diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 4a629bbe4..4640629a4 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s प्लेलिस्ट साझा करें - प्लेलिस्ट को प्लेलिस्ट नाम और वीडियो शीर्षक जैसे विवरण के साथ या वीडियो यूआरएल की एक सरल सूची के रूप में साझा करें - %1$s: %2$s %s जवाब diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 9be48f4fb..582421659 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -800,7 +800,6 @@ Srednja kvaliteta Visoka kvaliteta \? - Dijeli playlistu s detaljima kao što su ime playliste i naslovi videa ili kao jednostavan popis URL-ova videa Dijeli s naslovima Dijeli popis URL-ova – %1$s: %2$s diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 71a35db4c..216e6d733 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -796,7 +796,6 @@ Magas minőségű \? Lejátszási lista megosztása - Lejátszási lista megosztása olyan részletekkel, mint például a lejátszási lista neve és a videó címe, vagy a videó webcímek egyszerű listájaként Megosztás címekkel %1$s \n%2$s diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 3183f3014..5120a20de 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -790,7 +790,6 @@ %1$s \n%2$s Bagikan Daftar Putar - Bagikan daftar putar dengan detail seperti nama daftar putar dan judul video atau sebagai daftar video URL yang sederhana Panji - %1$s: %2$s Sentuh untuk menyunting tindakan notifikasi di bawah. Tiga tindakan pertama (mainkan/jeda, sebelumnya dan selanjutnya) disetel oleh sistem dan tidak bisa dikustomisasi. diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index edeeec214..148181861 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -792,7 +792,6 @@ Losa varanlega smámynd Breyttu hverri tilkynningu hér fyrir neðan með því að ýta á hana. Fyrstu þrjár aðgerðirnar (spila/bíða, fyrra og næsta) eru skilgreindar af kerfinu og er því ekki hægt að sérsníða. Flipar sem á að sækja við uppfærslu þessa streymis. Þetta hefur engin áhrif ef rás er uppfærð með hraðstreymisham. - Deildu spilunarlista með atriðum eins og heiti spilunarlistans og titlum myndskeiða eða sem einföldum lista yfir slóðir á myndskeið Nota varaeiginleika ExoPlayer-afkóðarans Vegna takmarkana í ExoPlayer-spilaranum var tímalengd hoppa sett á %d sekúndur Margmiðlunargöng (media tunneling) voru gerð óvirk á tækinu þínu þar sem þessi gerð tækja er þekkt fyrir að styðja ekki þennan eiginleika. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index a6a560fb4..542040d26 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -817,7 +817,6 @@ %1$s \n%2$s Condividi playlist - Condividi la playlist con dettagli come il suo nome e i titoli video o come un semplice elenco di URL video - %1$s: %2$s %s risposta diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index eeac136fc..04e54348d 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -791,7 +791,6 @@ %1$s \n%2$s プレイリストを共有 - プレイリスト名やビデオタイトルなどの詳細を含むプレイリスト、またはビデオURLのみのシンプルなリストとしてプレイリストを共有します - %1$s: %2$s %sの返信 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 39114997a..283adc7f2 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -776,7 +776,6 @@ 되감기 다시 재생 피드를 업데이트할 때 가져올 탭입니다. 빠른 모드를 사용하여 채널을 업데이트하는 경우 이 옵션은 효과가 없습니다. - 재생목록 이름, 동영상 제목 등의 세부정보 또는 간단한 동영상 URL 목록으로 재생목록을 공유하세요 중간 품질 업로더 아바타 배너 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 455f0e8c7..23476bf36 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -825,7 +825,6 @@ Vaizdo įrašai Takeliai Pasirinkite paveikslėlių kokybę ir ar apskritai įkelti paveikslėlius, kad sumažintumėte duomenų ir atminties naudojimą. Pakeitimai išvalo atmintyje ir diske esančių vaizdų talpyklą - %s - Dalintis grojaraščiu su tokia informacija kaip grojaraščio pavadinimas ir vaizdo įrašo pavadinimas arba paprastas vaizdo įrašų nuorodų sąrašas Dalintis su pavadinimais Dalintis grojaraščiu Dalintis nuorodų sąrašu diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 0698f89d3..2f528a346 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -824,7 +824,6 @@ %1$s %2$s Skaņdarbi Īsie video - Kopīgot atskaņošanas saraksta nosaukumu un to video nosaukumus vai tikai atskaņošanas sarakstā iekļauto video URL saites Kopīgot atskaņošanas sarakstu Kopīgot nosaukumus Importētā eksporta iestatījumi izmanto ievainojamo formātu, kas tika pārtraukts kopš NewPipe 0.27.0 versijas. Pārliecinieties, ka importētie dati ir no uzticama avota, un turpmāk ir vēlams izmantot tikai datus, kas veikti NewPipe 0.27.0 vai jaunākās versijās. Iestatījumu importēšanas atbalsts šajā neaizsargātajā formātā drīzumā tiks pilnībā aizvākts, un tad vecās NewPipe versijas vairs nevarēs importēt iestatījumus, kas veikti jaunajās versijās. diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index 92d265758..ba41b730b 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -713,7 +713,6 @@ Инстанцата не може да биде потврдена Изберете го квалитетот на сликите и дали воопшто да се вчитуваат слики, за да го намалите користењето на интернет и меморија. Промените го чистат кешот на сликите (анг. image cache), како и во меморијата, така и на дискот — %s - %1$s: %2$s - Споделете ја плејлистата со подробности (детали), како името на плејлистата и насловите на видеата или како едноставен список од линковите на видеата Ништо Поставките во извезениот фајл кој се увезува користат ранлив формат кој повеќе не е поддржан од NewPipe 0.27.0. Уверете се дека извезениот фајл кој се увезува е од доверлив извор и претпочитајте во иднина да користите само износи добиени од NewPipe 0.27.0 или понова верзија. Поддршката за увезување поставки од овој ранлив формат наскоро ќе биде целосно укината и тогаш старите верзии на NewPipe повеќе нема да можат да увезуваат поставки од износи од новите верзии. Побарај потврда пред чистење на редоследот diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index 9864051d8..bb0527655 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -503,7 +503,6 @@ Mutu rendah Mutu sederhana Mutu tinggi - Kongsikan senarai main dengan butiran seperti nama senarai main dan tajuk video atau sebagai senarai ringkas URL video Kongsi dengan Tajuk Kongsi senarai URL Tunjukkan lagi diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index a478ba8c3..33ed4d26d 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s Afspeellijst delen - Deel afspeellijst met details zoals afspeellijstnaam en videotitels of als een eenvoudige lijst met video-URL\'s - %1$s: %2$s %s reactie diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index 91c7f1425..cae53566e 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s ଖେଳ ତାଲିକା ସହଭାଗ କରନ୍ତୁ - ପ୍ଲେ-ଲିଷ୍ଟ ନାମ ଏବଂ ଭିଡିଓ ଶୀର୍ଷକ କିମ୍ବା ଭିଡିଓ URLଗୁଡ଼ିକର ଏକ ସରଳ ତାଲିକା ଭାବରେ ବିବରଣୀ ସହିତ ପ୍ଲେ-ଲିଷ୍ଟ ଅଂଶୀଦାର କରନ୍ତୁ - %1$s: %2$s ଅଧିକ ଦର୍ଶାନ୍ତୁ ଏହା ଉପରେ ଟ୍ୟାପ କରି ନିମ୍ନରେ ଦିଆଯାଇଥିବା ପ୍ରତ୍ୟେକ ବିଜ୍ଞପ୍ତି କାର୍ଯ୍ୟକୁ ସମ୍ପାଦନ କରନ୍ତୁ । ପ୍ରଥମ ତିନୋଟି କାର୍ଯ୍ୟ (ଖେଳ/ବିରତି, ପୂର୍ବବର୍ତ୍ତୀ ଏବଂ ପରବର୍ତ୍ତୀ) ତନ୍ତ୍ର ଦ୍ୱାରା ସେଟ କରାଯାଇଥାଏ ଏବଂ ଏହାକୁ ଇଚ୍ଛାରୂପଣ କରାଯାଇପାରିବ ନାହିଁ । diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index bfb51a738..0da6cdd09 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s ਪਲੇਲਿਸਟ ਸਾਂਝੀ ਕਰੋ - ਪਲੇਲਿਸਟ ਨੂੰ ਪਲੇਲਿਸਟ ਨਾਮ ਅਤੇ ਵੀਡੀਓ ਸਿਰਲੇਖ ਜਿਹੇ ਵੇਰਵਿਆਂ ਸਮੇਤ ਜਾਂ ਵੀਡੀਓ URL ਦੀ ਇੱਕ ਸਰਲ ਸੂਚੀ ਦੇ ਰੂਪ ਵਿੱਚ ਸਾਂਝਾ ਕਰੋ - %1$s: %2$s %s ਜਵਾਬ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b3a43f403..63768acb5 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -825,7 +825,6 @@ %1$s \n%2$s Udostępnij playlistę - Udostępnij playlistę ze szczegółami, takimi jak nazwa playlisty i tytuły wideo, lub jako prostą listę adresów URL wideo. – %1$s: %2$s %s odpowiedź diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index d7942aa99..e0b58da6a 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -809,7 +809,6 @@ Avançar Retroceder Repetir - Compartilhar playlist com detalhes como o nome da playlist e títulos de vídeo ou como uma lista simples dos URL de vídeos Qualidade média Fotos de perfil do autor - %1$s: %2$s diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 59c77daca..85e951b8e 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -804,7 +804,6 @@ Recuar Repetição Separadores a obter ao atualizar o feed. Esta opção não tem efeito se um canal for atualizado utilizando o modo rápido. - Partilhe a lista de reprodução com detalhes como o nome da lista de reprodução e os títulos dos vídeos ou como uma simples lista de URLs de vídeos Média qualidade Avatar dos publicadores Bandeiras diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index bd98dc7d8..1326e0ca7 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -817,7 +817,6 @@ Canais Vídeo anterior Direto - Partilhe a lista de reprodução com detalhes como o nome da lista de reprodução e os títulos dos vídeos ou como uma simples lista de URLs de vídeos Escolha a qualidade das imagens e se pretende carregar imagens, para reduzir a utilização de dados e de memória. As alterações limpam a cache de imagens na memória e no disco - %s Mostrar mais diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 3cc83967f..fc62b5d1e 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -791,7 +791,6 @@ File ce vor fi preluate când se actualizează fluxul. Această opțiune nu are niciun efect dacă un canal este actualizat folosind modul rapid. Selectați o coloană sonoră cu descrieri pentru persoane cu deficiențe vizuale, dacă este disponibilă Acțiunea gestului din stânga - Distribuiți playlistul cu detalii precum numele playlistului și titlurile videourilor sau ca o simplă listă de URL-uri a videourilor Calitate medie Preferați audioul descriptiv Modificați dimensiunea intervalului de încărcare pentru conținuturi progresive (în prezent %s). O valoare mai mică poate accelera încărcarea lor inițială diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 35fdb8263..71dcdaea4 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -808,7 +808,6 @@ Перемотать назад Повторить Получаемые вкладки при обновлении ленты. Эта функция не применяется, если канал обновляется с помощью быстрого режима. - Поделиться подборкой с подробностями, такими как название подборки и названия видео, или просто списком URL видео Среднее качество Загрузчик аватаров Баннеры diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index c0195057a..0396245e1 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s プレイリストちゅーゆーいん - プレイリストめいてぃがろービデオタイトルんでーぬしょうさいくくむるプレイリスト、あらんでぃビデオURLぬみぬシンプルやるリストとぅしてぃプレイリストちゅーゆーいんさびーん - %1$s: %2$s %sぬへんしん diff --git a/app/src/main/res/values-sat/strings.xml b/app/src/main/res/values-sat/strings.xml index 751a0cde7..8b44cd5e0 100644 --- a/app/src/main/res/values-sat/strings.xml +++ b/app/src/main/res/values-sat/strings.xml @@ -678,7 +678,6 @@ ᱞᱟᱯᱷᱟᱝ ᱥᱤᱠᱷᱱᱟ. ᱛᱟᱞᱢᱟ ᱥᱤᱠᱷᱱᱟᱹᱛ ᱩᱥᱩᱞ ᱥᱤᱠᱷᱱᱟᱹᱛ - ᱯᱷᱟᱭᱞᱤᱥᱴ ᱧᱩᱛᱩᱢ ᱟᱨ ᱵᱷᱤᱰᱤᱭᱳ ᱧᱩᱛᱩᱢ ᱞᱮᱠᱟᱛᱮ ᱟᱨᱵᱟᱝ ᱵᱷᱤᱰᱤᱭᱳ URL ᱨᱮᱱᱟᱜ ᱢᱤᱫ ᱞᱮᱠᱟᱱ ᱞᱤᱥᱴᱤ ᱞᱮᱠᱟᱛᱮ ᱴᱷᱟᱶ ᱮᱢ ᱢᱮ URL ᱛᱟᱹᱞᱠᱟᱹ ᱥᱟᱯᱲᱟᱣ - %1$s: %2$s ᱱᱚᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ ᱨᱮ ᱑᱖:᱙ ᱠᱷᱚᱱ ᱑:᱑ ᱟᱥᱯᱮᱠᱴ ᱚᱱᱩᱯᱟᱹᱛ ᱨᱮ ᱵᱷᱤᱰᱤᱭᱳ ᱛᱷᱚᱢᱵᱱᱮᱞ ᱜᱮᱫᱽ ᱢᱮ diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 9b6fb5863..d92532c31 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -788,7 +788,6 @@ Torra in segus Torra a reprodùere Ischedas de recuperare cando agiornas sa fonte. Custa optzione non tenet efetu si unu canale benit agiornadu impreende sa modalidade lestra. - Cumpartzi s\'iscalita cun detàllios che a su nùmene de s\'iscalita e sos tìtulos de sos vìdeos o che a una lista simpre de URL de vìdeos Calidade mesana Avatars de su carrigadore Insignas diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 0677feb95..dee7b1264 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -823,7 +823,6 @@ %s odpovede %s odpovedí - Zdieľajte playlist s podrobnosťami, ako je jeho názov a názvy videí, alebo ako jednoduchý zoznam URL adries videí - %1$s: %2$s %1$s \n%2$s diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index a837451ba..5c8c28a57 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -817,7 +817,6 @@ %1$s \n%2$s Дели плејлисту - Делите плејлисту са детаљима, као што су назив плејлисте и наслови видео снимака или као једноставна листа URL адреса видео снимака -%1$s: %2$s %s одговор diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 740143d0b..c85d17220 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -804,7 +804,6 @@ Uppladdarens visningsbilder Banderoller - %1$s: %2$s - Dela spellistan med detaljer så som spellistans namn och video-titlarna eller som en enkel lista med URL till videorna Välj bildkvalitet och om bilder överhuvudtaget ska laddas för att minska data och minnesanvändningen. Ändringar rensar både i minnet och bildcache på disk – %s Visa mer diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 958df593e..0056f7416 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -470,7 +470,6 @@ முன்னோக்கி பட தகுதி உயர் தகுதி - பிளேலிச்ட் பெயர் மற்றும் வீடியோ தலைப்புகள் போன்ற விவரங்களுடன் அல்லது வீடியோ முகவரி களின் எளிய பட்டியலாக பிளேலிச்ட்டைப் பகிரவும் மேலும் விருப்பங்கள் காலம் முன்னாடி diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index a87dac75e..ccd3b3b62 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -791,7 +791,6 @@ Geri sar Yeniden oynat Besleme güncellenirken alınacak sekmeler. Hızlı kip kullanılırken kanal güncelleniyorsa bu seçeneğin etkisi yoktur. - Oynatma listesini, oynatma listesi adı ve video başlıkları gibi ayrıntılarla ya da video adreslerinin basit listesi olarak paylaş Orta nitelik Yükleyen avatarları Afişler diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 39fdddd67..22d9eb478 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -821,7 +821,6 @@ %1$s \n%2$s Поділитися добіркою - Поділитися добіркою з подробицями, такими як назва добірки та назви відео, або просто списком URL-адрес відео - %1$s: %2$s Показати більше Відредагуйте кожну дію сповіщення, натиснувши на неї. Перші три дії (відтворення/пауза, попередній і наступний) встановлюються системою і не можуть бути змінені. diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 23a0c96dc..22bc03c2c 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -787,7 +787,6 @@ Tua đi Album Tua lại - Chia sẻ danh sách phát với các thông tin chi tiết như tên danh sách phát và tiêu đề video hoặc dưới dạng danh sách URL video đơn giản Chất lượng trung bình - %1$s: %2$s Chọn chất lượng hình ảnh và chọn có tải chất lượng ảnh hay không, để giảm mức sử dụng dữ liệu và bộ nhớ. Thay đổi xoá cache ảnh cho cả trong bộ nhớ lẫn ổ cứng - %s diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 5efb32d4f..e8d19cb8b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -791,7 +791,6 @@ %1$s \n%2$s 分享播放列表 - 分享详细的播放列表(带名称和视频标题等信息)或只分享视频网址列表 - %1$s: %2$s %s 条回复 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 0a862a48d..c804c53c0 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -775,7 +775,6 @@ 跳後 重播 更新摘要嘅時候要攞邊啲分頁返嚟。若果頻道用快速模式更新,就橫豎都無相干嘞。 - 分享播放清單要詳細包含播放清單個名同埋入面啲片名,定簡單得啲影片嘅 URL 一般畫質 上載者嘅頭像 橫額 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 30d66f124..030c23f60 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -791,7 +791,6 @@ %1$s \n%2$s 分享播放清單 - 分享包含播放清單名稱與影片標題等詳細資訊的播放清單,或是僅作為簡單的影片網址清單 - %1$s:%2$s %s 個回覆 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7c9637f31..729dae48c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -846,7 +846,6 @@ High quality \? Share Playlist - Share playlist with details such as playlist name and video titles or as a simple list of video URLs Share with Titles Share URL list Share as YouTube temporary playlist From 2ceb70236ef27b070eebbda25cbcca778db2c8e2 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Fri, 14 Mar 2025 21:56:42 -0300 Subject: [PATCH 21/21] sharePlaylist(): converting javadoc from Markdown back to "classic javadoc" (request from @Stypox) --- .../local/playlist/LocalPlaylistFragment.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 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 f40e6672c..f5562549c 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 @@ -388,15 +388,16 @@ public class LocalPlaylistFragment extends BaseLocalListFragment + *
  • {@code JUST_URLS}: shares the URLs only.
  • + *
  • {@code WITH_TITLES}: each entry in the list is accompanied by its title.
  • + *
  • {@code YOUTUBE_TEMP_PLAYLIST}: shares as a YouTube temporary playlist.
  • + * + * + * @param shareMode The way the playlist should be shared. + */ private void sharePlaylist(final PlayListShareMode shareMode) { final Context context = requireContext();