diff --git a/assets/i18n/en.json b/assets/i18n/en.json index b001952e..67e32016 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -121,8 +121,11 @@ "openButton": "Open", "uninstallButton": "Uninstall", "patchButton": "Patch", + "unpatchButton": "Unpatch", "uninstallDialogTitle": "Uninstall", "uninstallDialogText": "Are you sure you want to uninstall this app?", + "unpatchDialogTitle": "Unpatch", + "unpatchDialogText": "Are you sure you want to unpatch this app?", "rootDialogTitle": "Error", "rootDialogText": "App was installed with root mode enabled but currently root mode is disabled.\nPlease enable root mode first.", "packageNameLabel": "Package Name", diff --git a/lib/ui/widgets/appInfoView/app_info_view.dart b/lib/ui/widgets/appInfoView/app_info_view.dart index 3ab67461..90c53dc3 100644 --- a/lib/ui/widgets/appInfoView/app_info_view.dart +++ b/lib/ui/widgets/appInfoView/app_info_view.dart @@ -64,7 +64,7 @@ class AppInfoView extends StatelessWidget { CustomCard( child: IntrinsicHeight( child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: () => model.openApp(app), @@ -96,8 +96,11 @@ class AppInfoView extends StatelessWidget { color: Theme.of(context).canvasColor, ), InkWell( - onTap: () => - model.showUninstallAlertDialog(context, app), + onTap: () => model.showUninstallAlertDialog( + context, + app, + false, + ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -154,6 +157,45 @@ class AppInfoView extends StatelessWidget { ], ), ), + Visibility( + visible: app.isRooted, + child: VerticalDivider( + color: Theme.of(context).canvasColor, + ), + ), + Visibility( + visible: app.isRooted, + child: InkWell( + onTap: () => model.showUninstallAlertDialog( + context, + app, + true, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.settings_backup_restore_outlined, + color: + Theme.of(context).colorScheme.primary, + ), + const SizedBox(height: 10), + I18nText( + 'appInfoView.unpatchButton', + child: Text( + '', + style: TextStyle( + color: Theme.of(context) + .colorScheme + .primary, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ), ], ), ), diff --git a/lib/ui/widgets/appInfoView/app_info_viewmodel.dart b/lib/ui/widgets/appInfoView/app_info_viewmodel.dart index 519d1a72..97b57fe2 100644 --- a/lib/ui/widgets/appInfoView/app_info_viewmodel.dart +++ b/lib/ui/widgets/appInfoView/app_info_viewmodel.dart @@ -19,12 +19,15 @@ class AppInfoViewModel extends BaseViewModel { final PatcherAPI _patcherAPI = locator(); final RootAPI _rootAPI = RootAPI(); - Future uninstallApp(PatchedApplication app) async { + Future uninstallApp(PatchedApplication app, bool onlyUnpatch) async { if (app.isRooted) { bool hasRootPermissions = await _rootAPI.hasRootPermissions(); if (hasRootPermissions) { _rootAPI.deleteApp(app.packageName, app.apkFilePath); _managerAPI.deletePatchedApp(app); + if (!onlyUnpatch) { + DeviceApps.uninstallApp(app.packageName); + } } } else { DeviceApps.uninstallApp(app.packageName); @@ -43,32 +46,39 @@ class AppInfoViewModel extends BaseViewModel { Future showUninstallAlertDialog( BuildContext context, PatchedApplication app, + bool onlyUnpatch, ) async { - if (app.isRooted) { - bool hasRootPermissions = await _rootAPI.hasRootPermissions(); - if (!hasRootPermissions) { - return showDialog( - context: context, - builder: (context) => AlertDialog( - title: I18nText('appInfoView.rootDialogTitle'), - backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('appInfoView.rootDialogText'), - actions: [ - CustomMaterialButton( - label: I18nText('okButton'), - onPressed: () => Navigator.of(context).pop(), - ) - ], - ), - ); - } + bool hasRootPermissions = await _rootAPI.hasRootPermissions(); + if (app.isRooted && !hasRootPermissions) { + return showDialog( + context: context, + builder: (context) => AlertDialog( + title: I18nText('appInfoView.rootDialogTitle'), + backgroundColor: Theme.of(context).colorScheme.secondaryContainer, + content: I18nText('appInfoView.rootDialogText'), + actions: [ + CustomMaterialButton( + label: I18nText('okButton'), + onPressed: () => Navigator.of(context).pop(), + ) + ], + ), + ); } else { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('appInfoView.uninstallDialogTitle'), + title: I18nText( + onlyUnpatch + ? 'appInfoView.unpatchDialogTitle' + : 'appInfoView.uninstallDialogTitle', + ), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('appInfoView.uninstallDialogText'), + content: I18nText( + onlyUnpatch + ? 'appInfoView.unpatchDialogText' + : 'appInfoView.uninstallDialogText', + ), actions: [ CustomMaterialButton( isFilled: false, @@ -78,7 +88,7 @@ class AppInfoViewModel extends BaseViewModel { CustomMaterialButton( label: I18nText('okButton'), onPressed: () { - uninstallApp(app); + uninstallApp(app, onlyUnpatch); locator().initialize(context); Navigator.of(context).pop(); Navigator.of(context).pop();