From 9b6b7780d836a5c37e2d5df91a2ddfad2f5be99c Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 28 Jun 2024 20:11:43 -0400 Subject: [PATCH] Fix F-Droid repo search bugs (#1681) --- lib/components/generated_form.dart | 5 ++- lib/pages/add_app.dart | 49 ++++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index 23eb928..6335f09 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -28,6 +28,7 @@ class GeneratedFormTextField extends GeneratedFormItem { late String? hint; late bool password; late TextInputType? textInputType; + late List? autoCompleteOptions; GeneratedFormTextField(super.key, {super.label, @@ -39,7 +40,8 @@ class GeneratedFormTextField extends GeneratedFormItem { this.max = 1, this.hint, this.password = false, - this.textInputType}); + this.textInputType, + this.autoCompleteOptions}); @override String ensureType(val) { @@ -282,6 +284,7 @@ class _GeneratedFormState extends State { key: formFieldKey, initialValue: values[formItem.key], autovalidateMode: AutovalidateMode.onUserInteraction, + autofillHints: formItem.autoCompleteOptions, onChanged: (value) { setState(() { values[formItem.key] = value; diff --git a/lib/pages/add_app.dart b/lib/pages/add_app.dart index 248c813..a004794 100644 --- a/lib/pages/add_app.dart +++ b/lib/pages/add_app.dart @@ -51,10 +51,13 @@ class AddAppPageState extends State { } changeUserInput(String input, bool valid, bool isBuilding, - {bool updateUrlInput = false}) { + {bool updateUrlInput = false, String? overrideSource}) { userInput = input; if (!isBuilding) { setState(() { + if (overrideSource != null) { + pickedSourceOverride = overrideSource; + } if (updateUrlInput) { urlInputKey++; } @@ -280,9 +283,10 @@ class AddAppPageState extends State { settingsProvider.searchDeselected = sourceStrings.keys .where((s) => !searchSources.contains(s)) .toList(); - var results = await Future.wait(sourceProvider.sources - .where((e) => searchSources.contains(e.name)) - .map((e) async { + List>>?> results = + (await Future.wait(sourceProvider.sources + .where((e) => searchSources.contains(e.name)) + .map((e) async { try { Map? querySettings = {}; if (e.includeAdditionalOptsInMainSearch) { @@ -298,6 +302,18 @@ class AddAppPageState extends State { label: e.hosts.isNotEmpty ? tr('overrideSource') : 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: e.hosts.isNotEmpty ? e.hosts[0] : '', required: true) @@ -306,31 +322,36 @@ class AddAppPageState extends State { ); }); if (querySettings == null) { - return >{}; + return null; } } - return await e.search(searchQuery, querySettings: querySettings); + return MapEntry(e.runtimeType.toString(), + await e.search(searchQuery, querySettings: querySettings)); } catch (err) { if (err is! CredsNeededError) { rethrow; } else { err.unexpected = true; showError(err, context); - return >{}; + return null; } } - })); + }))) + .where((a) => a != null) + .toList(); // Interleave results instead of simple reduce - Map> res = {}; + Map>> res = {}; var si = 0; var done = false; while (!done) { done = true; for (var r in results) { - if (r.length > si) { + var sourceName = r!.key; + if (r.value.length > si) { done = false; - res.addEntries([r.entries.elementAt(si)]); + var singleRes = r.value.entries.elementAt(si); + res[singleRes.key] = MapEntry(sourceName, singleRes.value); } } si++; @@ -345,13 +366,15 @@ class AddAppPageState extends State { context: context, builder: (BuildContext ctx) { return SelectionModal( - entries: res, + entries: res.map((k, v) => MapEntry(k, v.value)), selectedByDefault: false, onlyOneSelectionAllowed: true, ); }); 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) {