mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-16 06:36:44 +02:00
GitHub search added
This commit is contained in:
@ -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<List<GeneratedFormItem>> 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<List<String>> 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<dynamic>)
|
||||
.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<String, List<String>> 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())),
|
||||
);
|
||||
|
@ -270,7 +270,10 @@ class _ImportExportPageState extends State<ImportExportPage> {
|
||||
(BuildContext
|
||||
ctx) {
|
||||
return UrlSelectionModal(
|
||||
urls: urls);
|
||||
urls: urls,
|
||||
defaultSelected:
|
||||
false,
|
||||
);
|
||||
});
|
||||
if (selectedUrls !=
|
||||
null &&
|
||||
@ -299,6 +302,9 @@ class _ImportExportPageState extends State<ImportExportPage> {
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw ObtainiumError(
|
||||
'No results found');
|
||||
}
|
||||
}
|
||||
}()
|
||||
@ -470,9 +476,11 @@ class _ImportErrorDialogState extends State<ImportErrorDialog> {
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class UrlSelectionModal extends StatefulWidget {
|
||||
UrlSelectionModal({super.key, required this.urls});
|
||||
UrlSelectionModal(
|
||||
{super.key, required this.urls, this.defaultSelected = true});
|
||||
|
||||
List<String> urls;
|
||||
bool defaultSelected;
|
||||
|
||||
@override
|
||||
State<UrlSelectionModal> createState() => _UrlSelectionModalState();
|
||||
@ -484,7 +492,7 @@ class _UrlSelectionModalState extends State<UrlSelectionModal> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
for (var url in widget.urls) {
|
||||
urlSelections.putIfAbsent(url, () => true);
|
||||
urlSelections.putIfAbsent(url, () => widget.defaultSelected);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user