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 | 98 ++++++++++++++----- .../local/playlist/PlayListShareMode.java | 8 ++ .../playlist/LocalPlaylistFragmentTest.java | 55 +++++++++++ 3 files changed, 137 insertions(+), 24 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 c87d9cccccd..3e99b01c4ec 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 @@ 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.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 boolean onOptionsItemSelected(final MenuItem item) { } /** - * Shares the playlist as a list of stream URLs if {@code shouldSharePlaylistDetails} is + * FIXME update this + * + * Shares the playlist as a list of stream URLs if {@code shareMode} is * set to {@code false}. Shares the playlist name along with a list of video titles and URLs - * if {@code shouldSharePlaylistDetails} is set to {@code true}. + * if {@code shareMode} is set to {@code true}. * - * @param shouldSharePlaylistDetails Whether the playlist details should be included in the - * shared content. + * @param shareMode Whether the playlist details should be included in the + * shared content. */ - private void sharePlaylist(final boolean shouldSharePlaylistDetails) { + private void sharePlaylist(PlayListShareMode shareMode) { final Context context = requireContext(); disposables.add(playlistManager.getPlaylistStreams(playlistId) - .flatMapSingle(playlist -> 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 @@ private void createShareConfirmationDialog() { .setMessage(R.string.share_playlist_with_titles_message) .setCancelable(true) .setPositiveButton(R.string.share_playlist_with_titles, (dialog, which) -> - 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 00000000000..3de1effc980 --- /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 00000000000..41e1f60916b --- /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 41e1f60916b..12242ad1d1b 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 @@ 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 3e99b01c4ec..354985b8583 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 boolean onOptionsItemSelected(final MenuItem item) { * @param shareMode Whether the playlist details should be included in the * shared content. */ - private void sharePlaylist(PlayListShareMode shareMode) { + private void sharePlaylist(final PlayListShareMode shareMode) { final Context context = requireContext(); disposables.add(playlistManager.getPlaylistStreams(playlistId) - .flatMapSingle(playlist -> 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 @@ static String export(PlayListShareMode shareMode, Stream entityStr }; } - static String exportWithTitles(Stream 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 @@ static String exportAsYoutubeTempPlaylist(Stream entityStream) { } /** - * Gets the video id from a YouTube URL + * Gets the video id from a YouTube URL. + * + * @param url YouTube URL + * @return the video id */ - static String getYouTubeId(String url) { + static String getYouTubeId(final String url) { - HttpUrl httpUrl = HttpUrl.parse(url); + final HttpUrl httpUrl = HttpUrl.parse(url); return httpUrl == null ? null - : httpUrl.queryParameter("v") - ; + : httpUrl.queryParameter("v"); } public void removeWatchedStreams(final boolean removePartiallyWatched) { @@ -924,7 +942,8 @@ private void createShareConfirmationDialog() { .setPositiveButton(R.string.share_playlist_with_titles, (dialog, which) -> 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 3de1effc980..f0433aba8c3 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 @@ 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 12242ad1d1b..170193155c3 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.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 void export_justUrls() { } @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 354985b8583..cb47c2199e3 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 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 @@ static String exportAsYoutubeTempPlaylist(final Stream entityStrea final String videoIDs = entityStream .map(entity -> 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 170193155c3..fb93a9e8605 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 void exportAsYouTubeTempPlaylist() { 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 d03bd64e320..2cdc952af96 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 cb47c2199e3..008dc4a9c33 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 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 @@ static String exportJustUrls(final Stream entityStream) { static String exportAsYoutubeTempPlaylist(final Stream 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 fb93a9e8605..eca798a243f 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.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 void exportAsYouTubeTempPlaylist() { 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 | 36 ++++++++++----- 2 files changed, 54 insertions(+), 27 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 008dc4a9c33..e8d8573a1b3 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.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.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 @@ private void sharePlaylist(final PlayListShareMode shareMode) { .flatMapSingle(playlist -> Single.just(export( shareMode, - playlist.stream().map(PlaylistStreamEntry::getStreamEntity), + playlist, context ))) .observeOn(AndroidSchedulers.mainThread()) @@ -430,20 +436,21 @@ private void sharePlaylist(final PlayListShareMode shareMode) { } static String export(final PlayListShareMode shareMode, - final Stream 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 @@ static String exportWithTitles(final Stream entityStream, final Co .collect(Collectors.joining("\n")); } - static String exportJustUrls(final Stream 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) { - - final CircularFifoQueue last50 = new CircularFifoQueue<>(50); + static String exportAsYoutubeTempPlaylist(final List playlist) { - 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()); + + reverse(videoIDs); - final String videoIDs = last50.stream() - .collect(Collectors.joining(",")); + final String commaSeparatedVideoIDs = videoIDs.stream() + .collect(Collectors.joining(",")); - return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; + 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 eca798a243f..1d5d4a6a0ad 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 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 void exportAsYouTubeTempPlaylist() { "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 void exportMoreThan50Items() { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 ); - final Stream entityStream = ids.stream() + final List playlist = asPlaylist( + + ids.stream() .map(id -> "https://www.youtube.com/watch?v=" + id) - .map(LocalPlaylistFragmentTest::newStreamEntity); + ); - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals( @@ -70,14 +73,14 @@ public void exportMoreThan50Items() { @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 void exportJustUrls() { } @NonNull - private static Stream asStreamEntityStream(final String... urls) { + static List asPlaylist(final String... urls) { + + 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 Stream.of(urls) - .map(LocalPlaylistFragmentTest::newStreamEntity); + 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 00000000000..94002dd5bfa --- /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 e8d8573a1b3..812d9fb3856 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.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 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 @@ private void sharePlaylist(final PlayListShareMode shareMode) { ); } - 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"); - } - 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 1d5d4a6a0ad..f90fd78bb1d 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 java.util.List; import java.util.stream.Stream; -public class LocalPlaylistFragmentTest { +public class ExportPlaylistTest { @Test public void exportAsYouTubeTempPlaylist() { @@ -27,7 +28,7 @@ public void exportAsYouTubeTempPlaylist() { "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 void exportMoreThan50Items() { .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 void exportJustUrls() { "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 @@ static List asPlaylist(final String... urls) { 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 94002dd5bfa..00000000000 --- 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 00000000000..953cb7d174d --- /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 812d9fb3856..61c12bfd4ad 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 @@ 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 f90fd78bb1d..00000000000 --- 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 00000000000..42622fe9cf0 --- /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 61c12bfd4ad..de1aabb9cc9 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 boolean onOptionsItemSelected(final MenuItem item) { return true; } - /** - * FIXME update this - * - * Shares the playlist as a list of stream URLs if {@code shareMode} is - * set to {@code false}. Shares the playlist name along with a list of video titles and URLs - * if {@code shareMode} is set to {@code true}. - * - * @param shareMode Whether the playlist details should be included in the - * shared content. - */ + /// + /// Shares the playlist in one of 3 ways, depending on the value of `shareMode`: + /// + /// - `JUST_URLS`: shares the URLs only. + /// - `WITH_TITLES`: each entry in the list is accompanied by its title. + /// - `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(); From 0fd2d4fed619abbc2aa43a8640c9592dea559aba Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" 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 2cdc952af96..d03bd64e320 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 953cb7d174d..226d4a8b0ad 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 226d4a8b0ad..72540d9d20f 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 42622fe9cf0..50db490bdbd 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 72540d9d20f..cb619c7cca9 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 50db490bdbd..41577742d12 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 41577742d12..d9be2271e76 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 cb619c7cca9..0d4dcbfd071 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 de1aabb9cc9..0cdc74abb93 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 @@ private void createShareConfirmationDialog() { .setPositiveButton(R.string.share_playlist_with_titles, (dialog, which) -> 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 2c27e6cbb76..7c9637f31e1 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 9f464a11c1e..d7942aa993d 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 0cdc74abb93..1d08bef810f 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 @@ private void sharePlaylist(final PlayListShareMode shareMode) { .subscribe( urlsText -> { - 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 1d08bef810f..f40e6672cf3 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 @@ private PlayQueue getPlayQueue(final int index) { private void createShareConfirmationDialog() { new AlertDialog.Builder(requireContext()) .setTitle(R.string.share_playlist) - .setMessage(R.string.share_playlist_with_titles_message) .setCancelable(true) .setPositiveButton(R.string.share_playlist_with_titles, (dialog, which) -> 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 26c1c8b4796..fa19afe7837 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 5946b6b16e7..8df5771d785 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 f9be4bf4653..7fe5bf335c2 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 b15060e36c8..132bfc95446 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 fe0376cdaa4..c91d0032700 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 e0c92119efe..c9d2e1e9434 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 b7925f3a4bf..f1afafa5f1f 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 d246233e329..a7c3f044d71 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 5d89408df90..66c16c0b9e9 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 28bc57358f2..66e2c4d104f 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 5cceeff41c6..8e0de7864e8 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 a002c9a0dac..1758092c23b 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 f38181f648d..b1c393db7ff 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 889b5115284..3aae666406e 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 a2ab6db1bd9..9c8a36557ae 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 40482eaea5a..84bbbb3387e 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 45f1d0b50bb..def09a450f7 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 4a629bbe428..4640629a4aa 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 9be48f4fb70..58242165915 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 71a35db4c19..216e6d7333a 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 3183f301410..5120a20de6a 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 edeeec21480..14818186132 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 a6a560fb409..542040d263c 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 eeac136fc04..04e54348dbb 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 39114997aa2..283adc7f2db 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 455f0e8c7ff..23476bf3602 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 0698f89d3ac..2f528a34625 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 92d26575865..ba41b730bb7 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 9864051d836..bb0527655ea 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 a478ba8c3a1..33ed4d26d72 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 91c7f142546..cae53566e09 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 bfb51a738ac..0da6cdd0928 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 b3a43f403e0..63768acb59a 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 d7942aa993d..e0b58da6acb 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 59c77daca66..85e951b8eef 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 bd98dc7d816..1326e0ca761 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 3cc83967f1c..fc62b5d1e44 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 35fdb826392..71dcdaea4bc 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 c0195057a8d..0396245e102 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 751a0cde75d..8b44cd5e084 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 9b6fb586393..d92532c31de 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 0677feb95c7..dee7b1264ac 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 a837451baf7..5c8c28a5700 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 740143d0b8d..c85d172201f 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 958df593e6c..0056f74166c 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 a87dac75e3f..ccd3b3b62cd 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 39fdddd6757..22d9eb478ee 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 23a0c96dc20..22bc03c2cb8 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 5efb32d4f0c..e8d19cb8b8d 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 0a862a48d07..c804c53c0f3 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 30d66f124e5..030c23f60de 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 7c9637f31e1..729dae48cb8 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 f40e6672cf3..f5562549cf5 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 boolean onOptionsItemSelected(final MenuItem item) { return true; } - /// - /// Shares the playlist in one of 3 ways, depending on the value of `shareMode`: - /// - /// - `JUST_URLS`: shares the URLs only. - /// - `WITH_TITLES`: each entry in the list is accompanied by its title. - /// - `YOUTUBE_TEMP_PLAYLIST`: shares as a YouTube temporary playlist. - /// - /// @param shareMode The way the playlist should be shared. - /// + /** + * Shares the playlist in one of 3 ways, depending on the value of {@code shareMode}: + *
    + *
  • {@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();