diff --git a/assets/i18n/en.json b/assets/i18n/en.json index 67e32016..275a7ac8 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -50,7 +50,10 @@ "widgetTitle": "Select application", "widgetTitleSelected": "Selected application", "widgetSubtitle": "No application selected.", - "noAppsLabel": "No applications found." + "noAppsLabel": "No applications found.", + "currentVersion": "Current", + "recommendedVersion": "Recommended", + "anyVersion": "any" }, "patchSelectorCard": { "widgetTitle": "Select patches", diff --git a/lib/services/patcher_api.dart b/lib/services/patcher_api.dart index 970a7e2d..6c872820 100644 --- a/lib/services/patcher_api.dart +++ b/lib/services/patcher_api.dart @@ -220,4 +220,32 @@ class PatcherAPI { log.writeAsStringSync(logs); ShareExtend.share(log.path, 'file'); } + + String getRecommendedVersion(String packageName) { + Map versions = {}; + for (Patch patch in _patches) { + Package? package = patch.compatiblePackages.firstWhereOrNull( + (pack) => pack.name == packageName, + ); + if (package != null) { + for (String version in package.versions) { + versions.update( + version, + (value) => versions[version]! + 1, + ifAbsent: () => 1, + ); + } + } + } + if (versions.isNotEmpty) { + var entries = versions.entries.toList() + ..sort((a, b) => a.value.compareTo(b.value)); + versions + ..clear() + ..addEntries(entries); + versions.removeWhere((key, value) => value != versions.values.last); + return (versions.keys.toList()..sort()).last; + } + return ''; + } } diff --git a/lib/ui/views/patcher/patcher_viewmodel.dart b/lib/ui/views/patcher/patcher_viewmodel.dart index a6ca8ced..63f78ef8 100644 --- a/lib/ui/views/patcher/patcher_viewmodel.dart +++ b/lib/ui/views/patcher/patcher_viewmodel.dart @@ -79,4 +79,32 @@ class PatcherViewModel extends BaseViewModel { ); } } + + String getAppSelectionString() { + String text = '${selectedApp!.name} (${selectedApp!.packageName})'; + if (text.length > 32) { + text = '${text.substring(0, 32)}...)'; + } + return text; + } + + String getRecommendedVersionString(BuildContext context) { + String recommendedVersion = + _patcherAPI.getRecommendedVersion(selectedApp!.packageName); + if (recommendedVersion.isEmpty) { + recommendedVersion = FlutterI18n.translate( + context, + 'appSelectorCard.anyVersion', + ); + } else { + recommendedVersion = 'v$recommendedVersion'; + } + return '${FlutterI18n.translate( + context, + 'appSelectorCard.currentVersion', + )}: v${selectedApp!.version}\n${FlutterI18n.translate( + context, + 'appSelectorCard.recommendedVersion', + )}: $recommendedVersion'; + } } diff --git a/lib/ui/widgets/patcherView/app_selector_card.dart b/lib/ui/widgets/patcherView/app_selector_card.dart index 9630719e..318d6530 100644 --- a/lib/ui/widgets/patcherView/app_selector_card.dart +++ b/lib/ui/widgets/patcherView/app_selector_card.dart @@ -39,7 +39,7 @@ class AppSelectorCard extends StatelessWidget { : Row( children: [ SizedBox( - height: 16.0, + height: 18.0, child: ClipOval( child: Image.memory( locator().selectedApp == null @@ -49,8 +49,23 @@ class AppSelectorCard extends StatelessWidget { ), ), ), - const SizedBox(width: 4), - Text(_getAppSelection()), + const SizedBox(width: 6), + Text(locator().getAppSelectionString()), + ], + ), + locator().selectedApp == null + ? Container() + : Column( + children: [ + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 20), + child: Text( + locator() + .getRecommendedVersionString(context), + style: const TextStyle(fontStyle: FontStyle.italic), + ), + ), ], ), ], @@ -58,10 +73,4 @@ class AppSelectorCard extends StatelessWidget { ), ); } - - String _getAppSelection() { - String name = locator().selectedApp!.name; - String version = locator().selectedApp!.version; - return '$name (v$version)'; - } }