Merge pull request #704 from ImranR98/dev

Copy error dialog on long press (#692), Minimum star count for GitHub/Codeberg search (#688)
This commit is contained in:
Imran Remtulla
2023-07-23 02:09:25 -04:00
committed by GitHub
23 changed files with 91 additions and 42 deletions

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Provjerite ima li novosti pri otvaranju stranice s detaljima aplikacije", "checkUpdateOnDetailPage": "Provjerite ima li novosti pri otvaranju stranice s detaljima aplikacije",
"disablePageTransitions": "Ugasite animaciju prijelaza stranice", "disablePageTransitions": "Ugasite animaciju prijelaza stranice",
"reversePageTransitions": "Reverzne animacije prijelaza stranice", "reversePageTransitions": "Reverzne animacije prijelaza stranice",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Želite li ukloniti aplikaciju?", "one": "Želite li ukloniti aplikaciju?",
"other": "Želite li ukloniti aplikacije?" "other": "Želite li ukloniti aplikacije?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "App entfernen?", "one": "App entfernen?",
"other": "Apps entfernen?" "other": "Apps entfernen?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remove App?", "one": "Remove App?",
"other": "Remove Apps?" "other": "Remove Apps?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "¿Eliminar Aplicación?", "one": "¿Eliminar Aplicación?",
"other": "¿Eliminar Aplicaciones?" "other": "¿Eliminar Aplicaciones?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "برنامه حذف شود؟", "one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟" "other": "برنامه ها حذف شوند؟"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Supprimer l'application ?", "one": "Supprimer l'application ?",
"other": "Supprimer les applications ?" "other": "Supprimer les applications ?"

View File

@@ -238,6 +238,7 @@
"checkUpdateOnDetailPage": "Frissítések keresése az app részleteit tartalmazó oldal megnyitásakor", "checkUpdateOnDetailPage": "Frissítések keresése az app részleteit tartalmazó oldal megnyitásakor",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?", "one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazást?" "other": "Eltávolítja az alkalmazást?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Rimuovere l'app?", "one": "Rimuovere l'app?",
"other": "Rimuovere le app?" "other": "Rimuovere le app?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "アプリの詳細ページを開く際にアップデートを確認する", "checkUpdateOnDetailPage": "アプリの詳細ページを開く際にアップデートを確認する",
"disablePageTransitions": "ページ遷移アニメーションを無効化する", "disablePageTransitions": "ページ遷移アニメーションを無効化する",
"reversePageTransitions": "ページ遷移アニメーションを反転する", "reversePageTransitions": "ページ遷移アニメーションを反転する",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "アプリを削除しますか?", "one": "アプリを削除しますか?",
"other": "アプリを削除しますか?" "other": "アプリを削除しますか?"

View File

@@ -243,6 +243,7 @@
"checkUpdateOnDetailPage": "Sprawdzaj aktualizacje podczas otwierania strony szczegółów aplikacji", "checkUpdateOnDetailPage": "Sprawdzaj aktualizacje podczas otwierania strony szczegółów aplikacji",
"disablePageTransitions": "Wyłącz animacje przejścia między stronami", "disablePageTransitions": "Wyłącz animacje przejścia między stronami",
"reversePageTransitions": "Odwróć animacje przejścia pomiędzy stronami", "reversePageTransitions": "Odwróć animacje przejścia pomiędzy stronami",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Usunąć aplikację?", "one": "Usunąć aplikację?",
"other": "Usunąć aplikacje?" "other": "Usunąć aplikacje?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Проверять наличие обновлений при открытии страницы представления приложения", "checkUpdateOnDetailPage": "Проверять наличие обновлений при открытии страницы представления приложения",
"disablePageTransitions": "Отключить анимацию перехода между страницами", "disablePageTransitions": "Отключить анимацию перехода между страницами",
"reversePageTransitions": "Реверс анимации перехода между страницами", "reversePageTransitions": "Реверс анимации перехода между страницами",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Удалить приложение?", "one": "Удалить приложение?",
"other": "Удалить приложения?" "other": "Удалить приложения?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "是否删除应用?", "one": "是否删除应用?",
"other": "是否删除应用?" "other": "是否删除应用?"

View File

@@ -5,6 +5,7 @@ import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart'; import 'package:obtainium/providers/source_provider.dart';
class Codeberg extends AppSource { class Codeberg extends AppSource {
GitHub gh = GitHub();
Codeberg() { Codeberg() {
host = 'codeberg.org'; host = 'codeberg.org';
@@ -32,10 +33,9 @@ class Codeberg extends AppSource {
]; ];
canSearch = true; canSearch = true;
searchQuerySettingFormItems = gh.searchQuerySettingFormItems;
} }
var gh = GitHub();
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+'); RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+');
@@ -68,10 +68,12 @@ class Codeberg extends AppSource {
} }
@override @override
Future<Map<String, List<String>>> search(String query) async { Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async {
return gh.searchCommon( return gh.searchCommon(
query, query,
'https://$host/api/v1/repos/search?q=${Uri.encodeQueryComponent(query)}&limit=100', 'https://$host/api/v1/repos/search?q=${Uri.encodeQueryComponent(query)}&limit=100',
'data'); 'data',
querySettings: querySettings);
} }
} }

View File

@@ -72,7 +72,8 @@ class FDroid extends AppSource {
} }
@override @override
Future<Map<String, List<String>>> search(String query) async { Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async {
Response res = await sourceRequest( Response res = await sourceRequest(
'https://search.$host/?q=${Uri.encodeQueryComponent(query)}'); 'https://search.$host/?q=${Uri.encodeQueryComponent(query)}');
if (res.statusCode == 200) { if (res.statusCode == 200) {

View File

@@ -79,6 +79,21 @@ class GitHub extends AppSource {
]; ];
canSearch = true; 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 @override
@@ -211,8 +226,8 @@ class GitHub extends AppSource {
(nameA as String).substring(matchA!.start, matchA.end), (nameA as String).substring(matchA!.start, matchA.end),
(nameB as String).substring(matchB!.start, matchB.end)); (nameB as String).substring(matchB!.start, matchB.end));
} else { } else {
return getReleaseDateFromRelease(a)! return (getReleaseDateFromRelease(a) ?? DateTime(1))
.compareTo(getReleaseDateFromRelease(b)!); .compareTo(getReleaseDateFromRelease(b) ?? DateTime(0));
} }
} }
}); });
@@ -310,20 +325,26 @@ class GitHub extends AppSource {
Future<Map<String, List<String>>> searchCommon( Future<Map<String, List<String>>> searchCommon(
String query, String requestUrl, String rootProp, String query, String requestUrl, String rootProp,
{Function(Response)? onHttpErrorCode}) async { {Function(Response)? onHttpErrorCode,
Map<String, dynamic> querySettings = const {}}) async {
Response res = await sourceRequest(requestUrl); Response res = await sourceRequest(requestUrl);
if (res.statusCode == 200) { if (res.statusCode == 200) {
int minStarCount = querySettings['minStarCount'] != null
? int.parse(querySettings['minStarCount'])
: 0;
Map<String, List<String>> urlsWithDescriptions = {}; Map<String, List<String>> urlsWithDescriptions = {};
for (var e in (jsonDecode(res.body)[rootProp] as List<dynamic>)) { for (var e in (jsonDecode(res.body)[rootProp] as List<dynamic>)) {
urlsWithDescriptions.addAll({ if ((e['stargazers_count'] ?? e['stars_count'] ?? 0) >= minStarCount) {
e['html_url'] as String: [ urlsWithDescriptions.addAll({
e['full_name'] as String, e['html_url'] as String: [
((e['archived'] == true ? '[ARCHIVED] ' : '') + e['full_name'] as String,
(e['description'] != null ((e['archived'] == true ? '[ARCHIVED] ' : '') +
? e['description'] as String (e['description'] != null
: tr('noDescription'))) ? e['description'] as String
] : tr('noDescription')))
}); ]
});
}
} }
return urlsWithDescriptions; return urlsWithDescriptions;
} else { } else {
@@ -335,13 +356,14 @@ class GitHub extends AppSource {
} }
@override @override
Future<Map<String, List<String>>> search(String query) async { Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async {
return searchCommon( return searchCommon(
query, query,
'${await getAPIHost()}/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100', '${await getAPIHost()}/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100',
'items', onHttpErrorCode: (Response res) { 'items', onHttpErrorCode: (Response res) {
rateLimitErrorCheck(res); rateLimitErrorCheck(res);
}); }, querySettings: querySettings);
} }
rateLimitErrorCheck(Response res) { rateLimitErrorCheck(Response res) {

View File

@@ -69,7 +69,8 @@ class GitLab extends AppSource {
} }
@override @override
Future<Map<String, List<String>>> search(String query) async { Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async {
String? PAT = await getPATIfAny(); String? PAT = await getPATIfAny();
if (PAT == null) { if (PAT == null) {
throw CredsNeededError(name); throw CredsNeededError(name);

View File

@@ -1,6 +1,7 @@
import 'package:android_package_installer/android_package_installer.dart'; import 'package:android_package_installer/android_package_installer.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:obtainium/providers/logs_provider.dart'; import 'package:obtainium/providers/logs_provider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -101,7 +102,14 @@ showError(dynamic e, BuildContext context) {
title: Text(e is MultiAppMultiError title: Text(e is MultiAppMultiError
? tr('someErrors') ? tr('someErrors')
: tr('unexpectedError')), : tr('unexpectedError')),
content: Text(e.toString()), content: GestureDetector(
onLongPress: () {
Clipboard.setData(ClipboardData(text: e.toString()));
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(tr('copiedToClipboard')),
));
},
child: Text(e.toString())),
actions: [ actions: [
TextButton( TextButton(
onPressed: () { onPressed: () {

View File

@@ -21,7 +21,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart';
// ignore: implementation_imports // ignore: implementation_imports
import 'package:easy_localization/src/localization.dart'; import 'package:easy_localization/src/localization.dart';
const String currentVersion = '0.13.18'; const String currentVersion = '0.13.19';
const String currentReleaseTag = const String currentReleaseTag =
'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES 'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES

View File

@@ -182,7 +182,8 @@ class _ImportExportPageState extends State<ImportExportPage> {
[ [
GeneratedFormTextField('searchQuery', GeneratedFormTextField('searchQuery',
label: tr('searchQuery')) label: tr('searchQuery'))
] ],
...source.searchQuerySettingFormItems.map((e) => [e])
], ],
); );
}); });
@@ -191,8 +192,8 @@ class _ImportExportPageState extends State<ImportExportPage> {
setState(() { setState(() {
importInProgress = true; importInProgress = true;
}); });
var urlsWithDescriptions = var urlsWithDescriptions = await source
await source.search(values['searchQuery'] as String); .search(values['searchQuery'] as String, querySettings: values);
if (urlsWithDescriptions.isNotEmpty) { if (urlsWithDescriptions.isNotEmpty) {
var selectedUrls = var selectedUrls =
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously

View File

@@ -346,7 +346,7 @@ class AppsProvider with ChangeNotifier {
// If 0 APKs installed, throw the first install error encountered // If 0 APKs installed, throw the first install error encountered
try { try {
var somethingInstalled = false; var somethingInstalled = false;
var firstError = null; Object? firstError;
for (var file in dir.extracted for (var file in dir.extracted
.listSync(recursive: true, followLinks: false) .listSync(recursive: true, followLinks: false)
.whereType<File>()) { .whereType<File>()) {
@@ -366,7 +366,7 @@ class AppsProvider with ChangeNotifier {
} }
if (somethingInstalled) { if (somethingInstalled) {
dir.file.delete(recursive: true); dir.file.delete(recursive: true);
} else if (firstError) { } else if (firstError != null) {
throw firstError; throw firstError;
} }
} finally { } finally {

View File

@@ -436,7 +436,9 @@ abstract class AppSource {
} }
bool canSearch = false; bool canSearch = false;
Future<Map<String, List<String>>> search(String query) { List<GeneratedFormItem> searchQuerySettingFormItems = [];
Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) {
throw NotImplementedError(); throw NotImplementedError();
} }

View File

@@ -243,10 +243,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_fgbg name: flutter_fgbg
sha256: d37511eef6afb7e2e3f2278ec6498bb12c650ed517c81bcd09452d910e8b9174 sha256: "08c4d2fd229e3df26083d5aecc3dea9ff4f2d188f8cd57aaf2b3f047bd08a047"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.2" version: "0.3.0"
flutter_launcher_icons: flutter_launcher_icons:
dependency: "direct dev" dependency: "direct dev"
description: description:
@@ -538,10 +538,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: permission_handler_android name: permission_handler_android
sha256: c0c9754479a4c4b1c1f3862ddc11930c9b3f03bef2816bb4ea6eed1e13551d6f sha256: "2ffaf52a21f64ac9b35fe7369bb9533edbd4f698e5604db8645b1064ff4cf221"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.3.2" version: "10.3.3"
permission_handler_apple: permission_handler_apple:
dependency: transitive dependency: transitive
description: description:
@@ -586,10 +586,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: plugin_platform_interface name: plugin_platform_interface
sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.1.5"
pointycastle: pointycastle:
dependency: transitive dependency: transitive
description: description:
@@ -783,10 +783,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
sha256: "15f5acbf0dce90146a0f5a2c4a002b1814a6303c4c5c075aa2623b2d16156f03" sha256: "78cb6dea3e93148615109e58e42c35d1ffbf5ef66c44add673d0ab75f12ff3af"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.36" version: "6.0.37"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
@@ -863,10 +863,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_android name: webview_flutter_android
sha256: "27ad6a99c4b2d5e1ffd2b993a10f738b6b4979f139b4d64c34ac511595fcd748" sha256: "8587d0b4991bd0f223f4b4957101c2c7449f905601571315f4967072498dd3fb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.9.0" version: "3.9.1"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -879,10 +879,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_wkwebview name: webview_flutter_wkwebview
sha256: "369fdf6160944a7db660ff15fa048c2bd681b09557907beaef1f95e8557d21dc" sha256: "3e36a8f564809cb7c257ff4278502b185e2191349df0ddee98837f91805c74b8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.7.0" version: "3.7.1"
win32: win32:
dependency: transitive dependency: transitive
description: description:

View File

@@ -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 # 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 # 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. # of the product and file versions while build-number is used as the build suffix.
version: 0.13.18+182 # When changing this, update the tag in main() accordingly version: 0.13.19+183 # When changing this, update the tag in main() accordingly
environment: environment:
sdk: '>=2.18.2 <3.0.0' sdk: '>=2.18.2 <3.0.0'
@@ -37,7 +37,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.5 cupertino_icons: ^1.0.5
path_provider: ^2.0.11 path_provider: ^2.0.11
flutter_fgbg: ^0.2.0 # Try removing reliance on this flutter_fgbg: ^0.3.0 # Try removing reliance on this
flutter_local_notifications: ^15.1.0+1 flutter_local_notifications: ^15.1.0+1
provider: ^6.0.3 provider: ^6.0.3
http: ^1.0.0 http: ^1.0.0