mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
feat: disable changing patches selection by default (#1132)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
dcd5ba41cf
commit
c400619338
@ -11,6 +11,7 @@
|
|||||||
"noButton": "No",
|
"noButton": "No",
|
||||||
"warning": "Warning",
|
"warning": "Warning",
|
||||||
"notice": "Notice",
|
"notice": "Notice",
|
||||||
|
"noShowAgain": "Don't show this again",
|
||||||
"new": "New",
|
"new": "New",
|
||||||
"navigationView": {
|
"navigationView": {
|
||||||
"dashboardTab": "Dashboard",
|
"dashboardTab": "Dashboard",
|
||||||
@ -136,7 +137,10 @@
|
|||||||
"unsupportedPatchVersion": "Patch is not supported for this app version. Enable the experimental toggle in settings to proceed.",
|
"unsupportedPatchVersion": "Patch is not supported for this app version. Enable the experimental toggle in settings to proceed.",
|
||||||
|
|
||||||
"newPatchDialogText": "This is a new patch that has been added since the last time you have patched this app.",
|
"newPatchDialogText": "This is a new patch that has been added since the last time you have patched this app.",
|
||||||
"newPatch": "New patch"
|
"newPatch": "New patch",
|
||||||
|
|
||||||
|
"patchesChangeWarningDialogText": "It is recommended to use the default selection of patches because changing it may cause unexpected issues.\n\nIf you know what you are doing, you can enable \"Enable changing selection\" in the settings.",
|
||||||
|
"patchesChangeWarningDialogButton": "Use default selection"
|
||||||
},
|
},
|
||||||
"installerView": {
|
"installerView": {
|
||||||
"widgetTitle": "Installer",
|
"widgetTitle": "Installer",
|
||||||
@ -205,6 +209,11 @@
|
|||||||
"logsLabel": "Logs",
|
"logsLabel": "Logs",
|
||||||
"logsHint": "Share Manager's logs",
|
"logsHint": "Share Manager's logs",
|
||||||
|
|
||||||
|
"enablePatchesSelectionLabel": "Enable changing selection",
|
||||||
|
"enablePatchesSelectionHint": "Enable changing the selection of patches.",
|
||||||
|
"enablePatchesSelectionWarningText": "Changing the default selection of patches may cause unexpected issues.\n\nEnable anyways?",
|
||||||
|
"disablePatchesSelectionWarningText": "You are about to disable changing the selection of patches.\nThe default selection of patches will be restored.\n\nDisable anyways?",
|
||||||
|
|
||||||
"autoUpdatePatchesLabel": "Auto update patches",
|
"autoUpdatePatchesLabel": "Auto update patches",
|
||||||
"autoUpdatePatchesHint": "Automatically update ReVanced Patches to the latest version",
|
"autoUpdatePatchesHint": "Automatically update ReVanced Patches to the latest version",
|
||||||
"experimentalUniversalPatchesLabel": "Experimental universal patches support",
|
"experimentalUniversalPatchesLabel": "Experimental universal patches support",
|
||||||
|
@ -2,6 +2,8 @@ import 'dart:convert';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:device_apps/device_apps.dart';
|
import 'package:device_apps/device_apps.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_i18n/widgets/I18nText.dart';
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
@ -11,6 +13,7 @@ import 'package:revanced_manager/models/patched_application.dart';
|
|||||||
import 'package:revanced_manager/services/github_api.dart';
|
import 'package:revanced_manager/services/github_api.dart';
|
||||||
import 'package:revanced_manager/services/revanced_api.dart';
|
import 'package:revanced_manager/services/revanced_api.dart';
|
||||||
import 'package:revanced_manager/services/root_api.dart';
|
import 'package:revanced_manager/services/root_api.dart';
|
||||||
|
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
||||||
import 'package:revanced_manager/utils/check_for_supported_patch.dart';
|
import 'package:revanced_manager/utils/check_for_supported_patch.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:timeago/timeago.dart';
|
import 'package:timeago/timeago.dart';
|
||||||
@ -107,6 +110,41 @@ class ManagerAPI {
|
|||||||
return _prefs.getBool('patchesAutoUpdate') ?? false;
|
return _prefs.getBool('patchesAutoUpdate') ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isPatchesChangeEnabled() {
|
||||||
|
if (getPatchedApps().isNotEmpty && !isChangingToggleModified()) {
|
||||||
|
for (final apps in getPatchedApps()) {
|
||||||
|
if (getSavedPatches(apps.originalPackageName)
|
||||||
|
.indexWhere((patch) => patch.excluded) !=
|
||||||
|
-1) {
|
||||||
|
setPatchesChangeWarning(false);
|
||||||
|
setPatchesChangeEnabled(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _prefs.getBool('patchesChangeEnabled') ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPatchesChangeEnabled(bool value) {
|
||||||
|
_prefs.setBool('patchesChangeEnabled', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showPatchesChangeWarning() {
|
||||||
|
return _prefs.getBool('showPatchesChangeWarning') ?? true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPatchesChangeWarning(bool value) {
|
||||||
|
_prefs.setBool('showPatchesChangeWarning', !value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isChangingToggleModified() {
|
||||||
|
return _prefs.getBool('isChangingToggleModified') ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setChangingToggleModified(bool value) {
|
||||||
|
_prefs.setBool('isChangingToggleModified', value);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> setPatchesAutoUpdate(bool value) async {
|
Future<void> setPatchesAutoUpdate(bool value) async {
|
||||||
await _prefs.setBool('patchesAutoUpdate', value);
|
await _prefs.setBool('patchesAutoUpdate', value);
|
||||||
}
|
}
|
||||||
@ -515,6 +553,63 @@ class ManagerAPI {
|
|||||||
return unsavedApps;
|
return unsavedApps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> showPatchesChangeWarningDialog(BuildContext context) {
|
||||||
|
final ValueNotifier<bool> noShow =
|
||||||
|
ValueNotifier(!showPatchesChangeWarning());
|
||||||
|
return showDialog(
|
||||||
|
barrierDismissible: false,
|
||||||
|
context: context,
|
||||||
|
builder: (context) => WillPopScope(
|
||||||
|
onWillPop: () async => false,
|
||||||
|
child: AlertDialog(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
title: I18nText('warning'),
|
||||||
|
content: ValueListenableBuilder(
|
||||||
|
valueListenable: noShow,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
I18nText(
|
||||||
|
'patchItem.patchesChangeWarningDialogText',
|
||||||
|
child: const Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
CheckboxListTile(
|
||||||
|
value: value,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
title: I18nText(
|
||||||
|
'noShowAgain',
|
||||||
|
),
|
||||||
|
onChanged: (selected) {
|
||||||
|
noShow.value = selected!;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CustomMaterialButton(
|
||||||
|
label: I18nText('okButton'),
|
||||||
|
onPressed: () {
|
||||||
|
setPatchesChangeWarning(noShow.value);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> reAssessSavedApps() async {
|
Future<void> reAssessSavedApps() async {
|
||||||
final List<PatchedApplication> patchedApps = getPatchedApps();
|
final List<PatchedApplication> patchedApps = getPatchedApps();
|
||||||
final List<PatchedApplication> unsavedApps =
|
final List<PatchedApplication> unsavedApps =
|
||||||
|
@ -191,6 +191,10 @@ class PatcherViewModel extends BaseViewModel {
|
|||||||
this
|
this
|
||||||
.selectedPatches
|
.selectedPatches
|
||||||
.addAll(patches.where((patch) => selectedPatches.contains(patch.name)));
|
.addAll(patches.where((patch) => selectedPatches.contains(patch.name)));
|
||||||
|
if (!_managerAPI.isPatchesChangeEnabled()) {
|
||||||
|
this.selectedPatches.clear();
|
||||||
|
this.selectedPatches.addAll(patches.where((patch) => !patch.excluded));
|
||||||
|
}
|
||||||
if (!_managerAPI.areExperimentalPatchesEnabled()) {
|
if (!_managerAPI.areExperimentalPatchesEnabled()) {
|
||||||
this.selectedPatches.removeWhere((patch) => !isPatchSupported(patch));
|
this.selectedPatches.removeWhere((patch) => !isPatchSupported(patch));
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,17 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
String _query = '';
|
String _query = '';
|
||||||
final _managerAPI = locator<ManagerAPI>();
|
final _managerAPI = locator<ManagerAPI>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
if (!_managerAPI.isPatchesChangeEnabled() &&
|
||||||
|
_managerAPI.showPatchesChangeWarning()) {
|
||||||
|
_managerAPI.showPatchesChangeWarningDialog(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ViewModelBuilder<PatchesSelectorViewModel>.reactive(
|
return ViewModelBuilder<PatchesSelectorViewModel>.reactive(
|
||||||
@ -87,7 +98,8 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
CustomPopupMenu(
|
CustomPopupMenu(
|
||||||
onSelected: (value) => {model.onMenuSelection(value)},
|
onSelected: (value) =>
|
||||||
|
{model.onMenuSelection(value, context)},
|
||||||
children: {
|
children: {
|
||||||
0: I18nText(
|
0: I18nText(
|
||||||
'patchesSelectorView.loadPatchesSelection',
|
'patchesSelectorView.loadPatchesSelection',
|
||||||
@ -152,7 +164,11 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
'patchesSelectorView.defaultTooltip',
|
'patchesSelectorView.defaultTooltip',
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
model.selectDefaultPatches();
|
if (_managerAPI.isPatchesChangeEnabled()) {
|
||||||
|
model.selectDefaultPatches();
|
||||||
|
} else {
|
||||||
|
model.showPatchesChangeDialog(context);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
@ -163,7 +179,11 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
'patchesSelectorView.noneTooltip',
|
'patchesSelectorView.noneTooltip',
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
model.clearPatches();
|
if (_managerAPI.isPatchesChangeEnabled()) {
|
||||||
|
model.clearPatches();
|
||||||
|
} else {
|
||||||
|
model.showPatchesChangeDialog(context);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -179,13 +199,14 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
supportedPackageVersions:
|
supportedPackageVersions:
|
||||||
model.getSupportedVersions(patch),
|
model.getSupportedVersions(patch),
|
||||||
isUnsupported: !isPatchSupported(patch),
|
isUnsupported: !isPatchSupported(patch),
|
||||||
|
isChangeEnabled: _managerAPI.isPatchesChangeEnabled(),
|
||||||
isNew: model.isPatchNew(
|
isNew: model.isPatchNew(
|
||||||
patch,
|
patch,
|
||||||
model.getAppInfo().packageName,
|
model.getAppInfo().packageName,
|
||||||
),
|
),
|
||||||
isSelected: model.isSelected(patch),
|
isSelected: model.isSelected(patch),
|
||||||
onChanged: (value) =>
|
onChanged: (value) =>
|
||||||
model.selectPatch(patch, value),
|
model.selectPatch(patch, value, context),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Container();
|
return Container();
|
||||||
@ -215,10 +236,14 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
supportedPackageVersions:
|
supportedPackageVersions:
|
||||||
model.getSupportedVersions(patch),
|
model.getSupportedVersions(patch),
|
||||||
isUnsupported: !isPatchSupported(patch),
|
isUnsupported: !isPatchSupported(patch),
|
||||||
|
isChangeEnabled: _managerAPI.isPatchesChangeEnabled(),
|
||||||
isNew: false,
|
isNew: false,
|
||||||
isSelected: model.isSelected(patch),
|
isSelected: model.isSelected(patch),
|
||||||
onChanged: (value) =>
|
onChanged: (value) => model.selectPatch(
|
||||||
model.selectPatch(patch, value),
|
patch,
|
||||||
|
false,
|
||||||
|
context,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Container();
|
return Container();
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import 'package:collection/collection.dart';
|
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/app/app.locator.dart';
|
||||||
import 'package:revanced_manager/models/patch.dart';
|
import 'package:revanced_manager/models/patch.dart';
|
||||||
import 'package:revanced_manager/models/patched_application.dart';
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
@ -6,6 +8,7 @@ import 'package:revanced_manager/services/manager_api.dart';
|
|||||||
import 'package:revanced_manager/services/patcher_api.dart';
|
import 'package:revanced_manager/services/patcher_api.dart';
|
||||||
import 'package:revanced_manager/services/toast.dart';
|
import 'package:revanced_manager/services/toast.dart';
|
||||||
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
||||||
|
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
||||||
import 'package:revanced_manager/utils/check_for_supported_patch.dart';
|
import 'package:revanced_manager/utils/check_for_supported_patch.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
|
|
||||||
@ -45,31 +48,70 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectPatch(Patch patch, bool isSelected) {
|
void selectPatch(Patch patch, bool isSelected, BuildContext context) {
|
||||||
if (isSelected && !selectedPatches.contains(patch)) {
|
if (_managerAPI.isPatchesChangeEnabled()) {
|
||||||
selectedPatches.add(patch);
|
if (isSelected && !selectedPatches.contains(patch)) {
|
||||||
|
selectedPatches.add(patch);
|
||||||
|
} else {
|
||||||
|
selectedPatches.remove(patch);
|
||||||
|
}
|
||||||
|
notifyListeners();
|
||||||
} else {
|
} else {
|
||||||
selectedPatches.remove(patch);
|
showPatchesChangeDialog(context);
|
||||||
}
|
}
|
||||||
notifyListeners();
|
}
|
||||||
|
|
||||||
|
Future<void> showPatchesChangeDialog(BuildContext context) async {
|
||||||
|
return showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
title: I18nText('warning'),
|
||||||
|
content: I18nText(
|
||||||
|
'patchItem.patchesChangeWarningDialogText',
|
||||||
|
child: const Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CustomMaterialButton(
|
||||||
|
isFilled: false,
|
||||||
|
label: I18nText('okButton'),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
CustomMaterialButton(
|
||||||
|
label: I18nText('patchItem.patchesChangeWarningDialogButton'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context)
|
||||||
|
..pop()
|
||||||
|
..pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectDefaultPatches() {
|
void selectDefaultPatches() {
|
||||||
selectedPatches.clear();
|
selectedPatches.clear();
|
||||||
|
if (locator<PatcherViewModel>().selectedApp?.originalPackageName != null) {
|
||||||
if (_managerAPI.areExperimentalPatchesEnabled() == false) {
|
|
||||||
selectedPatches.addAll(
|
selectedPatches.addAll(
|
||||||
patches.where(
|
_patcherAPI
|
||||||
(element) => element.excluded == false && isPatchSupported(element),
|
.getFilteredPatches(
|
||||||
),
|
locator<PatcherViewModel>().selectedApp!.originalPackageName,
|
||||||
|
)
|
||||||
|
.where(
|
||||||
|
(element) =>
|
||||||
|
!element.excluded &&
|
||||||
|
(_managerAPI.areExperimentalPatchesEnabled() ||
|
||||||
|
isPatchSupported(element)),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_managerAPI.areExperimentalPatchesEnabled()) {
|
|
||||||
selectedPatches
|
|
||||||
.addAll(patches.where((element) => element.excluded == false));
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,10 +175,10 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onMenuSelection(value) {
|
void onMenuSelection(value, BuildContext context) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 0:
|
case 0:
|
||||||
loadSelectedPatches();
|
loadSelectedPatches(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,18 +192,25 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadSelectedPatches() async {
|
Future<void> loadSelectedPatches(BuildContext context) async {
|
||||||
final List<String> selectedPatches = await _managerAPI.getSelectedPatches(
|
if (_managerAPI.isPatchesChangeEnabled()) {
|
||||||
locator<PatcherViewModel>().selectedApp!.originalPackageName,
|
final List<String> selectedPatches = await _managerAPI.getSelectedPatches(
|
||||||
);
|
locator<PatcherViewModel>().selectedApp!.originalPackageName,
|
||||||
if (selectedPatches.isNotEmpty) {
|
);
|
||||||
this.selectedPatches.clear();
|
if (selectedPatches.isNotEmpty) {
|
||||||
this.selectedPatches.addAll(
|
this.selectedPatches.clear();
|
||||||
patches.where((patch) => selectedPatches.contains(patch.name)),
|
this.selectedPatches.addAll(
|
||||||
);
|
patches.where((patch) => selectedPatches.contains(patch.name)),
|
||||||
|
);
|
||||||
|
if (!_managerAPI.areExperimentalPatchesEnabled()) {
|
||||||
|
this.selectedPatches.removeWhere((patch) => !isPatchSupported(patch));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
locator<Toast>().showBottom('patchesSelectorView.noSavedPatches');
|
||||||
|
}
|
||||||
|
notifyListeners();
|
||||||
} else {
|
} else {
|
||||||
locator<Toast>().showBottom('patchesSelectorView.noSavedPatches');
|
showPatchesChangeDialog(context);
|
||||||
}
|
}
|
||||||
notifyListeners();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ import 'package:cr_file_saver/file_saver.dart';
|
|||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_i18n/flutter_i18n.dart';
|
||||||
import 'package:logcat/logcat.dart';
|
import 'package:logcat/logcat.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
@ -10,8 +12,10 @@ import 'package:revanced_manager/app/app.router.dart';
|
|||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
import 'package:revanced_manager/services/toast.dart';
|
import 'package:revanced_manager/services/toast.dart';
|
||||||
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
||||||
|
import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_language.dart';
|
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_language.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_theme.dart';
|
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_theme.dart';
|
||||||
|
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
||||||
import 'package:share_extend/share_extend.dart';
|
import 'package:share_extend/share_extend.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:stacked_services/stacked_services.dart';
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
@ -19,6 +23,9 @@ import 'package:stacked_services/stacked_services.dart';
|
|||||||
class SettingsViewModel extends BaseViewModel {
|
class SettingsViewModel extends BaseViewModel {
|
||||||
final NavigationService _navigationService = locator<NavigationService>();
|
final NavigationService _navigationService = locator<NavigationService>();
|
||||||
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
||||||
|
final PatchesSelectorViewModel _patchesSelectorViewModel =
|
||||||
|
PatchesSelectorViewModel();
|
||||||
|
final PatcherViewModel _patcherViewModel = locator<PatcherViewModel>();
|
||||||
final Toast _toast = locator<Toast>();
|
final Toast _toast = locator<Toast>();
|
||||||
|
|
||||||
final SUpdateLanguage sUpdateLanguage = SUpdateLanguage();
|
final SUpdateLanguage sUpdateLanguage = SUpdateLanguage();
|
||||||
@ -37,6 +44,88 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isPatchesChangeEnabled() {
|
||||||
|
return _managerAPI.isPatchesChangeEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> showPatchesChangeEnableDialog(
|
||||||
|
bool value,
|
||||||
|
BuildContext context,
|
||||||
|
) async {
|
||||||
|
if (value) {
|
||||||
|
return showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
title: I18nText('warning'),
|
||||||
|
content: I18nText(
|
||||||
|
'settingsView.enablePatchesSelectionWarningText',
|
||||||
|
child: const Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CustomMaterialButton(
|
||||||
|
isFilled: false,
|
||||||
|
label: I18nText('noButton'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
CustomMaterialButton(
|
||||||
|
label: I18nText('yesButton'),
|
||||||
|
onPressed: () {
|
||||||
|
_managerAPI.setChangingToggleModified(true);
|
||||||
|
_managerAPI.setPatchesChangeEnabled(true);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
title: I18nText('warning'),
|
||||||
|
content: I18nText(
|
||||||
|
'settingsView.disablePatchesSelectionWarningText',
|
||||||
|
child: const Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CustomMaterialButton(
|
||||||
|
isFilled: false,
|
||||||
|
label: I18nText('noButton'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
CustomMaterialButton(
|
||||||
|
label: I18nText('yesButton'),
|
||||||
|
onPressed: () {
|
||||||
|
_managerAPI.setChangingToggleModified(true);
|
||||||
|
_patchesSelectorViewModel.selectDefaultPatches();
|
||||||
|
_managerAPI.setPatchesChangeEnabled(false);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool areUniversalPatchesEnabled() {
|
bool areUniversalPatchesEnabled() {
|
||||||
return _managerAPI.areUniversalPatchesEnabled();
|
return _managerAPI.areUniversalPatchesEnabled();
|
||||||
}
|
}
|
||||||
@ -90,26 +179,30 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> importPatches() async {
|
Future<void> importPatches(BuildContext context) async {
|
||||||
try {
|
if (isPatchesChangeEnabled()) {
|
||||||
final FilePickerResult? result = await FilePicker.platform.pickFiles(
|
try {
|
||||||
type: FileType.custom,
|
final FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||||
allowedExtensions: ['json'],
|
type: FileType.custom,
|
||||||
);
|
allowedExtensions: ['json'],
|
||||||
if (result != null && result.files.single.path != null) {
|
);
|
||||||
final File inFile = File(result.files.single.path!);
|
if (result != null && result.files.single.path != null) {
|
||||||
inFile.copySync(_managerAPI.storedPatchesFile);
|
final File inFile = File(result.files.single.path!);
|
||||||
inFile.delete();
|
inFile.copySync(_managerAPI.storedPatchesFile);
|
||||||
if (locator<PatcherViewModel>().selectedApp != null) {
|
inFile.delete();
|
||||||
locator<PatcherViewModel>().loadLastSelectedPatches();
|
if (_patcherViewModel.selectedApp != null) {
|
||||||
|
_patcherViewModel.loadLastSelectedPatches();
|
||||||
|
}
|
||||||
|
_toast.showBottom('settingsView.importedPatches');
|
||||||
}
|
}
|
||||||
_toast.showBottom('settingsView.importedPatches');
|
} on Exception catch (e) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
_toast.showBottom('settingsView.jsonSelectorErrorMessage');
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} else {
|
||||||
if (kDebugMode) {
|
_managerAPI.showPatchesChangeWarningDialog(context);
|
||||||
print(e);
|
|
||||||
}
|
|
||||||
_toast.showBottom('settingsView.jsonSelectorErrorMessage');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ class PatchItem extends StatefulWidget {
|
|||||||
required this.isNew,
|
required this.isNew,
|
||||||
required this.isSelected,
|
required this.isSelected,
|
||||||
required this.onChanged,
|
required this.onChanged,
|
||||||
|
required this.isChangeEnabled,
|
||||||
this.child,
|
this.child,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
final String name;
|
final String name;
|
||||||
@ -30,6 +31,7 @@ class PatchItem extends StatefulWidget {
|
|||||||
final bool isNew;
|
final bool isNew;
|
||||||
bool isSelected;
|
bool isSelected;
|
||||||
final Function(bool) onChanged;
|
final Function(bool) onChanged;
|
||||||
|
final bool isChangeEnabled;
|
||||||
final Widget? child;
|
final Widget? child;
|
||||||
final toast = locator<Toast>();
|
final toast = locator<Toast>();
|
||||||
final _managerAPI = locator<ManagerAPI>();
|
final _managerAPI = locator<ManagerAPI>();
|
||||||
@ -58,11 +60,13 @@ class _PatchItemState extends State<PatchItem> {
|
|||||||
!widget._managerAPI.areExperimentalPatchesEnabled()) {
|
!widget._managerAPI.areExperimentalPatchesEnabled()) {
|
||||||
widget.isSelected = false;
|
widget.isSelected = false;
|
||||||
widget.toast.showBottom('patchItem.unsupportedPatchVersion');
|
widget.toast.showBottom('patchItem.unsupportedPatchVersion');
|
||||||
} else {
|
} else if (widget.isChangeEnabled) {
|
||||||
widget.isSelected = !widget.isSelected;
|
widget.isSelected = !widget.isSelected;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
widget.onChanged(widget.isSelected);
|
if (!widget.isUnsupported || widget._managerAPI.areExperimentalPatchesEnabled()) {
|
||||||
|
widget.onChanged(widget.isSelected);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@ -124,11 +128,13 @@ class _PatchItemState extends State<PatchItem> {
|
|||||||
widget.toast.showBottom(
|
widget.toast.showBottom(
|
||||||
'patchItem.unsupportedPatchVersion',
|
'patchItem.unsupportedPatchVersion',
|
||||||
);
|
);
|
||||||
} else {
|
} else if (widget.isChangeEnabled) {
|
||||||
widget.isSelected = newValue!;
|
widget.isSelected = newValue!;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
widget.onChanged(widget.isSelected);
|
if (!widget.isUnsupported || widget._managerAPI.areExperimentalPatchesEnabled()) {
|
||||||
|
widget.onChanged(widget.isSelected);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -5,6 +5,7 @@ import 'package:flutter_i18n/widgets/I18nText.dart';
|
|||||||
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_api_url.dart';
|
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_api_url.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_sources.dart';
|
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_sources.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
||||||
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_enable_patches_selection.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_auto_update_patches.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_auto_update_patches.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_patches.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_patches.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_universal_patches.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_universal_patches.dart';
|
||||||
@ -25,6 +26,7 @@ class SAdvancedSection extends StatelessWidget {
|
|||||||
SManageSourcesUI(),
|
SManageSourcesUI(),
|
||||||
// SManageKeystorePasswordUI(),
|
// SManageKeystorePasswordUI(),
|
||||||
SAutoUpdatePatches(),
|
SAutoUpdatePatches(),
|
||||||
|
SEnablePatchesSelection(),
|
||||||
SExperimentalUniversalPatches(),
|
SExperimentalUniversalPatches(),
|
||||||
SExperimentalPatches(),
|
SExperimentalPatches(),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_i18n/widgets/I18nText.dart';
|
||||||
|
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
||||||
|
|
||||||
|
class SEnablePatchesSelection extends StatefulWidget {
|
||||||
|
const SEnablePatchesSelection({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SEnablePatchesSelection> createState() => _SEnablePatchesSelectionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
final _settingsViewModel = SettingsViewModel();
|
||||||
|
|
||||||
|
class _SEnablePatchesSelectionState extends State<SEnablePatchesSelection> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SwitchListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
|
title: I18nText(
|
||||||
|
'settingsView.enablePatchesSelectionLabel',
|
||||||
|
child: const Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: I18nText('settingsView.enablePatchesSelectionHint'),
|
||||||
|
value: _settingsViewModel.isPatchesChangeEnabled(),
|
||||||
|
onChanged: (value) async {
|
||||||
|
await _settingsViewModel.showPatchesChangeEnableDialog(value, context);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -43,7 +43,7 @@ class SExportSection extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: I18nText('settingsView.importPatchesHint'),
|
subtitle: I18nText('settingsView.importPatchesHint'),
|
||||||
onTap: () => _settingsViewModel.importPatches(),
|
onTap: () => _settingsViewModel.importPatches(context),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
@ -73,10 +73,10 @@ class SExportSection extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: I18nText('settingsView.importKeystoreHint'),
|
subtitle: I18nText('settingsView.importKeystoreHint'),
|
||||||
onTap: () async{
|
onTap: () async {
|
||||||
await _settingsViewModel.importKeystore();
|
await _settingsViewModel.importKeystore();
|
||||||
final sManageKeystorePassword = SManageKeystorePassword();
|
final sManageKeystorePassword = SManageKeystorePassword();
|
||||||
if(context.mounted){
|
if (context.mounted) {
|
||||||
sManageKeystorePassword.showKeystoreDialog(context);
|
sManageKeystorePassword.showKeystoreDialog(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user