Skip to content

Commit 7fa169a

Browse files
feat(YouTube - SponsorBlock): Add "Undo automatic skip toast" (#5277)
Co-authored-by: LisoUseInAIKyrios <[email protected]>
1 parent 94da329 commit 7fa169a

File tree

12 files changed

+592
-244
lines changed

12 files changed

+592
-244
lines changed

extensions/shared/library/src/main/java/app/revanced/extension/shared/Utils.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ public static float getResourceDimension(String resourceIdentifierName) throws R
311311
return getContext().getResources().getDimension(getResourceIdentifier(resourceIdentifierName, "dimen"));
312312
}
313313

314+
public static String[] getResourceStringArray(String resourceIdentifierName) throws Resources.NotFoundException {
315+
return getContext().getResources().getStringArray(getResourceIdentifier(resourceIdentifierName, "array"));
316+
}
317+
314318
public interface MatchFilter<T> {
315319
boolean matches(T object);
316320
}
@@ -579,7 +583,7 @@ private static void showToast(String messageToToast, int toastDuration) {
579583
Context currentContext = context;
580584

581585
if (currentContext == null) {
582-
Logger.printException(() -> "Cannot show toast (context is null): " + messageToToast, null);
586+
Logger.printException(() -> "Cannot show toast (context is null): " + messageToToast);
583587
} else {
584588
Logger.printDebug(() -> "Showing toast: " + messageToToast);
585589
Toast.makeText(currentContext, messageToToast, toastDuration).show();
@@ -809,7 +813,7 @@ public static Pair<Dialog, LinearLayout> createCustomDialog(
809813

810814
// Create content container (message/EditText) inside a ScrollView only if message or editText is provided.
811815
ScrollView contentScrollView = null;
812-
LinearLayout contentContainer = null;
816+
LinearLayout contentContainer;
813817
if (message != null || editText != null) {
814818
contentScrollView = new ScrollView(context);
815819
contentScrollView.setVerticalScrollBarEnabled(false); // Disable the vertical scrollbar.
@@ -833,7 +837,7 @@ public static Pair<Dialog, LinearLayout> createCustomDialog(
833837
contentScrollView.addView(contentContainer);
834838

835839
// Message (if not replaced by EditText).
836-
if (editText == null && message != null) {
840+
if (editText == null) {
837841
TextView messageView = new TextView(context);
838842
messageView.setText(message); // Supports Spanned (HTML).
839843
messageView.setTextSize(16);

extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/EnumSetting.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,20 @@ protected void writeToJSON(JSONObject json, String importExportKey) throws JSONE
7171
json.put(importExportKey, value.name().toLowerCase(Locale.ENGLISH));
7272
}
7373

74-
@NonNull
75-
private T getEnumFromString(String enumName) {
74+
/**
75+
* @param enumName Enum name. Casing does not matter.
76+
* @return Enum of this type with the same declared name.
77+
* @throws IllegalArgumentException if the name is not a valid enum of this type.
78+
*/
79+
protected T getEnumFromString(String enumName) {
7680
//noinspection ConstantConditions
7781
for (Enum<?> value : defaultValue.getClass().getEnumConstants()) {
7882
if (value.name().equalsIgnoreCase(enumName)) {
79-
// noinspection unchecked
83+
//noinspection unchecked
8084
return (T) value;
8185
}
8286
}
87+
8388
throw new IllegalArgumentException("Unknown enum value: " + enumName);
8489
}
8590

@@ -103,7 +108,9 @@ public T get() {
103108
* Availability based on if this setting is currently set to any of the provided types.
104109
*/
105110
@SafeVarargs
106-
public final Setting.Availability availability(@NonNull T... types) {
111+
public final Setting.Availability availability(T... types) {
112+
Objects.requireNonNull(types);
113+
107114
return () -> {
108115
T currentEnumType = get();
109116
for (T enumType : types) {

extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/Setting.java

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,14 @@ public interface Availability {
2828
/**
2929
* Availability based on a single parent setting being enabled.
3030
*/
31-
@NonNull
32-
public static Availability parent(@NonNull BooleanSetting parent) {
31+
public static Availability parent(BooleanSetting parent) {
3332
return parent::get;
3433
}
3534

3635
/**
3736
* Availability based on all parents being enabled.
3837
*/
39-
@NonNull
40-
public static Availability parentsAll(@NonNull BooleanSetting... parents) {
38+
public static Availability parentsAll(BooleanSetting... parents) {
4139
return () -> {
4240
for (BooleanSetting parent : parents) {
4341
if (!parent.get()) return false;
@@ -49,8 +47,7 @@ public static Availability parentsAll(@NonNull BooleanSetting... parents) {
4947
/**
5048
* Availability based on any parent being enabled.
5149
*/
52-
@NonNull
53-
public static Availability parentsAny(@NonNull BooleanSetting... parents) {
50+
public static Availability parentsAny(BooleanSetting... parents) {
5451
return () -> {
5552
for (BooleanSetting parent : parents) {
5653
if (parent.get()) return true;
@@ -79,7 +76,7 @@ public interface ImportExportCallback {
7976
/**
8077
* Adds a callback for {@link #importFromJSON(Context, String)} and {@link #exportToJson(Context)}.
8178
*/
82-
public static void addImportExportCallback(@NonNull ImportExportCallback callback) {
79+
public static void addImportExportCallback(ImportExportCallback callback) {
8380
importExportCallbacks.add(Objects.requireNonNull(callback));
8481
}
8582

@@ -100,22 +97,20 @@ public static void addImportExportCallback(@NonNull ImportExportCallback callbac
10097
public static final SharedPrefCategory preferences = new SharedPrefCategory("revanced_prefs");
10198

10299
@Nullable
103-
public static Setting<?> getSettingFromPath(@NonNull String str) {
100+
public static Setting<?> getSettingFromPath(String str) {
104101
return PATH_TO_SETTINGS.get(str);
105102
}
106103

107104
/**
108105
* @return All settings that have been created.
109106
*/
110-
@NonNull
111107
public static List<Setting<?>> allLoadedSettings() {
112108
return Collections.unmodifiableList(SETTINGS);
113109
}
114110

115111
/**
116112
* @return All settings that have been created, sorted by keys.
117113
*/
118-
@NonNull
119114
private static List<Setting<?>> allLoadedSettingsSorted() {
120115
Collections.sort(SETTINGS, (Setting<?> o1, Setting<?> o2) -> o1.key.compareTo(o2.key));
121116
return allLoadedSettings();
@@ -124,13 +119,11 @@ private static List<Setting<?>> allLoadedSettingsSorted() {
124119
/**
125120
* The key used to store the value in the shared preferences.
126121
*/
127-
@NonNull
128122
public final String key;
129123

130124
/**
131125
* The default value of the setting.
132126
*/
133-
@NonNull
134127
public final T defaultValue;
135128

136129
/**
@@ -161,7 +154,6 @@ private static List<Setting<?>> allLoadedSettingsSorted() {
161154
/**
162155
* The value of the setting.
163156
*/
164-
@NonNull
165157
protected volatile T value;
166158

167159
public Setting(String key, T defaultValue) {
@@ -199,8 +191,8 @@ public Setting(String key, T defaultValue, boolean rebootApp, String userDialogM
199191
* @param userDialogMessage Confirmation message to display, if the user tries to change the setting from the default value.
200192
* @param availability Condition that must be true, for this setting to be available to configure.
201193
*/
202-
public Setting(@NonNull String key,
203-
@NonNull T defaultValue,
194+
public Setting(String key,
195+
T defaultValue,
204196
boolean rebootApp,
205197
boolean includeWithImportExport,
206198
@Nullable String userDialogMessage,
@@ -227,7 +219,7 @@ public Setting(@NonNull String key,
227219
/**
228220
* Migrate a setting value if the path is renamed but otherwise the old and new settings are identical.
229221
*/
230-
public static <T> void migrateOldSettingToNew(@NonNull Setting<T> oldSetting, @NonNull Setting<T> newSetting) {
222+
public static <T> void migrateOldSettingToNew(Setting<T> oldSetting, Setting<T> newSetting) {
231223
if (oldSetting == newSetting) throw new IllegalArgumentException();
232224

233225
if (!oldSetting.isSetToDefault()) {
@@ -243,7 +235,7 @@ public static <T> void migrateOldSettingToNew(@NonNull Setting<T> oldSetting, @N
243235
* This method will be deleted in the future.
244236
*/
245237
@SuppressWarnings("rawtypes")
246-
public static void migrateFromOldPreferences(@NonNull SharedPrefCategory oldPrefs, @NonNull Setting setting, String settingKey) {
238+
public static void migrateFromOldPreferences(SharedPrefCategory oldPrefs, Setting setting, String settingKey) {
247239
if (!oldPrefs.preferences.contains(settingKey)) {
248240
return; // Nothing to do.
249241
}
@@ -285,7 +277,7 @@ public static void migrateFromOldPreferences(@NonNull SharedPrefCategory oldPref
285277
* This intentionally is a static method to deter
286278
* accidental usage when {@link #save(Object)} was intended.
287279
*/
288-
public static void privateSetValueFromString(@NonNull Setting<?> setting, @NonNull String newValue) {
280+
public static void privateSetValueFromString(Setting<?> setting, String newValue) {
289281
setting.setValueFromString(newValue);
290282

291283
// Clear the preference value since default is used, to allow changing
@@ -299,7 +291,7 @@ public static void privateSetValueFromString(@NonNull Setting<?> setting, @NonNu
299291
/**
300292
* Sets the value of {@link #value}, but do not save to {@link #preferences}.
301293
*/
302-
protected abstract void setValueFromString(@NonNull String newValue);
294+
protected abstract void setValueFromString(String newValue);
303295

304296
/**
305297
* Load and set the value of {@link #value}.
@@ -309,7 +301,7 @@ public static void privateSetValueFromString(@NonNull Setting<?> setting, @NonNu
309301
/**
310302
* Persistently saves the value.
311303
*/
312-
public final void save(@NonNull T newValue) {
304+
public final void save(T newValue) {
313305
if (value.equals(newValue)) {
314306
return;
315307
}
@@ -406,7 +398,6 @@ protected void writeToJSON(JSONObject json, String importExportKey) throws JSONE
406398
json.put(importExportKey, value);
407399
}
408400

409-
@NonNull
410401
public static String exportToJson(@Nullable Context alertDialogContext) {
411402
try {
412403
JSONObject json = new JSONObject();
@@ -445,7 +436,7 @@ public static String exportToJson(@Nullable Context alertDialogContext) {
445436
/**
446437
* @return if any settings that require a reboot were changed.
447438
*/
448-
public static boolean importFromJSON(@NonNull Context alertDialogContext, @NonNull String settingsJsonString) {
439+
public static boolean importFromJSON(Context alertDialogContext, String settingsJsonString) {
449440
try {
450441
if (!settingsJsonString.matches("[\\s\\S]*\\{")) {
451442
settingsJsonString = '{' + settingsJsonString + '}'; // Restore outer JSON braces

extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static app.revanced.extension.shared.settings.Setting.Availability;
66
import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew;
77
import static app.revanced.extension.shared.settings.Setting.parent;
8+
import static app.revanced.extension.shared.settings.Setting.parentsAll;
89
import static app.revanced.extension.shared.settings.Setting.parentsAny;
910
import static app.revanced.extension.youtube.patches.ChangeFormFactorPatch.FormFactor;
1011
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.ChangeStartPageTypeAvailability;
@@ -22,6 +23,7 @@
2223
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
2324
import static app.revanced.extension.youtube.patches.components.PlayerFlyoutMenuItemsFilter.HideAudioFlyoutMenuAvailability;
2425
import static app.revanced.extension.youtube.patches.theme.ThemePatch.SplashScreenAnimationStyle;
26+
import static app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController.SponsorBlockDuration;
2527
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE;
2628
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP;
2729
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY;
@@ -381,7 +383,11 @@ public class Settings extends BaseSettings {
381383
public static final BooleanSetting SB_SQUARE_LAYOUT = new BooleanSetting("sb_square_layout", FALSE, parent(SB_ENABLED));
382384
public static final BooleanSetting SB_COMPACT_SKIP_BUTTON = new BooleanSetting("sb_compact_skip_button", FALSE, parent(SB_ENABLED));
383385
public static final BooleanSetting SB_AUTO_HIDE_SKIP_BUTTON = new BooleanSetting("sb_auto_hide_skip_button", TRUE, parent(SB_ENABLED));
386+
public static final EnumSetting<SponsorBlockDuration> SB_AUTO_HIDE_SKIP_BUTTON_DURATION = new EnumSetting<>("sb_auto_hide_skip_button_duration",
387+
SponsorBlockDuration.FOUR_SECONDS, parent(SB_ENABLED));
384388
public static final BooleanSetting SB_TOAST_ON_SKIP = new BooleanSetting("sb_toast_on_skip", TRUE, parent(SB_ENABLED));
389+
public static final EnumSetting<SponsorBlockDuration> SB_TOAST_ON_SKIP_DURATION = new EnumSetting<>("sb_toast_on_skip_duration",
390+
SponsorBlockDuration.FOUR_SECONDS, parentsAll(SB_ENABLED, SB_TOAST_ON_SKIP));
385391
public static final BooleanSetting SB_TOAST_ON_CONNECTION_ERROR = new BooleanSetting("sb_toast_on_connection_error", TRUE, parent(SB_ENABLED));
386392
public static final BooleanSetting SB_TRACK_SKIP_COUNT = new BooleanSetting("sb_track_skip_count", TRUE, parent(SB_ENABLED));
387393
public static final FloatSetting SB_SEGMENT_MIN_DURATION = new FloatSetting("sb_min_segment_duration", 0F, parent(SB_ENABLED));

0 commit comments

Comments
 (0)