Fix F-Droid repo search bugs (#1681)

This commit is contained in:
Imran Remtulla
2024-06-28 20:11:43 -04:00
parent f53a4f3827
commit 9b6b7780d8
2 changed files with 40 additions and 14 deletions

View File

@ -28,6 +28,7 @@ class GeneratedFormTextField extends GeneratedFormItem {
late String? hint; late String? hint;
late bool password; late bool password;
late TextInputType? textInputType; late TextInputType? textInputType;
late List<String>? autoCompleteOptions;
GeneratedFormTextField(super.key, GeneratedFormTextField(super.key,
{super.label, {super.label,
@ -39,7 +40,8 @@ class GeneratedFormTextField extends GeneratedFormItem {
this.max = 1, this.max = 1,
this.hint, this.hint,
this.password = false, this.password = false,
this.textInputType}); this.textInputType,
this.autoCompleteOptions});
@override @override
String ensureType(val) { String ensureType(val) {
@ -282,6 +284,7 @@ class _GeneratedFormState extends State<GeneratedForm> {
key: formFieldKey, key: formFieldKey,
initialValue: values[formItem.key], initialValue: values[formItem.key],
autovalidateMode: AutovalidateMode.onUserInteraction, autovalidateMode: AutovalidateMode.onUserInteraction,
autofillHints: formItem.autoCompleteOptions,
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
values[formItem.key] = value; values[formItem.key] = value;

View File

@ -51,10 +51,13 @@ class AddAppPageState extends State<AddAppPage> {
} }
changeUserInput(String input, bool valid, bool isBuilding, changeUserInput(String input, bool valid, bool isBuilding,
{bool updateUrlInput = false}) { {bool updateUrlInput = false, String? overrideSource}) {
userInput = input; userInput = input;
if (!isBuilding) { if (!isBuilding) {
setState(() { setState(() {
if (overrideSource != null) {
pickedSourceOverride = overrideSource;
}
if (updateUrlInput) { if (updateUrlInput) {
urlInputKey++; urlInputKey++;
} }
@ -280,9 +283,10 @@ class AddAppPageState extends State<AddAppPage> {
settingsProvider.searchDeselected = sourceStrings.keys settingsProvider.searchDeselected = sourceStrings.keys
.where((s) => !searchSources.contains(s)) .where((s) => !searchSources.contains(s))
.toList(); .toList();
var results = await Future.wait(sourceProvider.sources List<MapEntry<String, Map<String, List<String>>>?> results =
.where((e) => searchSources.contains(e.name)) (await Future.wait(sourceProvider.sources
.map((e) async { .where((e) => searchSources.contains(e.name))
.map((e) async {
try { try {
Map<String, dynamic>? querySettings = {}; Map<String, dynamic>? querySettings = {};
if (e.includeAdditionalOptsInMainSearch) { if (e.includeAdditionalOptsInMainSearch) {
@ -298,6 +302,18 @@ class AddAppPageState extends State<AddAppPage> {
label: e.hosts.isNotEmpty label: e.hosts.isNotEmpty
? tr('overrideSource') ? tr('overrideSource')
: plural('url', 1).substring(2), : plural('url', 1).substring(2),
autoCompleteOptions: [
...(e.hosts.isNotEmpty ? [e.hosts[0]] : []),
...appsProvider.apps.values
.where((a) =>
sourceProvider
.getSource(a.app.url,
overrideSource:
a.app.overrideSource)
.runtimeType ==
e.runtimeType)
.map((a) => Uri.parse(a.app.url).host)
],
defaultValue: defaultValue:
e.hosts.isNotEmpty ? e.hosts[0] : '', e.hosts.isNotEmpty ? e.hosts[0] : '',
required: true) required: true)
@ -306,31 +322,36 @@ class AddAppPageState extends State<AddAppPage> {
); );
}); });
if (querySettings == null) { if (querySettings == null) {
return <String, List<String>>{}; return null;
} }
} }
return await e.search(searchQuery, querySettings: querySettings); return MapEntry(e.runtimeType.toString(),
await e.search(searchQuery, querySettings: querySettings));
} catch (err) { } catch (err) {
if (err is! CredsNeededError) { if (err is! CredsNeededError) {
rethrow; rethrow;
} else { } else {
err.unexpected = true; err.unexpected = true;
showError(err, context); showError(err, context);
return <String, List<String>>{}; return null;
} }
} }
})); })))
.where((a) => a != null)
.toList();
// Interleave results instead of simple reduce // Interleave results instead of simple reduce
Map<String, List<String>> res = {}; Map<String, MapEntry<String, List<String>>> res = {};
var si = 0; var si = 0;
var done = false; var done = false;
while (!done) { while (!done) {
done = true; done = true;
for (var r in results) { for (var r in results) {
if (r.length > si) { var sourceName = r!.key;
if (r.value.length > si) {
done = false; done = false;
res.addEntries([r.entries.elementAt(si)]); var singleRes = r.value.entries.elementAt(si);
res[singleRes.key] = MapEntry(sourceName, singleRes.value);
} }
} }
si++; si++;
@ -345,13 +366,15 @@ class AddAppPageState extends State<AddAppPage> {
context: context, context: context,
builder: (BuildContext ctx) { builder: (BuildContext ctx) {
return SelectionModal( return SelectionModal(
entries: res, entries: res.map((k, v) => MapEntry(k, v.value)),
selectedByDefault: false, selectedByDefault: false,
onlyOneSelectionAllowed: true, onlyOneSelectionAllowed: true,
); );
}); });
if (selectedUrls != null && selectedUrls.isNotEmpty) { if (selectedUrls != null && selectedUrls.isNotEmpty) {
changeUserInput(selectedUrls[0], true, false, updateUrlInput: true); var sourceName = res[selectedUrls[0]]?.key;
changeUserInput(selectedUrls[0], true, false,
updateUrlInput: true, overrideSource: sourceName);
} }
} }
} catch (e) { } catch (e) {