parent
50e2385e82
commit
962fe9c36d
|
@ -409,7 +409,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
|||
return;
|
||||
}
|
||||
|
||||
new InfoItemDialog.Builder(activity, this, item).create().show();
|
||||
new InfoItemDialog.Builder(activity, context, this, item).create().show();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -142,8 +142,8 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
|||
return;
|
||||
}
|
||||
|
||||
final InfoItemDialog.Builder dialogBuilder = new InfoItemDialog.Builder(
|
||||
activity, this, item);
|
||||
final InfoItemDialog.Builder dialogBuilder =
|
||||
new InfoItemDialog.Builder(activity, context, this, item);
|
||||
|
||||
dialogBuilder.setAction(StreamDialogDefaultEntry.START_HERE_ON_BACKGROUND,
|
||||
(fragment, infoItem) -> NavigationHelper.playOnBackgroundPlayer(
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package org.schabi.newpipe.info_list;
|
||||
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
@ -24,10 +23,18 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Dialog with actions for a {@link StreamInfoItem}.
|
||||
* Dialog for a {@link StreamInfoItem}.
|
||||
* The dialog'S content are actions that can be performed on the {@link StreamInfoItem}.
|
||||
* This dialog is mostly used for longpress context menus.
|
||||
*/
|
||||
public final class InfoItemDialog {
|
||||
/**
|
||||
* Ideally, {@link InfoItemDialog} would extend {@link AlertDialog}.
|
||||
* However, extending {@link AlertDialog} requires many additional lines
|
||||
* and brings more complexity to this class, especially the constructor.
|
||||
* To circumvent this, an {@link AlertDialog.Builder} is used in the constructor.
|
||||
* Its result is stored in this class variable to allow access via the {@link #show()} method.
|
||||
*/
|
||||
private final AlertDialog dialog;
|
||||
|
||||
private InfoItemDialog(@NonNull final Activity activity,
|
||||
|
@ -76,38 +83,100 @@ public final class InfoItemDialog {
|
|||
*/
|
||||
public static class Builder {
|
||||
@NonNull private final Activity activity;
|
||||
@NonNull private final Context context;
|
||||
@NonNull private final StreamInfoItem infoItem;
|
||||
@NonNull private final Fragment fragment;
|
||||
@NonNull private final List<StreamDialogEntry> entries = new ArrayList<>();
|
||||
private final boolean addDefaultEntriesAutomatically;
|
||||
|
||||
/**
|
||||
* <p>Create a Builder instance that automatically adds the some default entries
|
||||
* at the top and bottom of the dialog.</p>
|
||||
* The dialog has the following structure:
|
||||
* <pre>
|
||||
* + - - - - - - - - - - - - - - - - - - - - - -+
|
||||
* | ENQUEUE |
|
||||
* | ENQUEUE_HERE |
|
||||
* | START_ON_BACKGROUND |
|
||||
* | START_ON_POPUP |
|
||||
* + - - - - - - - - - - - - - - - - - - - - - -+
|
||||
* | entries added manually with |
|
||||
* | addEntry() and addAllEntries() |
|
||||
* + - - - - - - - - - - - - - - - - - - - - - -+
|
||||
* | APPEND_PLAYLIST |
|
||||
* | SHARE |
|
||||
* | OPEN_IN_BROWSER |
|
||||
* | PLAY_WITH_KODI |
|
||||
* | MARK_AS_WATCHED |
|
||||
* | SHOW_CHANNEL_DETAILS |
|
||||
* + - - - - - - - - - - - - - - - - - - - - - -+
|
||||
* </pre>
|
||||
* Please note that some entries are not added depending on the user's preferences,
|
||||
* the item's {@link StreamType} and the current player state.
|
||||
*
|
||||
* @param activity
|
||||
* @param context
|
||||
* @param fragment
|
||||
* @param infoItem the item for this dialog; all entries and their actions work with
|
||||
* this {@link org.schabi.newpipe.extractor.InfoItem}
|
||||
*/
|
||||
public Builder(@NonNull final Activity activity,
|
||||
@NonNull final Context context,
|
||||
@NonNull final Fragment fragment,
|
||||
@NonNull final StreamInfoItem infoItem) {
|
||||
this(activity, fragment, infoItem, true);
|
||||
this(activity, context, fragment, infoItem, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Create an instance of this Builder</p>
|
||||
* <p>Create an instance of this Builder.</p>
|
||||
* <p>If {@code addDefaultEntriesAutomatically} is set to {@code true},
|
||||
* some default entries are added to the top and bottom of the dialog.</p>
|
||||
* The dialog has the following structure:
|
||||
* <pre>
|
||||
* + - - - - - - - - - - - - - - - - - - - - - -+
|
||||
* | ENQUEUE |
|
||||
* | ENQUEUE_HERE |
|
||||
* | START_ON_BACKGROUND |
|
||||
* | START_ON_POPUP |
|
||||
* + - - - - - - - - - - - - - - - - - - - - - -+
|
||||
* | entries added manually with |
|
||||
* | addEntry() and addAllEntries() |
|
||||
* + - - - - - - - - - - - - - - - - - - - - - -+
|
||||
* | APPEND_PLAYLIST |
|
||||
* | SHARE |
|
||||
* | OPEN_IN_BROWSER |
|
||||
* | PLAY_WITH_KODI |
|
||||
* | MARK_AS_WATCHED |
|
||||
* | SHOW_CHANNEL_DETAILS |
|
||||
* + - - - - - - - - - - - - - - - - - - - - - -+
|
||||
* </pre>
|
||||
* Please note that some entries are not added depending on the user's preferences,
|
||||
* the item's {@link StreamType} and the current player state.
|
||||
*
|
||||
* @param activity
|
||||
* @param context
|
||||
* @param fragment
|
||||
* @param infoItem
|
||||
* @param addDefaultEntriesAutomatically whether default entries added with
|
||||
* {@link #addDefaultEntriesAtBeginning()} and
|
||||
* {@link #addDefaultEntriesAtEnd()}
|
||||
* are added automatically when generating
|
||||
* the {@link InfoItemDialog}.
|
||||
* @param addDefaultEntriesAutomatically
|
||||
* whether default entries added with {@link #addDefaultBeginningEntries()}
|
||||
* and {@link #addDefaultEndEntries()} are added automatically when generating
|
||||
* the {@link InfoItemDialog}.
|
||||
* <br/>
|
||||
* Entries added with {@link #addEntry(StreamDialogDefaultEntry)} and
|
||||
* {@link #addAllEntries(StreamDialogDefaultEntry...)} are added in between.
|
||||
*/
|
||||
public Builder(@NonNull final Activity activity,
|
||||
@NonNull final Context context,
|
||||
@NonNull final Fragment fragment,
|
||||
@NonNull final StreamInfoItem infoItem,
|
||||
final boolean addDefaultEntriesAutomatically) {
|
||||
this.activity = activity;
|
||||
this.context = context;
|
||||
this.fragment = fragment;
|
||||
this.infoItem = infoItem;
|
||||
this.addDefaultEntriesAutomatically = addDefaultEntriesAutomatically;
|
||||
if (addDefaultEntriesAutomatically) {
|
||||
addDefaultEntriesAtBeginning();
|
||||
addDefaultBeginningEntries();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,12 +208,11 @@ public final class InfoItemDialog {
|
|||
}
|
||||
}
|
||||
|
||||
public void addChannelDetailsEntryIfPossible() {
|
||||
if (!isNullOrEmpty(infoItem.getUploaderUrl())) {
|
||||
addEntry(StreamDialogDefaultEntry.SHOW_CHANNEL_DETAILS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@link StreamDialogDefaultEntry#ENQUEUE} if the player is open and
|
||||
* {@link StreamDialogDefaultEntry#ENQUEUE_NEXT} if there are multiple streams
|
||||
* in the play queue.
|
||||
*/
|
||||
public void addEnqueueEntriesIfNeeded() {
|
||||
if (PlayerHolder.getInstance().isPlayerOpen()) {
|
||||
addEntry(StreamDialogDefaultEntry.ENQUEUE);
|
||||
|
@ -155,6 +223,11 @@ public final class InfoItemDialog {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the {@link StreamDialogDefaultEntry#START_HERE_ON_BACKGROUND}.
|
||||
* If the {@link #infoItem} is not a pure audio (live) stream,
|
||||
* {@link StreamDialogDefaultEntry#START_HERE_ON_POPUP} is added, too.
|
||||
*/
|
||||
public void addStartHereEntries() {
|
||||
addEntry(StreamDialogDefaultEntry.START_HERE_ON_BACKGROUND);
|
||||
if (infoItem.getStreamType() != StreamType.AUDIO_STREAM
|
||||
|
@ -169,8 +242,8 @@ public final class InfoItemDialog {
|
|||
*/
|
||||
public void addMarkAsWatchedEntryIfNeeded() {
|
||||
final boolean isWatchHistoryEnabled = PreferenceManager
|
||||
.getDefaultSharedPreferences(activity)
|
||||
.getBoolean(activity.getString(R.string.enable_watch_history_key), false);
|
||||
.getDefaultSharedPreferences(context)
|
||||
.getBoolean(context.getString(R.string.enable_watch_history_key), false);
|
||||
if (isWatchHistoryEnabled
|
||||
&& infoItem.getStreamType() != StreamType.LIVE_STREAM
|
||||
&& infoItem.getStreamType() != StreamType.AUDIO_LIVE_STREAM) {
|
||||
|
@ -179,17 +252,26 @@ public final class InfoItemDialog {
|
|||
}
|
||||
|
||||
public void addPlayWithKodiEntryIfNeeded() {
|
||||
if (KoreUtils.shouldShowPlayWithKodi(activity, infoItem.getServiceId())) {
|
||||
if (KoreUtils.shouldShowPlayWithKodi(context, infoItem.getServiceId())) {
|
||||
addEntry(StreamDialogDefaultEntry.PLAY_WITH_KODI);
|
||||
}
|
||||
}
|
||||
|
||||
public void addDefaultEntriesAtBeginning() {
|
||||
/**
|
||||
* Add the entries which are usually at the top of the action list.
|
||||
* <br/>
|
||||
* This method adds the "enqueue" (see {@link #addEnqueueEntriesIfNeeded()})
|
||||
* and "start here" (see {@link #addStartHereEntries()} entries.
|
||||
*/
|
||||
public void addDefaultBeginningEntries() {
|
||||
addEnqueueEntriesIfNeeded();
|
||||
addStartHereEntries();
|
||||
}
|
||||
|
||||
public void addDefaultEntriesAtEnd() {
|
||||
/**
|
||||
* Add the entries which are usually at the bottom of the action list.
|
||||
*/
|
||||
public void addDefaultEndEntries() {
|
||||
addAllEntries(
|
||||
StreamDialogDefaultEntry.APPEND_PLAYLIST,
|
||||
StreamDialogDefaultEntry.SHARE,
|
||||
|
@ -197,7 +279,7 @@ public final class InfoItemDialog {
|
|||
);
|
||||
addPlayWithKodiEntryIfNeeded();
|
||||
addMarkAsWatchedEntryIfNeeded();
|
||||
addChannelDetailsEntryIfPossible();
|
||||
addEntry(StreamDialogDefaultEntry.SHOW_CHANNEL_DETAILS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,7 +288,7 @@ public final class InfoItemDialog {
|
|||
*/
|
||||
public InfoItemDialog create() {
|
||||
if (addDefaultEntriesAutomatically) {
|
||||
addDefaultEntriesAtEnd();
|
||||
addDefaultEndEntries();
|
||||
}
|
||||
return new InfoItemDialog(this.activity, this.fragment, this.infoItem, this.entries);
|
||||
}
|
||||
|
|
|
@ -357,7 +357,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
|||
val activity: Activity? = getActivity()
|
||||
if (context == null || context.resources == null || activity == null) return
|
||||
|
||||
InfoItemDialog.Builder(activity, this, item).create().show()
|
||||
InfoItemDialog.Builder(activity, context, this, item).create().show()
|
||||
}
|
||||
|
||||
private val listenerStreamItem = object : OnItemClickListener, OnItemLongClickListener {
|
||||
|
|
|
@ -332,8 +332,8 @@ public class StatisticsPlaylistFragment
|
|||
}
|
||||
final StreamInfoItem infoItem = item.toStreamInfoItem();
|
||||
|
||||
final InfoItemDialog.Builder dialogBuilder = new InfoItemDialog.Builder(
|
||||
activity, this, infoItem);
|
||||
final InfoItemDialog.Builder dialogBuilder =
|
||||
new InfoItemDialog.Builder(activity, context, this, infoItem);
|
||||
|
||||
// set entries in the middle; the others are added automatically
|
||||
dialogBuilder.addEntry(StreamDialogDefaultEntry.DELETE);
|
||||
|
|
|
@ -747,8 +747,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
|||
}
|
||||
final StreamInfoItem infoItem = item.toStreamInfoItem();
|
||||
|
||||
final InfoItemDialog.Builder dialogBuilder = new InfoItemDialog.Builder(
|
||||
activity, this, infoItem);
|
||||
final InfoItemDialog.Builder dialogBuilder =
|
||||
new InfoItemDialog.Builder(activity, context, this, infoItem);
|
||||
|
||||
// add entries in the middle
|
||||
dialogBuilder.addAllEntries(
|
||||
|
|
|
@ -12,6 +12,9 @@ import androidx.fragment.app.Fragment;
|
|||
import org.schabi.newpipe.NewPipeDatabase;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.database.stream.model.StreamEntity;
|
||||
import org.schabi.newpipe.error.ErrorInfo;
|
||||
import org.schabi.newpipe.error.ErrorUtil;
|
||||
import org.schabi.newpipe.error.UserAction;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
|
||||
import org.schabi.newpipe.local.dialog.PlaylistDialog;
|
||||
|
@ -25,11 +28,23 @@ import java.util.Collections;
|
|||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This enum provides entries that are accepted
|
||||
* by the {@link org.schabi.newpipe.info_list.InfoItemDialog.Builder}.
|
||||
* </p>
|
||||
* <p>
|
||||
* These entries contain a String {@link #resource} which is displayed in the dialog and
|
||||
* a default {@link #action} that is executed
|
||||
* when the entry is selected (via <code>onClick()</code>).
|
||||
* <br/>
|
||||
* They action can be overridden by using the Builder's
|
||||
* {@link org.schabi.newpipe.info_list.InfoItemDialog.Builder#setAction(
|
||||
* StreamDialogDefaultEntry, StreamDialogEntry.StreamDialogEntryAction)}
|
||||
* method.
|
||||
* </p>
|
||||
*/
|
||||
public enum StreamDialogDefaultEntry {
|
||||
//////////////////////////////////////
|
||||
// enum values with DEFAULT actions //
|
||||
//////////////////////////////////////
|
||||
|
||||
SHOW_CHANNEL_DETAILS(R.string.show_channel_details, (fragment, item) -> {
|
||||
if (isNullOrEmpty(item.getUploaderUrl())) {
|
||||
final int serviceId = item.getServiceId();
|
||||
|
@ -125,6 +140,7 @@ public enum StreamDialogDefaultEntry {
|
|||
public final int resource;
|
||||
@NonNull
|
||||
public final StreamDialogEntry.StreamDialogEntryAction action;
|
||||
|
||||
StreamDialogDefaultEntry(@StringRes final int resource,
|
||||
@NonNull final StreamDialogEntry.StreamDialogEntryAction action) {
|
||||
this.resource = resource;
|
||||
|
@ -136,10 +152,6 @@ public enum StreamDialogDefaultEntry {
|
|||
return new StreamDialogEntry(resource, action);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// private method to open channel fragment //
|
||||
/////////////////////////////////////////////
|
||||
|
||||
private static void openChannelFragment(@NonNull final Fragment fragment,
|
||||
@NonNull final StreamInfoItem item,
|
||||
final String uploaderUrl) {
|
||||
|
|
|
@ -10,6 +10,10 @@ import org.schabi.newpipe.R;
|
|||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
|
||||
/**
|
||||
* Util class that provides methods which are related to the Kodi Media Center and its Kore app.
|
||||
* @see <a href="https://kodi.tv/">Kodi website</a>
|
||||
*/
|
||||
public final class KoreUtils {
|
||||
private KoreUtils() { }
|
||||
|
||||
|
|
Loading…
Reference in New Issue