mirror of
https://github.com/revanced/revanced-manager.git
synced 2025-06-12 04:37:37 +02:00
feat: update rules of analysis_options.yaml. and solved all problems (#665)
* update rules of analysis_options.yaml. and solved all problems * refactor: fix remaining problems --------- Co-authored-by: Ushie <ushiekane@gmail.com>
This commit is contained in:
@ -1,10 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
||||
import 'package:revanced_manager/ui/views/app_selector/app_selector_viewmodel.dart';
|
||||
import 'package:revanced_manager/ui/widgets/appSelectorView/app_skeleton_loader.dart';
|
||||
import 'package:revanced_manager/ui/widgets/appSelectorView/installed_app_item.dart';
|
||||
import 'package:revanced_manager/ui/widgets/shared/search_bar.dart';
|
||||
import 'package:revanced_manager/ui/widgets/appSelectorView/app_skeleton_loader.dart';
|
||||
import 'package:stacked/stacked.dart' hide SkeletonLoader;
|
||||
import 'package:revanced_manager/ui/views/app_selector/app_selector_viewmodel.dart';
|
||||
|
||||
class AppSelectorView extends StatefulWidget {
|
||||
const AppSelectorView({Key? key}) : super(key: key);
|
||||
@ -19,7 +19,7 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder<AppSelectorViewModel>.reactive(
|
||||
onModelReady: (model) => model.initialize(),
|
||||
onViewModelReady: (model) => model.initialize(),
|
||||
viewModelBuilder: () => AppSelectorViewModel(),
|
||||
builder: (context, model, child) => Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
@ -36,7 +36,6 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
floating: true,
|
||||
snap: false,
|
||||
title: I18nText(
|
||||
'appSelectorView.viewTitle',
|
||||
child: Text(
|
||||
@ -61,7 +60,6 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
||||
horizontal: 12.0,
|
||||
),
|
||||
child: SearchBar(
|
||||
showSelectIcon: false,
|
||||
hintText: FlutterI18n.translate(
|
||||
context,
|
||||
'appSelectorView.searchBarHint',
|
||||
@ -88,17 +86,19 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
||||
child: Column(
|
||||
children: model
|
||||
.getFilteredApps(_query)
|
||||
.map((app) => InstalledAppItem(
|
||||
name: app.appName,
|
||||
pkgName: app.packageName,
|
||||
icon: app.icon,
|
||||
patchesCount:
|
||||
model.patchesCount(app.packageName),
|
||||
onTap: () {
|
||||
model.selectApp(app);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
))
|
||||
.map(
|
||||
(app) => InstalledAppItem(
|
||||
name: app.appName,
|
||||
pkgName: app.packageName,
|
||||
icon: app.icon,
|
||||
patchesCount:
|
||||
model.patchesCount(app.packageName),
|
||||
onTap: () {
|
||||
model.selectApp(app);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
|
@ -1,15 +1,16 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:device_apps/device_apps.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.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/services/patcher_api.dart';
|
||||
import 'package:revanced_manager/services/toast.dart';
|
||||
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
import '../../../services/manager_api.dart';
|
||||
|
||||
class AppSelectorViewModel extends BaseViewModel {
|
||||
final PatcherAPI _patcherAPI = locator<PatcherAPI>();
|
||||
@ -22,16 +23,21 @@ class AppSelectorViewModel extends BaseViewModel {
|
||||
}
|
||||
|
||||
Future<void> initialize() async {
|
||||
apps.addAll(await _patcherAPI.getFilteredInstalledApps(_managerAPI.areUniversalPatchesEnabled()));
|
||||
apps.sort(((a, b) => _patcherAPI
|
||||
.getFilteredPatches(b.packageName)
|
||||
.length
|
||||
.compareTo(_patcherAPI.getFilteredPatches(a.packageName).length)));
|
||||
apps.addAll(
|
||||
await _patcherAPI
|
||||
.getFilteredInstalledApps(_managerAPI.areUniversalPatchesEnabled()),
|
||||
);
|
||||
apps.sort(
|
||||
(a, b) => _patcherAPI
|
||||
.getFilteredPatches(b.packageName)
|
||||
.length
|
||||
.compareTo(_patcherAPI.getFilteredPatches(a.packageName).length),
|
||||
);
|
||||
noApps = apps.isEmpty;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void selectApp(ApplicationWithIcon application) async {
|
||||
Future<void> selectApp(ApplicationWithIcon application) async {
|
||||
locator<PatcherViewModel>().selectedApp = PatchedApplication(
|
||||
name: application.appName,
|
||||
packageName: application.packageName,
|
||||
@ -46,22 +52,24 @@ class AppSelectorViewModel extends BaseViewModel {
|
||||
|
||||
Future<void> selectAppFromStorage(BuildContext context) async {
|
||||
try {
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||
final FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ['apk'],
|
||||
);
|
||||
if (result != null && result.files.single.path != null) {
|
||||
File apkFile = File(result.files.single.path!);
|
||||
List<String> pathSplit = result.files.single.path!.split("/");
|
||||
final File apkFile = File(result.files.single.path!);
|
||||
final List<String> pathSplit = result.files.single.path!.split('/');
|
||||
pathSplit.removeLast();
|
||||
Directory filePickerCacheDir = Directory(pathSplit.join("/"));
|
||||
Iterable<File> deletableFiles =
|
||||
final Directory filePickerCacheDir = Directory(pathSplit.join('/'));
|
||||
final Iterable<File> deletableFiles =
|
||||
(await filePickerCacheDir.list().toList()).whereType<File>();
|
||||
for (var file in deletableFiles) {
|
||||
if (file.path != apkFile.path && file.path.endsWith(".apk"))
|
||||
for (final file in deletableFiles) {
|
||||
if (file.path != apkFile.path && file.path.endsWith('.apk')) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
ApplicationWithIcon? application = await DeviceApps.getAppFromStorage(
|
||||
final ApplicationWithIcon? application =
|
||||
await DeviceApps.getAppFromStorage(
|
||||
apkFile.path,
|
||||
true,
|
||||
) as ApplicationWithIcon?;
|
||||
@ -87,10 +95,12 @@ class AppSelectorViewModel extends BaseViewModel {
|
||||
|
||||
List<ApplicationWithIcon> getFilteredApps(String query) {
|
||||
return apps
|
||||
.where((app) =>
|
||||
query.isEmpty ||
|
||||
query.length < 2 ||
|
||||
app.appName.toLowerCase().contains(query.toLowerCase()))
|
||||
.where(
|
||||
(app) =>
|
||||
query.isEmpty ||
|
||||
query.length < 2 ||
|
||||
app.appName.toLowerCase().contains(query.toLowerCase()),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class ContributorsView extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder<ContributorsViewModel>.reactive(
|
||||
viewModelBuilder: () => ContributorsViewModel(),
|
||||
onModelReady: (model) => model.getContributors(),
|
||||
onViewModelReady: (model) => model.getContributors(),
|
||||
builder: (context, model, child) => Scaffold(
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
|
@ -11,7 +11,7 @@ class ContributorsViewModel extends BaseViewModel {
|
||||
List<dynamic> managerContributors = [];
|
||||
|
||||
Future<void> getContributors() async {
|
||||
Map<String, List<dynamic>> contributors =
|
||||
final Map<String, List<dynamic>> contributors =
|
||||
await _managerAPI.getContributors();
|
||||
patcherContributors = contributors[_managerAPI.defaultPatcherRepo] ?? [];
|
||||
patchesContributors = contributors[_managerAPI.getPatchesRepo()] ?? [];
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:animations/animations.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:animations/animations.dart';
|
||||
import 'package:revanced_manager/app/app.locator.dart';
|
||||
import 'package:revanced_manager/ui/views/home/home_viewmodel.dart';
|
||||
import 'package:revanced_manager/ui/widgets/homeView/available_updates_card.dart';
|
||||
@ -18,7 +18,7 @@ class HomeView extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder<HomeViewModel>.reactive(
|
||||
disposeViewModel: false,
|
||||
onModelReady: (model) => model.initialize(context),
|
||||
onViewModelReady: (model) => model.initialize(context),
|
||||
viewModelBuilder: () => locator<HomeViewModel>(),
|
||||
builder: (context, model, child) => Scaffold(
|
||||
body: RefreshIndicator(
|
||||
@ -48,7 +48,7 @@ class HomeView extends StatelessWidget {
|
||||
'homeView.updatesSubtitle',
|
||||
child: Text(
|
||||
'',
|
||||
style: Theme.of(context).textTheme.headline6!,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
@ -61,7 +61,7 @@ class HomeView extends StatelessWidget {
|
||||
'homeView.patchedSubtitle',
|
||||
child: Text(
|
||||
'',
|
||||
style: Theme.of(context).textTheme.headline6!,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
@ -1,5 +1,6 @@
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:app_installer/app_installer.dart';
|
||||
import 'package:cross_connectivity/cross_connectivity.dart';
|
||||
import 'package:device_apps/device_apps.dart';
|
||||
@ -10,9 +11,9 @@ import 'package:injectable/injectable.dart';
|
||||
import 'package:revanced_manager/app/app.locator.dart';
|
||||
import 'package:revanced_manager/app/app.router.dart';
|
||||
import 'package:revanced_manager/models/patched_application.dart';
|
||||
import 'package:revanced_manager/services/github_api.dart';
|
||||
import 'package:revanced_manager/services/manager_api.dart';
|
||||
import 'package:revanced_manager/services/patcher_api.dart';
|
||||
import 'package:revanced_manager/services/github_api.dart';
|
||||
import 'package:revanced_manager/services/toast.dart';
|
||||
import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.dart';
|
||||
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
||||
@ -47,7 +48,7 @@ class HomeViewModel extends BaseViewModel {
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin>()
|
||||
?.requestPermission();
|
||||
bool isConnected = await Connectivity().checkConnection();
|
||||
final bool isConnected = await Connectivity().checkConnection();
|
||||
if (!isConnected) {
|
||||
_toast.showBottom('homeView.noConnection');
|
||||
}
|
||||
@ -67,7 +68,7 @@ class HomeViewModel extends BaseViewModel {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void navigateToPatcher(PatchedApplication app) async {
|
||||
Future<void> navigateToPatcher(PatchedApplication app) async {
|
||||
locator<PatcherViewModel>().selectedApp = app;
|
||||
locator<PatcherViewModel>().selectedPatches =
|
||||
await _patcherAPI.getAppliedPatches(app.appliedPatches);
|
||||
@ -88,13 +89,13 @@ class HomeViewModel extends BaseViewModel {
|
||||
}
|
||||
|
||||
Future<bool> hasManagerUpdates() async {
|
||||
String? latestVersion = await _managerAPI.getLatestManagerVersion();
|
||||
String currentVersion = await _managerAPI.getCurrentManagerVersion();
|
||||
final String? latestVersion = await _managerAPI.getLatestManagerVersion();
|
||||
final String currentVersion = await _managerAPI.getCurrentManagerVersion();
|
||||
if (latestVersion != null) {
|
||||
try {
|
||||
int latestVersionInt =
|
||||
final int latestVersionInt =
|
||||
int.parse(latestVersion.replaceAll(RegExp('[^0-9]'), ''));
|
||||
int currentVersionInt =
|
||||
final int currentVersionInt =
|
||||
int.parse(currentVersion.replaceAll(RegExp('[^0-9]'), ''));
|
||||
return latestVersionInt > currentVersionInt;
|
||||
} on Exception catch (e, s) {
|
||||
@ -108,7 +109,7 @@ class HomeViewModel extends BaseViewModel {
|
||||
Future<void> updateManager(BuildContext context) async {
|
||||
try {
|
||||
_toast.showBottom('homeView.downloadingMessage');
|
||||
File? managerApk = await _managerAPI.downloadManager();
|
||||
final File? managerApk = await _managerAPI.downloadManager();
|
||||
if (managerApk != null) {
|
||||
await flutterLocalNotificationsPlugin.zonedSchedule(
|
||||
0,
|
||||
|
@ -2,9 +2,9 @@ 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/installer/installer_viewmodel.dart';
|
||||
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
||||
import 'package:revanced_manager/ui/widgets/installerView/gradient_progress_indicator.dart';
|
||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
||||
import 'package:revanced_manager/ui/widgets/shared/custom_popup_menu.dart';
|
||||
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
@ -15,7 +15,7 @@ class InstallerView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder<InstallerViewModel>.reactive(
|
||||
onModelReady: (model) => model.initialize(context),
|
||||
onViewModelReady: (model) => model.initialize(context),
|
||||
viewModelBuilder: () => InstallerViewModel(),
|
||||
builder: (context, model, child) => WillPopScope(
|
||||
child: SafeArea(
|
||||
@ -48,15 +48,15 @@ class InstallerView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
1: I18nText(
|
||||
'installerView.exportApkMenuOption',
|
||||
child: const Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
1: I18nText(
|
||||
'installerView.exportApkMenuOption',
|
||||
child: const Text(
|
||||
'',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
2: I18nText(
|
||||
'installerView.shareLogMenuOption',
|
||||
child: const Text(
|
||||
@ -71,9 +71,9 @@ class InstallerView extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
bottom: PreferredSize(
|
||||
preferredSize: const Size(double.infinity, 1.0),
|
||||
child:
|
||||
GradientProgressIndicator(progress: model.progress!)),
|
||||
preferredSize: const Size(double.infinity, 1.0),
|
||||
child: GradientProgressIndicator(progress: model.progress),
|
||||
),
|
||||
),
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
|
@ -51,10 +51,8 @@ class InstallerViewModel extends BaseViewModel {
|
||||
context,
|
||||
'installerView.notificationText',
|
||||
),
|
||||
notificationImportance: AndroidNotificationImportance.Default,
|
||||
notificationIcon: const AndroidResource(
|
||||
name: 'ic_notification',
|
||||
defType: 'drawable',
|
||||
),
|
||||
),
|
||||
).then((value) => FlutterBackground.enableBackgroundExecution());
|
||||
@ -73,10 +71,10 @@ class InstallerViewModel extends BaseViewModel {
|
||||
switch (call.method) {
|
||||
case 'update':
|
||||
if (call.arguments != null) {
|
||||
Map<dynamic, dynamic> arguments = call.arguments;
|
||||
double progress = arguments['progress'];
|
||||
String header = arguments['header'];
|
||||
String log = arguments['log'];
|
||||
final Map<dynamic, dynamic> arguments = call.arguments;
|
||||
final double progress = arguments['progress'];
|
||||
final String header = arguments['header'];
|
||||
final String log = arguments['log'];
|
||||
update(progress, header, log);
|
||||
}
|
||||
break;
|
||||
@ -159,13 +157,14 @@ class InstallerViewModel extends BaseViewModel {
|
||||
}
|
||||
}
|
||||
|
||||
void installResult(BuildContext context, bool installAsRoot) async {
|
||||
Future<void> installResult(BuildContext context, bool installAsRoot) async {
|
||||
try {
|
||||
_app.isRooted = installAsRoot;
|
||||
bool hasMicroG = _patches.any((p) => p.name.endsWith('microg-support'));
|
||||
bool rootMicroG = installAsRoot && hasMicroG;
|
||||
bool rootFromStorage = installAsRoot && _app.isFromStorage;
|
||||
bool ytWithoutRootMicroG =
|
||||
final bool hasMicroG =
|
||||
_patches.any((p) => p.name.endsWith('microg-support'));
|
||||
final bool rootMicroG = installAsRoot && hasMicroG;
|
||||
final bool rootFromStorage = installAsRoot && _app.isFromStorage;
|
||||
final bool ytWithoutRootMicroG =
|
||||
!installAsRoot && !hasMicroG && _app.packageName.contains('youtube');
|
||||
if (rootMicroG || rootFromStorage || ytWithoutRootMicroG) {
|
||||
return showDialog(
|
||||
|
@ -11,7 +11,7 @@ class NavigationView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder<NavigationViewModel>.reactive(
|
||||
onModelReady: (model) => model.initialize(context),
|
||||
onViewModelReady: (model) => model.initialize(context),
|
||||
viewModelBuilder: () => locator<NavigationViewModel>(),
|
||||
builder: (context, model, child) => Scaffold(
|
||||
body: PageTransitionSwitcher(
|
||||
|
@ -15,9 +15,9 @@ import 'package:stacked/stacked.dart';
|
||||
|
||||
@lazySingleton
|
||||
class NavigationViewModel extends IndexTrackingViewModel {
|
||||
void initialize(BuildContext context) async {
|
||||
Future<void> initialize(BuildContext context) async {
|
||||
locator<Toast>().initialize(context);
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
if (prefs.getBool('permissionsRequested') == null) {
|
||||
await prefs.setBool('permissionsRequested', true);
|
||||
RootAPI().hasRootPermissions().then(
|
||||
@ -27,7 +27,7 @@ class NavigationViewModel extends IndexTrackingViewModel {
|
||||
);
|
||||
}
|
||||
if (prefs.getBool('useDarkTheme') == null) {
|
||||
bool isDark =
|
||||
final bool isDark =
|
||||
MediaQuery.of(context).platformBrightness != Brightness.light;
|
||||
await prefs.setBool('useDarkTheme', isDark);
|
||||
await DynamicTheme.of(context)!.setTheme(isDark ? 1 : 0);
|
||||
|
@ -40,18 +40,18 @@ class PatcherViewModel extends BaseViewModel {
|
||||
}
|
||||
|
||||
Future<bool> isValidPatchConfig() async {
|
||||
bool needsResourcePatching = await _patcherAPI.needsResourcePatching(
|
||||
final bool needsResourcePatching = await _patcherAPI.needsResourcePatching(
|
||||
selectedPatches,
|
||||
);
|
||||
if (needsResourcePatching && selectedApp != null) {
|
||||
bool isSplit = await _managerAPI.isSplitApk(selectedApp!);
|
||||
final bool isSplit = await _managerAPI.isSplitApk(selectedApp!);
|
||||
return !isSplit;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<void> showPatchConfirmationDialog(BuildContext context) async {
|
||||
bool isValid = await isValidPatchConfig();
|
||||
final bool isValid = await isValidPatchConfig();
|
||||
if (isValid) {
|
||||
navigateToInstaller();
|
||||
} else {
|
||||
@ -110,9 +110,9 @@ class PatcherViewModel extends BaseViewModel {
|
||||
|
||||
Future<void> loadLastSelectedPatches() async {
|
||||
this.selectedPatches.clear();
|
||||
List<String> selectedPatches =
|
||||
final List<String> selectedPatches =
|
||||
await _managerAPI.getSelectedPatches(selectedApp!.originalPackageName);
|
||||
List<Patch> patches =
|
||||
final List<Patch> patches =
|
||||
_patcherAPI.getFilteredPatches(selectedApp!.originalPackageName);
|
||||
this.selectedPatches
|
||||
.addAll(patches.where((patch) => selectedPatches.contains(patch.name)));
|
||||
|
@ -20,7 +20,7 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder<PatchesSelectorViewModel>.reactive(
|
||||
onModelReady: (model) => model.initialize(),
|
||||
onViewModelReady: (model) => model.initialize(),
|
||||
viewModelBuilder: () => PatchesSelectorViewModel(),
|
||||
builder: (context, model, child) => Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
@ -45,7 +45,6 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
floating: true,
|
||||
snap: false,
|
||||
title: I18nText(
|
||||
'patchesSelectorView.viewTitle',
|
||||
child: Text(
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_i18n/widgets/I18nText.dart';
|
||||
import 'package:revanced_manager/app/app.locator.dart';
|
||||
import 'package:revanced_manager/models/patch.dart';
|
||||
@ -10,7 +11,6 @@ import 'package:revanced_manager/services/toast.dart';
|
||||
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
||||
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PatchesSelectorViewModel extends BaseViewModel {
|
||||
final PatcherAPI _patcherAPI = locator<PatcherAPI>();
|
||||
@ -26,9 +26,11 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
||||
|
||||
Future<void> initialize() async {
|
||||
getPatchesVersion();
|
||||
patches.addAll(_patcherAPI.getFilteredPatches(
|
||||
locator<PatcherViewModel>().selectedApp!.originalPackageName,
|
||||
));
|
||||
patches.addAll(
|
||||
_patcherAPI.getFilteredPatches(
|
||||
locator<PatcherViewModel>().selectedApp!.originalPackageName,
|
||||
),
|
||||
);
|
||||
patches.sort((a, b) => a.name.compareTo(b.name));
|
||||
notifyListeners();
|
||||
}
|
||||
@ -84,8 +86,11 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
||||
selectedPatches.clear();
|
||||
|
||||
if (_managerAPI.areExperimentalPatchesEnabled() == false) {
|
||||
selectedPatches.addAll(patches.where(
|
||||
(element) => element.excluded == false && isPatchSupported(element)));
|
||||
selectedPatches.addAll(
|
||||
patches.where(
|
||||
(element) => element.excluded == false && isPatchSupported(element),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (_managerAPI.areExperimentalPatchesEnabled()) {
|
||||
@ -117,15 +122,18 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
||||
patchesVersion = await _githubAPI
|
||||
.getLastestReleaseVersion(_managerAPI.getPatchesRepo());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Patch> getQueriedPatches(String query) {
|
||||
return patches
|
||||
.where((patch) =>
|
||||
query.isEmpty ||
|
||||
query.length < 2 ||
|
||||
patch.name.toLowerCase().contains(query.toLowerCase()) ||
|
||||
patch.getSimpleName().toLowerCase().contains(query.toLowerCase()))
|
||||
.where(
|
||||
(patch) =>
|
||||
query.isEmpty ||
|
||||
query.length < 2 ||
|
||||
patch.name.toLowerCase().contains(query.toLowerCase()) ||
|
||||
patch.getSimpleName().toLowerCase().contains(query.toLowerCase()),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@ -134,8 +142,8 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
||||
}
|
||||
|
||||
List<String> getSupportedVersions(Patch patch) {
|
||||
PatchedApplication app = locator<PatcherViewModel>().selectedApp!;
|
||||
Package? package = patch.compatiblePackages.firstWhereOrNull(
|
||||
final PatchedApplication app = locator<PatcherViewModel>().selectedApp!;
|
||||
final Package? package = patch.compatiblePackages.firstWhereOrNull(
|
||||
(pack) => pack.name == app.packageName,
|
||||
);
|
||||
if (package != null) {
|
||||
@ -146,10 +154,13 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
||||
}
|
||||
|
||||
bool isPatchSupported(Patch patch) {
|
||||
PatchedApplication app = locator<PatcherViewModel>().selectedApp!;
|
||||
return patch.compatiblePackages.isEmpty || patch.compatiblePackages.any((pack) =>
|
||||
pack.name == app.packageName &&
|
||||
(pack.versions.isEmpty || pack.versions.contains(app.version)));
|
||||
final PatchedApplication app = locator<PatcherViewModel>().selectedApp!;
|
||||
return patch.compatiblePackages.isEmpty ||
|
||||
patch.compatiblePackages.any(
|
||||
(pack) =>
|
||||
pack.name == app.packageName &&
|
||||
(pack.versions.isEmpty || pack.versions.contains(app.version)),
|
||||
);
|
||||
}
|
||||
|
||||
void onMenuSelection(value) {
|
||||
@ -161,20 +172,23 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
||||
}
|
||||
|
||||
Future<void> saveSelectedPatches() async {
|
||||
List<String> selectedPatches =
|
||||
final List<String> selectedPatches =
|
||||
this.selectedPatches.map((patch) => patch.name).toList();
|
||||
await _managerAPI.setSelectedPatches(
|
||||
locator<PatcherViewModel>().selectedApp!.originalPackageName,
|
||||
selectedPatches);
|
||||
locator<PatcherViewModel>().selectedApp!.originalPackageName,
|
||||
selectedPatches,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> loadSelectedPatches() async {
|
||||
List<String> selectedPatches = await _managerAPI.getSelectedPatches(
|
||||
locator<PatcherViewModel>().selectedApp!.originalPackageName);
|
||||
final List<String> selectedPatches = await _managerAPI.getSelectedPatches(
|
||||
locator<PatcherViewModel>().selectedApp!.originalPackageName,
|
||||
);
|
||||
if (selectedPatches.isNotEmpty) {
|
||||
this.selectedPatches.clear();
|
||||
this.selectedPatches.addAll(
|
||||
patches.where((patch) => selectedPatches.contains(patch.name)));
|
||||
patches.where((patch) => selectedPatches.contains(patch.name)),
|
||||
);
|
||||
} else {
|
||||
locator<Toast>().showBottom('patchesSelectorView.noSavedPatches');
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ class SManageApiUrl extends BaseViewModel {
|
||||
final TextEditingController _apiUrlController = TextEditingController();
|
||||
|
||||
Future<void> showApiUrlDialog(BuildContext context) async {
|
||||
String apiUrl = _managerAPI.getApiUrl();
|
||||
final String apiUrl = _managerAPI.getApiUrl();
|
||||
_apiUrlController.text = apiUrl.replaceAll('https://', '');
|
||||
return showDialog(
|
||||
context: context,
|
||||
|
@ -19,9 +19,9 @@ class SManageSources extends BaseViewModel {
|
||||
final TextEditingController _intSourceController = TextEditingController();
|
||||
|
||||
Future<void> showSourcesDialog(BuildContext context) async {
|
||||
String hostRepository = _managerAPI.getRepoUrl();
|
||||
String patchesRepo = _managerAPI.getPatchesRepo();
|
||||
String integrationsRepo = _managerAPI.getIntegrationsRepo();
|
||||
final String hostRepository = _managerAPI.getRepoUrl();
|
||||
final String patchesRepo = _managerAPI.getPatchesRepo();
|
||||
final String integrationsRepo = _managerAPI.getIntegrationsRepo();
|
||||
_hostSourceController.text = hostRepository;
|
||||
_orgPatSourceController.text = patchesRepo.split('/')[0];
|
||||
_patSourceController.text = patchesRepo.split('/')[1];
|
||||
|
@ -23,9 +23,9 @@ class SUpdateTheme extends BaseViewModel {
|
||||
return _managerAPI.getUseDynamicTheme();
|
||||
}
|
||||
|
||||
void setUseDynamicTheme(BuildContext context, bool value) async {
|
||||
Future<void> setUseDynamicTheme(BuildContext context, bool value) async {
|
||||
await _managerAPI.setUseDynamicTheme(value);
|
||||
int currentTheme = DynamicTheme.of(context)!.themeId;
|
||||
final int currentTheme = DynamicTheme.of(context)!.themeId;
|
||||
if (currentTheme.isEven) {
|
||||
await DynamicTheme.of(context)!.setTheme(value ? 2 : 0);
|
||||
} else {
|
||||
@ -38,9 +38,9 @@ class SUpdateTheme extends BaseViewModel {
|
||||
return _managerAPI.getUseDarkTheme();
|
||||
}
|
||||
|
||||
void setUseDarkTheme(BuildContext context, bool value) async {
|
||||
Future<void> setUseDarkTheme(BuildContext context, bool value) async {
|
||||
await _managerAPI.setUseDarkTheme(value);
|
||||
int currentTheme = DynamicTheme.of(context)!.themeId;
|
||||
final int currentTheme = DynamicTheme.of(context)!.themeId;
|
||||
if (currentTheme < 2) {
|
||||
await DynamicTheme.of(context)!.setTheme(value ? 1 : 0);
|
||||
} else {
|
||||
|
@ -3,7 +3,6 @@
|
||||
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/settings/settingsFragement/settings_update_language.dart';
|
||||
import 'package:revanced_manager/ui/views/settings/settingsFragement/settings_update_theme.dart';
|
||||
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_advanced_section.dart';
|
||||
|
@ -70,12 +70,12 @@ class SettingsViewModel extends BaseViewModel {
|
||||
|
||||
Future<void> exportPatches() async {
|
||||
try {
|
||||
File outFile = File(_managerAPI.storedPatchesFile);
|
||||
final File outFile = File(_managerAPI.storedPatchesFile);
|
||||
if (outFile.existsSync()) {
|
||||
String dateTime =
|
||||
final String dateTime =
|
||||
DateTime.now().toString().replaceAll(' ', '_').split('.').first;
|
||||
await CRFileSaver.saveFileWithDialog(SaveFileDialogParams(
|
||||
sourceFilePath: outFile.path, destinationFileName: 'selected_patches_$dateTime.json'));
|
||||
sourceFilePath: outFile.path, destinationFileName: 'selected_patches_$dateTime.json',),);
|
||||
_toast.showBottom('settingsView.exportedPatches');
|
||||
} else {
|
||||
_toast.showBottom('settingsView.noExportFileFound');
|
||||
@ -87,12 +87,12 @@ class SettingsViewModel extends BaseViewModel {
|
||||
|
||||
Future<void> importPatches() async {
|
||||
try {
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||
final FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ['json'],
|
||||
);
|
||||
if (result != null && result.files.single.path != null) {
|
||||
File inFile = File(result.files.single.path!);
|
||||
final File inFile = File(result.files.single.path!);
|
||||
inFile.copySync(_managerAPI.storedPatchesFile);
|
||||
inFile.delete();
|
||||
if (locator<PatcherViewModel>().selectedApp != null) {
|
||||
@ -112,13 +112,13 @@ class SettingsViewModel extends BaseViewModel {
|
||||
}
|
||||
|
||||
Future<int> getSdkVersion() async {
|
||||
AndroidDeviceInfo info = await DeviceInfoPlugin().androidInfo;
|
||||
final AndroidDeviceInfo info = await DeviceInfoPlugin().androidInfo;
|
||||
return info.version.sdkInt ?? -1;
|
||||
}
|
||||
|
||||
Future<void> deleteLogs() async {
|
||||
Directory appCacheDir = await getTemporaryDirectory();
|
||||
Directory logsDir = Directory('${appCacheDir.path}/logs');
|
||||
final Directory appCacheDir = await getTemporaryDirectory();
|
||||
final Directory logsDir = Directory('${appCacheDir.path}/logs');
|
||||
if (logsDir.existsSync()) {
|
||||
logsDir.deleteSync(recursive: true);
|
||||
}
|
||||
@ -126,17 +126,18 @@ class SettingsViewModel extends BaseViewModel {
|
||||
}
|
||||
|
||||
Future<void> exportLogcatLogs() async {
|
||||
Directory appCache = await getTemporaryDirectory();
|
||||
Directory logDir = Directory('${appCache.path}/logs');
|
||||
final Directory appCache = await getTemporaryDirectory();
|
||||
final Directory logDir = Directory('${appCache.path}/logs');
|
||||
logDir.createSync();
|
||||
String dateTime = DateTime.now()
|
||||
final String dateTime = DateTime.now()
|
||||
.toIso8601String()
|
||||
.replaceAll('-', '')
|
||||
.replaceAll(':', '')
|
||||
.replaceAll('T', '')
|
||||
.replaceAll('.', '');
|
||||
File logcat = File('${logDir.path}/revanced-manager_logcat_$dateTime.log');
|
||||
String logs = await Logcat.execute();
|
||||
final File logcat =
|
||||
File('${logDir.path}/revanced-manager_logcat_$dateTime.log');
|
||||
final String logs = await Logcat.execute();
|
||||
logcat.writeAsStringSync(logs);
|
||||
ShareExtend.share(logcat.path, 'file');
|
||||
}
|
||||
|
Reference in New Issue
Block a user