diff --git a/lib/services/patcher_api.dart b/lib/services/patcher_api.dart index cf6e6b97..bd7597a6 100644 --- a/lib/services/patcher_api.dart +++ b/lib/services/patcher_api.dart @@ -1,12 +1,12 @@ import 'dart:io'; -import 'package:app_installer/app_installer.dart'; import 'package:collection/collection.dart'; import 'package:cr_file_saver/file_saver.dart'; import 'package:device_apps/device_apps.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:injectable/injectable.dart'; +import 'package:install_plugin/install_plugin.dart'; import 'package:path_provider/path_provider.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/models/patch.dart'; @@ -232,10 +232,8 @@ class PatcherAPI { ); } } else { - await AppInstaller.installApk(_outFile!.path); - return await DeviceApps.isAppInstalled( - patchedApp.packageName, - ); + final install = await InstallPlugin.installApk(_outFile!.path); + return install['isSuccess']; } } on Exception catch (e) { if (kDebugMode) { diff --git a/lib/services/root_api.dart b/lib/services/root_api.dart index af1276c4..1a77c644 100644 --- a/lib/services/root_api.dart +++ b/lib/services/root_api.dart @@ -73,7 +73,7 @@ class RootAPI { } Future> getInstalledApps() async { - final List apps = List.empty(); + final List apps = List.empty(growable: true); try { String? res = await Root.exec( cmd: 'ls "$_revancedDirPath"', diff --git a/lib/ui/views/app_selector/app_selector_view.dart b/lib/ui/views/app_selector/app_selector_view.dart index e3ab0c41..6368df61 100644 --- a/lib/ui/views/app_selector/app_selector_view.dart +++ b/lib/ui/views/app_selector/app_selector_view.dart @@ -88,7 +88,7 @@ class _AppSelectorViewState extends State { ), ), ) - : model.apps.isEmpty + : model.allApps.isEmpty ? const AppSkeletonLoader() : Padding( padding: const EdgeInsets.symmetric(horizontal: 12.0) diff --git a/lib/ui/views/app_selector/app_selector_viewmodel.dart b/lib/ui/views/app_selector/app_selector_viewmodel.dart index 9eacb93c..e0784abd 100644 --- a/lib/ui/views/app_selector/app_selector_viewmodel.dart +++ b/lib/ui/views/app_selector/app_selector_viewmodel.dart @@ -45,9 +45,7 @@ class AppSelectorViewModel extends BaseViewModel { .length .compareTo(_patcherAPI.getFilteredPatches(a.packageName).length), ); - noApps = apps.isEmpty; getAllApps(); - notifyListeners(); } @@ -57,7 +55,7 @@ class AppSelectorViewModel extends BaseViewModel { .toSet() .where((name) => !apps.any((app) => app.packageName == name)) .toList(); - + noApps = allApps.isEmpty; return allApps; } diff --git a/lib/ui/views/home/home_view.dart b/lib/ui/views/home/home_view.dart index 07ff7dad..d3e4153d 100644 --- a/lib/ui/views/home/home_view.dart +++ b/lib/ui/views/home/home_view.dart @@ -128,7 +128,7 @@ class HomeView extends StatelessWidget { }, child: model.showUpdatableApps ? AvailableUpdatesCard() - : InstalledAppsCard(), + : const InstalledAppsCard(), ), ], ), diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index 4ffdd86b..f67125ab 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -1,13 +1,13 @@ // ignore_for_file: use_build_context_synchronously import 'dart:async'; import 'dart:io'; -import 'package:app_installer/app_installer.dart'; import 'package:cross_connectivity/cross_connectivity.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:injectable/injectable.dart'; +import 'package:install_plugin/install_plugin.dart'; import 'package:path_provider/path_provider.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.router.dart'; @@ -51,7 +51,7 @@ class HomeViewModel extends BaseViewModel { _toast.showBottom('homeView.installingMessage'); final File? managerApk = await _managerAPI.downloadManager(); if (managerApk != null) { - await AppInstaller.installApk(managerApk.path); + await InstallPlugin.installApk(managerApk.path); } else { _toast.showBottom('homeView.errorDownloadMessage'); } @@ -72,7 +72,7 @@ class HomeViewModel extends BaseViewModel { _toast.showBottom('homeView.installingMessage'); final File? managerApk = await _managerAPI.downloadManager(); if (managerApk != null) { - await AppInstaller.installApk(managerApk.path); + await InstallPlugin.installApk(managerApk.path); } else { _toast.showBottom('homeView.errorDownloadMessage'); } @@ -272,7 +272,7 @@ class HomeViewModel extends BaseViewModel { child: CustomMaterialButton( label: I18nText('updateButton'), onPressed: () async { - await AppInstaller.installApk( + await InstallPlugin.installApk( downloadedApk!.path, ); }, @@ -318,7 +318,7 @@ class HomeViewModel extends BaseViewModel { // UILocalNotificationDateInterpretation.absoluteTime, // ); _toast.showBottom('homeView.installingMessage'); - await AppInstaller.installApk(managerApk.path); + await InstallPlugin.installApk(managerApk.path); } else { _toast.showBottom('homeView.errorDownloadMessage'); } diff --git a/lib/ui/views/navigation/navigation_view.dart b/lib/ui/views/navigation/navigation_view.dart index d8fdd5c6..7089d069 100644 --- a/lib/ui/views/navigation/navigation_view.dart +++ b/lib/ui/views/navigation/navigation_view.dart @@ -13,58 +13,68 @@ class NavigationView extends StatelessWidget { return ViewModelBuilder.reactive( onViewModelReady: (model) => model.initialize(context), viewModelBuilder: () => locator(), - builder: (context, model, child) => Scaffold( - body: PageTransitionSwitcher( - duration: const Duration(milliseconds: 400), - transitionBuilder: ( - Widget child, - Animation animation, - Animation secondaryAnimation, - ) { - return FadeThroughTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - fillColor: Theme.of(context).colorScheme.surface, - child: child, - ); - }, - child: model.getViewForIndex(model.currentIndex), - ), - bottomNavigationBar: NavigationBar( - onDestinationSelected: model.setIndex, - selectedIndex: model.currentIndex, - destinations: [ - NavigationDestination( - icon: model.isIndexSelected(0) - ? const Icon(Icons.dashboard) - : const Icon(Icons.dashboard_outlined), - label: FlutterI18n.translate( - context, - 'navigationView.dashboardTab', + builder: (context, model, child) => WillPopScope( + onWillPop: () async { + if (model.currentIndex == 0) { + return true; + } else { + model.setIndex(0); + return false; + } + }, + child: Scaffold( + body: PageTransitionSwitcher( + duration: const Duration(milliseconds: 400), + transitionBuilder: ( + Widget child, + Animation animation, + Animation secondaryAnimation, + ) { + return FadeThroughTransition( + animation: animation, + secondaryAnimation: secondaryAnimation, + fillColor: Theme.of(context).colorScheme.surface, + child: child, + ); + }, + child: model.getViewForIndex(model.currentIndex), + ), + bottomNavigationBar: NavigationBar( + onDestinationSelected: model.setIndex, + selectedIndex: model.currentIndex, + destinations: [ + NavigationDestination( + icon: model.isIndexSelected(0) + ? const Icon(Icons.dashboard) + : const Icon(Icons.dashboard_outlined), + label: FlutterI18n.translate( + context, + 'navigationView.dashboardTab', + ), + tooltip: '', ), - tooltip: '', - ), - NavigationDestination( - icon: model.isIndexSelected(1) - ? const Icon(Icons.build) - : const Icon(Icons.build_outlined), - label: FlutterI18n.translate( - context, - 'navigationView.patcherTab', + NavigationDestination( + icon: model.isIndexSelected(1) + ? const Icon(Icons.build) + : const Icon(Icons.build_outlined), + label: FlutterI18n.translate( + context, + 'navigationView.patcherTab', + ), + tooltip: '', ), - tooltip: '', - ), - NavigationDestination( - icon: model.isIndexSelected(2) - ? const Icon(Icons.settings) - : const Icon(Icons.settings_outlined), - label: FlutterI18n.translate( - context, - 'navigationView.settingsTab', + NavigationDestination( + icon: model.isIndexSelected(2) + ? const Icon(Icons.settings) + : const Icon(Icons.settings_outlined), + label: FlutterI18n.translate( + context, + 'navigationView.settingsTab', + ), + tooltip: '', ), - tooltip: '', - ), - ], + ], + ), ), ), ); diff --git a/lib/ui/widgets/appSelectorView/installed_app_item.dart b/lib/ui/widgets/appSelectorView/installed_app_item.dart index 70a49a1a..69b08371 100644 --- a/lib/ui/widgets/appSelectorView/installed_app_item.dart +++ b/lib/ui/widgets/appSelectorView/installed_app_item.dart @@ -84,12 +84,16 @@ class _InstalledAppItemState extends State { }, ), const SizedBox(width: 4), - Text( - widget.patchesCount == 1 - ? '• ${widget.patchesCount} patch' - : '• ${widget.patchesCount} patches', - style: TextStyle( - color: Theme.of(context).colorScheme.secondary, + Flexible( + child: Text( + widget.patchesCount == 1 + ? '• ${widget.patchesCount} patch' + : '• ${widget.patchesCount} patches', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + ), ), ), ], diff --git a/lib/ui/widgets/appSelectorView/not_installed_app_item.dart b/lib/ui/widgets/appSelectorView/not_installed_app_item.dart index e932908b..ee40b8c1 100644 --- a/lib/ui/widgets/appSelectorView/not_installed_app_item.dart +++ b/lib/ui/widgets/appSelectorView/not_installed_app_item.dart @@ -78,12 +78,16 @@ class _NotInstalledAppItem extends State { }, ), const SizedBox(width: 4), - Text( - widget.patchesCount == 1 - ? '• ${widget.patchesCount} patch' - : '• ${widget.patchesCount} patches', - style: TextStyle( - color: Theme.of(context).colorScheme.secondary, + Flexible( + child: Text( + widget.patchesCount == 1 + ? '• ${widget.patchesCount} patch' + : '• ${widget.patchesCount} patches', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + ), ), ), ], diff --git a/lib/ui/widgets/homeView/installed_apps_card.dart b/lib/ui/widgets/homeView/installed_apps_card.dart index 2eb1119c..234ae3bd 100644 --- a/lib/ui/widgets/homeView/installed_apps_card.dart +++ b/lib/ui/widgets/homeView/installed_apps_card.dart @@ -1,16 +1,49 @@ +import 'package:device_apps/device_apps.dart'; import 'package:flutter/material.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/models/patched_application.dart'; +import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/application_item.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; -class InstalledAppsCard extends StatelessWidget { - InstalledAppsCard({Key? key}) : super(key: key); +class InstalledAppsCard extends StatefulWidget { + const InstalledAppsCard({Key? key}) : super(key: key); - final List apps = - locator().patchedInstalledApps; + @override + State createState() => _InstalledAppsCardState(); +} + +class _InstalledAppsCardState extends State { + List apps = locator().patchedInstalledApps; + final ManagerAPI _managerAPI = locator(); + List patchedApps = []; + + @override + void initState() { + super.initState(); + _getApps(); + } + + Future _getApps() async { + if (apps.isNotEmpty) { + patchedApps = [...apps]; + for (final element in apps) { + await DeviceApps.getApp(element.packageName).then((value) { + if (element.version != value?.versionName) { + patchedApps.remove(element); + } + }); + } + if (apps.length != patchedApps.length) { + await _managerAPI.setPatchedApps(patchedApps); + apps.clear(); + apps = [...patchedApps]; + } + setState(() {}); + } + } @override Widget build(BuildContext context) { diff --git a/pubspec.yaml b/pubspec.yaml index 3a99a5ba..52ecea22 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,14 +4,13 @@ homepage: https://github.com/revanced/revanced-manager publish_to: 'none' -version: 1.4.0+100400000 +version: 1.4.1+100400001 environment: sdk: '>=3.0.0 <4.0.0' dependencies: animations: ^2.0.7 - app_installer: ^1.1.0 collection: ^1.17.0 cross_connectivity: ^3.0.5 cr_file_saver: @@ -59,8 +58,8 @@ dependencies: pull_to_refresh: ^2.0.0 root: git: - url: https://github.com/gokul1630/root - ref: main + url: https://github.com/EvadeMaster/root + ref: 9bcf0dc06b8e2e3ccd5fbd16bc849938e817b36b share_extend: ^2.0.0 shared_preferences: ^2.1.0 skeletons: ^0.0.3 @@ -75,6 +74,7 @@ dependencies: flutter_dotenv: ^5.0.2 flutter_markdown: ^0.6.14 dio_cache_interceptor: ^3.4.0 + install_plugin: ^2.1.0 dev_dependencies: json_serializable: ^6.6.1