From 8ac8ac40b08e2793ce65312ba61f36ab6f4124db Mon Sep 17 00:00:00 2001 From: androidacy-user Date: Thu, 8 Jun 2023 21:50:30 -0400 Subject: [PATCH] various upgrades Signed-off-by: androidacy-user --- .github/workflows/dependencies.yml | 5 +- .../java/com/fox2code/mmm/AppUpdateManager.kt | 44 +- .../java/com/fox2code/mmm/MainActivity.kt | 1298 +++++++++-------- .../mmm/module/ModuleViewListBuilder.kt | 5 +- .../java/com/fox2code/mmm/repo/RepoData.java | 4 +- .../java/com/fox2code/mmm/repo/RepoUpdater.kt | 5 +- .../com/fox2code/mmm/utils/IntentHelper.kt | 2 +- 7 files changed, 724 insertions(+), 639 deletions(-) diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index d859220..21859c5 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -3,9 +3,8 @@ on: push: branches: - master # run the action on your projects default branch - pull_request: - branches: - - master # run the action on your projects default branch + paths-ignore: + - '**.md' jobs: build: diff --git a/app/src/main/java/com/fox2code/mmm/AppUpdateManager.kt b/app/src/main/java/com/fox2code/mmm/AppUpdateManager.kt index 3eace1c..ff94615 100644 --- a/app/src/main/java/com/fox2code/mmm/AppUpdateManager.kt +++ b/app/src/main/java/com/fox2code/mmm/AppUpdateManager.kt @@ -4,12 +4,10 @@ import com.fox2code.mmm.utils.io.Files.Companion.write import com.fox2code.mmm.utils.io.net.Http.Companion.doHttpGet import org.json.JSONObject import timber.log.Timber -import java.io.BufferedReader import java.io.File import java.io.FileInputStream import java.io.IOException import java.io.InputStream -import java.io.InputStreamReader import java.nio.charset.StandardCharsets // See https://docs.github.com/en/rest/reference/repos#releases @@ -96,48 +94,11 @@ class AppUpdateManager private constructor() { return if (!BuildConfig.ENABLE_AUTO_UPDATER || BuildConfig.DEBUG) false else peekShouldUpdate() } + @Suppress("UNUSED_PARAMETER") @Throws(IOException::class) private fun parseCompatibilityFlags(inputStream: InputStream) { compatDataId.clear() - val bufferedReader = BufferedReader(InputStreamReader(inputStream, StandardCharsets.UTF_8)) - var line: String - while (bufferedReader.readLine().also { line = it } != null) { - line = line.trim { it <= ' ' } - if (line.isEmpty() || line.startsWith("#")) continue - val i = line.indexOf('/') - if (i == -1) continue - var value = 0 - for (arg in line.substring(i + 1).split(",".toRegex()).dropLastWhile { it.isEmpty() } - .toTypedArray()) { - when (arg) { - "lowQuality" -> value = value or FLAG_COMPAT_LOW_QUALITY - "noExt" -> value = value or FLAG_COMPAT_NO_EXT - "magiskCmd" -> value = value or FLAG_COMPAT_MAGISK_CMD - "need32bit" -> value = value or FLAG_COMPAT_NEED_32BIT - "malware" -> value = value or FLAG_COMPAT_MALWARE - "noANSI" -> value = value or FLAG_COMPAT_NO_ANSI - "forceANSI" -> value = value or FLAG_COMPAT_FORCE_ANSI - "forceHide" -> value = value or FLAG_COMPAT_FORCE_HIDE - "mmtReborn" -> value = value or FLAG_COMPAT_MMT_REBORN - "wrapper" -> value = value or FLAG_COMPAT_ZIP_WRAPPER - else -> { - run {} - value = value or FLAG_COMPAT_LOW_QUALITY - value = value or FLAG_COMPAT_NO_EXT - value = value or FLAG_COMPAT_MAGISK_CMD - value = value or FLAG_COMPAT_NEED_32BIT - value = value or FLAG_COMPAT_MALWARE - value = value or FLAG_COMPAT_NO_ANSI - value = value or FLAG_COMPAT_FORCE_ANSI - value = value or FLAG_COMPAT_FORCE_HIDE - value = value or FLAG_COMPAT_MMT_REBORN - value = value or FLAG_COMPAT_ZIP_WRAPPER - } - } - } - compatDataId[line.substring(0, i)] = value - } - bufferedReader.close() + Timber.d("Not implemented") } fun getCompatibilityFlags(moduleId: String): Int { @@ -145,6 +106,7 @@ class AppUpdateManager private constructor() { return compatFlags ?: 0 } + @Suppress("MemberVisibilityCanBePrivate") companion object { const val FLAG_COMPAT_LOW_QUALITY = 0x0001 const val FLAG_COMPAT_NO_EXT = 0x0002 diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.kt b/app/src/main/java/com/fox2code/mmm/MainActivity.kt index d4465f8..70e3dee 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.kt +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.kt @@ -1,769 +1,891 @@ -package com.fox2code.mmm; - -import static com.fox2code.mmm.MainApplication.o; -import static com.fox2code.mmm.manager.ModuleInfo.FLAG_MM_REMOTE_MODULE; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Color; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.util.TypedValue; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; -import android.view.inputmethod.EditorInfo; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.SearchView; -import androidx.cardview.widget.CardView; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.fox2code.foxcompat.app.FoxActivity; -import com.fox2code.foxcompat.view.FoxDisplay; -import com.fox2code.mmm.androidacy.AndroidacyRepoData; -import com.fox2code.mmm.background.BackgroundUpdateChecker; -import com.fox2code.mmm.installer.InstallerInitializer; -import com.fox2code.mmm.manager.LocalModuleInfo; -import com.fox2code.mmm.manager.ModuleManager; -import com.fox2code.mmm.module.ModuleViewAdapter; -import com.fox2code.mmm.module.ModuleViewListBuilder; -import com.fox2code.mmm.repo.RepoManager; -import com.fox2code.mmm.repo.RepoModule; -import com.fox2code.mmm.settings.SettingsActivity; -import com.fox2code.mmm.utils.ExternalHelper; -import com.fox2code.mmm.utils.RuntimeUtils; -import com.fox2code.mmm.utils.io.net.Http; -import com.fox2code.mmm.utils.realm.ReposList; -import com.google.android.material.bottomnavigation.BottomNavigationView; -import com.google.android.material.progressindicator.LinearProgressIndicator; - -import org.matomo.sdk.extra.TrackHelper; - -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import io.realm.Realm; -import io.realm.RealmConfiguration; -import timber.log.Timber; - -public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRefreshListener, SearchView.OnQueryTextListener, SearchView.OnCloseListener, OverScrollManager.OverScrollHelper { - private static final int PRECISION = 10000; - public static boolean doSetupNowRunning = true; - public static boolean doSetupRestarting = false; - public static List localModuleInfoList = new ArrayList<>(); - public static List onlineModuleInfoList = new ArrayList<>(); - public final ModuleViewListBuilder moduleViewListBuilder; - public final ModuleViewListBuilder moduleViewListBuilderOnline; - public LinearProgressIndicator progressIndicator; - private ModuleViewAdapter moduleViewAdapter; - private ModuleViewAdapter moduleViewAdapterOnline; - private SwipeRefreshLayout swipeRefreshLayout; - private int swipeRefreshLayoutOrigStartOffset; - private int swipeRefreshLayoutOrigEndOffset; - private long swipeRefreshBlocker = 0; - private int overScrollInsetTop; - private int overScrollInsetBottom; - private RecyclerView moduleList; - private RecyclerView moduleListOnline; - private CardView searchCard; - private SearchView searchView; - private boolean initMode; - private RuntimeUtils runtimeUtils; - public static Boolean isShowingWeblateSb = false; // race condition - - public MainActivity() { - this.moduleViewListBuilder = new ModuleViewListBuilder(this); - this.moduleViewListBuilderOnline = new ModuleViewListBuilder(this); - this.moduleViewListBuilder.addNotification(NotificationType.INSTALL_FROM_STORAGE); +package com.fox2code.mmm + +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import android.content.res.Configuration +import android.graphics.Color +import android.os.Build +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.util.TypedValue +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup.MarginLayoutParams +import android.view.WindowManager +import android.view.animation.AccelerateInterpolator +import android.view.animation.DecelerateInterpolator +import android.view.inputmethod.EditorInfo +import android.widget.Toast +import androidx.appcompat.widget.SearchView +import androidx.cardview.widget.CardView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener +import com.fox2code.foxcompat.app.FoxActivity +import com.fox2code.foxcompat.view.FoxDisplay +import com.fox2code.mmm.AppUpdateManager.Companion.appUpdateManager +import com.fox2code.mmm.OverScrollManager.OverScrollHelper +import com.fox2code.mmm.androidacy.AndroidacyRepoData +import com.fox2code.mmm.background.BackgroundUpdateChecker.Companion.onMainActivityCreate +import com.fox2code.mmm.background.BackgroundUpdateChecker.Companion.onMainActivityResume +import com.fox2code.mmm.installer.InstallerInitializer +import com.fox2code.mmm.installer.InstallerInitializer.Companion.errorNotification +import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekMagiskVersion +import com.fox2code.mmm.installer.InstallerInitializer.Companion.tryGetMagiskPathAsync +import com.fox2code.mmm.manager.LocalModuleInfo +import com.fox2code.mmm.manager.ModuleInfo +import com.fox2code.mmm.manager.ModuleManager.Companion.instance +import com.fox2code.mmm.module.ModuleViewAdapter +import com.fox2code.mmm.module.ModuleViewListBuilder +import com.fox2code.mmm.repo.RepoManager +import com.fox2code.mmm.repo.RepoModule +import com.fox2code.mmm.settings.SettingsActivity +import com.fox2code.mmm.utils.ExternalHelper +import com.fox2code.mmm.utils.RuntimeUtils +import com.fox2code.mmm.utils.io.net.Http.Companion.cleanDnsCache +import com.fox2code.mmm.utils.io.net.Http.Companion.hasWebView +import com.fox2code.mmm.utils.realm.ReposList +import com.google.android.material.bottomnavigation.BottomNavigationView +import com.google.android.material.progressindicator.LinearProgressIndicator +import io.realm.Realm +import io.realm.RealmConfiguration +import org.matomo.sdk.extra.TrackHelper +import timber.log.Timber +import java.sql.Timestamp + +class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextListener, + SearchView.OnCloseListener, OverScrollHelper { + val moduleViewListBuilder: ModuleViewListBuilder = ModuleViewListBuilder(this) + val moduleViewListBuilderOnline: ModuleViewListBuilder = ModuleViewListBuilder(this) + var progressIndicator: LinearProgressIndicator? = null + private var moduleViewAdapter: ModuleViewAdapter? = null + private var moduleViewAdapterOnline: ModuleViewAdapter? = null + private var swipeRefreshLayout: SwipeRefreshLayout? = null + private var swipeRefreshLayoutOrigStartOffset = 0 + private var swipeRefreshLayoutOrigEndOffset = 0 + private var swipeRefreshBlocker: Long = 0 + override var overScrollInsetTop = 0 + private set + override var overScrollInsetBottom = 0 + private set + private var moduleList: RecyclerView? = null + private var moduleListOnline: RecyclerView? = null + private var searchCard: CardView? = null + private var searchView: SearchView? = null + private var initMode = false + private var runtimeUtils: RuntimeUtils? = null + + init { + moduleViewListBuilder.addNotification(NotificationType.INSTALL_FROM_STORAGE) } - @Override - protected void onResume() { - BackgroundUpdateChecker.onMainActivityResume(this); - super.onResume(); + override fun onResume() { + onMainActivityResume(this) + super.onResume() } @SuppressLint("RestrictedApi") - @Override - protected void onCreate(Bundle savedInstanceState) { - this.initMode = true; + override fun onCreate(savedInstanceState: Bundle?) { + initMode = true if (doSetupRestarting) { - doSetupRestarting = false; + doSetupRestarting = false } - BackgroundUpdateChecker.onMainActivityCreate(this); - super.onCreate(savedInstanceState); - TrackHelper.track().screen(this).with(MainApplication.getINSTANCE().getTracker()); + onMainActivityCreate(this) + super.onCreate(savedInstanceState) + TrackHelper.track().screen(this).with(MainApplication.getINSTANCE().tracker) // track enabled repos - RealmConfiguration realmConfig = new RealmConfiguration.Builder().name("ReposList.realm").encryptionKey(MainApplication.getINSTANCE().getKey()).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).allowQueriesOnUiThread(true).allowWritesOnUiThread(true).build(); - Realm realm = Realm.getInstance(realmConfig); - StringBuilder enabledRepos = new StringBuilder(); - realm.executeTransaction(r -> { - for (ReposList r2 : r.where(ReposList.class).equalTo("enabled", true).findAll()) { - enabledRepos.append(r2.getUrl()).append(":").append(r2.getName()).append(","); + val realmConfig = RealmConfiguration.Builder().name("ReposList.realm") + .encryptionKey(MainApplication.getINSTANCE().key) + .directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1) + .allowQueriesOnUiThread(true).allowWritesOnUiThread(true).build() + val realm = Realm.getInstance(realmConfig) + val enabledRepos = StringBuilder() + realm.executeTransaction { r: Realm -> + for (r2 in r.where( + ReposList::class.java + ).equalTo("enabled", true).findAll()) { + enabledRepos.append(r2.url).append(":").append(r2.name).append(",") } - }); - if (enabledRepos.length() > 0) { - enabledRepos.setLength(enabledRepos.length() - 1); } - TrackHelper.track().event("enabled_repos", enabledRepos.toString()).with(MainApplication.getINSTANCE().getTracker()); - realm.close(); + if (enabledRepos.isNotEmpty()) { + enabledRepos.setLength(enabledRepos.length - 1) + } + TrackHelper.track().event("enabled_repos", enabledRepos.toString()) + .with(MainApplication.getINSTANCE().tracker) + realm.close() // hide this behind a buildconfig flag for now, but crash the app if it's not an official build and not debug - if (BuildConfig.ENABLE_PROTECTION && !o && !BuildConfig.DEBUG) { - throw new RuntimeException("This is not an official build of AMM"); - } else if (!o && !BuildConfig.DEBUG) { - Timber.w("You may be running an untrusted build."); + if (BuildConfig.ENABLE_PROTECTION && !MainApplication.o && !BuildConfig.DEBUG) { + throw RuntimeException("This is not an official build of AMM") + } else if (!MainApplication.o && !BuildConfig.DEBUG) { + Timber.w("You may be running an untrusted build.") // Show a toast to warn the user - Toast.makeText(this, R.string.not_official_build, Toast.LENGTH_LONG).show(); + Toast.makeText(this, R.string.not_official_build, Toast.LENGTH_LONG).show() } - Timestamp ts = new Timestamp(System.currentTimeMillis() - (30L * 24 * 60 * 60 * 1000)); + val ts = Timestamp(System.currentTimeMillis() - 30L * 24 * 60 * 60 * 1000) // check if this build has expired - Timestamp buildTime = new Timestamp(BuildConfig.BUILD_TIME); + val buildTime = Timestamp(BuildConfig.BUILD_TIME) // if the build time is more than 30 days ago, throw an exception - if (ts.getTime() >= buildTime.getTime()) { - throw new IllegalStateException("This build has expired. Please download a stable build or update to the latest version."); - } - setContentView(R.layout.activity_main); - this.setTitle(R.string.app_name); + check(ts.time < buildTime.time) { "This build has expired. Please download a stable build or update to the latest version." } + setContentView(R.layout.activity_main) + this.setTitle(R.string.app_name) // set window flags to ignore status bar - this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // ignore status bar space + this.window.setDecorFitsSystemWindows(false) + } else { + @Suppress("DEPRECATION") + this.window.setFlags( + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + ) + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - WindowManager.LayoutParams layoutParams = this.getWindow().getAttributes(); - layoutParams.layoutInDisplayCutoutMode = // Support cutout in Android 9 - WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; - this.getWindow().setAttributes(layoutParams); + val layoutParams = this.window.attributes + layoutParams.layoutInDisplayCutoutMode = // Support cutout in Android 9 + WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES + this.window.attributes = layoutParams } - this.progressIndicator = findViewById(R.id.progress_bar); - this.swipeRefreshLayout = findViewById(R.id.swipe_refresh); - this.swipeRefreshLayoutOrigStartOffset = this.swipeRefreshLayout.getProgressViewStartOffset(); - this.swipeRefreshLayoutOrigEndOffset = this.swipeRefreshLayout.getProgressViewEndOffset(); - this.swipeRefreshBlocker = Long.MAX_VALUE; - this.moduleList = findViewById(R.id.module_list); - this.moduleListOnline = findViewById(R.id.module_list_online); - this.searchCard = findViewById(R.id.search_card); - this.searchView = findViewById(R.id.search_bar); - this.searchView.setIconified(true); - this.moduleViewAdapter = new ModuleViewAdapter(); - this.moduleViewAdapterOnline = new ModuleViewAdapter(); - this.moduleList.setAdapter(this.moduleViewAdapter); - this.moduleListOnline.setAdapter(this.moduleViewAdapterOnline); - this.moduleList.setLayoutManager(new LinearLayoutManager(this)); - this.moduleListOnline.setLayoutManager(new LinearLayoutManager(this)); - this.moduleList.setItemViewCacheSize(4); // Default is 2 - this.swipeRefreshLayout.setOnRefreshListener(this); - this.runtimeUtils = new RuntimeUtils(); + progressIndicator = findViewById(R.id.progress_bar) + swipeRefreshLayout = findViewById(R.id.swipe_refresh) + val swipeRefreshLayout = swipeRefreshLayout!! + swipeRefreshLayoutOrigStartOffset = swipeRefreshLayout.progressViewStartOffset + swipeRefreshLayoutOrigEndOffset = swipeRefreshLayout.progressViewEndOffset + swipeRefreshBlocker = Long.MAX_VALUE + moduleList = findViewById(R.id.module_list) + moduleListOnline = findViewById(R.id.module_list_online) + searchCard = findViewById(R.id.search_card) + searchView = findViewById(R.id.search_bar) + val searchView = searchView!! + searchView.isIconified = true + moduleViewAdapter = ModuleViewAdapter() + moduleViewAdapterOnline = ModuleViewAdapter() + val moduleList = moduleList!! + val moduleListOnline = moduleListOnline!! + moduleList.adapter = moduleViewAdapter + moduleListOnline.adapter = moduleViewAdapterOnline + moduleList.layoutManager = LinearLayoutManager(this) + moduleListOnline.layoutManager = LinearLayoutManager(this) + moduleList.setItemViewCacheSize(4) // Default is 2 + swipeRefreshLayout.setOnRefreshListener(this) + runtimeUtils = RuntimeUtils() // add background blur if enabled - this.updateBlurState(); + updateBlurState() //hideActionBar(); - runtimeUtils.checkShowInitialSetup(this, this); - this.moduleList.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - if (newState != RecyclerView.SCROLL_STATE_IDLE) - MainActivity.this.searchView.clearFocus(); + runtimeUtils!!.checkShowInitialSetup(this, this) + val searchCard = searchCard!! + moduleList.addOnScrollListener(object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + if (newState != RecyclerView.SCROLL_STATE_IDLE) searchView.clearFocus() // hide search view when scrolling if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { - MainActivity.this.searchCard.animate().translationY(-MainActivity.this.searchCard.getHeight()).setInterpolator(new AccelerateInterpolator(2)).start(); + searchCard.animate().translationY(-searchCard.height.toFloat()) + .setInterpolator(AccelerateInterpolator(2f)).start() } } - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + super.onScrolled(recyclerView, dx, dy) // if the user scrolled up, show the search bar if (dy < 0) { - MainActivity.this.searchCard.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start(); + searchCard.animate().translationY(0f) + .setInterpolator(DecelerateInterpolator(2f)).start() } } - }); + }) // same for online - this.moduleListOnline.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - if (newState != RecyclerView.SCROLL_STATE_IDLE) - MainActivity.this.searchView.clearFocus(); + moduleListOnline.addOnScrollListener(object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + if (newState != RecyclerView.SCROLL_STATE_IDLE) searchView.clearFocus() // hide search view when scrolling if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { - MainActivity.this.searchCard.animate().translationY(-MainActivity.this.searchCard.getHeight()).setInterpolator(new AccelerateInterpolator(2)).start(); + searchCard.animate().translationY(-searchCard.height.toFloat()) + .setInterpolator(AccelerateInterpolator(2f)).start() } } - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + super.onScrolled(recyclerView, dx, dy) // if the user scrolled up, show the search bar if (dy < 0) { - MainActivity.this.searchCard.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start(); + searchCard.animate().translationY(0f) + .setInterpolator(DecelerateInterpolator(2f)).start() } } - }); - this.searchCard.setRadius(this.searchCard.getHeight() / 2F); - this.searchView.setMinimumHeight(FoxDisplay.dpToPixel(16)); - this.searchView.setImeOptions(EditorInfo.IME_ACTION_SEARCH | EditorInfo.IME_FLAG_NO_FULLSCREEN); - this.searchView.setOnQueryTextListener(this); - this.searchView.setOnCloseListener(this); - this.searchView.setOnQueryTextFocusChangeListener((v, h) -> { + }) + searchCard.radius = searchCard.height / 2f + searchView.minimumHeight = FoxDisplay.dpToPixel(16f) + searchView.imeOptions = EditorInfo.IME_ACTION_SEARCH or EditorInfo.IME_FLAG_NO_FULLSCREEN + searchView.setOnQueryTextListener(this) + searchView.setOnCloseListener(this) + searchView.setOnQueryTextFocusChangeListener { _: View?, h: Boolean -> if (!h) { - String query = this.searchView.getQuery().toString(); + val query = searchView.query.toString() if (query.isEmpty()) { - this.searchView.setIconified(true); + searchView.isIconified = true } } - this.cardIconifyUpdate(); - }); - this.searchView.setEnabled(false); // Enabled later - this.cardIconifyUpdate(); - this.updateScreenInsets(this.getResources().getConfiguration()); + cardIconifyUpdate() + } + searchView.isEnabled = false // Enabled later + cardIconifyUpdate() + this.updateScreenInsets(this.resources.configuration) // on the bottom nav, there's a settings item. open the settings activity when it's clicked. - BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation); - bottomNavigationView.setOnItemSelectedListener(item -> { - if (item.getItemId() == R.id.settings_menu_item) { - TrackHelper.track().event("view_list", "settings").with(MainApplication.getINSTANCE().getTracker()); - startActivity(new Intent(MainActivity.this, SettingsActivity.class)); - overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); - finish(); - } else if (item.getItemId() == R.id.online_menu_item) { - TrackHelper.track().event("view_list", "online_modules").with(MainApplication.getINSTANCE().getTracker()); - // set module_list_online as visible and module_list as gone. fade in/out - this.moduleListOnline.setAlpha(0F); - this.moduleListOnline.setVisibility(View.VISIBLE); - this.moduleListOnline.animate().alpha(1F).setDuration(300).setListener(null); - this.moduleList.animate().alpha(0F).setDuration(300).setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - MainActivity.this.moduleList.setVisibility(View.GONE); - } - }); - // clear search view - this.searchView.setQuery("", false); - this.searchView.clearFocus(); - } else if (item.getItemId() == R.id.installed_menu_item) { - TrackHelper.track().event("view_list", "installed_modules").with(MainApplication.getINSTANCE().getTracker()); - // set module_list_online as gone and module_list as visible. fade in/out - this.moduleList.setAlpha(0F); - this.moduleList.setVisibility(View.VISIBLE); - this.moduleList.animate().alpha(1F).setDuration(300).setListener(null); - this.moduleListOnline.animate().alpha(0F).setDuration(300).setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - MainActivity.this.moduleListOnline.setVisibility(View.GONE); - } - }); - // set search view to cleared - this.searchView.setQuery("", false); - this.searchView.clearFocus(); + val bottomNavigationView = findViewById(R.id.bottom_navigation) + bottomNavigationView.setOnItemSelectedListener { item: MenuItem -> + when (item.itemId) { + R.id.settings_menu_item -> { + TrackHelper.track().event("view_list", "settings") + .with(MainApplication.getINSTANCE().tracker) + startActivity(Intent(this@MainActivity, SettingsActivity::class.java)) + overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out) + finish() + } + R.id.online_menu_item -> { + TrackHelper.track().event("view_list", "online_modules") + .with(MainApplication.getINSTANCE().tracker) + // set module_list_online as visible and module_list as gone. fade in/out + moduleListOnline.alpha = 0f + moduleListOnline.visibility = View.VISIBLE + moduleListOnline.animate().alpha(1f).setDuration(300).setListener(null) + moduleList.animate().alpha(0f).setDuration(300) + .setListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + moduleList.visibility = View.GONE + } + }) + // clear search view + searchView.setQuery("", false) + searchView.clearFocus() + } + R.id.installed_menu_item -> { + TrackHelper.track().event("view_list", "installed_modules") + .with(MainApplication.getINSTANCE().tracker) + // set module_list_online as gone and module_list as visible. fade in/out + moduleList.alpha = 0f + moduleList.visibility = View.VISIBLE + moduleList.animate().alpha(1f).setDuration(300).setListener(null) + moduleListOnline.animate().alpha(0f).setDuration(300) + .setListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + moduleListOnline.visibility = View.GONE + } + }) + // set search view to cleared + searchView.setQuery("", false) + searchView.clearFocus() + } } - return true; - }); + true + } // update the padding of blur_frame to match the new bottom nav height - View blurFrame = findViewById(R.id.blur_frame); - blurFrame.post(() -> blurFrame.setPadding(blurFrame.getPaddingLeft(), blurFrame.getPaddingTop(), blurFrame.getPaddingRight(), bottomNavigationView.getHeight())); + val blurFrame = findViewById(R.id.blur_frame) + blurFrame.post { + blurFrame.setPadding( + blurFrame.paddingLeft, + blurFrame.paddingTop, + blurFrame.paddingRight, + bottomNavigationView.height + ) + } // for some reason, root_container has a margin at the top. remove it. - View rootContainer = findViewById(R.id.root_container); - rootContainer.post(() -> { - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rootContainer.getLayoutParams(); - params.topMargin = 0; - rootContainer.setLayoutParams(params); - rootContainer.setY(0F); - }); + val rootContainer = findViewById(R.id.root_container) + rootContainer.post { + val params = rootContainer.layoutParams as MarginLayoutParams + params.topMargin = 0 + rootContainer.layoutParams = params + rootContainer.y = 0f + } // reset update module and update module count in main application - MainApplication.getINSTANCE().resetUpdateModule(); - InstallerInitializer.tryGetMagiskPathAsync(new InstallerInitializer.Callback() { - @Override - public void onPathReceived(String path) { - Timber.i("Got magisk path: %s", path); - if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND) - moduleViewListBuilder.addNotification(NotificationType.MAGISK_OUTDATED); - if (!MainApplication.isShowcaseMode()) - moduleViewListBuilder.addNotification(NotificationType.INSTALL_FROM_STORAGE); - Objects.requireNonNull(ModuleManager.getInstance()).scan(); - ModuleManager.getInstance().runAfterScan(moduleViewListBuilder::appendInstalledModules); - ModuleManager.getInstance().runAfterScan(moduleViewListBuilderOnline::appendRemoteModules); - this.commonNext(); + MainApplication.getINSTANCE().resetUpdateModule() + tryGetMagiskPathAsync(object : InstallerInitializer.Callback { + override fun onPathReceived(path: String?) { + Timber.i("Got magisk path: %s", path) + if (peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND) moduleViewListBuilder.addNotification( + NotificationType.MAGISK_OUTDATED + ) + if (!MainApplication.isShowcaseMode()) moduleViewListBuilder.addNotification( + NotificationType.INSTALL_FROM_STORAGE + ) + instance!!.scan() + instance!!.runAfterScan { moduleViewListBuilder.appendInstalledModules() } + instance!!.runAfterScan { moduleViewListBuilderOnline.appendRemoteModules() } + commonNext() } - @Override - public void onFailure(int error) { - Timber.e("Failed to get magisk path!"); - moduleViewListBuilder.addNotification(InstallerInitializer.getErrorNotification()); - moduleViewListBuilderOnline.addNotification(InstallerInitializer.getErrorNotification()); - this.commonNext(); + override fun onFailure(error: Int) { + Timber.e("Failed to get magisk path!") + moduleViewListBuilder.addNotification(errorNotification) + moduleViewListBuilderOnline.addNotification(errorNotification) + commonNext() } - public void commonNext() { + fun commonNext() { if (BuildConfig.DEBUG) { - Timber.d("Common next"); - moduleViewListBuilder.addNotification(NotificationType.DEBUG); + Timber.d("Common next") + moduleViewListBuilder.addNotification(NotificationType.DEBUG) } - NotificationType.NO_INTERNET.autoAdd(moduleViewListBuilderOnline); + NotificationType.NO_INTERNET.autoAdd(moduleViewListBuilderOnline) + val progressIndicator = progressIndicator!! // hide progress bar is repo-manager says we have no internet if (!RepoManager.getINSTANCE().hasConnectivity()) { - Timber.i("No connection, hiding progress"); - runOnUiThread(() -> { - progressIndicator.setVisibility(View.GONE); - progressIndicator.setIndeterminate(false); - progressIndicator.setMax(PRECISION); - }); + Timber.i("No connection, hiding progress") + runOnUiThread { + progressIndicator.visibility = View.GONE + progressIndicator.isIndeterminate = false + progressIndicator.max = PRECISION + } } - updateScreenInsets(); // Fix an edge case - Context context = MainActivity.this; - if (runtimeUtils.waitInitialSetupFinished(context, MainActivity.this)) { - Timber.d("waiting..."); - return; + updateScreenInsets() // Fix an edge case + val context: Context = this@MainActivity + if (runtimeUtils!!.waitInitialSetupFinished(context, this@MainActivity)) { + Timber.d("waiting...") + return } - swipeRefreshBlocker = System.currentTimeMillis() + 5_000L; - if (MainApplication.isShowcaseMode()) - moduleViewListBuilder.addNotification(NotificationType.SHOWCASE_MODE); - if (!Http.hasWebView()) { + swipeRefreshBlocker = System.currentTimeMillis() + 5000L + if (MainApplication.isShowcaseMode()) moduleViewListBuilder.addNotification( + NotificationType.SHOWCASE_MODE + ) + if (!hasWebView()) { // Check Http for WebView availability - moduleViewListBuilder.addNotification(NotificationType.NO_WEB_VIEW); + moduleViewListBuilder.addNotification(NotificationType.NO_WEB_VIEW) // disable online tab - runOnUiThread(() -> { - bottomNavigationView.getMenu().getItem(1).setEnabled(false); - bottomNavigationView.setSelectedItemId(R.id.installed_menu_item); - }); + runOnUiThread { + bottomNavigationView.menu.getItem(1).isEnabled = false + bottomNavigationView.selectedItemId = R.id.installed_menu_item + } } - moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter); - - Timber.i("Scanning for modules!"); - if (BuildConfig.DEBUG) Timber.i("Initialize Update"); - final int max = Objects.requireNonNull(ModuleManager.getInstance()).getUpdatableModuleCount(); - if (RepoManager.getINSTANCE().getCustomRepoManager() != null && RepoManager.getINSTANCE().getCustomRepoManager().needUpdate()) { - Timber.w("Need update on create"); - } else if (RepoManager.getINSTANCE().getCustomRepoManager() == null) { - Timber.w("CustomRepoManager is null"); + moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter!!) + Timber.i("Scanning for modules!") + if (BuildConfig.DEBUG) Timber.i("Initialize Update") + val max = instance!!.getUpdatableModuleCount() + if (RepoManager.getINSTANCE().customRepoManager != null && RepoManager.getINSTANCE().customRepoManager.needUpdate()) { + Timber.w("Need update on create") + } else if (RepoManager.getINSTANCE().customRepoManager == null) { + Timber.w("CustomRepoManager is null") } // update compat metadata - if (BuildConfig.DEBUG) Timber.i("Check Update Compat"); - AppUpdateManager.Companion.getAppUpdateManager().checkUpdateCompat(); - if (BuildConfig.DEBUG) Timber.i("Check Update"); + if (BuildConfig.DEBUG) Timber.i("Check Update Compat") + appUpdateManager.checkUpdateCompat() + if (BuildConfig.DEBUG) Timber.i("Check Update") // update repos - if (Http.hasWebView()) { - RepoManager.getINSTANCE().update(value -> runOnUiThread(max == 0 ? () -> progressIndicator.setProgressCompat((int) (value * PRECISION), true) : () -> progressIndicator.setProgressCompat((int) (value * PRECISION * 0.75F), true))); + if (hasWebView()) { + RepoManager.getINSTANCE().update { value: Double -> + runOnUiThread(if (max == 0) Runnable { + progressIndicator.setProgressCompat( + (value * PRECISION).toInt(), + true + ) + } else Runnable { + progressIndicator.setProgressCompat( + (value * PRECISION * 0.75f).toInt(), + true + ) + }) + } } // various notifications - NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilder); - NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilderOnline); - NotificationType.DEBUG.autoAdd(moduleViewListBuilder); - NotificationType.DEBUG.autoAdd(moduleViewListBuilderOnline); - if (Http.hasWebView() && !NotificationType.REPO_UPDATE_FAILED.shouldRemove()) { - moduleViewListBuilder.addNotification(NotificationType.REPO_UPDATE_FAILED); + NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilder) + NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilderOnline) + NotificationType.DEBUG.autoAdd(moduleViewListBuilder) + NotificationType.DEBUG.autoAdd(moduleViewListBuilderOnline) + if (hasWebView() && !NotificationType.REPO_UPDATE_FAILED.shouldRemove()) { + moduleViewListBuilder.addNotification(NotificationType.REPO_UPDATE_FAILED) } else { - if (!Http.hasWebView()) { - runOnUiThread(() -> { - progressIndicator.setProgressCompat(PRECISION, true); - progressIndicator.setVisibility(View.GONE); - searchView.setEnabled(false); - updateScreenInsets(getResources().getConfiguration()); - }); - return; + if (!hasWebView()) { + runOnUiThread { + progressIndicator.setProgressCompat(PRECISION, true) + progressIndicator.visibility = View.GONE + searchView.isEnabled = false + updateScreenInsets(resources.configuration) + } + return } // Compatibility data still needs to be updated - AppUpdateManager appUpdateManager = AppUpdateManager.Companion.getAppUpdateManager(); - if (BuildConfig.DEBUG) Timber.i("Check App Update"); - if (BuildConfig.ENABLE_AUTO_UPDATER && appUpdateManager.checkUpdate(true)) - moduleViewListBuilder.addNotification(NotificationType.UPDATE_AVAILABLE); - if (BuildConfig.DEBUG) Timber.i("Check Json Update"); + val appUpdateManager = appUpdateManager + if (BuildConfig.DEBUG) Timber.i("Check App Update") + if (BuildConfig.ENABLE_AUTO_UPDATER && appUpdateManager.checkUpdate(true)) moduleViewListBuilder.addNotification( + NotificationType.UPDATE_AVAILABLE + ) + if (BuildConfig.DEBUG) Timber.i("Check Json Update") if (max != 0) { - int current = 0; - for (LocalModuleInfo localModuleInfo : ModuleManager.getInstance().getModules().values()) { + var current = 0 + for (localModuleInfo in instance!!.modules.values) { // if it has updateJson and FLAG_MM_REMOTE_MODULE is not set on flags, check for json update // this is a dirty hack until we better store if it's a remote module // the reasoning is that remote repos are considered "validated" while local modules are not // for instance, a potential attacker could hijack a perfectly legitimate module and inject an updateJson with a malicious update - thereby bypassing any checks repos may have, without anyone noticing until it's too late - if (localModuleInfo.updateJson != null && (localModuleInfo.flags & FLAG_MM_REMOTE_MODULE) == 0) { - if (BuildConfig.DEBUG) Timber.i(localModuleInfo.id); + if (localModuleInfo.updateJson != null && localModuleInfo.flags and ModuleInfo.FLAG_MM_REMOTE_MODULE == 0) { + if (BuildConfig.DEBUG) Timber.i(localModuleInfo.id) try { - localModuleInfo.checkModuleUpdate(); - } catch (Exception e) { - Timber.e(e); + localModuleInfo.checkModuleUpdate() + } catch (e: Exception) { + Timber.e(e) + } + current++ + val currentTmp = current + runOnUiThread { + progressIndicator.setProgressCompat( + (1f * currentTmp / max * PRECISION * 0.25f + PRECISION * 0.75f).toInt(), + true + ) } - current++; - final int currentTmp = current; - runOnUiThread(() -> progressIndicator.setProgressCompat((int) ((1F * currentTmp / max) * PRECISION * 0.25F + (PRECISION * 0.75F)), true)); } } } } - if (BuildConfig.DEBUG) Timber.i("Apply"); - RepoManager.getINSTANCE().runAfterUpdate(moduleViewListBuilderOnline::appendRemoteModules); - moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter); - moduleViewListBuilder.applyTo(moduleListOnline, moduleViewAdapterOnline); - moduleViewListBuilderOnline.applyTo(moduleListOnline, moduleViewAdapterOnline); + if (BuildConfig.DEBUG) Timber.i("Apply") + RepoManager.getINSTANCE() + .runAfterUpdate { moduleViewListBuilderOnline.appendRemoteModules() } + moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter!!) + moduleViewListBuilder.applyTo(moduleListOnline, moduleViewAdapterOnline!!) + moduleViewListBuilderOnline.applyTo(moduleListOnline, moduleViewAdapterOnline!!) // if moduleViewListBuilderOnline has the upgradeable notification, show a badge on the online repo nav item if (MainApplication.getINSTANCE().modulesHaveUpdates) { - Timber.i("Applying badge"); - new Handler(Looper.getMainLooper()).post(() -> { - final var badge = bottomNavigationView.getOrCreateBadge(R.id.online_menu_item); - badge.setVisible(true); - badge.setNumber(MainApplication.getINSTANCE().updateModuleCount); - badge.applyTheme(MainApplication.getInitialApplication().getTheme()); - Timber.i("Badge applied"); - }); + Timber.i("Applying badge") + Handler(Looper.getMainLooper()).post { + val badge = bottomNavigationView.getOrCreateBadge(R.id.online_menu_item) + badge.isVisible = true + badge.number = MainApplication.getINSTANCE().updateModuleCount + badge.applyTheme(MainApplication.getInitialApplication().theme) + Timber.i("Badge applied") + } } - runOnUiThread(() -> { - progressIndicator.setProgressCompat(PRECISION, true); - progressIndicator.setVisibility(View.GONE); - searchView.setEnabled(true); - updateScreenInsets(getResources().getConfiguration()); - }); - maybeShowUpgrade(); - Timber.i("Finished app opening state!"); + runOnUiThread { + progressIndicator.setProgressCompat(PRECISION, true) + progressIndicator.visibility = View.GONE + searchView.isEnabled = true + updateScreenInsets(resources.configuration) + } + maybeShowUpgrade() + Timber.i("Finished app opening state!") } - }, true); + }, true) // if system lang is not in MainApplication.supportedLocales, show a snackbar to ask user to help translate - if (!MainApplication.supportedLocales.contains(this.getResources().getConfiguration().getLocales().get(0).getLanguage())) { + if (!MainApplication.supportedLocales.contains(this.resources.configuration.locales[0].language)) { // call showWeblateSnackbar() with language code and language name - runtimeUtils.showWeblateSnackbar(this, this, this.getResources().getConfiguration().getLocales().get(0).getLanguage(), this.getResources().getConfiguration().getLocales().get(0).getDisplayLanguage()); + runtimeUtils!!.showWeblateSnackbar( + this, + this, + this.resources.configuration.locales[0].language, + this.resources.configuration.locales[0].displayLanguage + ) } - ExternalHelper.INSTANCE.refreshHelper(this); - this.initMode = false; + ExternalHelper.INSTANCE.refreshHelper(this) + initMode = false // add preference listener to set isMatomoAllowed - SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, key) -> { - if (key.equals("pref_analytics_enabled")) { - MainApplication.getINSTANCE().isMatomoAllowed = sharedPreferences.getBoolean(key, false); - MainApplication.getINSTANCE().getTracker().setOptOut(MainApplication.getINSTANCE().isMatomoAllowed); - Timber.d("Matomo is allowed change: %s", MainApplication.getINSTANCE().isMatomoAllowed); - } - if (MainApplication.getINSTANCE().isMatomoAllowed) { - String value = sharedPreferences.getString(key, null); - // then log - if (value != null) { - TrackHelper.track().event("pref_changed", key + "=" + value).with(MainApplication.getINSTANCE().getTracker()); + val listener = + OnSharedPreferenceChangeListener { sharedPreferences: SharedPreferences, key: String -> + if (key == "pref_analytics_enabled") { + MainApplication.getINSTANCE().isMatomoAllowed = + sharedPreferences.getBoolean(key, false) + MainApplication.getINSTANCE().tracker.isOptOut = + MainApplication.getINSTANCE().isMatomoAllowed + Timber.d( + "Matomo is allowed change: %s", + MainApplication.getINSTANCE().isMatomoAllowed + ) + } + if (MainApplication.getINSTANCE().isMatomoAllowed) { + val value = sharedPreferences.getString(key, null) + // then log + if (value != null) { + TrackHelper.track().event("pref_changed", "$key=$value") + .with(MainApplication.getINSTANCE().tracker) + } } + Timber.d("Preference changed: %s", key) } - Timber.d("Preference changed: %s", key); - }; - MainApplication.getSharedPreferences("mmm").registerOnSharedPreferenceChangeListener(listener); + MainApplication.getSharedPreferences("mmm") + .registerOnSharedPreferenceChangeListener(listener) } - private void cardIconifyUpdate() { - boolean iconified = this.searchView.isIconified(); - int backgroundAttr = iconified ? MainApplication.isMonetEnabled() ? com.google.android.material.R.attr.colorSecondaryContainer : // Monet is special... - com.google.android.material.R.attr.colorSecondary : com.google.android.material.R.attr.colorPrimarySurface; - Resources.Theme theme = this.searchCard.getContext().getTheme(); - TypedValue value = new TypedValue(); - theme.resolveAttribute(backgroundAttr, value, true); - this.searchCard.setCardBackgroundColor(value.data); - this.searchCard.setAlpha(iconified ? 0.80F : 1F); + private fun cardIconifyUpdate() { + val iconified = searchView!!.isIconified + val backgroundAttr = + if (iconified) if (MainApplication.isMonetEnabled()) com.google.android.material.R.attr.colorSecondaryContainer else // Monet is special... + com.google.android.material.R.attr.colorSecondary else com.google.android.material.R.attr.colorPrimarySurface + val theme = searchCard!!.context.theme + val value = TypedValue() + theme.resolveAttribute(backgroundAttr, value, true) + searchCard!!.setCardBackgroundColor(value.data) + searchCard!!.alpha = if (iconified) 0.80f else 1f } - public void updateScreenInsets() { - this.runOnUiThread(() -> this.updateScreenInsets(this.getResources().getConfiguration())); + fun updateScreenInsets() { + runOnUiThread { this.updateScreenInsets(this.resources.configuration) } } - private void updateScreenInsets(Configuration configuration) { - boolean landscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE; - int bottomInset = (landscape ? 0 : this.getNavigationBarHeight()); - int statusBarHeight = getStatusBarHeight() + FoxDisplay.dpToPixel(2); - this.swipeRefreshLayout.setProgressViewOffset(false, swipeRefreshLayoutOrigStartOffset + statusBarHeight, swipeRefreshLayoutOrigEndOffset + statusBarHeight); - this.moduleViewListBuilder.setHeaderPx(statusBarHeight); - this.moduleViewListBuilderOnline.setHeaderPx(statusBarHeight); - this.moduleViewListBuilder.setFooterPx(FoxDisplay.dpToPixel(4) + bottomInset + this.searchCard.getHeight()); - this.moduleViewListBuilderOnline.setFooterPx(FoxDisplay.dpToPixel(4) + bottomInset + this.searchCard.getHeight()); - this.searchCard.setRadius(this.searchCard.getHeight() / 2F); - this.moduleViewListBuilder.updateInsets(); + private fun updateScreenInsets(configuration: Configuration) { + val landscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + val bottomInset = if (landscape) 0 else this.navigationBarHeight + val statusBarHeight = statusBarHeight + FoxDisplay.dpToPixel(2f) + swipeRefreshLayout!!.setProgressViewOffset( + false, + swipeRefreshLayoutOrigStartOffset + statusBarHeight, + swipeRefreshLayoutOrigEndOffset + statusBarHeight + ) + moduleViewListBuilder.setHeaderPx(statusBarHeight) + moduleViewListBuilderOnline.setHeaderPx(statusBarHeight) + moduleViewListBuilder.setFooterPx(FoxDisplay.dpToPixel(4f) + bottomInset + searchCard!!.height) + moduleViewListBuilderOnline.setFooterPx(FoxDisplay.dpToPixel(4f) + bottomInset + searchCard!!.height) + searchCard!!.radius = searchCard!!.height / 2f + moduleViewListBuilder.updateInsets() //this.actionBarBlur.invalidate(); - this.overScrollInsetTop = statusBarHeight; - this.overScrollInsetBottom = bottomInset; + overScrollInsetTop = statusBarHeight + overScrollInsetBottom = bottomInset // set root_container to have zero padding - findViewById(R.id.root_container).setPadding(0, statusBarHeight, 0, 0); + findViewById(R.id.root_container).setPadding(0, statusBarHeight, 0, 0) } - private void updateBlurState() { + private fun updateBlurState() { if (MainApplication.isBlurEnabled()) { // set bottom navigation bar color to transparent blur - BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation); + val bottomNavigationView = findViewById(R.id.bottom_navigation) if (bottomNavigationView != null) { - bottomNavigationView.setBackgroundColor(Color.TRANSPARENT); - bottomNavigationView.setAlpha(0.8F); + bottomNavigationView.setBackgroundColor(Color.TRANSPARENT) + bottomNavigationView.alpha = 0.8f } else { - Timber.w("Bottom navigation view not found"); + Timber.w("Bottom navigation view not found") } // set dialogs to have transparent blur - getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); + window.addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND) } } - @Override - public void refreshUI() { - super.refreshUI(); - if (this.initMode) return; - this.initMode = true; - Timber.i("Item Before"); - this.searchView.setQuery("", false); - this.searchView.clearFocus(); - this.searchView.setIconified(true); - this.cardIconifyUpdate(); - this.updateScreenInsets(); - this.updateBlurState(); - this.moduleViewListBuilder.setQuery(null); - Timber.i("Item After"); - this.moduleViewListBuilder.refreshNotificationsUI(this.moduleViewAdapter); - InstallerInitializer.tryGetMagiskPathAsync(new InstallerInitializer.Callback() { - @Override - public void onPathReceived(String path) { - Context context = MainActivity.this; - MainActivity mainActivity = MainActivity.this; - runtimeUtils.checkShowInitialSetup(context, mainActivity); + override fun refreshUI() { + super.refreshUI() + if (initMode) return + initMode = true + Timber.i("Item Before") + searchView!!.setQuery("", false) + searchView!!.clearFocus() + searchView!!.isIconified = true + cardIconifyUpdate() + this.updateScreenInsets() + updateBlurState() + moduleViewListBuilder.setQuery(null) + Timber.i("Item After") + moduleViewListBuilder.refreshNotificationsUI(moduleViewAdapter!!) + tryGetMagiskPathAsync(object : InstallerInitializer.Callback { + override fun onPathReceived(path: String?) { + val context: Context = this@MainActivity + val mainActivity = this@MainActivity + runtimeUtils!!.checkShowInitialSetup(context, mainActivity) // Wait for doSetupNow to finish while (doSetupNowRunning) { try { - //noinspection BusyWait - Thread.sleep(100); - } catch (InterruptedException ignored) { - Thread.currentThread().interrupt(); + Thread.sleep(100) + } catch (ignored: InterruptedException) { + Thread.currentThread().interrupt() } } - if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND) - moduleViewListBuilder.addNotification(NotificationType.MAGISK_OUTDATED); - if (!MainApplication.isShowcaseMode()) - moduleViewListBuilder.addNotification(NotificationType.INSTALL_FROM_STORAGE); - Objects.requireNonNull(ModuleManager.getInstance()).scan(); - ModuleManager.getInstance().runAfterScan(moduleViewListBuilder::appendInstalledModules); - this.commonNext(); + if (peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND) moduleViewListBuilder.addNotification( + NotificationType.MAGISK_OUTDATED + ) + if (!MainApplication.isShowcaseMode()) moduleViewListBuilder.addNotification( + NotificationType.INSTALL_FROM_STORAGE + ) + instance!!.scan() + instance!!.runAfterScan { moduleViewListBuilder.appendInstalledModules() } + commonNext() } - @Override - public void onFailure(int error) { - Timber.e("Error: %s", error); - moduleViewListBuilder.addNotification(InstallerInitializer.getErrorNotification()); - moduleViewListBuilderOnline.addNotification(InstallerInitializer.getErrorNotification()); - this.commonNext(); + override fun onFailure(error: Int) { + Timber.e("Error: %s", error) + moduleViewListBuilder.addNotification(errorNotification) + moduleViewListBuilderOnline.addNotification(errorNotification) + commonNext() } - public void commonNext() { - Timber.i("Common Before"); - if (MainApplication.isShowcaseMode()) - moduleViewListBuilder.addNotification(NotificationType.SHOWCASE_MODE); - NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilderOnline); - NotificationType.NO_INTERNET.autoAdd(moduleViewListBuilderOnline); - if (AppUpdateManager.Companion.getAppUpdateManager().checkUpdate(false)) - moduleViewListBuilder.addNotification(NotificationType.UPDATE_AVAILABLE); - RepoManager.getINSTANCE().updateEnabledStates(); - if (RepoManager.getINSTANCE().getCustomRepoManager().needUpdate()) { - runOnUiThread(() -> { - progressIndicator.setIndeterminate(false); - progressIndicator.setMax(PRECISION); - }); - if (BuildConfig.DEBUG) Timber.i("Check Update"); - RepoManager.getINSTANCE().update(value -> runOnUiThread(() -> progressIndicator.setProgressCompat((int) (value * PRECISION), true))); - runOnUiThread(() -> { - progressIndicator.setProgressCompat(PRECISION, true); - progressIndicator.setVisibility(View.GONE); - }); + fun commonNext() { + Timber.i("Common Before") + if (MainApplication.isShowcaseMode()) moduleViewListBuilder.addNotification( + NotificationType.SHOWCASE_MODE + ) + NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilderOnline) + NotificationType.NO_INTERNET.autoAdd(moduleViewListBuilderOnline) + if (appUpdateManager.checkUpdate(false)) moduleViewListBuilder.addNotification( + NotificationType.UPDATE_AVAILABLE + ) + RepoManager.getINSTANCE().updateEnabledStates() + if (RepoManager.getINSTANCE().customRepoManager.needUpdate()) { + runOnUiThread { + progressIndicator!!.isIndeterminate = false + progressIndicator!!.max = PRECISION + } + if (BuildConfig.DEBUG) Timber.i("Check Update") + RepoManager.getINSTANCE().update { value: Double -> + runOnUiThread { + progressIndicator!!.setProgressCompat( + (value * PRECISION).toInt(), + true + ) + } + } + runOnUiThread { + progressIndicator!!.setProgressCompat(PRECISION, true) + progressIndicator!!.visibility = View.GONE + } } - if (BuildConfig.DEBUG) Timber.i("Apply"); - RepoManager.getINSTANCE().runAfterUpdate(moduleViewListBuilderOnline::appendRemoteModules); - Timber.i("Common Before applyTo"); - moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter); - moduleViewListBuilderOnline.applyTo(moduleListOnline, moduleViewAdapterOnline); - Timber.i("Common After"); + if (BuildConfig.DEBUG) Timber.i("Apply") + RepoManager.getINSTANCE() + .runAfterUpdate { moduleViewListBuilderOnline.appendRemoteModules() } + Timber.i("Common Before applyTo") + moduleViewListBuilder.applyTo(moduleList!!, moduleViewAdapter!!) + moduleViewListBuilderOnline.applyTo(moduleListOnline!!, moduleViewAdapterOnline!!) + Timber.i("Common After") } - }); - this.initMode = false; + }) + initMode = false } - @Override - protected void onWindowUpdated() { - this.updateScreenInsets(); + override fun onWindowUpdated() { + this.updateScreenInsets() } - @Override - public void onRefresh() { - if (this.swipeRefreshBlocker > System.currentTimeMillis() || this.initMode || this.progressIndicator == null || this.progressIndicator.getVisibility() == View.VISIBLE || doSetupNowRunning) { - this.swipeRefreshLayout.setRefreshing(false); - return; // Do not double scan + override fun onRefresh() { + if (swipeRefreshBlocker > System.currentTimeMillis() || initMode || progressIndicator == null || progressIndicator!!.visibility == View.VISIBLE || doSetupNowRunning) { + swipeRefreshLayout!!.isRefreshing = false + return // Do not double scan } - if (BuildConfig.DEBUG) Timber.i("Refresh"); - this.progressIndicator.setVisibility(View.VISIBLE); - this.progressIndicator.setProgressCompat(0, false); - this.swipeRefreshBlocker = System.currentTimeMillis() + 5_000L; + if (BuildConfig.DEBUG) Timber.i("Refresh") + progressIndicator!!.visibility = View.VISIBLE + progressIndicator!!.setProgressCompat(0, false) + swipeRefreshBlocker = System.currentTimeMillis() + 5000L // this.swipeRefreshLayout.setRefreshing(true); ?? - new Thread(() -> { - Http.cleanDnsCache(); // Allow DNS reload from network - final int max = Objects.requireNonNull(ModuleManager.getInstance()).getUpdatableModuleCount(); - RepoManager.getINSTANCE().update(value -> runOnUiThread(max == 0 ? () -> progressIndicator.setProgressCompat((int) (value * PRECISION), true) : () -> progressIndicator.setProgressCompat((int) (value * PRECISION * 0.75F), true))); - NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilder); + Thread({ + cleanDnsCache() // Allow DNS reload from network + val max = instance!!.getUpdatableModuleCount() + RepoManager.getINSTANCE().update { value: Double -> + runOnUiThread(if (max == 0) Runnable { + progressIndicator!!.setProgressCompat( + (value * PRECISION).toInt(), + true + ) + } else Runnable { + progressIndicator!!.setProgressCompat( + (value * PRECISION * 0.75f).toInt(), + true + ) + }) + } + NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilder) if (!NotificationType.NO_INTERNET.shouldRemove()) { - moduleViewListBuilderOnline.addNotification(NotificationType.NO_INTERNET); + moduleViewListBuilderOnline.addNotification(NotificationType.NO_INTERNET) } else if (!NotificationType.REPO_UPDATE_FAILED.shouldRemove()) { - moduleViewListBuilder.addNotification(NotificationType.REPO_UPDATE_FAILED); + moduleViewListBuilder.addNotification(NotificationType.REPO_UPDATE_FAILED) } else { // Compatibility data still needs to be updated - AppUpdateManager appUpdateManager = AppUpdateManager.Companion.getAppUpdateManager(); - if (BuildConfig.DEBUG) Timber.i("Check App Update"); - if (BuildConfig.ENABLE_AUTO_UPDATER && appUpdateManager.checkUpdate(true)) - moduleViewListBuilder.addNotification(NotificationType.UPDATE_AVAILABLE); - if (BuildConfig.DEBUG) Timber.i("Check Json Update"); + val appUpdateManager = appUpdateManager + if (BuildConfig.DEBUG) Timber.i("Check App Update") + if (BuildConfig.ENABLE_AUTO_UPDATER && appUpdateManager.checkUpdate(true)) moduleViewListBuilder.addNotification( + NotificationType.UPDATE_AVAILABLE + ) + if (BuildConfig.DEBUG) Timber.i("Check Json Update") if (max != 0) { - int current = 0; - for (LocalModuleInfo localModuleInfo : ModuleManager.getInstance().getModules().values()) { - if (localModuleInfo.updateJson != null && (localModuleInfo.flags & FLAG_MM_REMOTE_MODULE) == 0) { - if (BuildConfig.DEBUG) Timber.i(localModuleInfo.id); + var current = 0 + for (localModuleInfo in instance!!.modules.values) { + if (localModuleInfo.updateJson != null && localModuleInfo.flags and ModuleInfo.FLAG_MM_REMOTE_MODULE == 0) { + if (BuildConfig.DEBUG) Timber.i(localModuleInfo.id) try { - localModuleInfo.checkModuleUpdate(); - } catch (Exception e) { - Timber.e(e); + localModuleInfo.checkModuleUpdate() + } catch (e: Exception) { + Timber.e(e) + } + current++ + val currentTmp = current + runOnUiThread { + progressIndicator!!.setProgressCompat( + (1f * currentTmp / max * PRECISION * 0.25f + PRECISION * 0.75f).toInt(), + true + ) } - current++; - final int currentTmp = current; - runOnUiThread(() -> progressIndicator.setProgressCompat((int) ((1F * currentTmp / max) * PRECISION * 0.25F + (PRECISION * 0.75F)), true)); } } } } - if (BuildConfig.DEBUG) Timber.i("Apply"); - runOnUiThread(() -> { - this.progressIndicator.setVisibility(View.GONE); - this.swipeRefreshLayout.setRefreshing(false); - }); - NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilder); - RepoManager.getINSTANCE().updateEnabledStates(); - RepoManager.getINSTANCE().runAfterUpdate(moduleViewListBuilder::appendInstalledModules); - RepoManager.getINSTANCE().runAfterUpdate(moduleViewListBuilderOnline::appendRemoteModules); - this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter); - this.moduleViewListBuilderOnline.applyTo(moduleListOnline, moduleViewAdapterOnline); - }, "Repo update thread").start(); + if (BuildConfig.DEBUG) Timber.i("Apply") + runOnUiThread { + progressIndicator!!.visibility = View.GONE + swipeRefreshLayout!!.isRefreshing = false + } + NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilder) + RepoManager.getINSTANCE().updateEnabledStates() + RepoManager.getINSTANCE() + .runAfterUpdate { moduleViewListBuilder.appendInstalledModules() } + RepoManager.getINSTANCE() + .runAfterUpdate { moduleViewListBuilderOnline.appendRemoteModules() } + moduleViewListBuilder.applyTo(moduleList!!, moduleViewAdapter!!) + moduleViewListBuilderOnline.applyTo(moduleListOnline!!, moduleViewAdapterOnline!!) + }, "Repo update thread").start() } - @Override - public boolean onQueryTextSubmit(final String query) { - this.searchView.clearFocus(); - if (this.initMode) return false; - TrackHelper.track().search(query).with(MainApplication.getINSTANCE().getTracker()); - if (this.moduleViewListBuilder.setQueryChange(query)) { - Timber.i("Query submit: %s on offline list", query); - new Thread(() -> this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter), "Query update thread").start(); + override fun onQueryTextSubmit(query: String): Boolean { + searchView!!.clearFocus() + if (initMode) return false + TrackHelper.track().search(query).with(MainApplication.getINSTANCE().tracker) + if (moduleViewListBuilder.setQueryChange(query)) { + Timber.i("Query submit: %s on offline list", query) + Thread( + { moduleViewListBuilder.applyTo(moduleList!!, moduleViewAdapter!!) }, + "Query update thread" + ).start() } // same for online list - if (this.moduleViewListBuilderOnline.setQueryChange(query)) { - Timber.i("Query submit: %s on online list", query); - new Thread(() -> this.moduleViewListBuilderOnline.applyTo(moduleListOnline, moduleViewAdapterOnline), "Query update thread").start(); + if (moduleViewListBuilderOnline.setQueryChange(query)) { + Timber.i("Query submit: %s on online list", query) + Thread({ + moduleViewListBuilderOnline.applyTo( + moduleListOnline!!, + moduleViewAdapterOnline!! + ) + }, "Query update thread").start() } - return true; + return true } - @Override - public boolean onQueryTextChange(String query) { - if (this.initMode) return false; - TrackHelper.track().search(query).with(MainApplication.getINSTANCE().getTracker()); - if (this.moduleViewListBuilder.setQueryChange(query)) { - Timber.i("Query submit: %s on offline list", query); - new Thread(() -> this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter), "Query update thread").start(); + override fun onQueryTextChange(query: String): Boolean { + if (initMode) return false + TrackHelper.track().search(query).with(MainApplication.getINSTANCE().tracker) + if (moduleViewListBuilder.setQueryChange(query)) { + Timber.i("Query submit: %s on offline list", query) + Thread( + { moduleViewListBuilder.applyTo(moduleList!!, moduleViewAdapter!!) }, + "Query update thread" + ).start() } // same for online list - if (this.moduleViewListBuilderOnline.setQueryChange(query)) { - Timber.i("Query submit: %s on online list", query); - new Thread(() -> this.moduleViewListBuilderOnline.applyTo(moduleListOnline, moduleViewAdapterOnline), "Query update thread").start(); + if (moduleViewListBuilderOnline.setQueryChange(query)) { + Timber.i("Query submit: %s on online list", query) + Thread({ + moduleViewListBuilderOnline.applyTo( + moduleListOnline!!, + moduleViewAdapterOnline!! + ) + }, "Query update thread").start() } - return false; + return false } - @Override - public boolean onClose() { - if (this.initMode) return false; - if (this.moduleViewListBuilder.setQueryChange(null)) { - new Thread(() -> this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter), "Query update thread").start(); + override fun onClose(): Boolean { + if (initMode) return false + if (moduleViewListBuilder.setQueryChange(null)) { + Thread( + { moduleViewListBuilder.applyTo(moduleList!!, moduleViewAdapter!!) }, + "Query update thread" + ).start() } // same for online list - if (this.moduleViewListBuilderOnline.setQueryChange(null)) { - new Thread(() -> this.moduleViewListBuilderOnline.applyTo(moduleListOnline, moduleViewAdapterOnline), "Query update thread").start(); + if (moduleViewListBuilderOnline.setQueryChange(null)) { + Thread({ + moduleViewListBuilderOnline.applyTo( + moduleListOnline!!, + moduleViewAdapterOnline!! + ) + }, "Query update thread").start() } - return false; - } - - @Override - public int getOverScrollInsetTop() { - return this.overScrollInsetTop; + return false } - @Override - public int getOverScrollInsetBottom() { - return this.overScrollInsetBottom; + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + this.updateScreenInsets() } - @Override - public void onConfigurationChanged(@NonNull Configuration newConfig) { - super.onConfigurationChanged(newConfig); - this.updateScreenInsets(); + override fun onWindowFocusChanged(hasFocus: Boolean) { + super.onWindowFocusChanged(hasFocus) + this.updateScreenInsets() } - @Override - public void onWindowFocusChanged(boolean hasFocus) { - super.onWindowFocusChanged(hasFocus); - this.updateScreenInsets(); - } - - - - public void maybeShowUpgrade() { + fun maybeShowUpgrade() { if (AndroidacyRepoData.getInstance() == null || AndroidacyRepoData.getInstance().memberLevel == null) { // wait for up to 10 seconds for AndroidacyRepoData to be initialized - int i = 0; + var i = 0 while (AndroidacyRepoData.getInstance() == null && i < 10) { try { - //noinspection BusyWait - Thread.sleep(1000); - } catch (InterruptedException e) { - Timber.e(e); + Thread.sleep(1000) + } catch (e: InterruptedException) { + Timber.e(e) } - i++; + i++ } - if (AndroidacyRepoData.getInstance().isEnabled() && AndroidacyRepoData.getInstance().memberLevel == null) { - Timber.d("Member level is null, waiting for it to be initialized"); - i = 0; + if (AndroidacyRepoData.getInstance() + .isEnabled && AndroidacyRepoData.getInstance().memberLevel == null + ) { + Timber.d("Member level is null, waiting for it to be initialized") + i = 0 while (AndroidacyRepoData.getInstance().memberLevel == null && i < 20) { - i++; + i++ try { - //noinspection BusyWait - Thread.sleep(500); - } catch (InterruptedException e) { - Timber.e(e); + Thread.sleep(500) + } catch (e: InterruptedException) { + Timber.e(e) } } } // if it's still null, but it's enabled, throw an error - if (AndroidacyRepoData.getInstance().isEnabled() && AndroidacyRepoData.getInstance().memberLevel == null) { - Timber.e("AndroidacyRepoData is enabled, but member level is null"); + if (AndroidacyRepoData.getInstance() + .isEnabled && AndroidacyRepoData.getInstance().memberLevel == null + ) { + Timber.e("AndroidacyRepoData is enabled, but member level is null") } - if (AndroidacyRepoData.getInstance() != null && AndroidacyRepoData.getInstance().isEnabled() && Objects.equals(AndroidacyRepoData.getInstance().memberLevel, "Guest")) { - runtimeUtils.showUpgradeSnackbar(this, this); + if (AndroidacyRepoData.getInstance() != null && AndroidacyRepoData.getInstance() + .isEnabled && AndroidacyRepoData.getInstance().memberLevel == "Guest" + ) { + runtimeUtils!!.showUpgradeSnackbar(this, this) } else { - if (!AndroidacyRepoData.getInstance().isEnabled()) { - Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 1"); - } else if (!Objects.equals(AndroidacyRepoData.getInstance().memberLevel, "Guest")) { - Timber.i("AndroidacyRepoData is not Guest, not showing upgrade snackbar 1. Level: %s", AndroidacyRepoData.getInstance().memberLevel); + if (!AndroidacyRepoData.getInstance().isEnabled) { + Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 1") + } else if (AndroidacyRepoData.getInstance().memberLevel != "Guest") { + Timber.i( + "AndroidacyRepoData is not Guest, not showing upgrade snackbar 1. Level: %s", + AndroidacyRepoData.getInstance().memberLevel + ) } else { - Timber.i("Unknown error, not showing upgrade snackbar 1"); + Timber.i("Unknown error, not showing upgrade snackbar 1") } } - } else if (AndroidacyRepoData.getInstance().isEnabled() && Objects.equals(AndroidacyRepoData.getInstance().memberLevel, "Guest")) { - runtimeUtils.showUpgradeSnackbar(this, this); + } else if (AndroidacyRepoData.getInstance() + .isEnabled && AndroidacyRepoData.getInstance().memberLevel == "Guest" + ) { + runtimeUtils!!.showUpgradeSnackbar(this, this) } else { - if (!AndroidacyRepoData.getInstance().isEnabled()) { - Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 2"); - } else if (!Objects.equals(AndroidacyRepoData.getInstance().memberLevel, "Guest")) { - Timber.i("AndroidacyRepoData is not Guest, not showing upgrade snackbar 2. Level: %s", AndroidacyRepoData.getInstance().memberLevel); + if (!AndroidacyRepoData.getInstance().isEnabled) { + Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 2") + } else if (AndroidacyRepoData.getInstance().memberLevel != "Guest") { + Timber.i( + "AndroidacyRepoData is not Guest, not showing upgrade snackbar 2. Level: %s", + AndroidacyRepoData.getInstance().memberLevel + ) } else { - Timber.i("Unknown error, not showing upgrade snackbar 2"); + Timber.i("Unknown error, not showing upgrade snackbar 2") } } } -} + + companion object { + fun getFoxActivity(activity: FoxActivity): FoxActivity { + return activity + } + + fun getFoxActivity(context: Context): FoxActivity { + return context as FoxActivity + } + + private const val PRECISION = 10000 + @JvmField + var doSetupNowRunning = true + var doSetupRestarting = false + var localModuleInfoList: List = ArrayList() + var onlineModuleInfoList: List = ArrayList() + var isShowingWeblateSb = false // race condition + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fox2code/mmm/module/ModuleViewListBuilder.kt b/app/src/main/java/com/fox2code/mmm/module/ModuleViewListBuilder.kt index da0aba2..75f9acb 100644 --- a/app/src/main/java/com/fox2code/mmm/module/ModuleViewListBuilder.kt +++ b/app/src/main/java/com/fox2code/mmm/module/ModuleViewListBuilder.kt @@ -50,7 +50,7 @@ class ModuleViewListBuilder(private val activity: Activity) { Timber.i("A1: %s", moduleManager.modules.size) for (moduleInfo in moduleManager.modules.values) { // add the local module to the list in MainActivity - MainActivity.localModuleInfoList.add(moduleInfo) + MainActivity.localModuleInfoList += moduleInfo var moduleHolder = mappedModuleHolders[moduleInfo.id] if (moduleHolder == null) { mappedModuleHolders[moduleInfo.id] = ModuleHolder(moduleInfo.id).also { @@ -78,8 +78,9 @@ class ModuleViewListBuilder(private val activity: Activity) { val no32bitSupport = Build.SUPPORTED_32_BIT_ABIS.isEmpty() for (repoModule in repoManager.modules.values) { // add the remote module to the list in MainActivity - MainActivity.onlineModuleInfoList.add(repoModule) + MainActivity.onlineModuleInfoList += repoModule // if repoData is null, something is wrong + @Suppress("SENSELESS_COMPARISON") if (repoModule.repoData == null) { Timber.w("RepoData is null for module %s", repoModule.id) continue 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 74020b2..5c6d624 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoData.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoData.java @@ -103,7 +103,7 @@ public class RepoData extends XRepo { this.metaDataCache = null; this.moduleHashMap = new HashMap<>(); this.defaultName = url; // Set url as default name - this.forceHide = AppUpdateManager.shouldForceHide(this.id); + this.forceHide = AppUpdateManager.Companion.shouldForceHide(getPreferenceId()); // this.enable is set from the database RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").encryptionKey(MainApplication.getINSTANCE().getKey()).allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); Realm realm = Realm.getInstance(realmConfiguration); @@ -334,7 +334,7 @@ public class RepoData extends XRepo { return; } // if repo starts with repo_, it's always enabled bc custom repos can't be disabled without being deleted. - this.forceHide = AppUpdateManager.shouldForceHide(this.id); + this.forceHide = AppUpdateManager.Companion.shouldForceHide(getPreferenceId()); // reposlist realm RealmConfiguration realmConfiguration2 = new RealmConfiguration.Builder().name("ReposList.realm").encryptionKey(MainApplication.getINSTANCE().getKey()).allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); Realm realm2 = Realm.getInstance(realmConfiguration2); diff --git a/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.kt b/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.kt index b3c61da..02c4c83 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.kt +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.kt @@ -12,9 +12,10 @@ import timber.log.Timber import java.nio.charset.StandardCharsets import java.util.concurrent.atomic.AtomicBoolean -class RepoUpdater(val repoData2: RepoData) { +class RepoUpdater(repoData2: RepoData) { private var indexRaw: ByteArray? = null - @JvmField public var repoData: RepoData = repoData2 + @JvmField + var repoData: RepoData = repoData2 private var toUpdate: List? = null private var toApply: Collection? = null fun fetchIndex(): Int { diff --git a/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.kt b/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.kt index 686d42a..48d2f84 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.kt +++ b/app/src/main/java/com/fox2code/mmm/utils/IntentHelper.kt @@ -445,7 +445,7 @@ enum class IntentHelper {; openFileTo(compatActivity!!, destination, object : OnFileReceivedCallback { override fun onReceived(target: File?, uri: Uri?, response: Int) { if (response == RESPONSE_ERROR) { - MainActivity.getFoxActivity(compatActivity)?.runOnUiThread { + MainActivity.getFoxActivity(compatActivity).runOnUiThread { Toast.makeText( compatActivity, R.string.no_file_provided, Toast.LENGTH_SHORT ).show()