mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
feat: Disable selection of un-suggested app version by default (#1471)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
e7d82850c9
commit
70b2ee0a84
@ -111,6 +111,8 @@
|
|||||||
|
|
||||||
"downloadToast": "Download function is not available yet",
|
"downloadToast": "Download function is not available yet",
|
||||||
|
|
||||||
|
"requireSuggestedAppVersionDialogText": "The version of the app you have selected does not match the suggested version. Please select the app that matches the suggested version.\n\nSelected version: v{selected}\nSuggested version: v{suggested}\n\n.To proceed anyway, disable \"Require suggested app version\" in the settings.",
|
||||||
|
|
||||||
"featureNotAvailable": "Feature not implemented",
|
"featureNotAvailable": "Feature not implemented",
|
||||||
"featureNotAvailableText": "This application is a split APK and cannot be selected. Unfortunately, this feature is only available for rooted users at the moment. However, you can still install the application by selecting its APK files from your device's storage instead"
|
"featureNotAvailableText": "This application is a split APK and cannot be selected. Unfortunately, this feature is only available for rooted users at the moment. However, you can still install the application by selecting its APK files from your device's storage instead"
|
||||||
},
|
},
|
||||||
@ -234,8 +236,12 @@
|
|||||||
"autoUpdatePatchesHint": "Automatically update patches to the latest version",
|
"autoUpdatePatchesHint": "Automatically update patches to the latest version",
|
||||||
"universalPatchesLabel": "Show universal patches",
|
"universalPatchesLabel": "Show universal patches",
|
||||||
"universalPatchesHint": "Display all apps and universal patches (may slow down the app list)",
|
"universalPatchesHint": "Display all apps and universal patches (may slow down the app list)",
|
||||||
|
|
||||||
"versionCompatibilityCheckLabel": "Version compatibility check",
|
"versionCompatibilityCheckLabel": "Version compatibility check",
|
||||||
"versionCompatibilityCheckHint": "Restricts patches to supported app versions",
|
"versionCompatibilityCheckHint": "Restricts patches to supported app versions",
|
||||||
|
"requireSuggestedAppVersionLabel": "Require suggested app version",
|
||||||
|
"requireSuggestedAppVersionHint": "Enforce selection of suggested app version",
|
||||||
|
"requireSuggestedAppVersionDialogText": "Selecting an app that is not the suggested version may cause unexpected issues.\n\nDo you want to proceed anyways?",
|
||||||
|
|
||||||
"aboutLabel": "About",
|
"aboutLabel": "About",
|
||||||
"snackbarMessage": "Copied to clipboard",
|
"snackbarMessage": "Copied to clipboard",
|
||||||
|
@ -34,6 +34,7 @@ class ManagerAPI {
|
|||||||
Patch? selectedPatch;
|
Patch? selectedPatch;
|
||||||
BuildContext? ctx;
|
BuildContext? ctx;
|
||||||
bool isRooted = false;
|
bool isRooted = false;
|
||||||
|
bool suggestedAppVersionSelected = true;
|
||||||
bool isDynamicThemeAvailable = false;
|
bool isDynamicThemeAvailable = false;
|
||||||
String storedPatchesFile = '/selected-patches.json';
|
String storedPatchesFile = '/selected-patches.json';
|
||||||
String keystoreFile =
|
String keystoreFile =
|
||||||
@ -259,6 +260,14 @@ class ManagerAPI {
|
|||||||
await _prefs.setBool('versionCompatibilityCheckEnabled', value);
|
await _prefs.setBool('versionCompatibilityCheckEnabled', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isRequireSuggestedAppVersionEnabled() {
|
||||||
|
return _prefs.getBool('requireSuggestedAppVersionEnabled') ?? true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> enableRequireSuggestedAppVersionStatus(bool value) async {
|
||||||
|
await _prefs.setBool('requireSuggestedAppVersionEnabled', value);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> setKeystorePassword(String password) async {
|
Future<void> setKeystorePassword(String password) async {
|
||||||
await _prefs.setString('keystorePassword', password);
|
await _prefs.setString('keystorePassword', password);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
|||||||
icon: const Icon(Icons.sd_storage),
|
icon: const Icon(Icons.sd_storage),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
model.selectAppFromStorage(context);
|
model.selectAppFromStorage(context);
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
|
@ -70,7 +70,26 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> selectApp(ApplicationWithIcon application) async {
|
Future<void> selectApp(
|
||||||
|
BuildContext context,
|
||||||
|
ApplicationWithIcon application, [
|
||||||
|
bool isFromStorage = false,
|
||||||
|
]) async {
|
||||||
|
final String suggestedVersion =
|
||||||
|
getSuggestedVersion(application.packageName);
|
||||||
|
if (application.versionName != suggestedVersion && suggestedVersion.isNotEmpty) {
|
||||||
|
_managerAPI.suggestedAppVersionSelected = false;
|
||||||
|
if (_managerAPI.isRequireSuggestedAppVersionEnabled() &&
|
||||||
|
context.mounted) {
|
||||||
|
return showRequireSuggestedAppVersionDialog(
|
||||||
|
context,
|
||||||
|
application.versionName!,
|
||||||
|
suggestedVersion,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_managerAPI.suggestedAppVersionSelected = true;
|
||||||
|
}
|
||||||
locator<PatcherViewModel>().selectedApp = PatchedApplication(
|
locator<PatcherViewModel>().selectedApp = PatchedApplication(
|
||||||
name: application.appName,
|
name: application.appName,
|
||||||
packageName: application.packageName,
|
packageName: application.packageName,
|
||||||
@ -78,8 +97,12 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
apkFilePath: application.apkFilePath,
|
apkFilePath: application.apkFilePath,
|
||||||
icon: application.icon,
|
icon: application.icon,
|
||||||
patchDate: DateTime.now(),
|
patchDate: DateTime.now(),
|
||||||
|
isFromStorage: isFromStorage,
|
||||||
);
|
);
|
||||||
await locator<PatcherViewModel>().loadLastSelectedPatches();
|
await locator<PatcherViewModel>().loadLastSelectedPatches();
|
||||||
|
if (context.mounted) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> canSelectInstalled(
|
Future<void> canSelectInstalled(
|
||||||
@ -89,23 +112,60 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
final app =
|
final app =
|
||||||
await DeviceApps.getApp(packageName, true) as ApplicationWithIcon?;
|
await DeviceApps.getApp(packageName, true) as ApplicationWithIcon?;
|
||||||
if (app != null) {
|
if (app != null) {
|
||||||
if (await checkSplitApk(packageName) && !isRooted) {
|
final bool isSplitApk = await checkSplitApk(packageName);
|
||||||
|
if (isRooted || !isSplitApk) {
|
||||||
|
if (context.mounted) {
|
||||||
|
await selectApp(context, app);
|
||||||
|
}
|
||||||
|
final List<Option> requiredNullOptions = getNullRequiredOptions(
|
||||||
|
locator<PatcherViewModel>().selectedPatches,
|
||||||
|
packageName,
|
||||||
|
);
|
||||||
|
if (requiredNullOptions.isNotEmpty) {
|
||||||
|
locator<PatcherViewModel>().showRequiredOptionDialog();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
return showSelectFromStorageDialog(context);
|
return showSelectFromStorageDialog(context);
|
||||||
}
|
}
|
||||||
} else if (!await checkSplitApk(packageName) || isRooted) {
|
|
||||||
await selectApp(app);
|
|
||||||
if (context.mounted) {
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
|
||||||
final List<Option> requiredNullOptions = getNullRequiredOptions(locator<PatcherViewModel>().selectedPatches, packageName);
|
|
||||||
if(requiredNullOptions.isNotEmpty){
|
|
||||||
locator<PatcherViewModel>().showRequiredOptionDialog();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future showRequireSuggestedAppVersionDialog(
|
||||||
|
BuildContext context,
|
||||||
|
String selectedVersion,
|
||||||
|
String suggestedVersion,
|
||||||
|
) async {
|
||||||
|
return showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
title: I18nText('warning'),
|
||||||
|
content: I18nText(
|
||||||
|
'appSelectorView.requireSuggestedAppVersionDialogText',
|
||||||
|
translationParams: {
|
||||||
|
'suggested': suggestedVersion,
|
||||||
|
'selected': selectedVersion,
|
||||||
|
},
|
||||||
|
child: const Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CustomMaterialButton(
|
||||||
|
label: I18nText('okButton'),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future showSelectFromStorageDialog(BuildContext context) async {
|
Future showSelectFromStorageDialog(BuildContext context) async {
|
||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -145,12 +205,10 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
CustomMaterialButton(
|
CustomMaterialButton(
|
||||||
onPressed: () => selectAppFromStorage(context).then(
|
onPressed: () async {
|
||||||
(_) {
|
Navigator.pop(context);
|
||||||
Navigator.pop(context);
|
await selectAppFromStorage(context);
|
||||||
Navigator.pop(context);
|
},
|
||||||
},
|
|
||||||
),
|
|
||||||
label: Row(
|
label: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
@ -203,17 +261,8 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
apkFile.path,
|
apkFile.path,
|
||||||
true,
|
true,
|
||||||
) as ApplicationWithIcon?;
|
) as ApplicationWithIcon?;
|
||||||
if (application != null) {
|
if (application != null && context.mounted) {
|
||||||
locator<PatcherViewModel>().selectedApp = PatchedApplication(
|
await selectApp(context, application, true);
|
||||||
name: application.appName,
|
|
||||||
packageName: application.packageName,
|
|
||||||
version: application.versionName!,
|
|
||||||
apkFilePath: result,
|
|
||||||
icon: application.icon,
|
|
||||||
patchDate: DateTime.now(),
|
|
||||||
isFromStorage: true,
|
|
||||||
);
|
|
||||||
locator<PatcherViewModel>().loadLastSelectedPatches();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
|
@ -140,6 +140,57 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isRequireSuggestedAppVersionEnabled() {
|
||||||
|
return _managerAPI.isRequireSuggestedAppVersionEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void>? showRequireSuggestedAppVersionDialog(
|
||||||
|
BuildContext context, bool value) {
|
||||||
|
if (!value) {
|
||||||
|
return showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
title: I18nText('warning'),
|
||||||
|
content: I18nText(
|
||||||
|
'settingsView.requireSuggestedAppVersionDialogText',
|
||||||
|
child: const Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CustomMaterialButton(
|
||||||
|
isFilled: false,
|
||||||
|
label: I18nText('yesButton'),
|
||||||
|
onPressed: () {
|
||||||
|
_managerAPI.enableRequireSuggestedAppVersionStatus(false);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
CustomMaterialButton(
|
||||||
|
label: I18nText('noButton'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_managerAPI.enableRequireSuggestedAppVersionStatus(true);
|
||||||
|
|
||||||
|
if (!_managerAPI.suggestedAppVersionSelected) {
|
||||||
|
_patcherViewModel.selectedApp = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void deleteKeystore() {
|
void deleteKeystore() {
|
||||||
_managerAPI.deleteKeystore();
|
_managerAPI.deleteKeystore();
|
||||||
_toast.showBottom('settingsView.regeneratedKeystore');
|
_toast.showBottom('settingsView.regeneratedKeystore');
|
||||||
|
@ -5,6 +5,7 @@ import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_man
|
|||||||
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/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_enable_patches_selection.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_enable_patches_selection.dart';
|
||||||
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_require_suggested_app_version.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_universal_patches.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_universal_patches.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_version_compatibility_check.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_version_compatibility_check.dart';
|
||||||
@ -20,6 +21,7 @@ class SAdvancedSection extends StatelessWidget {
|
|||||||
children: const <Widget>[
|
children: const <Widget>[
|
||||||
SAutoUpdatePatches(),
|
SAutoUpdatePatches(),
|
||||||
SEnablePatchesSelection(),
|
SEnablePatchesSelection(),
|
||||||
|
SRequireSuggestedAppVersion(),
|
||||||
SVersionCompatibilityCheck(),
|
SVersionCompatibilityCheck(),
|
||||||
SUniversalPatches(),
|
SUniversalPatches(),
|
||||||
SManageSourcesUI(),
|
SManageSourcesUI(),
|
||||||
|
@ -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 SRequireSuggestedAppVersion extends StatefulWidget {
|
||||||
|
const SRequireSuggestedAppVersion({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SRequireSuggestedAppVersion> createState() => _SRequireSuggestedAppVersionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
final _settingsViewModel = SettingsViewModel();
|
||||||
|
|
||||||
|
class _SRequireSuggestedAppVersionState extends State<SRequireSuggestedAppVersion> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SwitchListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
|
title: I18nText(
|
||||||
|
'settingsView.requireSuggestedAppVersionLabel',
|
||||||
|
child: const Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: I18nText('settingsView.requireSuggestedAppVersionHint'),
|
||||||
|
value: _settingsViewModel.isRequireSuggestedAppVersionEnabled(),
|
||||||
|
onChanged: (value) async {
|
||||||
|
await _settingsViewModel.showRequireSuggestedAppVersionDialog(context, value);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user