Skip to content

Commit aab6580

Browse files
committed
Extract NotificationSlot from NotificationActionsPreference
1 parent 30f0db1 commit aab6580

2 files changed

Lines changed: 193 additions & 166 deletions

File tree

app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java

Lines changed: 21 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,22 @@
55
import android.content.Context;
66
import android.content.Intent;
77
import android.content.SharedPreferences;
8-
import android.content.res.ColorStateList;
98
import android.os.Build;
109
import android.util.AttributeSet;
11-
import android.view.LayoutInflater;
1210
import android.view.View;
13-
import android.view.ViewGroup;
1411
import android.widget.CheckBox;
15-
import android.widget.ImageView;
16-
import android.widget.RadioButton;
17-
import android.widget.RadioGroup;
1812
import android.widget.TextView;
1913
import android.widget.Toast;
2014

2115
import androidx.annotation.NonNull;
22-
import androidx.annotation.Nullable;
23-
import androidx.appcompat.app.AlertDialog;
24-
import androidx.appcompat.content.res.AppCompatResources;
25-
import androidx.core.widget.TextViewCompat;
2616
import androidx.preference.Preference;
2717
import androidx.preference.PreferenceViewHolder;
2818

2919
import org.schabi.newpipe.App;
3020
import org.schabi.newpipe.R;
31-
import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
32-
import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
3321
import org.schabi.newpipe.player.notification.NotificationConstants;
34-
import org.schabi.newpipe.util.DeviceUtils;
35-
import org.schabi.newpipe.util.ThemeHelper;
36-
import org.schabi.newpipe.views.FocusOverlayView;
3722

3823
import java.util.List;
39-
import java.util.Objects;
4024
import java.util.stream.IntStream;
4125

4226
public class NotificationActionsPreference extends Preference {
@@ -47,8 +31,9 @@ public NotificationActionsPreference(final Context context, final AttributeSet a
4731
}
4832

4933

50-
@Nullable private NotificationSlot[] notificationSlots = null;
51-
@Nullable private List<Integer> compactSlots = null;
34+
private NotificationSlot[] notificationSlots;
35+
private List<Integer> compactSlots;
36+
5237

5338
////////////////////////////////////////////////////////////////////////////
5439
// Lifecycle
@@ -85,10 +70,26 @@ private void setupActions(@NonNull final View view) {
8570
compactSlots = NotificationConstants.getCompactSlotsFromPreferences(getContext(),
8671
getSharedPreferences(), 5);
8772
notificationSlots = IntStream.range(0, 5)
88-
.mapToObj(i -> new NotificationSlot(i, view))
73+
.mapToObj(i -> new NotificationSlot(getContext(), getSharedPreferences(), i, view,
74+
compactSlots.contains(i), this::onToggleCompactSlot))
8975
.toArray(NotificationSlot[]::new);
9076
}
9177

78+
private void onToggleCompactSlot(final int i, final CheckBox checkBox) {
79+
if (checkBox.isChecked()) {
80+
compactSlots.remove((Integer) i);
81+
} else if (compactSlots.size() < 3) {
82+
compactSlots.add(i);
83+
} else {
84+
Toast.makeText(getContext(),
85+
R.string.notification_actions_at_most_three,
86+
Toast.LENGTH_SHORT).show();
87+
return;
88+
}
89+
90+
checkBox.toggle();
91+
}
92+
9293

9394
////////////////////////////////////////////////////////////////////////////
9495
// Saving
@@ -106,156 +107,10 @@ private void saveChanges() {
106107

107108
for (int i = 0; i < 5; i++) {
108109
editor.putInt(getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
109-
notificationSlots[i].selectedAction);
110+
notificationSlots[i].getSelectedAction());
110111
}
111112

112113
editor.apply();
113114
}
114115
}
115-
116-
117-
////////////////////////////////////////////////////////////////////////////
118-
// Notification action
119-
////////////////////////////////////////////////////////////////////////////
120-
121-
private static final int[] SLOT_ITEMS = {
122-
R.id.notificationAction0,
123-
R.id.notificationAction1,
124-
R.id.notificationAction2,
125-
R.id.notificationAction3,
126-
R.id.notificationAction4,
127-
};
128-
129-
private static final int[] SLOT_TITLES = {
130-
R.string.notification_action_0_title,
131-
R.string.notification_action_1_title,
132-
R.string.notification_action_2_title,
133-
R.string.notification_action_3_title,
134-
R.string.notification_action_4_title,
135-
};
136-
137-
private class NotificationSlot {
138-
139-
final int i;
140-
@NotificationConstants.Action int selectedAction;
141-
142-
ImageView icon;
143-
TextView summary;
144-
145-
NotificationSlot(final int actionIndex, final View parentView) {
146-
this.i = actionIndex;
147-
selectedAction = Objects.requireNonNull(getSharedPreferences()).getInt(
148-
getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
149-
NotificationConstants.SLOT_DEFAULTS[i]);
150-
final View view = parentView.findViewById(SLOT_ITEMS[i]);
151-
152-
// only show the last two notification slots on Android 13+
153-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || i >= 3) {
154-
setupSelectedAction(view);
155-
setupTitle(view);
156-
setupCheckbox(view);
157-
} else {
158-
view.setVisibility(View.GONE);
159-
}
160-
}
161-
162-
void setupTitle(final View view) {
163-
((TextView) view.findViewById(R.id.notificationActionTitle))
164-
.setText(SLOT_TITLES[i]);
165-
view.findViewById(R.id.notificationActionClickableArea).setOnClickListener(
166-
v -> openActionChooserDialog());
167-
}
168-
169-
void setupCheckbox(final View view) {
170-
final CheckBox compactSlotCheckBox = view.findViewById(R.id.notificationActionCheckBox);
171-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
172-
// there are no compact slots to customize on Android 33+
173-
compactSlotCheckBox.setVisibility(View.GONE);
174-
view.findViewById(R.id.notificationActionCheckBoxClickableArea)
175-
.setVisibility(View.GONE);
176-
return;
177-
}
178-
179-
compactSlotCheckBox.setChecked(compactSlots.contains(i));
180-
view.findViewById(R.id.notificationActionCheckBoxClickableArea).setOnClickListener(
181-
v -> {
182-
if (compactSlotCheckBox.isChecked()) {
183-
compactSlots.remove((Integer) i);
184-
} else if (compactSlots.size() < 3) {
185-
compactSlots.add(i);
186-
} else {
187-
Toast.makeText(getContext(),
188-
R.string.notification_actions_at_most_three,
189-
Toast.LENGTH_SHORT).show();
190-
return;
191-
}
192-
193-
compactSlotCheckBox.toggle();
194-
});
195-
}
196-
197-
void setupSelectedAction(final View view) {
198-
icon = view.findViewById(R.id.notificationActionIcon);
199-
summary = view.findViewById(R.id.notificationActionSummary);
200-
updateInfo();
201-
}
202-
203-
void updateInfo() {
204-
if (NotificationConstants.ACTION_ICONS[selectedAction] == 0) {
205-
icon.setImageDrawable(null);
206-
} else {
207-
icon.setImageDrawable(AppCompatResources.getDrawable(getContext(),
208-
NotificationConstants.ACTION_ICONS[selectedAction]));
209-
}
210-
211-
summary.setText(NotificationConstants.getActionName(getContext(), selectedAction));
212-
}
213-
214-
void openActionChooserDialog() {
215-
final LayoutInflater inflater = LayoutInflater.from(getContext());
216-
final SingleChoiceDialogViewBinding binding =
217-
SingleChoiceDialogViewBinding.inflate(inflater);
218-
219-
final AlertDialog alertDialog = new AlertDialog.Builder(getContext())
220-
.setTitle(SLOT_TITLES[i])
221-
.setView(binding.getRoot())
222-
.setCancelable(true)
223-
.create();
224-
225-
final View.OnClickListener radioButtonsClickListener = v -> {
226-
selectedAction = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][v.getId()];
227-
updateInfo();
228-
alertDialog.dismiss();
229-
};
230-
231-
for (int id = 0; id < NotificationConstants.SLOT_ALLOWED_ACTIONS[i].length; ++id) {
232-
final int action = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id];
233-
final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater)
234-
.getRoot();
235-
236-
// if present set action icon with correct color
237-
final int iconId = NotificationConstants.ACTION_ICONS[action];
238-
if (iconId != 0) {
239-
radioButton.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, iconId, 0);
240-
241-
final var color = ColorStateList.valueOf(ThemeHelper
242-
.resolveColorFromAttr(getContext(), android.R.attr.textColorPrimary));
243-
TextViewCompat.setCompoundDrawableTintList(radioButton, color);
244-
}
245-
246-
radioButton.setText(NotificationConstants.getActionName(getContext(), action));
247-
radioButton.setChecked(action == selectedAction);
248-
radioButton.setId(id);
249-
radioButton.setLayoutParams(new RadioGroup.LayoutParams(
250-
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
251-
radioButton.setOnClickListener(radioButtonsClickListener);
252-
binding.list.addView(radioButton);
253-
}
254-
alertDialog.show();
255-
256-
if (DeviceUtils.isTv(getContext())) {
257-
FocusOverlayView.setupFocusObserver(alertDialog);
258-
}
259-
}
260-
}
261116
}

0 commit comments

Comments
 (0)