diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 435e0177..516dace6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,13 +1,9 @@ - - + + NSAllowsArbitraryLoads + NSLocationWhenInUseUsageDescription + diff --git a/lib/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart b/lib/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart index c8aef3fa..dcad0306 100644 --- a/lib/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart +++ b/lib/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart @@ -64,4 +64,14 @@ class RegistrationCubit extends Cubit { rethrow; } } + + Future> getLocationsByCoordinates(String latitude, String longitude) async { + try { + final location = (await registrationRepository.getLocationsListByCoordinates(latitude, longitude)); + emit(RegistrationState(sheet: state.sheet.copyWith(responseBody: location.responseBody))); + return location.locations; + } catch (e) { + rethrow; + } + } } diff --git a/lib/features/registration/presentation/pages/city_of_living_screen.dart b/lib/features/registration/presentation/pages/city_of_living_screen.dart index 0a3dd291..808c0ccc 100644 --- a/lib/features/registration/presentation/pages/city_of_living_screen.dart +++ b/lib/features/registration/presentation/pages/city_of_living_screen.dart @@ -2,8 +2,10 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart'; import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart'; +import 'package:location/location.dart'; class CityOfLivingScreen extends StatefulWidget { final UserRegistrationSheet sheet; @@ -21,6 +23,8 @@ class _CityOfLivingScreenState extends State { late SelectionPopupModel selectedItem; final cityController = TextEditingController(); + final suggestionsController = SuggestionsController(); + bool isLoading = false; @override void initState() { @@ -30,6 +34,34 @@ class _CityOfLivingScreenState extends State { } } + Future getLocationData() async { + Location location = new Location(); + + bool _serviceEnabled; + PermissionStatus _permissionGranted; + LocationData _locationData; + + _serviceEnabled = await location.serviceEnabled(); + if (!_serviceEnabled) { + _serviceEnabled = await location.requestService(); + if (!_serviceEnabled) { + return null; + } + } + + _permissionGranted = await location.hasPermission(); + if (_permissionGranted == PermissionStatus.denied) { + _permissionGranted = await location.requestPermission(); + if (_permissionGranted != PermissionStatus.granted) { + return null; + } + } + + _locationData = await location.getLocation(); + + return _locationData; + } + @override Widget build(BuildContext context) { return SingleChildScrollView( @@ -39,43 +71,89 @@ class _CityOfLivingScreenState extends State { children: [ Text("Местоположение"), SizedBox(height: 4), - TypeAheadField( - debounceDuration: Duration(milliseconds: 300), - controller: cityController, - builder: (context, controller, focus) => CustomTextFormField( - controller: cityController, - focusNode: focus, - autofocus: true, - textStyle: TextStyle( - fontSize: 16, - color: Colors.black, - )), - itemBuilder: (BuildContext context, String item) { - return Padding( - padding: const EdgeInsets.all(8.0), - child: Text(item, style: theme.textTheme.bodyLarge?.copyWith(color: Colors.black)), - ); - }, - decorationBuilder: (context, child) => Material( - type: MaterialType.card, - elevation: 4, - borderRadius: BorderRadius.circular(8), - child: child, - ), - onSelected: (item) { - setState(() { - cityController.text = item; - }); - final registrationCubit = context.read(); - registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(location: item)); - }, - suggestionsCallback: (query) async { - if (query.length >= 3) { - final registrationCubit = context.read(); - return (await registrationCubit.getLocationsByQuery(query)); - } - return null; - }, + Row( + children: [ + SizedBox( + width: MediaQuery.of(context).size.width - 80, + child: TypeAheadField( + debounceDuration: Duration(milliseconds: 300), + controller: cityController, + suggestionsController: suggestionsController, + builder: (context, controller, focus) => CustomTextFormField( + controller: cityController, + focusNode: focus, + autofocus: true, + textStyle: TextStyle( + fontSize: 16, + color: Colors.black, + )), + itemBuilder: (BuildContext context, String item) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Text(item, style: theme.textTheme.bodyLarge?.copyWith(color: Colors.black)), + ); + }, + decorationBuilder: (context, child) => Material( + type: MaterialType.card, + elevation: 4, + borderRadius: BorderRadius.circular(8), + child: child, + ), + onSelected: (item) { + setState(() { + cityController.text = item; + }); + final registrationCubit = context.read(); + registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(location: item)); + }, + suggestionsCallback: (query) async { + if (query.length >= 3) { + final registrationCubit = context.read(); + return (await registrationCubit.getLocationsByQuery(query)); + } + return null; + }, + ), + ), + SizedBox(width: 8), + InkWell( + borderRadius: BorderRadius.circular(8), + onTap: !isLoading + ? () async { + setState(() { + isLoading = true; + }); + final LocationData? locationData = await getLocationData(); + if (locationData != null) { + final List locations = await context + .read() + .getLocationsByCoordinates(locationData.latitude.toString(), locationData.longitude.toString()); + setState(() { + cityController.text = locations.first; + suggestionsController.suggestions = locations; + }); + } + setState(() { + isLoading = false; + }); + } + : null, + child: Ink( + height: 40, + width: 40, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Color(0xFFEAF2FD), + ), + child: !isLoading + ? Icon( + Icons.near_me_rounded, + color: appTheme.blueA400, + ) + : CupertinoActivityIndicator(), + ), + ), + ], ), ], ), diff --git a/lib/features/registration/repositories/registration_repository.dart b/lib/features/registration/repositories/registration_repository.dart index a96a32f3..d609ee12 100644 --- a/lib/features/registration/repositories/registration_repository.dart +++ b/lib/features/registration/repositories/registration_repository.dart @@ -22,4 +22,12 @@ class RegistrationRepository { rethrow; } } + + Future getLocationsListByCoordinates(String latitude, String longitude) async { + try { + return (await registrationService.getLocationsByCoordinate(latitude: latitude, longitude: longitude)); + } catch (e) { + rethrow; + } + } } diff --git a/lib/features/registration/services/registration_service.dart b/lib/features/registration/services/registration_service.dart index 08a23a0e..200c2f6f 100644 --- a/lib/features/registration/services/registration_service.dart +++ b/lib/features/registration/services/registration_service.dart @@ -18,7 +18,7 @@ abstract class RegistrationService { @Query('user_address') required String query, }); - @GET('/api/api/location_by_coordinate') + @GET('/api/location_by_coordinate') Future getLocationsByCoordinate({ @Query('coordinate[position][latitude]') required String latitude, @Query('coordinate[position][longitude]') required String longitude, diff --git a/lib/features/registration/services/registration_service.g.dart b/lib/features/registration/services/registration_service.g.dart index 9cd29f32..9820fd33 100644 --- a/lib/features/registration/services/registration_service.g.dart +++ b/lib/features/registration/services/registration_service.g.dart @@ -94,7 +94,7 @@ class _RegistrationService implements RegistrationService { ) .compose( _dio.options, - '/api/api/location_by_coordinate', + '/api/location_by_coordinate', queryParameters: queryParameters, data: _data, ) diff --git a/pubspec.yaml b/pubspec.yaml index 2cdbe598..110e8fca 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: lazy_load_scrollview: ^1.3.0 badges: ^3.1.2 google_fonts: ^6.2.1 + location: ^7.0.0 dev_dependencies: build_runner: ^2.4.11