diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 4e96f3bb6e5..68d48cf1d5c 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -27,6 +27,8 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.content.res.AppCompatResources; +import androidx.appcompat.widget.AppCompatButton; +import androidx.appcompat.widget.SwitchCompat; import androidx.core.app.NotificationCompat; import androidx.core.app.ServiceCompat; import androidx.core.widget.TextViewCompat; @@ -35,7 +37,6 @@ import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.databinding.ListRadioIconItemBinding; -import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding; import org.schabi.newpipe.download.DownloadDialog; import org.schabi.newpipe.error.ErrorActivity; import org.schabi.newpipe.error.ErrorInfo; @@ -324,13 +325,54 @@ protected void onSuccess() { } } + /** + * Toggle the visibility for advanced options view. + * @param dialogView Main view of the dialog. + * @param visible State of the visibility. + */ + private void toggleAdvancedOptions(final View dialogView, final boolean visible) { + final AppCompatButton toggle = dialogView.findViewById(R.id.toggle_adv); + final SwitchCompat prioritizeEnqueue = dialogView.findViewById(R.id.prioritize_enqueue); + + final int visibility = (visible + ? View.VISIBLE + : View.GONE); + final int icon = (visible + ? R.drawable.ic_arrow_drop_down + : R.drawable.ic_arrow_drop_right); + + prioritizeEnqueue.setVisibility(visibility); + TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(toggle, + AppCompatResources.getDrawable(getApplicationContext(), icon), + null, null, null); + }; + private void showDialog(final List 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 View dialogView = View.inflate(themeWrapperContext, R.layout.dialog_share_context, + null); + final RadioGroup radioGroup = dialogView.findViewById(R.id.player_group); + final AppCompatButton toggle = dialogView.findViewById(R.id.toggle_adv); + final SwitchCompat prioritizeEnqueue = dialogView.findViewById(R.id.prioritize_enqueue); + + /* Initialize component states. */ + toggleAdvancedOptions(dialogView, false); + prioritizeEnqueue.setChecked(preferences.getBoolean( + getString(R.string.prioritize_enqueue), + false)); + + /* Save linked preference when changed. */ + prioritizeEnqueue.setOnCheckedChangeListener((v, checked) -> { + preferences.edit().putBoolean(getString(R.string.prioritize_enqueue), checked).apply(); + }); + /* Toggle advanced options view. */ + toggle.setOnClickListener(v -> { + toggleAdvancedOptions(dialogView, + prioritizeEnqueue.getVisibility() != View.VISIBLE); + }); final DialogInterface.OnClickListener dialogButtonsClickListener = (dialog, which) -> { final int indexOfChild = radioGroup.indexOfChild( @@ -349,7 +391,7 @@ private void showDialog(final List choices) { alertDialogChoice = new AlertDialog.Builder(themeWrapperContext) .setTitle(R.string.preferred_open_action_share_menu_title) - .setView(radioGroup) + .setView(dialogView) .setCancelable(true) .setNegativeButton(R.string.just_once, dialogButtonsClickListener) .setPositiveButton(R.string.always, dialogButtonsClickListener) @@ -796,12 +838,38 @@ public Consumer getResultHandler(final Choice choice) { return; } - if (choice.playerChoice.equals(videoPlayerKey)) { - NavigationHelper.playOnMainPlayer(this, playQueue, false); - } else if (choice.playerChoice.equals(backgroundPlayerKey)) { - NavigationHelper.playOnBackgroundPlayer(this, playQueue, true); - } else if (choice.playerChoice.equals(popupPlayerKey)) { - NavigationHelper.playOnPopupPlayer(this, playQueue, true); + final boolean prioritizeEnqueue = preferences.getBoolean( + getString(R.string.prioritize_enqueue), + false); + // BUG: getType() always return null if main view is not open. + // final MainPlayer.PlayerType type = PlayerHolder.getType(); + + /* If prioritize_enqueue is enabled and we have running player, then enqueue + this stream. Otherwise, open preferred player instead. */ + if (prioritizeEnqueue /* && type != null*/) { + /* See getType() BUG above. + if (type == MainPlayer.PlayerType.AUDIO) { + NavigationHelper.enqueueOnBackgroundPlayer(this, playQueue, false); + } else if (type == MainPlayer.PlayerType.POPUP) { + NavigationHelper.enqueueOnPopupPlayer(this, playQueue, false); + } else if (type == MainPlayer.PlayerType.VIDEO) { + NavigationHelper.enqueueOnVideoPlayer(this, playQueue, false); + } */ + if (choice.playerChoice.equals(videoPlayerKey)) { + NavigationHelper.enqueueOnVideoPlayer(this, playQueue, false); + } else if (choice.playerChoice.equals(backgroundPlayerKey)) { + NavigationHelper.enqueueOnBackgroundPlayer(this, playQueue, false); + } else if (choice.playerChoice.equals(popupPlayerKey)) { + NavigationHelper.enqueueOnPopupPlayer(this, playQueue, false); + } + } else { + if (choice.playerChoice.equals(videoPlayerKey)) { + NavigationHelper.playOnMainPlayer(this, playQueue, false); + } else if (choice.playerChoice.equals(backgroundPlayerKey)) { + NavigationHelper.playOnBackgroundPlayer(this, playQueue, true); + } else if (choice.playerChoice.equals(popupPlayerKey)) { + NavigationHelper.playOnPopupPlayer(this, playQueue, true); + } } }; } diff --git a/app/src/main/res/drawable/ic_arrow_drop_right.xml b/app/src/main/res/drawable/ic_arrow_drop_right.xml new file mode 100644 index 00000000000..dcf2035ada7 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_drop_right.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/dialog_share_context.xml b/app/src/main/res/layout/dialog_share_context.xml new file mode 100644 index 00000000000..b593b9a70e3 --- /dev/null +++ b/app/src/main/res/layout/dialog_share_context.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 9489ef543c8..ba7d74a68a2 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -247,6 +247,7 @@ peertube_selected_instance peertube_instance_list content_country + prioritize_enqueue show_age_restricted_content youtube_restricted_mode_enabled enable_search_history diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 897ec0af8b3..70706113f3b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -148,6 +148,8 @@ Playing in background Playing in popup mode Content + Prioritize stream queuing + Attempt to enqueue streams for shared URLs instead of playing them immediately Show age restricted content Show content possibly unsuitable for children because it has an age limit (like 18+) Turn on YouTube\'s \"Restricted Mode\" @@ -704,4 +706,5 @@ Error at Show Channel Details Loading Channel Details… + Advanced Options diff --git a/app/src/main/res/xml/video_audio_settings.xml b/app/src/main/res/xml/video_audio_settings.xml index f605fbe170e..55c55735926 100644 --- a/app/src/main/res/xml/video_audio_settings.xml +++ b/app/src/main/res/xml/video_audio_settings.xml @@ -119,6 +119,13 @@ app:singleLineTitle="false" app:iconSpaceReserved="false" /> + +