Added uninstall option

This commit is contained in:
Imran Remtulla
2023-02-04 18:58:14 -05:00
parent 15ad3bb439
commit a2c227931e
12 changed files with 148 additions and 62 deletions

View File

@@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/components/generated_form_modal.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/main.dart';
@@ -361,40 +362,12 @@ class _AppPageState extends State<AppPage> {
onPressed: app?.downloadProgress != null
? null
: () {
showDialog(
context: context,
builder: (BuildContext ctx) {
return AlertDialog(
title: Text(tr('removeAppQuestion')),
content: Text(tr(
'xWillBeRemovedButRemainInstalled',
args: [
app?.installedInfo?.name ??
app?.app.name ??
tr('app')
])),
actions: [
TextButton(
onPressed: () {
HapticFeedback
.selectionClick();
appsProvider.removeApps(
[app!.app.id]).then((_) {
int count = 0;
Navigator.of(context)
.popUntil((_) =>
count++ >= 2);
});
},
child: Text(tr('remove'))),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(tr('cancel')))
],
);
});
appsProvider.removeAppsWithModal(
context, [app!.app]).then((value) {
if (value == true) {
Navigator.of(context).pop();
}
});
},
style: TextButton.styleFrom(
foregroundColor:
@@ -414,3 +387,18 @@ class _AppPageState extends State<AppPage> {
);
}
}
class RemoveAppsModal extends StatefulWidget {
const RemoveAppsModal({super.key, this.apps = const []});
final List<App> apps;
@override
State<RemoveAppsModal> createState() => _RemoveAppsModalState();
}
class _RemoveAppsModalState extends State<RemoveAppsModal> {
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}

View File

@@ -389,28 +389,30 @@ class AppsPageState extends State<AppsPage> {
onPressed: selectedApps.isEmpty
? null
: () {
showDialog<Map<String, dynamic>?>(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
title: tr(
'removeSelectedAppsQuestion'),
items: const [],
initValid: true,
message: tr(
'xWillBeRemovedButRemainInstalled',
args: [
plural('apps',
selectedApps.length)
]),
);
}).then((values) {
if (values != null) {
appsProvider.removeApps(selectedApps
.map((e) => e.id)
.toList());
}
});
appsProvider.removeAppsWithModal(
context, selectedApps.toList());
// showDialog<Map<String, dynamic>?>(
// context: context,
// builder: (BuildContext ctx) {
// return GeneratedFormModal(
// title: tr(
// 'removeSelectedAppsQuestion'),
// items: const [],
// initValid: true,
// message: tr(
// 'xWillBeRemovedButRemainInstalled',
// args: [
// plural('apps',
// selectedApps.length)
// ]),
// );
// }).then((values) {
// if (values != null) {
// appsProvider.removeApps(selectedApps
// .map((e) => e.id)
// .toList());
// }
// });
},
tooltip: tr('removeSelectedApps'),
icon: const Icon(Icons.delete_outline_outlined),

View File

@@ -5,6 +5,7 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:android_intent_plus/flag.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@@ -12,6 +13,8 @@ import 'package:flutter/services.dart';
import 'package:install_plugin_v2/install_plugin_v2.dart';
import 'package:installed_apps/app_info.dart';
import 'package:installed_apps/installed_apps.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/components/generated_form_modal.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/logs_provider.dart';
import 'package:obtainium/providers/notifications_provider.dart';
@@ -23,6 +26,7 @@ import 'package:path_provider/path_provider.dart';
import 'package:flutter_fgbg/flutter_fgbg.dart';
import 'package:obtainium/providers/source_provider.dart';
import 'package:http/http.dart';
import 'package:android_intent_plus/android_intent.dart';
class AppInMemory {
late App app;
@@ -259,6 +263,15 @@ class AppsProvider with ChangeNotifier {
attemptToCorrectInstallStatus: false);
}
void uninstallApp(String appId) async {
var intent = AndroidIntent(
action: 'android.intent.action.DELETE',
data: 'package:$appId',
flags: <int>[Flag.FLAG_ACTIVITY_NEW_TASK],
package: 'vnd.android.package-archive');
await intent.launch();
}
Future<String?> confirmApkUrl(App app, BuildContext? context) async {
// If the App has more than one APK, the user should pick one (if context provided)
String? apkUrl = app.apkUrls[app.preferredApkIndex];
@@ -622,6 +635,49 @@ class AppsProvider with ChangeNotifier {
}
}
Future<bool> removeAppsWithModal(BuildContext context, List<App> apps) async {
var showUninstallOption =
apps.where((a) => a.installedVersion != null).isNotEmpty;
var values = await showDialog(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
title: plural('removeAppQuestion', apps.length),
items: !showUninstallOption
? []
: [
[
GeneratedFormSwitch('rmAppEntry',
label: tr('removeFromObtainium'), defaultValue: true)
],
[
GeneratedFormSwitch('uninstallApp',
label: tr('uninstallFromDevice'))
]
],
initValid: true,
);
});
if (values != null) {
bool uninstall = values['uninstallApp'] == true && showUninstallOption;
bool remove = values['rmAppEntry'] == true || !showUninstallOption;
if (uninstall) {
for (var i = 0; i < apps.length; i++) {
if (apps[i].installedVersion != null) {
uninstallApp(apps[i].id);
apps[i].installedVersion = null;
}
}
await saveApps(apps, attemptToCorrectInstallStatus: false);
}
if (remove) {
await removeApps(apps.map((e) => e.id).toList());
}
return uninstall || remove;
}
return false;
}
Future<App?> checkUpdate(String appId) async {
App? currentApp = apps[appId]!.app;
SourceProvider sourceProvider = SourceProvider();