From 905a807ee90dddeecaea68d44373f451cd5bf617 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Sat, 12 Nov 2022 01:25:32 -0500 Subject: [PATCH] GitHub search added --- lib/app_sources/github.dart | 75 ++++++++++++++++++++++-------------- lib/custom_errors.dart | 8 ++-- lib/pages/import_export.dart | 14 +++++-- 3 files changed, 61 insertions(+), 36 deletions(-) diff --git a/lib/app_sources/github.dart b/lib/app_sources/github.dart index e5d4651..8ec3a80 100644 --- a/lib/app_sources/github.dart +++ b/lib/app_sources/github.dart @@ -51,6 +51,35 @@ class GitHub extends AppSource { ]) ]; + additionalDataFormItems = [ + [ + GeneratedFormItem(label: 'Include prereleases', type: FormItemType.bool) + ], + [ + GeneratedFormItem( + label: 'Fallback to older releases', type: FormItemType.bool) + ], + [ + GeneratedFormItem( + label: 'Filter Release Titles by Regular Expression', + type: FormItemType.string, + required: false, + additionalValidators: [ + (value) { + if (value == null || value.isEmpty) { + return null; + } + try { + RegExp(value); + } catch (e) { + return 'Invalid regular expression'; + } + return null; + } + ]) + ] + ]; + canSearch = true; } @@ -156,36 +185,24 @@ class GitHub extends AppSource { return AppNames(names[0], names[1]); } - @override - List> additionalDataFormItems = [ - [GeneratedFormItem(label: 'Include prereleases', type: FormItemType.bool)], - [ - GeneratedFormItem( - label: 'Fallback to older releases', type: FormItemType.bool) - ], - [ - GeneratedFormItem( - label: 'Filter Release Titles by Regular Expression', - type: FormItemType.string, - required: false, - additionalValidators: [ - (value) { - if (value == null || value.isEmpty) { - return null; - } - try { - RegExp(value); - } catch (e) { - return 'Invalid regular expression'; - } - return null; - } - ]) - ] - ]; - @override Future> search(String query) async { - return []; + Response res = await get(Uri.parse( + 'https://${await getCredentialPrefixIfAny()}api.$host/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100')); + if (res.statusCode == 200) { + return (jsonDecode(res.body)['items'] as List) + .map((e) => e['html_url'] as String) + .toList(); + } else { + if (res.headers['x-ratelimit-remaining'] == '0') { + throw RateLimitError( + (int.parse(res.headers['x-ratelimit-reset'] ?? '1800000000') / + 60000000) + .round()); + } + throw ObtainiumError( + res.reasonPhrase ?? 'Error ${res.statusCode.toString()}', + unexpected: true); + } } } diff --git a/lib/custom_errors.dart b/lib/custom_errors.dart index 3b3a568..a1a9902 100644 --- a/lib/custom_errors.dart +++ b/lib/custom_errors.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:obtainium/providers/apps_provider.dart'; class ObtainiumError { late String message; - ObtainiumError(this.message); + bool unexpected; + ObtainiumError(this.message, {this.unexpected = false}); @override String toString() { return message; @@ -55,7 +55,7 @@ class NotImplementedError extends ObtainiumError { class MultiAppMultiError extends ObtainiumError { Map> content = {}; - MultiAppMultiError() : super('Multiple Errors Placeholder'); + MultiAppMultiError() : super('Multiple Errors Placeholder', unexpected: true); add(String appId, String string) { var tempIds = content.remove(string); @@ -75,7 +75,7 @@ class MultiAppMultiError extends ObtainiumError { } showError(dynamic e, BuildContext context) { - if (e is String || (e is ObtainiumError && e is! MultiAppMultiError)) { + if (e is String || (e is ObtainiumError && !e.unexpected)) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(e.toString())), ); diff --git a/lib/pages/import_export.dart b/lib/pages/import_export.dart index 82dbfee..56d261d 100644 --- a/lib/pages/import_export.dart +++ b/lib/pages/import_export.dart @@ -270,7 +270,10 @@ class _ImportExportPageState extends State { (BuildContext ctx) { return UrlSelectionModal( - urls: urls); + urls: urls, + defaultSelected: + false, + ); }); if (selectedUrls != null && @@ -299,6 +302,9 @@ class _ImportExportPageState extends State { }); } } + } else { + throw ObtainiumError( + 'No results found'); } } }() @@ -470,9 +476,11 @@ class _ImportErrorDialogState extends State { // ignore: must_be_immutable class UrlSelectionModal extends StatefulWidget { - UrlSelectionModal({super.key, required this.urls}); + UrlSelectionModal( + {super.key, required this.urls, this.defaultSelected = true}); List urls; + bool defaultSelected; @override State createState() => _UrlSelectionModalState(); @@ -484,7 +492,7 @@ class _UrlSelectionModalState extends State { void initState() { super.initState(); for (var url in widget.urls) { - urlSelections.putIfAbsent(url, () => true); + urlSelections.putIfAbsent(url, () => widget.defaultSelected); } }