11package org .schabi .newpipe .info_list ;
22
3+ import static org .schabi .newpipe .MainActivity .DEBUG ;
4+
35import android .app .Activity ;
46import android .content .Context ;
57import android .content .DialogInterface ;
8+ import android .os .Build ;
9+ import android .util .Log ;
610import android .view .View ;
711import android .widget .TextView ;
812
1115import androidx .fragment .app .Fragment ;
1216import androidx .preference .PreferenceManager ;
1317
18+ import org .schabi .newpipe .App ;
1419import org .schabi .newpipe .R ;
20+ import org .schabi .newpipe .error .ErrorInfo ;
21+ import org .schabi .newpipe .error .ErrorUtil ;
22+ import org .schabi .newpipe .error .UserAction ;
23+ import org .schabi .newpipe .extractor .InfoItem ;
1524import org .schabi .newpipe .extractor .stream .StreamInfoItem ;
1625import org .schabi .newpipe .extractor .stream .StreamType ;
1726import org .schabi .newpipe .player .helper .PlayerHolder ;
2130
2231import java .util .ArrayList ;
2332import java .util .List ;
33+ import java .util .stream .Stream ;
2434
2535/**
2636 * Dialog for a {@link StreamInfoItem}.
27- * The dialog'S content are actions that can be performed on the {@link StreamInfoItem}.
37+ * The dialog's content are actions that can be performed on the {@link StreamInfoItem}.
2838 * This dialog is mostly used for longpress context menus.
2939 */
3040public final class InfoItemDialog {
41+ private static final String TAG = Build .class .getSimpleName ();
3142 /**
3243 * Ideally, {@link InfoItemDialog} would extend {@link AlertDialog}.
3344 * However, extending {@link AlertDialog} requires many additional lines
@@ -42,6 +53,7 @@ private InfoItemDialog(@NonNull final Activity activity,
4253 @ NonNull final StreamInfoItem info ,
4354 @ NonNull final List <StreamDialogEntry > entries ) {
4455
56+ // Create the dialog's title
4557 final View bannerView = View .inflate (activity , R .layout .dialog_title , null );
4658 bannerView .setSelected (true );
4759
@@ -56,9 +68,11 @@ private InfoItemDialog(@NonNull final Activity activity,
5668 detailsView .setVisibility (View .GONE );
5769 }
5870
71+ // Get the entry's descriptions which are displayed in the dialog
5972 final String [] items = entries .stream ()
6073 .map (entry -> entry .getString (activity )).toArray (String []::new );
6174
75+ // Call an entry's action / onClick method when the entry is selected.
6276 final DialogInterface .OnClickListener action = (d , index ) ->
6377 entries .get (index ).action .onClick (fragment , info );
6478
@@ -96,7 +110,7 @@ public static class Builder {
96110 * <pre>
97111 * + - - - - - - - - - - - - - - - - - - - - - -+
98112 * | ENQUEUE |
99- * | ENQUEUE_HERE |
113+ * | ENQUEUE_NEXT |
100114 * | START_ON_BACKGROUND |
101115 * | START_ON_POPUP |
102116 * + - - - - - - - - - - - - - - - - - - - - - -+
@@ -118,10 +132,12 @@ public static class Builder {
118132 * @param context
119133 * @param fragment
120134 * @param infoItem the item for this dialog; all entries and their actions work with
121- * this {@link org.schabi.newpipe.extractor.InfoItem}
135+ * this {@link StreamInfoItem}
136+ * @throws IllegalArgumentException if <code>activity, context</code>
137+ * or resources is <code>null</code>
122138 */
123- public Builder (@ NonNull final Activity activity ,
124- @ NonNull final Context context ,
139+ public Builder (final Activity activity ,
140+ final Context context ,
125141 @ NonNull final Fragment fragment ,
126142 @ NonNull final StreamInfoItem infoItem ) {
127143 this (activity , context , fragment , infoItem , true );
@@ -135,7 +151,7 @@ public Builder(@NonNull final Activity activity,
135151 * <pre>
136152 * + - - - - - - - - - - - - - - - - - - - - - -+
137153 * | ENQUEUE |
138- * | ENQUEUE_HERE |
154+ * | ENQUEUE_NEXT |
139155 * | START_ON_BACKGROUND |
140156 * | START_ON_POPUP |
141157 * + - - - - - - - - - - - - - - - - - - - - - -+
@@ -164,12 +180,21 @@ public Builder(@NonNull final Activity activity,
164180 * <br/>
165181 * Entries added with {@link #addEntry(StreamDialogDefaultEntry)} and
166182 * {@link #addAllEntries(StreamDialogDefaultEntry...)} are added in between.
183+ * @throws IllegalArgumentException if <code>activity, context</code>
184+ * or resources is <code>null</code>
167185 */
168- public Builder (@ NonNull final Activity activity ,
169- @ NonNull final Context context ,
186+ public Builder (final Activity activity ,
187+ final Context context ,
170188 @ NonNull final Fragment fragment ,
171189 @ NonNull final StreamInfoItem infoItem ,
172190 final boolean addDefaultEntriesAutomatically ) {
191+ if (activity == null || context == null || context .getResources () == null ) {
192+ if (DEBUG ) {
193+ Log .d (TAG , "activity, context or resources is null: activity = "
194+ + activity + ", context = " + context );
195+ }
196+ throw new IllegalArgumentException ("activity, context or resources is null" );
197+ }
173198 this .activity = activity ;
174199 this .context = context ;
175200 this .fragment = fragment ;
@@ -180,14 +205,24 @@ public Builder(@NonNull final Activity activity,
180205 }
181206 }
182207
183- public void addEntry (@ NonNull final StreamDialogDefaultEntry entry ) {
208+ /**
209+ * Adds a new entry and appends it to the current entry list.
210+ * @param entry the entry to add
211+ * @return the current {@link Builder} instance
212+ */
213+ public Builder addEntry (@ NonNull final StreamDialogDefaultEntry entry ) {
184214 entries .add (entry .toStreamDialogEntry ());
215+ return this ;
185216 }
186217
187- public void addAllEntries (@ NonNull final StreamDialogDefaultEntry ... newEntries ) {
188- for (final StreamDialogDefaultEntry entry : newEntries ) {
189- this .entries .add (entry .toStreamDialogEntry ());
190- }
218+ /**
219+ * Adds new entries. These are appended to the current entry list.
220+ * @param newEntries the entries to add
221+ * @return the current {@link Builder} instance
222+ */
223+ public Builder addAllEntries (@ NonNull final StreamDialogDefaultEntry ... newEntries ) {
224+ Stream .of (newEntries ).forEach (this ::addEntry );
225+ return this ;
191226 }
192227
193228 /**
@@ -197,50 +232,57 @@ public void addAllEntries(@NonNull final StreamDialogDefaultEntry... newEntries)
197232 * does not have an effect.</p>
198233 * @param entry the entry to change
199234 * @param action the action to perform when the entry is selected
235+ * @return the current {@link Builder} instance
200236 */
201- public void setAction (@ NonNull final StreamDialogDefaultEntry entry ,
237+ public Builder setAction (@ NonNull final StreamDialogDefaultEntry entry ,
202238 @ NonNull final StreamDialogEntry .StreamDialogEntryAction action ) {
203239 for (int i = 0 ; i < entries .size (); i ++) {
204240 if (entries .get (i ).resource == entry .resource ) {
205241 entries .set (i , new StreamDialogEntry (entry .resource , action ));
206- return ;
242+ return this ;
207243 }
208244 }
245+ return this ;
209246 }
210247
211248 /**
212249 * Adds {@link StreamDialogDefaultEntry#ENQUEUE} if the player is open and
213250 * {@link StreamDialogDefaultEntry#ENQUEUE_NEXT} if there are multiple streams
214251 * in the play queue.
252+ * @return the current {@link Builder} instance
215253 */
216- public void addEnqueueEntriesIfNeeded () {
254+ public Builder addEnqueueEntriesIfNeeded () {
217255 if (PlayerHolder .getInstance ().isPlayerOpen ()) {
218256 addEntry (StreamDialogDefaultEntry .ENQUEUE );
219257
220258 if (PlayerHolder .getInstance ().getQueueSize () > 1 ) {
221259 addEntry (StreamDialogDefaultEntry .ENQUEUE_NEXT );
222260 }
223261 }
262+ return this ;
224263 }
225264
226265 /**
227266 * Adds the {@link StreamDialogDefaultEntry#START_HERE_ON_BACKGROUND}.
228267 * If the {@link #infoItem} is not a pure audio (live) stream,
229268 * {@link StreamDialogDefaultEntry#START_HERE_ON_POPUP} is added, too.
269+ * @return the current {@link Builder} instance
230270 */
231- public void addStartHereEntries () {
271+ public Builder addStartHereEntries () {
232272 addEntry (StreamDialogDefaultEntry .START_HERE_ON_BACKGROUND );
233273 if (infoItem .getStreamType () != StreamType .AUDIO_STREAM
234274 && infoItem .getStreamType () != StreamType .AUDIO_LIVE_STREAM ) {
235275 addEntry (StreamDialogDefaultEntry .START_HERE_ON_POPUP );
236276 }
277+ return this ;
237278 }
238279
239280 /**
240281 * Adds {@link StreamDialogDefaultEntry.MARK_AS_WATCHED} if the watch history is enabled
241282 * and the stream is not a livestream.
283+ * @return the current {@link Builder} instance
242284 */
243- public void addMarkAsWatchedEntryIfNeeded () {
285+ public Builder addMarkAsWatchedEntryIfNeeded () {
244286 final boolean isWatchHistoryEnabled = PreferenceManager
245287 .getDefaultSharedPreferences (context )
246288 .getBoolean (context .getString (R .string .enable_watch_history_key ), false );
@@ -249,29 +291,38 @@ public void addMarkAsWatchedEntryIfNeeded() {
249291 && infoItem .getStreamType () != StreamType .AUDIO_LIVE_STREAM ) {
250292 addEntry (StreamDialogDefaultEntry .MARK_AS_WATCHED );
251293 }
294+ return this ;
252295 }
253296
254- public void addPlayWithKodiEntryIfNeeded () {
297+ /**
298+ * Adds the {@link StreamDialogDefaultEntry.PLAY_WITH_KODI} entry if it is needed.
299+ * @return the current {@link Builder} instance
300+ */
301+ public Builder addPlayWithKodiEntryIfNeeded () {
255302 if (KoreUtils .shouldShowPlayWithKodi (context , infoItem .getServiceId ())) {
256303 addEntry (StreamDialogDefaultEntry .PLAY_WITH_KODI );
257304 }
305+ return this ;
258306 }
259307
260308 /**
261309 * Add the entries which are usually at the top of the action list.
262310 * <br/>
263311 * This method adds the "enqueue" (see {@link #addEnqueueEntriesIfNeeded()})
264312 * and "start here" (see {@link #addStartHereEntries()} entries.
313+ * @return the current {@link Builder} instance
265314 */
266- public void addDefaultBeginningEntries () {
315+ public Builder addDefaultBeginningEntries () {
267316 addEnqueueEntriesIfNeeded ();
268317 addStartHereEntries ();
318+ return this ;
269319 }
270320
271321 /**
272322 * Add the entries which are usually at the bottom of the action list.
323+ * @return the current {@link Builder} instance
273324 */
274- public void addDefaultEndEntries () {
325+ public Builder addDefaultEndEntries () {
275326 addAllEntries (
276327 StreamDialogDefaultEntry .APPEND_PLAYLIST ,
277328 StreamDialogDefaultEntry .SHARE ,
@@ -280,6 +331,7 @@ public void addDefaultEndEntries() {
280331 addPlayWithKodiEntryIfNeeded ();
281332 addMarkAsWatchedEntryIfNeeded ();
282333 addEntry (StreamDialogDefaultEntry .SHOW_CHANNEL_DETAILS );
334+ return this ;
283335 }
284336
285337 /**
@@ -292,5 +344,14 @@ public InfoItemDialog create() {
292344 }
293345 return new InfoItemDialog (this .activity , this .fragment , this .infoItem , this .entries );
294346 }
347+
348+ public static void reportErrorDuringInitialization (final Throwable throwable ,
349+ final InfoItem item ) {
350+ ErrorUtil .showSnackbar (App .getApp ().getBaseContext (), new ErrorInfo (
351+ throwable ,
352+ UserAction .OPEN_INFO_ITEM_DIALOG ,
353+ "none" ,
354+ item .getServiceId ()));
355+ }
295356 }
296357}
0 commit comments