mirror of
https://github.com/revanced/revanced-manager.git
synced 2025-04-30 05:54:26 +02:00
build(Needs bump): Bump ReVanced Patcher (#2242)
Co-authored-by: aAbed <aabedhkhan@gmail.com>
This commit is contained in:
parent
4db4789a06
commit
8d0d782ab5
@ -9,14 +9,15 @@ import android.os.Handler
|
|||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import app.revanced.library.ApkUtils
|
import app.revanced.library.ApkUtils
|
||||||
import app.revanced.library.ApkUtils.applyTo
|
import app.revanced.library.ApkUtils.applyTo
|
||||||
|
import app.revanced.library.installation.installer.LocalInstaller
|
||||||
import app.revanced.manager.flutter.utils.Aapt
|
import app.revanced.manager.flutter.utils.Aapt
|
||||||
import app.revanced.manager.flutter.utils.packageInstaller.InstallerReceiver
|
import app.revanced.manager.flutter.utils.packageInstaller.InstallerReceiver
|
||||||
import app.revanced.manager.flutter.utils.packageInstaller.UninstallerReceiver
|
import app.revanced.manager.flutter.utils.packageInstaller.UninstallerReceiver
|
||||||
import app.revanced.patcher.PatchBundleLoader
|
|
||||||
import app.revanced.patcher.PatchSet
|
|
||||||
import app.revanced.patcher.Patcher
|
import app.revanced.patcher.Patcher
|
||||||
import app.revanced.patcher.PatcherConfig
|
import app.revanced.patcher.PatcherConfig
|
||||||
|
import app.revanced.patcher.patch.Patch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.loadPatchesFromDex
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
import io.flutter.embedding.engine.FlutterEngine
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
@ -37,7 +38,7 @@ class MainActivity : FlutterActivity() {
|
|||||||
private var cancel: Boolean = false
|
private var cancel: Boolean = false
|
||||||
private var stopResult: MethodChannel.Result? = null
|
private var stopResult: MethodChannel.Result? = null
|
||||||
|
|
||||||
private lateinit var patches: PatchSet
|
private lateinit var patches: Set<Patch<*>>
|
||||||
|
|
||||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
super.configureFlutterEngine(flutterEngine)
|
super.configureFlutterEngine(flutterEngine)
|
||||||
@ -70,7 +71,6 @@ class MainActivity : FlutterActivity() {
|
|||||||
"runPatcher" -> {
|
"runPatcher" -> {
|
||||||
val inFilePath = call.argument<String>("inFilePath")
|
val inFilePath = call.argument<String>("inFilePath")
|
||||||
val outFilePath = call.argument<String>("outFilePath")
|
val outFilePath = call.argument<String>("outFilePath")
|
||||||
val integrationsPath = call.argument<String>("integrationsPath")
|
|
||||||
val selectedPatches = call.argument<List<String>>("selectedPatches")
|
val selectedPatches = call.argument<List<String>>("selectedPatches")
|
||||||
val options = call.argument<Map<String, Map<String, Any>>>("options")
|
val options = call.argument<Map<String, Map<String, Any>>>("options")
|
||||||
val tmpDirPath = call.argument<String>("tmpDirPath")
|
val tmpDirPath = call.argument<String>("tmpDirPath")
|
||||||
@ -80,7 +80,6 @@ class MainActivity : FlutterActivity() {
|
|||||||
if (
|
if (
|
||||||
inFilePath != null &&
|
inFilePath != null &&
|
||||||
outFilePath != null &&
|
outFilePath != null &&
|
||||||
integrationsPath != null &&
|
|
||||||
selectedPatches != null &&
|
selectedPatches != null &&
|
||||||
options != null &&
|
options != null &&
|
||||||
tmpDirPath != null &&
|
tmpDirPath != null &&
|
||||||
@ -92,14 +91,17 @@ class MainActivity : FlutterActivity() {
|
|||||||
result,
|
result,
|
||||||
inFilePath,
|
inFilePath,
|
||||||
outFilePath,
|
outFilePath,
|
||||||
integrationsPath,
|
|
||||||
selectedPatches,
|
selectedPatches,
|
||||||
options,
|
options,
|
||||||
tmpDirPath,
|
tmpDirPath,
|
||||||
keyStoreFilePath,
|
keyStoreFilePath,
|
||||||
keystorePassword
|
keystorePassword
|
||||||
)
|
)
|
||||||
} else result.notImplemented()
|
} else result.error(
|
||||||
|
"INVALID_ARGUMENTS",
|
||||||
|
"Invalid arguments",
|
||||||
|
"One or more arguments are missing"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"stopPatcher" -> {
|
"stopPatcher" -> {
|
||||||
@ -113,14 +115,16 @@ class MainActivity : FlutterActivity() {
|
|||||||
try {
|
try {
|
||||||
val patchBundleFile = File(patchBundleFilePath)
|
val patchBundleFile = File(patchBundleFilePath)
|
||||||
patchBundleFile.setWritable(false)
|
patchBundleFile.setWritable(false)
|
||||||
patches = PatchBundleLoader.Dex(
|
patches = loadPatchesFromDex(
|
||||||
patchBundleFile,
|
setOf(patchBundleFile),
|
||||||
optimizedDexDirectory = codeCacheDir
|
optimizedDexDirectory = codeCacheDir
|
||||||
)
|
)
|
||||||
} catch (ex: Exception) {
|
} catch (t: Throwable) {
|
||||||
return@setMethodCallHandler result.notImplemented()
|
return@setMethodCallHandler result.error(
|
||||||
} catch (err: Error) {
|
"PATCH_BUNDLE_ERROR",
|
||||||
return@setMethodCallHandler result.notImplemented()
|
"Failed to load patch bundle",
|
||||||
|
t.stackTraceToString()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray().apply {
|
JSONArray().apply {
|
||||||
@ -130,13 +134,13 @@ class MainActivity : FlutterActivity() {
|
|||||||
put("description", it.description)
|
put("description", it.description)
|
||||||
put("excluded", !it.use)
|
put("excluded", !it.use)
|
||||||
put("compatiblePackages", JSONArray().apply {
|
put("compatiblePackages", JSONArray().apply {
|
||||||
it.compatiblePackages?.forEach { compatiblePackage ->
|
it.compatiblePackages?.forEach { (name, versions) ->
|
||||||
val compatiblePackageJson = JSONObject().apply {
|
val compatiblePackageJson = JSONObject().apply {
|
||||||
put("name", compatiblePackage.name)
|
put("name", name)
|
||||||
put(
|
put(
|
||||||
"versions",
|
"versions",
|
||||||
JSONArray().apply {
|
JSONArray().apply {
|
||||||
compatiblePackage.versions?.forEach { version ->
|
versions?.forEach { version ->
|
||||||
put(version)
|
put(version)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -172,7 +176,7 @@ class MainActivity : FlutterActivity() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} ?: put("values", null)
|
} ?: put("values", null)
|
||||||
put("valueType", option.valueType)
|
put("type", option.type)
|
||||||
}.let(::put)
|
}.let(::put)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -211,7 +215,6 @@ class MainActivity : FlutterActivity() {
|
|||||||
result: MethodChannel.Result,
|
result: MethodChannel.Result,
|
||||||
inFilePath: String,
|
inFilePath: String,
|
||||||
outFilePath: String,
|
outFilePath: String,
|
||||||
integrationsPath: String,
|
|
||||||
selectedPatches: List<String>,
|
selectedPatches: List<String>,
|
||||||
options: Map<String, Map<String, Any>>,
|
options: Map<String, Map<String, Any>>,
|
||||||
tmpDirPath: String,
|
tmpDirPath: String,
|
||||||
@ -223,7 +226,6 @@ class MainActivity : FlutterActivity() {
|
|||||||
inFile.setWritable(true)
|
inFile.setWritable(true)
|
||||||
inFile.setReadable(true)
|
inFile.setReadable(true)
|
||||||
val outFile = File(outFilePath)
|
val outFile = File(outFilePath)
|
||||||
val integrations = File(integrationsPath)
|
|
||||||
val keyStoreFile = File(keyStoreFilePath)
|
val keyStoreFile = File(keyStoreFilePath)
|
||||||
val tmpDir = File(tmpDirPath)
|
val tmpDir = File(tmpDirPath)
|
||||||
|
|
||||||
@ -289,8 +291,8 @@ class MainActivity : FlutterActivity() {
|
|||||||
updateProgress(0.02, "Loading patches...", "Loading patches")
|
updateProgress(0.02, "Loading patches...", "Loading patches")
|
||||||
|
|
||||||
val patches = patches.filter { patch ->
|
val patches = patches.filter { patch ->
|
||||||
val isCompatible = patch.compatiblePackages?.any {
|
val isCompatible = patch.compatiblePackages?.any { (name, _) ->
|
||||||
it.name == patcher.context.packageMetadata.packageName
|
name == patcher.context.packageMetadata.packageName
|
||||||
} ?: false
|
} ?: false
|
||||||
|
|
||||||
val compatibleOrUniversal =
|
val compatibleOrUniversal =
|
||||||
@ -307,10 +309,7 @@ class MainActivity : FlutterActivity() {
|
|||||||
updateProgress(0.05, "Executing...", "")
|
updateProgress(0.05, "Executing...", "")
|
||||||
|
|
||||||
val patcherResult = patcher.use {
|
val patcherResult = patcher.use {
|
||||||
patcher.apply {
|
it += patches
|
||||||
acceptIntegrations(setOf(integrations))
|
|
||||||
acceptPatches(patches)
|
|
||||||
}
|
|
||||||
|
|
||||||
runBlocking {
|
runBlocking {
|
||||||
// Update the progress bar every time a patch is executed from 0.15 to 0.7
|
// Update the progress bar every time a patch is executed from 0.15 to 0.7
|
||||||
@ -318,7 +317,7 @@ class MainActivity : FlutterActivity() {
|
|||||||
val progressStep = 0.55 / totalPatchesCount
|
val progressStep = 0.55 / totalPatchesCount
|
||||||
var progress = 0.05
|
var progress = 0.05
|
||||||
|
|
||||||
patcher.apply(false).collect(FlowCollector { patchResult: PatchResult ->
|
patcher().collect(FlowCollector { patchResult: PatchResult ->
|
||||||
if (cancel(patcher::close)) return@FlowCollector
|
if (cancel(patcher::close)) return@FlowCollector
|
||||||
|
|
||||||
val msg = patchResult.exception?.let {
|
val msg = patchResult.exception?.let {
|
||||||
@ -346,10 +345,11 @@ class MainActivity : FlutterActivity() {
|
|||||||
|
|
||||||
if (cancel(patcher::close)) return@Thread
|
if (cancel(patcher::close)) return@Thread
|
||||||
|
|
||||||
ApkUtils.sign(
|
ApkUtils.signApk(
|
||||||
inFile,
|
inFile,
|
||||||
outFile,
|
outFile,
|
||||||
ApkUtils.SigningOptions(
|
"ReVanced",
|
||||||
|
ApkUtils.KeyStoreDetails(
|
||||||
keyStoreFile,
|
keyStoreFile,
|
||||||
keystorePassword,
|
keystorePassword,
|
||||||
"alias",
|
"alias",
|
||||||
|
@ -21,6 +21,7 @@ subprojects {
|
|||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
extensions.findByName("android")?.let {
|
extensions.findByName("android")?.let {
|
||||||
it as CommonExtension<*, *, *, *, *, *>
|
it as CommonExtension<*, *, *, *, *, *>
|
||||||
|
if (it.compileSdk != null && it.compileSdk!! < 31)
|
||||||
it.compileSdk = 34
|
it.compileSdk = 34
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[versions]
|
[versions]
|
||||||
revanced-patcher = "19.3.1" # TODO: Update to non-dev
|
revanced-patcher = "20.0.2"
|
||||||
revanced-library = "2.2.1"
|
revanced-library = "3.0.1"
|
||||||
desugar_jdk_libs = "2.1.2"
|
desugar_jdk_libs = "2.1.2"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
@ -17,7 +17,7 @@ pluginManagement {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||||
id("com.android.application") version "8.7.0" apply false
|
id("com.android.application") version "8.5.0" apply false
|
||||||
id("org.jetbrains.kotlin.android") version "2.0.20" apply false
|
id("org.jetbrains.kotlin.android") version "2.0.20" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,20 +158,18 @@
|
|||||||
"languageLabel": "Language",
|
"languageLabel": "Language",
|
||||||
"languageUpdated": "Language updated",
|
"languageUpdated": "Language updated",
|
||||||
"sourcesLabel": "Alternative sources",
|
"sourcesLabel": "Alternative sources",
|
||||||
"sourcesLabelHint": "Configure the alternative sources for ReVanced Patches and ReVanced Integrations",
|
"sourcesLabelHint": "Configure the alternative sources for ReVanced Patches",
|
||||||
"sourcesIntegrationsLabel": "Integrations source",
|
|
||||||
"useAlternativeSources": "Use alternative sources",
|
"useAlternativeSources": "Use alternative sources",
|
||||||
"useAlternativeSourcesHint": "Use alternative sources for ReVanced Patches and ReVanced Integrations instead of the API",
|
"useAlternativeSourcesHint": "Use alternative sources for ReVanced Patches instead of the API",
|
||||||
"sourcesResetDialogTitle": "Reset",
|
"sourcesResetDialogTitle": "Reset",
|
||||||
"sourcesResetDialogText": "Are you sure you want to reset your sources to their default values?",
|
"sourcesResetDialogText": "Are you sure you want to reset your sources to their default values?",
|
||||||
"apiURLResetDialogText": "Are you sure you want to reset your API URL to its default value?",
|
"apiURLResetDialogText": "Are you sure you want to reset your API URL to its default value?",
|
||||||
"sourcesUpdateNote": "Note: This will automatically download ReVanced Patches and ReVanced Integrations from the alternative sources.\n\nThis will connect you to the alternative source.",
|
"sourcesUpdateNote": "Note: This will automatically download ReVanced Patches from the alternative sources.\n\nThis will connect you to the alternative source.",
|
||||||
"apiURLLabel": "API URL",
|
"apiURLLabel": "API URL",
|
||||||
"apiURLHint": "Configure the API URL of ReVanced Manager",
|
"apiURLHint": "Configure the API URL of ReVanced Manager",
|
||||||
"selectApiURL": "API URL",
|
"selectApiURL": "API URL",
|
||||||
"orgPatchesLabel": "Patches organization",
|
"orgPatchesLabel": "Patches organization",
|
||||||
"sourcesPatchesLabel": "Patches source",
|
"sourcesPatchesLabel": "Patches source",
|
||||||
"orgIntegrationsLabel": "Integrations organization",
|
|
||||||
"contributorsLabel": "Contributors",
|
"contributorsLabel": "Contributors",
|
||||||
"contributorsHint": "A list of contributors of ReVanced",
|
"contributorsHint": "A list of contributors of ReVanced",
|
||||||
"logsLabel": "Share logs",
|
"logsLabel": "Share logs",
|
||||||
|
@ -62,11 +62,12 @@ class Option {
|
|||||||
required this.value,
|
required this.value,
|
||||||
required this.values,
|
required this.values,
|
||||||
required this.required,
|
required this.required,
|
||||||
required this.valueType,
|
required this.type,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Option.fromJson(Map<String, dynamic> json) {
|
factory Option.fromJson(Map<String, dynamic> json) {
|
||||||
_migrateV17ToV19(json);
|
_migrateV17ToV19(json);
|
||||||
|
_migrateV19ToV20(json);
|
||||||
|
|
||||||
return _$OptionFromJson(json);
|
return _$OptionFromJson(json);
|
||||||
}
|
}
|
||||||
@ -83,13 +84,25 @@ class Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _migrateV19ToV20(Map<String, dynamic> json) {
|
||||||
|
if (json['valueType'] != null) {
|
||||||
|
final String type = json['valueType'];
|
||||||
|
|
||||||
|
json['type'] = type.endsWith('Array')
|
||||||
|
? 'kotlin.collections.List<kotlin.${type.replaceAll('Array', '')}>'
|
||||||
|
: 'kotlin.$type';
|
||||||
|
|
||||||
|
json['valueType'] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final String key;
|
final String key;
|
||||||
final String title;
|
final String title;
|
||||||
final String description;
|
final String description;
|
||||||
final dynamic value;
|
final dynamic value;
|
||||||
final Map<String, dynamic>? values;
|
final Map<String, dynamic>? values;
|
||||||
final bool required;
|
final bool required;
|
||||||
final String valueType;
|
final String type;
|
||||||
|
|
||||||
Map toJson() => _$OptionToJson(this);
|
Map toJson() => _$OptionToJson(this);
|
||||||
}
|
}
|
||||||
|
@ -111,11 +111,7 @@ class GithubAPI {
|
|||||||
);
|
);
|
||||||
if (asset != null) {
|
if (asset != null) {
|
||||||
final String downloadUrl = asset['browser_download_url'];
|
final String downloadUrl = asset['browser_download_url'];
|
||||||
if (extension == '.apk') {
|
|
||||||
_managerAPI.setIntegrationsDownloadURL(downloadUrl);
|
|
||||||
} else {
|
|
||||||
_managerAPI.setPatchesDownloadURL(downloadUrl);
|
_managerAPI.setPatchesDownloadURL(downloadUrl);
|
||||||
}
|
|
||||||
return await _downloadManager.getSingleFile(
|
return await _downloadManager.getSingleFile(
|
||||||
downloadUrl,
|
downloadUrl,
|
||||||
);
|
);
|
||||||
|
@ -44,15 +44,13 @@ class ManagerAPI {
|
|||||||
String keystoreFile =
|
String keystoreFile =
|
||||||
'/sdcard/Android/data/app.revanced.manager.flutter/files/revanced-manager.keystore';
|
'/sdcard/Android/data/app.revanced.manager.flutter/files/revanced-manager.keystore';
|
||||||
String defaultKeystorePassword = 's3cur3p@ssw0rd';
|
String defaultKeystorePassword = 's3cur3p@ssw0rd';
|
||||||
String defaultApiUrl = 'https://api.revanced.app/';
|
String defaultApiUrl = 'https://api.revanced.app/v3';
|
||||||
String defaultRepoUrl = 'https://api.github.com';
|
String defaultRepoUrl = 'https://api.github.com';
|
||||||
String defaultPatcherRepo = 'revanced/revanced-patcher';
|
String defaultPatcherRepo = 'revanced/revanced-patcher';
|
||||||
String defaultPatchesRepo = 'revanced/revanced-patches';
|
String defaultPatchesRepo = 'revanced/revanced-patches';
|
||||||
String defaultIntegrationsRepo = 'revanced/revanced-integrations';
|
|
||||||
String defaultCliRepo = 'revanced/revanced-cli';
|
String defaultCliRepo = 'revanced/revanced-cli';
|
||||||
String defaultManagerRepo = 'revanced/revanced-manager';
|
String defaultManagerRepo = 'revanced/revanced-manager';
|
||||||
String? patchesVersion = '';
|
String? patchesVersion = '';
|
||||||
String? integrationsVersion = '';
|
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
_prefs = await SharedPreferences.getInstance();
|
_prefs = await SharedPreferences.getInstance();
|
||||||
@ -69,13 +67,15 @@ class ManagerAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Migrate to new API URL if not done yet as the old one is sunset.
|
// Migrate to new API URL if not done yet as the old one is sunset.
|
||||||
final bool hasMigratedToNewApi =
|
final bool hasMigratedToLatestApi =
|
||||||
_prefs.getBool('migratedToNewApiUrl') ?? false;
|
_prefs.getBool('migratedToLatestApiUrl') ?? false;
|
||||||
if (!hasMigratedToNewApi) {
|
if (!hasMigratedToLatestApi) {
|
||||||
final String apiUrl = getApiUrl().toLowerCase();
|
final String apiUrl = getApiUrl().toLowerCase();
|
||||||
if (apiUrl.contains('releases.revanced.app')) {
|
if (apiUrl.contains('releases.revanced.app') ||
|
||||||
|
(apiUrl.contains('api.revanced.app') &&
|
||||||
|
!apiUrl.contains('v3'))) {
|
||||||
await setApiUrl(''); // Reset to default.
|
await setApiUrl(''); // Reset to default.
|
||||||
_prefs.setBool('migratedToNewApiUrl', true);
|
_prefs.setBool('migratedToLatestApiUrl', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,10 +83,8 @@ class ManagerAPI {
|
|||||||
_prefs.getBool('migratedToAlternativeSource') ?? false;
|
_prefs.getBool('migratedToAlternativeSource') ?? false;
|
||||||
if (!hasMigratedToAlternativeSource) {
|
if (!hasMigratedToAlternativeSource) {
|
||||||
final String patchesRepo = getPatchesRepo();
|
final String patchesRepo = getPatchesRepo();
|
||||||
final String integrationsRepo = getIntegrationsRepo();
|
|
||||||
final bool usingAlternativeSources =
|
final bool usingAlternativeSources =
|
||||||
patchesRepo.toLowerCase() != defaultPatchesRepo ||
|
patchesRepo.toLowerCase() != defaultPatchesRepo;
|
||||||
integrationsRepo.toLowerCase() != defaultIntegrationsRepo;
|
|
||||||
_prefs.setBool('useAlternativeSources', usingAlternativeSources);
|
_prefs.setBool('useAlternativeSources', usingAlternativeSources);
|
||||||
_prefs.setBool('migratedToAlternativeSource', true);
|
_prefs.setBool('migratedToAlternativeSource', true);
|
||||||
}
|
}
|
||||||
@ -200,14 +198,6 @@ class ManagerAPI {
|
|||||||
await _prefs.setStringList('savedPatches-$packageName', patchesJson);
|
await _prefs.setStringList('savedPatches-$packageName', patchesJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getIntegrationsDownloadURL() {
|
|
||||||
return _prefs.getString('integrationsDownloadURL') ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> setIntegrationsDownloadURL(String value) async {
|
|
||||||
await _prefs.setString('integrationsDownloadURL', value);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Patch> getUsedPatches(String packageName) {
|
List<Patch> getUsedPatches(String packageName) {
|
||||||
final List<String> patchesJson =
|
final List<String> patchesJson =
|
||||||
_prefs.getStringList('usedPatches-$packageName') ?? [];
|
_prefs.getStringList('usedPatches-$packageName') ?? [];
|
||||||
@ -256,17 +246,6 @@ class ManagerAPI {
|
|||||||
_prefs.remove('patchOption-$packageName-$patchName-$key');
|
_prefs.remove('patchOption-$packageName-$patchName-$key');
|
||||||
}
|
}
|
||||||
|
|
||||||
String getIntegrationsRepo() {
|
|
||||||
return _prefs.getString('integrationsRepo') ?? defaultIntegrationsRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> setIntegrationsRepo(String value) async {
|
|
||||||
if (value.isEmpty || value.startsWith('/') || value.endsWith('/')) {
|
|
||||||
value = defaultIntegrationsRepo;
|
|
||||||
}
|
|
||||||
await _prefs.setString('integrationsRepo', value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getUseDynamicTheme() {
|
bool getUseDynamicTheme() {
|
||||||
return _prefs.getBool('useDynamicTheme') ?? false;
|
return _prefs.getBool('useDynamicTheme') ?? false;
|
||||||
}
|
}
|
||||||
@ -464,28 +443,7 @@ class ManagerAPI {
|
|||||||
final String currentVersion = await getCurrentPatchesVersion();
|
final String currentVersion = await getCurrentPatchesVersion();
|
||||||
final String url = getPatchesDownloadURL();
|
final String url = getPatchesDownloadURL();
|
||||||
return await _githubAPI.getReleaseFile(
|
return await _githubAPI.getReleaseFile(
|
||||||
'.jar',
|
'.rvp',
|
||||||
repoName,
|
|
||||||
currentVersion,
|
|
||||||
url,
|
|
||||||
);
|
|
||||||
} on Exception catch (e) {
|
|
||||||
if (kDebugMode) {
|
|
||||||
print(e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<File?> downloadIntegrations() async {
|
|
||||||
try {
|
|
||||||
final String repoName = !isUsingAlternativeSources()
|
|
||||||
? defaultIntegrationsRepo
|
|
||||||
: getIntegrationsRepo();
|
|
||||||
final String currentVersion = await getCurrentIntegrationsVersion();
|
|
||||||
final String url = getIntegrationsDownloadURL();
|
|
||||||
return await _githubAPI.getReleaseFile(
|
|
||||||
'.apk',
|
|
||||||
repoName,
|
repoName,
|
||||||
currentVersion,
|
currentVersion,
|
||||||
url,
|
url,
|
||||||
@ -499,18 +457,12 @@ class ManagerAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<File?> downloadManager() async {
|
Future<File?> downloadManager() async {
|
||||||
return await _revancedAPI.getLatestReleaseFile(
|
return await _revancedAPI.getLatestReleaseFile('manager');
|
||||||
'.apk',
|
|
||||||
defaultManagerRepo,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestPatchesReleaseTime() async {
|
Future<String?> getLatestPatchesReleaseTime() async {
|
||||||
if (!isUsingAlternativeSources()) {
|
if (!isUsingAlternativeSources()) {
|
||||||
return await _revancedAPI.getLatestReleaseTime(
|
return await _revancedAPI.getLatestReleaseTime('patches');
|
||||||
'.json',
|
|
||||||
defaultPatchesRepo,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
final release = await _githubAPI.getLatestRelease(getPatchesRepo());
|
final release = await _githubAPI.getLatestRelease(getPatchesRepo());
|
||||||
if (release != null) {
|
if (release != null) {
|
||||||
@ -525,39 +477,20 @@ class ManagerAPI {
|
|||||||
|
|
||||||
Future<String?> getLatestManagerReleaseTime() async {
|
Future<String?> getLatestManagerReleaseTime() async {
|
||||||
return await _revancedAPI.getLatestReleaseTime(
|
return await _revancedAPI.getLatestReleaseTime(
|
||||||
'.apk',
|
'manager',
|
||||||
defaultManagerRepo,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestManagerVersion() async {
|
Future<String?> getLatestManagerVersion() async {
|
||||||
return await _revancedAPI.getLatestReleaseVersion(
|
return await _revancedAPI.getLatestReleaseVersion(
|
||||||
'.apk',
|
'manager',
|
||||||
defaultManagerRepo,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestIntegrationsVersion() async {
|
|
||||||
if (!isUsingAlternativeSources()) {
|
|
||||||
return await _revancedAPI.getLatestReleaseVersion(
|
|
||||||
'.apk',
|
|
||||||
defaultIntegrationsRepo,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
final release = await _githubAPI.getLatestRelease(getIntegrationsRepo());
|
|
||||||
if (release != null) {
|
|
||||||
return release['tag_name'];
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String?> getLatestPatchesVersion() async {
|
Future<String?> getLatestPatchesVersion() async {
|
||||||
if (!isUsingAlternativeSources()) {
|
if (!isUsingAlternativeSources()) {
|
||||||
return await _revancedAPI.getLatestReleaseVersion(
|
return await _revancedAPI.getLatestReleaseVersion(
|
||||||
'.json',
|
'patches',
|
||||||
defaultPatchesRepo,
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final release = await _githubAPI.getLatestRelease(getPatchesRepo());
|
final release = await _githubAPI.getLatestRelease(getPatchesRepo());
|
||||||
@ -620,25 +553,6 @@ class ManagerAPI {
|
|||||||
await downloadPatches();
|
await downloadPatches();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getCurrentIntegrationsVersion() async {
|
|
||||||
integrationsVersion = _prefs.getString('integrationsVersion') ?? '0.0.0';
|
|
||||||
if (integrationsVersion == '0.0.0' || isPatchesAutoUpdate()) {
|
|
||||||
final String newIntegrationsVersion =
|
|
||||||
await getLatestIntegrationsVersion() ?? '0.0.0';
|
|
||||||
if (integrationsVersion != newIntegrationsVersion &&
|
|
||||||
newIntegrationsVersion != '0.0.0') {
|
|
||||||
await setCurrentIntegrationsVersion(newIntegrationsVersion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return integrationsVersion!;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> setCurrentIntegrationsVersion(String version) async {
|
|
||||||
await _prefs.setString('integrationsVersion', version);
|
|
||||||
await setIntegrationsDownloadURL('');
|
|
||||||
await downloadIntegrations();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<PatchedApplication>> getAppsToRemove(
|
Future<List<PatchedApplication>> getAppsToRemove(
|
||||||
List<PatchedApplication> patchedApps,
|
List<PatchedApplication> patchedApps,
|
||||||
) async {
|
) async {
|
||||||
|
@ -33,7 +33,6 @@ class PatcherAPI {
|
|||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
await loadPatches();
|
await loadPatches();
|
||||||
await _managerAPI.downloadIntegrations();
|
|
||||||
final Directory appCache = await getApplicationSupportDirectory();
|
final Directory appCache = await getApplicationSupportDirectory();
|
||||||
_dataDir = await getExternalStorageDirectory() ?? appCache;
|
_dataDir = await getExternalStorageDirectory() ?? appCache;
|
||||||
_tmpDir = Directory('${appCache.path}/patcher');
|
_tmpDir = Directory('${appCache.path}/patcher');
|
||||||
@ -153,7 +152,6 @@ class PatcherAPI {
|
|||||||
List<Patch> selectedPatches,
|
List<Patch> selectedPatches,
|
||||||
bool isFromStorage,
|
bool isFromStorage,
|
||||||
) async {
|
) async {
|
||||||
final File? integrationsFile = await _managerAPI.downloadIntegrations();
|
|
||||||
final Map<String, Map<String, dynamic>> options = {};
|
final Map<String, Map<String, dynamic>> options = {};
|
||||||
for (final patch in selectedPatches) {
|
for (final patch in selectedPatches) {
|
||||||
if (patch.options.isNotEmpty) {
|
if (patch.options.isNotEmpty) {
|
||||||
@ -169,7 +167,6 @@ class PatcherAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (integrationsFile != null) {
|
|
||||||
_dataDir.createSync();
|
_dataDir.createSync();
|
||||||
_tmpDir.createSync();
|
_tmpDir.createSync();
|
||||||
final Directory workDir = await _tmpDir.createTemp('tmp-');
|
final Directory workDir = await _tmpDir.createTemp('tmp-');
|
||||||
@ -195,7 +192,6 @@ class PatcherAPI {
|
|||||||
{
|
{
|
||||||
'inFilePath': inApkFile.path,
|
'inFilePath': inApkFile.path,
|
||||||
'outFilePath': outFile!.path,
|
'outFilePath': outFile!.path,
|
||||||
'integrationsPath': integrationsFile.path,
|
|
||||||
'selectedPatches': selectedPatches.map((p) => p.name).toList(),
|
'selectedPatches': selectedPatches.map((p) => p.name).toList(),
|
||||||
'options': options,
|
'options': options,
|
||||||
'tmpDirPath': tmpDir.path,
|
'tmpDirPath': tmpDir.path,
|
||||||
@ -209,7 +205,6 @@ class PatcherAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> stopPatcher() async {
|
Future<void> stopPatcher() async {
|
||||||
try {
|
try {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
@ -31,7 +29,7 @@ class RevancedAPI {
|
|||||||
final Map<String, List<dynamic>> contributors = {};
|
final Map<String, List<dynamic>> contributors = {};
|
||||||
try {
|
try {
|
||||||
final response = await _dio.get('/contributors');
|
final response = await _dio.get('/contributors');
|
||||||
final List<dynamic> repositories = response.data['repositories'];
|
final List<dynamic> repositories = response.data;
|
||||||
for (final Map<String, dynamic> repo in repositories) {
|
for (final Map<String, dynamic> repo in repositories) {
|
||||||
final String name = repo['name'];
|
final String name = repo['name'];
|
||||||
contributors[name] = repo['contributors'];
|
contributors[name] = repo['contributors'];
|
||||||
@ -46,21 +44,15 @@ class RevancedAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>?> _getLatestRelease(
|
Future<Map<String, dynamic>?> _getLatestRelease(
|
||||||
String extension,
|
String toolName,
|
||||||
String repoName,
|
|
||||||
) {
|
) {
|
||||||
if (!locator<ManagerAPI>().getDownloadConsent()) {
|
if (!locator<ManagerAPI>().getDownloadConsent()) {
|
||||||
return Future(() => null);
|
return Future(() => null);
|
||||||
}
|
}
|
||||||
return getToolsLock.synchronized(() async {
|
return getToolsLock.synchronized(() async {
|
||||||
try {
|
try {
|
||||||
final response = await _dio.get('/tools');
|
final response = await _dio.get('/$toolName/latest');
|
||||||
final List<dynamic> tools = response.data['tools'];
|
return response.data;
|
||||||
return tools.firstWhereOrNull(
|
|
||||||
(t) =>
|
|
||||||
(t['repository'] as String) == repoName &&
|
|
||||||
(t['name'] as String).endsWith(extension),
|
|
||||||
);
|
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(e);
|
print(e);
|
||||||
@ -71,13 +63,11 @@ class RevancedAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestReleaseVersion(
|
Future<String?> getLatestReleaseVersion(
|
||||||
String extension,
|
String toolName,
|
||||||
String repoName,
|
|
||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
final Map<String, dynamic>? release = await _getLatestRelease(
|
final Map<String, dynamic>? release = await _getLatestRelease(
|
||||||
extension,
|
toolName,
|
||||||
repoName,
|
|
||||||
);
|
);
|
||||||
if (release != null) {
|
if (release != null) {
|
||||||
return release['version'];
|
return release['version'];
|
||||||
@ -92,16 +82,14 @@ class RevancedAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<File?> getLatestReleaseFile(
|
Future<File?> getLatestReleaseFile(
|
||||||
String extension,
|
String toolName,
|
||||||
String repoName,
|
|
||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
final Map<String, dynamic>? release = await _getLatestRelease(
|
final Map<String, dynamic>? release = await _getLatestRelease(
|
||||||
extension,
|
toolName,
|
||||||
repoName,
|
|
||||||
);
|
);
|
||||||
if (release != null) {
|
if (release != null) {
|
||||||
final String url = release['browser_download_url'];
|
final String url = release['assets'][0]['download_url'];
|
||||||
return await _downloadManager.getSingleFile(url);
|
return await _downloadManager.getSingleFile(url);
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
@ -129,13 +117,10 @@ class RevancedAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<File?> downloadManager() async {
|
Future<File?> downloadManager() async {
|
||||||
final Map<String, dynamic>? release = await _getLatestRelease(
|
final Map<String, dynamic>? release = await _getLatestRelease('manager');
|
||||||
'.apk',
|
|
||||||
'revanced/revanced-manager',
|
|
||||||
);
|
|
||||||
File? outputFile;
|
File? outputFile;
|
||||||
await for (final result in _downloadManager.getFileStream(
|
await for (final result in _downloadManager.getFileStream(
|
||||||
release!['browser_download_url'] as String,
|
release!['download_url'] as String,
|
||||||
)) {
|
)) {
|
||||||
if (result is DownloadProgress) {
|
if (result is DownloadProgress) {
|
||||||
final totalSize = result.totalSize ?? 10000000;
|
final totalSize = result.totalSize ?? 10000000;
|
||||||
@ -152,17 +137,15 @@ class RevancedAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestReleaseTime(
|
Future<String?> getLatestReleaseTime(
|
||||||
String extension,
|
String toolName,
|
||||||
String repoName,
|
|
||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
final Map<String, dynamic>? release = await _getLatestRelease(
|
final Map<String, dynamic>? release = await _getLatestRelease(
|
||||||
extension,
|
toolName,
|
||||||
repoName,
|
|
||||||
);
|
);
|
||||||
if (release != null) {
|
if (release != null) {
|
||||||
final DateTime timestamp =
|
final DateTime timestamp =
|
||||||
DateTime.parse(release['timestamp'] as String);
|
DateTime.parse(release['created_at'] as String);
|
||||||
return format(timestamp, locale: 'en_short');
|
return format(timestamp, locale: 'en_short');
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
|
@ -40,11 +40,6 @@ class ContributorsView extends StatelessWidget {
|
|||||||
contributors: model.patchesContributors,
|
contributors: model.patchesContributors,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ContributorsCard(
|
|
||||||
title: 'ReVanced Integrations',
|
|
||||||
contributors: model.integrationsContributors,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
ContributorsCard(
|
ContributorsCard(
|
||||||
title: 'ReVanced CLI',
|
title: 'ReVanced CLI',
|
||||||
contributors: model.cliContributors,
|
contributors: model.cliContributors,
|
||||||
|
@ -6,19 +6,18 @@ class ContributorsViewModel extends BaseViewModel {
|
|||||||
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
||||||
List<dynamic> patcherContributors = [];
|
List<dynamic> patcherContributors = [];
|
||||||
List<dynamic> patchesContributors = [];
|
List<dynamic> patchesContributors = [];
|
||||||
List<dynamic> integrationsContributors = [];
|
|
||||||
List<dynamic> cliContributors = [];
|
List<dynamic> cliContributors = [];
|
||||||
List<dynamic> managerContributors = [];
|
List<dynamic> managerContributors = [];
|
||||||
|
|
||||||
|
String repoName(String repo) => repo.split('/').last;
|
||||||
|
|
||||||
Future<void> getContributors() async {
|
Future<void> getContributors() async {
|
||||||
final Map<String, List<dynamic>> contributors =
|
final Map<String, List<dynamic>> contributors =
|
||||||
await _managerAPI.getContributors();
|
await _managerAPI.getContributors();
|
||||||
patcherContributors = contributors[_managerAPI.defaultPatcherRepo] ?? [];
|
patcherContributors = contributors[repoName(_managerAPI.defaultPatcherRepo)] ?? [];
|
||||||
patchesContributors = contributors[_managerAPI.defaultPatchesRepo] ?? [];
|
patchesContributors = contributors[repoName(_managerAPI.defaultPatchesRepo)] ?? [];
|
||||||
integrationsContributors =
|
cliContributors = contributors[repoName(_managerAPI.defaultCliRepo)] ?? [];
|
||||||
contributors[_managerAPI.defaultIntegrationsRepo] ?? [];
|
managerContributors = contributors[repoName(_managerAPI.defaultManagerRepo)] ?? [];
|
||||||
cliContributors = contributors[_managerAPI.defaultCliRepo] ?? [];
|
|
||||||
managerContributors = contributors[_managerAPI.defaultManagerRepo] ?? [];
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,11 +311,8 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
_toast.showBottom(t.homeView.downloadingMessage);
|
_toast.showBottom(t.homeView.downloadingMessage);
|
||||||
final String patchesVersion =
|
final String patchesVersion =
|
||||||
await _managerAPI.getLatestPatchesVersion() ?? '0.0.0';
|
await _managerAPI.getLatestPatchesVersion() ?? '0.0.0';
|
||||||
final String integrationsVersion =
|
if (patchesVersion != '0.0.0') {
|
||||||
await _managerAPI.getLatestIntegrationsVersion() ?? '0.0.0';
|
|
||||||
if (patchesVersion != '0.0.0' && integrationsVersion != '0.0.0') {
|
|
||||||
await _managerAPI.setCurrentPatchesVersion(patchesVersion);
|
await _managerAPI.setCurrentPatchesVersion(patchesVersion);
|
||||||
await _managerAPI.setCurrentIntegrationsVersion(integrationsVersion);
|
|
||||||
_toast.showBottom(t.homeView.downloadedMessage);
|
_toast.showBottom(t.homeView.downloadedMessage);
|
||||||
forceRefresh(context);
|
forceRefresh(context);
|
||||||
} else {
|
} else {
|
||||||
|
@ -330,7 +330,6 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
'Version compatibility check: ${_managerAPI.isVersionCompatibilityCheckEnabled()}',
|
'Version compatibility check: ${_managerAPI.isVersionCompatibilityCheckEnabled()}',
|
||||||
'Show universal patches: ${_managerAPI.areUniversalPatchesEnabled()}',
|
'Show universal patches: ${_managerAPI.areUniversalPatchesEnabled()}',
|
||||||
'Patches source: ${_managerAPI.getPatchesRepo()}',
|
'Patches source: ${_managerAPI.getPatchesRepo()}',
|
||||||
'Integration source: ${_managerAPI.getIntegrationsRepo()}', //
|
|
||||||
|
|
||||||
'\n- Logs',
|
'\n- Logs',
|
||||||
logsTrimmed.join('\n'),
|
logsTrimmed.join('\n'),
|
||||||
|
@ -44,20 +44,20 @@ class PatchOptionsView extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
for (final Option option in model.modifiedOptions)
|
for (final Option option in model.modifiedOptions)
|
||||||
if (option.valueType == 'String' ||
|
if (option.type == 'kotlin.String' ||
|
||||||
option.valueType == 'Int')
|
option.type == 'kotlin.Int')
|
||||||
IntAndStringPatchOption(
|
IntAndStringPatchOption(
|
||||||
patchOption: option,
|
patchOption: option,
|
||||||
model: model,
|
model: model,
|
||||||
)
|
)
|
||||||
else if (option.valueType == 'Boolean')
|
else if (option.type == 'kotlin.Boolean')
|
||||||
BooleanPatchOption(
|
BooleanPatchOption(
|
||||||
patchOption: option,
|
patchOption: option,
|
||||||
model: model,
|
model: model,
|
||||||
)
|
)
|
||||||
else if (option.valueType == 'StringArray' ||
|
else if (option.type == 'kotlin.collections.List<kotlin.String>' ||
|
||||||
option.valueType == 'IntArray' ||
|
option.type == 'kotlin.collections.List<kotlin.Int>' ||
|
||||||
option.valueType == 'LongArray')
|
option.type == 'kotlin.collections.List<kotlin.Long>')
|
||||||
IntStringLongListPatchOption(
|
IntStringLongListPatchOption(
|
||||||
patchOption: option,
|
patchOption: option,
|
||||||
model: model,
|
model: model,
|
||||||
|
@ -74,7 +74,7 @@ class PatchOptionsViewModel extends BaseViewModel {
|
|||||||
title: option.title,
|
title: option.title,
|
||||||
description: option.description,
|
description: option.description,
|
||||||
values: option.values,
|
values: option.values,
|
||||||
valueType: option.valueType,
|
type: option.type,
|
||||||
value: value,
|
value: value,
|
||||||
required: option.required,
|
required: option.required,
|
||||||
key: option.key,
|
key: option.key,
|
||||||
@ -90,7 +90,7 @@ class PatchOptionsViewModel extends BaseViewModel {
|
|||||||
title: option.title,
|
title: option.title,
|
||||||
description: option.description,
|
description: option.description,
|
||||||
values: option.values,
|
values: option.values,
|
||||||
valueType: option.valueType,
|
type: option.type,
|
||||||
value: option.value is List ? option.value.toList() : option.value,
|
value: option.value is List ? option.value.toList() : option.value,
|
||||||
required: option.required,
|
required: option.required,
|
||||||
key: option.key,
|
key: option.key,
|
||||||
|
@ -14,16 +14,11 @@ class SManageSources extends BaseViewModel {
|
|||||||
|
|
||||||
final TextEditingController _orgPatSourceController = TextEditingController();
|
final TextEditingController _orgPatSourceController = TextEditingController();
|
||||||
final TextEditingController _patSourceController = TextEditingController();
|
final TextEditingController _patSourceController = TextEditingController();
|
||||||
final TextEditingController _orgIntSourceController = TextEditingController();
|
|
||||||
final TextEditingController _intSourceController = TextEditingController();
|
|
||||||
|
|
||||||
Future<void> showSourcesDialog(BuildContext context) async {
|
Future<void> showSourcesDialog(BuildContext context) async {
|
||||||
final String patchesRepo = _managerAPI.getPatchesRepo();
|
final String patchesRepo = _managerAPI.getPatchesRepo();
|
||||||
final String integrationsRepo = _managerAPI.getIntegrationsRepo();
|
|
||||||
_orgPatSourceController.text = patchesRepo.split('/')[0];
|
_orgPatSourceController.text = patchesRepo.split('/')[0];
|
||||||
_patSourceController.text = patchesRepo.split('/')[1];
|
_patSourceController.text = patchesRepo.split('/')[1];
|
||||||
_orgIntSourceController.text = integrationsRepo.split('/')[0];
|
|
||||||
_intSourceController.text = integrationsRepo.split('/')[1];
|
|
||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
@ -72,38 +67,6 @@ class SManageSources extends BaseViewModel {
|
|||||||
hintText: patchesRepo.split('/')[1],
|
hintText: patchesRepo.split('/')[1],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
|
||||||
// Integrations owner's name
|
|
||||||
TextField(
|
|
||||||
controller: _orgIntSourceController,
|
|
||||||
autocorrect: false,
|
|
||||||
onChanged: (value) => notifyListeners(),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.merge_outlined,
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
border: const OutlineInputBorder(),
|
|
||||||
labelText: t.settingsView.orgIntegrationsLabel,
|
|
||||||
hintText: integrationsRepo.split('/')[0],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
// Integrations repository's name
|
|
||||||
TextField(
|
|
||||||
controller: _intSourceController,
|
|
||||||
autocorrect: false,
|
|
||||||
onChanged: (value) => notifyListeners(),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.merge_outlined,
|
|
||||||
color: Colors.transparent,
|
|
||||||
),
|
|
||||||
border: const OutlineInputBorder(),
|
|
||||||
labelText: t.settingsView.sourcesIntegrationsLabel,
|
|
||||||
hintText: integrationsRepo.split('/')[1],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Text(t.settingsView.sourcesUpdateNote),
|
Text(t.settingsView.sourcesUpdateNote),
|
||||||
],
|
],
|
||||||
@ -113,8 +76,6 @@ class SManageSources extends BaseViewModel {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
_orgPatSourceController.clear();
|
_orgPatSourceController.clear();
|
||||||
_patSourceController.clear();
|
_patSourceController.clear();
|
||||||
_orgIntSourceController.clear();
|
|
||||||
_intSourceController.clear();
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: Text(t.cancelButton),
|
child: Text(t.cancelButton),
|
||||||
@ -124,11 +85,7 @@ class SManageSources extends BaseViewModel {
|
|||||||
_managerAPI.setPatchesRepo(
|
_managerAPI.setPatchesRepo(
|
||||||
'${_orgPatSourceController.text.trim()}/${_patSourceController.text.trim()}',
|
'${_orgPatSourceController.text.trim()}/${_patSourceController.text.trim()}',
|
||||||
);
|
);
|
||||||
_managerAPI.setIntegrationsRepo(
|
|
||||||
'${_orgIntSourceController.text.trim()}/${_intSourceController.text.trim()}',
|
|
||||||
);
|
|
||||||
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
||||||
_managerAPI.setCurrentIntegrationsVersion('0.0.0');
|
|
||||||
_managerAPI.setLastUsedPatchesVersion();
|
_managerAPI.setLastUsedPatchesVersion();
|
||||||
_toast.showBottom(t.settingsView.restartAppForChanges);
|
_toast.showBottom(t.settingsView.restartAppForChanges);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
@ -154,9 +111,7 @@ class SManageSources extends BaseViewModel {
|
|||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_managerAPI.setPatchesRepo('');
|
_managerAPI.setPatchesRepo('');
|
||||||
_managerAPI.setIntegrationsRepo('');
|
|
||||||
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
||||||
_managerAPI.setCurrentIntegrationsVersion('0.0.0');
|
|
||||||
_toast.showBottom(t.settingsView.restartAppForChanges);
|
_toast.showBottom(t.settingsView.restartAppForChanges);
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
..pop()
|
..pop()
|
||||||
|
@ -56,7 +56,6 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
void useAlternativeSources(bool value) {
|
void useAlternativeSources(bool value) {
|
||||||
_managerAPI.useAlternativeSources(value);
|
_managerAPI.useAlternativeSources(value);
|
||||||
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
||||||
_managerAPI.setCurrentIntegrationsVersion('0.0.0');
|
|
||||||
_managerAPI.setLastUsedPatchesVersion();
|
_managerAPI.setLastUsedPatchesVersion();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ class IntStringLongListPatchOption extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final List<dynamic> values = List.from(patchOption.value ?? []);
|
final List<dynamic> values = List.from(patchOption.value ?? []);
|
||||||
final ValueNotifier patchOptionValue = ValueNotifier(values);
|
final ValueNotifier patchOptionValue = ValueNotifier(values);
|
||||||
final String type = patchOption.valueType;
|
final String type = patchOption.type;
|
||||||
|
|
||||||
String getKey(dynamic value) {
|
String getKey(dynamic value) {
|
||||||
if (value != null && patchOption.values != null) {
|
if (value != null && patchOption.values != null) {
|
||||||
@ -408,12 +408,12 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final bool isStringOption = widget.patchOption.valueType.contains('String');
|
final bool isStringOption = widget.patchOption.type.contains('String');
|
||||||
final bool isArrayOption = widget.patchOption.valueType.contains('Array');
|
final bool isListOption = widget.patchOption.type.contains('List');
|
||||||
selectedKey = selectedKey == '' ? selectedKey : widget.selectedKey;
|
selectedKey = selectedKey == '' ? selectedKey : widget.selectedKey;
|
||||||
final bool isValueArray = widget.value?.startsWith('[') ?? false;
|
final bool isValueArray = widget.value?.startsWith('[') ?? false;
|
||||||
final bool shouldResetValue =
|
final bool shouldResetValue =
|
||||||
!isStringOption && isArrayOption && selectedKey == '' && isValueArray;
|
!isStringOption && isListOption && selectedKey == '' && isValueArray;
|
||||||
controller.text = shouldResetValue ? '' : widget.value ?? '';
|
controller.text = shouldResetValue ? '' : widget.value ?? '';
|
||||||
defaultValue ??= controller.text;
|
defaultValue ??= controller.text;
|
||||||
return Column(
|
return Column(
|
||||||
@ -479,7 +479,7 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
|
|||||||
} else {
|
} else {
|
||||||
controller.text = widget.patchOption.values![value].toString();
|
controller.text = widget.patchOption.values![value].toString();
|
||||||
widget.onChanged(
|
widget.onChanged(
|
||||||
isArrayOption
|
isListOption
|
||||||
? widget.patchOption.values![value]
|
? widget.patchOption.values![value]
|
||||||
: controller.text,
|
: controller.text,
|
||||||
);
|
);
|
||||||
@ -492,9 +492,9 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
|
|||||||
if (selectedKey == '')
|
if (selectedKey == '')
|
||||||
TextFormField(
|
TextFormField(
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
if (widget.patchOption.valueType.contains('Int'))
|
if (widget.patchOption.type.contains('Int'))
|
||||||
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
|
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
|
||||||
if (widget.patchOption.valueType.contains('Long'))
|
if (widget.patchOption.type.contains('Long'))
|
||||||
FilteringTextInputFormatter.allow(RegExp(r'^[0-9]*\.?[0-9]*')),
|
FilteringTextInputFormatter.allow(RegExp(r'^[0-9]*\.?[0-9]*')),
|
||||||
],
|
],
|
||||||
controller: controller,
|
controller: controller,
|
||||||
@ -505,7 +505,7 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
|
|||||||
tooltip: t.patchOptionsView.tooltip,
|
tooltip: t.patchOptionsView.tooltip,
|
||||||
itemBuilder: (BuildContext context) {
|
itemBuilder: (BuildContext context) {
|
||||||
return [
|
return [
|
||||||
if (isArrayOption)
|
if (isListOption)
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: 'remove',
|
value: 'remove',
|
||||||
child: Text(t.remove),
|
child: Text(t.remove),
|
||||||
|
@ -33,7 +33,7 @@ bool hasUnsupportedRequiredOption(List<Option> options, Patch patch) {
|
|||||||
option.key,
|
option.key,
|
||||||
) ==
|
) ==
|
||||||
null) {
|
null) {
|
||||||
requiredOptionsType.add(option.valueType);
|
requiredOptionsType.add(option.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (final String optionType in requiredOptionsType) {
|
for (final String optionType in requiredOptionsType) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user