diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index 4b5c260e0..199b8b2da 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -409,7 +409,7 @@ public abstract class BaseListFragment extends BaseStateFragment return; } - new InfoItemDialog.Builder(activity, this, item).create().show(); + new InfoItemDialog.Builder(activity, context, this, item).create().show(); } /*////////////////////////////////////////////////////////////////////////// diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 14d77b31d..3485678d6 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -142,8 +142,8 @@ public class PlaylistFragment extends BaseListInfoFragment { 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( diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java index 11489621d..6db66ef14 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java @@ -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 entries = new ArrayList<>(); private final boolean addDefaultEntriesAutomatically; + /** + *

Create a Builder instance that automatically adds the some default entries + * at the top and bottom of the dialog.

+ * The dialog has the following structure: + *
+         *     + - - - - - - - - - - - - - - - - - - - - - -+
+         *     | 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                       |
+         *     + - - - - - - - - - - - - - - - - - - - - - -+
+         * 
+ * 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); } /** - *

Create an instance of this Builder

+ *

Create an instance of this Builder.

+ *

If {@code addDefaultEntriesAutomatically} is set to {@code true}, + * some default entries are added to the top and bottom of the dialog.

+ * The dialog has the following structure: + *
+         *     + - - - - - - - - - - - - - - - - - - - - - -+
+         *     | 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                       |
+         *     + - - - - - - - - - - - - - - - - - - - - - -+
+         * 
+ * 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}. + *
+ * 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. + *
+ * 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); } diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index 63e918739..5c1c78902 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -357,7 +357,7 @@ class FeedFragment : BaseStateFragment() { 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 { diff --git a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java index 8567f3804..b33a5b5af 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java @@ -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); 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 bd6957cd0..a46370f8c 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 @@ -747,8 +747,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment + * This enum provides entries that are accepted + * by the {@link org.schabi.newpipe.info_list.InfoItemDialog.Builder}. + *

+ *

+ * 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 onClick()). + *
+ * They action can be overridden by using the Builder's + * {@link org.schabi.newpipe.info_list.InfoItemDialog.Builder#setAction( + * StreamDialogDefaultEntry, StreamDialogEntry.StreamDialogEntryAction)} + * method. + *

+ */ 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) { diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/KoreUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/KoreUtils.java index 6801f24ef..0df579d88 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/KoreUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/KoreUtils.java @@ -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 Kodi website + */ public final class KoreUtils { private KoreUtils() { }