From 18c2a135c72bcd3de033f931a0299d4dfd7573e2 Mon Sep 17 00:00:00 2001 From: Samuel Rioja Date: Tue, 28 Jan 2025 11:56:42 -0400 Subject: [PATCH 1/3] add implementation --- .../components/location_form_field.dart | 21 ++- .../components/location_search_delegate.dart | 164 ++++++++++-------- 2 files changed, 101 insertions(+), 84 deletions(-) diff --git a/lib/base/pages/home/search_location_field/components/location_form_field.dart b/lib/base/pages/home/search_location_field/components/location_form_field.dart index d273f710..3cc96bb1 100644 --- a/lib/base/pages/home/search_location_field/components/location_form_field.dart +++ b/lib/base/pages/home/search_location_field/components/location_form_field.dart @@ -58,14 +58,21 @@ class _LocationFormFieldState extends State { Expanded( child: GestureDetector( onTap: () async { + final defaultSearch = (widget.value != null) + ? "${widget.value?.displayName(localizationSP)}${widget.value?.address?.isNotEmpty ?? false ? ", ${widget.value?.address}" : ""}" + : null; + // Show search - final TrufiLocation? location = await showSearch( - context: context, - delegate: LocationSearchDelegate( - isOrigin: widget.isOrigin, - hint: widget.isOrigin - ? localization.searchHintOrigin - : localization.searchHintDestination, + final TrufiLocation? location = + await Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => CustomLocationSearchPage( + isOrigin: widget.isOrigin, + hint: widget.isOrigin + ? localization.searchHintOrigin + : localization.searchHintDestination, + defaultSearch: defaultSearch, + ), ), ); // Check result diff --git a/lib/base/pages/home/search_location_field/components/location_search_delegate.dart b/lib/base/pages/home/search_location_field/components/location_search_delegate.dart index 2fbab021..d28bd734 100644 --- a/lib/base/pages/home/search_location_field/components/location_search_delegate.dart +++ b/lib/base/pages/home/search_location_field/components/location_search_delegate.dart @@ -1,110 +1,120 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:stadtnavi_core/base/pages/home/search_location_field/components/suggestion.dart'; - import 'package:trufi_core/base/blocs/theme/theme_cubit.dart'; import 'package:trufi_core/base/models/trufi_place.dart'; import 'package:trufi_core/base/widgets/location_search_delegate/build_street_results.dart'; -class LocationSearchDelegate extends SearchDelegate { +import 'package:stadtnavi_core/base/pages/home/search_location_field/components/suggestion.dart'; + +class CustomLocationSearchPage extends StatefulWidget { final bool isOrigin; final String hint; - LocationSearchDelegate({ + final String? defaultSearch; + + const CustomLocationSearchPage({ + Key? key, required this.isOrigin, required this.hint, - }) : super( - searchFieldLabel: hint, - ); + this.defaultSearch, + }) : super(key: key); + + @override + State createState() => + _CustomLocationSearchPageState(); +} +class _CustomLocationSearchPageState extends State { + late TextEditingController _controller; dynamic _result; @override - ThemeData appBarTheme(BuildContext context) { - final theme = context.watch().themeData(context); - return theme.copyWith( - scaffoldBackgroundColor: - ThemeCubit.isDarkMode(theme) ? Colors.grey[900] : null, - textSelectionTheme: theme.textSelectionTheme.copyWith( - cursorColor: Colors.black87, - selectionColor: Colors.grey[300], - ), - hintColor: Colors.black54, - textTheme: theme.textTheme.copyWith( - headlineSmall: const TextStyle( - color: Colors.black, - fontSize: 16, - ), - ), - ); + void initState() { + super.initState(); + _controller = TextEditingController(text: widget.defaultSearch ?? ''); } @override - Widget buildLeading(BuildContext context) { - final theme = context.watch().themeData(context); - return BackButton( - onPressed: () { - if (_result != null) { - _result = null; - showSuggestions(context); - } else { - close(context, null); - } - }, - color: theme.appBarTheme.foregroundColor, - ); + void dispose() { + _controller.dispose(); + super.dispose(); } - @override - Widget buildSuggestions(BuildContext context) { + void _onSuggestionTap(TrufiLocation suggestion) { + Navigator.of(context).pop(suggestion); + } + + void _onStreetTapped(TrufiStreet street) { + setState(() { + _result = street; + }); + } + + Widget _buildSuggestions() { return SuggestionList( - query: query, - isOrigin: isOrigin, - onSelected: (TrufiLocation suggestion) { - _result = suggestion; - close(context, suggestion); - }, - onSelectedMap: (TrufiLocation location) { - _result = location; - showResults(context); - }, - onStreetTapped: (TrufiStreet street) { - _result = street; - showResults(context); - }, + query: _controller.text, + isOrigin: widget.isOrigin, + onSelected: (TrufiLocation suggestion) => _onSuggestionTap(suggestion), + onSelectedMap: (TrufiLocation location) => _onSuggestionTap(location), + onStreetTapped: (TrufiStreet street) => _onStreetTapped(street), ); } @override - Widget buildResults(BuildContext context) { - if (_result != null) { - if (_result is TrufiStreet) { - return BuildStreetResults( + Widget build(BuildContext context) { + final theme = context.watch().themeData(context); + + if (_result != null && _result is TrufiStreet) { + return Scaffold( + appBar: AppBar( + leading: BackButton( + onPressed: () { + setState(() => _result = null); + }, + ), + title: Text(widget.hint), + ), + body: BuildStreetResults( street: _result as TrufiStreet, onTap: (location) { - close(context, location); + Navigator.of(context).pop(location); }, - ); - } else { - Future.delayed(Duration.zero, () { - close(context, _result as TrufiLocation); - }); - } + ), + ); } - return buildSuggestions(context); - } - @override - List buildActions(BuildContext context) { - return [ - if (query.isNotEmpty) - IconButton( - icon: const Icon(Icons.clear), - onPressed: () { - _result = null; - query = ''; - showSuggestions(context); + return Scaffold( + appBar: AppBar( + backgroundColor: theme.appBarTheme.backgroundColor, + leading: IconButton( + icon: const Icon(Icons.arrow_back), + color: theme.appBarTheme.foregroundColor, + onPressed: () => Navigator.of(context).pop(null), + ), + title: TextField( + controller: _controller, + autofocus: true, + decoration: InputDecoration( + hintText: widget.hint, + border: InputBorder.none, + ), + onChanged: (_) { + setState(() {}); }, ), - ]; + actions: [ + if (_controller.text.isNotEmpty) + IconButton( + onPressed: () { + setState(() { + _result = null; + _controller.clear(); + }); + }, + icon: const Icon(Icons.clear), + ) + ], + ), + body: _buildSuggestions(), + ); } } From 8a7527a4a9443d45f453f754c95212a3848f53d0 Mon Sep 17 00:00:00 2001 From: Samuel Rioja Date: Thu, 30 Jan 2025 02:15:50 -0400 Subject: [PATCH 2/3] add X close button to each text field --- .../cubits/map_route_cubit/map_route_cubit.dart | 8 +++++++- lib/base/pages/home/home_page.dart | 14 ++++++++++++++ .../components/location_form_field.dart | 11 +++++++++-- .../form_fields_landscape.dart | 15 ++++++--------- .../form_fields_portrait.dart | 17 ++++++++++------- .../search_location_field/home_app_bar.dart | 8 ++++++++ 6 files changed, 54 insertions(+), 19 deletions(-) diff --git a/lib/base/pages/home/cubits/map_route_cubit/map_route_cubit.dart b/lib/base/pages/home/cubits/map_route_cubit/map_route_cubit.dart index f7fdf665..ad707ead 100644 --- a/lib/base/pages/home/cubits/map_route_cubit/map_route_cubit.dart +++ b/lib/base/pages/home/cubits/map_route_cubit/map_route_cubit.dart @@ -71,11 +71,17 @@ class MapRouteCubit extends Cubit { await updateMapRouteState( state.copyWithNullable(fromPlace: const Optional.value(null))); } + Future resetFromPlaceKeepingToPlace() async { + await updateMapRouteState(MapRouteState(toPlace: state.toPlace)); + } - Future resetToPlace() async { + Future resetToPlace() async { await updateMapRouteState( state.copyWithNullable(toPlace: const Optional.value(null))); } + Future resetToPlaceKeepingFromPlace() async { + await updateMapRouteState(MapRouteState(fromPlace: state.fromPlace)); + } Future removeInfoBox() async { await updateMapRouteState( diff --git a/lib/base/pages/home/home_page.dart b/lib/base/pages/home/home_page.dart index 741f8b41..cd1c1efa 100644 --- a/lib/base/pages/home/home_page.dart +++ b/lib/base/pages/home/home_page.dart @@ -143,6 +143,13 @@ class _HomePageState extends State _callFetchPlan(context); }, ), + onClearFrom: () async { + mapRouteCubit.resetFromPlaceKeepingToPlace(); + if (mapRouteCubit.state.plan != null) { + panelCubit.cleanPanel(); + await mapModesCubit.reset(); + } + }, onSaveTo: (TrufiLocation toPlace) => mapRouteCubit.setToPlace(toPlace).then( (value) { @@ -154,6 +161,13 @@ class _HomePageState extends State _callFetchPlan(context); }, ), + onClearTo: () async { + mapRouteCubit.resetToPlaceKeepingFromPlace(); + if (mapRouteCubit.state.plan != null) { + panelCubit.cleanPanel(); + await mapModesCubit.reset(); + } + }, onBackButton: () { HomePage.scaffoldKey.currentState?.openDrawer(); }, diff --git a/lib/base/pages/home/search_location_field/components/location_form_field.dart b/lib/base/pages/home/search_location_field/components/location_form_field.dart index 3cc96bb1..4017f1e2 100644 --- a/lib/base/pages/home/search_location_field/components/location_form_field.dart +++ b/lib/base/pages/home/search_location_field/components/location_form_field.dart @@ -11,6 +11,7 @@ class LocationFormField extends StatefulWidget { required this.hintText, required this.textLeadingImage, required this.onSaved, + required this.onClear, required this.isOrigin, this.value, this.leading, @@ -21,6 +22,7 @@ class LocationFormField extends StatefulWidget { final String hintText; final Widget textLeadingImage; final Function(TrufiLocation) onSaved; + final Function() onClear; final TrufiLocation? value; final Widget? leading; final Widget? trailing; @@ -95,7 +97,7 @@ class _LocationFormFieldState extends State { child: Row( children: [ SizedBox(height: 24.0, child: widget.textLeadingImage), - Flexible( + Expanded( child: SingleChildScrollView( controller: _scrollController, scrollDirection: Axis.horizontal, @@ -116,7 +118,12 @@ class _LocationFormFieldState extends State { ), ), ), - ) + ), + if(widget.value != null) + GestureDetector( + child: const Icon(Icons.close), + onTap: widget.onClear, + ), ], ), ), diff --git a/lib/base/pages/home/search_location_field/form_fields_landscape.dart b/lib/base/pages/home/search_location_field/form_fields_landscape.dart index 973909c6..3b49d82d 100644 --- a/lib/base/pages/home/search_location_field/form_fields_landscape.dart +++ b/lib/base/pages/home/search_location_field/form_fields_landscape.dart @@ -12,14 +12,18 @@ class FormFieldsLandscape extends StatelessWidget { const FormFieldsLandscape({ Key? key, required this.onSaveFrom, + required this.onClearFrom, required this.onSaveTo, + required this.onClearTo, required this.onFetchPlan, required this.onReset, required this.onSwap, }) : super(key: key); final void Function(TrufiLocation) onSaveFrom; + final void Function() onClearFrom; final void Function(TrufiLocation) onSaveTo; + final void Function() onClearTo; final void Function() onFetchPlan; final void Function() onReset; final void Function() onSwap; @@ -38,6 +42,7 @@ class FormFieldsLandscape extends StatelessWidget { hintText: localization.searchPleaseSelectOrigin, textLeadingImage: mapConfiguratiom.markersConfiguration.fromMarker, onSaved: onSaveFrom, + onClear: onClearFrom, value: mapRouteState.fromPlace, ), ), @@ -57,18 +62,10 @@ class FormFieldsLandscape extends StatelessWidget { hintText: localization.searchPleaseSelectDestination, textLeadingImage: mapConfiguratiom.markersConfiguration.toMarker, onSaved: onSaveTo, + onClear: onClearTo, value: mapRouteState.toPlace, ), ), - SizedBox( - width: 40.0, - child: mapRouteState.isPlacesDefined - ? ResetButton( - onReset: onReset, - color: theme.appBarTheme.foregroundColor!, - ) - : null, - ), ], ); } diff --git a/lib/base/pages/home/search_location_field/form_fields_portrait.dart b/lib/base/pages/home/search_location_field/form_fields_portrait.dart index 91426bb3..5c5aa97c 100644 --- a/lib/base/pages/home/search_location_field/form_fields_portrait.dart +++ b/lib/base/pages/home/search_location_field/form_fields_portrait.dart @@ -12,14 +12,18 @@ class FormFieldsPortrait extends StatelessWidget { const FormFieldsPortrait({ Key? key, required this.onSaveFrom, + required this.onClearFrom, required this.onSaveTo, + required this.onClearTo, required this.onFetchPlan, required this.onReset, required this.onSwap, }) : super(key: key); final void Function(TrufiLocation) onSaveFrom; + final void Function() onClearFrom; final void Function(TrufiLocation) onSaveTo; + final void Function() onClearTo; final void Function() onFetchPlan; final void Function() onReset; final void Function() onSwap; @@ -35,11 +39,13 @@ class FormFieldsPortrait extends StatelessWidget { LocationFormField( isOrigin: true, onSaved: onSaveFrom, + onClear: onClearFrom, hintText: localization.searchPleaseSelectOrigin, textLeadingImage: mapConfiguratiom.markersConfiguration.fromMarker, trailing: mapRouteState.isPlacesDefined - ? ResetButton( - onReset: onReset, + ? SwapButton( + orientation: Orientation.portrait, + onSwap: onSwap, color: theme.appBarTheme.foregroundColor!, ) : null, @@ -48,14 +54,11 @@ class FormFieldsPortrait extends StatelessWidget { LocationFormField( isOrigin: false, onSaved: onSaveTo, + onClear: onClearTo, hintText: localization.searchPleaseSelectDestination, textLeadingImage: mapConfiguratiom.markersConfiguration.toMarker, trailing: mapRouteState.isPlacesDefined - ? SwapButton( - orientation: Orientation.portrait, - onSwap: onSwap, - color: theme.appBarTheme.foregroundColor!, - ) + ? Container() : null, value: mapRouteState.toPlace, ), diff --git a/lib/base/pages/home/search_location_field/home_app_bar.dart b/lib/base/pages/home/search_location_field/home_app_bar.dart index 2f3b09a9..3f1f8adb 100644 --- a/lib/base/pages/home/search_location_field/home_app_bar.dart +++ b/lib/base/pages/home/search_location_field/home_app_bar.dart @@ -10,7 +10,9 @@ import 'package:trufi_core/base/models/trufi_place.dart'; class HomeAppBar extends StatelessWidget { final void Function(TrufiLocation) onSaveFrom; + final void Function() onClearFrom; final void Function(TrufiLocation) onSaveTo; + final void Function() onClearTo; final void Function() onBackButton; final void Function() onFetchPlan; final void Function() onReset; @@ -18,7 +20,9 @@ class HomeAppBar extends StatelessWidget { const HomeAppBar({ Key? key, required this.onSaveFrom, + required this.onClearFrom, required this.onSaveTo, + required this.onClearTo, required this.onBackButton, required this.onFetchPlan, required this.onReset, @@ -75,7 +79,9 @@ class HomeAppBar extends StatelessWidget { onFetchPlan: onFetchPlan, onReset: onReset, onSaveFrom: onSaveFrom, + onClearFrom:onClearFrom, onSaveTo: onSaveTo, + onClearTo:onClearTo, onSwap: onSwap, ), ) @@ -86,7 +92,9 @@ class HomeAppBar extends StatelessWidget { onFetchPlan: onFetchPlan, onReset: onReset, onSaveFrom: onSaveFrom, + onClearFrom:onClearFrom, onSaveTo: onSaveTo, + onClearTo:onClearTo, onSwap: onSwap, ), ), From 600235cdbeceed9af91c1681a01698a762c2ad15 Mon Sep 17 00:00:00 2001 From: Samuel Rioja Date: Wed, 12 Feb 2025 00:14:12 -0400 Subject: [PATCH 3/3] add ui adjusts --- .../components/location_form_field.dart | 29 +++++---- .../form_fields_portrait.dart | 61 ++++++++++--------- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/lib/base/pages/home/search_location_field/components/location_form_field.dart b/lib/base/pages/home/search_location_field/components/location_form_field.dart index 4017f1e2..33836d33 100644 --- a/lib/base/pages/home/search_location_field/components/location_form_field.dart +++ b/lib/base/pages/home/search_location_field/components/location_form_field.dart @@ -50,6 +50,7 @@ class _LocationFormFieldState extends State { Widget build(BuildContext context) { final localization = TrufiBaseLocalization.of(context); final localizationSP = SavedPlacesLocalization.of(context); + final theme = Theme.of(context); return Row( children: [ if (widget.leading != null) @@ -68,12 +69,15 @@ class _LocationFormFieldState extends State { final TrufiLocation? location = await Navigator.of(context).push( MaterialPageRoute( - builder: (_) => CustomLocationSearchPage( - isOrigin: widget.isOrigin, - hint: widget.isOrigin - ? localization.searchHintOrigin - : localization.searchHintDestination, - defaultSearch: defaultSearch, + builder: (_) => Theme( + data: Theme.of(context), + child: CustomLocationSearchPage( + isOrigin: widget.isOrigin, + hint: widget.isOrigin + ? localization.searchHintOrigin + : localization.searchHintDestination, + defaultSearch: defaultSearch, + ), ), ), ); @@ -119,11 +123,14 @@ class _LocationFormFieldState extends State { ), ), ), - if(widget.value != null) - GestureDetector( - child: const Icon(Icons.close), - onTap: widget.onClear, - ), + if (widget.value != null) + GestureDetector( + child: Icon( + Icons.close, + color: theme.primaryColor, + ), + onTap: widget.onClear, + ), ], ), ), diff --git a/lib/base/pages/home/search_location_field/form_fields_portrait.dart b/lib/base/pages/home/search_location_field/form_fields_portrait.dart index 5c5aa97c..1554640f 100644 --- a/lib/base/pages/home/search_location_field/form_fields_portrait.dart +++ b/lib/base/pages/home/search_location_field/form_fields_portrait.dart @@ -33,35 +33,40 @@ class FormFieldsPortrait extends StatelessWidget { final localization = TrufiBaseLocalization.of(context); final mapRouteState = context.watch().state; final mapConfiguratiom = context.read().state; - return Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - LocationFormField( - isOrigin: true, - onSaved: onSaveFrom, - onClear: onClearFrom, - hintText: localization.searchPleaseSelectOrigin, - textLeadingImage: mapConfiguratiom.markersConfiguration.fromMarker, - trailing: mapRouteState.isPlacesDefined - ? SwapButton( - orientation: Orientation.portrait, - onSwap: onSwap, - color: theme.appBarTheme.foregroundColor!, - ) - : null, - value: mapRouteState.fromPlace, - ), - LocationFormField( - isOrigin: false, - onSaved: onSaveTo, - onClear: onClearTo, - hintText: localization.searchPleaseSelectDestination, - textLeadingImage: mapConfiguratiom.markersConfiguration.toMarker, - trailing: mapRouteState.isPlacesDefined - ? Container() - : null, - value: mapRouteState.toPlace, + return Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + LocationFormField( + isOrigin: true, + onSaved: onSaveFrom, + onClear: onClearFrom, + hintText: localization.searchPleaseSelectOrigin, + textLeadingImage: + mapConfiguratiom.markersConfiguration.fromMarker, + trailing: null, + value: mapRouteState.fromPlace, + ), + LocationFormField( + isOrigin: false, + onSaved: onSaveTo, + onClear: onClearTo, + hintText: localization.searchPleaseSelectDestination, + textLeadingImage: mapConfiguratiom.markersConfiguration.toMarker, + trailing: null, + value: mapRouteState.toPlace, + ), + ], + ), ), + if (mapRouteState.isPlacesDefined) + SwapButton( + orientation: Orientation.portrait, + onSwap: onSwap, + color: theme.appBarTheme.foregroundColor!, + ) ], ); }