Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Disable selection of unsuggested app version by default #1471

Merged
merged 6 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions assets/i18n/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@

"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",
"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"
},
Expand Down Expand Up @@ -234,8 +236,12 @@
"autoUpdatePatchesHint": "Automatically update patches to the latest version",
"universalPatchesLabel": "Show universal patches",
"universalPatchesHint": "Display all apps and universal patches (may slow down the app list)",

"versionCompatibilityCheckLabel": "Version compatibility check",
"versionCompatibilityCheckHint": "Restricts patches to supported app versions",
"requireSuggestedAppVersionLabel": "Require suggested app version",
"requireSuggestedAppVersionHint": "Enforce selection of suggested app version",
"requireSuggestedAppVersionDialogText": "Selecting an app that does not have the suggested version may cause unexpected issues.\n\nDisable anyways?",
oSumAtrIX marked this conversation as resolved.
Show resolved Hide resolved

"aboutLabel": "About",
"snackbarMessage": "Copied to clipboard",
Expand Down
9 changes: 9 additions & 0 deletions lib/services/manager_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class ManagerAPI {
Patch? selectedPatch;
BuildContext? ctx;
bool isRooted = false;
bool suggestedAppVersionSelected = true;
bool isDynamicThemeAvailable = false;
String storedPatchesFile = '/selected-patches.json';
String keystoreFile =
Expand Down Expand Up @@ -259,6 +260,14 @@ class ManagerAPI {
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 {
await _prefs.setString('keystorePassword', password);
}
Expand Down
1 change: 0 additions & 1 deletion lib/ui/views/app_selector/app_selector_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class _AppSelectorViewState extends State<AppSelectorView> {
icon: const Icon(Icons.sd_storage),
onPressed: () {
model.selectAppFromStorage(context);
Navigator.of(context).pop();
},
),
body: CustomScrollView(
Expand Down
103 changes: 76 additions & 27 deletions lib/ui/views/app_selector/app_selector_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,39 @@ class AppSelectorViewModel extends BaseViewModel {
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(
name: application.appName,
packageName: application.packageName,
version: application.versionName!,
apkFilePath: application.apkFilePath,
icon: application.icon,
patchDate: DateTime.now(),
isFromStorage: isFromStorage,
);
await locator<PatcherViewModel>().loadLastSelectedPatches();
if (context.mounted) {
Navigator.pop(context);
}
}

Future<void> canSelectInstalled(
Expand All @@ -89,23 +112,60 @@ class AppSelectorViewModel extends BaseViewModel {
final app =
await DeviceApps.getApp(packageName, true) as ApplicationWithIcon?;
if (app != null) {
if (await checkSplitApk(packageName) && !isRooted) {
if (context.mounted) {
return showSelectFromStorageDialog(context);
}
} else if (!await checkSplitApk(packageName) || isRooted) {
await selectApp(app);
final bool isSplitApk = await checkSplitApk(packageName);
if (isRooted || !isSplitApk) {
if (context.mounted) {
Navigator.pop(context);
await selectApp(context, app);
}
final List<Option> requiredNullOptions = getNullRequiredOptions(locator<PatcherViewModel>().selectedPatches, packageName);
if(requiredNullOptions.isNotEmpty){
final List<Option> requiredNullOptions = getNullRequiredOptions(
locator<PatcherViewModel>().selectedPatches,
packageName,
);
if (requiredNullOptions.isNotEmpty) {
locator<PatcherViewModel>().showRequiredOptionDialog();
}
} else {
if (context.mounted) {
return showSelectFromStorageDialog(context);
}
}
}
}

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 {
return showDialog(
context: context,
Expand Down Expand Up @@ -145,12 +205,10 @@ class AppSelectorViewModel extends BaseViewModel {
),
const SizedBox(height: 30),
CustomMaterialButton(
onPressed: () => selectAppFromStorage(context).then(
(_) {
Navigator.pop(context);
Navigator.pop(context);
},
),
onPressed: () async {
Navigator.pop(context);
await selectAppFromStorage(context);
},
label: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expand Down Expand Up @@ -203,17 +261,8 @@ class AppSelectorViewModel extends BaseViewModel {
apkFile.path,
true,
) as ApplicationWithIcon?;
if (application != null) {
locator<PatcherViewModel>().selectedApp = PatchedApplication(
name: application.appName,
packageName: application.packageName,
version: application.versionName!,
apkFilePath: result,
icon: application.icon,
patchDate: DateTime.now(),
isFromStorage: true,
);
locator<PatcherViewModel>().loadLastSelectedPatches();
if (application != null && context.mounted) {
await selectApp(context, application, true);
}
}
} on Exception catch (e) {
Expand Down
48 changes: 48 additions & 0 deletions lib/ui/views/settings/settings_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,54 @@ class SettingsViewModel extends BaseViewModel {
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;
}
}
}

void deleteKeystore() {
_managerAPI.deleteKeystore();
_toast.showBottom('settingsView.regeneratedKeystore');
Expand Down
2 changes: 2 additions & 0 deletions lib/ui/widgets/settingsView/settings_advanced_section.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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/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_require_suggested_app_version.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_version_compatibility_check.dart';
Expand All @@ -20,6 +21,7 @@ class SAdvancedSection extends StatelessWidget {
children: const <Widget>[
SAutoUpdatePatches(),
SEnablePatchesSelection(),
SRequireSuggestedAppVersion(),
SVersionCompatibilityCheck(),
SUniversalPatches(),
SManageSourcesUI(),
Expand Down
Original file line number Diff line number Diff line change
@@ -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(() {});
},
);
}
}