Add notification costumization settings menu
@ -258,7 +258,7 @@ public class RouterActivity extends AppCompatActivity {
|
||||
|
||||
final LayoutInflater inflater = LayoutInflater.from(themeWrapperContext);
|
||||
final LinearLayout rootLayout = (LinearLayout) inflater.inflate(
|
||||
R.layout.preferred_player_dialog_view, null, false);
|
||||
R.layout.single_choice_dialog_view, null, false);
|
||||
final RadioGroup radioGroup = rootLayout.findViewById(android.R.id.list);
|
||||
|
||||
final DialogInterface.OnClickListener dialogButtonsClickListener = (dialog, which) -> {
|
||||
|
@ -77,11 +77,11 @@ public final class MainPlayer extends Service {
|
||||
static final String ACTION_FAST_FORWARD
|
||||
= "org.schabi.newpipe.player.MainPlayer.ACTION_FAST_FORWARD";
|
||||
static final String ACTION_BUFFERING
|
||||
= "org.schabi.newpipe.player.BackgroundPlayer.ACTION_BUFFERING";
|
||||
= "org.schabi.newpipe.player.MainPlayer.ACTION_BUFFERING";
|
||||
static final String ACTION_SHUFFLE
|
||||
= "org.schabi.newpipe.player.BackgroundPlayer.ACTION_SHUFFLE";
|
||||
|
||||
static final String SET_IMAGE_RESOURCE_METHOD = "setImageResource";
|
||||
= "org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE";
|
||||
public static final String ACTION_RECREATE_NOTIFICATION
|
||||
= "org.schabi.newpipe.player.MainPlayer.ACTION_RECREATE_NOTIFICATION";
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Service's LifeCycle
|
||||
|
@ -0,0 +1,141 @@
|
||||
package org.schabi.newpipe.player;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public final class NotificationConstants {
|
||||
|
||||
private NotificationConstants() { }
|
||||
|
||||
|
||||
public static final int NOTHING = 0;
|
||||
public static final int PREVIOUS = 1;
|
||||
public static final int NEXT = 2;
|
||||
public static final int REWIND = 3;
|
||||
public static final int FORWARD = 4;
|
||||
public static final int SMART_REWIND_PREVIOUS = 5;
|
||||
public static final int SMART_FORWARD_NEXT = 6;
|
||||
public static final int PLAY_PAUSE = 7;
|
||||
public static final int PLAY_PAUSE_BUFFERING = 8;
|
||||
public static final int REPEAT = 9;
|
||||
public static final int SHUFFLE = 10;
|
||||
public static final int CLOSE = 11;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({NOTHING, PREVIOUS, NEXT, REWIND, FORWARD, SMART_REWIND_PREVIOUS, SMART_FORWARD_NEXT,
|
||||
PLAY_PAUSE, PLAY_PAUSE_BUFFERING, REPEAT, SHUFFLE, CLOSE})
|
||||
public @interface Action { }
|
||||
|
||||
@StringRes
|
||||
public static final int[] ACTION_SUMMARIES = {
|
||||
R.string.notification_action_nothing,
|
||||
R.string.notification_action_previous,
|
||||
R.string.notification_action_next,
|
||||
R.string.notification_action_rewind,
|
||||
R.string.notification_action_forward,
|
||||
R.string.notification_action_smart_rewind_previous,
|
||||
R.string.notification_action_smart_forward_next,
|
||||
R.string.notification_action_play_pause,
|
||||
R.string.notification_action_play_pause_buffering,
|
||||
R.string.notification_action_repeat,
|
||||
R.string.notification_action_shuffle,
|
||||
R.string.close,
|
||||
};
|
||||
|
||||
@DrawableRes
|
||||
public static final int[] ACTION_ICONS = {
|
||||
0,
|
||||
R.drawable.exo_icon_previous,
|
||||
R.drawable.exo_icon_next,
|
||||
R.drawable.exo_icon_rewind,
|
||||
R.drawable.exo_icon_fastforward,
|
||||
R.drawable.exo_icon_previous,
|
||||
R.drawable.exo_icon_next,
|
||||
R.drawable.ic_pause_white_24dp,
|
||||
R.drawable.ic_hourglass_top_white_24dp,
|
||||
R.drawable.exo_icon_repeat_all,
|
||||
R.drawable.exo_icon_shuffle_on,
|
||||
R.drawable.ic_close_white_24dp,
|
||||
};
|
||||
|
||||
|
||||
@Action
|
||||
public static final int[] SLOT_DEFAULTS = {
|
||||
SMART_REWIND_PREVIOUS,
|
||||
PLAY_PAUSE_BUFFERING,
|
||||
SMART_FORWARD_NEXT,
|
||||
REPEAT,
|
||||
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 = {
|
||||
R.string.notification_slot_0_key,
|
||||
R.string.notification_slot_1_key,
|
||||
R.string.notification_slot_2_key,
|
||||
R.string.notification_slot_3_key,
|
||||
R.string.notification_slot_4_key,
|
||||
};
|
||||
|
||||
|
||||
public static final Integer[] SLOT_COMPACT_DEFAULTS = {0, 1, 2};
|
||||
|
||||
public static final int[] SLOT_COMPACT_PREF_KEYS = {
|
||||
R.string.notification_slot_compact_0_key,
|
||||
R.string.notification_slot_compact_1_key,
|
||||
R.string.notification_slot_compact_2_key,
|
||||
};
|
||||
|
||||
/**
|
||||
* @param context the context to use
|
||||
* @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
|
||||
*/
|
||||
public static List<Integer> getCompactSlotsFromPreferences(
|
||||
@NonNull final Context context,
|
||||
final SharedPreferences sharedPreferences,
|
||||
final int slotCount) {
|
||||
final SortedSet<Integer> compactSlots = new TreeSet<>();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
final int compactSlot = sharedPreferences.getInt(
|
||||
context.getString(SLOT_COMPACT_PREF_KEYS[i]), Integer.MAX_VALUE);
|
||||
|
||||
if (compactSlot == Integer.MAX_VALUE) {
|
||||
// settings not yet populated, return default values
|
||||
return new ArrayList<>(Arrays.asList(SLOT_COMPACT_DEFAULTS));
|
||||
}
|
||||
|
||||
// a negative value (-1) is set when the user does not want a particular compact slot
|
||||
if (compactSlot >= 0 && compactSlot < slotCount) {
|
||||
compactSlots.add(compactSlot);
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(compactSlots);
|
||||
}
|
||||
}
|
@ -20,6 +20,8 @@ import org.schabi.newpipe.MainActivity;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
|
||||
import static android.content.Context.NOTIFICATION_SERVICE;
|
||||
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
|
||||
@ -46,11 +48,8 @@ public final class NotificationUtil {
|
||||
|
||||
@Nullable private static NotificationUtil instance = null;
|
||||
|
||||
private String notificationSlot0 = "smart_rewind_prev";
|
||||
private String notificationSlot1 = "play_pause_buffering";
|
||||
private String notificationSlot2 = "smart_forward_next";
|
||||
private String notificationSlot3 = "repeat";
|
||||
private String notificationSlot4 = "close";
|
||||
@NotificationConstants.Action
|
||||
private int[] notificationSlots = NotificationConstants.SLOT_DEFAULTS.clone();
|
||||
|
||||
private NotificationManager notificationManager;
|
||||
private NotificationCompat.Builder notificationBuilder;
|
||||
@ -91,35 +90,28 @@ public final class NotificationUtil {
|
||||
final NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context,
|
||||
player.context.getString(R.string.notification_channel_id));
|
||||
|
||||
final String compactView = player.sharedPreferences.getString(player.context.getString(
|
||||
R.string.settings_notifications_compact_view_key), "0,1,2");
|
||||
int compactSlot0 = 0;
|
||||
int compactSlot1 = 1;
|
||||
int compactSlot2 = 2;
|
||||
try {
|
||||
if (compactView != null) {
|
||||
final String[] parts = compactView.split(",");
|
||||
compactSlot0 = Integer.parseInt(parts[0]);
|
||||
compactSlot1 = Integer.parseInt(parts[1]);
|
||||
compactSlot2 = Integer.parseInt(parts[2]);
|
||||
if (compactSlot0 > 4) {
|
||||
compactSlot0 = 0;
|
||||
}
|
||||
if (compactSlot1 > 4) {
|
||||
compactSlot1 = 1;
|
||||
}
|
||||
if (compactSlot2 > 4) {
|
||||
compactSlot2 = 2;
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
initializeNotificationSlots(player);
|
||||
|
||||
// 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.context, player.sharedPreferences, nonNothingSlotCount);
|
||||
final int[] compactSlots = new int[compactSlotList.size()];
|
||||
for (int i = 0; i < compactSlotList.size(); i++) {
|
||||
compactSlots[i] = compactSlotList.get(i);
|
||||
}
|
||||
|
||||
builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
|
||||
.setMediaSession(player.mediaSessionManager.getSessionToken())
|
||||
.setShowActionsInCompactView(compactSlot0, compactSlot1, compactSlot2))
|
||||
.setShowActionsInCompactView(compactSlots))
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
@ -131,7 +123,6 @@ public final class NotificationUtil {
|
||||
.setDeleteIntent(PendingIntent.getBroadcast(player.context, NOTIFICATION_ID,
|
||||
new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT));
|
||||
|
||||
initializeNotificationSlots(player);
|
||||
updateActions(builder, player);
|
||||
setLargeIcon(builder, player);
|
||||
|
||||
@ -171,22 +162,20 @@ public final class NotificationUtil {
|
||||
|
||||
|
||||
boolean hasSlotWithBuffering() {
|
||||
return notificationSlot0.equals("play_pause_buffering")
|
||||
|| notificationSlot1.equals("play_pause_buffering")
|
||||
|| notificationSlot2.equals("play_pause_buffering")
|
||||
|| notificationSlot3.equals("play_pause_buffering")
|
||||
|| notificationSlot4.equals("play_pause_buffering");
|
||||
return notificationSlots[1] == NotificationConstants.PLAY_PAUSE_BUFFERING
|
||||
|| notificationSlots[2] == NotificationConstants.PLAY_PAUSE_BUFFERING;
|
||||
}
|
||||
|
||||
public void cancelNotification() {
|
||||
void cancelNotification() {
|
||||
try {
|
||||
if (notificationManager != null) {
|
||||
notificationManager.cancel(NOTIFICATION_ID);
|
||||
notificationManager = null;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
Log.e(TAG, "Could not cancel notification", e);
|
||||
}
|
||||
notificationManager = null;
|
||||
notificationBuilder = null;
|
||||
}
|
||||
|
||||
|
||||
@ -195,32 +184,25 @@ public final class NotificationUtil {
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
private void initializeNotificationSlots(final VideoPlayerImpl player) {
|
||||
notificationSlot0 = player.sharedPreferences.getString(
|
||||
player.context.getString(R.string.notification_action_0_key), notificationSlot0);
|
||||
notificationSlot1 = player.sharedPreferences.getString(
|
||||
player.context.getString(R.string.notification_action_1_key), notificationSlot1);
|
||||
notificationSlot2 = player.sharedPreferences.getString(
|
||||
player.context.getString(R.string.notification_action_2_key), notificationSlot2);
|
||||
notificationSlot3 = player.sharedPreferences.getString(
|
||||
player.context.getString(R.string.notification_action_3_key), notificationSlot3);
|
||||
notificationSlot4 = player.sharedPreferences.getString(
|
||||
player.context.getString(R.string.notification_action_4_key), notificationSlot4);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
notificationSlots[i] = player.sharedPreferences.getInt(
|
||||
player.context.getString(NotificationConstants.SLOT_PREF_KEYS[i]),
|
||||
NotificationConstants.SLOT_DEFAULTS[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
private void updateActions(final NotificationCompat.Builder builder,
|
||||
final VideoPlayerImpl player) {
|
||||
builder.mActions.clear();
|
||||
addAction(builder, player, notificationSlot0);
|
||||
addAction(builder, player, notificationSlot1);
|
||||
addAction(builder, player, notificationSlot2);
|
||||
addAction(builder, player, notificationSlot3);
|
||||
addAction(builder, player, notificationSlot4);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
addAction(builder, player, notificationSlots[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void addAction(final NotificationCompat.Builder builder,
|
||||
final VideoPlayerImpl player,
|
||||
final String slot) {
|
||||
@NotificationConstants.Action final int slot) {
|
||||
final NotificationCompat.Action action = getAction(player, slot);
|
||||
if (action != null) {
|
||||
builder.addAction(action);
|
||||
@ -228,23 +210,42 @@ public final class NotificationUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private NotificationCompat.Action getAction(final VideoPlayerImpl player,
|
||||
final String slot) {
|
||||
switch (slot) {
|
||||
case "play_pause_buffering":
|
||||
if (player.getCurrentState() == BasePlayer.STATE_PREFLIGHT
|
||||
|| player.getCurrentState() == BasePlayer.STATE_BLOCKED
|
||||
|| player.getCurrentState() == BasePlayer.STATE_BUFFERING) {
|
||||
return getAction(player, R.drawable.ic_hourglass_top_white_24dp,
|
||||
"Buffering", ACTION_BUFFERING);
|
||||
private NotificationCompat.Action getAction(
|
||||
final VideoPlayerImpl player,
|
||||
@NotificationConstants.Action final int selectedAction) {
|
||||
final int baseActionIcon = NotificationConstants.ACTION_ICONS[selectedAction];
|
||||
switch (selectedAction) {
|
||||
case NotificationConstants.PREVIOUS:
|
||||
return getAction(player, baseActionIcon, "Previous", ACTION_PLAY_PREVIOUS);
|
||||
|
||||
case NotificationConstants.NEXT:
|
||||
return getAction(player, baseActionIcon, "Next", ACTION_PLAY_NEXT);
|
||||
|
||||
case NotificationConstants.REWIND:
|
||||
return getAction(player, baseActionIcon, "Rewind", ACTION_FAST_REWIND);
|
||||
|
||||
case NotificationConstants.FORWARD:
|
||||
return getAction(player, baseActionIcon, "Forward", ACTION_FAST_FORWARD);
|
||||
|
||||
case NotificationConstants.SMART_REWIND_PREVIOUS:
|
||||
if (player.playQueue != null && player.playQueue.size() > 1) {
|
||||
return getAction(player, R.drawable.exo_notification_previous,
|
||||
"Previous", ACTION_PLAY_PREVIOUS);
|
||||
} else {
|
||||
return getAction(player,
|
||||
player.isPlaying() ? R.drawable.exo_notification_pause
|
||||
: R.drawable.exo_notification_play,
|
||||
player.isPlaying() ? "Pause" : "Play",
|
||||
ACTION_PLAY_PAUSE);
|
||||
return getAction(player, R.drawable.exo_controls_rewind,
|
||||
"Rewind", ACTION_FAST_REWIND);
|
||||
}
|
||||
case "play_pause":
|
||||
|
||||
case NotificationConstants.SMART_FORWARD_NEXT:
|
||||
if (player.playQueue != null && player.playQueue.size() > 1) {
|
||||
return getAction(player, R.drawable.exo_notification_next,
|
||||
"Next", ACTION_PLAY_NEXT);
|
||||
} else {
|
||||
return getAction(player, R.drawable.exo_controls_fastforward,
|
||||
"Forward", ACTION_FAST_FORWARD);
|
||||
}
|
||||
|
||||
case NotificationConstants.PLAY_PAUSE:
|
||||
final boolean pauseOrPlay = player.isPlaying()
|
||||
|| player.getCurrentState() == BasePlayer.STATE_PREFLIGHT
|
||||
|| player.getCurrentState() == BasePlayer.STATE_BLOCKED
|
||||
@ -254,48 +255,38 @@ public final class NotificationUtil {
|
||||
: R.drawable.exo_notification_play,
|
||||
pauseOrPlay ? "Pause" : "Play",
|
||||
ACTION_PLAY_PAUSE);
|
||||
case "rewind":
|
||||
return getAction(player, R.drawable.exo_controls_rewind,
|
||||
"Rewind", ACTION_FAST_REWIND);
|
||||
case "smart_rewind_prev":
|
||||
if (player.playQueue != null && player.playQueue.size() > 1) {
|
||||
return getAction(player, R.drawable.exo_notification_previous,
|
||||
"Prev", ACTION_PLAY_PREVIOUS);
|
||||
|
||||
case NotificationConstants.PLAY_PAUSE_BUFFERING:
|
||||
if (player.getCurrentState() == BasePlayer.STATE_PREFLIGHT
|
||||
|| player.getCurrentState() == BasePlayer.STATE_BLOCKED
|
||||
|| player.getCurrentState() == BasePlayer.STATE_BUFFERING) {
|
||||
return getAction(player, R.drawable.ic_hourglass_top_white_24dp_png,
|
||||
"Buffering", ACTION_BUFFERING);
|
||||
} else {
|
||||
return getAction(player, R.drawable.exo_controls_rewind,
|
||||
"Rewind", ACTION_FAST_REWIND);
|
||||
return getAction(player,
|
||||
player.isPlaying() ? R.drawable.exo_notification_pause
|
||||
: R.drawable.exo_notification_play,
|
||||
player.isPlaying() ? "Pause" : "Play",
|
||||
ACTION_PLAY_PAUSE);
|
||||
}
|
||||
case "forward":
|
||||
return getAction(player, R.drawable.exo_controls_fastforward,
|
||||
"Forward", ACTION_FAST_FORWARD);
|
||||
case "smart_forward_next":
|
||||
if (player.playQueue != null && player.playQueue.size() > 1) {
|
||||
return getAction(player, R.drawable.exo_notification_next,
|
||||
"Next", ACTION_PLAY_NEXT);
|
||||
} else {
|
||||
return getAction(player, R.drawable.exo_controls_fastforward,
|
||||
"Forward", ACTION_FAST_FORWARD);
|
||||
}
|
||||
case "next":
|
||||
return getAction(player, R.drawable.exo_notification_next,
|
||||
"Next", ACTION_PLAY_NEXT);
|
||||
case "prev":
|
||||
return getAction(player, R.drawable.exo_notification_previous,
|
||||
"Prev", ACTION_PLAY_PREVIOUS);
|
||||
case "repeat":
|
||||
|
||||
case NotificationConstants.REPEAT:
|
||||
return getAction(player, getRepeatModeDrawable(player.getRepeatMode()),
|
||||
getRepeatModeTitle(player.getRepeatMode()), ACTION_REPEAT);
|
||||
case "shuffle":
|
||||
|
||||
case NotificationConstants.SHUFFLE:
|
||||
final boolean shuffled = player.playQueue != null && player.playQueue.isShuffled();
|
||||
return getAction(player,
|
||||
shuffled ? R.drawable.exo_controls_shuffle_on
|
||||
: R.drawable.exo_controls_shuffle_off,
|
||||
shuffled ? "ShuffleOn" : "ShuffleOff",
|
||||
ACTION_SHUFFLE);
|
||||
case "close":
|
||||
return getAction(player, R.drawable.ic_close_white_24dp,
|
||||
|
||||
case NotificationConstants.CLOSE:
|
||||
return getAction(player, R.drawable.ic_close_white_24dp_png,
|
||||
"Close", ACTION_CLOSE);
|
||||
case "n/a":
|
||||
|
||||
case NotificationConstants.NOTHING:
|
||||
default:
|
||||
// do nothing
|
||||
return null;
|
||||
|
@ -112,6 +112,7 @@ import static org.schabi.newpipe.player.MainPlayer.ACTION_OPEN_CONTROLS;
|
||||
import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_NEXT;
|
||||
import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PAUSE;
|
||||
import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PREVIOUS;
|
||||
import static org.schabi.newpipe.player.MainPlayer.ACTION_RECREATE_NOTIFICATION;
|
||||
import static org.schabi.newpipe.player.MainPlayer.ACTION_REPEAT;
|
||||
import static org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE;
|
||||
import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_BACKGROUND;
|
||||
@ -1179,6 +1180,7 @@ public class VideoPlayerImpl extends VideoPlayer
|
||||
intentFilter.addAction(ACTION_FAST_FORWARD);
|
||||
intentFilter.addAction(ACTION_BUFFERING);
|
||||
intentFilter.addAction(ACTION_SHUFFLE);
|
||||
intentFilter.addAction(ACTION_RECREATE_NOTIFICATION);
|
||||
|
||||
intentFilter.addAction(VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED);
|
||||
intentFilter.addAction(VideoDetailFragment.ACTION_VIDEO_FRAGMENT_STOPPED);
|
||||
@ -1236,6 +1238,9 @@ public class VideoPlayerImpl extends VideoPlayer
|
||||
case ACTION_SHUFFLE:
|
||||
onShuffleClicked();
|
||||
break;
|
||||
case ACTION_RECREATE_NOTIFICATION:
|
||||
resetNotification(true);
|
||||
break;
|
||||
case Intent.ACTION_HEADSET_PLUG: //FIXME
|
||||
/*notificationManager.cancel(NOTIFICATION_ID);
|
||||
mediaSessionManager.dispose();
|
||||
|
@ -0,0 +1,271 @@
|
||||
package org.schabi.newpipe.settings;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.LayoutInflater;
|
||||
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.Switch;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.player.MainPlayer;
|
||||
import org.schabi.newpipe.player.NotificationConstants;
|
||||
import org.schabi.newpipe.util.DeviceUtils;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
import org.schabi.newpipe.views.FocusOverlayView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NotificationSettingsFragment extends Fragment {
|
||||
|
||||
private Switch scaleSwitch;
|
||||
private NotificationSlot[] notificationSlots;
|
||||
|
||||
private SharedPreferences pref;
|
||||
private List<Integer> compactSlots;
|
||||
private String scaleKey;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
pref = PreferenceManager.getDefaultSharedPreferences(requireContext());
|
||||
scaleKey = getString(R.string.scale_to_square_image_in_notifications_key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull final LayoutInflater inflater,
|
||||
final ViewGroup container,
|
||||
@Nullable final Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.settings_notification, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull final View rootView,
|
||||
@Nullable final Bundle savedInstanceState) {
|
||||
super.onViewCreated(rootView, savedInstanceState);
|
||||
|
||||
setupScaleSwitch(rootView);
|
||||
setupActions(rootView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
ThemeHelper.setTitleToAppCompatActivity(getActivity(),
|
||||
getString(R.string.settings_category_notification_title));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
saveChanges();
|
||||
requireContext().sendBroadcast(new Intent(MainPlayer.ACTION_RECREATE_NOTIFICATION));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Setup
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setupScaleSwitch(@NonNull final View view) {
|
||||
scaleSwitch = view.findViewById(R.id.notificationScaleSwitch);
|
||||
scaleSwitch.setChecked(pref.getBoolean(scaleKey, false));
|
||||
|
||||
view.findViewById(R.id.notificationScaleSwitchClickableArea)
|
||||
.setOnClickListener(v -> scaleSwitch.toggle());
|
||||
}
|
||||
|
||||
private void setupActions(@NonNull final View view) {
|
||||
compactSlots =
|
||||
NotificationConstants.getCompactSlotsFromPreferences(requireContext(), pref, 5);
|
||||
notificationSlots = new NotificationSlot[5];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
notificationSlots[i] = new NotificationSlot(i, view);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Saving
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void saveChanges() {
|
||||
final SharedPreferences.Editor editor = pref.edit();
|
||||
editor.putBoolean(scaleKey, scaleSwitch.isChecked());
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
editor.putInt(getString(NotificationConstants.SLOT_COMPACT_PREF_KEYS[i]),
|
||||
(i < compactSlots.size() ? compactSlots.get(i) : -1));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
editor.putInt(getString(NotificationConstants.SLOT_PREF_KEYS[i]),
|
||||
notificationSlots[i].selectedAction);
|
||||
}
|
||||
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Notification action
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static final int[] SLOT_ITEMS = {
|
||||
R.id.notificationAction0,
|
||||
R.id.notificationAction1,
|
||||
R.id.notificationAction2,
|
||||
R.id.notificationAction3,
|
||||
R.id.notificationAction4,
|
||||
};
|
||||
|
||||
private static final int[] SLOT_TITLES = {
|
||||
R.string.notification_action_0_title,
|
||||
R.string.notification_action_1_title,
|
||||
R.string.notification_action_2_title,
|
||||
R.string.notification_action_3_title,
|
||||
R.string.notification_action_4_title,
|
||||
};
|
||||
|
||||
private class NotificationSlot {
|
||||
|
||||
final int i;
|
||||
@NotificationConstants.Action int selectedAction;
|
||||
|
||||
ImageView icon;
|
||||
TextView summary;
|
||||
|
||||
NotificationSlot(final int actionIndex, final View parentView) {
|
||||
this.i = actionIndex;
|
||||
|
||||
final View view = parentView.findViewById(SLOT_ITEMS[i]);
|
||||
setupSelectedAction(view);
|
||||
setupTitle(view);
|
||||
setupCheckbox(view);
|
||||
}
|
||||
|
||||
void setupTitle(final View view) {
|
||||
((TextView) view.findViewById(R.id.notificationActionTitle))
|
||||
.setText(SLOT_TITLES[i]);
|
||||
view.findViewById(R.id.notificationActionClickableArea).setOnClickListener(
|
||||
v -> openActionChooserDialog());
|
||||
}
|
||||
|
||||
void setupCheckbox(final View view) {
|
||||
final CheckBox compactSlotCheckBox = view.findViewById(R.id.notificationActionCheckBox);
|
||||
compactSlotCheckBox.setChecked(compactSlots.contains(i));
|
||||
view.findViewById(R.id.notificationActionCheckBoxClickableArea).setOnClickListener(
|
||||
v -> {
|
||||
if (compactSlotCheckBox.isChecked()) {
|
||||
compactSlots.remove((Integer) i);
|
||||
} else if (compactSlots.size() < 3) {
|
||||
compactSlots.add(i);
|
||||
} else {
|
||||
Toast.makeText(requireContext(),
|
||||
R.string.notification_actions_at_most_three,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
compactSlotCheckBox.toggle();
|
||||
});
|
||||
}
|
||||
|
||||
void setupSelectedAction(final View view) {
|
||||
icon = view.findViewById(R.id.notificationActionIcon);
|
||||
summary = view.findViewById(R.id.notificationActionSummary);
|
||||
selectedAction = pref.getInt(getString(NotificationConstants.SLOT_PREF_KEYS[i]),
|
||||
NotificationConstants.SLOT_DEFAULTS[i]);
|
||||
updateInfo();
|
||||
}
|
||||
|
||||
void updateInfo() {
|
||||
if (NotificationConstants.ACTION_ICONS[selectedAction] == 0) {
|
||||
icon.setImageDrawable(null);
|
||||
} else {
|
||||
icon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),
|
||||
NotificationConstants.ACTION_ICONS[selectedAction]));
|
||||
}
|
||||
|
||||
summary.setText(NotificationConstants.ACTION_SUMMARIES[selectedAction]);
|
||||
}
|
||||
|
||||
void openActionChooserDialog() {
|
||||
final LayoutInflater inflater = LayoutInflater.from(requireContext());
|
||||
final LinearLayout rootLayout = (LinearLayout) inflater.inflate(
|
||||
R.layout.single_choice_dialog_view, null, false);
|
||||
final RadioGroup radioGroup = rootLayout.findViewById(android.R.id.list);
|
||||
|
||||
final AlertDialog alertDialog = new AlertDialog.Builder(requireContext())
|
||||
.setTitle(SLOT_TITLES[i])
|
||||
.setView(radioGroup)
|
||||
.setCancelable(true)
|
||||
.create();
|
||||
|
||||
final View.OnClickListener radioButtonsClickListener = v -> {
|
||||
final int id = ((RadioButton) v).getId();
|
||||
selectedAction = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id];
|
||||
updateInfo();
|
||||
alertDialog.dismiss();
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
// if present set action icon with correct color
|
||||
if (NotificationConstants.ACTION_ICONS[action] != 0) {
|
||||
final Drawable drawable = AppCompatResources.getDrawable(requireContext(),
|
||||
NotificationConstants.ACTION_ICONS[action]);
|
||||
if (drawable != null) {
|
||||
final int color = ThemeHelper.resolveColorFromAttr(requireContext(),
|
||||
android.R.attr.textColorPrimary);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
drawable.setTint(color);
|
||||
} else {
|
||||
drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
radioButton.setCompoundDrawablesWithIntrinsicBounds(
|
||||
null, null, drawable, null);
|
||||
}
|
||||
}
|
||||
|
||||
radioButton.setText(NotificationConstants.ACTION_SUMMARIES[action]);
|
||||
radioButton.setChecked(action == selectedAction);
|
||||
radioButton.setId(id);
|
||||
radioButton.setLayoutParams(new RadioGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
radioButton.setOnClickListener(radioButtonsClickListener);
|
||||
radioGroup.addView(radioButton);
|
||||
}
|
||||
alertDialog.show();
|
||||
|
||||
if (DeviceUtils.isTv(requireContext())) {
|
||||
FocusOverlayView.setupFocusObserver(alertDialog);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
app/src/main/res/drawable-hdpi/ic_close_white_24dp_png.png
Normal file
After Width: | Height: | Size: 415 B |
Before Width: | Height: | Size: 302 B After Width: | Height: | Size: 302 B |
BIN
app/src/main/res/drawable-mdpi/ic_close_white_24dp_png.png
Normal file
After Width: | Height: | Size: 285 B |
Before Width: | Height: | Size: 246 B After Width: | Height: | Size: 246 B |
BIN
app/src/main/res/drawable-xhdpi/ic_close_white_24dp_png.png
Normal file
After Width: | Height: | Size: 602 B |
Before Width: | Height: | Size: 413 B After Width: | Height: | Size: 413 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_close_white_24dp_png.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 614 B After Width: | Height: | Size: 614 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_close_white_24dp_png.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 777 B After Width: | Height: | Size: 777 B |
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M6,2l0.01,6L10,12l-3.99,4.01L6,22h12v-6l-4,-4l4,-3.99V2H6zM16,16.5V20H8v-3.5l4,-4L16,16.5z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
@ -10,10 +10,8 @@
|
||||
android:maxLines="2"
|
||||
android:minHeight="?attr/listPreferredItemHeightSmall"
|
||||
android:paddingEnd="?attr/listPreferredItemPaddingRight"
|
||||
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?attr/listPreferredItemPaddingRight"
|
||||
android:paddingStart="?attr/listPreferredItemPaddingLeft"
|
||||
android:background="?attr/checked_selector"
|
||||
android:textColor="?attr/textColorAlertDialogListItem"
|
||||
tools:drawableLeft="?attr/ic_play"
|
||||
tools:drawableLeft="?attr/ic_play_arrow"
|
||||
tools:text="Lorem ipsum dolor sit amet" />
|
||||
|
135
app/src/main/res/layout/settings_notification.xml
Normal file
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<Switch
|
||||
android:id="@+id/notificationScaleSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/textView2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/textView" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:maxLines="1"
|
||||
android:text="@string/notification_scale_to_square_image_title"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/notificationScaleSwitch"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/notification_scale_to_square_image_summary"
|
||||
app:layout_constraintEnd_toStartOf="@+id/notificationScaleSwitch"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView" />
|
||||
|
||||
<View
|
||||
android:id="@+id/notificationScaleSwitchClickableArea"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:layout_constraintBottom_toTopOf="@+id/divider"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:background="?android:selectableItemBackground" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView4"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:gravity="center"
|
||||
android:lines="4"
|
||||
android:text="@string/notification_actions_summary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/divider" />
|
||||
|
||||
<include
|
||||
android:id="@+id/notificationAction0"
|
||||
layout="@layout/settings_notification_action"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView4" />
|
||||
|
||||
<include
|
||||
android:id="@+id/notificationAction1"
|
||||
layout="@layout/settings_notification_action"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/notificationAction0" />
|
||||
|
||||
<include
|
||||
android:id="@+id/notificationAction2"
|
||||
layout="@layout/settings_notification_action"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/notificationAction1" />
|
||||
|
||||
<include
|
||||
android:id="@+id/notificationAction3"
|
||||
layout="@layout/settings_notification_action"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/notificationAction2" />
|
||||
|
||||
<include
|
||||
android:id="@+id/notificationAction4"
|
||||
layout="@layout/settings_notification_action"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/notificationAction3" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
88
app/src/main/res/layout/settings_notification_action.xml
Normal file
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/notificationActionIcon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:tint="?android:textColorPrimary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintDimensionRatio="H,1:1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:src="@drawable/ic_previous_white_24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notificationActionTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/notificationActionSummary"
|
||||
app:layout_constraintEnd_toEndOf="@id/notificationActionClickableArea"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@+id/notificationActionIcon"
|
||||
app:layout_constraintTop_toTopOf="@+id/notificationActionIcon"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
tools:text="@string/notification_action_1_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notificationActionSummary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/notificationActionIcon"
|
||||
app:layout_constraintEnd_toEndOf="@+id/notificationActionClickableArea"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="@+id/notificationActionTitle"
|
||||
app:layout_constraintTop_toBottomOf="@+id/notificationActionTitle"
|
||||
tools:text="@string/notification_action_play_pause_buffering_value" />
|
||||
|
||||
<View
|
||||
android:id="@+id/notificationActionClickableArea"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/notificationActionCheckBoxClickableArea"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/notificationActionCheckBox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/notificationActionCheckBoxClickableArea"
|
||||
app:layout_constraintEnd_toEndOf="@+id/notificationActionCheckBoxClickableArea"
|
||||
app:layout_constraintStart_toStartOf="@+id/notificationActionCheckBoxClickableArea"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/notificationActionCheckBoxClickableArea"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintDimensionRatio="H,1:1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -118,108 +118,15 @@
|
||||
<string name="settings_notifications_compact_view_default_value" translatable="false">0,1,2</string>
|
||||
<string name="scale_to_square_image_in_notifications_key" translatable="false">scale_to_square_image_in_notifications</string>
|
||||
|
||||
<string name="notification_action_prev_key" translatable="false">prev</string>
|
||||
<string name="notification_action_next_key" translatable="false">next</string>
|
||||
<string name="notification_action_rewind_key" translatable="false">rewind</string>
|
||||
<string name="notification_action_forward_key" translatable="false">forward</string>
|
||||
<string name="notification_action_smart_rewind_prev_key" translatable="false">smart_rewind_prev</string>
|
||||
<string name="notification_action_smart_forward_next_key" translatable="false">smart_forward_next</string>
|
||||
<string name="notification_action_play_pause_buffering_key" translatable="false">play_pause_buffering</string>
|
||||
<string name="notification_action_play_pause_key" translatable="false">play_pause</string>
|
||||
<string name="notification_action_repeat_key" translatable="false">repeat</string>
|
||||
<string name="notification_action_shuffle_key" translatable="false">shuffle</string>
|
||||
<string name="notification_action_close_key" translatable="false">close</string>
|
||||
<string name="notification_action_n_a_key" translatable="false">n/a</string>
|
||||
<string name="notification_slot_0_key" translatable="false">notification_slot_0_key</string>
|
||||
<string name="notification_slot_1_key" translatable="false">notification_slot_1_key</string>
|
||||
<string name="notification_slot_2_key" translatable="false">notification_slot_2_key</string>
|
||||
<string name="notification_slot_3_key" translatable="false">notification_slot_3_key</string>
|
||||
<string name="notification_slot_4_key" translatable="false">notification_slot_4_key</string>
|
||||
|
||||
<string name="notification_action_0_key" translatable="false">notification_action_0_key</string>
|
||||
<string name="notification_action_0_value" translatable="false">@string/notification_action_smart_rewind_prev_key</string>
|
||||
<string-array name="notification_action_0_description_list" translatable="false">
|
||||
<item>@string/notification_action_smart_rewind_prev_value</item>
|
||||
<item>@string/notification_action_prev_value</item>
|
||||
<item>@string/notification_action_rewind_value</item>
|
||||
</string-array>
|
||||
<string-array name="notification_action_0_values_list" translatable="false">
|
||||
<item>@string/notification_action_smart_rewind_prev_key</item>
|
||||
<item>@string/notification_action_prev_key</item>
|
||||
<item>@string/notification_action_rewind_key</item>
|
||||
</string-array>
|
||||
|
||||
<string name="notification_action_1_key" translatable="false">notification_action_1_key</string>
|
||||
<string name="notification_action_1_value" translatable="false">@string/notification_action_play_pause_buffering_key</string>
|
||||
<string-array name="notification_action_1_description_list" translatable="false">
|
||||
<item>@string/notification_action_play_pause_buffering_value</item>
|
||||
<item>@string/notification_action_play_pause_value</item>
|
||||
<item>@string/notification_action_rewind_value</item>
|
||||
</string-array>
|
||||
<string-array name="notification_action_1_values_list" translatable="false">
|
||||
<item>@string/notification_action_play_pause_buffering_key</item>
|
||||
<item>@string/notification_action_play_pause_key</item>
|
||||
<item>@string/notification_action_rewind_key</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<string name="notification_action_2_key" translatable="false">notification_action_2_key</string>
|
||||
<string name="notification_action_2_value" translatable="false">@string/notification_action_smart_forward_next_key</string>
|
||||
<string-array name="notification_action_2_description_list" translatable="false">
|
||||
<item>@string/notification_action_smart_forward_next_value</item>
|
||||
<item>@string/notification_action_forward_value</item>
|
||||
<item>@string/notification_action_next_value</item>
|
||||
<item>@string/notification_action_play_pause_buffering_value</item>
|
||||
<item>@string/notification_action_play_pause_value</item>
|
||||
</string-array>
|
||||
<string-array name="notification_action_2_values_list" translatable="false">
|
||||
<item>@string/notification_action_smart_forward_next_key</item>
|
||||
<item>@string/notification_action_forward_key</item>
|
||||
<item>@string/notification_action_next_key</item>
|
||||
<item>@string/notification_action_play_pause_buffering_key</item>
|
||||
<item>@string/notification_action_play_pause_key</item>
|
||||
</string-array>
|
||||
|
||||
<string name="notification_action_3_key" translatable="false">notification_action_3_key</string>
|
||||
<string name="notification_action_3_value" translatable="false">@string/notification_action_repeat_key</string>
|
||||
<string-array name="notification_action_3_description_list" translatable="false">
|
||||
<item>@string/notification_action_repeat_value</item>
|
||||
<item>@string/notification_action_shuffle_value</item>
|
||||
<item>@string/notification_action_prev_value</item>
|
||||
<item>@string/notification_action_forward_value</item>
|
||||
<item>@string/notification_action_smart_forward_next_value</item>
|
||||
<item>@string/notification_action_rewind_value</item>
|
||||
<item>@string/notification_action_smart_rewind_prev_value</item>
|
||||
<item>@string/notification_action_close_value</item>
|
||||
<item>@string/notification_action_n_a_value</item>
|
||||
</string-array>
|
||||
<string-array name="notification_action_3_values_list" translatable="false">
|
||||
<item>@string/notification_action_repeat_key</item>
|
||||
<item>@string/notification_action_shuffle_key</item>
|
||||
<item>@string/notification_action_prev_key</item>
|
||||
<item>@string/notification_action_forward_key</item>
|
||||
<item>@string/notification_action_smart_forward_next_key</item>
|
||||
<item>@string/notification_action_rewind_key</item>
|
||||
<item>@string/notification_action_smart_rewind_prev_key</item>
|
||||
<item>@string/notification_action_close_key</item>
|
||||
<item>@string/notification_action_n_a_key</item>
|
||||
</string-array>
|
||||
|
||||
<string name="notification_action_4_key" translatable="false">notification_action_4_key</string>
|
||||
<string name="notification_action_4_value" translatable="false">@string/notification_action_close_key</string>
|
||||
<string-array name="notification_action_4_description_list" translatable="false">
|
||||
<item>@string/notification_action_close_value</item>
|
||||
<item>@string/notification_action_repeat_value</item>
|
||||
<item>@string/notification_action_shuffle_value</item>
|
||||
<item>@string/notification_action_next_value</item>
|
||||
<item>@string/notification_action_forward_value</item>
|
||||
<item>@string/notification_action_smart_forward_next_value</item>
|
||||
<item>@string/notification_action_n_a_value</item>
|
||||
</string-array>
|
||||
<string-array name="notification_action_4_values_list" translatable="false">
|
||||
<item>@string/notification_action_close_key</item>
|
||||
<item>@string/notification_action_repeat_key</item>
|
||||
<item>@string/notification_action_shuffle_key</item>
|
||||
<item>@string/notification_action_next_key</item>
|
||||
<item>@string/notification_action_forward_key</item>
|
||||
<item>@string/notification_action_smart_forward_next_key</item>
|
||||
<item>@string/notification_action_n_a_key</item>
|
||||
</string-array>
|
||||
<string name="notification_slot_compact_0_key" translatable="false">notification_slot_compact_0_key</string>
|
||||
<string name="notification_slot_compact_1_key" translatable="false">notification_slot_compact_1_key</string>
|
||||
<string name="notification_slot_compact_2_key" translatable="false">notification_slot_compact_2_key</string>
|
||||
|
||||
<string name="video_mp4_key" translatable="false">video_mp4</string>
|
||||
<string name="video_webm_key" translatable="false">video_webm</string>
|
||||
|
@ -66,21 +66,20 @@
|
||||
<string name="notification_action_2_title">Third action button</string>
|
||||
<string name="notification_action_3_title">Fourth action button</string>
|
||||
<string name="notification_action_4_title">Fifth action button</string>
|
||||
<string name="notification_compact_view_title">Notification compact view</string>
|
||||
<string name="notification_compact_view_summary">Notification slots to show in compact view</string>
|
||||
|
||||
<string name="notification_action_prev_value">Previous</string>
|
||||
<string name="notification_action_next_value">Next</string>
|
||||
<string name="notification_action_rewind_value">Rewind</string>
|
||||
<string name="notification_action_forward_value">Forward</string>
|
||||
<string name="notification_action_smart_rewind_prev_value">Rewind / Previous</string>
|
||||
<string name="notification_action_smart_forward_next_value">Forward / Next</string>
|
||||
<string name="notification_action_play_pause_buffering_value">Play / Pause / Buffering</string>
|
||||
<string name="notification_action_play_pause_value">Play / Pause</string>
|
||||
<string name="notification_action_repeat_value">Repeat</string>
|
||||
<string name="notification_action_shuffle_value">Shuffle</string>
|
||||
<string name="notification_action_close_value">Close</string>
|
||||
<string name="notification_action_n_a_value">Nothing</string>
|
||||
<string name="notification_actions_summary">Edit each notification action below by tapping on it.\nSelect up to three of them to be shown in the compact notification by using the checkboxes on the right.</string>
|
||||
<string name="notification_actions_at_most_three">You can select at most three actions to show in the compact notification!</string>
|
||||
|
||||
<string name="notification_action_previous">Previous</string>
|
||||
<string name="notification_action_next">Next</string>
|
||||
<string name="notification_action_rewind">Rewind</string>
|
||||
<string name="notification_action_forward">Forward</string>
|
||||
<string name="notification_action_smart_rewind_previous">Rewind / Previous</string>
|
||||
<string name="notification_action_smart_forward_next">Forward / Next</string>
|
||||
<string name="notification_action_play_pause_buffering">Play / Pause / Buffering</string>
|
||||
<string name="notification_action_play_pause">Play / Pause</string>
|
||||
<string name="notification_action_repeat">Repeat</string>
|
||||
<string name="notification_action_shuffle">Shuffle</string>
|
||||
<string name="notification_action_nothing">Nothing</string>
|
||||
|
||||
<string name="play_audio">Audio</string>
|
||||
<string name="default_audio_format_title">Default audio format</string>
|
||||
@ -154,7 +153,7 @@
|
||||
<string name="settings_category_other_title">Other</string>
|
||||
<string name="settings_category_debug_title">Debug</string>
|
||||
<string name="settings_category_updates_title">Updates</string>
|
||||
<string name="settings_category_notifications_title">Notifications</string>
|
||||
<string name="settings_category_notification_title">Notification</string>
|
||||
<string name="background_player_playing_toast">Playing in background</string>
|
||||
<string name="popup_playing_toast">Playing in popup mode</string>
|
||||
<string name="background_player_append">Queued on background player</string>
|
||||
|
@ -34,70 +34,4 @@
|
||||
android:title="@string/caption_setting_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:layout="@layout/settings_category_header_layout"
|
||||
android:title="@string/settings_category_notifications_title"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/scale_to_square_image_in_notifications_key"
|
||||
android:summary="@string/notification_scale_to_square_image_summary"
|
||||
android:title="@string/notification_scale_to_square_image_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="@string/notification_action_0_value"
|
||||
android:entries="@array/notification_action_0_description_list"
|
||||
android:entryValues="@array/notification_action_0_values_list"
|
||||
android:key="@string/notification_action_0_key"
|
||||
android:summary="%s"
|
||||
android:title="@string/notification_action_0_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="@string/notification_action_1_value"
|
||||
android:entries="@array/notification_action_1_description_list"
|
||||
android:entryValues="@array/notification_action_1_values_list"
|
||||
android:key="@string/notification_action_1_key"
|
||||
android:summary="%s"
|
||||
android:title="@string/notification_action_1_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="@string/notification_action_2_value"
|
||||
android:entries="@array/notification_action_2_description_list"
|
||||
android:entryValues="@array/notification_action_2_values_list"
|
||||
android:key="@string/notification_action_2_key"
|
||||
android:summary="%s"
|
||||
android:title="@string/notification_action_2_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="@string/notification_action_3_value"
|
||||
android:entries="@array/notification_action_3_description_list"
|
||||
android:entryValues="@array/notification_action_3_values_list"
|
||||
android:key="@string/notification_action_3_key"
|
||||
android:summary="%s"
|
||||
android:title="@string/notification_action_3_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="@string/notification_action_4_value"
|
||||
android:entries="@array/notification_action_4_description_list"
|
||||
android:entryValues="@array/notification_action_4_values_list"
|
||||
android:key="@string/notification_action_4_key"
|
||||
android:summary="%s"
|
||||
android:title="@string/notification_action_4_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="@string/settings_notifications_compact_view_default_value"
|
||||
android:key="@string/settings_notifications_compact_view_key"
|
||||
android:summary="@string/notification_compact_view_summary"
|
||||
android:title="@string/notification_compact_view_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@ -35,6 +35,12 @@
|
||||
android:icon="?attr/ic_language"
|
||||
android:title="@string/content"/>
|
||||
|
||||
<PreferenceScreen
|
||||
app:iconSpaceReserved="false"
|
||||
android:fragment="org.schabi.newpipe.settings.NotificationSettingsFragment"
|
||||
android:icon="?attr/ic_play_arrow"
|
||||
android:title="@string/settings_category_notification_title"/>
|
||||
|
||||
<PreferenceScreen
|
||||
app:iconSpaceReserved="false"
|
||||
android:fragment="org.schabi.newpipe.settings.UpdateSettingsFragment"
|
||||
|