From d4ee5725297ec7d311df72ac933474e03aa7777d Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Sun, 17 Jul 2022 19:25:25 +0200 Subject: [PATCH] Finish custom repos implementation + add more default repos. --- app/build.gradle | 2 +- .../java/com/fox2code/mmm/MainActivity.java | 16 ++ .../main/java/com/fox2code/mmm/XHooks.java | 3 +- .../mmm/module/ModuleViewAdapter.java | 4 + .../com/fox2code/mmm/repo/CustomRepoData.java | 49 ++++++ .../fox2code/mmm/repo/CustomRepoManager.java | 121 +++++++++++++ .../fox2code/mmm/repo/LimitedRepoData.java | 21 --- .../java/com/fox2code/mmm/repo/RepoData.java | 10 +- .../com/fox2code/mmm/repo/RepoManager.java | 78 +++++++-- .../mmm/settings/SettingsActivity.java | 161 +++++++++++++++--- .../res/drawable/ic_baseline_add_box_24.xml | 10 ++ app/src/main/res/values/themable.xml | 2 + app/src/main/res/xml/repo_preferences.xml | 144 ++++++++++++++++ 13 files changed, 563 insertions(+), 58 deletions(-) create mode 100644 app/src/main/java/com/fox2code/mmm/repo/CustomRepoData.java create mode 100644 app/src/main/java/com/fox2code/mmm/repo/CustomRepoManager.java delete mode 100644 app/src/main/java/com/fox2code/mmm/repo/LimitedRepoData.java create mode 100644 app/src/main/res/drawable/ic_baseline_add_box_24.xml diff --git a/app/build.gradle b/app/build.gradle index e8de5b9..dd80180 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -37,7 +37,7 @@ android { buildConfigField( "java.util.List", "ENABLED_REPOS", - "java.util.Arrays.asList(\"magisk_alt_repo\", \"androidacy_repo\")", + "java.util.Arrays.asList(\"magisk_alt_repo\", \"dg_magisk_repo\", \"androidacy_repo\")", ) } diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index ecc775d..30fbc21 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -171,6 +171,9 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe }); Log.i(TAG, "Scanning for modules!"); final int max = ModuleManager.getINSTANCE().getUpdatableModuleCount(); + if (RepoManager.getINSTANCE().getCustomRepoManager().needUpdate()) { + Log.w(TAG, "Need update on create?"); + } RepoManager.getINSTANCE().update(value -> runOnUiThread(max == 0 ? () -> progressIndicator.setProgressCompat( (int) (value * PRECISION), true) :() -> @@ -326,6 +329,19 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe else if (AppUpdateManager.getAppUpdateManager().checkUpdate(false)) moduleViewListBuilder.addNotification(NotificationType.UPDATE_AVAILABLE); RepoManager.getINSTANCE().updateEnabledStates(); + if (RepoManager.getINSTANCE().getCustomRepoManager().needUpdate()) { + runOnUiThread(() -> { + progressIndicator.setIndeterminate(false); + progressIndicator.setMax(PRECISION); + }); + RepoManager.getINSTANCE().update(value -> runOnUiThread(() -> + progressIndicator.setProgressCompat( + (int) (value * PRECISION), true))); + runOnUiThread(() -> { + progressIndicator.setProgressCompat(PRECISION, true); + progressIndicator.setVisibility(View.GONE); + }); + } moduleViewListBuilder.appendRemoteModules(); Log.i(TAG, "Common Before applyTo"); moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter); diff --git a/app/src/main/java/com/fox2code/mmm/XHooks.java b/app/src/main/java/com/fox2code/mmm/XHooks.java index 88b60df..50d0f63 100644 --- a/app/src/main/java/com/fox2code/mmm/XHooks.java +++ b/app/src/main/java/com/fox2code/mmm/XHooks.java @@ -8,6 +8,7 @@ import android.webkit.WebView; import androidx.annotation.Keep; import com.fox2code.mmm.manager.ModuleManager; +import com.fox2code.mmm.repo.RepoData; import com.fox2code.mmm.repo.RepoManager; /** @@ -45,7 +46,7 @@ public class XHooks { @Keep public static XRepo addXRepo(String url, String fallbackName) { - return RepoManager.getINSTANCE().addOrGet(url); + return RepoManager.getINSTANCE().addOrGet(url, fallbackName); } @Keep diff --git a/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java b/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java index 95ef33a..28bd62c 100644 --- a/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java +++ b/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java @@ -17,6 +17,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.StringRes; import androidx.cardview.widget.CardView; +import androidx.core.graphics.ColorUtils; import androidx.recyclerview.widget.RecyclerView; import com.fox2code.foxcompat.FoxDisplay; @@ -365,6 +366,9 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter= MAX_CUSTOM_REPOS) return null; + String repo = customRepos[index]; + return repo == null ? null : + (CustomRepoData) this.repoManager.get(repo); + } + + public void removeRepo(int index) { + String oldRepo = customRepos[index]; + if (oldRepo != null) { + customRepos[index] = null; + customReposCount--; + CustomRepoData customRepoData = + (CustomRepoData) this.repoManager.get(oldRepo); + if (customRepoData != null) { + customRepoData.setEnabled(false); + customRepoData.override = null; + } + this.getSharedPreferences().edit() + .remove("repo_" + index).apply(); + this.dirty = true; + } + } + + public boolean hasRepo(String repo) { + for (String repoEntry : this.customRepos) { + if (repo.equals(repoEntry)) + return true; + } + return false; + } + + public boolean canAddRepo() { + return this.customReposCount < MAX_CUSTOM_REPOS; + } + + public boolean canAddRepo(String repo) { + if (RepoManager.isBuiltInRepo(repo) || + this.hasRepo(repo) || !this.canAddRepo()) + return false; + return repo.startsWith("https://") && + repo.indexOf('/', 9) != -1; + } + + public boolean needUpdate() { + boolean needUpdate = this.dirty; + if (needUpdate) this.dirty = false; + return needUpdate; + } + +} diff --git a/app/src/main/java/com/fox2code/mmm/repo/LimitedRepoData.java b/app/src/main/java/com/fox2code/mmm/repo/LimitedRepoData.java deleted file mode 100644 index 1ca5449..0000000 --- a/app/src/main/java/com/fox2code/mmm/repo/LimitedRepoData.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.fox2code.mmm.repo; - -import android.content.SharedPreferences; - -import java.io.File; - -public class LimitedRepoData extends RepoData { - LimitedRepoData(String url, File cacheRoot, SharedPreferences cachedPreferences) { - super(url, cacheRoot, cachedPreferences); - } - - @Override - public final boolean isEnabledByDefault() { - return false; - } - - @Override - public final boolean isLimited() { - return true; - } -} diff --git a/app/src/main/java/com/fox2code/mmm/repo/RepoData.java b/app/src/main/java/com/fox2code/mmm/repo/RepoData.java index e40985b..5c50be4 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoData.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoData.java @@ -48,7 +48,7 @@ public class RepoData extends XRepo { this.metaDataCache = new File(cacheRoot, "modules.json"); this.moduleHashMap = new HashMap<>(); this.name = this.url; // Set url as default name - this.enabled = MainApplication.getSharedPreferences() + this.enabled = !this.isLimited() && MainApplication.getSharedPreferences() .getBoolean("pref_" + this.id + "_enabled", this.isEnabledByDefault()); this.defaultName = url; this.defaultWebsite = "https://" + Uri.parse(url).getHost() + "/"; @@ -103,6 +103,7 @@ public class RepoData extends XRepo { String moduleZipUrl = module.getString("zip_url"); String moduleChecksum = module.optString("checksum"); String moduleStars = module.optString("stars"); + String moduleDownloads = module.optString("downloads"); RepoModule repoModule = this.moduleHashMap.get(moduleId); if (repoModule == null) { repoModule = new RepoModule(this, moduleId); @@ -121,11 +122,16 @@ public class RepoData extends XRepo { repoModule.propUrl = modulePropsUrl; repoModule.zipUrl = moduleZipUrl; repoModule.checksum = moduleChecksum; - if (!moduleStars.isEmpty() && !this.isLimited()) { + if (!moduleStars.isEmpty()) { try { repoModule.qualityValue = Integer.parseInt(moduleStars); repoModule.qualityText = R.string.module_stars; } catch (NumberFormatException ignored) {} + } else if (!moduleDownloads.isEmpty()) { + try { + repoModule.qualityValue = Integer.parseInt(moduleDownloads); + repoModule.qualityText = R.string.module_downloads; + } catch (NumberFormatException ignored) {} } } // Remove no longer existing modules diff --git a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java index 03204d1..34cc3a9 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java @@ -21,6 +21,13 @@ import java.util.List; public final class RepoManager { private static final String TAG = "RepoManager"; + + private static final String MAGISK_REPO_MANAGER = + "https://magisk-modules-repo.github.io/submission/modules.json"; + public static final String MAGISK_REPO = + "https://raw.githubusercontent.com/Magisk-Modules-Repo/submission/modules/modules.json"; + public static final String MAGISK_REPO_HOMEPAGE = "https://github.com/Magisk-Modules-Repo"; + public static final String MAGISK_ALT_REPO = "https://raw.githubusercontent.com/Magisk-Modules-Alt-Repo/json/main/modules.json"; public static final String MAGISK_ALT_REPO_HOMEPAGE = @@ -35,6 +42,8 @@ public final class RepoManager { public static final String DG_MAGISK_REPO = "https://repo.dergoogler.com/modules.json"; + public static final String DG_MAGISK_REPO_GITHUB = + "https://googlers-magisk-repo.github.io/modules.json"; private static final Object lock = new Object(); private static volatile RepoManager INSTANCE; @@ -60,6 +69,7 @@ public final class RepoManager { private final LinkedHashMap repoData; private final HashMap modules; private final AndroidacyRepoData androidacyRepoData; + private final CustomRepoManager customRepoManager; private boolean initialized; private RepoManager(MainApplication mainApplication) { @@ -68,16 +78,16 @@ public final class RepoManager { this.repoData = new LinkedHashMap<>(); this.modules = new HashMap<>(); // We do not have repo list config yet. - RepoData altRepo = this.addRepoData(MAGISK_ALT_REPO); - altRepo.defaultName = "Magisk Modules Alt Repo"; + RepoData altRepo = this.addRepoData( + MAGISK_ALT_REPO, "Magisk Modules Alt Repo"); altRepo.defaultWebsite = RepoManager.MAGISK_ALT_REPO_HOMEPAGE; altRepo.defaultSubmitModule = "https://github.com/Magisk-Modules-Alt-Repo/submission/issues"; - /*RepoData dgRepo = this.addRepoData(DG_MAGISK_REPO); - dgRepo.defaultName = "DerGoogler Magisk Repo"; - dgRepo.defaultWebsite = "https://repo.dergoogler.com/";*/ - this.androidacyRepoData = - this.addAndroidacyRepoData(); + RepoData dgRepo = this.addRepoData( + DG_MAGISK_REPO_GITHUB, "Googlers Magisk Repo"); + dgRepo.defaultWebsite = "https://dergoogler.com/repo"; + this.androidacyRepoData = this.addAndroidacyRepoData(); + this.customRepoManager = new CustomRepoManager(mainApplication, this); // Populate default cache for (RepoData repoData:this.repoData.values()) { this.populateDefaultCache(repoData); @@ -111,6 +121,10 @@ public final class RepoManager { } public RepoData addOrGet(String url) { + return this.addOrGet(url, null); + } + + public RepoData addOrGet(String url, String fallBackName) { RepoData repoData; synchronized (this.repoUpdateLock) { repoData = this.repoData.get(url); @@ -118,7 +132,7 @@ public final class RepoManager { if (ANDROIDACY_MAGISK_REPO_ENDPOINT.equals(url)) { return this.addAndroidacyRepoData(); } else { - return this.addRepoData(url); + return this.addRepoData(url, fallBackName); } } } @@ -149,6 +163,8 @@ public final class RepoManager { // MultiThread friendly method public void update(UpdateListener updateListener) { + if (updateListener == null) + updateListener = value -> {}; if (!this.repoUpdating) { // Do scan synchronized (this.repoUpdateLock) { @@ -236,8 +252,13 @@ public final class RepoManager { } public void updateEnabledStates() { - for (RepoData repoData:this.repoData.values()) - repoData.updateEnabledState(); + for (RepoData repoData:this.repoData.values()) { + boolean wasEnabled = repoData.isEnabled(); + repoData.updateEnabledState(); + if (!wasEnabled && repoData.isEnabled()) { + this.customRepoManager.dirty = true; + } + } } public HashMap getModules() { @@ -257,6 +278,7 @@ public final class RepoManager { case ANDROIDACY_MAGISK_REPO_ENDPOINT: return "androidacy_repo"; case DG_MAGISK_REPO: + case DG_MAGISK_REPO_GITHUB: return "dg_magisk_repo"; default: return "repo_" + Hashes.hashSha1( @@ -264,16 +286,44 @@ public final class RepoManager { } } - private RepoData addRepoData(String url) { + static boolean isBuiltInRepo(String repo) { + switch (repo) { + case RepoManager.MAGISK_ALT_REPO: + case RepoManager.MAGISK_ALT_REPO_JSDELIVR: + case RepoManager.ANDROIDACY_MAGISK_REPO_ENDPOINT: + case RepoManager.DG_MAGISK_REPO: + case RepoManager.DG_MAGISK_REPO_GITHUB: + return true; + } + return false; + } + + private RepoData addRepoData(String url, String fallBackName) { if (MAGISK_ALT_REPO_JSDELIVR.equals(url)) url = MAGISK_ALT_REPO; + if (DG_MAGISK_REPO.equals(url)) + url = DG_MAGISK_REPO_GITHUB; String id = internalIdOfUrl(url); File cacheRoot = new File(this.mainApplication.getCacheDir(), id); SharedPreferences sharedPreferences = this.mainApplication .getSharedPreferences("mmm_" + id, Context.MODE_PRIVATE); RepoData repoData = id.startsWith("repo_") ? - new LimitedRepoData(url, cacheRoot, sharedPreferences) : + new CustomRepoData(url, cacheRoot, sharedPreferences) : new RepoData(url, cacheRoot, sharedPreferences); + if (fallBackName != null && !fallBackName.isEmpty()) { + if (repoData instanceof CustomRepoData) { + ((CustomRepoData) repoData).loadedExternal = true; + this.customRepoManager.dirty = true; + repoData.updateEnabledState(); + } + repoData.defaultName = fallBackName; + } + switch (url) { + case MAGISK_REPO: + case MAGISK_REPO_MANAGER: { + repoData.defaultWebsite = MAGISK_REPO_HOMEPAGE; + } + } this.repoData.put(url, repoData); if (this.initialized) { this.populateDefaultCache(repoData); @@ -294,4 +344,8 @@ public final class RepoManager { public AndroidacyRepoData getAndroidacyRepoData() { return this.androidacyRepoData; } + + public CustomRepoManager getCustomRepoManager() { + return customRepoManager; + } } diff --git a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java index d38bed5..ab22ae8 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -4,14 +4,24 @@ import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; +import android.content.SharedPreferences; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; import android.util.Log; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.EditText; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.annotation.StringRes; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.AppCompatEditText; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; import androidx.preference.ListPreference; @@ -28,18 +38,28 @@ import com.fox2code.mmm.MainApplication; import com.fox2code.mmm.R; import com.fox2code.mmm.installer.InstallerInitializer; import com.fox2code.mmm.module.ActionButtonType; +import com.fox2code.mmm.repo.CustomRepoData; +import com.fox2code.mmm.repo.CustomRepoManager; import com.fox2code.mmm.repo.RepoData; import com.fox2code.mmm.repo.RepoManager; import com.fox2code.mmm.utils.Http; import com.fox2code.mmm.utils.IntentHelper; import com.fox2code.rosettax.LanguageActivity; import com.fox2code.rosettax.LanguageSwitcher; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.internal.TextWatcherAdapter; +import com.google.android.material.textfield.MaterialAutoCompleteTextView; import com.mikepenz.aboutlibraries.LibsBuilder; import com.topjohnwu.superuser.internal.UiThreadHandler; +import org.json.JSONException; + +import java.io.IOException; import java.util.HashSet; +import java.util.Objects; public class SettingsActivity extends FoxActivity implements LanguageActivity { + private static final String TAG = "SettingsActivity"; private static int devModeStep = 0; @Override @@ -236,42 +256,135 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { } public static class RepoFragment extends PreferenceFragmentCompat { + private static final int CUSTOM_REPO_ENTRIES = 3; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { getPreferenceManager().setSharedPreferencesName("mmm"); setPreferencesFromResource(R.xml.repo_preferences, rootKey); setRepoData(RepoManager.MAGISK_ALT_REPO); - // Androidacy backend not yet implemented! setRepoData(RepoManager.ANDROIDACY_MAGISK_REPO_ENDPOINT); + setRepoData(RepoManager.DG_MAGISK_REPO_GITHUB); + updateCustomRepoList(true); + } + + @SuppressLint("RestrictedApi") + public void updateCustomRepoList(boolean initial) { + final SharedPreferences sharedPreferences = Objects.requireNonNull( + this.getPreferenceManager().getSharedPreferences()); + final CustomRepoManager customRepoManager = + RepoManager.getINSTANCE().getCustomRepoManager(); + for (int i = 0; i < CUSTOM_REPO_ENTRIES; i++) { + CustomRepoData repoData = customRepoManager.getRepo(i); + setRepoData(repoData, "pref_custom_repo_" + i); + if (initial) { + Preference preference = + findPreference("pref_custom_repo_" + i + "_delete"); + if (preference == null) continue; + final int index = i; + preference.setOnPreferenceClickListener(preference1 -> { + sharedPreferences.edit().putBoolean( + "pref_custom_repo_" + index + "_enabled", false).apply(); + customRepoManager.removeRepo(index); + updateCustomRepoList(false); + return true; + }); + } + } + Preference preference = findPreference("pref_custom_add_repo"); + if (preference == null) return; + preference.setVisible(customRepoManager.canAddRepo()); + if (initial) { // Custom repo add button part. + preference = findPreference("pref_custom_add_repo_button"); + if (preference == null) return; + preference.setOnPreferenceClickListener(preference1 -> { + final Context context = this.requireContext(); + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context); + final MaterialAutoCompleteTextView input = + new MaterialAutoCompleteTextView(context); + input.setHint(R.string.custom_url); + builder.setTitle(R.string.add_repo); + builder.setView(input); + builder.setPositiveButton("OK", (dialog, which) -> { + String text = String.valueOf(input.getText()); + if (customRepoManager.canAddRepo(text)) { + final CustomRepoData customRepoData = + customRepoManager.addRepo(text); + customRepoData.setEnabled(true); + new Thread("Add Custom Repo Thread") { + @Override + public void run() { + try { + customRepoData.quickPrePopulate(); + } catch (IOException|JSONException e) { + Log.e(TAG, "Failed to preload repo values", e); + } + UiThreadHandler.handler.post(() -> { + updateCustomRepoList(false); + }); + } + }.start(); + } + }); + builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel()); + AlertDialog alertDialog = builder.show(); + final Button positiveButton = + alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); + input.setValidator(new AutoCompleteTextView.Validator() { + @Override + public boolean isValid(CharSequence charSequence) { + return customRepoManager.canAddRepo(charSequence.toString()); + } + + @Override + public CharSequence fixText(CharSequence charSequence) { + return charSequence; + } + }); + input.addTextChangedListener(new TextWatcherAdapter() { + @Override + public void onTextChanged( + @NonNull CharSequence charSequence, int i, int i1, int i2) { + positiveButton.setEnabled(customRepoManager + .canAddRepo(charSequence.toString())); + } + }); + positiveButton.setEnabled(false); + return true; + }); + } } private void setRepoData(String url) { - String preferenceName = "pref_" + RepoManager.internalIdOfUrl(url); + final RepoData repoData = RepoManager.getINSTANCE().get(url); + setRepoData(repoData, "pref_" + (repoData == null ? + RepoManager.internalIdOfUrl(url) : repoData.getPreferenceId())); + } + + private void setRepoData(final RepoData repoData, String preferenceName) { + if (repoData == null) { + hideRepoData(preferenceName); + return; + } Preference preference = findPreference(preferenceName); if (preference == null) return; - final RepoData repoData = RepoManager.getINSTANCE().get(url); - preference.setTitle(repoData == null ? url : repoData.getName()); + preference.setVisible(true); + preference.setTitle(repoData.getName()); preference = findPreference(preferenceName + "_enabled"); if (preference != null) { - if (repoData == null) { - preference.setTitle(R.string.repo_disabled); - preference.setEnabled(false); - } else { - ((TwoStatePreference) preference).setChecked(repoData.isEnabled()); - preference.setTitle(repoData.isEnabled() ? + ((TwoStatePreference) preference).setChecked(repoData.isEnabled()); + preference.setTitle(repoData.isEnabled() ? + R.string.repo_enabled : R.string.repo_disabled); + preference.setOnPreferenceChangeListener((p, newValue) -> { + p.setTitle(((Boolean) newValue) ? R.string.repo_enabled : R.string.repo_disabled); - preference.setOnPreferenceChangeListener((p, newValue) -> { - p.setTitle(((Boolean) newValue) ? - R.string.repo_enabled : R.string.repo_disabled); - return true; - }); - } + return true; + }); } preference = findPreference(preferenceName + "_website"); - String homepage = repoData == null ? null : repoData.getWebsite(); + String homepage = repoData.getWebsite(); if (preference != null) { - if (homepage != null && !homepage.isEmpty()) { + if (!homepage.isEmpty()) { preference.setVisible(true); preference.setOnPreferenceClickListener(p -> { if (homepage.startsWith("https://www.androidacy.com/")) { @@ -287,7 +400,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { } } preference = findPreference(preferenceName + "_support"); - String supportUrl = repoData == null ? null : repoData.getSupport(); + String supportUrl = repoData.getSupport(); if (preference != null) { if (supportUrl != null && !supportUrl.isEmpty()) { preference.setVisible(true); @@ -301,7 +414,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { } } preference = findPreference(preferenceName + "_donate"); - String donateUrl = repoData == null ? null : repoData.getDonate(); + String donateUrl = repoData.getDonate(); if (preference != null) { if (donateUrl != null) { preference.setVisible(true); @@ -315,7 +428,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { } } preference = findPreference(preferenceName + "_submit"); - String submissionUrl = repoData == null ? null : repoData.getSubmitModule(); + String submissionUrl = repoData.getSubmitModule(); if (preference != null) { if (submissionUrl != null && !submissionUrl.isEmpty()) { preference.setVisible(true); @@ -333,5 +446,11 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { } } } + + private void hideRepoData(String preferenceName) { + Preference preference = findPreference(preferenceName); + if (preference == null) return; + preference.setVisible(false); + } } } diff --git a/app/src/main/res/drawable/ic_baseline_add_box_24.xml b/app/src/main/res/drawable/ic_baseline_add_box_24.xml new file mode 100644 index 0000000..bade214 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_add_box_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values/themable.xml b/app/src/main/res/values/themable.xml index 95b5fa6..b744e7b 100644 --- a/app/src/main/res/values/themable.xml +++ b/app/src/main/res/values/themable.xml @@ -1,4 +1,6 @@ + false + false diff --git a/app/src/main/res/xml/repo_preferences.xml b/app/src/main/res/xml/repo_preferences.xml index d55e48a..c354f28 100644 --- a/app/src/main/res/xml/repo_preferences.xml +++ b/app/src/main/res/xml/repo_preferences.xml @@ -66,4 +66,148 @@ app:summary="@string/androidacy_repo_info" app:singleLineTitle="false" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +