import 'dart:async'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_material_pickers/flutter_material_pickers.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_place_picker/google_maps_place_picker.dart'; import 'package:provider/provider.dart'; import 'rrt-place-order.dart'; class RRTRequestPickupAddressPage extends StatefulWidget { final ServicePrice servicePrice; RRTRequestPickupAddressPage({@required this.servicePrice}); @override State createState() => RRTRequestPickupAddressPageState(); } class RRTRequestPickupAddressPageState extends State with SingleTickerProviderStateMixin { bool acceptTerms = false; bool mapIdle = true; Completer mapController = Completer(); CameraPosition mapCameraPosition = CameraPosition( target: LatLng(24.7114693, 46.67469582), zoom: 14.4746, ); List myAddresses = []; Addresses selectedAddress; StreamController addressStreamController = StreamController(); Stream addressStream; StreamController addressLoadingStreamController = StreamController(); Stream addressLoadingStream; @override void initState() { super.initState(); goToCurrentLocation(); addressStream = addressStreamController.stream; addressLoadingStream = addressLoadingStreamController.stream; } void loadAddresses() async { // GifLoaderDialogUtils.showMyDialog(context); myAddresses = await viewModel.getAddresses(); // GifLoaderDialogUtils.hideDialog(context); if (myAddresses.isNotEmpty) setState(() {}); } TranslationBase localize; RRTViewModel viewModel; @override Widget build(BuildContext context) { localize = TranslationBase.of(context); ProjectViewModel projectViewModel = Provider.of(context); addressStreamController.sink.add(0); return BaseView( onModelReady: (vm) { viewModel = vm; loadAddresses(); }, builder: (ctx, vm, widget) => AppScaffold( appBarTitle: localize.pickupLocation, isShowAppBar: true, showNewAppBar: true, showNewAppBarTitle: true, body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ StreamBuilder( stream: addressStream, builder: (context, snapshot) { return selectAddressField(); }), StreamBuilder( stream: addressLoadingStream, builder: (context, snapshot) { return snapshot.hasData ? LinearProgressIndicator(backgroundColor: Colors.transparent) : Container( height: 4, ); }), Expanded( child: PlacePicker( apiKey: GOOGLE_API_KEY, enableMyLocationButton: true, automaticallyImplyAppBarLeading: false, autocompleteOnTrailingWhitespace: true, selectInitialPosition: true, autocompleteLanguage: projectViewModel.currentLanguage, enableMapTypeButton: true, searchForInitialValue: false, selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { if (state == SearchingState.Idle) { addressLoadingStreamController.sink.add(null); if (selectedPlace != null) { var loc = selectedPlace.geometry.location; var address1 = selectedPlace.addressComponents.first.longName; var address2 = ""; if (selectedPlace.addressComponents.length > 1) address2 = selectedPlace.addressComponents[1].longName; selectedAddress = Addresses(latLong: '${loc.lat},${loc.lng}', address1: address1, address2: address2); addressStreamController.sink.add(0); } } else { addressLoadingStreamController.sink.add(0); } return Container(); }, initialPosition: LatLng(24.7114693, 46.67469582), useCurrentLocation: false, ), ), continueButton() ], ))); } Widget centerTargetPoint() { double size = mapIdle ? 20 : 30; double margin = mapIdle ? 3 : 10; return Center( child: Container( width: size, height: size, decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), border: Border.all(width: 2, color: Theme.of(context).appBarTheme.color)), child: Container(margin: EdgeInsets.all(margin), decoration: BoxDecoration(color: Theme.of(context).appBarTheme.color, borderRadius: BorderRadius.circular(20))), ), ); } Widget selectAddressField() { var text = selectedAddress == null ? localize.selectAddress : selectedAddress.toString(); return Container( margin: EdgeInsets.all(10), height: 50, child: MaterialButton( height: 50, color: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), onPressed: openAddressSelectDialog, child: Row( children: [ Expanded(child: Text(text, style: TextStyle(color: Colors.grey, fontSize: 13, letterSpacing: 1))), Icon( Icons.keyboard_arrow_down, size: 20, color: Colors.grey, ) ], ), ), ); } Widget continueButton() { return Padding( padding: const EdgeInsets.all(15), child: DefaultButton(TranslationBase.of(context).continues, () { Navigator.push( context, FadePage( page: RRTPlaceOrderPage( selectedAddress: selectedAddress, servicePrice: widget.servicePrice, ))); }), ); } openAddressSelectDialog() { showMaterialResponsiveDialog( hideButtons: true, context: context, title: localize.selectAddress, child: ListView.separated( shrinkWrap: true, padding: EdgeInsets.all(10), itemCount: myAddresses.length, itemBuilder: (ctx, idx) { var itm = myAddresses[idx]; return ListTile( title: Text(itm.toString()), onTap: () { setState(() { selectedAddress = itm; Navigator.pop(context); if (itm.latLong != null && itm.latLong.isNotEmpty && itm.latLong.split(',').length > 1) { var cordinates = itm.latLong.split(','); var latlng = LatLng(double.parse(cordinates.first), double.parse(cordinates.last)); moveToLocation(latlng); } else { AppToast.showErrorToast(message: 'Invalid address coordinates'); } }); }, ); }, separatorBuilder: (ctx, idx) => Container( height: 0.25, color: Colors.grey.withOpacity(0.7), ))); } moveToLocation(LatLng location, {bool animate = true}) async { await Future.delayed(Duration(milliseconds: 200)); mapCameraPosition = CameraPosition( target: location, zoom: 16.4746, ); if (animate) (await mapController.future).animateCamera( CameraUpdate.newCameraPosition(mapCameraPosition), ); else (await mapController.future).moveCamera( CameraUpdate.newCameraPosition(mapCameraPosition), ); } goToCurrentLocation() async { var location = await Geolocator.getLastKnownPosition(); if (location == null) { Geolocator.getCurrentPosition().then((value) { moveToLocation(LatLng(value.latitude, value.longitude)); }); return; } moveToLocation(LatLng(location.latitude, location.longitude), animate: false); } }