diff --git a/lib/app/app.locator.dart b/lib/app/app.locator.dart index ba377dc1..b2b3ecdd 100644 --- a/lib/app/app.locator.dart +++ b/lib/app/app.locator.dart @@ -12,6 +12,7 @@ import 'package:stacked_core/stacked_core.dart'; import 'package:stacked_services/src/navigation/navigation_service.dart'; import '../services/patcher_api.dart'; +import '../ui/views/patcher/patcher_viewmodel.dart'; final locator = StackedLocator.instance; @@ -24,4 +25,5 @@ Future setupLocator( // Register dependencies locator.registerLazySingleton(() => NavigationService()); locator.registerLazySingleton(() => PatcherService()); + locator.registerLazySingleton(() => PatcherViewModel()); } diff --git a/lib/main.dart b/lib/main.dart index 0cf7d953..6db54481 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -51,7 +51,7 @@ class Navigation extends StatelessWidget { Widget build(BuildContext context) { return ViewModelBuilder.reactive( viewModelBuilder: () => MainViewModel(), - builder: (context, MainViewModel model, child) => Scaffold( + builder: (context, model, child) => Scaffold( body: getViewForIndex(model.currentIndex), bottomNavigationBar: NavigationBar( onDestinationSelected: model.setIndex, diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 8fa926d3..068c5423 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -3,7 +3,7 @@ import 'package:dio/dio.dart'; import 'package:injectable/injectable.dart'; import 'package:path_provider/path_provider.dart' as p; import 'package:revanced_manager/constants.dart'; -import 'github_api.dart'; +import 'package:revanced_manager/services/github_api.dart'; // use path_provider to get the path of the storage directory @lazySingleton diff --git a/lib/services/patcher_api.dart b/lib/services/patcher_api.dart index b83a2192..ddd41f47 100644 --- a/lib/services/patcher_api.dart +++ b/lib/services/patcher_api.dart @@ -1,21 +1,30 @@ import 'dart:io'; import 'package:flutter/services.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:injectable/injectable.dart'; import 'package:installed_apps/app_info.dart'; import 'package:installed_apps/installed_apps.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/services/github_api.dart'; import 'package:revanced_manager/utils/string.dart'; +@lazySingleton class PatcherService { - File? _patchBundleFile; + final GithubAPI githubAPI = GithubAPI(); final List _filteredPackages = []; final Map> _filteredPatches = >{}; - final GithubAPI githubAPI = GithubAPI(); + File? _patchBundleFile; + String _selectedApp = ''; + List _selectedPatches = []; static const platform = MethodChannel('app.revanced/patcher'); - static final PatcherService _instance = PatcherService.internal(); - factory PatcherService() => _instance; - PatcherService.internal(); + + String getSelectedApp() => _selectedApp; + + void setSelectedApp(String app) => _selectedApp = app; + + List getSelectedPatches() => _selectedPatches; + + void setSelectedPatches(List patches) => _selectedPatches = patches; Future loadPatches() async { if (_patchBundleFile == null) { diff --git a/lib/ui/views/app_selector/app_selector_view.dart b/lib/ui/views/app_selector/app_selector_view.dart index d43f8e1e..005e4773 100644 --- a/lib/ui/views/app_selector/app_selector_view.dart +++ b/lib/ui/views/app_selector/app_selector_view.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; -import 'package:installed_apps/app_info.dart'; -import 'package:installed_apps/installed_apps.dart'; +import 'package:revanced_manager/app/app.locator.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/installed_app_item.dart'; import 'package:revanced_manager/ui/widgets/search_bar.dart'; import 'package:stacked/stacked.dart'; @@ -15,23 +16,13 @@ class AppSelectorView extends StatefulWidget { } class _AppSelectorViewState extends State { - List apps = []; + final PatcherService patcherService = locator(); String query = ''; - void getApps() async { - apps = await InstalledApps.getInstalledApps(false, true); - setState(() {}); - } - - @override - void initState() { - getApps(); - super.initState(); - } - @override Widget build(BuildContext context) { - return ViewModelBuilder.reactive( + return ViewModelBuilder.reactive( + onModelReady: (model) => model.initialise(), builder: (context, model, child) => Scaffold( body: SafeArea( child: Padding( @@ -51,41 +42,53 @@ class _AppSelectorViewState extends State { }, ), if (query.isEmpty || query.length < 2) - apps.isEmpty + model.apps.isEmpty ? const Center( child: CircularProgressIndicator(), ) : Expanded( child: ListView.builder( - itemCount: apps.length, + itemCount: model.apps.length, itemBuilder: (context, index) { //sort alphabetically - apps.sort((a, b) => a.name!.compareTo(b.name!)); - return InstalledAppItem( - name: apps[index].name!, - pkgName: apps[index].packageName!, - icon: apps[index].icon!, + model.apps + .sort((a, b) => a.name!.compareTo(b.name!)); + return InkWell( + onTap: () { + patcherService.setSelectedApp( + model.apps[index].packageName!); + Navigator.of(context).pop(); + locator().notifyListeners(); + }, + child: InstalledAppItem( + name: model.apps[index].name!, + pkgName: model.apps[index].packageName!, + icon: model.apps[index].icon!, + ), ); }, ), ), if (query.isNotEmpty) - apps.isEmpty + model.apps.isEmpty ? Center( child: I18nText('appSelectorCard.noAppsLabel'), ) : Expanded( child: ListView.builder( - itemCount: apps.length, + itemCount: model.apps.length, itemBuilder: (context, index) { - apps.sort((a, b) => a.name!.compareTo(b.name!)); - if (apps[index].name!.toLowerCase().contains( + model.apps + .sort((a, b) => a.name!.compareTo(b.name!)); + if (model.apps[index].name! + .toLowerCase() + .contains( query.toLowerCase(), )) { return InstalledAppItem( - name: apps[index].name!, - pkgName: apps[index].packageName!, - icon: apps[index].icon!, + name: model.apps[index].name!, + pkgName: model.apps[index].packageName!, + icon: model.apps[index].icon!, ); } else { return const SizedBox(); diff --git a/lib/ui/views/app_selector/app_selector_viewmodel.dart b/lib/ui/views/app_selector/app_selector_viewmodel.dart index a2004ba2..46122faa 100644 --- a/lib/ui/views/app_selector/app_selector_viewmodel.dart +++ b/lib/ui/views/app_selector/app_selector_viewmodel.dart @@ -1,16 +1,20 @@ import 'package:installed_apps/app_info.dart'; -import 'package:installed_apps/installed_apps.dart'; +import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/services/patcher_api.dart'; import 'package:stacked/stacked.dart'; class AppSelectorViewModel extends BaseViewModel { + final PatcherService patcherService = locator(); List apps = []; String query = ''; - void initialization() { - getApps(); + Future initialise() async { + await getApps(); + notifyListeners(); } - void getApps() async { - apps = await InstalledApps.getInstalledApps(false, true); + Future getApps() async { + await patcherService.loadPatches(); + apps = await patcherService.getFilteredInstalledApps(); } } diff --git a/lib/ui/views/home/home_view.dart b/lib/ui/views/home/home_view.dart index 8c084330..6007faf9 100644 --- a/lib/ui/views/home/home_view.dart +++ b/lib/ui/views/home/home_view.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/available_updates_card.dart'; import 'package:revanced_manager/ui/widgets/installed_apps_card.dart'; import 'package:revanced_manager/ui/widgets/latest_commit_card.dart'; import 'package:stacked/stacked.dart'; -import 'home_viewmodel.dart'; class HomeView extends StatelessWidget { const HomeView({Key? key}) : super(key: key); diff --git a/lib/ui/views/patcher/patcher_view.dart b/lib/ui/views/patcher/patcher_view.dart index ff179133..a744942d 100644 --- a/lib/ui/views/patcher/patcher_view.dart +++ b/lib/ui/views/patcher/patcher_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/ui/widgets/app_selector_card.dart'; import 'package:revanced_manager/ui/widgets/patch_selector_card.dart'; import 'package:stacked/stacked.dart'; @@ -12,8 +13,8 @@ class PatcherView extends StatelessWidget { @override Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - builder: (context, PatcherViewModel model, child) => Scaffold( + return ViewModelBuilder.reactive( + builder: (context, model, child) => Scaffold( floatingActionButton: FloatingActionButton( onPressed: () {}, child: const Icon( @@ -51,7 +52,7 @@ class PatcherView extends StatelessWidget { ), ), ), - viewModelBuilder: () => PatcherViewModel(), + viewModelBuilder: () => locator(), ); } } diff --git a/lib/ui/views/patches_selector/patches_selector_view.dart b/lib/ui/views/patches_selector/patches_selector_view.dart index 38c83c6d..c17e9a6c 100644 --- a/lib/ui/views/patches_selector/patches_selector_view.dart +++ b/lib/ui/views/patches_selector/patches_selector_view.dart @@ -18,9 +18,9 @@ class _PatchesSelectorViewState extends State { @override Widget build(BuildContext context) { - return ViewModelBuilder.reactive( + return ViewModelBuilder.reactive( viewModelBuilder: () => PatchesSelectorViewModel(), - builder: (context, PatchesSelectorViewModel model, child) => Scaffold( + builder: (context, model, child) => Scaffold( body: Container( margin: const EdgeInsets.fromLTRB(6.0, 26.0, 6.0, 0), child: Column( diff --git a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart index 4c4c3b4f..55ebc41c 100644 --- a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart +++ b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart @@ -1,23 +1,21 @@ import 'package:installed_apps/app_info.dart'; import 'package:installed_apps/installed_apps.dart'; +import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/services/patcher_api.dart'; import 'package:stacked/stacked.dart'; class PatchesSelectorViewModel extends BaseViewModel { - PatcherService patcherService = PatcherService(); - List? patches = []; + final PatcherService patcherService = locator(); AppInfo? appInfo; Future getApp() async { AppInfo app = await InstalledApps.getAppInfo("com.google.android.youtube"); appInfo = app; } - Future?>? getPatches() async { + + Future?> getPatches() async { getApp(); - PatcherService patcherService = PatcherService(); - patcherService.loadPatches(); return patcherService.getFilteredPatches(appInfo); } - -} \ No newline at end of file +} diff --git a/lib/ui/widgets/app_selector_card.dart b/lib/ui/widgets/app_selector_card.dart index b1334e1d..89109f09 100644 --- a/lib/ui/widgets/app_selector_card.dart +++ b/lib/ui/widgets/app_selector_card.dart @@ -1,15 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/constants.dart'; +import 'package:revanced_manager/services/patcher_api.dart'; class AppSelectorCard extends StatelessWidget { final Function()? onPressed; - const AppSelectorCard({ + AppSelectorCard({ Key? key, this.onPressed, }) : super(key: key); + final PatcherService patcherService = locator(); + @override Widget build(BuildContext context) { return GestureDetector( @@ -35,13 +39,18 @@ class AppSelectorCard extends StatelessWidget { ), ), const SizedBox(height: 10), - I18nText( - 'appSelectorCard.widgetSubtitle', - child: Text( - '', - style: robotoTextStyle, - ), - ), + patcherService.getSelectedApp().isNotEmpty + ? Text( + patcherService.getSelectedApp(), + style: robotoTextStyle, + ) + : I18nText( + 'appSelectorCard.widgetSubtitle', + child: Text( + '', + style: robotoTextStyle, + ), + ), ], ), ), diff --git a/lib/ui/widgets/installed_app_item.dart b/lib/ui/widgets/installed_app_item.dart index 7b6aa3b9..e33b474b 100644 --- a/lib/ui/widgets/installed_app_item.dart +++ b/lib/ui/widgets/installed_app_item.dart @@ -23,52 +23,49 @@ class InstalledAppItem extends StatefulWidget { class _InstalledAppItemState extends State { @override Widget build(BuildContext context) { - return InkWell( - onTap: () => Navigator.pop(context), - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 4.0), - child: Container( - padding: const EdgeInsets.all(12.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: const Color(0xff1B222B), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - width: 48, - height: 48, - padding: const EdgeInsets.symmetric(vertical: 4.0), - alignment: Alignment.center, - child: CircleAvatar( - child: Image.memory(widget.icon), - ), + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4.0), + child: Container( + padding: const EdgeInsets.all(12.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: const Color(0xff1B222B), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: 48, + height: 48, + padding: const EdgeInsets.symmetric(vertical: 4.0), + alignment: Alignment.center, + child: CircleAvatar( + child: Image.memory(widget.icon), ), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.name, - maxLines: 2, - overflow: TextOverflow.visible, - style: GoogleFonts.inter( - fontSize: 16, - fontWeight: FontWeight.w500, - ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.name, + maxLines: 2, + overflow: TextOverflow.visible, + style: GoogleFonts.inter( + fontSize: 16, + fontWeight: FontWeight.w500, ), - const SizedBox(height: 4), - Text( - widget.pkgName, - style: robotoTextStyle, - ), - ], - ), + ), + const SizedBox(height: 4), + Text( + widget.pkgName, + style: robotoTextStyle, + ), + ], ), - ], - ), + ), + ], ), ), ); diff --git a/lib/ui/widgets/patch_item.dart b/lib/ui/widgets/patch_item.dart index eed9abbd..b2e2ae3e 100644 --- a/lib/ui/widgets/patch_item.dart +++ b/lib/ui/widgets/patch_item.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +// ignore: must_be_immutable class PatchItem extends StatefulWidget { final String name; final String description;