diff --git a/assets/i18n/en.json b/assets/i18n/en.json index 8ffd5bbd35..e62390db70 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -89,7 +89,11 @@ "notificationTitle": "ReVanced Manager is patching", "notificationText": "Tap to return to the installer", "shareApkMenuOption": "Share APK", - "shareLogMenuOption": "Share log" + "shareLogMenuOption": "Share log", + "installErrorDialogTitle": "Error", + "installErrorDialogText1": "Root install is not possible with the current patches selection.\nRepatch your app or choose non-root install.", + "installErrorDialogText2": "Non-root install is not possible with the current patches selection.\nRepatch your app or choose root install if you have your device rooted.", + "installErrorDialogText3": "Root install is not possible as the original APK was selected from storage.\nSelect an installed app or choose non-root install." }, "settingsView": { "widgetTitle": "Settings", diff --git a/lib/models/patched_application.dart b/lib/models/patched_application.dart index aa89133e84..192c30ad2c 100644 --- a/lib/models/patched_application.dart +++ b/lib/models/patched_application.dart @@ -17,6 +17,7 @@ class PatchedApplication { Uint8List icon; DateTime patchDate; bool isRooted; + bool isFromStorage; bool hasUpdates; List appliedPatches; List changelog; @@ -29,6 +30,7 @@ class PatchedApplication { required this.icon, required this.patchDate, this.isRooted = false, + this.isFromStorage = false, this.hasUpdates = false, this.appliedPatches = const [], this.changelog = const [], diff --git a/lib/ui/views/app_selector/app_selector_viewmodel.dart b/lib/ui/views/app_selector/app_selector_viewmodel.dart index 00e0f6a508..faa8702033 100644 --- a/lib/ui/views/app_selector/app_selector_viewmodel.dart +++ b/lib/ui/views/app_selector/app_selector_viewmodel.dart @@ -54,6 +54,7 @@ class AppSelectorViewModel extends BaseViewModel { apkFilePath: result.files.single.path!, icon: application.icon, patchDate: DateTime.now(), + isFromStorage: true, ); locator().selectedPatches.clear(); locator().notifyListeners(); diff --git a/lib/ui/views/installer/installer_view.dart b/lib/ui/views/installer/installer_view.dart index 7f747f0bcc..8ac9ca7c27 100644 --- a/lib/ui/views/installer/installer_view.dart +++ b/lib/ui/views/installer/installer_view.dart @@ -111,7 +111,10 @@ class InstallerView extends StatelessWidget { label: I18nText('installerView.installRootButton'), isExpanded: true, - onPressed: () => model.installResult(true), + onPressed: () => model.installResult( + context, + true, + ), ), ), Visibility( @@ -125,7 +128,10 @@ class InstallerView extends StatelessWidget { child: CustomMaterialButton( label: I18nText('installerView.installButton'), isExpanded: true, - onPressed: () => model.installResult(false), + onPressed: () => model.installResult( + context, + false, + ), ), ), ], diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index 877784d03e..165a250a43 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -10,6 +10,7 @@ import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/patcher_api.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; +import 'package:revanced_manager/ui/widgets/installerView/custom_material_button.dart'; import 'package:stacked/stacked.dart'; import 'package:wakelock/wakelock.dart'; @@ -133,28 +134,56 @@ class InstallerViewModel extends BaseViewModel { isPatching = false; } - void installResult(bool installAsRoot) async { + void installResult(BuildContext context, bool installAsRoot) async { _app.isRooted = installAsRoot; - update( - 1.0, - 'Installing...', - _app.isRooted - ? 'Installing patched file using root method' - : 'Installing patched file using nonroot method', - ); - isInstalled = await _patcherAPI.installPatchedFile(_app); - if (isInstalled) { - update(1.0, 'Installed!', 'Installed!'); - _app.patchDate = DateTime.now(); - _app.appliedPatches = _patches.map((p) => p.name).toList(); - bool hasMicroG = _patches.any((p) => p.name.endsWith('microg-support')); - if (hasMicroG) { - _app.packageName = _app.packageName.replaceFirst( - 'com.google.', - 'app.revanced.', - ); + bool hasMicroG = _patches.any((p) => p.name.endsWith('microg-support')); + bool rootMicroG = installAsRoot && hasMicroG; + bool rootFromStorage = installAsRoot && _app.isFromStorage; + bool ytWithoutRootMicroG = + !installAsRoot && !hasMicroG && _app.packageName.contains('youtube'); + if (rootMicroG || rootFromStorage || ytWithoutRootMicroG) { + return showDialog( + context: context, + builder: (context) => AlertDialog( + title: I18nText('installerView.installErrorDialogTitle'), + backgroundColor: Theme.of(context).colorScheme.secondaryContainer, + content: I18nText( + rootMicroG + ? 'installerView.installErrorDialogText1' + : rootFromStorage + ? 'installerView.installErrorDialogText3' + : 'installerView.installErrorDialogText2', + ), + actions: [ + CustomMaterialButton( + label: I18nText('okButton'), + onPressed: () => Navigator.of(context).pop(), + ) + ], + ), + ); + } else { + update( + 1.0, + 'Installing...', + _app.isRooted + ? 'Installing patched file using root method' + : 'Installing patched file using nonroot method', + ); + isInstalled = await _patcherAPI.installPatchedFile(_app); + if (isInstalled) { + update(1.0, 'Installed!', 'Installed!'); + _app.isFromStorage = false; + _app.patchDate = DateTime.now(); + _app.appliedPatches = _patches.map((p) => p.name).toList(); + if (hasMicroG) { + _app.packageName = _app.packageName.replaceFirst( + 'com.google.', + 'app.revanced.', + ); + } + await _managerAPI.savePatchedApp(_app); } - await _managerAPI.savePatchedApp(_app); } }