diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 008dc4a9c..e8d8573a1 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -1,5 +1,7 @@ package org.schabi.newpipe.local.playlist; +import static com.google.common.collect.Streams.stream; +import static org.apache.commons.collections4.IterableUtils.reversedIterable; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.ktx.ViewUtils.animate; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; @@ -7,6 +9,8 @@ import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout; +import static java.util.Collections.reverse; + import android.content.Context; import android.os.Bundle; import android.os.Parcelable; @@ -30,7 +34,9 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.viewbinding.ViewBinding; import com.evernote.android.state.State; +import com.google.common.collect.Streams; +import org.apache.commons.collections4.IterableUtils; import org.apache.commons.collections4.queue.CircularFifoQueue; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; @@ -408,7 +414,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Single.just(export( shareMode, - playlist.stream().map(PlaylistStreamEntry::getStreamEntity), + playlist, context ))) .observeOn(AndroidSchedulers.mainThread()) @@ -430,20 +436,21 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream, + final List playlist, final Context context) { return switch (shareMode) { - case WITH_TITLES -> exportWithTitles(entityStream, context); - case JUST_URLS -> exportJustUrls(entityStream); - case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(entityStream); + case WITH_TITLES -> exportWithTitles(playlist, context); + case JUST_URLS -> exportJustUrls(playlist); + case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist); }; } - static String exportWithTitles(final Stream entityStream, final Context context) { + static String exportWithTitles(final List playlist, final Context context) { - return entityStream + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) .map(entity -> context.getString(R.string.video_details_list_item, entity.getTitle(), entity.getUrl() @@ -452,26 +459,30 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream) { + static String exportJustUrls(final List playlist) { - return entityStream + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) .map(StreamEntity::getUrl) .collect(Collectors.joining("\n")); } - static String exportAsYoutubeTempPlaylist(final Stream entityStream) { + static String exportAsYoutubeTempPlaylist(final List playlist) { - final CircularFifoQueue last50 = new CircularFifoQueue<>(50); - - entityStream + final List videoIDs = + stream(reversedIterable(playlist)) + .map(PlaylistStreamEntry::getStreamEntity) .map(entity -> getYouTubeId(entity.getUrl())) .filter(Objects::nonNull) - .forEachOrdered(last50::add); + .limit(50) + .collect(Collectors.toList()); - final String videoIDs = last50.stream() - .collect(Collectors.joining(",")); + reverse(videoIDs); - return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; + final String commaSeparatedVideoIDs = videoIDs.stream() + .collect(Collectors.joining(",")); + + return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs; } /** diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index eca798a24..1d5d4a6a0 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; import org.junit.Assert; import org.junit.Test; +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.extractor.stream.StreamType; @@ -18,7 +19,7 @@ public class LocalPlaylistFragmentTest { @Test public void exportAsYouTubeTempPlaylist() { - final Stream entityStream = asStreamEntityStream( + final List playlist = asPlaylist( "https://www.youtube.com/watch?v=1", "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be @@ -26,7 +27,7 @@ public class LocalPlaylistFragmentTest { "https://www.youtube.com/watch?v=3" ); - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } @@ -48,11 +49,13 @@ public class LocalPlaylistFragmentTest { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 ); - final Stream entityStream = ids.stream() - .map(id -> "https://www.youtube.com/watch?v=" + id) - .map(LocalPlaylistFragmentTest::newStreamEntity); + final List playlist = asPlaylist( - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + ids.stream() + .map(id -> "https://www.youtube.com/watch?v=" + id) + ); + + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals( @@ -70,14 +73,14 @@ public class LocalPlaylistFragmentTest { @Test public void exportJustUrls() { - final Stream entityStream = asStreamEntityStream( + final List playlist = asPlaylist( "https://www.youtube.com/watch?v=1", "https://www.youtube.com/watch?v=2", "https://www.youtube.com/watch?v=3" ); - final String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); + final String exported = LocalPlaylistFragment.export(JUST_URLS, playlist, null); Assert.assertEquals(""" https://www.youtube.com/watch?v=1 @@ -86,10 +89,23 @@ public class LocalPlaylistFragmentTest { } @NonNull - private static Stream asStreamEntityStream(final String... urls) { + static List asPlaylist(final String... urls) { - return Stream.of(urls) - .map(LocalPlaylistFragmentTest::newStreamEntity); + return asPlaylist(Stream.of(urls)); + } + + @NonNull + static List asPlaylist(final Stream urls) { + + return urls + .map(LocalPlaylistFragmentTest::newPlaylistStreamEntry) + .toList(); + } + + @NonNull + private static PlaylistStreamEntry newPlaylistStreamEntry(final String url) { + + return new PlaylistStreamEntry(newStreamEntity(url), 0, 0, 0); } @NonNull