From 659867719f4b7848e8db92542ad28bb8c84a009c Mon Sep 17 00:00:00 2001 From: Jonathan <57756132+jdk-21@users.noreply.github.com> Date: Sat, 2 Nov 2024 17:10:34 +0100 Subject: [PATCH] Revert "feat: added autocomplete options to url input" --- .../custom_autocomplete_options.dart | 92 ---------------- lib/components/url_autocomplete_field.dart | 100 ------------------ lib/providers/url_autocomplete_provider.dart | 5 - lib/screens/login_screen.dart | 12 ++- lib/screens/player_screen.dart | 1 - 5 files changed, 9 insertions(+), 201 deletions(-) delete mode 100644 lib/components/custom_autocomplete_options.dart delete mode 100644 lib/components/url_autocomplete_field.dart delete mode 100644 lib/providers/url_autocomplete_provider.dart diff --git a/lib/components/custom_autocomplete_options.dart b/lib/components/custom_autocomplete_options.dart deleted file mode 100644 index fd3bf3b..0000000 --- a/lib/components/custom_autocomplete_options.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:jellyflix/providers/url_autocomplete_provider.dart'; - -class CustomAutocompleteOptions extends ConsumerWidget { - const CustomAutocompleteOptions({ - super.key, - required this.displayStringForOption, - required this.onSelected, - required this.openDirection, - required this.options, - required this.maxOptionsHeight, - required this.maxOptionsWidth, - }); - - final AutocompleteOptionToString displayStringForOption; - - final AutocompleteOnSelected onSelected; - final OptionsViewOpenDirection openDirection; - - final Iterable options; - final double maxOptionsHeight; - final double maxOptionsWidth; - - @override - Widget build(BuildContext context, WidgetRef ref) { - final AlignmentDirectional optionsAlignment = switch (openDirection) { - OptionsViewOpenDirection.up => AlignmentDirectional.bottomStart, - OptionsViewOpenDirection.down => AlignmentDirectional.topStart, - }; - // taken from flutter\lib\src\material\autocomplete.dart and slightly modified - return Align( - alignment: optionsAlignment, - child: Material( - elevation: 4.0, - child: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: maxOptionsHeight, - maxWidth: maxOptionsWidth, - ), - child: ListView.builder( - padding: EdgeInsets.zero, - shrinkWrap: true, - itemCount: options.length, - itemBuilder: (BuildContext context, int index) { - final T option = options.elementAt(index); - return InkWell( - onTap: () { - onSelected(option); - }, - child: Builder(builder: (BuildContext context) { - final bool highlight = - AutocompleteHighlightedOption.of(context) == index; - if (highlight) { - // wrapped in a future to update the options after building - Future( - () => ref.read(selectedOptionProvider.notifier).state = - option as String, - ); - SchedulerBinding.instance.addPostFrameCallback( - (Duration timeStamp) { - Scrollable.ensureVisible(context, alignment: 0.5); - }, debugLabel: 'AutocompleteOptions.ensureVisible'); - } - - return Container( - color: highlight ? Theme.of(context).focusColor : null, - padding: const EdgeInsets.all(16.0), - // do not show shortcut hint on mobile platforms - child: highlight && !(Platform.isAndroid || Platform.isIOS) - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(displayStringForOption(option)), - const SizedBox(width: 20), - const Text('Enter to fill') - ], - ) - : Text(displayStringForOption(option)), - ); - }), - ); - }, - ), - ), - ), - ); - } -} diff --git a/lib/components/url_autocomplete_field.dart b/lib/components/url_autocomplete_field.dart deleted file mode 100644 index 08cdab0..0000000 --- a/lib/components/url_autocomplete_field.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:jellyflix/components/custom_autocomplete_options.dart'; -import 'package:jellyflix/providers/auth_provider.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:jellyflix/providers/url_autocomplete_provider.dart'; - -// Courtesy of sevenrats for the shortcuts - -class UrlFieldInput extends ConsumerWidget { - const UrlFieldInput({super.key, required this.serverAddress}); - - final TextEditingController serverAddress; - - @override - Widget build(BuildContext context, WidgetRef ref) { - final savedAddress = ref.read(allProfilesProvider); - - // Needed to get width of the URL text field - // so we can assign that to the autocomplete width - final urlTextFieldKey = GlobalKey(); - - // Create a custom FocusNode to listen for key events - final focusNode = FocusNode(); - - // Attach the key listener for Tab key press - focusNode.onKeyEvent = (FocusNode node, KeyEvent event) { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - serverAddress.text = ref.read(selectedOptionProvider); - return KeyEventResult.handled; - } - return KeyEventResult.ignored; - }; - - return RawAutocomplete( - focusNode: focusNode, - textEditingController: serverAddress, - optionsBuilder: (TextEditingValue textEditingValue) { - final result = savedAddress.valueOrNull - ?.where( - (element) => - element.serverAdress! - .contains(textEditingValue.text.toLowerCase()) && - // ensure that the option is not already filled - element.serverAdress! != textEditingValue.text.toLowerCase(), - ) - .map((e) => e.serverAdress!) - .toSet(); // remove duplicates - - final options = result == null || result.isEmpty - ? ['http://', 'https://'].where((e) => - e.contains(textEditingValue.text.toLowerCase()) && - // ensure that the option is not already filled - e != textEditingValue.text.toLowerCase()) - : result; - - // clear options on change - ref.invalidate(selectedOptionProvider); - - return options; - }, - onSelected: (option) => serverAddress.text = option, - optionsViewOpenDirection: OptionsViewOpenDirection.down, - fieldViewBuilder: (context, controller, focusNode, _) { - return TextField( - key: urlTextFieldKey, - focusNode: focusNode, - controller: controller, - decoration: InputDecoration( - border: const OutlineInputBorder(), - labelText: AppLocalizations.of(context)!.serverAddress, - hintText: 'http://', - ), - ); - }, - optionsViewBuilder: ( - BuildContext context, - void Function(String) onSelected, - Iterable options, - ) { - RenderBox? renderBox; - if (urlTextFieldKey.currentContext?.findRenderObject() != null) { - renderBox = - urlTextFieldKey.currentContext!.findRenderObject() as RenderBox; - } - - return CustomAutocompleteOptions( - displayStringForOption: RawAutocomplete.defaultStringForOption, - onSelected: onSelected, - options: options, - openDirection: OptionsViewOpenDirection.down, - maxOptionsHeight: 150, - maxOptionsWidth: renderBox?.size.width ?? 300, - ); - }, - ); - } -} diff --git a/lib/providers/url_autocomplete_provider.dart b/lib/providers/url_autocomplete_provider.dart deleted file mode 100644 index 1447cb6..0000000 --- a/lib/providers/url_autocomplete_provider.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -final selectedOptionProvider = StateProvider((ref) { - return ''; -}); diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index 753561c..d1ad132 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -6,7 +6,6 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:jellyflix/components/url_autocomplete_field.dart'; import 'package:jellyflix/models/screen_paths.dart'; import 'package:jellyflix/models/user.dart'; import 'package:jellyflix/providers/auth_provider.dart'; @@ -57,7 +56,15 @@ class LoginScreen extends HookConsumerWidget { const SizedBox(height: 20), Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), - child: UrlFieldInput(serverAddress: serverAddress), + child: TextField( + controller: serverAddress, + decoration: InputDecoration( + border: const OutlineInputBorder(), + labelText: + AppLocalizations.of(context)!.serverAddress, + hintText: 'http://', + ), + ), ), Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), @@ -259,4 +266,3 @@ class LoginScreen extends HookConsumerWidget { .trim(); } } - diff --git a/lib/screens/player_screen.dart b/lib/screens/player_screen.dart index eac80c5..c0b483e 100644 --- a/lib/screens/player_screen.dart +++ b/lib/screens/player_screen.dart @@ -140,7 +140,6 @@ class _PlayerSreenState extends ConsumerState { ); }); - if (!context.mounted) return; player.stream.error.listen((error) { if (mounted) { showDialog(