diff --git a/assets/translations/bs.json b/assets/translations/bs.json index dd9c8be..54fa76b 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -244,6 +244,8 @@ "addInfoInSettings": "Add this info in the Settings.", "githubSourceNote": "GitHub rate limiting can be avoided using an API key.", "gitlabSourceNote": "GitLab APK extraction may not work without an API key.", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" diff --git a/assets/translations/de.json b/assets/translations/de.json index 95028a6..fe26fab 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -244,6 +244,8 @@ "addInfoInSettings": "Fügen Sie diese Info in den Einstellungen hinzu.", "githubSourceNote": "Die GitHub-Ratenbegrenzung kann mit einem API-Schlüssel umgangen werden.", "gitlabSourceNote": "GitLab APK-Extraktion funktioniert möglicherweise nicht ohne API-Schlüssel", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index e86bf32..2daf50e 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -244,6 +244,8 @@ "addInfoInSettings": "Add this info in the Settings.", "githubSourceNote": "GitHub rate limiting can be avoided using an API key.", "gitlabSourceNote": "GitLab APK extraction may not work without an API key.", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/es.json b/assets/translations/es.json index 2708bce..76bddc6 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -244,6 +244,8 @@ "addInfoInSettings": "Add this info in the Settings.", "githubSourceNote": "GitHub rate limiting can be avoided using an API key.", "gitlabSourceNote": "GitLab APK extraction may not work without an API key.", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index 781b45b..342d98d 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -244,6 +244,8 @@ "addInfoInSettings": "Add this info in the Settings.", "githubSourceNote": "GitHub rate limiting can be avoided using an API key.", "gitlabSourceNote": "GitLab APK extraction may not work without an API key.", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 1619faf..32d1e35 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -45,7 +45,7 @@ "addApp": "Ajouter une application", "appSourceURL": "URL de la source de l'application", "error": "Erreur", - "add": "Ajoutée", + "add": "Ajouter", "searchSomeSourcesLabel": "Rechercher (certaines sources uniquement)", "search": "Rechercher", "additionalOptsFor": "Options supplémentaires pour {}", @@ -244,6 +244,8 @@ "addInfoInSettings": "Add this info in the Settings.", "githubSourceNote": "GitHub rate limiting can be avoided using an API key.", "gitlabSourceNote": "GitLab APK extraction may not work without an API key.", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index 6beafe7..ab5be1f 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -243,6 +243,8 @@ "addInfoInSettings": "Adja hozzá ezt az infót a Beállításokban.", "githubSourceNote": "A GitHub értékelési korlátozása elkerülhető API-kulcs használatával.", "gitlabSourceNote": "Előfordulhat, hogy a GitLab APK kibontása nem működik API-kulcs nélkül.", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "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 e905551..be3e441 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -244,6 +244,8 @@ "addInfoInSettings": "Add this info in the Settings.", "githubSourceNote": "GitHub rate limiting can be avoided using an API key.", "gitlabSourceNote": "GitLab APK extraction may not work without an API key.", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index aaf4530..a89fc20 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -244,6 +244,8 @@ "addInfoInSettings": "設定でこの情報を追加してください。", "githubSourceNote": "GitHubのレート制限はAPIキーを使うことで回避できます。", "gitlabSourceNote": "GitLabのAPK抽出はAPIキーがないと動作しない場合があります。", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/pl.json b/assets/translations/pl.json index e957c9b..be2f699 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -248,6 +248,8 @@ "addInfoInSettings": "Dodaj tę informację w Ustawieniach.", "githubSourceNote": "Limit żądań GitHub można ominąć za pomocą klucza API.", "gitlabSourceNote": "Pozyskiwanie pliku APK z GitLab może nie działać bez klucza API.", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "Usunąć aplikację?", "other": "Usunąć aplikacje?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 14b5f06..94a6ebf 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -244,6 +244,8 @@ "addInfoInSettings": "Добавьте эту информацию в Настройки.", "githubSourceNote": "Лимит запросов GitHub можно обойти, используя ключ API.", "gitlabSourceNote": "Извлечение APK из GitLab может не работать без ключа API.", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 6a3058e..e59296d 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -244,6 +244,8 @@ "addInfoInSettings": "在“设置”中添加此凭据。", "githubSourceNote": "使用访问令牌可避免触发 GitHub 的 API 请求限制。", "gitlabSourceNote": "未使用访问令牌时可能无法从 GitLab 获取 APK 文件。", + "sortByFileNamesNotLinks": "Sort by file names instead of full links", + "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" diff --git a/lib/app_sources/codeberg.dart b/lib/app_sources/codeberg.dart index 8e9ef04..df06b9f 100644 --- a/lib/app_sources/codeberg.dart +++ b/lib/app_sources/codeberg.dart @@ -1,6 +1,4 @@ -import 'package:easy_localization/easy_localization.dart'; import 'package:obtainium/app_sources/github.dart'; -import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/providers/source_provider.dart'; @@ -9,26 +7,8 @@ class Codeberg extends AppSource { Codeberg() { host = 'codeberg.org'; - additionalSourceAppSpecificSettingFormItems = [ - [ - GeneratedFormSwitch('includePrereleases', - label: tr('includePrereleases'), defaultValue: false) - ], - [ - GeneratedFormSwitch('fallbackToOlderReleases', - label: tr('fallbackToOlderReleases'), defaultValue: true) - ], - [ - GeneratedFormTextField('filterReleaseTitlesByRegEx', - label: tr('filterReleaseTitlesByRegEx'), - required: false, - additionalValidators: [ - (value) { - return regExValidator(value); - } - ]) - ] - ]; + additionalSourceAppSpecificSettingFormItems = + gh.additionalSourceAppSpecificSettingFormItems; canSearch = true; searchQuerySettingFormItems = gh.searchQuerySettingFormItems; diff --git a/lib/app_sources/github.dart b/lib/app_sources/github.dart index b6a5e2d..608c31c 100644 --- a/lib/app_sources/github.dart +++ b/lib/app_sources/github.dart @@ -75,6 +75,16 @@ class GitHub extends AppSource { return regExValidator(value); } ]) + ], + [ + GeneratedFormTextField('filterReleaseNotesByRegEx', + label: tr('filterReleaseNotesByRegEx'), + required: false, + additionalValidators: [ + (value) { + return regExValidator(value); + } + ]) ] ]; @@ -196,6 +206,12 @@ class GitHub extends AppSource { true ? additionalSettings['filterReleaseTitlesByRegEx'] : null; + String? regexNotesFilter = + (additionalSettings['filterReleaseNotesByRegEx'] as String?) + ?.isNotEmpty == + true + ? additionalSettings['filterReleaseNotesByRegEx'] + : null; Response res = await sourceRequest(requestUrl); if (res.statusCode == 200) { var releases = jsonDecode(res.body) as List; @@ -264,6 +280,11 @@ class GitHub extends AppSource { !RegExp(regexFilter).hasMatch(nameToFilter.trim())) { continue; } + if (regexNotesFilter != null && + !RegExp(regexNotesFilter) + .hasMatch(((releases[i]['body'] as String?) ?? '').trim())) { + continue; + } var apkUrls = getReleaseAPKUrls(releases[i]); if (apkUrls.isEmpty && additionalSettings['trackOnly'] != true) { continue; diff --git a/lib/app_sources/html.dart b/lib/app_sources/html.dart index 47d6acd..a60386e 100644 --- a/lib/app_sources/html.dart +++ b/lib/app_sources/html.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:html/parser.dart'; import 'package:http/http.dart'; +import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/providers/source_provider.dart'; @@ -85,6 +86,15 @@ bool _isNumeric(String s) { } class HTML extends AppSource { + HTML() { + additionalSourceAppSpecificSettingFormItems = [ + [ + GeneratedFormSwitch('sortByFileNamesNotLinks', + label: tr('sortByFileNamesNotLinks')) + ] + ]; + } + @override // TODO: implement requestHeaders choice, hardcoded for now Map? get requestHeaders => { @@ -111,7 +121,9 @@ class HTML extends AppSource { .where((element) => Uri.parse(element).path.toLowerCase().endsWith('.apk')) .toList(); - links.sort((a, b) => compareAlphaNumeric(a, b)); + links.sort((a, b) => additionalSettings['sortByFileNamesNotLinks'] == true + ? compareAlphaNumeric(a.split('/').last, b.split('/').last) + : compareAlphaNumeric(a, b)); if (additionalSettings['apkFilterRegEx'] != null) { var reg = RegExp(additionalSettings['apkFilterRegEx']); links = links.where((element) => reg.hasMatch(element)).toList(); diff --git a/lib/app_sources/vlc.dart b/lib/app_sources/vlc.dart index c531f26..bbdec76 100644 --- a/lib/app_sources/vlc.dart +++ b/lib/app_sources/vlc.dart @@ -38,16 +38,14 @@ class VLC extends AppSource { } String? targetUrl = 'https://$dwUrlBase/$version/'; Response res2 = await sourceRequest(targetUrl); - String mirrorDwBase = - 'https://plug-mirror.rcac.purdue.edu/vlc/vlc-android/$version/'; List apkUrls = []; if (res2.statusCode == 200) { apkUrls = parse(res2.body) .querySelectorAll('a') - .map((e) => e.attributes['href']) + .map((e) => e.attributes['href']?.split('/').last) .where((h) => h != null && h.isNotEmpty && h.toLowerCase().endsWith('.apk')) - .map((e) => mirrorDwBase + e!) + .map((e) => targetUrl + e!) .toList(); } else { throw getObtainiumHttpError(res2); @@ -59,4 +57,20 @@ class VLC extends AppSource { throw getObtainiumHttpError(res); } } + + @override + Future apkUrlPrefetchModifier( + String apkUrl, String standardUrl) async { + Response res = await sourceRequest(apkUrl); + if (res.statusCode == 200) { + String? apkUrl = + parse(res.body).querySelector('#alt_link')?.attributes['href']; + if (apkUrl == null) { + throw NoAPKError(); + } + return apkUrl; + } else { + throw getObtainiumHttpError(res); + } + } } diff --git a/lib/components/generated_form_modal.dart b/lib/components/generated_form_modal.dart index f44acc4..838b187 100644 --- a/lib/components/generated_form_modal.dart +++ b/lib/components/generated_form_modal.dart @@ -11,7 +11,8 @@ class GeneratedFormModal extends StatefulWidget { this.initValid = false, this.message = '', this.additionalWidgets = const [], - this.singleNullReturnButton}); + this.singleNullReturnButton, + this.primaryActionColour}); final String title; final String message; @@ -19,6 +20,7 @@ class GeneratedFormModal extends StatefulWidget { final bool initValid; final List additionalWidgets; final String? singleNullReturnButton; + final Color? primaryActionColour; @override State createState() => _GeneratedFormModalState(); @@ -71,6 +73,10 @@ class _GeneratedFormModalState extends State { : widget.singleNullReturnButton!)), widget.singleNullReturnButton == null ? TextButton( + style: widget.primaryActionColour == null + ? null + : TextButton.styleFrom( + foregroundColor: widget.primaryActionColour), onPressed: !valid ? null : () { diff --git a/lib/main.dart b/lib/main.dart index d330268..7861e1b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,7 +22,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart'; // ignore: implementation_imports import 'package:easy_localization/src/localization.dart'; -const String currentVersion = '0.13.22'; +const String currentVersion = '0.13.23'; const String currentReleaseTag = 'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index c96c72d..2ea391e 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -403,10 +403,13 @@ class _SettingsPageState extends State { Switch( value: settingsProvider.reversePageTransitions, - onChanged: (value) { - settingsProvider.reversePageTransitions = - value; - }) + onChanged: settingsProvider + .disablePageTransitions + ? null + : (value) { + settingsProvider + .reversePageTransitions = value; + }) ], ), height32, diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 9c8d7db..ec9c104 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -892,6 +892,7 @@ class AppsProvider with ChangeNotifier { context: context, builder: (BuildContext ctx) { return GeneratedFormModal( + primaryActionColour: Theme.of(context).colorScheme.error, title: plural('removeAppQuestion', apps.length), items: !showUninstallOption ? [] diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index ca2c969..da88640 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -431,14 +431,14 @@ abstract class AppSource { Map additionalSettings, SettingsProvider settingsProvider) async { Map results = {}; - sourceConfigSettingFormItems.forEach((e) { + for (var e in sourceConfigSettingFormItems) { var val = hostChanged ? additionalSettings[e.key] : settingsProvider.getSettingString(e.key); if (val != null) { results[e.key] = val; } - }); + } return results; } diff --git a/pubspec.lock b/pubspec.lock index c4ff360..f1e82a6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: "direct main" description: name: android_alarm_manager_plus - sha256: "80f963d47cb7ab0818144c7b0668aea4c038f9cb8626626e89a4ea77375defb7" + sha256: c20d91a9096596f66274bf8172321c278f9cba8091638f80205fe66d31587fa5 url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" android_intent_plus: dependency: "direct main" description: name: android_intent_plus - sha256: "2c87d8330ba5deef5fe20e77f4d178190b3b24531dce08368030ab4be40a9d4e" + sha256: f72ae20bb37108694f442e7ae6acbd28b453ca62ce86842f6787b784355abfe6 url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "4.0.2" android_package_installer: dependency: "direct main" description: @@ -158,10 +158,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "2c35b6d1682b028e42d07b3aee4b98fa62996c10bc12cb651ec856a80d6a761b" + sha256: "86add5ef97215562d2e090535b0a16f197902b10c369c558a100e74ea06e8659" url: "https://pub.dev" source: hosted - version: "9.0.2" + version: "9.0.3" device_info_plus_platform_interface: dependency: transitive description: @@ -490,42 +490,42 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" + sha256: "5d44fc3314d969b84816b569070d7ace0f1dea04bd94a83f74c4829615d22ad8" url: "https://pub.dev" source: hosted - version: "2.0.27" + version: "2.1.0" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297" + sha256: "1b744d3d774e5a879bb76d6cd1ecee2ba2c6960c03b1020cd35212f6aa267ac5" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.3.0" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 + sha256: ba2b77f0c52a33db09fc8caf85b12df691bf28d983e84cf87ff6d693cfa007b3 url: "https://pub.dev" source: hosted - version: "2.1.11" + version: "2.2.0" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + sha256: bced5679c7df11190e1ddc35f3222c858f328fff85c3942e46e7f5589bf9eb84 url: "https://pub.dev" source: hosted - version: "2.0.6" + version: "2.1.0" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96" + sha256: ee0e0d164516b90ae1f970bdf29f726f1aa730d7cfc449ecc74c495378b705da url: "https://pub.dev" source: hosted - version: "2.1.7" + version: "2.2.0" permission_handler: dependency: "direct main" description: @@ -610,18 +610,18 @@ packages: dependency: "direct main" description: name: share_plus - sha256: ed3fcea4f789ed95913328e629c0c53e69e80e08b6c24542f1b3576046c614e8 + sha256: "6cec740fa0943a826951223e76218df002804adb588235a8910dc3d6b0654e11" url: "https://pub.dev" source: hosted - version: "7.0.2" + version: "7.1.0" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - sha256: "0c6e61471bd71b04a138b8b588fa388e66d8b005e6f2deda63371c5c505a0981" + sha256: "357412af4178d8e11d14f41723f80f12caea54cf0d5cd29af9dcdab85d58aea7" url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.3.0" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 8f84e5d..7e52a3a 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.13.22+186 # When changing this, update the tag in main() accordingly +version: 0.13.23+187 # When changing this, update the tag in main() accordingly environment: sdk: '>=2.18.2 <3.0.0'