From acc6a780fa14a432ccb31d41dda76cc0ee2e5a0d Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 13 Sep 2023 21:01:39 -0400 Subject: [PATCH 1/5] Fix export encoding (#887) --- lib/providers/apps_provider.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 9dff5ff..e7b79ce 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -1132,7 +1132,8 @@ class AppsProvider with ChangeNotifier { displayName: '${tr('obtainiumExportHyphenatedLowercase')}-${DateTime.now().toIso8601String().replaceAll(':', '-')}${isAuto ? '-auto' : ''}.json', mimeType: 'application/json', - content: jsonEncode(apps.values.map((e) => e.app.toJson()).toList())); + bytes: Uint8List.fromList(utf8.encode( + jsonEncode(apps.values.map((e) => e.app.toJson()).toList())))); if (result == null) { throw ObtainiumError(tr('unexpectedError')); } From 7d9571cfddf189a7bd10aa12ba66631332237f25 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 13 Sep 2023 21:24:25 -0400 Subject: [PATCH 2/5] Fix repeating background install for some apps (#886) --- lib/providers/apps_provider.dart | 35 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index e7b79ce..a9b5edd 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -430,7 +430,8 @@ class AppsProvider with ChangeNotifier { zipFile: File(filePath), destinationDir: Directory(destinationPath)); } - Future installXApkDir(DownloadedXApkDir dir) async { + Future installXApkDir( + DownloadedXApkDir dir, BuildContext? context) async { // We don't know which APKs in an XAPK are supported by the user's device // So we try installing all of them and assume success if at least one installed // If 0 APKs installed, throw the first install error encountered @@ -443,7 +444,7 @@ class AppsProvider with ChangeNotifier { if (file.path.toLowerCase().endsWith('.apk')) { try { somethingInstalled = somethingInstalled || - await installApk(DownloadedApk(dir.appId, file)); + await installApk(DownloadedApk(dir.appId, file), context); } catch (e) { logs.add( 'Could not install APK from XAPK \'${file.path}\': ${e.toString()}'); @@ -463,7 +464,7 @@ class AppsProvider with ChangeNotifier { } } - Future installApk(DownloadedApk file) async { + Future installApk(DownloadedApk file, BuildContext? context) async { var newInfo = await pm.getPackageArchiveInfo(archiveFilePath: file.file.path); PackageInfo? appInfo = await getInstalledInfo(apps[file.appId]!.app.id); @@ -472,8 +473,16 @@ class AppsProvider with ChangeNotifier { !(await canDowngradeApps())) { throw DowngradeError(); } - int? code = - await AndroidPackageInstaller.installApk(apkFilePath: file.file.path); + int? code; + if (context == null) { + // In background installs, 'installApk' never returns so don't wait for it + // TODO: Find a fix to make this work synchronously without context + AndroidPackageInstaller.installApk(apkFilePath: file.file.path); + code = 0; // Be optimistic (ver. det. will get most wrong ones anyways) + } else { + code = + await AndroidPackageInstaller.installApk(apkFilePath: file.file.path); + } bool installed = false; if (code != null && code != 0 && code != 3) { throw InstallError(code); @@ -640,19 +649,11 @@ class AppsProvider with ChangeNotifier { notifyListeners(); try { if (downloadedFile != null) { - if (willBeSilent && context == null) { - // Would await forever - workaround - TODO - installApk(downloadedFile); - } else { - await installApk(downloadedFile); - } + // ignore: use_build_context_synchronously + await installApk(downloadedFile, context); } else { - if (willBeSilent && context == null) { - // Would await forever - workaround - TODO - installXApkDir(downloadedDir!); - } else { - await installXApkDir(downloadedDir!); - } + // ignore: use_build_context_synchronously + await installXApkDir(downloadedDir!, context); } if (willBeSilent && context == null) { notificationsProvider?.notify(SilentUpdateAttemptNotification( From 2d5a9bec84c139405bac07747912b29c6dbef647 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 13 Sep 2023 21:27:18 -0400 Subject: [PATCH 3/5] Increment version, update packages --- lib/main.dart | 2 +- pubspec.lock | 16 ++++++++-------- pubspec.yaml | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 0b2338d..14276a1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -19,7 +19,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart'; // ignore: implementation_imports import 'package:easy_localization/src/localization.dart'; -const String currentVersion = '0.14.13'; +const String currentVersion = '0.14.14'; const String currentReleaseTag = 'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES diff --git a/pubspec.lock b/pubspec.lock index cdacfb5..ef2647c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -46,10 +46,10 @@ packages: dependency: transitive description: name: archive - sha256: "49b1fad315e57ab0bbc15bcbb874e83116a1d78f77ebd500a4af6c9407d6b28e" + sha256: e0902a06f0e00414e4e3438a084580161279f137aeb862274710f29ec10cf01e url: "https://pub.dev" source: hosted - version: "3.3.8" + version: "3.3.9" args: dependency: transitive description: @@ -320,10 +320,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: d4a1cb250c4e059586af0235f32e02882860a508e189b61f2b31b8810c1e1330 + sha256: a10979814c5f4ddbe2b6143fba25d927599e21e3ba65b3862995960606fae78f url: "https://pub.dev" source: hosted - version: "0.6.17+2" + version: "0.6.17+3" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -538,18 +538,18 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: bc56bfe9d3f44c3c612d8d393bd9b174eb796d706759f9b495ac254e4294baa5 + sha256: ad65ba9af42a3d067203641de3fd9f547ded1410bad3b84400c2b4899faede70 url: "https://pub.dev" source: hosted - version: "10.4.5" + version: "11.0.0" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: "59c6322171c29df93a22d150ad95f3aa19ed86542eaec409ab2691b8f35f9a47" + sha256: f23cfe9af0d49c6b9fd8a8b09f7b3301ca7e346204939b5afef4404d36d2608f url: "https://pub.dev" source: hosted - version: "10.3.6" + version: "11.0.1" permission_handler_apple: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 09d66b8..db5c5ca 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 0.14.13+205 # When changing this, update the tag in main() accordingly +version: 0.14.14+206 # When changing this, update the tag in main() accordingly environment: sdk: '>=3.0.0 <4.0.0' @@ -46,7 +46,7 @@ dependencies: html: ^0.15.0 shared_preferences: ^2.0.15 url_launcher: ^6.1.5 - permission_handler: ^10.0.0 + permission_handler: ^11.0.0 fluttertoast: ^8.0.9 device_info_plus: ^9.0.0 file_picker: ^5.2.10 From a2e494b2bae8d2e96c3902ef7b866529162e66d7 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 13 Sep 2023 22:15:10 -0400 Subject: [PATCH 4/5] More version filtering options for F-Droid (#885) --- assets/translations/br.json | 2 + assets/translations/bs.json | 2 + assets/translations/de.json | 2 + assets/translations/en.json | 2 + assets/translations/es.json | 2 + assets/translations/fa.json | 2 + assets/translations/fr.json | 2 + assets/translations/hu.json | 2 + assets/translations/it.json | 2 + assets/translations/ja.json | 2 + assets/translations/pl.json | 2 + assets/translations/ru.json | 2 + assets/translations/zh.json | 2 + lib/app_sources/fdroid.dart | 94 ++++++++++++++++++++++++++++---- lib/app_sources/izzyondroid.dart | 5 +- 15 files changed, 112 insertions(+), 13 deletions(-) diff --git a/assets/translations/br.json b/assets/translations/br.json index 96e9e7d..a083e20 100644 --- a/assets/translations/br.json +++ b/assets/translations/br.json @@ -256,6 +256,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "Remover App?", "other": "Remover Apps?" diff --git a/assets/translations/bs.json b/assets/translations/bs.json index 01d0d2b..7352027 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -253,6 +253,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" diff --git a/assets/translations/de.json b/assets/translations/de.json index f6f9d0e..5ab4801 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -253,6 +253,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index 4395c68..6e782f9 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -256,6 +256,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/es.json b/assets/translations/es.json index b662041..aefea28 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -253,6 +253,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index c3f5274..9c62c43 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -253,6 +253,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 8576909..33e9fb6 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -253,6 +253,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index 845e313..164cd9a 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -252,6 +252,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "Eltávolítja az alkalmazást?", "other": "Eltávolítja az alkalmazást?" diff --git a/assets/translations/it.json b/assets/translations/it.json index 7fec3c8..b805fc5 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -253,6 +253,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index 541da17..9093e15 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -254,6 +254,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/pl.json b/assets/translations/pl.json index 04f8322..205d716 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -259,6 +259,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "Usunąć aplikację?", "few": "Usunąć aplikacje?", diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 690cd53..9db80ce 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -253,6 +253,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 66fc426..1057515 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -254,6 +254,8 @@ "highlightTouchTargets": "Highlight less obvious touch targets", "pickExportDir": "Pick Export Directory", "autoExportOnChanges": "Auto-export on changes", + "filterVersionsByRegEx": "Filter Versions by Regular Expression", + "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" diff --git a/lib/app_sources/fdroid.dart b/lib/app_sources/fdroid.dart index ffee596..f2dd3f9 100644 --- a/lib/app_sources/fdroid.dart +++ b/lib/app_sources/fdroid.dart @@ -13,10 +13,24 @@ class FDroid extends AppSource { name = tr('fdroid'); canSearch = true; additionalSourceAppSpecificSettingFormItems = [ + [ + GeneratedFormTextField('filterVersionsByRegEx', + label: tr('filterVersionsByRegEx'), + required: false, + additionalValidators: [ + (value) { + return regExValidator(value); + } + ]) + ], + [ + GeneratedFormSwitch('trySelectingSuggestedVersionCode', + label: tr('trySelectingSuggestedVersionCode'), defaultValue: true) + ], [ GeneratedFormSwitch('autoSelectHighestVersionCode', label: tr('autoSelectHighestVersionCode')) - ] + ], ]; } @@ -45,25 +59,73 @@ class FDroid extends AppSource { APKDetails getAPKUrlsFromFDroidPackagesAPIResponse( Response res, String apkUrlPrefix, String standardUrl, - {bool autoSelectHighestVersionCode = false}) { + {bool autoSelectHighestVersionCode = false, + bool trySelectingSuggestedVersionCode = false, + String? filterVersionsByRegEx}) { if (res.statusCode == 200) { - List releases = jsonDecode(res.body)['packages'] ?? []; + var response = jsonDecode(res.body); + List releases = response['packages'] ?? []; if (releases.isEmpty) { throw NoReleasesError(); } - String? latestVersion = releases[0]['versionName']; - if (latestVersion == null) { + String? version; + Iterable releaseChoices = []; + // Grab the versionCode suggested if the user chose to do that + // Only do so at this stage if the user has no release filter + if (trySelectingSuggestedVersionCode && + response['suggestedVersionCode'] != null && + filterVersionsByRegEx == null) { + var suggestedReleases = releases.where((element) => + element['versionCode'] == response['suggestedVersionCode']); + if (suggestedReleases.isNotEmpty) { + releaseChoices = suggestedReleases; + version = suggestedReleases.first['versionName']; + } + } + // Apply the release filter if any + if (filterVersionsByRegEx != null) { + version = null; + releaseChoices = []; + for (var i = 0; i < releases.length; i++) { + if (RegExp(filterVersionsByRegEx) + .hasMatch(releases[i]['versionName'])) { + version = releases[i]['versionName']; + } + } + if (version == null) { + throw NoVersionError(); + } + } + // Default to the highest version + version ??= releases[0]['versionName']; + if (version == null) { throw NoVersionError(); } - Iterable latestReleases = - releases.where((element) => element['versionName'] == latestVersion); - if (latestReleases.length > 1 && autoSelectHighestVersionCode) { - latestReleases = [latestReleases.first]; + // If a suggested release was not already picked, pick all those with the selected version + if (releaseChoices.isEmpty) { + releaseChoices = + releases.where((element) => element['versionName'] == version); } - List apkUrls = latestReleases + // For the remaining releases, use the toggles to auto-select one if possible + if (releaseChoices.length > 1) { + if (autoSelectHighestVersionCode) { + releaseChoices = [releaseChoices.first]; + } else if (trySelectingSuggestedVersionCode && + response['suggestedVersionCode'] != null) { + var suggestedReleases = releaseChoices.where((element) => + element['versionCode'] == response['suggestedVersionCode']); + if (suggestedReleases.isNotEmpty) { + releaseChoices = suggestedReleases; + } + } + } + if (releaseChoices.isEmpty) { + throw NoReleasesError(); + } + List apkUrls = releaseChoices .map((e) => '${apkUrlPrefix}_${e['versionCode']}.apk') .toList(); - return APKDetails(latestVersion, getApkUrlsFromUrls(apkUrls), + return APKDetails(version, getApkUrlsFromUrls(apkUrls), AppNames(name, Uri.parse(standardUrl).pathSegments.last)); } else { throw getObtainiumHttpError(res); @@ -82,7 +144,15 @@ class FDroid extends AppSource { 'https://$host/repo/$appId', standardUrl, autoSelectHighestVersionCode: - additionalSettings['autoSelectHighestVersionCode'] == true); + additionalSettings['autoSelectHighestVersionCode'] == true, + trySelectingSuggestedVersionCode: + additionalSettings['trySelectingSuggestedVersionCode'] == true, + filterVersionsByRegEx: + (additionalSettings['filterVersionsByRegEx'] as String?) + ?.isNotEmpty == + true + ? additionalSettings['filterVersionsByRegEx'] + : null); } @override diff --git a/lib/app_sources/izzyondroid.dart b/lib/app_sources/izzyondroid.dart index f145bb8..8f801db 100644 --- a/lib/app_sources/izzyondroid.dart +++ b/lib/app_sources/izzyondroid.dart @@ -40,6 +40,9 @@ class IzzyOnDroid extends AppSource { 'https://android.izzysoft.de/frepo/$appId', standardUrl, autoSelectHighestVersionCode: - additionalSettings['autoSelectHighestVersionCode'] == true); + additionalSettings['autoSelectHighestVersionCode'] == true, + trySelectingSuggestedVersionCode: + additionalSettings['trySelectingSuggestedVersionCode'] == true, + filterVersionsByRegEx: additionalSettings['filterVersionsByRegEx']); } } From 4c0c4b70104b2226198127712797aa2b7a99974e Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 13 Sep 2023 22:19:09 -0400 Subject: [PATCH 5/5] Trim user URL input --- lib/pages/add_app.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/add_app.dart b/lib/pages/add_app.dart index ee8099e..c792a2a 100644 --- a/lib/pages/add_app.dart +++ b/lib/pages/add_app.dart @@ -148,7 +148,7 @@ class _AddAppPageState extends State { userPickedTrackOnly))) { var trackOnly = pickedSource!.enforceTrackOnly || userPickedTrackOnly; app = await sourceProvider.getApp( - pickedSource!, userInput, additionalSettings, + pickedSource!, userInput.trim(), additionalSettings, trackOnlyOverride: trackOnly, overrideSource: pickedSourceOverride, inferAppIdIfOptional: inferAppIdIfOptional);