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 0d8f8133440..28711c6fe2b 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
@@ -51,8 +51,8 @@
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.OnClickGesture;
-import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.PlayButtonHelper;
+import org.schabi.newpipe.util.external_communication.ShareUtils;
import java.util.ArrayList;
import java.util.Collections;
@@ -346,7 +346,7 @@ public void onComplete() {
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (item.getItemId() == R.id.menu_item_share_playlist) {
- sharePlaylist();
+ createShareConfirmationDialog();
} else if (item.getItemId() == R.id.menu_item_rename_playlist) {
createRenameDialog();
} else if (item.getItemId() == R.id.menu_item_remove_watched) {
@@ -374,16 +374,33 @@ public boolean onOptionsItemSelected(final MenuItem item) {
}
/**
- * Share the playlist as a newline-separated list of stream URLs.
+ * Shares the playlist as a list of stream URLs if {@code shouldSharePlaylistDetails} 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}.
+ *
+ * @param shouldSharePlaylistDetails Whether the playlist details should be included in the
+ * shared content.
*/
- public void sharePlaylist() {
+ private void sharePlaylist(final boolean shouldSharePlaylistDetails) {
+ final Context context = requireContext();
+
disposables.add(playlistManager.getPlaylistStreams(playlistId)
.flatMapSingle(playlist -> Single.just(playlist.stream()
.map(PlaylistStreamEntry::getStreamEntity)
- .map(StreamEntity::getUrl)
+ .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(requireContext(), name, urlsText),
+ .subscribe(urlsText -> ShareUtils.shareText(
+ context, name, shouldSharePlaylistDetails
+ ? context.getString(R.string.share_playlist_content_details,
+ name, urlsText) : urlsText),
throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable)));
}
@@ -841,5 +858,24 @@ private PlayQueue getPlayQueue(final int index) {
}
return new SinglePlayQueue(streamInfoItems, index);
}
+
+ /**
+ * Creates a dialog to confirm whether the user wants to share the playlist
+ * with the playlist details or just the list of stream URLs.
+ * After the user has made a choice, the playlist is shared.
+ */
+ 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(/* shouldSharePlaylistDetails= */ true)
+ )
+ .setNegativeButton(R.string.share_playlist_with_list, (dialog, which) ->
+ sharePlaylist(/* shouldSharePlaylistDetails= */ false)
+ )
+ .show();
+ }
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9dfca829440..bf618739c16 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -832,4 +832,10 @@
Medium quality
High quality
\?
-
\ No newline at end of file
+ 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
+ - %s: %s
+ %s\n%s
+