Allow each notification slot to contain any possible action

This commit is contained in:
Stypox 2023-12-29 14:04:18 +01:00
parent aab6580195
commit 9fb8125655
No known key found for this signature in database
GPG key ID: 4BDF1B40A49FDD23
4 changed files with 48 additions and 43 deletions

View file

@ -13,7 +13,7 @@ import org.schabi.newpipe.util.Localization;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
@ -65,10 +65,16 @@ public final class NotificationConstants {
public static final int CLOSE = 11; public static final int CLOSE = 11;
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({NOTHING, PREVIOUS, NEXT, REWIND, FORWARD, SMART_REWIND_PREVIOUS, SMART_FORWARD_NEXT, @IntDef({NOTHING, PREVIOUS, NEXT, REWIND, FORWARD,
PLAY_PAUSE, PLAY_PAUSE_BUFFERING, REPEAT, SHUFFLE, CLOSE}) SMART_REWIND_PREVIOUS, SMART_FORWARD_NEXT, PLAY_PAUSE, PLAY_PAUSE_BUFFERING, REPEAT,
SHUFFLE, CLOSE})
public @interface Action { } public @interface Action { }
@Action
public static final int[] ALL_ACTIONS = {NOTHING, PREVIOUS, NEXT, REWIND, FORWARD,
SMART_REWIND_PREVIOUS, SMART_FORWARD_NEXT, PLAY_PAUSE, PLAY_PAUSE_BUFFERING, REPEAT,
SHUFFLE, CLOSE};
@DrawableRes @DrawableRes
public static final int[] ACTION_ICONS = { public static final int[] ACTION_ICONS = {
0, 0,
@ -95,16 +101,6 @@ public final class NotificationConstants {
CLOSE, CLOSE,
}; };
@Action
public static final int[][] SLOT_ALLOWED_ACTIONS = {
new int[] {PREVIOUS, REWIND, SMART_REWIND_PREVIOUS},
new int[] {REWIND, PLAY_PAUSE, PLAY_PAUSE_BUFFERING},
new int[] {NEXT, FORWARD, SMART_FORWARD_NEXT, PLAY_PAUSE, PLAY_PAUSE_BUFFERING},
new int[] {NOTHING, PREVIOUS, NEXT, REWIND, FORWARD, SMART_REWIND_PREVIOUS,
SMART_FORWARD_NEXT, REPEAT, SHUFFLE, CLOSE},
new int[] {NOTHING, NEXT, FORWARD, SMART_FORWARD_NEXT, REPEAT, SHUFFLE, CLOSE},
};
public static final int[] SLOT_PREF_KEYS = { public static final int[] SLOT_PREF_KEYS = {
R.string.notification_slot_0_key, R.string.notification_slot_0_key,
R.string.notification_slot_1_key, R.string.notification_slot_1_key,
@ -165,14 +161,11 @@ public final class NotificationConstants {
/** /**
* @param context the context to use * @param context the context to use
* @param sharedPreferences the shared preferences to query values from * @param sharedPreferences the shared preferences to query values from
* @param slotCount remove indices >= than this value (set to {@code 5} to do nothing, or make
* it lower if there are slots with empty actions)
* @return a sorted list of the indices of the slots to use as compact slots * @return a sorted list of the indices of the slots to use as compact slots
*/ */
public static List<Integer> getCompactSlotsFromPreferences( public static Collection<Integer> getCompactSlotsFromPreferences(
@NonNull final Context context, @NonNull final Context context,
final SharedPreferences sharedPreferences, final SharedPreferences sharedPreferences) {
final int slotCount) {
final SortedSet<Integer> compactSlots = new TreeSet<>(); final SortedSet<Integer> compactSlots = new TreeSet<>();
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
final int compactSlot = sharedPreferences.getInt( final int compactSlot = sharedPreferences.getInt(
@ -180,14 +173,14 @@ public final class NotificationConstants {
if (compactSlot == Integer.MAX_VALUE) { if (compactSlot == Integer.MAX_VALUE) {
// settings not yet populated, return default values // settings not yet populated, return default values
return new ArrayList<>(SLOT_COMPACT_DEFAULTS); return SLOT_COMPACT_DEFAULTS;
} }
// a negative value (-1) is set when the user does not want a particular compact slot if (compactSlot >= 0) {
if (compactSlot >= 0 && compactSlot < slotCount) { // compact slot is < 0 if there are less than 3 checked checkboxes
compactSlots.add(compactSlot); compactSlots.add(compactSlot);
} }
} }
return new ArrayList<>(compactSlots); return compactSlots;
} }
} }

View file

@ -23,6 +23,8 @@ import org.schabi.newpipe.player.Player;
import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi; import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@ -101,21 +103,7 @@ public final class NotificationUtil {
new NotificationCompat.Builder(player.getContext(), new NotificationCompat.Builder(player.getContext(),
player.getContext().getString(R.string.notification_channel_id)); player.getContext().getString(R.string.notification_channel_id));
initializeNotificationSlots(); final int[] compactSlots = initializeNotificationSlots();
// count the number of real slots, to make sure compact slots indices are not out of bound
int nonNothingSlotCount = 5;
if (notificationSlots[3] == NotificationConstants.NOTHING) {
--nonNothingSlotCount;
}
if (notificationSlots[4] == NotificationConstants.NOTHING) {
--nonNothingSlotCount;
}
// build the compact slot indices array (need code to convert from Integer... because Java)
final List<Integer> compactSlotList = NotificationConstants.getCompactSlotsFromPreferences(
player.getContext(), player.getPrefs(), nonNothingSlotCount);
final int[] compactSlots = compactSlotList.stream().mapToInt(Integer::intValue).toArray();
final MediaStyle mediaStyle = new MediaStyle().setShowActionsInCompactView(compactSlots); final MediaStyle mediaStyle = new MediaStyle().setShowActionsInCompactView(compactSlots);
player.UIs() player.UIs()
@ -209,12 +197,35 @@ public final class NotificationUtil {
// ACTIONS // ACTIONS
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
private void initializeNotificationSlots() { /**
* The compact slots array from settings contains indices from 0 to 4, each referring to one of
* the five actions configurable by the user. However, if the user sets an action to "Nothing",
* then all of the actions coming after will have a "settings index" different than the index
* of the corresponding action when sent to the system.
*
* @return the indices of compact slots referred to the list of non-nothing actions that will be
* sent to the system
*/
private int[] initializeNotificationSlots() {
final Collection<Integer> settingsCompactSlots = NotificationConstants
.getCompactSlotsFromPreferences(player.getContext(), player.getPrefs());
final List<Integer> adjustedCompactSlots = new ArrayList<>();
int nonNothingIndex = 0;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
notificationSlots[i] = player.getPrefs().getInt( notificationSlots[i] = player.getPrefs().getInt(
player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]), player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
NotificationConstants.SLOT_DEFAULTS[i]); NotificationConstants.SLOT_DEFAULTS[i]);
if (notificationSlots[i] != NotificationConstants.NOTHING) {
if (settingsCompactSlots.contains(i)) {
adjustedCompactSlots.add(nonNothingIndex);
} }
nonNothingIndex += 1;
}
}
return adjustedCompactSlots.stream().mapToInt(Integer::intValue).toArray();
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")

View file

@ -20,6 +20,7 @@ import org.schabi.newpipe.App;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.player.notification.NotificationConstants; import org.schabi.newpipe.player.notification.NotificationConstants;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.IntStream; import java.util.stream.IntStream;
@ -67,8 +68,8 @@ public class NotificationActionsPreference extends Preference {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
private void setupActions(@NonNull final View view) { private void setupActions(@NonNull final View view) {
compactSlots = NotificationConstants.getCompactSlotsFromPreferences(getContext(), compactSlots = new ArrayList<>(NotificationConstants.getCompactSlotsFromPreferences(
getSharedPreferences(), 5); getContext(), getSharedPreferences()));
notificationSlots = IntStream.range(0, 5) notificationSlots = IntStream.range(0, 5)
.mapToObj(i -> new NotificationSlot(getContext(), getSharedPreferences(), i, view, .mapToObj(i -> new NotificationSlot(getContext(), getSharedPreferences(), i, view,
compactSlots.contains(i), this::onToggleCompactSlot)) compactSlots.contains(i), this::onToggleCompactSlot))

View file

@ -130,13 +130,13 @@ class NotificationSlot {
.create(); .create();
final View.OnClickListener radioButtonsClickListener = v -> { final View.OnClickListener radioButtonsClickListener = v -> {
selectedAction = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][v.getId()]; selectedAction = NotificationConstants.ALL_ACTIONS[v.getId()];
updateInfo(); updateInfo();
alertDialog.dismiss(); alertDialog.dismiss();
}; };
for (int id = 0; id < NotificationConstants.SLOT_ALLOWED_ACTIONS[i].length; ++id) { for (int id = 0; id < NotificationConstants.ALL_ACTIONS.length; ++id) {
final int action = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id]; final int action = NotificationConstants.ALL_ACTIONS[id];
final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater) final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater)
.getRoot(); .getRoot();