Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

import androidx.fragment.app.FragmentManager;

import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.local.dialog.PlaylistCreationDialog;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.NavigationHelper;
Expand Down Expand Up @@ -47,13 +47,15 @@ public static void openPopupMenu(final PlayQueue playQueue,
false);
return true;
case R.id.menu_item_append_playlist:
final PlaylistAppendDialog d = PlaylistAppendDialog.fromPlayQueueItems(
Collections.singletonList(item)
PlaylistDialog.createCorrespondingDialog(
context,
Collections.singletonList(new StreamEntity(item)),
dialog -> dialog.show(
fragmentManager,
"QueueItemMenuUtil@append_playlist"
)
);
PlaylistAppendDialog.onPlaylistFound(context,
() -> d.show(fragmentManager, "QueueItemMenuUtil@append_playlist"),
() -> PlaylistCreationDialog.newInstance(d)
.show(fragmentManager, "QueueItemMenuUtil@append_playlist"));

return true;
case R.id.menu_item_share:
shareText(context, item.getTitle(), item.getUrl(),
Expand Down
63 changes: 58 additions & 5 deletions app/src/main/java/org/schabi/newpipe/RouterActivity.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.schabi.newpipe;

import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO;
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO;

import android.annotation.SuppressLint;
import android.app.IntentService;
import android.content.Context;
Expand Down Expand Up @@ -30,6 +33,7 @@
import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceManager;

import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
import org.schabi.newpipe.download.DownloadDialog;
Expand All @@ -56,6 +60,7 @@
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.player.MainPlayer;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.helper.PlayerHolder;
Expand All @@ -69,14 +74,15 @@
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.urlfinder.UrlFinder;
import org.schabi.newpipe.views.FocusOverlayView;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import icepick.Icepick;
Expand All @@ -89,9 +95,6 @@
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.schedulers.Schedulers;

import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO;
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO;

/**
* Get the url from the intent and open it in the chosen preferred player.
*/
Expand All @@ -107,6 +110,7 @@ public class RouterActivity extends AppCompatActivity {
protected String currentUrl;
private StreamingService currentService;
private boolean selectionIsDownload = false;
private boolean selectionIsAddToPlaylist = false;
private AlertDialog alertDialogChoice = null;

@Override
Expand Down Expand Up @@ -350,7 +354,7 @@ private void showDialog(final List<AdapterChoiceItem> choices) {
.setNegativeButton(R.string.just_once, dialogButtonsClickListener)
.setPositiveButton(R.string.always, dialogButtonsClickListener)
.setOnDismissListener((dialog) -> {
if (!selectionIsDownload) {
if (!selectionIsDownload && !selectionIsAddToPlaylist) {
finish();
}
})
Expand Down Expand Up @@ -446,6 +450,10 @@ private List<AdapterChoiceItem> getChoicesForService(final StreamingService serv
final AdapterChoiceItem backgroundPlayer = new AdapterChoiceItem(
getString(R.string.background_player_key), getString(R.string.background_player),
R.drawable.ic_headset);
final AdapterChoiceItem addToPlaylist = new AdapterChoiceItem(
getString(R.string.add_to_playlist_key), getString(R.string.add_to_playlist),
R.drawable.ic_add);


if (linkType == LinkType.STREAM) {
if (isExtVideoEnabled) {
Expand Down Expand Up @@ -482,6 +490,10 @@ private List<AdapterChoiceItem> getChoicesForService(final StreamingService serv
getString(R.string.download),
R.drawable.ic_file_download));

// Add to playlist is not necessary for CHANNEL and PLAYLIST linkType since those can
// not be added to a playlist
returnList.add(addToPlaylist);

} else {
returnList.add(showInfo);
if (capabilities.contains(VIDEO) && !isExtVideoEnabled) {
Expand Down Expand Up @@ -547,6 +559,12 @@ private void handleChoice(final String selectedChoiceKey) {
return;
}

if (selectedChoiceKey.equals(getString(R.string.add_to_playlist_key))) {
selectionIsAddToPlaylist = true;
openAddToPlaylistDialog();
return;
}

// stop and bypass FetcherService if InfoScreen was selected since
// StreamDetailFragment can fetch data itself
if (selectedChoiceKey.equals(getString(R.string.show_info_key))) {
Expand All @@ -572,6 +590,41 @@ private void handleChoice(final String selectedChoiceKey) {
finish();
}

private void openAddToPlaylistDialog() {
// Getting the stream info usually takes a moment
// Notifying the user here to ensure that no confusion arises
Toast.makeText(
getApplicationContext(),
getString(R.string.processing_may_take_a_moment),
Toast.LENGTH_SHORT)
.show();

disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
info -> PlaylistDialog.createCorrespondingDialog(
getThemeWrapperContext(),
Collections.singletonList(new StreamEntity(info)),
playlistDialog -> {
playlistDialog.setOnDismissListener(dialog -> finish());

playlistDialog.show(
this.getSupportFragmentManager(),
"addToPlaylistDialog"
);
}
),
throwable -> handleError(this, new ErrorInfo(
throwable,
UserAction.REQUESTED_STREAM,
"Tried to add " + currentUrl + " to a playlist",
currentService.getServiceId())
)
)
);
}

@SuppressLint("CheckResult")
private void openDownloadDialog() {
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

import org.schabi.newpipe.App;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.FragmentVideoDetailBinding;
import org.schabi.newpipe.download.DownloadDialog;
import org.schabi.newpipe.error.ErrorActivity;
Expand All @@ -73,8 +74,7 @@
import org.schabi.newpipe.fragments.list.comments.CommentsFragment;
import org.schabi.newpipe.fragments.list.videos.RelatedItemsFragment;
import org.schabi.newpipe.ktx.AnimationType;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.local.dialog.PlaylistCreationDialog;
import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.player.MainPlayer;
import org.schabi.newpipe.player.MainPlayer.PlayerType;
Expand All @@ -99,6 +99,7 @@
import org.schabi.newpipe.util.external_communication.ShareUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
Expand Down Expand Up @@ -444,12 +445,11 @@ public void onClick(final View v) {
break;
case R.id.detail_controls_playlist_append:
if (getFM() != null && currentInfo != null) {

final PlaylistAppendDialog d = PlaylistAppendDialog.fromStreamInfo(currentInfo);
disposables.add(
PlaylistAppendDialog.onPlaylistFound(getContext(),
() -> d.show(getFM(), TAG),
() -> PlaylistCreationDialog.newInstance(d).show(getFM(), TAG)
PlaylistDialog.createCorrespondingDialog(
getContext(),
Collections.singletonList(new StreamEntity(currentInfo)),
dialog -> dialog.show(getFM(), TAG)
)
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.schabi.newpipe.local.dialog;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
Expand All @@ -17,20 +16,14 @@
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.local.LocalItemListAdapter;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.OnClickGesture;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;

public final class PlaylistAppendDialog extends PlaylistDialog {
private static final String TAG = PlaylistAppendDialog.class.getCanonicalName();
Expand All @@ -40,47 +33,8 @@ public final class PlaylistAppendDialog extends PlaylistDialog {

private final CompositeDisposable playlistDisposables = new CompositeDisposable();

public static Disposable onPlaylistFound(
final Context context, final Runnable onSuccess, final Runnable onFailed
) {
final LocalPlaylistManager playlistManager =
new LocalPlaylistManager(NewPipeDatabase.getInstance(context));

return playlistManager.hasPlaylists()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(hasPlaylists -> {
if (hasPlaylists) {
onSuccess.run();
} else {
onFailed.run();
}
});
}

public static PlaylistAppendDialog fromStreamInfo(final StreamInfo info) {
final PlaylistAppendDialog dialog = new PlaylistAppendDialog();
dialog.setInfo(Collections.singletonList(new StreamEntity(info)));
return dialog;
}

public static PlaylistAppendDialog fromStreamInfoItems(final List<StreamInfoItem> items) {
final PlaylistAppendDialog dialog = new PlaylistAppendDialog();
final List<StreamEntity> entities = new ArrayList<>(items.size());
for (final StreamInfoItem item : items) {
entities.add(new StreamEntity(item));
}
dialog.setInfo(entities);
return dialog;
}

public static PlaylistAppendDialog fromPlayQueueItems(final List<PlayQueueItem> items) {
final PlaylistAppendDialog dialog = new PlaylistAppendDialog();
final List<StreamEntity> entities = new ArrayList<>(items.size());
for (final PlayQueueItem item : items) {
entities.add(new StreamEntity(item));
}
dialog.setInfo(entities);
return dialog;
public PlaylistAppendDialog(final List<StreamEntity> streamEntities) {
super(streamEntities);
}

/*//////////////////////////////////////////////////////////////////////////
Expand All @@ -104,11 +58,15 @@ public void onViewCreated(@NonNull final View view, @Nullable final Bundle saved
playlistAdapter.setSelectedListener(new OnClickGesture<LocalItem>() {
@Override
public void selected(final LocalItem selectedItem) {
if (!(selectedItem instanceof PlaylistMetadataEntry) || getStreams() == null) {
if (!(selectedItem instanceof PlaylistMetadataEntry)
|| getStreamEntities() == null) {
return;
}
onPlaylistSelected(playlistManager, (PlaylistMetadataEntry) selectedItem,
getStreams());
onPlaylistSelected(
playlistManager,
(PlaylistMetadataEntry) selectedItem,
getStreamEntities()
);
}
});

Expand Down Expand Up @@ -146,11 +104,17 @@ public void onDestroyView() {
//////////////////////////////////////////////////////////////////////////*/

public void openCreatePlaylistDialog() {
if (getStreams() == null || !isAdded()) {
if (getStreamEntities() == null || !isAdded()) {
return;
}

PlaylistCreationDialog.newInstance(getStreams()).show(getParentFragmentManager(), TAG);
final PlaylistCreationDialog playlistCreationDialog =
new PlaylistCreationDialog(getStreamEntities());
// Move the dismissListener to the new dialog.
playlistCreationDialog.setOnDismissListener(this.getOnDismissListener());
this.setOnDismissListener(null);

playlistCreationDialog.show(getParentFragmentManager(), TAG);
requireDialog().dismiss();
}

Expand All @@ -165,7 +129,7 @@ private void onPlaylistsReceived(@NonNull final List<PlaylistMetadataEntry> play
private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager,
@NonNull final PlaylistMetadataEntry playlist,
@NonNull final List<StreamEntity> streams) {
if (getStreams() == null) {
if (getStreamEntities() == null) {
return;
}

Expand Down
Loading