feat(patches-selector): show New tag for new patches (#1099)

This commit is contained in:
aAbed 2023-08-07 21:13:09 +05:45 committed by GitHub
parent 131df28110
commit 1714c3fa86
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 17 deletions

View file

@ -10,6 +10,7 @@
"yesButton": "Yes", "yesButton": "Yes",
"noButton": "No", "noButton": "No",
"warning": "Warning", "warning": "Warning",
"new": "New",
"navigationView": { "navigationView": {
"dashboardTab": "Dashboard", "dashboardTab": "Dashboard",
"patcherTab": "Patcher", "patcherTab": "Patcher",
@ -130,7 +131,10 @@
}, },
"patchItem": { "patchItem": {
"unsupportedDialogText": "Selecting this patch may result in patching errors.\n\nApp version: {packageVersion}\nSupported versions:\n{supportedVersions}", "unsupportedDialogText": "Selecting this patch may result in patching errors.\n\nApp version: {packageVersion}\nSupported versions:\n{supportedVersions}",
"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.",
"newPatch": "New patch"
}, },
"installerView": { "installerView": {
"widgetTitle": "Installer", "widgetTitle": "Installer",

View file

@ -98,6 +98,21 @@ class ManagerAPI {
await _prefs.setBool('patchesAutoUpdate', value); await _prefs.setBool('patchesAutoUpdate', value);
} }
List<Patch> getSavedPatches(String packageName) {
final List<String> patchesJson = _prefs.getStringList('savedPatches-$packageName') ?? [];
final List<Patch> patches = patchesJson.map((String patchJson) {
return Patch.fromJson(jsonDecode(patchJson));
}).toList();
return patches;
}
Future<void> savePatches(List<Patch> patches, String packageName) async {
final List<String> patchesJson = patches.map((Patch patch) {
return jsonEncode(patch.toJson());
}).toList();
await _prefs.setStringList('savedPatches-$packageName', patchesJson);
}
String getIntegrationsRepo() { String getIntegrationsRepo() {
return _prefs.getString('integrationsRepo') ?? defaultIntegrationsRepo; return _prefs.getString('integrationsRepo') ?? defaultIntegrationsRepo;
} }

View file

@ -85,7 +85,7 @@ class InstallerViewModel extends BaseViewModel {
}); });
} }
void update(double value, String header, String log) { Future<void> update(double value, String header, String log) async {
if (value >= 0.0) { if (value >= 0.0) {
progress = value; progress = value;
} }
@ -97,6 +97,10 @@ class InstallerViewModel extends BaseViewModel {
} else if (value == 1.0) { } else if (value == 1.0) {
isPatching = false; isPatching = false;
hasErrors = false; hasErrors = false;
await _managerAPI.savePatches(
_patcherAPI.getFilteredPatches(_app.packageName),
_app.packageName,
);
} else if (value == -100.0) { } else if (value == -100.0) {
isPatching = false; isPatching = false;
hasErrors = true; hasErrors = true;

View file

@ -175,10 +175,14 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
name: patch.name, name: patch.name,
simpleName: patch.getSimpleName(), simpleName: patch.getSimpleName(),
description: patch.description, description: patch.description,
packageVersion: model.getAppVersion(), packageVersion: model.getAppInfo().version,
supportedPackageVersions: supportedPackageVersions:
model.getSupportedVersions(patch), model.getSupportedVersions(patch),
isUnsupported: !isPatchSupported(patch), isUnsupported: !isPatchSupported(patch),
isNew: model.isPatchNew(
patch,
model.getAppInfo().packageName,
),
isSelected: model.isSelected(patch), isSelected: model.isSelected(patch),
onChanged: (value) => onChanged: (value) =>
model.selectPatch(patch, value), model.selectPatch(patch, value),
@ -206,10 +210,12 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
name: patch.name, name: patch.name,
simpleName: patch.getSimpleName(), simpleName: patch.getSimpleName(),
description: patch.description, description: patch.description,
packageVersion: model.getAppVersion(), packageVersion:
model.getAppInfo().version,
supportedPackageVersions: supportedPackageVersions:
model.getSupportedVersions(patch), model.getSupportedVersions(patch),
isUnsupported: !isPatchSupported(patch), isUnsupported: !isPatchSupported(patch),
isNew: false,
isSelected: model.isSelected(patch), isSelected: model.isSelected(patch),
onChanged: (value) => onChanged: (value) =>
model.selectPatch(patch, value), model.selectPatch(patch, value),

View file

@ -15,6 +15,7 @@ class PatchesSelectorViewModel extends BaseViewModel {
final List<Patch> patches = []; final List<Patch> patches = [];
final List<Patch> selectedPatches = final List<Patch> selectedPatches =
locator<PatcherViewModel>().selectedPatches; locator<PatcherViewModel>().selectedPatches;
PatchedApplication? selectedApp = locator<PatcherViewModel>().selectedApp;
String? patchesVersion = ''; String? patchesVersion = '';
bool isDefaultPatchesRepo() { bool isDefaultPatchesRepo() {
return _managerAPI.getPatchesRepo() == 'revanced/revanced-patches'; return _managerAPI.getPatchesRepo() == 'revanced/revanced-patches';
@ -24,10 +25,17 @@ class PatchesSelectorViewModel extends BaseViewModel {
getPatchesVersion().whenComplete(() => notifyListeners()); getPatchesVersion().whenComplete(() => notifyListeners());
patches.addAll( patches.addAll(
_patcherAPI.getFilteredPatches( _patcherAPI.getFilteredPatches(
locator<PatcherViewModel>().selectedApp!.originalPackageName, selectedApp!.originalPackageName,
), ),
); );
patches.sort((a, b) => a.name.compareTo(b.name)); patches.sort((a, b) {
if (isPatchNew(a, selectedApp!.packageName) ==
isPatchNew(b, selectedApp!.packageName)) {
return a.name.compareTo(b.name);
} else {
return isPatchNew(b, selectedApp!.packageName) ? 1 : -1;
}
});
notifyListeners(); notifyListeners();
} }
@ -99,8 +107,18 @@ class PatchesSelectorViewModel extends BaseViewModel {
} }
} }
String getAppVersion() { PatchedApplication getAppInfo() {
return locator<PatcherViewModel>().selectedApp!.version; return locator<PatcherViewModel>().selectedApp!;
}
bool isPatchNew(Patch patch, String packageName) {
final List<Patch> savedPatches = _managerAPI.getSavedPatches(packageName);
if (savedPatches.isEmpty) {
return false;
} else {
return !savedPatches
.any((p) => p.name == patch.name.toLowerCase().replaceAll(' ', '-'));
}
} }
List<String> getSupportedVersions(Patch patch) { List<String> getSupportedVersions(Patch patch) {

View file

@ -16,6 +16,7 @@ class PatchItem extends StatefulWidget {
required this.packageVersion, required this.packageVersion,
required this.supportedPackageVersions, required this.supportedPackageVersions,
required this.isUnsupported, required this.isUnsupported,
required this.isNew,
required this.isSelected, required this.isSelected,
required this.onChanged, required this.onChanged,
this.child, this.child,
@ -26,6 +27,7 @@ class PatchItem extends StatefulWidget {
final String packageVersion; final String packageVersion;
final List<String> supportedPackageVersions; final List<String> supportedPackageVersions;
final bool isUnsupported; final bool isUnsupported;
final bool isNew;
bool isSelected; bool isSelected;
final Function(bool) onChanged; final Function(bool) onChanged;
final Widget? child; final Widget? child;
@ -132,12 +134,12 @@ class _PatchItemState extends State<PatchItem> {
), ),
], ],
), ),
if (widget.isUnsupported && Row(
widget._managerAPI.areExperimentalPatchesEnabled()) children: [
Row( if (widget.isUnsupported &&
children: <Widget>[ widget._managerAPI.areExperimentalPatchesEnabled())
Padding( Padding(
padding: const EdgeInsets.only(top: 8), padding: const EdgeInsets.only(top: 8, right: 8),
child: TextButton.icon( child: TextButton.icon(
label: I18nText('warning'), label: I18nText('warning'),
icon: const Icon(Icons.warning, size: 20.0), icon: const Icon(Icons.warning, size: 20.0),
@ -160,10 +162,33 @@ class _PatchItemState extends State<PatchItem> {
), ),
), ),
), ),
], if (widget.isNew)
) Padding(
else padding: const EdgeInsets.only(top: 8),
Container(), child: TextButton.icon(
label: I18nText('new'),
icon: const Icon(Icons.star, size: 20.0),
onPressed: () => _showNewPatchDialog(),
style: ButtonStyle(
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: Theme.of(context).colorScheme.secondary,
),
),
),
backgroundColor: MaterialStateProperty.all(
Colors.transparent,
),
foregroundColor: MaterialStateProperty.all(
Theme.of(context).colorScheme.secondary,
),
),
),
)
],
),
widget.child ?? const SizedBox(), widget.child ?? const SizedBox(),
], ],
), ),
@ -195,4 +220,23 @@ class _PatchItemState extends State<PatchItem> {
), ),
); );
} }
Future<void> _showNewPatchDialog() {
return showDialog(
context: context,
builder: (context) => AlertDialog(
title: I18nText('patchItem.newPatch'),
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
content: I18nText(
'patchItem.newPatchDialogText',
),
actions: <Widget>[
CustomMaterialButton(
label: I18nText('okButton'),
onPressed: () => Navigator.of(context).pop(),
),
],
),
);
}
} }