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:
commit
a59660f421
|
@ -24,6 +24,7 @@ import android.widget.Toast;
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.content.res.AppCompatResources;
|
import androidx.appcompat.content.res.AppCompatResources;
|
||||||
|
@ -259,80 +260,122 @@ public class RouterActivity extends AppCompatActivity {
|
||||||
protected void onSuccess() {
|
protected void onSuccess() {
|
||||||
final SharedPreferences preferences = PreferenceManager
|
final SharedPreferences preferences = PreferenceManager
|
||||||
.getDefaultSharedPreferences(this);
|
.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 ChoiceAvailabilityChecker choiceChecker = new ChoiceAvailabilityChecker(
|
||||||
final String videoPlayerKey = getString(R.string.video_player_key);
|
getChoicesForService(currentService, currentLinkType),
|
||||||
final String backgroundPlayerKey = getString(R.string.background_player_key);
|
preferences.getString(getString(R.string.preferred_open_action_key),
|
||||||
final String popupPlayerKey = getString(R.string.popup_player_key);
|
getString(R.string.preferred_open_action_default)));
|
||||||
final String downloadKey = getString(R.string.download_key);
|
|
||||||
final String alwaysAskKey = getString(R.string.always_ask_open_action_key);
|
|
||||||
|
|
||||||
if (selectedChoiceKey.equals(alwaysAskKey)) {
|
// Check for non-player related choices
|
||||||
final List<AdapterChoiceItem> choices
|
if (choiceChecker.isAvailableAndSelected(
|
||||||
= getChoicesForService(currentService, currentLinkType);
|
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(
|
final boolean isExtVideoEnabled = preferences.getBoolean(
|
||||||
getString(R.string.use_external_video_player_key), false);
|
getString(R.string.use_external_video_player_key), false);
|
||||||
final boolean isExtAudioEnabled = preferences.getBoolean(
|
final boolean isExtAudioEnabled = preferences.getBoolean(
|
||||||
getString(R.string.use_external_audio_player_key), false);
|
getString(R.string.use_external_audio_player_key), false);
|
||||||
final boolean isVideoPlayerSelected = selectedChoiceKey.equals(videoPlayerKey)
|
final boolean isVideoPlayerSelected =
|
||||||
|| selectedChoiceKey.equals(popupPlayerKey);
|
selectedChoice.equals(getString(R.string.video_player_key))
|
||||||
final boolean isAudioPlayerSelected = selectedChoiceKey.equals(backgroundPlayerKey);
|
|| selectedChoice.equals(getString(R.string.popup_player_key));
|
||||||
|
final boolean isAudioPlayerSelected =
|
||||||
|
selectedChoice.equals(getString(R.string.background_player_key));
|
||||||
|
|
||||||
if (currentLinkType != LinkType.STREAM) {
|
if (currentLinkType != LinkType.STREAM
|
||||||
if (isExtAudioEnabled && isAudioPlayerSelected
|
&& ((isExtAudioEnabled && isAudioPlayerSelected)
|
||||||
|| isExtVideoEnabled && isVideoPlayerSelected) {
|
|| (isExtVideoEnabled && isVideoPlayerSelected))
|
||||||
Toast.makeText(this, R.string.external_player_unsupported_link_type,
|
) {
|
||||||
Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.external_player_unsupported_link_type,
|
||||||
handleChoice(showInfoKey);
|
Toast.LENGTH_LONG).show();
|
||||||
return;
|
handleChoice(getString(R.string.show_info_key));
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<StreamingService.ServiceInfo.MediaCapability> capabilities
|
final List<StreamingService.ServiceInfo.MediaCapability> capabilities =
|
||||||
= currentService.getServiceInfo().getMediaCapabilities();
|
currentService.getServiceInfo().getMediaCapabilities();
|
||||||
|
|
||||||
boolean serviceSupportsChoice = false;
|
// Check if the service supports the choice
|
||||||
if (isVideoPlayerSelected) {
|
if ((isVideoPlayerSelected && capabilities.contains(VIDEO))
|
||||||
serviceSupportsChoice = capabilities.contains(VIDEO);
|
|| (isAudioPlayerSelected && capabilities.contains(AUDIO))) {
|
||||||
} else if (selectedChoiceKey.equals(backgroundPlayerKey)) {
|
handleChoice(selectedChoice);
|
||||||
serviceSupportsChoice = capabilities.contains(AUDIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serviceSupportsChoice) {
|
|
||||||
handleChoice(selectedChoiceKey);
|
|
||||||
} else {
|
} 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) {
|
private void showDialog(final List<AdapterChoiceItem> choices) {
|
||||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
final Context themeWrapperContext = getThemeWrapperContext();
|
|
||||||
|
|
||||||
final LayoutInflater inflater = LayoutInflater.from(themeWrapperContext);
|
final Context themeWrapperContext = getThemeWrapperContext();
|
||||||
final RadioGroup radioGroup = SingleChoiceDialogViewBinding.inflate(getLayoutInflater())
|
final LayoutInflater layoutInflater = LayoutInflater.from(themeWrapperContext);
|
||||||
.list;
|
|
||||||
|
final SingleChoiceDialogViewBinding binding =
|
||||||
|
SingleChoiceDialogViewBinding.inflate(layoutInflater);
|
||||||
|
final RadioGroup radioGroup = binding.list;
|
||||||
|
|
||||||
final DialogInterface.OnClickListener dialogButtonsClickListener = (dialog, which) -> {
|
final DialogInterface.OnClickListener dialogButtonsClickListener = (dialog, which) -> {
|
||||||
final int indexOfChild = radioGroup.indexOfChild(
|
final int indexOfChild = radioGroup.indexOfChild(
|
||||||
|
@ -351,21 +394,19 @@ public class RouterActivity extends AppCompatActivity {
|
||||||
|
|
||||||
alertDialogChoice = new AlertDialog.Builder(themeWrapperContext)
|
alertDialogChoice = new AlertDialog.Builder(themeWrapperContext)
|
||||||
.setTitle(R.string.preferred_open_action_share_menu_title)
|
.setTitle(R.string.preferred_open_action_share_menu_title)
|
||||||
.setView(radioGroup)
|
.setView(binding.getRoot())
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setNegativeButton(R.string.just_once, dialogButtonsClickListener)
|
.setNegativeButton(R.string.just_once, dialogButtonsClickListener)
|
||||||
.setPositiveButton(R.string.always, dialogButtonsClickListener)
|
.setPositiveButton(R.string.always, dialogButtonsClickListener)
|
||||||
.setOnDismissListener((dialog) -> {
|
.setOnDismissListener(dialog -> {
|
||||||
if (!selectionIsDownload && !selectionIsAddToPlaylist) {
|
if (!selectionIsDownload && !selectionIsAddToPlaylist) {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
//noinspection CodeBlock2Expr
|
alertDialogChoice.setOnShowListener(dialog -> setDialogButtonsState(
|
||||||
alertDialogChoice.setOnShowListener(dialog -> {
|
alertDialogChoice, radioGroup.getCheckedRadioButtonId() != -1));
|
||||||
setDialogButtonsState(alertDialogChoice, radioGroup.getCheckedRadioButtonId() != -1);
|
|
||||||
});
|
|
||||||
|
|
||||||
radioGroup.setOnCheckedChangeListener((group, checkedId) ->
|
radioGroup.setOnCheckedChangeListener((group, checkedId) ->
|
||||||
setDialogButtonsState(alertDialogChoice, true));
|
setDialogButtonsState(alertDialogChoice, true));
|
||||||
|
@ -385,7 +426,8 @@ public class RouterActivity extends AppCompatActivity {
|
||||||
|
|
||||||
int id = 12345;
|
int id = 12345;
|
||||||
for (final AdapterChoiceItem item : choices) {
|
for (final AdapterChoiceItem item : choices) {
|
||||||
final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater).getRoot();
|
final RadioButton radioButton = ListRadioIconItemBinding.inflate(layoutInflater)
|
||||||
|
.getRoot();
|
||||||
radioButton.setText(item.description);
|
radioButton.setText(item.description);
|
||||||
radioButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
radioButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||||
AppCompatResources.getDrawable(themeWrapperContext, item.icon),
|
AppCompatResources.getDrawable(themeWrapperContext, item.icon),
|
||||||
|
@ -427,87 +469,64 @@ public class RouterActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private List<AdapterChoiceItem> getChoicesForService(final StreamingService service,
|
private List<AdapterChoiceItem> getChoicesForService(final StreamingService service,
|
||||||
final LinkType linkType) {
|
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(
|
final AdapterChoiceItem showInfo = new AdapterChoiceItem(
|
||||||
getString(R.string.show_info_key), getString(R.string.show_info),
|
getString(R.string.show_info_key), getString(R.string.show_info),
|
||||||
R.drawable.ic_info_outline);
|
R.drawable.ic_info_outline);
|
||||||
final AdapterChoiceItem popupPlayer = new AdapterChoiceItem(
|
final AdapterChoiceItem videoPlayer = new AdapterChoiceItem(
|
||||||
getString(R.string.popup_player_key), getString(R.string.popup_player),
|
getString(R.string.video_player_key), getString(R.string.video_player),
|
||||||
R.drawable.ic_picture_in_picture);
|
R.drawable.ic_play_arrow);
|
||||||
final AdapterChoiceItem backgroundPlayer = new AdapterChoiceItem(
|
final AdapterChoiceItem backgroundPlayer = new AdapterChoiceItem(
|
||||||
getString(R.string.background_player_key), getString(R.string.background_player),
|
getString(R.string.background_player_key), getString(R.string.background_player),
|
||||||
R.drawable.ic_headset);
|
R.drawable.ic_headset);
|
||||||
final AdapterChoiceItem addToPlaylist = new AdapterChoiceItem(
|
final AdapterChoiceItem popupPlayer = new AdapterChoiceItem(
|
||||||
getString(R.string.add_to_playlist_key), getString(R.string.add_to_playlist),
|
getString(R.string.popup_player_key), getString(R.string.popup_player),
|
||||||
R.drawable.ic_add);
|
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 (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)) {
|
if (capabilities.contains(VIDEO)) {
|
||||||
returnList.add(popupPlayer);
|
returnedItems.add(videoPlayer);
|
||||||
|
returnedItems.add(popupPlayer);
|
||||||
}
|
}
|
||||||
if (capabilities.contains(AUDIO)) {
|
if (capabilities.contains(AUDIO)) {
|
||||||
returnList.add(backgroundPlayer);
|
returnedItems.add(backgroundPlayer);
|
||||||
}
|
}
|
||||||
// download is redundant for linkType CHANNEL AND PLAYLIST (till playlist downloading is
|
// download is redundant for linkType CHANNEL AND PLAYLIST (till playlist downloading is
|
||||||
// not supported )
|
// not supported )
|
||||||
returnList.add(new AdapterChoiceItem(getString(R.string.download_key),
|
returnedItems.add(new AdapterChoiceItem(getString(R.string.download_key),
|
||||||
getString(R.string.download),
|
getString(R.string.download),
|
||||||
R.drawable.ic_file_download));
|
R.drawable.ic_file_download));
|
||||||
|
|
||||||
// Add to playlist is not necessary for CHANNEL and PLAYLIST linkType since those can
|
// Add to playlist is not necessary for CHANNEL and PLAYLIST linkType since those can
|
||||||
// not be added to a playlist
|
// 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 {
|
} 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) {
|
if (capabilities.contains(VIDEO) && !isExtVideoEnabled) {
|
||||||
returnList.add(videoPlayer);
|
returnedItems.add(videoPlayer);
|
||||||
returnList.add(popupPlayer);
|
returnedItems.add(popupPlayer);
|
||||||
}
|
}
|
||||||
if (capabilities.contains(AUDIO) && !isExtAudioEnabled) {
|
if (capabilities.contains(AUDIO) && !isExtAudioEnabled) {
|
||||||
returnList.add(backgroundPlayer);
|
returnedItems.add(backgroundPlayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnList;
|
return returnedItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Context getThemeWrapperContext() {
|
private Context getThemeWrapperContext() {
|
||||||
|
@ -569,7 +588,8 @@ public class RouterActivity extends AppCompatActivity {
|
||||||
|
|
||||||
// stop and bypass FetcherService if InfoScreen was selected since
|
// stop and bypass FetcherService if InfoScreen was selected since
|
||||||
// StreamDetailFragment can fetch data itself
|
// 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
|
disposables.add(Observable
|
||||||
.fromCallable(() -> NavigationHelper.getIntentByLink(this, currentUrl))
|
.fromCallable(() -> NavigationHelper.getIntentByLink(this, currentUrl))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
@ -592,6 +612,30 @@ public class RouterActivity extends AppCompatActivity {
|
||||||
finish();
|
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() {
|
private void openAddToPlaylistDialog() {
|
||||||
// Getting the stream info usually takes a moment
|
// Getting the stream info usually takes a moment
|
||||||
// Notifying the user here to ensure that no confusion arises
|
// Notifying the user here to ensure that no confusion arises
|
||||||
|
@ -674,8 +718,8 @@ public class RouterActivity extends AppCompatActivity {
|
||||||
final int icon;
|
final int icon;
|
||||||
|
|
||||||
AdapterChoiceItem(final String key, final String description, final int icon) {
|
AdapterChoiceItem(final String key, final String description, final int icon) {
|
||||||
this.description = description;
|
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
this.description = description;
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -663,8 +663,7 @@ public final class VideoDetailFragment
|
||||||
binding.detailControlsCrashThePlayer.setOnClickListener(
|
binding.detailControlsCrashThePlayer.setOnClickListener(
|
||||||
v -> VideoDetailPlayerCrasher.onCrashThePlayer(
|
v -> VideoDetailPlayerCrasher.onCrashThePlayer(
|
||||||
this.getContext(),
|
this.getContext(),
|
||||||
this.player,
|
this.player)
|
||||||
getLayoutInflater())
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package org.schabi.newpipe.fragments.detail;
|
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.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextThemeWrapper;
|
import android.view.ContextThemeWrapper;
|
||||||
|
@ -29,10 +33,6 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
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}.
|
* Outsourced logic for crashing the player in the {@link VideoDetailFragment}.
|
||||||
*/
|
*/
|
||||||
|
@ -97,8 +97,7 @@ public final class VideoDetailPlayerCrasher {
|
||||||
|
|
||||||
public static void onCrashThePlayer(
|
public static void onCrashThePlayer(
|
||||||
@NonNull final Context context,
|
@NonNull final Context context,
|
||||||
@Nullable final Player player,
|
@Nullable final Player player
|
||||||
@NonNull final LayoutInflater layoutInflater
|
|
||||||
) {
|
) {
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
Log.d(TAG, "Player is not available");
|
Log.d(TAG, "Player is not available");
|
||||||
|
@ -109,16 +108,15 @@ public final class VideoDetailPlayerCrasher {
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Build the dialog/UI --
|
// -- Build the dialog/UI --
|
||||||
|
|
||||||
final Context themeWrapperContext = getThemeWrapperContext(context);
|
final Context themeWrapperContext = getThemeWrapperContext(context);
|
||||||
|
|
||||||
final LayoutInflater inflater = LayoutInflater.from(themeWrapperContext);
|
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")
|
.setTitle("Choose an exception")
|
||||||
.setView(radioGroup)
|
.setView(binding.getRoot())
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.create();
|
.create();
|
||||||
|
@ -136,11 +134,9 @@ public final class VideoDetailPlayerCrasher {
|
||||||
);
|
);
|
||||||
radioButton.setOnClickListener(v -> {
|
radioButton.setOnClickListener(v -> {
|
||||||
tryCrashPlayerWith(player, entry.getValue().get());
|
tryCrashPlayerWith(player, entry.getValue().get());
|
||||||
if (alertDialog != null) {
|
alertDialog.cancel();
|
||||||
alertDialog.cancel();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
radioGroup.addView(radioButton);
|
binding.list.addView(radioButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
alertDialog.show();
|
alertDialog.show();
|
||||||
|
|
|
@ -10,7 +10,6 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
import android.widget.RadioGroup;
|
import android.widget.RadioGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -25,6 +24,8 @@ import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceViewHolder;
|
import androidx.preference.PreferenceViewHolder;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
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.MainPlayer;
|
||||||
import org.schabi.newpipe.player.NotificationConstants;
|
import org.schabi.newpipe.player.NotificationConstants;
|
||||||
import org.schabi.newpipe.util.DeviceUtils;
|
import org.schabi.newpipe.util.DeviceUtils;
|
||||||
|
@ -189,13 +190,12 @@ public class NotificationActionsPreference extends Preference {
|
||||||
|
|
||||||
void openActionChooserDialog() {
|
void openActionChooserDialog() {
|
||||||
final LayoutInflater inflater = LayoutInflater.from(getContext());
|
final LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||||
final LinearLayout rootLayout = (LinearLayout) inflater.inflate(
|
final SingleChoiceDialogViewBinding binding =
|
||||||
R.layout.single_choice_dialog_view, null, false);
|
SingleChoiceDialogViewBinding.inflate(inflater);
|
||||||
final RadioGroup radioGroup = rootLayout.findViewById(android.R.id.list);
|
|
||||||
|
|
||||||
final AlertDialog alertDialog = new AlertDialog.Builder(getContext())
|
final AlertDialog alertDialog = new AlertDialog.Builder(getContext())
|
||||||
.setTitle(SLOT_TITLES[i])
|
.setTitle(SLOT_TITLES[i])
|
||||||
.setView(radioGroup)
|
.setView(binding.getRoot())
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
|
@ -207,8 +207,8 @@ public class NotificationActionsPreference extends Preference {
|
||||||
|
|
||||||
for (int id = 0; id < NotificationConstants.SLOT_ALLOWED_ACTIONS[i].length; ++id) {
|
for (int id = 0; id < NotificationConstants.SLOT_ALLOWED_ACTIONS[i].length; ++id) {
|
||||||
final int action = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id];
|
final int action = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id];
|
||||||
final RadioButton radioButton
|
final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater)
|
||||||
= (RadioButton) inflater.inflate(R.layout.list_radio_icon_item, null);
|
.getRoot();
|
||||||
|
|
||||||
// if present set action icon with correct color
|
// if present set action icon with correct color
|
||||||
if (NotificationConstants.ACTION_ICONS[action] != 0) {
|
if (NotificationConstants.ACTION_ICONS[action] != 0) {
|
||||||
|
@ -230,7 +230,7 @@ public class NotificationActionsPreference extends Preference {
|
||||||
radioButton.setLayoutParams(new RadioGroup.LayoutParams(
|
radioButton.setLayoutParams(new RadioGroup.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
radioButton.setOnClickListener(radioButtonsClickListener);
|
radioButton.setOnClickListener(radioButtonsClickListener);
|
||||||
radioGroup.addView(radioButton);
|
binding.list.addView(radioButton);
|
||||||
}
|
}
|
||||||
alertDialog.show();
|
alertDialog.show();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?><!-- -->
|
||||||
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@android:id/list"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:paddingTop="?attr/listPreferredItemPaddingLeft" />
|
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"/>
|
<style name="Base" parent="Base.V21"/>
|
||||||
|
|
||||||
<!-- Light Theme -->
|
<!-- 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" />
|
<style name="Base.LightTheme" parent="Base.V21.LightTheme" />
|
||||||
|
|
||||||
<!-- Dark Theme -->
|
<!-- 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" />
|
<style name="Base.DarkTheme" parent="Base.V21.DarkTheme" />
|
||||||
|
|
||||||
<!-- Black Theme -->
|
<!-- 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" />
|
<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>
|
</resources>
|
||||||
|
|
|
@ -130,7 +130,8 @@
|
||||||
<item name="colorAccent">@color/black_settings_accent_color</item>
|
<item name="colorAccent">@color/black_settings_accent_color</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="RouterActivityThemeLight" parent="LightTheme">
|
<!-- Router Activity -->
|
||||||
|
<style name="Base.RouterActivityThemeLight" parent="LightTheme">
|
||||||
<item name="android:windowNoTitle">true</item>
|
<item name="android:windowNoTitle">true</item>
|
||||||
<item name="android:windowBackground">@android:color/transparent</item>
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
<item name="android:colorBackgroundCacheHint">@null</item>
|
<item name="android:colorBackgroundCacheHint">@null</item>
|
||||||
|
@ -138,7 +139,9 @@
|
||||||
<item name="android:windowAnimationStyle">@null</item>
|
<item name="android:windowAnimationStyle">@null</item>
|
||||||
</style>
|
</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:windowNoTitle">true</item>
|
||||||
<item name="android:windowBackground">@android:color/transparent</item>
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
<item name="android:colorBackgroundCacheHint">@null</item>
|
<item name="android:colorBackgroundCacheHint">@null</item>
|
||||||
|
@ -146,4 +149,6 @@
|
||||||
<item name="android:windowAnimationStyle">@null</item>
|
<item name="android:windowAnimationStyle">@null</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="RouterActivityThemeDark" parent="Base.RouterActivityThemeDark" />
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue