fix(YouTube - Settings): Add native language names for each language in the language settings menu

This commit is contained in:
inotia00 2025-03-24 21:04:30 +09:00
parent b99ec2cd8d
commit aebeb8b9d3
3 changed files with 243 additions and 97 deletions

View File

@ -22,16 +22,16 @@ import android.widget.ListView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Objects;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.BooleanSetting;
import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.utils.Logger;
import app.revanced.extension.shared.utils.StringRef;
import app.revanced.extension.shared.utils.Utils;
@SuppressWarnings({"unused", "deprecation"})
public abstract class AbstractPreferenceFragment extends PreferenceFragment {
/**
* Indicates that if a preference changes,
* to apply the change from the Setting to the UI component.
@ -39,7 +39,11 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
public static boolean settingImportInProgress;
/**
* Confirm and restart dialog button text and title.
* Prevents recursive calls during preference <-> UI syncing from showing extra dialogs.
*/
private static boolean updatingPreference;
/**
* Set by subclasses if Strings cannot be added as a resource.
*/
@Nullable
@ -52,7 +56,14 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
try {
Setting<?> setting = Setting.getSettingFromPath(Objects.requireNonNull(str));
if (updatingPreference) {
Logger.printDebug(() -> "Ignoring preference change as sync is in progress");
return;
}
if (str == null) {
return;
}
Setting<?> setting = Setting.getSettingFromPath(str);
if (setting == null) {
return;
}
@ -73,10 +84,13 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
}
}
updatingPreference = true;
// Apply 'Setting <- Preference', unless during importing when it needs to be 'Setting -> Preference'.
// Updating here can can cause a recursive call back into this same method.
updatePreference(pref, setting, true, settingImportInProgress);
// Update any other preference availability that may now be different.
updateUIAvailability();
updatingPreference = false;
} catch (Exception ex) {
Logger.printException(() -> "OnSharedPreferenceChangeListener failure", ex);
}
@ -103,29 +117,32 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
Utils.verifyOnMainThread();
final var context = getActivity();
showingUserDialogMessage = true;
assert setting.userDialogMessage != null;
new AlertDialog.Builder(context)
.setTitle(android.R.string.dialog_alert_title)
.setMessage(setting.userDialogMessage.toString())
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
// User confirmed, save to the Setting.
updatePreference(pref, setting, true, false);
final StringRef userDialogMessage = setting.userDialogMessage;
if (context != null && userDialogMessage != null) {
showingUserDialogMessage = true;
// Update availability of other preferences that may be changed.
updateUIAvailability();
new AlertDialog.Builder(context)
.setTitle(android.R.string.dialog_alert_title)
.setMessage(userDialogMessage.toString())
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
// User confirmed, save to the Setting.
updatePreference(pref, setting, true, false);
if (setting.rebootApp) {
showRestartDialog(context);
}
})
.setNegativeButton(android.R.string.cancel, (dialog, id) -> {
// Restore whatever the setting was before the change.
updatePreference(pref, setting, true, true);
})
.setOnDismissListener(dialog -> showingUserDialogMessage = false)
.setCancelable(false)
.show();
// Update availability of other preferences that may be changed.
updateUIAvailability();
if (setting.rebootApp) {
showRestartDialog(context);
}
})
.setNegativeButton(android.R.string.cancel, (dialog, id) -> {
// Restore whatever the setting was before the change.
updatePreference(pref, setting, true, true);
})
.setOnDismissListener(dialog -> showingUserDialogMessage = false)
.setCancelable(false)
.show();
}
}
/**
@ -146,14 +163,16 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
* @return If the preference is currently set to the default value of the Setting.
*/
protected boolean prefIsSetToDefault(Preference pref, Setting<?> setting) {
Object defaultValue = setting.defaultValue;
if (pref instanceof SwitchPreference switchPref) {
return switchPref.isChecked() == (Boolean) setting.defaultValue;
return switchPref.isChecked() == (Boolean) defaultValue;
}
String defaultValueString = defaultValue.toString();
if (pref instanceof EditTextPreference editPreference) {
return editPreference.getText().equals(setting.defaultValue.toString());
return editPreference.getText().equals(defaultValueString);
}
if (pref instanceof ListPreference listPref) {
return listPref.getValue().equals(setting.defaultValue.toString());
return listPref.getValue().equals(defaultValueString);
}
throw new IllegalStateException("Must override method to handle "
@ -258,18 +277,19 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
listPreference.setSummary(objectStringValue);
}
public static void showRestartDialog(@NonNull final Context context) {
public static void showRestartDialog(@NonNull Context context) {
if (restartDialogMessage == null) {
restartDialogMessage = str("revanced_extended_restart_message");
}
showRestartDialog(context, restartDialogMessage);
}
public static void showRestartDialog(@NonNull final Context context, String message) {
public static void showRestartDialog(@NonNull Context context, String message) {
showRestartDialog(context, message, 0);
}
public static void showRestartDialog(@NonNull final Context context, String message, long delay) {
public static void showRestartDialog(@NonNull Context context, String message, long delay) {
Utils.verifyOnMainThread();
new AlertDialog.Builder(context)

View File

@ -31,6 +31,7 @@ import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
import android.util.Pair;
import android.util.TypedValue;
import android.view.ViewGroup;
import android.view.WindowInsets;
@ -55,12 +56,15 @@ import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.BooleanSetting;
import app.revanced.extension.shared.settings.EnumSetting;
import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.utils.Logger;
import app.revanced.extension.shared.utils.ResourceUtils;
import app.revanced.extension.shared.utils.Utils;
import app.revanced.extension.youtube.patches.video.CustomPlaybackSpeedPatch;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.utils.ExtendedUtils;
import app.revanced.extension.youtube.utils.ThemeUtils;
@ -74,14 +78,19 @@ public class ReVancedPreferenceFragment extends PreferenceFragment {
@SuppressLint("SuspiciousIndentation")
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
try {
if (str == null) return;
Setting<?> setting = Setting.getSettingFromPath(Objects.requireNonNull(str));
if (str == null) {
return;
}
if (setting == null) return;
Setting<?> setting = Setting.getSettingFromPath(str);
if (setting == null) {
return;
}
Preference mPreference = findPreference(str);
if (mPreference == null) return;
if (mPreference == null) {
return;
}
if (mPreference instanceof SwitchPreference switchPreference) {
BooleanSetting boolSetting = (BooleanSetting) setting;
@ -122,17 +131,13 @@ public class ReVancedPreferenceFragment extends PreferenceFragment {
ReVancedSettingsPreference.initializeReVancedSettings();
if (settingImportInProgress) {
return;
}
if (!showingUserDialogMessage) {
if (!settingImportInProgress && !showingUserDialogMessage) {
final Context context = getActivity();
if (setting.userDialogMessage != null
&& mPreference instanceof SwitchPreference switchPreference
&& setting.defaultValue instanceof Boolean defaultValue
&& switchPreference.isChecked() != defaultValue) {
if (setting.userDialogMessage != null &&
mPreference instanceof SwitchPreference switchPreference &&
setting.defaultValue instanceof Boolean defaultValue &&
switchPreference.isChecked() != defaultValue) {
showSettingUserDialogConfirmation(context, switchPreference, (BooleanSetting) setting);
} else if (setting.rebootApp) {
showRestartDialog(context);
@ -314,6 +319,10 @@ public class ReVancedPreferenceFragment extends PreferenceFragment {
originalPreferenceScreen = getPreferenceManager().createPreferenceScreen(getActivity());
copyPreferences(getPreferenceScreen(), originalPreferenceScreen);
sortPreferenceListMenu(Settings.CHANGE_START_PAGE);
sortPreferenceListMenu(Settings.SPOOF_STREAMING_DATA_LANGUAGE);
sortPreferenceListMenu(BaseSettings.REVANCED_LANGUAGE);
} catch (Exception th) {
Logger.printException(() -> "Error during onCreate()", th);
}
@ -331,6 +340,65 @@ public class ReVancedPreferenceFragment extends PreferenceFragment {
super.onDestroy();
}
/**
* Sorts a preference list by menu entries, but preserves the first value as the first entry.
*
* @noinspection SameParameterValue
*/
private static void sortListPreferenceByValues(ListPreference listPreference, int firstEntriesToPreserve) {
CharSequence[] entries = listPreference.getEntries();
CharSequence[] entryValues = listPreference.getEntryValues();
final int entrySize = entries.length;
if (entrySize != entryValues.length) {
// Xml array declaration has a missing/extra entry.
throw new IllegalStateException();
}
// Since the text of Preference is Spanned, CharSequence#toString() should not be used.
// If CharSequence#toString() is used, Spanned styling, such as HTML syntax, will be broken.
List<Pair<CharSequence, CharSequence>> firstPairs = new ArrayList<>(firstEntriesToPreserve);
List<Pair<CharSequence, CharSequence>> pairsToSort = new ArrayList<>(entrySize);
for (int i = 0; i < entrySize; i++) {
Pair<CharSequence, CharSequence> pair = new Pair<>(entries[i], entryValues[i]);
if (i < firstEntriesToPreserve) {
firstPairs.add(pair);
} else {
pairsToSort.add(pair);
}
}
pairsToSort.sort((pair1, pair2)
-> pair1.first.toString().compareToIgnoreCase(pair2.first.toString()));
CharSequence[] sortedEntries = new CharSequence[entrySize];
CharSequence[] sortedEntryValues = new CharSequence[entrySize];
int i = 0;
for (Pair<CharSequence, CharSequence> pair : firstPairs) {
sortedEntries[i] = pair.first;
sortedEntryValues[i] = pair.second;
i++;
}
for (Pair<CharSequence, CharSequence> pair : pairsToSort) {
sortedEntries[i] = pair.first;
sortedEntryValues[i] = pair.second;
i++;
}
listPreference.setEntries(sortedEntries);
listPreference.setEntryValues(sortedEntryValues);
}
private void sortPreferenceListMenu(EnumSetting<?> setting) {
Preference preference = findPreference(setting.key);
if (preference instanceof ListPreference languagePreference) {
sortListPreferenceByValues(languagePreference, 1);
}
}
/**
* Recursively stores all preferences and their dependencies grouped by their parent PreferenceGroup.
*

View File

@ -24,58 +24,116 @@ Please download %2$s from the website."</string>
<string name="revanced_external_downloader_not_installed_warning">%s is not installed. Please install it.</string>
<string name="revanced_language_title">RVX language</string>
<string name="revanced_language_DEFAULT">App language</string>
<string name="revanced_language_AR">Arabic</string>
<string name="revanced_language_AZ">Azerbaijani</string>
<string name="revanced_language_BG">Bulgarian</string>
<string name="revanced_language_BN">Bengali</string>
<string name="revanced_language_CA">Catalan</string>
<string name="revanced_language_CS">Czech</string>
<string name="revanced_language_DA">Danish</string>
<string name="revanced_language_DE">German</string>
<string name="revanced_language_EL">Greek</string>
<string name="revanced_language_EN">English</string>
<string name="revanced_language_ES">Spanish</string>
<string name="revanced_language_ET">Estonian</string>
<string name="revanced_language_FA">Persian</string>
<string name="revanced_language_FI">Finnish</string>
<string name="revanced_language_FR">French</string>
<string name="revanced_language_GU">Gujarati</string>
<string name="revanced_language_HI">Hindi</string>
<string name="revanced_language_HR">Croatian</string>
<string name="revanced_language_HU">Hungarian</string>
<string name="revanced_language_ID">Indonesian</string>
<string name="revanced_language_IT">Italian</string>
<string name="revanced_language_JA">Japanese</string>
<string name="revanced_language_KK">Kazakh</string>
<string name="revanced_language_KO">Korean</string>
<string name="revanced_language_LT">Lithuanian</string>
<string name="revanced_language_LV">Latvian</string>
<string name="revanced_language_MK">Macedonian</string>
<string name="revanced_language_MN">Mongolian</string>
<string name="revanced_language_MR">Marathi</string>
<string name="revanced_language_MS">Malay</string>
<string name="revanced_language_MY">Burmese</string>
<string name="revanced_language_NL">Dutch</string>
<string name="revanced_language_OR">Odia</string>
<string name="revanced_language_PA">Punjabi</string>
<string name="revanced_language_PL">Polish</string>
<string name="revanced_language_PT">Portuguese</string>
<string name="revanced_language_RO">Romanian</string>
<string name="revanced_language_RU">Russian</string>
<string name="revanced_language_SK">Slovak</string>
<string name="revanced_language_SL">Slovene</string>
<string name="revanced_language_SR">Serbian</string>
<string name="revanced_language_SV">Swedish</string>
<string name="revanced_language_SW">Swahili</string>
<string name="revanced_language_TA">Tamil</string>
<string name="revanced_language_TE">Telugu</string>
<string name="revanced_language_TH">Thai</string>
<string name="revanced_language_TR">Turkish</string>
<string name="revanced_language_UK">Ukrainian</string>
<string name="revanced_language_UR">Urdu</string>
<string name="revanced_language_VI">Vietnamese</string>
<string name="revanced_language_ZH">Chinese</string>
<string name="revanced_language_AM">"Amharic
<small>አማርኛ</small>"</string>
<string name="revanced_language_AR">"Arabic
<small>العربية</small>"</string>
<string name="revanced_language_AZ">"Azerbaijani
<small>Azərbaycan</small>"</string>
<string name="revanced_language_BE">"Belarusian
<small>беларуская</small>"</string>
<string name="revanced_language_BG">"Bulgarian
<small>Български</small>"</string>
<string name="revanced_language_BN">"Bengali
<small>বাংলা</small>"</string>
<string name="revanced_language_CA">"Catalan
<small>Català</small>"</string>
<string name="revanced_language_CS">"Czech
<small>Čeština</small>"</string>
<string name="revanced_language_DA">"Danish
<small>Dansk</small>"</string>
<string name="revanced_language_DE">"German
<small>Deutsch</small>"</string>
<string name="revanced_language_EL">"Greek
<small>Ελληνικά</small>"</string>
<string name="revanced_language_EN">"English
<small>English</small>"</string>
<string name="revanced_language_ES">"Spanish
<small>Español</small>"</string>
<string name="revanced_language_ET">"Estonian
<small>Eesti</small>"</string>
<string name="revanced_language_FA">"Persian
<small>فارسی</small>"</string>
<string name="revanced_language_FI">"Finnish
<small>Suomi</small>"</string>
<string name="revanced_language_FR">"French
<small>Français</small>"</string>
<string name="revanced_language_GU">"Gujarati
<small>ગુજરાતી</small>"</string>
<string name="revanced_language_HE">"Hebrew
<small>עברי</small>"</string>
<string name="revanced_language_HI">"Hindi
<small>हिन्दी</small>"</string>
<string name="revanced_language_HR">"Croatian
<small>Hrvatski</small>"</string>
<string name="revanced_language_HU">"Hungarian
<small>Magyar</small>"</string>
<string name="revanced_language_ID">"Indonesian
<small>Indonesia</small>"</string>
<string name="revanced_language_IT">"Italian
<small>Italiano</small>"</string>
<string name="revanced_language_JA">"Japanese
<small>日本語</small>"</string>
<string name="revanced_language_KK">"Kazakh
<small>Қазақ тілі</small>"</string>
<string name="revanced_language_KO">"Korean
<small>한국어</small>"</string>
<string name="revanced_language_LT">"Lithuanian
<small>Lietuvių</small>"</string>
<string name="revanced_language_LV">"Latvian
<small>Latviešu</small>"</string>
<string name="revanced_language_MK">"Macedonian
<small>Македонски</small>"</string>
<string name="revanced_language_MN">"Mongolian
<small>Монгол</small>"</string>
<string name="revanced_language_MR">"Marathi
<small>मराठी</small>"</string>
<string name="revanced_language_MS">"Malay
<small>Melayu</small>"</string>
<string name="revanced_language_MY">"Burmese
<small>ဗမာ</small>"</string>
<string name="revanced_language_NL">"Dutch
<small>Nederlands</small>"</string>
<string name="revanced_language_OR">"Odia
<small>ଓଡ଼ିଆ</small>"</string>
<string name="revanced_language_PA">"Punjabi
<small>ਪੰਜਾਬੀ</small>"</string>
<string name="revanced_language_PL">"Polish
<small>Polski</small>"</string>
<string name="revanced_language_PT">"Portuguese
<small>Português</small>"</string>
<string name="revanced_language_RO">"Romanian
<small>Română</small>"</string>
<string name="revanced_language_RU">"Russian
<small>Русский</small>"</string>
<string name="revanced_language_SK">"Slovak
<small>Slovenčina</small>"</string>
<string name="revanced_language_SQ">"Albanian
<small>Shqip</small>"</string>
<string name="revanced_language_SL">"Slovene
<small>Slovenščina</small>"</string>
<string name="revanced_language_SR">"Serbian
<small>Српски</small>"</string>
<string name="revanced_language_SV">"Swedish
<small>Svenska</small>"</string>
<string name="revanced_language_SW">"Swahili
<small>Kiswahili</small>"</string>
<string name="revanced_language_TA">"Tamil
<small>தமிழ்</small>"</string>
<string name="revanced_language_TE">"Telugu
<small>తెలుగు</small>"</string>
<string name="revanced_language_TH">"Thai
<small>ไทย</small>"</string>
<string name="revanced_language_TR">"Turkish
<small>Türkçe</small>"</string>
<string name="revanced_language_UK">"Ukrainian
<small>Українська</small>"</string>
<string name="revanced_language_UR">"Urdu
<small>اردو</small>"</string>
<string name="revanced_language_VI">"Vietnamese
<small>Tiếng Việt</small>"</string>
<string name="revanced_language_ZH">"Chinese
<small>中文</small>"</string>
<!-- PreferenceScreen: Ads -->
<string name="revanced_preference_screen_ads_title">Ads</string>