Cleanup custom API key support

Also allow devs to purposely crash the app, because it's fun

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/27/head
androidacy-user 3 years ago
parent aad605cbd0
commit 8c6f75c7bf

@ -3,7 +3,6 @@ package com.fox2code.mmm.settings;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -27,6 +26,7 @@ import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreferenceCompat;
import androidx.preference.TwoStatePreference; import androidx.preference.TwoStatePreference;
import com.fox2code.foxcompat.FoxActivity; import com.fox2code.foxcompat.FoxActivity;
@ -52,6 +52,7 @@ import com.fox2code.rosettax.LanguageActivity;
import com.fox2code.rosettax.LanguageSwitcher; import com.fox2code.rosettax.LanguageSwitcher;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.internal.TextWatcherAdapter; import com.google.android.material.internal.TextWatcherAdapter;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.MaterialAutoCompleteTextView; import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.mikepenz.aboutlibraries.LibsBuilder; import com.mikepenz.aboutlibraries.LibsBuilder;
import com.topjohnwu.superuser.internal.UiThreadHandler; import com.topjohnwu.superuser.internal.UiThreadHandler;
@ -77,10 +78,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
setTitle(R.string.app_name); setTitle(R.string.app_name);
setActionBarBackground(null); setActionBarBackground(null);
if (savedInstanceState == null) { if (savedInstanceState == null) {
getSupportFragmentManager() getSupportFragmentManager().beginTransaction().replace(R.id.settings, new SettingsFragment()).commit();
.beginTransaction()
.replace(R.id.settings, new SettingsFragment())
.commit();
} }
} }
@ -90,8 +88,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
Intent mStartActivity = new Intent(this, MainActivity.class); Intent mStartActivity = new Intent(this, MainActivity.class);
mStartActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); mStartActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
int mPendingIntentId = 123456; int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
AlarmManager mgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); AlarmManager mgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0); // Exit app process System.exit(0); // Exit app process
@ -103,8 +100,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
super.onPause(); super.onPause();
} }
public static class SettingsFragment extends PreferenceFragmentCompat public static class SettingsFragment extends PreferenceFragmentCompat implements FoxActivity.OnBackPressedCallback {
implements FoxActivity.OnBackPressedCallback {
@Override @Override
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
@ -126,8 +122,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
devModeStep = 0; devModeStep = 0;
UiThreadHandler.handler.postDelayed(() -> { UiThreadHandler.handler.postDelayed(() -> {
MainApplication.getINSTANCE().updateTheme(); MainApplication.getINSTANCE().updateTheme();
FoxActivity.getFoxActivity(this).setThemeRecreate( FoxActivity.getFoxActivity(this).setThemeRecreate(MainApplication.getINSTANCE().getManagerThemeResId());
MainApplication.getINSTANCE().getManagerThemeResId());
}, 1); }, 1);
return true; return true;
}); });
@ -136,8 +131,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
crashReportingPreference.setChecked(MainApplication.isCrashReportingEnabled()); crashReportingPreference.setChecked(MainApplication.isCrashReportingEnabled());
crashReportingPreference.setOnPreferenceChangeListener((preference, newValue) -> { crashReportingPreference.setOnPreferenceChangeListener((preference, newValue) -> {
devModeStep = 0; devModeStep = 0;
getCrashReportingEditor(requireActivity()).putBoolean("crash_reporting", getCrashReportingEditor(requireActivity()).putBoolean("crash_reporting", (boolean) newValue).apply();
(boolean) newValue).apply();
return true; return true;
}); });
Preference enableBlur = findPreference("pref_enable_blur"); Preference enableBlur = findPreference("pref_enable_blur");
@ -154,8 +148,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
disableMonet.setOnPreferenceClickListener(preference -> { disableMonet.setOnPreferenceClickListener(preference -> {
UiThreadHandler.handler.postDelayed(() -> { UiThreadHandler.handler.postDelayed(() -> {
MainApplication.getINSTANCE().updateTheme(); MainApplication.getINSTANCE().updateTheme();
((FoxActivity) this.requireActivity()).setThemeRecreate( ((FoxActivity) this.requireActivity()).setThemeRecreate(MainApplication.getINSTANCE().getManagerThemeResId());
MainApplication.getINSTANCE().getManagerThemeResId());
}, 1); }, 1);
return true; return true;
}); });
@ -198,8 +191,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
int level = this.currentLanguageLevel(); int level = this.currentLanguageLevel();
if (level != LANGUAGE_SUPPORT_LEVEL) { if (level != LANGUAGE_SUPPORT_LEVEL) {
Log.e(TAG, "Detected language level " + level + Log.e(TAG, "Detected language level " + level + ", latest is " + LANGUAGE_SUPPORT_LEVEL);
", latest is " + LANGUAGE_SUPPORT_LEVEL);
languageSelector.setSummary(R.string.language_support_outdated); languageSelector.setSummary(R.string.language_support_outdated);
} else { } else {
if (!"Translated by Fox2Code".equals( // I don't "translate" english if (!"Translated by Fox2Code".equals( // I don't "translate" english
@ -212,45 +204,45 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
if (!MainApplication.isDeveloper()) { if (!MainApplication.isDeveloper()) {
findPreference("pref_disable_low_quality_module_filter").setVisible(false); findPreference("pref_disable_low_quality_module_filter").setVisible(false);
// Hide the pref_crash option if not in debug mode - stop users from purposely crashing the app
Objects.requireNonNull((Preference) findPreference("pref_crash")).setVisible(false);
} else {
findPreference("pref_crash").setOnPreferenceClickListener(preference -> {
// Hard crash the app
throw new RuntimeException("This is a test crash");
});
} }
if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND || !MainApplication.isDeveloper()) {
|| !MainApplication.isDeveloper()) {
findPreference("pref_use_magisk_install_command").setVisible(false); findPreference("pref_use_magisk_install_command").setVisible(false);
} }
Preference debugNotification = findPreference("pref_background_update_check_debug"); Preference debugNotification = findPreference("pref_background_update_check_debug");
debugNotification.setEnabled(MainApplication.isBackgroundUpdateCheckEnabled()); debugNotification.setEnabled(MainApplication.isBackgroundUpdateCheckEnabled());
debugNotification.setVisible(MainApplication.isDeveloper()); debugNotification.setVisible(MainApplication.isDeveloper());
debugNotification.setOnPreferenceClickListener(preference -> { debugNotification.setOnPreferenceClickListener(preference -> {
BackgroundUpdateChecker.postNotification( BackgroundUpdateChecker.postNotification(this.requireContext(), new Random().nextInt(4) + 2);
this.requireContext(), new Random().nextInt(4) + 2);
return true; return true;
}); });
findPreference("pref_background_update_check").setOnPreferenceChangeListener((preference, newValue) -> { findPreference("pref_background_update_check").setOnPreferenceChangeListener((preference, newValue) -> {
boolean enabled = Boolean.parseBoolean(String.valueOf(newValue)); boolean enabled = Boolean.parseBoolean(String.valueOf(newValue));
debugNotification.setEnabled(enabled); debugNotification.setEnabled(enabled);
if (!enabled) { if (!enabled) {
BackgroundUpdateChecker.onMainActivityResume( BackgroundUpdateChecker.onMainActivityResume(this.requireContext());
this.requireContext());
} }
return true; return true;
}); });
final LibsBuilder libsBuilder = new LibsBuilder().withShowLoadingProgress(false) final LibsBuilder libsBuilder = new LibsBuilder().withShowLoadingProgress(false).withLicenseShown(true).withAboutMinimalDesign(false);
.withLicenseShown(true).withAboutMinimalDesign(false);
Preference update = findPreference("pref_update"); Preference update = findPreference("pref_update");
update.setVisible(BuildConfig.ENABLE_AUTO_UPDATER && (BuildConfig.DEBUG || update.setVisible(BuildConfig.ENABLE_AUTO_UPDATER && (BuildConfig.DEBUG || AppUpdateManager.getAppUpdateManager().peekHasUpdate()));
AppUpdateManager.getAppUpdateManager().peekHasUpdate()));
update.setOnPreferenceClickListener(p -> { update.setOnPreferenceClickListener(p -> {
devModeStep = 0; devModeStep = 0;
IntentHelper.openUrl(p.getContext(), IntentHelper.openUrl(p.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager/releases");
"https://github.com/Fox2Code/FoxMagiskModuleManager/releases");
return true; return true;
}); });
if (BuildConfig.DEBUG || BuildConfig.ENABLE_AUTO_UPDATER) { if (BuildConfig.DEBUG || BuildConfig.ENABLE_AUTO_UPDATER) {
findPreference("pref_report_bug").setOnPreferenceClickListener(p -> { findPreference("pref_report_bug").setOnPreferenceClickListener(p -> {
devModeStep = 0; devModeStep = 0;
IntentHelper.openUrl(p.getContext(), IntentHelper.openUrl(p.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager/issues");
"https://github.com/Fox2Code/FoxMagiskModuleManager/issues");
return true; return true;
}); });
} else { } else {
@ -260,20 +252,17 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
if (devModeStep == 2) { if (devModeStep == 2) {
devModeStep = 0; devModeStep = 0;
if (MainApplication.isDeveloper() && !BuildConfig.DEBUG) { if (MainApplication.isDeveloper() && !BuildConfig.DEBUG) {
MainApplication.getSharedPreferences().edit() MainApplication.getSharedPreferences().edit().putBoolean("developer", false).apply();
.putBoolean("developer", false).apply();
Toast.makeText(getContext(), // Tell the user something changed Toast.makeText(getContext(), // Tell the user something changed
R.string.dev_mode_disabled, Toast.LENGTH_SHORT).show(); R.string.dev_mode_disabled, Toast.LENGTH_SHORT).show();
} else { } else {
MainApplication.getSharedPreferences().edit() MainApplication.getSharedPreferences().edit().putBoolean("developer", true).apply();
.putBoolean("developer", true).apply();
Toast.makeText(getContext(), // Tell the user something changed Toast.makeText(getContext(), // Tell the user something changed
R.string.dev_mode_enabled, Toast.LENGTH_SHORT).show(); R.string.dev_mode_enabled, Toast.LENGTH_SHORT).show();
} }
return true; return true;
} }
IntentHelper.openUrl(p.getContext(), IntentHelper.openUrl(p.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager");
"https://github.com/Fox2Code/FoxMagiskModuleManager");
return true; return true;
}); });
findPreference("pref_support").setOnPreferenceClickListener(p -> { findPreference("pref_support").setOnPreferenceClickListener(p -> {
@ -287,14 +276,10 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
openFragment(libsBuilder.supportFragment(), R.string.licenses); openFragment(libsBuilder.supportFragment(), R.string.licenses);
return true; return true;
}); });
findPreference("pref_pkg_info").setSummary( findPreference("pref_pkg_info").setSummary(BuildConfig.APPLICATION_ID + " v" + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")");
BuildConfig.APPLICATION_ID + " v" +
BuildConfig.VERSION_NAME + " (" +
BuildConfig.VERSION_CODE + ")");
} }
private SharedPreferences.Editor getCrashReportingEditor(FragmentActivity private SharedPreferences.Editor getCrashReportingEditor(FragmentActivity requireActivity) {
requireActivity) {
return requireActivity.getSharedPreferences("crash_reporting", Context.MODE_PRIVATE).edit(); return requireActivity.getSharedPreferences("crash_reporting", Context.MODE_PRIVATE).edit();
} }
@ -302,33 +287,20 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
FoxActivity compatActivity = getFoxActivity(this); FoxActivity compatActivity = getFoxActivity(this);
compatActivity.setOnBackPressedCallback(this); compatActivity.setOnBackPressedCallback(this);
compatActivity.setTitle(title); compatActivity.setTitle(title);
compatActivity.getSupportFragmentManager() compatActivity.getSupportFragmentManager().beginTransaction().replace(R.id.settings, fragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit();
.beginTransaction()
.replace(R.id.settings, fragment)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
} }
@Override @Override
public boolean onBackPressed(FoxActivity compatActivity) { public boolean onBackPressed(FoxActivity compatActivity) {
compatActivity.setTitle(R.string.app_name); compatActivity.setTitle(R.string.app_name);
compatActivity.getSupportFragmentManager() compatActivity.getSupportFragmentManager().beginTransaction().replace(R.id.settings, this).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit();
.beginTransaction().replace(R.id.settings, this)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
return true; return true;
} }
private int currentLanguageLevel() { private int currentLanguageLevel() {
int declaredLanguageLevel = int declaredLanguageLevel = this.getResources().getInteger(R.integer.language_support_level);
this.getResources().getInteger(R.integer.language_support_level); if (declaredLanguageLevel != LANGUAGE_SUPPORT_LEVEL) return declaredLanguageLevel;
if (declaredLanguageLevel != LANGUAGE_SUPPORT_LEVEL) if (!this.getResources().getConfiguration().locale.getLanguage().equals("en") && this.getResources().getString(R.string.notification_update_pref).equals("Background modules update check") && this.getResources().getString(R.string.notification_update_desc).equals("May increase battery usage")) {
return declaredLanguageLevel;
if (!this.getResources().getConfiguration().locale.getLanguage().equals("en") &&
this.getResources().getString(R.string.notification_update_pref)
.equals("Background modules update check") &&
this.getResources().getString(R.string.notification_update_desc)
.equals("May increase battery usage")) {
return 0; return 0;
} }
return LANGUAGE_SUPPORT_LEVEL; return LANGUAGE_SUPPORT_LEVEL;
@ -348,13 +320,26 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
setRepoData(RepoManager.DG_MAGISK_REPO_GITHUB); setRepoData(RepoManager.DG_MAGISK_REPO_GITHUB);
updateCustomRepoList(true); updateCustomRepoList(true);
if (!MainApplication.isDeveloper()) { if (!MainApplication.isDeveloper()) {
Objects.requireNonNull((Preference) findPreference( Objects.requireNonNull((Preference) findPreference("pref_androidacy_test_mode")).setVisible(false);
"pref_androidacy_test_mode")).setVisible(false); } else {
// Show a warning if user tries to enable test mode
Objects.requireNonNull((SwitchPreferenceCompat) findPreference("pref_androidacy_test_mode")).setOnPreferenceChangeListener((preference, newValue) -> {
if (Boolean.parseBoolean(String.valueOf(newValue))) {
new AlertDialog.Builder(this.requireContext())
.setTitle(R.string.warning)
.setMessage(R.string.androidacy_test_mode_warning)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
// Do nothing
})
.show();
}
return true;
});
} }
String originalApiKey = MainApplication.getSharedPreferences() String originalApiKey = MainApplication.getSharedPreferences().getString("pref_androidacy_api_token", "");
.getString("pref_androidacy_api_token", "");
// Create the pref_androidacy_repo_api_key text input with validation // Create the pref_androidacy_repo_api_key text input with validation
EditTextPreference prefAndroidacyRepoApiKey = findPreference("pref_androidacy_repo_api_key"); EditTextPreference prefAndroidacyRepoApiKey = findPreference("pref_androidacy_repo_api_key");
assert prefAndroidacyRepoApiKey != null;
prefAndroidacyRepoApiKey.setOnBindEditTextListener(editText -> { prefAndroidacyRepoApiKey.setOnBindEditTextListener(editText -> {
editText.setSingleLine(); editText.setSingleLine();
// Make the single line wrap // Make the single line wrap
@ -370,61 +355,48 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
// throw new RuntimeException("This is a test crash"); // throw new RuntimeException("This is a test crash");
// get original api key // get original api key
String apiKey = String.valueOf(newValue); String apiKey = String.valueOf(newValue);
// Show progress dialog // Show snack bar with indeterminate progress
ProgressDialog progressDialog = new ProgressDialog(getContext()); Snackbar.make(requireView(), R.string.checking_api_key, Snackbar.LENGTH_INDEFINITE).setAction(R.string.cancel, v -> {
progressDialog.setMessage(getString(R.string.checking_api_key)); // Restore the original api key
progressDialog.setCancelable(false); prefAndroidacyRepoApiKey.setText(originalApiKey);
progressDialog.show(); }).show();
// Check the API key on a background thread // Check the API key on a background thread
new Thread(() -> { new Thread(() -> {
// If key is empty, just remove it and show a toast // If key is empty, just remove it and change the text of the snack bar
if (apiKey.isEmpty()) { if (apiKey.isEmpty()) {
MainApplication.getSharedPreferences().edit() MainApplication.getSharedPreferences().edit().remove("pref_androidacy_repo_api_key").apply();
.remove("pref_androidacy_repo_api_key").apply(); new Handler(Looper.getMainLooper()).post(() -> Snackbar.make(requireView(), R.string.api_key_removed, Snackbar.LENGTH_SHORT).show());
new Handler(Looper.getMainLooper()).post(() -> {
progressDialog.dismiss();
Toast.makeText(getContext(), R.string.api_key_removed, Toast.LENGTH_SHORT).show();
});
return;
} else { } else {
// If key < 64 chars, it's not valid // If key < 64 chars, it's not valid
if (apiKey.length() < 64) { if (apiKey.length() < 64) {
new Handler(Looper.getMainLooper()).post(() -> { new Handler(Looper.getMainLooper()).post(() -> {
progressDialog.dismiss(); Snackbar.make(requireView(), R.string.api_key_invalid, Snackbar.LENGTH_SHORT).show();
// Save the original key // Save the original key
MainApplication.getSharedPreferences().edit() MainApplication.getSharedPreferences().edit().putString("pref_androidacy_api_token", originalApiKey).apply();
.putString("pref_androidacy_api_token", originalApiKey).apply();
// Re-show the dialog with an error // Re-show the dialog with an error
prefAndroidacyRepoApiKey.performClick(); prefAndroidacyRepoApiKey.performClick();
// Show error // Show error
prefAndroidacyRepoApiKey.setDialogMessage(getString(R.string.api_key_invalid)); prefAndroidacyRepoApiKey.setDialogMessage(getString(R.string.api_key_invalid));
// Set the error color
Toast.makeText(getContext(), R.string.api_key_invalid, Toast.LENGTH_SHORT).show();
}); });
return;
}
}
// Check the API key
boolean valid = AndroidacyRepoData.getInstance().isValidToken(apiKey);
// Update the UI on the main thread
new Handler(Looper.getMainLooper()).post(() -> {
progressDialog.dismiss();
if (valid) {
// Show a success message
Toast.makeText(getContext(), R.string.api_key_valid,
Toast.LENGTH_SHORT).show();
// Save the API key
MainApplication.getSharedPreferences().edit()
.putString("pref_androidacy_api_token", apiKey).apply();
} else { } else {
// Show an error message boolean valid = AndroidacyRepoData.getInstance().isValidToken(apiKey);
Toast.makeText(getContext(), R.string.api_key_invalid, // If the key is valid, save it
Toast.LENGTH_SHORT).show(); if (valid) {
// Restore the original API key MainApplication.getSharedPreferences().edit().putString("pref_androidacy_repo_api_key", apiKey).apply();
MainApplication.getSharedPreferences().edit() new Handler(Looper.getMainLooper()).post(() -> Snackbar.make(requireView(), R.string.api_key_valid, Snackbar.LENGTH_SHORT).show());
.putString("pref_androidacy_api_token", originalApiKey).apply(); } else {
new Handler(Looper.getMainLooper()).post(() -> {
Snackbar.make(requireView(), R.string.api_key_invalid, Snackbar.LENGTH_SHORT).show();
// Save the original key
MainApplication.getSharedPreferences().edit().putString("pref_androidacy_api_token", originalApiKey).apply();
// Re-show the dialog with an error
prefAndroidacyRepoApiKey.performClick();
// Show error
prefAndroidacyRepoApiKey.setDialogMessage(getString(R.string.api_key_invalid));
});
}
} }
}); }
}).start(); }).start();
return true; return true;
}); });
@ -432,21 +404,17 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
public void updateCustomRepoList(boolean initial) { public void updateCustomRepoList(boolean initial) {
final SharedPreferences sharedPreferences = Objects.requireNonNull( final SharedPreferences sharedPreferences = Objects.requireNonNull(this.getPreferenceManager().getSharedPreferences());
this.getPreferenceManager().getSharedPreferences()); final CustomRepoManager customRepoManager = RepoManager.getINSTANCE().getCustomRepoManager();
final CustomRepoManager customRepoManager =
RepoManager.getINSTANCE().getCustomRepoManager();
for (int i = 0; i < CUSTOM_REPO_ENTRIES; i++) { for (int i = 0; i < CUSTOM_REPO_ENTRIES; i++) {
CustomRepoData repoData = customRepoManager.getRepo(i); CustomRepoData repoData = customRepoManager.getRepo(i);
setRepoData(repoData, "pref_custom_repo_" + i); setRepoData(repoData, "pref_custom_repo_" + i);
if (initial) { if (initial) {
Preference preference = Preference preference = findPreference("pref_custom_repo_" + i + "_delete");
findPreference("pref_custom_repo_" + i + "_delete");
if (preference == null) continue; if (preference == null) continue;
final int index = i; final int index = i;
preference.setOnPreferenceClickListener(preference1 -> { preference.setOnPreferenceClickListener(preference1 -> {
sharedPreferences.edit().putBoolean( sharedPreferences.edit().putBoolean("pref_custom_repo_" + index + "_enabled", false).apply();
"pref_custom_repo_" + index + "_enabled", false).apply();
customRepoManager.removeRepo(index); customRepoManager.removeRepo(index);
updateCustomRepoList(false); updateCustomRepoList(false);
return true; return true;
@ -455,16 +423,14 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
} }
Preference preference = findPreference("pref_custom_add_repo"); Preference preference = findPreference("pref_custom_add_repo");
if (preference == null) return; if (preference == null) return;
preference.setVisible(customRepoManager.canAddRepo() && preference.setVisible(customRepoManager.canAddRepo() && customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
if (initial) { // Custom repo add button part. if (initial) { // Custom repo add button part.
preference = findPreference("pref_custom_add_repo_button"); preference = findPreference("pref_custom_add_repo_button");
if (preference == null) return; if (preference == null) return;
preference.setOnPreferenceClickListener(preference1 -> { preference.setOnPreferenceClickListener(preference1 -> {
final Context context = this.requireContext(); final Context context = this.requireContext();
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context); MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
final MaterialAutoCompleteTextView input = final MaterialAutoCompleteTextView input = new MaterialAutoCompleteTextView(context);
new MaterialAutoCompleteTextView(context);
input.setHint(R.string.custom_url); input.setHint(R.string.custom_url);
builder.setIcon(R.drawable.ic_baseline_add_box_24); builder.setIcon(R.drawable.ic_baseline_add_box_24);
builder.setTitle(R.string.add_repo); builder.setTitle(R.string.add_repo);
@ -472,8 +438,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
builder.setPositiveButton("OK", (dialog, which) -> { builder.setPositiveButton("OK", (dialog, which) -> {
String text = String.valueOf(input.getText()); String text = String.valueOf(input.getText());
if (customRepoManager.canAddRepo(text)) { if (customRepoManager.canAddRepo(text)) {
final CustomRepoData customRepoData = final CustomRepoData customRepoData = customRepoManager.addRepo(text);
customRepoManager.addRepo(text);
customRepoData.setEnabled(true); customRepoData.setEnabled(true);
new Thread("Add Custom Repo Thread") { new Thread("Add Custom Repo Thread") {
@Override @Override
@ -490,8 +455,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
}); });
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel()); builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
AlertDialog alertDialog = builder.show(); AlertDialog alertDialog = builder.show();
final Button positiveButton = final Button positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
input.setValidator(new AutoCompleteTextView.Validator() { input.setValidator(new AutoCompleteTextView.Validator() {
@Override @Override
public boolean isValid(CharSequence charSequence) { public boolean isValid(CharSequence charSequence) {
@ -505,16 +469,12 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
}); });
input.addTextChangedListener(new TextWatcherAdapter() { input.addTextChangedListener(new TextWatcherAdapter() {
@Override @Override
public void onTextChanged( public void onTextChanged(@NonNull CharSequence charSequence, int i, int i1, int i2) {
@NonNull CharSequence charSequence, int i, int i1, int i2) { positiveButton.setEnabled(customRepoManager.canAddRepo(charSequence.toString()) && customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
positiveButton.setEnabled(customRepoManager
.canAddRepo(charSequence.toString()) &&
customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
} }
}); });
positiveButton.setEnabled(false); positiveButton.setEnabled(false);
int dp10 = FoxDisplay.dpToPixel(10), int dp10 = FoxDisplay.dpToPixel(10), dp20 = FoxDisplay.dpToPixel(20);
dp20 = FoxDisplay.dpToPixel(20);
FoxViewCompat.setMargin(input, dp20, dp10, dp20, dp10); FoxViewCompat.setMargin(input, dp20, dp10, dp20, dp10);
return true; return true;
}); });
@ -523,8 +483,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
private void setRepoData(String url) { private void setRepoData(String url) {
final RepoData repoData = RepoManager.getINSTANCE().get(url); final RepoData repoData = RepoManager.getINSTANCE().get(url);
setRepoData(repoData, "pref_" + (repoData == null ? setRepoData(repoData, "pref_" + (repoData == null ? RepoManager.internalIdOfUrl(url) : repoData.getPreferenceId()));
RepoManager.internalIdOfUrl(url) : repoData.getPreferenceId()));
} }
private void setRepoData(final RepoData repoData, String preferenceName) { private void setRepoData(final RepoData repoData, String preferenceName) {
@ -539,11 +498,9 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
preference = findPreference(preferenceName + "_enabled"); preference = findPreference(preferenceName + "_enabled");
if (preference != null) { if (preference != null) {
((TwoStatePreference) preference).setChecked(repoData.isEnabled()); ((TwoStatePreference) preference).setChecked(repoData.isEnabled());
preference.setTitle(repoData.isEnabled() ? preference.setTitle(repoData.isEnabled() ? R.string.repo_enabled : R.string.repo_disabled);
R.string.repo_enabled : R.string.repo_disabled);
preference.setOnPreferenceChangeListener((p, newValue) -> { preference.setOnPreferenceChangeListener((p, newValue) -> {
p.setTitle(((Boolean) newValue) ? p.setTitle(((Boolean) newValue) ? R.string.repo_enabled : R.string.repo_disabled);
R.string.repo_enabled : R.string.repo_disabled);
return true; return true;
}); });
} }
@ -554,8 +511,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
preference.setVisible(true); preference.setVisible(true);
preference.setOnPreferenceClickListener(p -> { preference.setOnPreferenceClickListener(p -> {
if (homepage.startsWith("https://www.androidacy.com/")) { if (homepage.startsWith("https://www.androidacy.com/")) {
IntentHelper.openUrlAndroidacy( IntentHelper.openUrlAndroidacy(getFoxActivity(this), homepage, true);
getFoxActivity(this), homepage, true);
} else { } else {
IntentHelper.openUrl(getFoxActivity(this), homepage); IntentHelper.openUrl(getFoxActivity(this), homepage);
} }
@ -600,8 +556,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
preference.setVisible(true); preference.setVisible(true);
preference.setOnPreferenceClickListener(p -> { preference.setOnPreferenceClickListener(p -> {
if (submissionUrl.startsWith("https://www.androidacy.com/")) { if (submissionUrl.startsWith("https://www.androidacy.com/")) {
IntentHelper.openUrlAndroidacy( IntentHelper.openUrlAndroidacy(getFoxActivity(this), submissionUrl, true);
getFoxActivity(this), submissionUrl, true);
} else { } else {
IntentHelper.openUrl(getFoxActivity(this), submissionUrl); IntentHelper.openUrl(getFoxActivity(this), submissionUrl);
} }

@ -24,4 +24,5 @@
<color name="light_colorBackgroundFloating">#FFFFFFFF</color> <color name="light_colorBackgroundFloating">#FFFFFFFF</color>
<color name="light_backgroundColor">#FFFFFFFF</color> <color name="light_backgroundColor">#FFFFFFFF</color>
<color name="light_chipBackgroundColor">#FFDADADA</color> <color name="light_chipBackgroundColor">#FFDADADA</color>
<color name="gray_900">#3A3A3A</color>
</resources> </resources>

@ -165,4 +165,7 @@
<string name="please_wait">Please wait</string> <string name="please_wait">Please wait</string>
<string name="api_key_removed">Successfully reset API key</string> <string name="api_key_removed">Successfully reset API key</string>
<string name="save_api_key">Validate</string> <string name="save_api_key">Validate</string>
<string name="warning">Warning!</string>
<string name="androidacy_test_mode_warning">You are setting the app to use a non-production endpoint for Androidacy. This may result in app instability and failure to load the online repo. Do NOT report bugs if you have this switch on. Change will take effect on app restart.</string>
<string name="crash">Crash the app for testing</string>
</resources> </resources>

@ -3,161 +3,165 @@
<!-- Custom repos has been announced, check https://github.com/Fox2Code/FoxMagiskModuleManager/issues/131 --> <!-- Custom repos has been announced, check https://github.com/Fox2Code/FoxMagiskModuleManager/issues/131 -->
<PreferenceCategory app:title="@string/pref_category_repos"> <PreferenceCategory app:title="@string/pref_category_repos">
<Preference <Preference
app:key="pref_manage_repos"
app:icon="@drawable/ic_baseline_extension_24" app:icon="@drawable/ic_baseline_extension_24"
app:title="@string/manage_repos_pref" app:key="pref_manage_repos"
app:singleLineTitle="false" /> app:singleLineTitle="false"
app:title="@string/manage_repos_pref" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="false" app:defaultValue="false"
app:key="pref_show_incompatible"
app:icon="@drawable/ic_baseline_hide_source_24" app:icon="@drawable/ic_baseline_hide_source_24"
app:title="@string/show_incompatible_pref" app:key="pref_show_incompatible"
app:singleLineTitle="false"
app:summary="@string/show_incompatible_desc" app:summary="@string/show_incompatible_desc"
app:singleLineTitle="false" /> app:title="@string/show_incompatible_pref" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="false" app:defaultValue="false"
app:key="pref_disable_low_quality_module_filter"
app:icon="@drawable/ic_baseline_warning_24" app:icon="@drawable/ic_baseline_warning_24"
app:title="@string/disable_low_quality_module_filter_pref" app:key="pref_disable_low_quality_module_filter"
app:singleLineTitle="false"
app:summary="@string/disable_low_quality_module_filter_desc" app:summary="@string/disable_low_quality_module_filter_desc"
app:singleLineTitle="false" /> app:title="@string/disable_low_quality_module_filter_pref" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="false" app:defaultValue="false"
app:key="pref_use_magisk_install_command"
app:icon="@drawable/ic_baseline_numbers_24" app:icon="@drawable/ic_baseline_numbers_24"
app:title="@string/use_magisk_install_command_pref" app:key="pref_use_magisk_install_command"
app:singleLineTitle="false"
app:summary="@string/use_magisk_install_command_desc" app:summary="@string/use_magisk_install_command_desc"
app:singleLineTitle="false" /> app:title="@string/use_magisk_install_command_pref" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="true" app:defaultValue="true"
app:key="pref_background_update_check"
app:icon="@drawable/ic_baseline_notifications_24" app:icon="@drawable/ic_baseline_notifications_24"
app:title="@string/notification_update_pref" app:key="pref_background_update_check"
app:singleLineTitle="false"
app:summary="@string/notification_update_desc" app:summary="@string/notification_update_desc"
app:singleLineTitle="false" /> app:title="@string/notification_update_pref" />
<Preference <Preference
app:key="pref_background_update_check_debug" app:key="pref_background_update_check_debug"
app:title="@string/notification_update_debug_pref" app:singleLineTitle="false"
app:singleLineTitle="false" /> app:title="@string/notification_update_debug_pref" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory app:title="@string/pref_category_appearance"> <PreferenceCategory app:title="@string/pref_category_appearance">
<ListPreference <ListPreference
app:key="pref_theme"
app:icon="@drawable/ic_baseline_palette_24"
app:title="@string/theme_pref"
app:defaultValue="system" app:defaultValue="system"
app:entries="@array/theme_values_names" app:entries="@array/theme_values_names"
app:entryValues="@array/theme_values" app:entryValues="@array/theme_values"
app:singleLineTitle="false" /> app:icon="@drawable/ic_baseline_palette_24"
app:key="pref_theme"
app:singleLineTitle="false"
app:title="@string/theme_pref" />
<Preference <Preference
app:key="pref_language_selector"
app:icon="@drawable/ic_baseline_language_24" app:icon="@drawable/ic_baseline_language_24"
app:title="@string/language" /> app:key="pref_language_selector"
app:title="@string/language" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="false" app:defaultValue="false"
app:key="pref_enable_blur"
app:icon="@drawable/ic_baseline_blur_on_24" app:icon="@drawable/ic_baseline_blur_on_24"
app:title="@string/enable_blur_pref" app:key="pref_enable_blur"
app:singleLineTitle="false" /> app:singleLineTitle="false"
app:title="@string/enable_blur_pref" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="false" app:defaultValue="false"
app:key="pref_force_dark_terminal"
app:icon="@drawable/ic_baseline_list_24" app:icon="@drawable/ic_baseline_list_24"
app:title="@string/force_dark_terminal_title" app:key="pref_force_dark_terminal"
app:singleLineTitle="false" /> app:singleLineTitle="false"
app:title="@string/force_dark_terminal_title" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="@bool/monet_enabled_by_default" app:defaultValue="@bool/monet_enabled_by_default"
app:key="pref_enable_monet"
app:icon="@drawable/ic_baseline_design_services_24" app:icon="@drawable/ic_baseline_design_services_24"
app:title="@string/enable_monet" app:key="pref_enable_monet"
app:singleLineTitle="false" /> app:singleLineTitle="false"
app:title="@string/enable_monet" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="false" app:defaultValue="false"
app:key="pref_wrap_text"
app:icon="@drawable/ic_baseline_keyboard_return_24" app:icon="@drawable/ic_baseline_keyboard_return_24"
app:title="@string/wrap_text_pref" app:key="pref_wrap_text"
app:singleLineTitle="false"
app:summary="@string/wrap_text_desc" app:summary="@string/wrap_text_desc"
app:singleLineTitle="false" /> app:title="@string/wrap_text_pref" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory app:title="@string/pref_category_security"> <PreferenceCategory app:title="@string/pref_category_security">
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="true" app:defaultValue="true"
app:key="pref_dns_over_https"
app:icon="@drawable/ic_baseline_security_24" app:icon="@drawable/ic_baseline_security_24"
app:title="@string/dns_over_https_pref" app:key="pref_dns_over_https"
app:singleLineTitle="false"
app:summary="@string/dns_over_https_desc" app:summary="@string/dns_over_https_desc"
app:singleLineTitle="false" /> app:title="@string/dns_over_https_pref" />
<!-- Note: Lockdown mode used to be called showcase mode --> <!-- Note: Lockdown mode used to be called showcase mode -->
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="false" app:defaultValue="false"
app:key="pref_showcase_mode"
app:icon="@drawable/ic_baseline_lock_24" app:icon="@drawable/ic_baseline_lock_24"
app:title="@string/showcase_mode_pref" app:key="pref_showcase_mode"
app:singleLineTitle="false"
app:summary="@string/showcase_mode_desc" app:summary="@string/showcase_mode_desc"
app:singleLineTitle="false" /> app:title="@string/showcase_mode_pref" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="true" app:defaultValue="true"
app:key="pref_prevent_reboot"
app:icon="@drawable/ic_reboot_24" app:icon="@drawable/ic_reboot_24"
app:title="@string/prevent_reboot_pref" app:key="pref_prevent_reboot"
app:singleLineTitle="false"
app:summary="@string/prevent_reboot_desc" app:summary="@string/prevent_reboot_desc"
app:singleLineTitle="false" /> app:title="@string/prevent_reboot_pref" />
<!-- Crash reporting --> <!-- Crash reporting -->
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="true" app:defaultValue="true"
app:key="pref_crash_reporting"
app:icon="@drawable/ic_baseline_bug_report_24" app:icon="@drawable/ic_baseline_bug_report_24"
app:title="@string/crash_reporting" app:key="pref_crash_reporting"
app:singleLineTitle="false"
app:summary="@string/crash_reporting_desc" app:summary="@string/crash_reporting_desc"
app:singleLineTitle="false" /> app:title="@string/crash_reporting" />
<!-- Purposely crash the app -->
<Preference
app:icon="@drawable/ic_baseline_bug_report_24"
app:key="pref_crash"
app:singleLineTitle="false"
app:title="@string/crash" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory app:title="@string/pref_category_info">
app:title="@string/pref_category_info">
<Preference <Preference
app:key="pref_update"
app:icon="@drawable/ic_baseline_system_update_24" app:icon="@drawable/ic_baseline_system_update_24"
app:title="@string/app_update" app:key="pref_update"
app:singleLineTitle="false" /> app:singleLineTitle="false"
app:title="@string/app_update" />
<Preference <Preference
app:key="pref_report_bug"
app:icon="@drawable/ic_baseline_bug_report_24" app:icon="@drawable/ic_baseline_bug_report_24"
app:title="@string/report_bugs" app:key="pref_report_bug"
app:singleLineTitle="false" /> app:singleLineTitle="false"
app:title="@string/report_bugs" />
<Preference <Preference
app:key="pref_source_code"
app:icon="@drawable/ic_github" app:icon="@drawable/ic_github"
app:title="@string/source_code" app:key="pref_source_code"
app:singleLineTitle="false" /> app:singleLineTitle="false"
app:title="@string/source_code" />
<Preference <Preference
app:key="pref_support"
app:icon="@drawable/ic_baseline_telegram_24" app:icon="@drawable/ic_baseline_telegram_24"
app:title="@string/support" app:key="pref_support"
app:singleLineTitle="false" /> app:singleLineTitle="false"
app:title="@string/support" />
<Preference <Preference
app:key="pref_show_licenses"
app:icon="@drawable/ic_baseline_info_24" app:icon="@drawable/ic_baseline_info_24"
app:title="@string/show_licenses" app:key="pref_show_licenses"
app:singleLineTitle="false" /> app:singleLineTitle="false"
app:title="@string/show_licenses" />
<Preference <Preference
app:key="pref_pkg_info"
app:enabled="false" app:enabled="false"
app:summary="@string/loading" app:iconSpaceReserved="false"
app:key="pref_pkg_info"
app:singleLineTitle="false" app:singleLineTitle="false"
app:iconSpaceReserved="false" /> app:summary="@string/loading" />
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>
Loading…
Cancel
Save