mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-29 06:17:38 +00:00 
			
		
		
		
	Merge pull request #8340 from litetex/fix-add-to-playlist
Fix "Add to playlist" not working and cleanup "RouterActivity" choice handling
This commit is contained in:
		| @@ -24,6 +24,7 @@ import android.widget.Toast; | ||||
| import androidx.annotation.DrawableRes; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.annotation.StringRes; | ||||
| import androidx.appcompat.app.AlertDialog; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.appcompat.content.res.AppCompatResources; | ||||
| @@ -259,80 +260,122 @@ public class RouterActivity extends AppCompatActivity { | ||||
|     protected void onSuccess() { | ||||
|         final SharedPreferences preferences = PreferenceManager | ||||
|                 .getDefaultSharedPreferences(this); | ||||
|         final String selectedChoiceKey = preferences | ||||
|                 .getString(getString(R.string.preferred_open_action_key), | ||||
|                         getString(R.string.preferred_open_action_default)); | ||||
|  | ||||
|         final String showInfoKey = getString(R.string.show_info_key); | ||||
|         final String videoPlayerKey = getString(R.string.video_player_key); | ||||
|         final String backgroundPlayerKey = getString(R.string.background_player_key); | ||||
|         final String popupPlayerKey = getString(R.string.popup_player_key); | ||||
|         final String downloadKey = getString(R.string.download_key); | ||||
|         final String alwaysAskKey = getString(R.string.always_ask_open_action_key); | ||||
|         final ChoiceAvailabilityChecker choiceChecker = new ChoiceAvailabilityChecker( | ||||
|                 getChoicesForService(currentService, currentLinkType), | ||||
|                 preferences.getString(getString(R.string.preferred_open_action_key), | ||||
|                         getString(R.string.preferred_open_action_default))); | ||||
|  | ||||
|         if (selectedChoiceKey.equals(alwaysAskKey)) { | ||||
|             final List<AdapterChoiceItem> choices | ||||
|                     = getChoicesForService(currentService, currentLinkType); | ||||
|         // Check for non-player related choices | ||||
|         if (choiceChecker.isAvailableAndSelected( | ||||
|                 R.string.show_info_key, | ||||
|                 R.string.download_key, | ||||
|                 R.string.add_to_playlist_key)) { | ||||
|             handleChoice(choiceChecker.getSelectedChoiceKey()); | ||||
|             return; | ||||
|         } | ||||
|         // Check if the choice is player related | ||||
|         if (choiceChecker.isAvailableAndSelected( | ||||
|                 R.string.video_player_key, | ||||
|                 R.string.background_player_key, | ||||
|                 R.string.popup_player_key)) { | ||||
|  | ||||
|             final String selectedChoice = choiceChecker.getSelectedChoiceKey(); | ||||
|  | ||||
|             switch (choices.size()) { | ||||
|                 case 1: | ||||
|                     handleChoice(choices.get(0).key); | ||||
|                     break; | ||||
|                 case 0: | ||||
|                     handleChoice(showInfoKey); | ||||
|                     break; | ||||
|                 default: | ||||
|                     showDialog(choices); | ||||
|                     break; | ||||
|             } | ||||
|         } else if (selectedChoiceKey.equals(showInfoKey)) { | ||||
|             handleChoice(showInfoKey); | ||||
|         } else if (selectedChoiceKey.equals(downloadKey)) { | ||||
|             handleChoice(downloadKey); | ||||
|         } else { | ||||
|             final boolean isExtVideoEnabled = preferences.getBoolean( | ||||
|                     getString(R.string.use_external_video_player_key), false); | ||||
|             final boolean isExtAudioEnabled = preferences.getBoolean( | ||||
|                     getString(R.string.use_external_audio_player_key), false); | ||||
|             final boolean isVideoPlayerSelected = selectedChoiceKey.equals(videoPlayerKey) | ||||
|                     || selectedChoiceKey.equals(popupPlayerKey); | ||||
|             final boolean isAudioPlayerSelected = selectedChoiceKey.equals(backgroundPlayerKey); | ||||
|             final boolean isVideoPlayerSelected = | ||||
|                     selectedChoice.equals(getString(R.string.video_player_key)) | ||||
|                             || selectedChoice.equals(getString(R.string.popup_player_key)); | ||||
|             final boolean isAudioPlayerSelected = | ||||
|                     selectedChoice.equals(getString(R.string.background_player_key)); | ||||
|  | ||||
|             if (currentLinkType != LinkType.STREAM) { | ||||
|                 if (isExtAudioEnabled && isAudioPlayerSelected | ||||
|                         || isExtVideoEnabled && isVideoPlayerSelected) { | ||||
|                     Toast.makeText(this, R.string.external_player_unsupported_link_type, | ||||
|                             Toast.LENGTH_LONG).show(); | ||||
|                     handleChoice(showInfoKey); | ||||
|                     return; | ||||
|                 } | ||||
|             if (currentLinkType != LinkType.STREAM | ||||
|                     && ((isExtAudioEnabled && isAudioPlayerSelected) | ||||
|                     || (isExtVideoEnabled && isVideoPlayerSelected)) | ||||
|             ) { | ||||
|                 Toast.makeText(this, R.string.external_player_unsupported_link_type, | ||||
|                         Toast.LENGTH_LONG).show(); | ||||
|                 handleChoice(getString(R.string.show_info_key)); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             final List<StreamingService.ServiceInfo.MediaCapability> capabilities | ||||
|                     = currentService.getServiceInfo().getMediaCapabilities(); | ||||
|             final List<StreamingService.ServiceInfo.MediaCapability> capabilities = | ||||
|                     currentService.getServiceInfo().getMediaCapabilities(); | ||||
|  | ||||
|             boolean serviceSupportsChoice = false; | ||||
|             if (isVideoPlayerSelected) { | ||||
|                 serviceSupportsChoice = capabilities.contains(VIDEO); | ||||
|             } else if (selectedChoiceKey.equals(backgroundPlayerKey)) { | ||||
|                 serviceSupportsChoice = capabilities.contains(AUDIO); | ||||
|             } | ||||
|  | ||||
|             if (serviceSupportsChoice) { | ||||
|                 handleChoice(selectedChoiceKey); | ||||
|             // Check if the service supports the choice | ||||
|             if ((isVideoPlayerSelected && capabilities.contains(VIDEO)) | ||||
|                     || (isAudioPlayerSelected && capabilities.contains(AUDIO))) { | ||||
|                 handleChoice(selectedChoice); | ||||
|             } else { | ||||
|                 handleChoice(showInfoKey); | ||||
|                 handleChoice(getString(R.string.show_info_key)); | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Default / Ask always | ||||
|         final List<AdapterChoiceItem> availableChoices = choiceChecker.getAvailableChoices(); | ||||
|         switch (availableChoices.size()) { | ||||
|             case 1: | ||||
|                 handleChoice(availableChoices.get(0).key); | ||||
|                 break; | ||||
|             case 0: | ||||
|                 handleChoice(getString(R.string.show_info_key)); | ||||
|                 break; | ||||
|             default: | ||||
|                 showDialog(availableChoices); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This is a helper class for checking if the choices are available and/or selected. | ||||
|      */ | ||||
|     class ChoiceAvailabilityChecker { | ||||
|         private final List<AdapterChoiceItem> availableChoices; | ||||
|         private final String selectedChoiceKey; | ||||
|  | ||||
|         ChoiceAvailabilityChecker( | ||||
|                 @NonNull final List<AdapterChoiceItem> availableChoices, | ||||
|                 @NonNull final String selectedChoiceKey) { | ||||
|             this.availableChoices = availableChoices; | ||||
|             this.selectedChoiceKey = selectedChoiceKey; | ||||
|         } | ||||
|  | ||||
|         public List<AdapterChoiceItem> getAvailableChoices() { | ||||
|             return availableChoices; | ||||
|         } | ||||
|  | ||||
|         public String getSelectedChoiceKey() { | ||||
|             return selectedChoiceKey; | ||||
|         } | ||||
|  | ||||
|         public boolean isAvailableAndSelected(@StringRes final int... wantedKeys) { | ||||
|             return Arrays.stream(wantedKeys).anyMatch(this::isAvailableAndSelected); | ||||
|         } | ||||
|  | ||||
|         public boolean isAvailableAndSelected(@StringRes final int wantedKey) { | ||||
|             final String wanted = getString(wantedKey); | ||||
|             // Check if the wanted option is selected | ||||
|             if (!selectedChoiceKey.equals(wanted)) { | ||||
|                 return false; | ||||
|             } | ||||
|             // Check if it's available | ||||
|             return availableChoices.stream().anyMatch(item -> wanted.equals(item.key)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void showDialog(final List<AdapterChoiceItem> choices) { | ||||
|         final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); | ||||
|         final Context themeWrapperContext = getThemeWrapperContext(); | ||||
|  | ||||
|         final LayoutInflater inflater = LayoutInflater.from(themeWrapperContext); | ||||
|         final RadioGroup radioGroup = SingleChoiceDialogViewBinding.inflate(getLayoutInflater()) | ||||
|                 .list; | ||||
|         final Context themeWrapperContext = getThemeWrapperContext(); | ||||
|         final LayoutInflater layoutInflater = LayoutInflater.from(themeWrapperContext); | ||||
|  | ||||
|         final SingleChoiceDialogViewBinding binding = | ||||
|                 SingleChoiceDialogViewBinding.inflate(layoutInflater); | ||||
|         final RadioGroup radioGroup = binding.list; | ||||
|  | ||||
|         final DialogInterface.OnClickListener dialogButtonsClickListener = (dialog, which) -> { | ||||
|             final int indexOfChild = radioGroup.indexOfChild( | ||||
| @@ -351,21 +394,19 @@ public class RouterActivity extends AppCompatActivity { | ||||
|  | ||||
|         alertDialogChoice = new AlertDialog.Builder(themeWrapperContext) | ||||
|                 .setTitle(R.string.preferred_open_action_share_menu_title) | ||||
|                 .setView(radioGroup) | ||||
|                 .setView(binding.getRoot()) | ||||
|                 .setCancelable(true) | ||||
|                 .setNegativeButton(R.string.just_once, dialogButtonsClickListener) | ||||
|                 .setPositiveButton(R.string.always, dialogButtonsClickListener) | ||||
|                 .setOnDismissListener((dialog) -> { | ||||
|                 .setOnDismissListener(dialog -> { | ||||
|                     if (!selectionIsDownload && !selectionIsAddToPlaylist) { | ||||
|                         finish(); | ||||
|                     } | ||||
|                 }) | ||||
|                 .create(); | ||||
|  | ||||
|         //noinspection CodeBlock2Expr | ||||
|         alertDialogChoice.setOnShowListener(dialog -> { | ||||
|             setDialogButtonsState(alertDialogChoice, radioGroup.getCheckedRadioButtonId() != -1); | ||||
|         }); | ||||
|         alertDialogChoice.setOnShowListener(dialog -> setDialogButtonsState( | ||||
|                 alertDialogChoice, radioGroup.getCheckedRadioButtonId() != -1)); | ||||
|  | ||||
|         radioGroup.setOnCheckedChangeListener((group, checkedId) -> | ||||
|                 setDialogButtonsState(alertDialogChoice, true)); | ||||
| @@ -385,7 +426,8 @@ public class RouterActivity extends AppCompatActivity { | ||||
|  | ||||
|         int id = 12345; | ||||
|         for (final AdapterChoiceItem item : choices) { | ||||
|             final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater).getRoot(); | ||||
|             final RadioButton radioButton = ListRadioIconItemBinding.inflate(layoutInflater) | ||||
|                     .getRoot(); | ||||
|             radioButton.setText(item.description); | ||||
|             radioButton.setCompoundDrawablesRelativeWithIntrinsicBounds( | ||||
|                     AppCompatResources.getDrawable(themeWrapperContext, item.icon), | ||||
| @@ -427,87 +469,64 @@ public class RouterActivity extends AppCompatActivity { | ||||
|  | ||||
|     private List<AdapterChoiceItem> getChoicesForService(final StreamingService service, | ||||
|                                                          final LinkType linkType) { | ||||
|         final Context context = getThemeWrapperContext(); | ||||
|  | ||||
|         final List<AdapterChoiceItem> returnList = new ArrayList<>(); | ||||
|         final List<StreamingService.ServiceInfo.MediaCapability> capabilities | ||||
|                 = service.getServiceInfo().getMediaCapabilities(); | ||||
|  | ||||
|         final SharedPreferences preferences = PreferenceManager | ||||
|                 .getDefaultSharedPreferences(this); | ||||
|         final boolean isExtVideoEnabled = preferences.getBoolean( | ||||
|                 getString(R.string.use_external_video_player_key), false); | ||||
|         final boolean isExtAudioEnabled = preferences.getBoolean( | ||||
|                 getString(R.string.use_external_audio_player_key), false); | ||||
|  | ||||
|         final AdapterChoiceItem videoPlayer = new AdapterChoiceItem( | ||||
|                 getString(R.string.video_player_key), getString(R.string.video_player), | ||||
|                 R.drawable.ic_play_arrow); | ||||
|         final AdapterChoiceItem showInfo = new AdapterChoiceItem( | ||||
|                 getString(R.string.show_info_key), getString(R.string.show_info), | ||||
|                 R.drawable.ic_info_outline); | ||||
|         final AdapterChoiceItem popupPlayer = new AdapterChoiceItem( | ||||
|                 getString(R.string.popup_player_key), getString(R.string.popup_player), | ||||
|                 R.drawable.ic_picture_in_picture); | ||||
|         final AdapterChoiceItem videoPlayer = new AdapterChoiceItem( | ||||
|                 getString(R.string.video_player_key), getString(R.string.video_player), | ||||
|                 R.drawable.ic_play_arrow); | ||||
|         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); | ||||
|         final AdapterChoiceItem popupPlayer = new AdapterChoiceItem( | ||||
|                 getString(R.string.popup_player_key), getString(R.string.popup_player), | ||||
|                 R.drawable.ic_picture_in_picture); | ||||
|  | ||||
|         final List<AdapterChoiceItem> returnedItems = new ArrayList<>(); | ||||
|         returnedItems.add(showInfo); // Always present | ||||
|  | ||||
|         final List<StreamingService.ServiceInfo.MediaCapability> capabilities = | ||||
|                 service.getServiceInfo().getMediaCapabilities(); | ||||
|  | ||||
|         if (linkType == LinkType.STREAM) { | ||||
|             if (isExtVideoEnabled) { | ||||
|                 // show both "show info" and "video player", they are two different activities | ||||
|                 returnList.add(showInfo); | ||||
|                 returnList.add(videoPlayer); | ||||
|             } else { | ||||
|                 final MainPlayer.PlayerType playerType = PlayerHolder.getInstance().getType(); | ||||
|                 if (capabilities.contains(VIDEO) | ||||
|                         && PlayerHelper.isAutoplayAllowedByUser(context) | ||||
|                         && playerType == null || playerType == MainPlayer.PlayerType.VIDEO) { | ||||
|                     // show only "video player" since the details activity will be opened and the | ||||
|                     // video will be auto played there. Since "show info" would do the exact same | ||||
|                     // thing, use that as a key to let VideoDetailFragment load the stream instead | ||||
|                     // of using FetcherService (see comment in handleChoice()) | ||||
|                     returnList.add(new AdapterChoiceItem( | ||||
|                             showInfo.key, videoPlayer.description, videoPlayer.icon)); | ||||
|                 } else { | ||||
|                     // show only "show info" if video player is not applicable, auto play is | ||||
|                     // disabled or a video is playing in a player different than the main one | ||||
|                     returnList.add(showInfo); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (capabilities.contains(VIDEO)) { | ||||
|                 returnList.add(popupPlayer); | ||||
|                 returnedItems.add(videoPlayer); | ||||
|                 returnedItems.add(popupPlayer); | ||||
|             } | ||||
|             if (capabilities.contains(AUDIO)) { | ||||
|                 returnList.add(backgroundPlayer); | ||||
|                 returnedItems.add(backgroundPlayer); | ||||
|             } | ||||
|             // download is redundant for linkType CHANNEL AND PLAYLIST (till playlist downloading is | ||||
|             // not supported ) | ||||
|             returnList.add(new AdapterChoiceItem(getString(R.string.download_key), | ||||
|             returnedItems.add(new AdapterChoiceItem(getString(R.string.download_key), | ||||
|                     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); | ||||
|  | ||||
|             returnedItems.add(new AdapterChoiceItem(getString(R.string.add_to_playlist_key), | ||||
|                     getString(R.string.add_to_playlist), | ||||
|                     R.drawable.ic_add)); | ||||
|         } else { | ||||
|             returnList.add(showInfo); | ||||
|             // LinkType.NONE is never present because it's filtered out before | ||||
|             // channels and playlist can be played as they contain a list of videos | ||||
|             final SharedPreferences preferences = PreferenceManager | ||||
|                     .getDefaultSharedPreferences(this); | ||||
|             final boolean isExtVideoEnabled = preferences.getBoolean( | ||||
|                     getString(R.string.use_external_video_player_key), false); | ||||
|             final boolean isExtAudioEnabled = preferences.getBoolean( | ||||
|                     getString(R.string.use_external_audio_player_key), false); | ||||
|  | ||||
|             if (capabilities.contains(VIDEO) && !isExtVideoEnabled) { | ||||
|                 returnList.add(videoPlayer); | ||||
|                 returnList.add(popupPlayer); | ||||
|                 returnedItems.add(videoPlayer); | ||||
|                 returnedItems.add(popupPlayer); | ||||
|             } | ||||
|             if (capabilities.contains(AUDIO) && !isExtAudioEnabled) { | ||||
|                 returnList.add(backgroundPlayer); | ||||
|                 returnedItems.add(backgroundPlayer); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return returnList; | ||||
|         return returnedItems; | ||||
|     } | ||||
|  | ||||
|     private Context getThemeWrapperContext() { | ||||
| @@ -569,7 +588,8 @@ public class RouterActivity extends AppCompatActivity { | ||||
|  | ||||
|         // stop and bypass FetcherService if InfoScreen was selected since | ||||
|         // StreamDetailFragment can fetch data itself | ||||
|         if (selectedChoiceKey.equals(getString(R.string.show_info_key))) { | ||||
|         if (selectedChoiceKey.equals(getString(R.string.show_info_key)) | ||||
|                 || canHandleChoiceLikeShowInfo(selectedChoiceKey)) { | ||||
|             disposables.add(Observable | ||||
|                     .fromCallable(() -> NavigationHelper.getIntentByLink(this, currentUrl)) | ||||
|                     .subscribeOn(Schedulers.io()) | ||||
| @@ -592,6 +612,30 @@ public class RouterActivity extends AppCompatActivity { | ||||
|         finish(); | ||||
|     } | ||||
|  | ||||
|     private boolean canHandleChoiceLikeShowInfo(final String selectedChoiceKey) { | ||||
|         if (!selectedChoiceKey.equals(getString(R.string.video_player_key))) { | ||||
|             return false; | ||||
|         } | ||||
|         // "video player" can be handled like "show info" (because VideoDetailFragment can load | ||||
|         // the stream instead of FetcherService) when... | ||||
|  | ||||
|         // ...Autoplay is enabled | ||||
|         if (!PlayerHelper.isAutoplayAllowedByUser(getThemeWrapperContext())) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         final boolean isExtVideoEnabled = PreferenceManager.getDefaultSharedPreferences(this) | ||||
|                 .getBoolean(getString(R.string.use_external_video_player_key), false); | ||||
|         // ...it's not done via an external player | ||||
|         if (isExtVideoEnabled) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // ...the player is not running or in normal Video-mode/type | ||||
|         final MainPlayer.PlayerType playerType = PlayerHolder.getInstance().getType(); | ||||
|         return playerType == null || playerType == MainPlayer.PlayerType.VIDEO; | ||||
|     } | ||||
|  | ||||
|     private void openAddToPlaylistDialog() { | ||||
|         // Getting the stream info usually takes a moment | ||||
|         // Notifying the user here to ensure that no confusion arises | ||||
| @@ -674,8 +718,8 @@ public class RouterActivity extends AppCompatActivity { | ||||
|         final int icon; | ||||
|  | ||||
|         AdapterChoiceItem(final String key, final String description, final int icon) { | ||||
|             this.description = description; | ||||
|             this.key = key; | ||||
|             this.description = description; | ||||
|             this.icon = icon; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -663,8 +663,7 @@ public final class VideoDetailFragment | ||||
|             binding.detailControlsCrashThePlayer.setOnClickListener( | ||||
|                     v -> VideoDetailPlayerCrasher.onCrashThePlayer( | ||||
|                             this.getContext(), | ||||
|                             this.player, | ||||
|                             getLayoutInflater()) | ||||
|                             this.player) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,9 @@ | ||||
| package org.schabi.newpipe.fragments.detail; | ||||
|  | ||||
| import static com.google.android.exoplayer2.PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW; | ||||
| import static com.google.android.exoplayer2.PlaybackException.ERROR_CODE_DECODING_FAILED; | ||||
| import static com.google.android.exoplayer2.PlaybackException.ERROR_CODE_UNSPECIFIED; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.util.Log; | ||||
| import android.view.ContextThemeWrapper; | ||||
| @@ -29,10 +33,6 @@ import java.util.LinkedHashMap; | ||||
| import java.util.Map; | ||||
| import java.util.function.Supplier; | ||||
|  | ||||
| import static com.google.android.exoplayer2.PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW; | ||||
| import static com.google.android.exoplayer2.PlaybackException.ERROR_CODE_DECODING_FAILED; | ||||
| import static com.google.android.exoplayer2.PlaybackException.ERROR_CODE_UNSPECIFIED; | ||||
|  | ||||
| /** | ||||
|  * Outsourced logic for crashing the player in the {@link VideoDetailFragment}. | ||||
|  */ | ||||
| @@ -97,8 +97,7 @@ public final class VideoDetailPlayerCrasher { | ||||
|  | ||||
|     public static void onCrashThePlayer( | ||||
|             @NonNull final Context context, | ||||
|             @Nullable final Player player, | ||||
|             @NonNull final LayoutInflater layoutInflater | ||||
|             @Nullable final Player player | ||||
|     ) { | ||||
|         if (player == null) { | ||||
|             Log.d(TAG, "Player is not available"); | ||||
| @@ -109,16 +108,15 @@ public final class VideoDetailPlayerCrasher { | ||||
|         } | ||||
|  | ||||
|         // -- Build the dialog/UI -- | ||||
|  | ||||
|         final Context themeWrapperContext = getThemeWrapperContext(context); | ||||
|  | ||||
|         final LayoutInflater inflater = LayoutInflater.from(themeWrapperContext); | ||||
|         final RadioGroup radioGroup = SingleChoiceDialogViewBinding.inflate(layoutInflater) | ||||
|                 .list; | ||||
|  | ||||
|         final AlertDialog alertDialog = new AlertDialog.Builder(getThemeWrapperContext(context)) | ||||
|         final SingleChoiceDialogViewBinding binding = | ||||
|                 SingleChoiceDialogViewBinding.inflate(inflater); | ||||
|  | ||||
|         final AlertDialog alertDialog = new AlertDialog.Builder(themeWrapperContext) | ||||
|                 .setTitle("Choose an exception") | ||||
|                 .setView(radioGroup) | ||||
|                 .setView(binding.getRoot()) | ||||
|                 .setCancelable(true) | ||||
|                 .setNegativeButton(R.string.cancel, null) | ||||
|                 .create(); | ||||
| @@ -136,11 +134,9 @@ public final class VideoDetailPlayerCrasher { | ||||
|             ); | ||||
|             radioButton.setOnClickListener(v -> { | ||||
|                 tryCrashPlayerWith(player, entry.getValue().get()); | ||||
|                 if (alertDialog != null) { | ||||
|                     alertDialog.cancel(); | ||||
|                 } | ||||
|                 alertDialog.cancel(); | ||||
|             }); | ||||
|             radioGroup.addView(radioButton); | ||||
|             binding.list.addView(radioButton); | ||||
|         } | ||||
|  | ||||
|         alertDialog.show(); | ||||
|   | ||||
| @@ -10,7 +10,6 @@ import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.CheckBox; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.RadioButton; | ||||
| import android.widget.RadioGroup; | ||||
| import android.widget.TextView; | ||||
| @@ -25,6 +24,8 @@ import androidx.preference.Preference; | ||||
| import androidx.preference.PreferenceViewHolder; | ||||
|  | ||||
| import org.schabi.newpipe.R; | ||||
| import org.schabi.newpipe.databinding.ListRadioIconItemBinding; | ||||
| import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding; | ||||
| import org.schabi.newpipe.player.MainPlayer; | ||||
| import org.schabi.newpipe.player.NotificationConstants; | ||||
| import org.schabi.newpipe.util.DeviceUtils; | ||||
| @@ -189,13 +190,12 @@ public class NotificationActionsPreference extends Preference { | ||||
|  | ||||
|         void openActionChooserDialog() { | ||||
|             final LayoutInflater inflater = LayoutInflater.from(getContext()); | ||||
|             final LinearLayout rootLayout = (LinearLayout) inflater.inflate( | ||||
|                     R.layout.single_choice_dialog_view, null, false); | ||||
|             final RadioGroup radioGroup = rootLayout.findViewById(android.R.id.list); | ||||
|             final SingleChoiceDialogViewBinding binding = | ||||
|                     SingleChoiceDialogViewBinding.inflate(inflater); | ||||
|  | ||||
|             final AlertDialog alertDialog = new AlertDialog.Builder(getContext()) | ||||
|                     .setTitle(SLOT_TITLES[i]) | ||||
|                     .setView(radioGroup) | ||||
|                     .setView(binding.getRoot()) | ||||
|                     .setCancelable(true) | ||||
|                     .create(); | ||||
|  | ||||
| @@ -207,8 +207,8 @@ public class NotificationActionsPreference extends Preference { | ||||
|  | ||||
|             for (int id = 0; id < NotificationConstants.SLOT_ALLOWED_ACTIONS[i].length; ++id) { | ||||
|                 final int action = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id]; | ||||
|                 final RadioButton radioButton | ||||
|                         = (RadioButton) inflater.inflate(R.layout.list_radio_icon_item, null); | ||||
|                 final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater) | ||||
|                         .getRoot(); | ||||
|  | ||||
|                 // if present set action icon with correct color | ||||
|                 if (NotificationConstants.ACTION_ICONS[action] != 0) { | ||||
| @@ -230,7 +230,7 @@ public class NotificationActionsPreference extends Preference { | ||||
|                 radioButton.setLayoutParams(new RadioGroup.LayoutParams( | ||||
|                         ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); | ||||
|                 radioButton.setOnClickListener(radioButtonsClickListener); | ||||
|                 radioGroup.addView(radioButton); | ||||
|                 binding.list.addView(radioButton); | ||||
|             } | ||||
|             alertDialog.show(); | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,14 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <RadioGroup xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:id="@android:id/list" | ||||
| <?xml version="1.0" encoding="utf-8"?><!-- --> | ||||
| <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content" | ||||
|     android:paddingTop="?attr/listPreferredItemPaddingLeft" /> | ||||
|     android:layout_height="match_parent" | ||||
|     android:fadeScrollbars="false"> | ||||
|  | ||||
|     <RadioGroup | ||||
|         android:id="@android:id/list" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:paddingTop="?attr/listPreferredItemPaddingLeft" /> | ||||
| </ScrollView> | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -12,21 +12,31 @@ | ||||
|     <style name="Base" parent="Base.V21"/> | ||||
|  | ||||
|     <!-- Light Theme --> | ||||
|     <style name="Base.V21.LightTheme" parent="Base.V19.LightTheme"> | ||||
|     <style name="Base.V21.LightTheme" parent="Base.V19.LightTheme" /> | ||||
|  | ||||
|     </style> | ||||
|     <style name="Base.LightTheme" parent="Base.V21.LightTheme" /> | ||||
|  | ||||
|     <!-- Dark Theme --> | ||||
|     <style name="Base.V21.DarkTheme" parent="Base.V19.DarkTheme"> | ||||
|     <style name="Base.V21.DarkTheme" parent="Base.V19.DarkTheme" /> | ||||
|  | ||||
|     </style> | ||||
|     <style name="Base.DarkTheme" parent="Base.V21.DarkTheme" /> | ||||
|  | ||||
|     <!-- Black Theme --> | ||||
|     <style name="Base.V21.BlackTheme" parent="Base.V19.BlackTheme"> | ||||
|     <style name="Base.V21.BlackTheme" parent="Base.V19.BlackTheme" /> | ||||
|  | ||||
|     </style> | ||||
|     <style name="Base.BlackTheme" parent="Base.V21.BlackTheme" /> | ||||
|  | ||||
|     <!-- Router Activity --> | ||||
|     <style name="Base.V21.RouterActivityThemeLight" parent="Base.RouterActivityThemeLight"> | ||||
|         <item name="android:statusBarColor">@android:color/transparent</item> | ||||
|     </style> | ||||
|  | ||||
|     <style name="RouterActivityThemeLight" parent="Base.V21.RouterActivityThemeLight" /> | ||||
|  | ||||
|     <style name="Base.V21.RouterActivityThemeDark" parent="Base.RouterActivityThemeDark"> | ||||
|         <item name="android:statusBarColor">@android:color/transparent</item> | ||||
|     </style> | ||||
|  | ||||
|     <style name="RouterActivityThemeDark" parent="Base.V21.RouterActivityThemeDark" /> | ||||
|  | ||||
| </resources> | ||||
|   | ||||
| @@ -130,7 +130,8 @@ | ||||
|         <item name="colorAccent">@color/black_settings_accent_color</item> | ||||
|     </style> | ||||
|  | ||||
|     <style name="RouterActivityThemeLight" parent="LightTheme"> | ||||
|     <!-- Router Activity --> | ||||
|     <style name="Base.RouterActivityThemeLight" parent="LightTheme"> | ||||
|         <item name="android:windowNoTitle">true</item> | ||||
|         <item name="android:windowBackground">@android:color/transparent</item> | ||||
|         <item name="android:colorBackgroundCacheHint">@null</item> | ||||
| @@ -138,7 +139,9 @@ | ||||
|         <item name="android:windowAnimationStyle">@null</item> | ||||
|     </style> | ||||
|  | ||||
|     <style name="RouterActivityThemeDark" parent="DarkTheme"> | ||||
|     <style name="RouterActivityThemeLight" parent="Base.RouterActivityThemeLight" /> | ||||
|  | ||||
|     <style name="Base.RouterActivityThemeDark" parent="DarkTheme"> | ||||
|         <item name="android:windowNoTitle">true</item> | ||||
|         <item name="android:windowBackground">@android:color/transparent</item> | ||||
|         <item name="android:colorBackgroundCacheHint">@null</item> | ||||
| @@ -146,4 +149,6 @@ | ||||
|         <item name="android:windowAnimationStyle">@null</item> | ||||
|     </style> | ||||
|  | ||||
|     <style name="RouterActivityThemeDark" parent="Base.RouterActivityThemeDark" /> | ||||
|  | ||||
| </resources> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Stypox
					Stypox