finish room and kotlin migration
SettingsActivity.java cannot be converted right now because AS crashes silently Signed-off-by: androidacy-user <opensource@androidacy.com>pull/89/head
parent
0b05dfe29b
commit
743cd3f46d
@ -0,0 +1,142 @@
|
|||||||
|
{
|
||||||
|
"formatVersion": 1,
|
||||||
|
"database": {
|
||||||
|
"version": 1,
|
||||||
|
"identityHash": "2abfd2dad332c887d96cdda63d92a639",
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"tableName": "modulelistcache",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`codename` TEXT NOT NULL, `version` TEXT NOT NULL, `versionCode` INTEGER NOT NULL, `author` TEXT NOT NULL, `description` TEXT NOT NULL, `minApi` INTEGER NOT NULL, `maxApi` INTEGER NOT NULL, `minMagisk` INTEGER NOT NULL, `needRamdisk` INTEGER NOT NULL, `support` TEXT NOT NULL, `donate` TEXT NOT NULL, `config` TEXT NOT NULL, `changeBoot` INTEGER NOT NULL, `mmtReborn` INTEGER NOT NULL, `repoId` TEXT NOT NULL, `lastUpdate` INTEGER NOT NULL, `name` TEXT NOT NULL, `safe` INTEGER NOT NULL, `stats` INTEGER NOT NULL, PRIMARY KEY(`codename`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "codename",
|
||||||
|
"columnName": "codename",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "version",
|
||||||
|
"columnName": "version",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "versionCode",
|
||||||
|
"columnName": "versionCode",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "author",
|
||||||
|
"columnName": "author",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "description",
|
||||||
|
"columnName": "description",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "minApi",
|
||||||
|
"columnName": "minApi",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "maxApi",
|
||||||
|
"columnName": "maxApi",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "minMagisk",
|
||||||
|
"columnName": "minMagisk",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "needRamdisk",
|
||||||
|
"columnName": "needRamdisk",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "support",
|
||||||
|
"columnName": "support",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "donate",
|
||||||
|
"columnName": "donate",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "config",
|
||||||
|
"columnName": "config",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "changeBoot",
|
||||||
|
"columnName": "changeBoot",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "mmtReborn",
|
||||||
|
"columnName": "mmtReborn",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "repoId",
|
||||||
|
"columnName": "repoId",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "lastUpdate",
|
||||||
|
"columnName": "lastUpdate",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "name",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "safe",
|
||||||
|
"columnName": "safe",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "stats",
|
||||||
|
"columnName": "stats",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"autoGenerate": false,
|
||||||
|
"columnNames": [
|
||||||
|
"codename"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"views": [],
|
||||||
|
"setupQueries": [
|
||||||
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2abfd2dad332c887d96cdda63d92a639')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"formatVersion": 1,
|
||||||
|
"database": {
|
||||||
|
"version": 1,
|
||||||
|
"identityHash": "5a217dbf3caa5a6b70e7eee98636866c",
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"tableName": "ReposList",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `url` TEXT NOT NULL, `enabled` INTEGER NOT NULL, `donate` TEXT, `support` TEXT, `submitModule` TEXT, `lastUpdate` INTEGER NOT NULL, `name` TEXT NOT NULL, `website` TEXT, PRIMARY KEY(`id`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "id",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "url",
|
||||||
|
"columnName": "url",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "enabled",
|
||||||
|
"columnName": "enabled",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "donate",
|
||||||
|
"columnName": "donate",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "support",
|
||||||
|
"columnName": "support",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "submitModule",
|
||||||
|
"columnName": "submitModule",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "lastUpdate",
|
||||||
|
"columnName": "lastUpdate",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "name",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "website",
|
||||||
|
"columnName": "website",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"autoGenerate": false,
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"views": [],
|
||||||
|
"setupQueries": [
|
||||||
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5a217dbf3caa5a6b70e7eee98636866c')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
@ -1,376 +1,430 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
||||||
*/
|
*/
|
||||||
|
package com.fox2code.mmm.module
|
||||||
|
|
||||||
package com.fox2code.mmm.module;
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.net.Uri
|
||||||
|
import android.text.Spanned
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import com.fox2code.foxcompat.app.FoxActivity
|
||||||
|
import com.fox2code.foxcompat.view.FoxDisplay
|
||||||
|
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
|
||||||
|
import com.fox2code.mmm.MainApplication.Companion.isShowcaseMode
|
||||||
|
import com.fox2code.mmm.R
|
||||||
|
import com.fox2code.mmm.androidacy.AndroidacyUtil.Companion.isAndroidacyLink
|
||||||
|
import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekMagiskPath
|
||||||
|
import com.fox2code.mmm.manager.ModuleInfo
|
||||||
|
import com.fox2code.mmm.manager.ModuleManager.Companion.instance
|
||||||
|
import com.fox2code.mmm.utils.ExternalHelper
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openConfig
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openCustomTab
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openInstaller
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openMarkdown
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openUrl
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openUrlAndroidacy
|
||||||
|
import com.google.android.material.chip.Chip
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
import org.matomo.sdk.extra.TrackHelper
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.util.Objects
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
@Suppress("SENSELESS_COMPARISON")
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.text.Spanned;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
|
|
||||||
import com.fox2code.foxcompat.app.FoxActivity;
|
|
||||||
import com.fox2code.foxcompat.view.FoxDisplay;
|
|
||||||
import com.fox2code.mmm.MainApplication;
|
|
||||||
import com.fox2code.mmm.R;
|
|
||||||
import com.fox2code.mmm.androidacy.AndroidacyUtil;
|
|
||||||
import com.fox2code.mmm.installer.InstallerInitializer;
|
|
||||||
import com.fox2code.mmm.manager.LocalModuleInfo;
|
|
||||||
import com.fox2code.mmm.manager.ModuleInfo;
|
|
||||||
import com.fox2code.mmm.manager.ModuleManager;
|
|
||||||
import com.fox2code.mmm.utils.ExternalHelper;
|
|
||||||
import com.fox2code.mmm.utils.IntentHelper;
|
|
||||||
import com.google.android.material.chip.Chip;
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
||||||
|
|
||||||
import org.matomo.sdk.extra.TrackHelper;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import io.noties.markwon.Markwon;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
@SuppressWarnings("ReplaceNullCheck")
|
|
||||||
@SuppressLint("UseCompatLoadingForDrawables")
|
@SuppressLint("UseCompatLoadingForDrawables")
|
||||||
public enum ActionButtonType {
|
enum class ActionButtonType {
|
||||||
INFO() {
|
INFO {
|
||||||
@Override
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
button.chipIcon = button.context.getDrawable(R.drawable.ic_baseline_info_24)
|
||||||
button.setChipIcon(button.getContext().getDrawable(R.drawable.ic_baseline_info_24));
|
button.setText(R.string.description)
|
||||||
button.setText(R.string.description);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
String name;
|
moduleHolder.moduleInfo!!.name
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("view_notes", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("view_notes", name).with(INSTANCE!!.getTracker())
|
||||||
String notesUrl = moduleHolder.repoModule.notesUrl;
|
val notesUrl = moduleHolder.repoModule?.notesUrl
|
||||||
if (AndroidacyUtil.Companion.isAndroidacyLink(notesUrl)) {
|
if (isAndroidacyLink(notesUrl)) {
|
||||||
IntentHelper.openUrlAndroidacy(button.getContext(), notesUrl, false, moduleHolder.repoModule.moduleInfo.name, moduleHolder.getMainModuleConfig());
|
openUrlAndroidacy(
|
||||||
|
button.context,
|
||||||
|
notesUrl,
|
||||||
|
false,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.name,
|
||||||
|
moduleHolder.mainModuleConfig
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
IntentHelper.openMarkdown(button.getContext(), notesUrl, moduleHolder.repoModule.moduleInfo.name, moduleHolder.getMainModuleConfig(), moduleHolder.repoModule.moduleInfo.changeBoot, moduleHolder.repoModule.moduleInfo.needRamdisk, moduleHolder.repoModule.moduleInfo.minMagisk, moduleHolder.repoModule.moduleInfo.minApi, moduleHolder.repoModule.moduleInfo.maxApi);
|
openMarkdown(
|
||||||
|
button.context,
|
||||||
|
notesUrl,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.name,
|
||||||
|
moduleHolder.mainModuleConfig,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.changeBoot,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.needRamdisk,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.minMagisk ?: 0,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.minApi ?: 0,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.maxApi ?: 9999
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doActionLong(button: Chip, moduleHolder: ModuleHolder): Boolean {
|
||||||
public boolean doActionLong(Chip button, ModuleHolder moduleHolder) {
|
val context = button.context
|
||||||
Context context = button.getContext();
|
Toast.makeText(
|
||||||
Toast.makeText(context, context.getString(R.string.module_id_prefix) + moduleHolder.moduleId, Toast.LENGTH_SHORT).show();
|
context,
|
||||||
return true;
|
context.getString(R.string.module_id_prefix) + moduleHolder.moduleId,
|
||||||
}
|
Toast.LENGTH_SHORT
|
||||||
}, UPDATE_INSTALL() {
|
).show()
|
||||||
@Override
|
return true
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
}
|
||||||
int icon;
|
},
|
||||||
|
UPDATE_INSTALL {
|
||||||
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
|
val icon: Int
|
||||||
if (moduleHolder.hasUpdate()) {
|
if (moduleHolder.hasUpdate()) {
|
||||||
icon = R.drawable.ic_baseline_update_24;
|
icon = R.drawable.ic_baseline_update_24
|
||||||
button.setText(R.string.update);
|
button.setText(R.string.update)
|
||||||
} else if (moduleHolder.moduleInfo != null) {
|
} else if (moduleHolder.moduleInfo != null) {
|
||||||
icon = R.drawable.ic_baseline_refresh_24;
|
icon = R.drawable.ic_baseline_refresh_24
|
||||||
button.setText(R.string.reinstall);
|
button.setText(R.string.reinstall)
|
||||||
} else {
|
} else {
|
||||||
icon = R.drawable.ic_baseline_system_update_24;
|
icon = R.drawable.ic_baseline_system_update_24
|
||||||
button.setText(R.string.install);
|
button.setText(R.string.install)
|
||||||
}
|
}
|
||||||
button.setChipIcon(button.getContext().getDrawable(icon));
|
button.chipIcon = button.context.getDrawable(icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
// if mainmoduleinfo is null, we are in repo mode
|
||||||
ModuleInfo moduleInfo = moduleHolder.getMainModuleInfo();
|
val moduleInfo: ModuleInfo = if (moduleHolder.mainModuleInfo != null) {
|
||||||
if (moduleInfo == null) return;
|
moduleHolder.mainModuleInfo
|
||||||
|
|
||||||
String name;
|
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo ?: return
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("view_update_install", name).with(MainApplication.getINSTANCE().getTracker());
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
|
moduleHolder.moduleInfo!!.name
|
||||||
|
} else {
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
|
}
|
||||||
|
TrackHelper.track().event("view_update_install", name).with(INSTANCE!!.getTracker())
|
||||||
// if icon is reinstall, we need to uninstall first - warn the user but don't proceed
|
// if icon is reinstall, we need to uninstall first - warn the user but don't proceed
|
||||||
if (moduleHolder.moduleInfo != null) {
|
if (moduleHolder.moduleInfo != null) {
|
||||||
// get icon of the button
|
// get icon of the button
|
||||||
Drawable icon = button.getChipIcon();
|
val icon = button.chipIcon
|
||||||
if (icon != null && icon.getConstantState() != null) {
|
if (icon != null && icon.constantState != null) {
|
||||||
Drawable reinstallIcon = button.getContext().getDrawable(R.drawable.ic_baseline_refresh_24);
|
val reinstallIcon =
|
||||||
if (reinstallIcon != null && reinstallIcon.getConstantState() != null) {
|
button.context.getDrawable(R.drawable.ic_baseline_refresh_24)
|
||||||
if (icon.getConstantState().equals(reinstallIcon.getConstantState())) {
|
if (reinstallIcon != null && reinstallIcon.constantState != null) {
|
||||||
new MaterialAlertDialogBuilder(button.getContext())
|
if (icon.constantState == reinstallIcon.constantState) {
|
||||||
|
MaterialAlertDialogBuilder(button.context)
|
||||||
.setTitle(R.string.reinstall)
|
.setTitle(R.string.reinstall)
|
||||||
.setMessage(R.string.reinstall_warning)
|
.setMessage(R.string.reinstall_warning)
|
||||||
.setPositiveButton(R.string.reinstall, null)
|
.setPositiveButton(R.string.reinstall, null)
|
||||||
.show();
|
.show()
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String updateZipUrl = moduleHolder.getUpdateZipUrl();
|
val updateZipUrl = moduleHolder.updateZipUrl ?: return
|
||||||
if (updateZipUrl == null) return;
|
|
||||||
// Androidacy manage the selection between download and install
|
// Androidacy manage the selection between download and install
|
||||||
if (AndroidacyUtil.Companion.isAndroidacyLink(updateZipUrl)) {
|
if (isAndroidacyLink(updateZipUrl)) {
|
||||||
IntentHelper.openUrlAndroidacy(button.getContext(), updateZipUrl, true, moduleInfo.name, moduleInfo.config);
|
openUrlAndroidacy(
|
||||||
return;
|
button.context,
|
||||||
}
|
updateZipUrl,
|
||||||
boolean hasRoot = InstallerInitializer.peekMagiskPath() != null && !MainApplication.Companion.isShowcaseMode();
|
true,
|
||||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(button.getContext());
|
moduleInfo.name,
|
||||||
builder.setTitle(moduleInfo.name).setCancelable(true).setIcon(R.drawable.ic_baseline_extension_24);
|
moduleInfo.config
|
||||||
CharSequence desc = moduleInfo.description;
|
)
|
||||||
Markwon markwon = null;
|
return
|
||||||
LocalModuleInfo localModuleInfo = moduleHolder.moduleInfo;
|
}
|
||||||
if (localModuleInfo != null && !localModuleInfo.updateChangeLog.isEmpty()) {
|
val hasRoot = peekMagiskPath() != null && !isShowcaseMode
|
||||||
markwon = MainApplication.getINSTANCE().getMarkwon();
|
val builder = MaterialAlertDialogBuilder(button.context)
|
||||||
|
builder.setTitle(moduleInfo.name).setCancelable(true)
|
||||||
|
.setIcon(R.drawable.ic_baseline_extension_24)
|
||||||
|
var desc: CharSequence? = moduleInfo.description
|
||||||
|
var markwon: Markwon? = null
|
||||||
|
val localModuleInfo = moduleHolder.moduleInfo
|
||||||
|
if (localModuleInfo != null && localModuleInfo.updateChangeLog.isNotEmpty()) {
|
||||||
|
markwon = INSTANCE!!.getMarkwon()
|
||||||
// Re-render each time in cse of config changes
|
// Re-render each time in cse of config changes
|
||||||
desc = markwon.toMarkdown(localModuleInfo.updateChangeLog);
|
desc = markwon!!.toMarkdown(localModuleInfo.updateChangeLog)
|
||||||
}
|
}
|
||||||
|
if (desc.isNullOrEmpty()) {
|
||||||
if (desc == null || desc.length() == 0) {
|
builder.setMessage(R.string.no_desc_found)
|
||||||
builder.setMessage(R.string.no_desc_found);
|
|
||||||
} else {
|
} else {
|
||||||
builder.setMessage(desc);
|
builder.setMessage(desc)
|
||||||
}
|
}
|
||||||
Timber.i("URL: %s", updateZipUrl);
|
Timber.i("URL: %s", updateZipUrl)
|
||||||
builder.setNegativeButton(R.string.download_module, (x, y) -> IntentHelper.openCustomTab(button.getContext(), updateZipUrl));
|
builder.setNegativeButton(R.string.download_module) { _: DialogInterface?, _: Int ->
|
||||||
if (hasRoot) {
|
openCustomTab(
|
||||||
builder.setPositiveButton(moduleHolder.hasUpdate() ? R.string.update_module : R.string.install_module, (x, y) -> {
|
button.context,
|
||||||
String updateZipChecksum = moduleHolder.getUpdateZipChecksum();
|
updateZipUrl
|
||||||
IntentHelper.openInstaller(button.getContext(), updateZipUrl, moduleInfo.name, moduleInfo.config, updateZipChecksum, moduleInfo.mmtReborn);
|
)
|
||||||
});
|
|
||||||
}
|
}
|
||||||
ExternalHelper.INSTANCE.injectButton(builder, () -> Uri.parse(updateZipUrl), moduleHolder.getUpdateZipRepo());
|
if (hasRoot) {
|
||||||
int dim5dp = FoxDisplay.dpToPixel(5);
|
builder.setPositiveButton(if (moduleHolder.hasUpdate()) R.string.update_module else R.string.install_module) { _: DialogInterface?, _: Int ->
|
||||||
builder.setBackgroundInsetStart(dim5dp).setBackgroundInsetEnd(dim5dp);
|
val updateZipChecksum = moduleHolder.updateZipChecksum
|
||||||
AlertDialog alertDialog = builder.show();
|
openInstaller(
|
||||||
for (int i = -3; i < 0; i++) {
|
button.context,
|
||||||
Button alertButton = alertDialog.getButton(i);
|
updateZipUrl,
|
||||||
if (alertButton != null && alertButton.getPaddingStart() > dim5dp) {
|
moduleInfo.name,
|
||||||
alertButton.setPadding(dim5dp, dim5dp, dim5dp, dim5dp);
|
moduleInfo.config,
|
||||||
|
updateZipChecksum,
|
||||||
|
moduleInfo.mmtReborn
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExternalHelper.INSTANCE.injectButton(
|
||||||
|
builder,
|
||||||
|
{ Uri.parse(updateZipUrl) },
|
||||||
|
moduleHolder.updateZipRepo
|
||||||
|
)
|
||||||
|
val dim5dp = FoxDisplay.dpToPixel(5f)
|
||||||
|
builder.setBackgroundInsetStart(dim5dp).setBackgroundInsetEnd(dim5dp)
|
||||||
|
val alertDialog = builder.show()
|
||||||
|
for (i in -3..-1) {
|
||||||
|
val alertButton = alertDialog.getButton(i)
|
||||||
|
if (alertButton != null && alertButton.paddingStart > dim5dp) {
|
||||||
|
alertButton.setPadding(dim5dp, dim5dp, dim5dp, dim5dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (markwon != null) {
|
if (markwon != null) {
|
||||||
TextView messageView = Objects.requireNonNull(alertDialog.getWindow()).findViewById(android.R.id.message);
|
val messageView = alertDialog.window!!.findViewById<TextView>(android.R.id.message)
|
||||||
markwon.setParsedMarkdown(messageView, (Spanned) desc);
|
markwon.setParsedMarkdown(messageView, (desc as Spanned?)!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, UNINSTALL() {
|
},
|
||||||
@Override
|
UNINSTALL {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
int icon = moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UNINSTALLING) ? R.drawable.ic_baseline_delete_outline_24 : (!moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UPDATING) || moduleHolder.hasFlag(ModuleInfo.FLAGS_MODULE_ACTIVE)) ? R.drawable.ic_baseline_delete_24 : R.drawable.ic_baseline_delete_forever_24;
|
val icon =
|
||||||
button.setChipIcon(button.getContext().getDrawable(icon));
|
if (moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UNINSTALLING)) R.drawable.ic_baseline_delete_outline_24 else if (!moduleHolder.hasFlag(
|
||||||
button.setText(R.string.uninstall);
|
ModuleInfo.FLAG_MODULE_UPDATING
|
||||||
|
) || moduleHolder.hasFlag(ModuleInfo.FLAGS_MODULE_ACTIVE)
|
||||||
|
) R.drawable.ic_baseline_delete_24 else R.drawable.ic_baseline_delete_forever_24
|
||||||
|
button.chipIcon = button.context.getDrawable(icon)
|
||||||
|
button.setText(R.string.uninstall)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
if (!moduleHolder.hasFlag(ModuleInfo.FLAGS_MODULE_ACTIVE or ModuleInfo.FLAG_MODULE_UNINSTALLING) && moduleHolder.hasFlag(
|
||||||
if (!moduleHolder.hasFlag(ModuleInfo.FLAGS_MODULE_ACTIVE | ModuleInfo.FLAG_MODULE_UNINSTALLING) && moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UPDATING)) {
|
ModuleInfo.FLAG_MODULE_UPDATING
|
||||||
doActionLong(button, moduleHolder);
|
)
|
||||||
return;
|
) {
|
||||||
}
|
doActionLong(button, moduleHolder)
|
||||||
String name;
|
return
|
||||||
if (moduleHolder.moduleInfo != null) {
|
}
|
||||||
name = moduleHolder.moduleInfo.name;
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
|
moduleHolder.moduleInfo!!.name
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("uninstall_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("uninstall_module", name).with(INSTANCE!!.getTracker())
|
||||||
Timber.i(Integer.toHexString(moduleHolder.moduleInfo.flags));
|
Timber.i(Integer.toHexString(moduleHolder.moduleInfo?.flags ?: 0))
|
||||||
if (!Objects.requireNonNull(ModuleManager.getInstance()).setUninstallState(moduleHolder.moduleInfo, !moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UNINSTALLING))) {
|
if (!instance!!.setUninstallState(
|
||||||
Timber.e("Failed to switch uninstalled state!");
|
moduleHolder.moduleInfo!!, !moduleHolder.hasFlag(
|
||||||
|
ModuleInfo.FLAG_MODULE_UNINSTALLING
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Timber.e("Failed to switch uninstalled state!")
|
||||||
}
|
}
|
||||||
update(button, moduleHolder);
|
update(button, moduleHolder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doActionLong(button: Chip, moduleHolder: ModuleHolder): Boolean {
|
||||||
public boolean doActionLong(Chip button, ModuleHolder moduleHolder) {
|
if (moduleHolder.moduleInfo == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// Actually a module having mount is the only issue when deleting module
|
// Actually a module having mount is the only issue when deleting module
|
||||||
if (moduleHolder.moduleInfo.hasFlag(ModuleInfo.FLAG_MODULE_HAS_ACTIVE_MOUNT))
|
if (moduleHolder.moduleInfo!!.hasFlag(ModuleInfo.FLAG_MODULE_HAS_ACTIVE_MOUNT)) return false // We can't trust active flag on first boot
|
||||||
return false; // We can't trust active flag on first boot
|
val builder = MaterialAlertDialogBuilder(button.context)
|
||||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(button.getContext());
|
builder.setTitle(R.string.master_delete)
|
||||||
builder.setTitle(R.string.master_delete);
|
builder.setPositiveButton(R.string.master_delete_yes) { _: DialogInterface?, _: Int ->
|
||||||
builder.setPositiveButton(R.string.master_delete_yes, (dialog, which) -> {
|
val moduleId = moduleHolder.moduleInfo!!.id
|
||||||
String moduleId = moduleHolder.moduleInfo.id;
|
if (!instance!!.masterClear(moduleHolder.moduleInfo!!)) {
|
||||||
if (!Objects.requireNonNull(ModuleManager.getInstance()).masterClear(moduleHolder.moduleInfo)) {
|
Toast.makeText(button.context, R.string.master_delete_fail, Toast.LENGTH_SHORT)
|
||||||
Toast.makeText(button.getContext(), R.string.master_delete_fail, Toast.LENGTH_SHORT).show();
|
.show()
|
||||||
} else {
|
} else {
|
||||||
moduleHolder.moduleInfo = null;
|
moduleHolder.moduleInfo = null
|
||||||
FoxActivity.getFoxActivity(button).refreshUI();
|
FoxActivity.getFoxActivity(button).refreshUI()
|
||||||
Timber.e("Cleared: %s", moduleId);
|
Timber.e("Cleared: %s", moduleId)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
builder.setNegativeButton(R.string.master_delete_no, (v, i) -> {
|
builder.setNegativeButton(R.string.master_delete_no) { _: DialogInterface?, _: Int -> }
|
||||||
});
|
builder.create()
|
||||||
builder.create();
|
builder.show()
|
||||||
builder.show();
|
return true
|
||||||
return true;
|
}
|
||||||
}
|
},
|
||||||
}, CONFIG() {
|
CONFIG {
|
||||||
@Override
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
button.chipIcon =
|
||||||
button.setChipIcon(button.getContext().getDrawable(R.drawable.ic_baseline_app_settings_alt_24));
|
button.context.getDrawable(R.drawable.ic_baseline_app_settings_alt_24)
|
||||||
button.setText(R.string.config);
|
button.setText(R.string.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
if (moduleHolder.moduleInfo == null) {
|
||||||
String config = moduleHolder.getMainModuleConfig();
|
return
|
||||||
if (config == null) return;
|
}
|
||||||
|
val config = moduleHolder.mainModuleConfig ?: return
|
||||||
String name;
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
if (moduleHolder.moduleInfo != null) {
|
moduleHolder.moduleInfo!!.name
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("config_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("config_module", name).with(INSTANCE!!.getTracker())
|
||||||
if (AndroidacyUtil.Companion.isAndroidacyLink(config)) {
|
if (isAndroidacyLink(config)) {
|
||||||
IntentHelper.openUrlAndroidacy(button.getContext(), config, true);
|
openUrlAndroidacy(button.context, config, true)
|
||||||
} else {
|
} else {
|
||||||
IntentHelper.openConfig(button.getContext(), config);
|
openConfig(button.context, config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, SUPPORT() {
|
},
|
||||||
@Override
|
SUPPORT {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
ModuleInfo moduleInfo = moduleHolder.getMainModuleInfo();
|
val moduleInfo = moduleHolder.mainModuleInfo
|
||||||
button.setChipIcon(button.getContext().getDrawable(supportIconForUrl(moduleInfo.support)));
|
button.chipIcon = button.context.getDrawable(
|
||||||
button.setText(R.string.support);
|
supportIconForUrl(moduleInfo.support)
|
||||||
|
)
|
||||||
|
button.setText(R.string.support)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
|
moduleHolder.moduleInfo!!.name
|
||||||
String name;
|
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("support_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("support_module", name).with(INSTANCE!!.getTracker())
|
||||||
IntentHelper.Companion.openUrl(button.getContext(), Objects.requireNonNull(moduleHolder.getMainModuleInfo().support));
|
openUrl(button.context, Objects.requireNonNull(moduleHolder.mainModuleInfo.support))
|
||||||
}
|
}
|
||||||
}, DONATE() {
|
},
|
||||||
@Override
|
DONATE {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
ModuleInfo moduleInfo = moduleHolder.getMainModuleInfo();
|
val moduleInfo = moduleHolder.mainModuleInfo
|
||||||
button.setChipIcon(button.getContext().getDrawable(donateIconForUrl(moduleInfo.donate)));
|
button.chipIcon = button.context.getDrawable(
|
||||||
button.setText(R.string.donate);
|
donateIconForUrl(moduleInfo.donate)
|
||||||
|
)
|
||||||
|
button.setText(R.string.donate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
String name;
|
moduleHolder.moduleInfo!!.name
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("donate_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("donate_module", name).with(INSTANCE!!.getTracker())
|
||||||
IntentHelper.Companion.openUrl(button.getContext(), moduleHolder.getMainModuleInfo().donate);
|
openUrl(button.context, moduleHolder.mainModuleInfo.donate)
|
||||||
}
|
}
|
||||||
}, WARNING() {
|
},
|
||||||
@Override
|
WARNING {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
button.setChipIcon(button.getContext().getDrawable(R.drawable.ic_baseline_warning_24));
|
button.chipIcon = button.context.getDrawable(R.drawable.ic_baseline_warning_24)
|
||||||
button.setText(R.string.warning);
|
button.setText(R.string.warning)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
String name;
|
moduleHolder.moduleInfo!!.name
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("warning_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("warning_module", name).with(INSTANCE!!.getTracker())
|
||||||
new MaterialAlertDialogBuilder(button.getContext()).setTitle(R.string.warning).setMessage(R.string.warning_message).setPositiveButton(R.string.understand, (v, i) -> {
|
MaterialAlertDialogBuilder(button.context).setTitle(R.string.warning)
|
||||||
}).create().show();
|
.setMessage(R.string.warning_message).setPositiveButton(
|
||||||
|
R.string.understand
|
||||||
|
) { _: DialogInterface?, _: Int -> }
|
||||||
|
.create().show()
|
||||||
}
|
}
|
||||||
}, SAFE() {
|
},
|
||||||
|
SAFE {
|
||||||
// SAFE is for modules that the api says are clean. only supported by androidacy currently
|
// SAFE is for modules that the api says are clean. only supported by androidacy currently
|
||||||
@Override
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
button.chipIcon =
|
||||||
button.setChipIcon(button.getContext().getDrawable(R.drawable.baseline_verified_user_24));
|
button.context.getDrawable(R.drawable.baseline_verified_user_24)
|
||||||
button.setText(R.string.safe);
|
button.setText(R.string.safe)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
String name;
|
moduleHolder.moduleInfo!!.name
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("safe_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("safe_module", name).with(INSTANCE!!.getTracker())
|
||||||
new MaterialAlertDialogBuilder(button.getContext()).setTitle(R.string.safe_module).setMessage(R.string.safe_message).setPositiveButton(R.string.understand, (v, i) -> {
|
MaterialAlertDialogBuilder(button.context).setTitle(R.string.safe_module)
|
||||||
}).create().show();
|
.setMessage(R.string.safe_message).setPositiveButton(
|
||||||
|
R.string.understand
|
||||||
|
) { _: DialogInterface?, _: Int -> }
|
||||||
|
.create().show()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
private final int iconId;
|
private val iconId: Int
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
iconId = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
constructor(iconId: Int) {
|
||||||
|
this.iconId = iconId
|
||||||
|
}
|
||||||
|
|
||||||
ActionButtonType() {
|
open fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
this.iconId = 0;
|
button.chipIcon = button.context.getDrawable(iconId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
abstract fun doAction(button: Chip, moduleHolder: ModuleHolder)
|
||||||
ActionButtonType(int iconId) {
|
open fun doActionLong(button: Chip, moduleHolder: ModuleHolder): Boolean {
|
||||||
this.iconId = iconId;
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
public static int supportIconForUrl(String url) {
|
fun supportIconForUrl(url: String?): Int {
|
||||||
int icon = R.drawable.ic_baseline_support_24;
|
var icon = R.drawable.ic_baseline_support_24
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
return icon;
|
return icon
|
||||||
} else if (url.startsWith("https://t.me/")) {
|
} else if (url.startsWith("https://t.me/")) {
|
||||||
icon = R.drawable.ic_baseline_telegram_24;
|
icon = R.drawable.ic_baseline_telegram_24
|
||||||
} else if (url.startsWith("https://discord.gg/") || url.startsWith("https://discord.com/invite/")) {
|
} else if (url.startsWith("https://discord.gg/") || url.startsWith("https://discord.com/invite/")) {
|
||||||
icon = R.drawable.ic_baseline_discord_24;
|
icon = R.drawable.ic_baseline_discord_24
|
||||||
} else if (url.startsWith("https://github.com/")) {
|
} else if (url.startsWith("https://github.com/")) {
|
||||||
icon = R.drawable.ic_github;
|
icon = R.drawable.ic_github
|
||||||
} else if (url.startsWith("https://gitlab.com/")) {
|
} else if (url.startsWith("https://gitlab.com/")) {
|
||||||
icon = R.drawable.ic_gitlab;
|
icon = R.drawable.ic_gitlab
|
||||||
} else if (url.startsWith("https://forum.xda-developers.com/")) {
|
} else if (url.startsWith("https://forum.xda-developers.com/")) {
|
||||||
icon = R.drawable.ic_xda;
|
icon = R.drawable.ic_xda
|
||||||
}
|
}
|
||||||
return icon;
|
return icon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
public static int donateIconForUrl(String url) {
|
fun donateIconForUrl(url: String?): Int {
|
||||||
int icon = R.drawable.ic_baseline_monetization_on_24;
|
var icon = R.drawable.ic_baseline_monetization_on_24
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
return icon;
|
return icon
|
||||||
} else if (url.startsWith("https://www.paypal.me/") || url.startsWith("https://www.paypal.com/paypalme/") || url.startsWith("https://www.paypal.com/donate/")) {
|
} else if (url.startsWith("https://www.paypal.me/") || url.startsWith("https://www.paypal.com/paypalme/") || url.startsWith(
|
||||||
icon = R.drawable.ic_baseline_paypal_24;
|
"https://www.paypal.com/donate/"
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
icon = R.drawable.ic_baseline_paypal_24
|
||||||
} else if (url.startsWith("https://patreon.com/") || url.startsWith("https://www.patreon.com/")) {
|
} else if (url.startsWith("https://patreon.com/") || url.startsWith("https://www.patreon.com/")) {
|
||||||
icon = R.drawable.ic_patreon;
|
icon = R.drawable.ic_patreon
|
||||||
}
|
}
|
||||||
return icon;
|
return icon
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
|
||||||
button.setChipIcon(button.getContext().getDrawable(this.iconId));
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void doAction(Chip button, ModuleHolder moduleHolder);
|
|
||||||
|
|
||||||
public boolean doActionLong(Chip button, ModuleHolder moduleHolder) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,374 +1,420 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
||||||
*/
|
*/
|
||||||
|
package com.fox2code.mmm.module
|
||||||
package com.fox2code.mmm.module;
|
|
||||||
|
import android.content.Context
|
||||||
import android.content.Context;
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.PackageManager;
|
import android.view.View
|
||||||
import android.view.View;
|
import androidx.annotation.StringRes
|
||||||
|
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
|
||||||
import androidx.annotation.NonNull;
|
import com.fox2code.mmm.MainApplication.Companion.formatTime
|
||||||
import androidx.annotation.StringRes;
|
import com.fox2code.mmm.MainApplication.Companion.getSharedPreferences
|
||||||
|
import com.fox2code.mmm.MainApplication.Companion.isDisableLowQualityModuleFilter
|
||||||
import com.fox2code.mmm.MainApplication;
|
import com.fox2code.mmm.NotificationType
|
||||||
import com.fox2code.mmm.NotificationType;
|
import com.fox2code.mmm.R
|
||||||
import com.fox2code.mmm.R;
|
import com.fox2code.mmm.XHooks.Companion.checkConfigTargetExists
|
||||||
import com.fox2code.mmm.XHooks;
|
import com.fox2code.mmm.manager.LocalModuleInfo
|
||||||
import com.fox2code.mmm.manager.LocalModuleInfo;
|
import com.fox2code.mmm.manager.ModuleInfo
|
||||||
import com.fox2code.mmm.manager.ModuleInfo;
|
import com.fox2code.mmm.repo.RepoModule
|
||||||
import com.fox2code.mmm.repo.RepoModule;
|
import com.fox2code.mmm.utils.IntentHelper.Companion.getPackageOfConfig
|
||||||
import com.fox2code.mmm.utils.IntentHelper;
|
import com.fox2code.mmm.utils.io.PropUtils.Companion.isLowQualityModule
|
||||||
import com.fox2code.mmm.utils.io.PropUtils;
|
import com.fox2code.mmm.utils.io.net.Http.Companion.hasWebView
|
||||||
import com.fox2code.mmm.utils.io.net.Http;
|
import timber.log.Timber
|
||||||
|
import java.util.Objects
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashSet;
|
@Suppress("unused", "KotlinConstantConditions")
|
||||||
import java.util.List;
|
class ModuleHolder : Comparable<ModuleHolder?> {
|
||||||
import java.util.Locale;
|
val moduleId: String
|
||||||
import java.util.Objects;
|
val notificationType: NotificationType?
|
||||||
import java.util.Set;
|
val separator: Type?
|
||||||
|
var footerPx: Int
|
||||||
import timber.log.Timber;
|
var onClickListener: View.OnClickListener? = null
|
||||||
|
var moduleInfo: LocalModuleInfo? = null
|
||||||
public final class ModuleHolder implements Comparable<ModuleHolder> {
|
var repoModule: RepoModule? = null
|
||||||
|
var filterLevel = 0
|
||||||
public final String moduleId;
|
|
||||||
public final NotificationType notificationType;
|
constructor(moduleId: String) {
|
||||||
public final Type separator;
|
this.moduleId = Objects.requireNonNull(moduleId)
|
||||||
public int footerPx;
|
notificationType = null
|
||||||
public View.OnClickListener onClickListener;
|
separator = null
|
||||||
|
footerPx = -1
|
||||||
public LocalModuleInfo moduleInfo;
|
}
|
||||||
public RepoModule repoModule;
|
|
||||||
public int filterLevel;
|
constructor(notificationType: NotificationType) {
|
||||||
|
moduleId = ""
|
||||||
public ModuleHolder(String moduleId) {
|
this.notificationType = Objects.requireNonNull(notificationType)
|
||||||
this.moduleId = Objects.requireNonNull(moduleId);
|
separator = null
|
||||||
this.notificationType = null;
|
footerPx = -1
|
||||||
this.separator = null;
|
}
|
||||||
this.footerPx = -1;
|
|
||||||
}
|
constructor(separator: Type?) {
|
||||||
|
moduleId = ""
|
||||||
public ModuleHolder(NotificationType notificationType) {
|
notificationType = null
|
||||||
this.moduleId = "";
|
this.separator = separator
|
||||||
this.notificationType = Objects.requireNonNull(notificationType);
|
footerPx = -1
|
||||||
this.separator = null;
|
}
|
||||||
this.footerPx = -1;
|
|
||||||
}
|
@Suppress("unused")
|
||||||
|
constructor(footerPx: Int, header: Boolean) {
|
||||||
public ModuleHolder(Type separator) {
|
moduleId = ""
|
||||||
this.moduleId = "";
|
notificationType = null
|
||||||
this.notificationType = null;
|
separator = null
|
||||||
this.separator = separator;
|
this.footerPx = footerPx
|
||||||
this.footerPx = -1;
|
filterLevel = if (header) 1 else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
val isModuleHolder: Boolean
|
||||||
public ModuleHolder(int footerPx, boolean header) {
|
get() = notificationType == null && separator == null && footerPx == -1
|
||||||
this.moduleId = "";
|
val mainModuleInfo: ModuleInfo
|
||||||
this.notificationType = null;
|
get() = if (repoModule != null && (moduleInfo == null || moduleInfo!!.versionCode < repoModule!!.moduleInfo.versionCode)) repoModule!!.moduleInfo else moduleInfo!!
|
||||||
this.separator = null;
|
val updateZipUrl: String?
|
||||||
this.footerPx = footerPx;
|
get() = if (moduleInfo == null || repoModule != null && moduleInfo!!.updateVersionCode < repoModule!!.moduleInfo.versionCode) repoModule!!.zipUrl else moduleInfo!!.updateZipUrl
|
||||||
this.filterLevel = header ? 1 : 0;
|
val updateZipRepo: String?
|
||||||
}
|
get() = if (moduleInfo == null || repoModule != null && moduleInfo!!.updateVersionCode < repoModule!!.moduleInfo.versionCode) repoModule!!.repoData.preferenceId else "update_json"
|
||||||
|
val updateZipChecksum: String?
|
||||||
public boolean isModuleHolder() {
|
get() = if (moduleInfo == null || repoModule != null && moduleInfo!!.updateVersionCode < repoModule!!.moduleInfo.versionCode) repoModule!!.checksum else moduleInfo!!.updateChecksum
|
||||||
return this.notificationType == null && this.separator == null && this.footerPx == -1;
|
val mainModuleName: String?
|
||||||
}
|
get() {
|
||||||
|
val moduleInfo = mainModuleInfo
|
||||||
public ModuleInfo getMainModuleInfo() {
|
if (moduleInfo.name == null) throw Error("Error for " + type.name + " id " + moduleId)
|
||||||
return this.repoModule != null && (this.moduleInfo == null || this.moduleInfo.versionCode < this.repoModule.moduleInfo.versionCode) ? this.repoModule.moduleInfo : this.moduleInfo;
|
return moduleInfo.name
|
||||||
}
|
}
|
||||||
|
val mainModuleNameLowercase: String
|
||||||
public String getUpdateZipUrl() {
|
get() = mainModuleName!!.lowercase()
|
||||||
return this.moduleInfo == null || (this.repoModule != null && this.moduleInfo.updateVersionCode < this.repoModule.moduleInfo.versionCode) ? this.repoModule.zipUrl : this.moduleInfo.updateZipUrl;
|
val mainModuleConfig: String?
|
||||||
}
|
get() {
|
||||||
|
if (moduleInfo == null) return null
|
||||||
public String getUpdateZipRepo() {
|
var config = moduleInfo!!.config
|
||||||
return this.moduleInfo == null || (this.repoModule != null && this.moduleInfo.updateVersionCode < this.repoModule.moduleInfo.versionCode) ? this.repoModule.repoData.preferenceId : "update_json";
|
if (config == null && repoModule != null) {
|
||||||
}
|
config = repoModule!!.moduleInfo.config
|
||||||
|
}
|
||||||
public String getUpdateZipChecksum() {
|
return config
|
||||||
return this.moduleInfo == null || (this.repoModule != null && this.moduleInfo.updateVersionCode < this.repoModule.moduleInfo.versionCode) ? this.repoModule.checksum : this.moduleInfo.updateChecksum;
|
}
|
||||||
}
|
val updateTimeText: String
|
||||||
|
get() {
|
||||||
public String getMainModuleName() {
|
if (repoModule == null) return ""
|
||||||
ModuleInfo moduleInfo = this.getMainModuleInfo();
|
val timeStamp = repoModule!!.lastUpdated
|
||||||
if (moduleInfo == null || moduleInfo.name == null)
|
return if (timeStamp <= 0) "" else formatTime(timeStamp)
|
||||||
throw new Error("Error for " + this.getType().name() + " id " + this.moduleId);
|
}
|
||||||
return moduleInfo.name;
|
val repoName: String?
|
||||||
}
|
get() = if (repoModule == null) "" else repoModule!!.repoName
|
||||||
|
|
||||||
public String getMainModuleNameLowercase() {
|
fun hasFlag(flag: Int): Boolean {
|
||||||
return this.getMainModuleName().toLowerCase(Locale.ROOT);
|
return moduleInfo != null && moduleInfo!!.hasFlag(flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMainModuleConfig() {
|
val type: Type
|
||||||
if (this.moduleInfo == null) return null;
|
get() = if (footerPx != -1) {
|
||||||
String config = this.moduleInfo.config;
|
Timber.i("Module %s is footer", moduleId)
|
||||||
if (config == null && this.repoModule != null) {
|
Type.FOOTER
|
||||||
config = this.repoModule.moduleInfo.config;
|
} else if (separator != null) {
|
||||||
}
|
Timber.i("Module %s is separator", moduleId)
|
||||||
return config;
|
Type.SEPARATOR
|
||||||
}
|
} else if (notificationType != null) {
|
||||||
|
Timber.i("Module %s is notification", moduleId)
|
||||||
public String getUpdateTimeText() {
|
Type.NOTIFICATION
|
||||||
if (this.repoModule == null) return "";
|
} else if (moduleInfo == null) {
|
||||||
long timeStamp = this.repoModule.lastUpdated;
|
Type.INSTALLABLE
|
||||||
return timeStamp <= 0 ? "" : MainApplication.formatTime(timeStamp);
|
} else if (moduleInfo!!.versionCode < moduleInfo!!.updateVersionCode || repoModule != null && moduleInfo!!.versionCode < repoModule!!.moduleInfo.versionCode) {
|
||||||
}
|
var ignoreUpdate = false
|
||||||
|
|
||||||
public String getRepoName() {
|
|
||||||
if (this.repoModule == null) return "";
|
|
||||||
return this.repoModule.repoName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasFlag(int flag) {
|
|
||||||
return this.moduleInfo != null && this.moduleInfo.hasFlag(flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type getType() {
|
|
||||||
if (this.footerPx != -1) {
|
|
||||||
Timber.i("Module %s is footer", this.moduleId);
|
|
||||||
return Type.FOOTER;
|
|
||||||
} else if (this.separator != null) {
|
|
||||||
Timber.i("Module %s is separator", this.moduleId);
|
|
||||||
return Type.SEPARATOR;
|
|
||||||
} else if (this.notificationType != null) {
|
|
||||||
Timber.i("Module %s is notification", this.moduleId);
|
|
||||||
return Type.NOTIFICATION;
|
|
||||||
} else if (this.moduleInfo == null) {
|
|
||||||
return Type.INSTALLABLE;
|
|
||||||
} else if (this.moduleInfo.versionCode < this.moduleInfo.updateVersionCode || (this.repoModule != null && this.moduleInfo.versionCode < this.repoModule.moduleInfo.versionCode)) {
|
|
||||||
boolean ignoreUpdate = false;
|
|
||||||
try {
|
try {
|
||||||
if (Objects.requireNonNull(Objects.requireNonNull(MainApplication.getSharedPreferences("mmm")).getStringSet("pref_background_update_check_excludes", new HashSet<>())).contains(moduleInfo.id))
|
if (getSharedPreferences("mmm")?.getStringSet("pref_background_update_check_excludes", HashSet())!!
|
||||||
ignoreUpdate = true;
|
.contains(
|
||||||
} catch (Exception ignored) {
|
moduleInfo!!.id
|
||||||
|
)
|
||||||
|
) ignoreUpdate = true
|
||||||
|
} catch (ignored: Exception) {
|
||||||
}
|
}
|
||||||
// now, we just had to make it more fucking complicated, didn't we?
|
// now, we just had to make it more fucking complicated, didn't we?
|
||||||
// we now have pref_background_update_check_excludes_version, which is a id:version stringset of versions the user may want to "skip"
|
// we now have pref_background_update_check_excludes_version, which is a id:version stringset of versions the user may want to "skip"
|
||||||
// oh, and because i hate myself, i made ^ at the beginning match that version and newer, and $ at the end match that version and older
|
// oh, and because i hate myself, i made ^ at the beginning match that version and newer, and $ at the end match that version and older
|
||||||
Set<String> stringSetT = Objects.requireNonNull(MainApplication.getSharedPreferences("mmm")).getStringSet("pref_background_update_check_excludes_version", new HashSet<>());
|
val stringSetT = getSharedPreferences("mmm")?.getStringSet("pref_background_update_check_excludes_version", HashSet())
|
||||||
String version = "";
|
var version = ""
|
||||||
Timber.d(stringSetT.toString());
|
Timber.d(stringSetT.toString())
|
||||||
// unfortunately, stringset.contains() doesn't work for partial matches
|
// unfortunately, stringset.contains() doesn't work for partial matches
|
||||||
// so we have to iterate through the set
|
// so we have to iterate through the set
|
||||||
for (String s : stringSetT) {
|
for (s in stringSetT!!) {
|
||||||
if (s.startsWith(this.moduleInfo.id)) {
|
if (s.startsWith(moduleInfo!!.id)) {
|
||||||
version = s;
|
version = s
|
||||||
Timber.d("igV: %s", version);
|
Timber.d("igV: %s", version)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String remoteVersionCode = String.valueOf(moduleInfo.updateVersionCode);
|
var remoteVersionCode = moduleInfo!!.updateVersionCode.toString()
|
||||||
if (repoModule != null) {
|
if (repoModule != null) {
|
||||||
remoteVersionCode = String.valueOf(repoModule.moduleInfo.versionCode);
|
remoteVersionCode = repoModule!!.moduleInfo.versionCode.toString()
|
||||||
}
|
}
|
||||||
if (!version.isEmpty()) {
|
if (version.isNotEmpty()) {
|
||||||
// now, coerce everything into an int
|
// now, coerce everything into an int
|
||||||
int remoteVersionCodeInt = Integer.parseInt(remoteVersionCode);
|
val remoteVersionCodeInt = remoteVersionCode.toInt()
|
||||||
int wantsVersion = Integer.parseInt(version.split(":")[1].replaceAll("[^0-9]", ""));
|
val wantsVersion = version.split(":".toRegex()).dropLastWhile { it.isEmpty() }
|
||||||
|
.toTypedArray()[1].replace("[^0-9]".toRegex(), "").toInt()
|
||||||
// now find out if user wants up to and including this version, or this version and newer
|
// now find out if user wants up to and including this version, or this version and newer
|
||||||
Timber.d("igV start with");
|
Timber.d("igV start with")
|
||||||
version = version.split(":")[1];
|
version =
|
||||||
|
version.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
|
||||||
// this version and newer
|
// this version and newer
|
||||||
if (version.startsWith("^")) {
|
if (version.startsWith("^")) {
|
||||||
Timber.d("igV: newer");
|
Timber.d("igV: newer")
|
||||||
// the wantsversion and newer
|
// the wantsversion and newer
|
||||||
if (remoteVersionCodeInt >= wantsVersion) {
|
if (remoteVersionCodeInt >= wantsVersion) {
|
||||||
Timber.d("igV: skipping");
|
Timber.d("igV: skipping")
|
||||||
// if it is, we skip it
|
// if it is, we skip it
|
||||||
ignoreUpdate = true;
|
ignoreUpdate = true
|
||||||
}
|
}
|
||||||
} else if (version.endsWith("$")) {
|
} else if (version.endsWith("$")) {
|
||||||
Timber.d("igV: older");
|
Timber.d("igV: older")
|
||||||
// this wantsversion and older
|
// this wantsversion and older
|
||||||
if (remoteVersionCodeInt <= wantsVersion) {
|
if (remoteVersionCodeInt <= wantsVersion) {
|
||||||
Timber.d("igV: skipping");
|
Timber.d("igV: skipping")
|
||||||
// if it is, we skip it
|
// if it is, we skip it
|
||||||
ignoreUpdate = true;
|
ignoreUpdate = true
|
||||||
}
|
}
|
||||||
} else if (wantsVersion == remoteVersionCodeInt) {
|
} else if (wantsVersion == remoteVersionCodeInt) {
|
||||||
Timber.d("igV: equal");
|
Timber.d("igV: equal")
|
||||||
// if it is, we skip it
|
// if it is, we skip it
|
||||||
ignoreUpdate = true;
|
ignoreUpdate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (ignoreUpdate) {
|
if (ignoreUpdate) {
|
||||||
Timber.d("Module %s has update, but is ignored", this.moduleId);
|
Timber.d("Module %s has update, but is ignored", moduleId)
|
||||||
return Type.INSTALLABLE;
|
Type.INSTALLABLE
|
||||||
} else {
|
} else {
|
||||||
Objects.requireNonNull(MainApplication.getINSTANCE()).modulesHaveUpdates = true;
|
INSTANCE!!.modulesHaveUpdates = true
|
||||||
if (!MainApplication.getINSTANCE().updateModules.contains(this.moduleId)) {
|
if (!INSTANCE!!.updateModules.contains(moduleId)) {
|
||||||
MainApplication.getINSTANCE().updateModules.add(this.moduleId);
|
INSTANCE!!.updateModules += moduleId
|
||||||
MainApplication.getINSTANCE().updateModuleCount++;
|
INSTANCE!!.updateModuleCount++
|
||||||
}
|
}
|
||||||
Timber.d("modulesHaveUpdates = %s, updateModuleCount = %s", MainApplication.getINSTANCE().modulesHaveUpdates, MainApplication.getINSTANCE().updateModuleCount);
|
Timber.d(
|
||||||
Timber.d("Module %s has update", this.moduleId);
|
"modulesHaveUpdates = %s, updateModuleCount = %s",
|
||||||
return Type.UPDATABLE;
|
INSTANCE!!.modulesHaveUpdates,
|
||||||
|
INSTANCE!!.updateModuleCount
|
||||||
|
)
|
||||||
|
Timber.d("Module %s has update", moduleId)
|
||||||
|
Type.UPDATABLE
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Type.INSTALLED;
|
Type.INSTALLED
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getCompareType(Type type) {
|
fun getCompareType(type: Type?): Type? {
|
||||||
if (this.separator != null) {
|
return separator
|
||||||
return this.separator;
|
?: if (notificationType != null && notificationType.special) {
|
||||||
} else if (this.notificationType != null && this.notificationType.special) {
|
Type.SPECIAL_NOTIFICATIONS
|
||||||
return Type.SPECIAL_NOTIFICATIONS;
|
|
||||||
} else {
|
} else {
|
||||||
return type;
|
type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldRemove() {
|
fun shouldRemove(): Boolean {
|
||||||
if (this.repoModule != null && this.moduleInfo != null && !hasUpdate()) {
|
if (repoModule != null && moduleInfo != null && !hasUpdate()) {
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
return this.notificationType != null ? this.notificationType.shouldRemove() : this.footerPx == -1 && this.moduleInfo == null && (this.repoModule == null || !this.repoModule.repoData.isEnabled() || (PropUtils.isLowQualityModule(this.repoModule.moduleInfo) && !MainApplication.Companion.isDisableLowQualityModuleFilter()));
|
return notificationType?.shouldRemove()
|
||||||
|
?: (footerPx == -1 && moduleInfo == null && (repoModule == null || !repoModule!!.repoData.isEnabled || isLowQualityModule(
|
||||||
|
repoModule!!.moduleInfo
|
||||||
|
) && !isDisableLowQualityModuleFilter))
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getButtons(Context context, List<ActionButtonType> buttonTypeList, boolean showcaseMode) {
|
fun getButtons(
|
||||||
if (!this.isModuleHolder()) return;
|
context: Context?,
|
||||||
LocalModuleInfo localModuleInfo = this.moduleInfo;
|
buttonTypeList: MutableList<ActionButtonType?>,
|
||||||
|
showcaseMode: Boolean
|
||||||
|
) {
|
||||||
|
if (!isModuleHolder) return
|
||||||
|
val localModuleInfo = moduleInfo
|
||||||
// Add warning button if module id begins with a dot - this is a hidden module which could indicate malware
|
// Add warning button if module id begins with a dot - this is a hidden module which could indicate malware
|
||||||
if (this.moduleId.startsWith(".") || !this.moduleId.matches("^[a-zA-Z][a-zA-Z0-9._-]+$")) {
|
if (moduleId.startsWith(".") || !moduleId.matches("^[a-zA-Z][a-zA-Z0-9._-]+$".toRegex())) {
|
||||||
buttonTypeList.add(ActionButtonType.WARNING);
|
buttonTypeList.add(ActionButtonType.WARNING)
|
||||||
}
|
}
|
||||||
if (localModuleInfo != null && !showcaseMode) {
|
if (localModuleInfo != null && !showcaseMode) {
|
||||||
buttonTypeList.add(ActionButtonType.UNINSTALL);
|
buttonTypeList.add(ActionButtonType.UNINSTALL)
|
||||||
}
|
}
|
||||||
if (this.repoModule != null && this.repoModule.notesUrl != null) {
|
if (repoModule != null && repoModule!!.notesUrl != null) {
|
||||||
buttonTypeList.add(ActionButtonType.INFO);
|
buttonTypeList.add(ActionButtonType.INFO)
|
||||||
}
|
}
|
||||||
if ((this.repoModule != null || (localModuleInfo != null && localModuleInfo.updateZipUrl != null))) {
|
if (repoModule != null || localModuleInfo?.updateZipUrl != null) {
|
||||||
buttonTypeList.add(ActionButtonType.UPDATE_INSTALL);
|
buttonTypeList.add(ActionButtonType.UPDATE_INSTALL)
|
||||||
}
|
}
|
||||||
String config = this.getMainModuleConfig();
|
val config = mainModuleConfig
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
if (config.startsWith("https://www.androidacy.com/") && Http.hasWebView()) {
|
if (config.startsWith("https://www.androidacy.com/") && hasWebView()) {
|
||||||
buttonTypeList.add(ActionButtonType.CONFIG);
|
buttonTypeList.add(ActionButtonType.CONFIG)
|
||||||
} else {
|
} else {
|
||||||
String pkg = IntentHelper.getPackageOfConfig(config);
|
val pkg = getPackageOfConfig(config)
|
||||||
try {
|
try {
|
||||||
XHooks.checkConfigTargetExists(context, pkg, config);
|
checkConfigTargetExists(context!!, pkg, config)
|
||||||
buttonTypeList.add(ActionButtonType.CONFIG);
|
buttonTypeList.add(ActionButtonType.CONFIG)
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
Timber.w("Config package \"" + pkg + "\" missing for module \"" + this.moduleId + "\"");
|
Timber.w("Config package \"$pkg\" missing for module \"$moduleId\"")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleInfo moduleInfo = this.getMainModuleInfo();
|
var moduleInfo: ModuleInfo? = mainModuleInfo
|
||||||
if (moduleInfo == null) { // Avoid concurrency NPE
|
if (moduleInfo == null) { // Avoid concurrency NPE
|
||||||
if (localModuleInfo == null) return;
|
if (localModuleInfo == null) return
|
||||||
moduleInfo = localModuleInfo;
|
moduleInfo = localModuleInfo
|
||||||
}
|
}
|
||||||
if (moduleInfo.support != null) {
|
if (moduleInfo.support != null) {
|
||||||
buttonTypeList.add(ActionButtonType.SUPPORT);
|
buttonTypeList.add(ActionButtonType.SUPPORT)
|
||||||
}
|
}
|
||||||
if (moduleInfo.donate != null) {
|
if (moduleInfo.donate != null) {
|
||||||
buttonTypeList.add(ActionButtonType.DONATE);
|
buttonTypeList.add(ActionButtonType.DONATE)
|
||||||
}
|
}
|
||||||
if (moduleInfo.safe) {
|
if (moduleInfo.safe) {
|
||||||
buttonTypeList.add(ActionButtonType.SAFE);
|
buttonTypeList.add(ActionButtonType.SAFE)
|
||||||
} else {
|
} else {
|
||||||
Timber.d("Module %s is not safe", this.moduleId);
|
Timber.d("Module %s is not safe", moduleId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasUpdate() {
|
fun hasUpdate(): Boolean {
|
||||||
return this.moduleInfo != null && this.repoModule != null && this.moduleInfo.versionCode < this.repoModule.moduleInfo.versionCode;
|
return moduleInfo != null && repoModule != null && moduleInfo!!.versionCode < repoModule!!.moduleInfo.versionCode
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override operator fun compareTo(other: ModuleHolder?): Int {
|
||||||
public int compareTo(ModuleHolder o) {
|
|
||||||
// Compare depend on type, also allow type spoofing
|
// Compare depend on type, also allow type spoofing
|
||||||
Type selfTypeReal = this.getType();
|
val selfTypeReal = type
|
||||||
Type otherTypeReal = o.getType();
|
val otherTypeReal = other!!.type
|
||||||
Type selfType = this.getCompareType(selfTypeReal);
|
val selfType = getCompareType(selfTypeReal)
|
||||||
Type otherType = o.getCompareType(otherTypeReal);
|
val otherType = other.getCompareType(otherTypeReal)
|
||||||
int compare = selfType.compareTo(otherType);
|
val compare = selfType!!.compareTo(otherType!!)
|
||||||
return compare != 0 ? compare : selfTypeReal == otherTypeReal ? selfTypeReal.compare(this, o) : selfTypeReal.compareTo(otherTypeReal);
|
return if (compare != 0) compare else if (selfTypeReal === otherTypeReal) selfTypeReal.compare(
|
||||||
}
|
this,
|
||||||
|
other
|
||||||
@NonNull
|
) else selfTypeReal.compareTo(otherTypeReal)
|
||||||
@Override
|
}
|
||||||
public String toString() {
|
|
||||||
return "ModuleHolder{" + "moduleId='" + moduleId + '\'' + ", notificationType=" + notificationType + ", separator=" + separator + ", footerPx=" + footerPx + '}';
|
override fun toString(): String {
|
||||||
}
|
return "ModuleHolder{moduleId='$moduleId', notificationType=$notificationType, separator=$separator, footerPx=$footerPx}"
|
||||||
|
}
|
||||||
public enum Type implements Comparator<ModuleHolder> {
|
|
||||||
HEADER(R.string.loading, false, false), SEPARATOR(R.string.loading, false, false) {
|
enum class Type(
|
||||||
@Override
|
@field:StringRes @param:StringRes val title: Int,
|
||||||
@SuppressWarnings("ConstantConditions")
|
val hasBackground: Boolean,
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
val moduleHolder: Boolean
|
||||||
return o1.separator.compareTo(o2.separator);
|
) : Comparator<ModuleHolder?> {
|
||||||
}
|
HEADER(R.string.loading, false, false) {
|
||||||
}, NOTIFICATION(R.string.loading, true, false) {
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
@Override
|
if (o1 != null && o2 != null) {
|
||||||
@SuppressWarnings("ConstantConditions")
|
return o1.separator!!.compareTo(o2.separator!!)
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
} else if (o1 != null) {
|
||||||
return o1.notificationType.compareTo(o2.notificationType);
|
return -1
|
||||||
}
|
} else if (o2 != null) {
|
||||||
}, UPDATABLE(R.string.updatable, true, true) {
|
return 1
|
||||||
@Override
|
}
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
return 0
|
||||||
int cmp = Integer.compare(o1.filterLevel, o2.filterLevel);
|
}
|
||||||
if (cmp != 0) return cmp;
|
}, SEPARATOR(R.string.loading, false, false) {
|
||||||
long lastUpdated1 = o1.repoModule == null ? 0L : o1.repoModule.lastUpdated;
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
long lastUpdated2 = o2.repoModule == null ? 0L : o2.repoModule.lastUpdated;
|
if (o1 != null && o2 != null) {
|
||||||
cmp = Long.compare(lastUpdated2, lastUpdated1);
|
return o1.separator!!.compareTo(o2.separator!!)
|
||||||
if (cmp != 0) return cmp;
|
} else if (o1 != null) {
|
||||||
return o1.getMainModuleName().compareTo(o2.getMainModuleName());
|
return -1
|
||||||
}
|
} else if (o2 != null) {
|
||||||
}, INSTALLED(R.string.installed, true, true) {
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
NOTIFICATION(R.string.loading, true, false) {
|
||||||
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
|
if (o1 != null && o2 != null) {
|
||||||
|
return o1.notificationType!!.compareTo(o2.notificationType!!)
|
||||||
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UPDATABLE(R.string.updatable, true, true) {
|
||||||
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
|
if (o1 != null && o2 != null) {
|
||||||
|
var cmp = o1.filterLevel.compareTo(o2.filterLevel)
|
||||||
|
if (cmp != 0) return cmp
|
||||||
|
val lastUpdated1 =
|
||||||
|
if (o1.repoModule == null) 0L else o1.repoModule!!.lastUpdated
|
||||||
|
val lastUpdated2 =
|
||||||
|
if (o2.repoModule == null) 0L else o2.repoModule!!.lastUpdated
|
||||||
|
cmp = lastUpdated2.compareTo(lastUpdated1)
|
||||||
|
return if (cmp != 0) cmp else o1.mainModuleName!!.compareTo(o2.mainModuleName!!)
|
||||||
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
INSTALLED(R.string.installed, true, true) {
|
||||||
// get stacktrace for debugging
|
// get stacktrace for debugging
|
||||||
@Override
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
if (o1 != null && o2 != null) {
|
||||||
int cmp = Integer.compare(o1.filterLevel, o2.filterLevel);
|
val cmp = o1.filterLevel.compareTo(o2.filterLevel)
|
||||||
if (cmp != 0) return cmp;
|
return if (cmp != 0) cmp else o1.mainModuleNameLowercase.compareTo(o2.mainModuleNameLowercase)
|
||||||
return o1.getMainModuleNameLowercase().compareTo(o2.getMainModuleNameLowercase());
|
} else if (o1 != null) {
|
||||||
}
|
return -1
|
||||||
}, SPECIAL_NOTIFICATIONS(R.string.loading, true, false), INSTALLABLE(R.string.online_repo, true, true) {
|
} else if (o2 != null) {
|
||||||
@Override
|
return 1
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
}
|
||||||
int cmp = Integer.compare(o1.filterLevel, o2.filterLevel);
|
return 0
|
||||||
if (cmp != 0) return cmp;
|
}
|
||||||
long lastUpdated1 = o1.repoModule == null ? 0L : o1.repoModule.lastUpdated;
|
},
|
||||||
long lastUpdated2 = o2.repoModule == null ? 0L : o2.repoModule.lastUpdated;
|
SPECIAL_NOTIFICATIONS(R.string.loading, true, false) {
|
||||||
cmp = Long.compare(lastUpdated2, lastUpdated1);
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
if (cmp != 0) return cmp;
|
if (o1 != null && o2 != null) {
|
||||||
return o1.getMainModuleName().compareTo(o2.getMainModuleName());
|
var cmp = o1.filterLevel.compareTo(o2.filterLevel)
|
||||||
}
|
if (cmp != 0) return cmp
|
||||||
}, FOOTER(R.string.loading, false, false);
|
val lastUpdated1 =
|
||||||
|
if (o1.repoModule == null) 0L else o1.repoModule!!.lastUpdated
|
||||||
@StringRes
|
val lastUpdated2 =
|
||||||
public final int title;
|
if (o2.repoModule == null) 0L else o2.repoModule!!.lastUpdated
|
||||||
public final boolean hasBackground;
|
cmp = lastUpdated2.compareTo(lastUpdated1)
|
||||||
public final boolean moduleHolder;
|
return if (cmp != 0) cmp else o1.mainModuleName!!.compareTo(o2.mainModuleName!!)
|
||||||
|
} else if (o1 != null) {
|
||||||
Type(@StringRes int title, boolean hasBackground, boolean moduleHolder) {
|
return -1
|
||||||
this.title = title;
|
} else if (o2 != null) {
|
||||||
this.hasBackground = hasBackground;
|
return 1
|
||||||
this.moduleHolder = moduleHolder;
|
}
|
||||||
}
|
return 0
|
||||||
|
}
|
||||||
// Note: This method should only be called if both element have the same type
|
}, INSTALLABLE(
|
||||||
@Override
|
R.string.online_repo,
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
true,
|
||||||
if (o1 == o2) {
|
true
|
||||||
return 0;
|
) {
|
||||||
} else if (o1 == null) {
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
return -1;
|
if (o1 != null && o2 != null) {
|
||||||
} else if (o2 == null) {
|
var cmp = o1.filterLevel.compareTo(o2.filterLevel)
|
||||||
return 1;
|
if (cmp != 0) return cmp
|
||||||
} else {
|
val lastUpdated1 =
|
||||||
return o1.moduleId.compareTo(o2.moduleId);
|
if (o1.repoModule == null) 0L else o1.repoModule!!.lastUpdated
|
||||||
}
|
val lastUpdated2 =
|
||||||
}
|
if (o2.repoModule == null) 0L else o2.repoModule!!.lastUpdated
|
||||||
|
cmp = lastUpdated2.compareTo(lastUpdated1)
|
||||||
|
return if (cmp != 0) cmp else o1.mainModuleName!!.compareTo(o2.mainModuleName!!)
|
||||||
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
FOOTER(R.string.loading, false, false) {
|
||||||
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
|
if (o1 != null && o2 != null) {
|
||||||
|
return o1.footerPx.compareTo(o2.footerPx)
|
||||||
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue