mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2024-11-10 01:01:56 +01:00
feat(patches-selector): show New
tag for new patches (#1099)
This commit is contained in:
parent
131df28110
commit
1714c3fa86
6 changed files with 108 additions and 17 deletions
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue