mirror of
https://github.com/revanced/revanced-integrations
synced 2024-11-27 11:13:38 +01:00
feat(YouTube): Reorganize settings menu (#571)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
db7e24994b
commit
eea4a48cd5
@ -12,6 +12,7 @@ import android.os.Handler;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceGroup;
|
import android.preference.PreferenceGroup;
|
||||||
|
import android.preference.PreferenceScreen;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
@ -26,10 +27,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.text.Bidi;
|
import java.text.Bidi;
|
||||||
import java.util.Locale;
|
import java.util.*;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.SortedMap;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.SynchronousQueue;
|
import java.util.concurrent.SynchronousQueue;
|
||||||
@ -102,7 +100,6 @@ public class Utils {
|
|||||||
view.setVisibility(View.GONE);
|
view.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General purpose pool for network calls and other background tasks.
|
* General purpose pool for network calls and other background tasks.
|
||||||
* All tasks run at max thread priority.
|
* All tasks run at max thread priority.
|
||||||
@ -205,7 +202,9 @@ public class Utils {
|
|||||||
public static <T extends View> T getChildView(@NonNull ViewGroup viewGroup, @NonNull MatchFilter filter) {
|
public static <T extends View> T getChildView(@NonNull ViewGroup viewGroup, @NonNull MatchFilter filter) {
|
||||||
for (int i = 0, childCount = viewGroup.getChildCount(); i < childCount; i++) {
|
for (int i = 0, childCount = viewGroup.getChildCount(); i < childCount; i++) {
|
||||||
View childAt = viewGroup.getChildAt(i);
|
View childAt = viewGroup.getChildAt(i);
|
||||||
|
//noinspection unchecked
|
||||||
if (filter.matches(childAt)) {
|
if (filter.matches(childAt)) {
|
||||||
|
//noinspection unchecked
|
||||||
return (T) childAt;
|
return (T) childAt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,6 +344,12 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum NetworkType {
|
||||||
|
NONE,
|
||||||
|
MOBILE,
|
||||||
|
OTHER,
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isNetworkConnected() {
|
public static boolean isNetworkConnected() {
|
||||||
NetworkType networkType = getNetworkType();
|
NetworkType networkType = getNetworkType();
|
||||||
return networkType == NetworkType.MOBILE
|
return networkType == NetworkType.MOBILE
|
||||||
@ -393,48 +398,104 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link PreferenceScreen} and {@link PreferenceGroup} sorting styles.
|
||||||
|
*/
|
||||||
|
private enum Sort {
|
||||||
|
/**
|
||||||
|
* Sort by the localized preference title.
|
||||||
|
*/
|
||||||
|
BY_TITLE("_sort_by_title"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by the preference keys.
|
||||||
|
*/
|
||||||
|
BY_KEY("_sort_by_key"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unspecified sorting.
|
||||||
|
*/
|
||||||
|
UNSORTED("_sort_by_unsorted");
|
||||||
|
|
||||||
|
final String keySuffix;
|
||||||
|
|
||||||
|
Sort(String keySuffix) {
|
||||||
|
this.keySuffix = keySuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defaults to {@link #UNSORTED} if key is null or has no sort suffix.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
static Sort fromKey(@Nullable String key) {
|
||||||
|
if (key != null) {
|
||||||
|
for (Sort sort : values()) {
|
||||||
|
if (key.endsWith(sort.keySuffix)) {
|
||||||
|
return sort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UNSORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final Regex punctuationRegex = new Regex("\\p{P}+");
|
private static final Regex punctuationRegex = new Regex("\\p{P}+");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort the preferences by title and ignore the casing.
|
* Strips all punctuation and converts to lower case. A null parameter returns an empty string.
|
||||||
*
|
|
||||||
* Android Preferences are automatically sorted by title,
|
|
||||||
* but if using a localized string key it sorts on the key and not the actual title text that's used at runtime.
|
|
||||||
*
|
|
||||||
* @param menuDepthToSort Maximum menu depth to sort. Menus deeper than this value
|
|
||||||
* will show preferences in the order created in patches.
|
|
||||||
*/
|
*/
|
||||||
public static void sortPreferenceGroupByTitle(PreferenceGroup group, int menuDepthToSort) {
|
public static String removePunctuationConvertToLowercase(@Nullable CharSequence original) {
|
||||||
if (menuDepthToSort == 0) return;
|
if (original == null) return "";
|
||||||
|
|
||||||
SortedMap<String, Preference> preferences = new TreeMap<>();
|
|
||||||
for (int i = 0, prefCount = group.getPreferenceCount(); i < prefCount; i++) {
|
|
||||||
Preference preference = group.getPreference(i);
|
|
||||||
if (preference instanceof PreferenceGroup) {
|
|
||||||
sortPreferenceGroupByTitle((PreferenceGroup) preference, menuDepthToSort - 1);
|
|
||||||
}
|
|
||||||
preferences.put(removePunctuationConvertToLowercase(preference.getTitle()), preference);
|
|
||||||
}
|
|
||||||
|
|
||||||
int prefIndex = 0;
|
|
||||||
for (Preference pref : preferences.values()) {
|
|
||||||
int indexToSet = prefIndex++;
|
|
||||||
if (pref instanceof PreferenceGroup || pref.getIntent() != null) {
|
|
||||||
// Place preference groups last.
|
|
||||||
// Use an offset to push the group to the end.
|
|
||||||
indexToSet += 1000;
|
|
||||||
}
|
|
||||||
pref.setOrder(indexToSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String removePunctuationConvertToLowercase(CharSequence original) {
|
|
||||||
return punctuationRegex.replace(original, "").toLowerCase();
|
return punctuationRegex.replace(original, "").toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum NetworkType {
|
/**
|
||||||
NONE,
|
* Sort a PreferenceGroup and all it's sub groups by title or key.
|
||||||
MOBILE,
|
*
|
||||||
OTHER,
|
* Sort order is determined by the preferences key {@link Sort} suffix.
|
||||||
|
*
|
||||||
|
* If a preference has no key or no {@link Sort} suffix,
|
||||||
|
* then the preferences are left unsorted.
|
||||||
|
*/
|
||||||
|
public static void sortPreferenceGroups(@NonNull PreferenceGroup group) {
|
||||||
|
Sort sort = Sort.fromKey(group.getKey());
|
||||||
|
SortedMap<String, Preference> preferences = new TreeMap<>();
|
||||||
|
|
||||||
|
for (int i = 0, prefCount = group.getPreferenceCount(); i < prefCount; i++) {
|
||||||
|
Preference preference = group.getPreference(i);
|
||||||
|
|
||||||
|
if (preference instanceof PreferenceGroup) {
|
||||||
|
sortPreferenceGroups((PreferenceGroup) preference);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String sortValue;
|
||||||
|
switch (sort) {
|
||||||
|
case BY_TITLE:
|
||||||
|
sortValue = removePunctuationConvertToLowercase(preference.getTitle());
|
||||||
|
break;
|
||||||
|
case BY_KEY:
|
||||||
|
sortValue = preference.getKey();
|
||||||
|
break;
|
||||||
|
case UNSORTED:
|
||||||
|
continue; // Keep original sorting.
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
preferences.put(sortValue, preference);
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (Preference pref : preferences.values()) {
|
||||||
|
int order = index++;
|
||||||
|
|
||||||
|
// If the preference is a PreferenceScreen or is an intent preference, move to the top.
|
||||||
|
if (pref instanceof PreferenceScreen || pref.getIntent() != null) {
|
||||||
|
// Arbitrary high number.
|
||||||
|
order -= 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
pref.setOrder(order);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
|
|
||||||
if (identifier == 0) return;
|
if (identifier == 0) return;
|
||||||
addPreferencesFromResource(identifier);
|
addPreferencesFromResource(identifier);
|
||||||
Utils.sortPreferenceGroupByTitle(getPreferenceScreen(), 2);
|
Utils.sortPreferenceGroups(getPreferenceScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showSettingUserDialogConfirmation(SwitchPreference switchPref, BooleanSetting setting) {
|
private void showSettingUserDialogConfirmation(SwitchPreference switchPref, BooleanSetting setting) {
|
||||||
|
@ -49,10 +49,6 @@ final class ButtonsFilter extends Filter {
|
|||||||
);
|
);
|
||||||
|
|
||||||
bufferButtonsGroupList.addAll(
|
bufferButtonsGroupList.addAll(
|
||||||
new ByteArrayFilterGroup(
|
|
||||||
Settings.HIDE_LIVE_CHAT_BUTTON,
|
|
||||||
"yt_outline_message_bubble_overlap"
|
|
||||||
),
|
|
||||||
new ByteArrayFilterGroup(
|
new ByteArrayFilterGroup(
|
||||||
Settings.HIDE_REPORT_BUTTON,
|
Settings.HIDE_REPORT_BUTTON,
|
||||||
"yt_outline_flag"
|
"yt_outline_flag"
|
||||||
|
@ -15,15 +15,14 @@ import java.util.Arrays;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import app.revanced.integrations.shared.Logger;
|
import app.revanced.integrations.shared.settings.BaseSettings;
|
||||||
import app.revanced.integrations.shared.settings.BooleanSetting;
|
import app.revanced.integrations.shared.settings.BooleanSetting;
|
||||||
import app.revanced.integrations.shared.settings.FloatSetting;
|
import app.revanced.integrations.shared.settings.FloatSetting;
|
||||||
import app.revanced.integrations.shared.settings.IntegerSetting;
|
import app.revanced.integrations.shared.settings.IntegerSetting;
|
||||||
import app.revanced.integrations.shared.settings.LongSetting;
|
import app.revanced.integrations.shared.settings.LongSetting;
|
||||||
import app.revanced.integrations.shared.settings.Setting;
|
import app.revanced.integrations.shared.settings.Setting;
|
||||||
import app.revanced.integrations.shared.settings.preference.SharedPrefCategory;
|
|
||||||
import app.revanced.integrations.shared.settings.BaseSettings;
|
|
||||||
import app.revanced.integrations.shared.settings.StringSetting;
|
import app.revanced.integrations.shared.settings.StringSetting;
|
||||||
|
import app.revanced.integrations.shared.settings.preference.SharedPrefCategory;
|
||||||
import app.revanced.integrations.youtube.sponsorblock.SponsorBlockSettings;
|
import app.revanced.integrations.youtube.sponsorblock.SponsorBlockSettings;
|
||||||
|
|
||||||
public class Settings extends BaseSettings {
|
public class Settings extends BaseSettings {
|
||||||
@ -167,7 +166,6 @@ public class Settings extends BaseSettings {
|
|||||||
|
|
||||||
// Action buttons
|
// Action buttons
|
||||||
public static final BooleanSetting HIDE_LIKE_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_like_dislike_button", FALSE);
|
public static final BooleanSetting HIDE_LIKE_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_like_dislike_button", FALSE);
|
||||||
public static final BooleanSetting HIDE_LIVE_CHAT_BUTTON = new BooleanSetting("revanced_hide_live_chat_button", FALSE);
|
|
||||||
public static final BooleanSetting HIDE_SHARE_BUTTON = new BooleanSetting("revanced_hide_share_button", FALSE);
|
public static final BooleanSetting HIDE_SHARE_BUTTON = new BooleanSetting("revanced_hide_share_button", FALSE);
|
||||||
public static final BooleanSetting HIDE_REPORT_BUTTON = new BooleanSetting("revanced_hide_report_button", FALSE);
|
public static final BooleanSetting HIDE_REPORT_BUTTON = new BooleanSetting("revanced_hide_report_button", FALSE);
|
||||||
public static final BooleanSetting HIDE_REMIX_BUTTON = new BooleanSetting("revanced_hide_remix_button", TRUE);
|
public static final BooleanSetting HIDE_REMIX_BUTTON = new BooleanSetting("revanced_hide_remix_button", TRUE);
|
||||||
|
@ -150,7 +150,7 @@ public class ReturnYouTubeDislikePreferenceFragment extends PreferenceFragment {
|
|||||||
pref.getContext().startActivity(i);
|
pref.getContext().startActivity(i);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
preferenceScreen.addPreference(aboutWebsitePreference);
|
aboutCategory.addPreference(aboutWebsitePreference);
|
||||||
|
|
||||||
// RYD API connection statistics
|
// RYD API connection statistics
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user