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 +