From 2938cea4194bac245542de0022e302e387115fc9 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 28 Jun 2024 21:03:53 -0400 Subject: [PATCH] Added autocomplete for F-Droid repos (#1681) --- lib/components/generated_form.dart | 78 +++++++++++++++++--------- lib/pages/add_app.dart | 5 +- pubspec.lock | 88 ++++++++++++++++++++++++++++++ pubspec.yaml | 1 + 4 files changed, 144 insertions(+), 28 deletions(-) diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index 6335f09..e9dcc0b 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -5,6 +5,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:obtainium/components/generated_form_modal.dart'; import 'package:obtainium/providers/source_provider.dart'; +import 'package:flutter_typeahead/flutter_typeahead.dart'; abstract class GeneratedFormItem { late String key; @@ -276,39 +277,62 @@ class _GeneratedFormState extends State { var formItem = e.value; if (formItem is GeneratedFormTextField) { final formFieldKey = GlobalKey(); - return TextFormField( - keyboardType: formItem.textInputType, - obscureText: formItem.password, - autocorrect: !formItem.password, - enableSuggestions: !formItem.password, - key: formFieldKey, - initialValue: values[formItem.key], - autovalidateMode: AutovalidateMode.onUserInteraction, - autofillHints: formItem.autoCompleteOptions, - onChanged: (value) { + var ctrl = TextEditingController(text: values[formItem.key]); + return TypeAheadField( + controller: ctrl, + builder: (context, controller, focusNode) { + return TextFormField( + controller: ctrl, + focusNode: focusNode, + keyboardType: formItem.textInputType, + obscureText: formItem.password, + autocorrect: !formItem.password, + enableSuggestions: !formItem.password, + key: formFieldKey, + autovalidateMode: AutovalidateMode.onUserInteraction, + onChanged: (value) { + setState(() { + values[formItem.key] = value; + someValueChanged(); + }); + }, + decoration: InputDecoration( + helperText: + formItem.label + (formItem.required ? ' *' : ''), + hintText: formItem.hint), + minLines: formItem.max <= 1 ? null : formItem.max, + maxLines: formItem.max <= 1 ? 1 : formItem.max, + validator: (value) { + if (formItem.required && + (value == null || value.trim().isEmpty)) { + return '${formItem.label} ${tr('requiredInBrackets')}'; + } + for (var validator in formItem.additionalValidators) { + String? result = validator(value); + if (result != null) { + return result; + } + } + return null; + }, + ); + }, + itemBuilder: (context, value) { + return ListTile(title: Text(value)); + }, + onSelected: (value) { + ctrl.text = value; setState(() { values[formItem.key] = value; someValueChanged(); }); }, - decoration: InputDecoration( - helperText: formItem.label + (formItem.required ? ' *' : ''), - hintText: formItem.hint), - minLines: formItem.max <= 1 ? null : formItem.max, - maxLines: formItem.max <= 1 ? 1 : formItem.max, - validator: (value) { - if (formItem.required && - (value == null || value.trim().isEmpty)) { - return '${formItem.label} ${tr('requiredInBrackets')}'; - } - for (var validator in formItem.additionalValidators) { - String? result = validator(value); - if (result != null) { - return result; - } - } - return null; + suggestionsCallback: (search) { + return formItem.autoCompleteOptions + ?.where((t) => t.toLowerCase().contains(search.toLowerCase())) + .toList(); }, + hideOnEmpty: true, ); } else if (formItem is GeneratedFormDropdown) { if (formItem.opts!.isEmpty) { diff --git a/lib/pages/add_app.dart b/lib/pages/add_app.dart index a004794..3da2829 100644 --- a/lib/pages/add_app.dart +++ b/lib/pages/add_app.dart @@ -312,7 +312,10 @@ class AddAppPageState extends State { a.app.overrideSource) .runtimeType == e.runtimeType) - .map((a) => Uri.parse(a.app.url).host) + .map((a) { + var uri = Uri.parse(a.app.url); + return '${uri.origin}${uri.path}'; + }) ], defaultValue: e.hosts.isNotEmpty ? e.hosts[0] : '', diff --git a/pubspec.lock b/pubspec.lock index 1218dfc..f9dcf84 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -312,6 +312,54 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.0" + flutter_keyboard_visibility: + dependency: transitive + description: + name: flutter_keyboard_visibility + sha256: "98664be7be0e3ffca00de50f7f6a287ab62c763fc8c762e0a21584584a3ff4f8" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + flutter_keyboard_visibility_linux: + dependency: transitive + description: + name: flutter_keyboard_visibility_linux + sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + flutter_keyboard_visibility_macos: + dependency: transitive + description: + name: flutter_keyboard_visibility_macos + sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086 + url: "https://pub.dev" + source: hosted + version: "1.0.0" + flutter_keyboard_visibility_platform_interface: + dependency: transitive + description: + name: flutter_keyboard_visibility_platform_interface + sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4 + url: "https://pub.dev" + source: hosted + version: "2.0.0" + flutter_keyboard_visibility_web: + dependency: transitive + description: + name: flutter_keyboard_visibility_web + sha256: d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1 + url: "https://pub.dev" + source: hosted + version: "2.0.0" + flutter_keyboard_visibility_windows: + dependency: transitive + description: + name: flutter_keyboard_visibility_windows + sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73 + url: "https://pub.dev" + source: hosted + version: "1.0.0" flutter_launcher_icons: dependency: "direct dev" description: @@ -378,6 +426,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_typeahead: + dependency: "direct main" + description: + name: flutter_typeahead + sha256: d64712c65db240b1057559b952398ebb6e498077baeebf9b0731dade62438a6d + url: "https://pub.dev" + source: hosted + version: "5.2.0" flutter_web_plugins: dependency: transitive description: flutter @@ -679,6 +735,38 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pointer_interceptor: + dependency: transitive + description: + name: pointer_interceptor + sha256: d0a8e660d1204eaec5bd34b34cc92174690e076d2e4f893d9d68c486a13b07c4 + url: "https://pub.dev" + source: hosted + version: "0.10.1+1" + pointer_interceptor_ios: + dependency: transitive + description: + name: pointer_interceptor_ios + sha256: a6906772b3205b42c44614fcea28f818b1e5fdad73a4ca742a7bd49818d9c917 + url: "https://pub.dev" + source: hosted + version: "0.10.1" + pointer_interceptor_platform_interface: + dependency: transitive + description: + name: pointer_interceptor_platform_interface + sha256: "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506" + url: "https://pub.dev" + source: hosted + version: "0.10.0+1" + pointer_interceptor_web: + dependency: transitive + description: + name: pointer_interceptor_web + sha256: a6237528b46c411d8d55cdfad8fcb3269fc4cbb26060b14bff94879165887d1e + url: "https://pub.dev" + source: hosted + version: "0.10.2" provider: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 3489b98..b54fe28 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -80,6 +80,7 @@ dependencies: ref: master markdown: any + flutter_typeahead: ^5.2.0 dev_dependencies: flutter_test: sdk: flutter