diff --git a/assets/translations/bs.json b/assets/translations/bs.json index 38e2b0d..b0296f6 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "Provjerite ima li novosti pri otvaranju stranice s detaljima aplikacije", "disablePageTransitions": "Ugasite animaciju prijelaza stranice", "reversePageTransitions": "Reverzne animacije prijelaza stranice", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" diff --git a/assets/translations/de.json b/assets/translations/de.json index bee3009..78911ce 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "disablePageTransitions": "Disable page transition animations", "reversePageTransitions": "Reverse page transition animations", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index 6937f3e..d6afd88 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "disablePageTransitions": "Disable page transition animations", "reversePageTransitions": "Reverse page transition animations", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/es.json b/assets/translations/es.json index a572f71..ad5789e 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "disablePageTransitions": "Disable page transition animations", "reversePageTransitions": "Reverse page transition animations", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index 4db143d..eaa94a6 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "disablePageTransitions": "Disable page transition animations", "reversePageTransitions": "Reverse page transition animations", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 8c014b4..6869452 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "disablePageTransitions": "Disable page transition animations", "reversePageTransitions": "Reverse page transition animations", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index 32fd821..7a9b1dd 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -238,6 +238,7 @@ "checkUpdateOnDetailPage": "Frissítések keresése az app részleteit tartalmazó oldal megnyitásakor", "disablePageTransitions": "Disable page transition animations", "reversePageTransitions": "Reverse page transition animations", + "minStarCount": "Minimum Star Count", "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 057d88f..064382e 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "disablePageTransitions": "Disable page transition animations", "reversePageTransitions": "Reverse page transition animations", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index b5532f3..bf70542 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "アプリの詳細ページを開く際にアップデートを確認する", "disablePageTransitions": "ページ遷移アニメーションを無効化する", "reversePageTransitions": "ページ遷移アニメーションを反転する", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/pl.json b/assets/translations/pl.json index e475cc0..755db7e 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -243,6 +243,7 @@ "checkUpdateOnDetailPage": "Sprawdzaj aktualizacje podczas otwierania strony szczegółów aplikacji", "disablePageTransitions": "Wyłącz animacje przejścia między stronami", "reversePageTransitions": "Odwróć animacje przejścia pomiędzy stronami", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "Usunąć aplikację?", "other": "Usunąć aplikacje?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index aa3d2eb..4b90d63 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "Проверять наличие обновлений при открытии страницы представления приложения", "disablePageTransitions": "Отключить анимацию перехода между страницами", "reversePageTransitions": "Реверс анимации перехода между страницами", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 2904972..55763dd 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -239,6 +239,7 @@ "checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "disablePageTransitions": "Disable page transition animations", "reversePageTransitions": "Reverse page transition animations", + "minStarCount": "Minimum Star Count", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" diff --git a/lib/app_sources/codeberg.dart b/lib/app_sources/codeberg.dart index f94cdb9..669e0d9 100644 --- a/lib/app_sources/codeberg.dart +++ b/lib/app_sources/codeberg.dart @@ -5,6 +5,7 @@ import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/providers/source_provider.dart'; class Codeberg extends AppSource { + GitHub gh = GitHub(); Codeberg() { host = 'codeberg.org'; @@ -32,10 +33,9 @@ class Codeberg extends AppSource { ]; canSearch = true; + searchQuerySettingFormItems = gh.searchQuerySettingFormItems; } - var gh = GitHub(); - @override String sourceSpecificStandardizeURL(String url) { RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+'); @@ -68,10 +68,12 @@ class Codeberg extends AppSource { } @override - Future>> search(String query) async { + Future>> search(String query, + {Map querySettings = const {}}) async { return gh.searchCommon( query, 'https://$host/api/v1/repos/search?q=${Uri.encodeQueryComponent(query)}&limit=100', - 'data'); + 'data', + querySettings: querySettings); } } diff --git a/lib/app_sources/fdroid.dart b/lib/app_sources/fdroid.dart index 0602f6d..2f96fe7 100644 --- a/lib/app_sources/fdroid.dart +++ b/lib/app_sources/fdroid.dart @@ -72,7 +72,8 @@ class FDroid extends AppSource { } @override - Future>> search(String query) async { + Future>> search(String query, + {Map querySettings = const {}}) async { Response res = await sourceRequest( 'https://search.$host/?q=${Uri.encodeQueryComponent(query)}'); if (res.statusCode == 200) { diff --git a/lib/app_sources/github.dart b/lib/app_sources/github.dart index 4334abd..0f74c47 100644 --- a/lib/app_sources/github.dart +++ b/lib/app_sources/github.dart @@ -79,6 +79,21 @@ class GitHub extends AppSource { ]; canSearch = true; + searchQuerySettingFormItems = [ + GeneratedFormTextField('minStarCount', + label: tr('minStarCount'), + defaultValue: '0', + additionalValidators: [ + (value) { + try { + int.parse(value ?? '0'); + } catch (e) { + return tr('invalidInput'); + } + return null; + } + ]) + ]; } @override @@ -310,20 +325,26 @@ class GitHub extends AppSource { Future>> searchCommon( String query, String requestUrl, String rootProp, - {Function(Response)? onHttpErrorCode}) async { + {Function(Response)? onHttpErrorCode, + Map querySettings = const {}}) async { Response res = await sourceRequest(requestUrl); if (res.statusCode == 200) { + int minStarCount = querySettings['minStarCount'] != null + ? int.parse(querySettings['minStarCount']) + : 0; Map> urlsWithDescriptions = {}; for (var e in (jsonDecode(res.body)[rootProp] as List)) { - urlsWithDescriptions.addAll({ - e['html_url'] as String: [ - e['full_name'] as String, - ((e['archived'] == true ? '[ARCHIVED] ' : '') + - (e['description'] != null - ? e['description'] as String - : tr('noDescription'))) - ] - }); + if ((e['stargazers_count'] ?? e['stars_count'] ?? 0) >= minStarCount) { + urlsWithDescriptions.addAll({ + e['html_url'] as String: [ + e['full_name'] as String, + ((e['archived'] == true ? '[ARCHIVED] ' : '') + + (e['description'] != null + ? e['description'] as String + : tr('noDescription'))) + ] + }); + } } return urlsWithDescriptions; } else { @@ -335,13 +356,14 @@ class GitHub extends AppSource { } @override - Future>> search(String query) async { + Future>> search(String query, + {Map querySettings = const {}}) async { return searchCommon( query, '${await getAPIHost()}/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100', 'items', onHttpErrorCode: (Response res) { rateLimitErrorCheck(res); - }); + }, querySettings: querySettings); } rateLimitErrorCheck(Response res) { diff --git a/lib/app_sources/gitlab.dart b/lib/app_sources/gitlab.dart index 574e814..ec2fd94 100644 --- a/lib/app_sources/gitlab.dart +++ b/lib/app_sources/gitlab.dart @@ -69,7 +69,8 @@ class GitLab extends AppSource { } @override - Future>> search(String query) async { + Future>> search(String query, + {Map querySettings = const {}}) async { String? PAT = await getPATIfAny(); if (PAT == null) { throw CredsNeededError(name); diff --git a/lib/pages/import_export.dart b/lib/pages/import_export.dart index fd10f86..e2ebdf9 100644 --- a/lib/pages/import_export.dart +++ b/lib/pages/import_export.dart @@ -182,7 +182,8 @@ class _ImportExportPageState extends State { [ GeneratedFormTextField('searchQuery', label: tr('searchQuery')) - ] + ], + ...source.searchQuerySettingFormItems.map((e) => [e]) ], ); }); @@ -191,8 +192,8 @@ class _ImportExportPageState extends State { setState(() { importInProgress = true; }); - var urlsWithDescriptions = - await source.search(values['searchQuery'] as String); + var urlsWithDescriptions = await source + .search(values['searchQuery'] as String, querySettings: values); if (urlsWithDescriptions.isNotEmpty) { var selectedUrls = // ignore: use_build_context_synchronously diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index 6917ba5..f71c238 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -436,7 +436,9 @@ abstract class AppSource { } bool canSearch = false; - Future>> search(String query) { + List searchQuerySettingFormItems = []; + Future>> search(String query, + {Map querySettings = const {}}) { throw NotImplementedError(); }