import 'dart:async'; import 'dart:convert'; import 'dart:math' show cos; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_polyline_algorithm/google_polyline_algorithm.dart'; import 'package:location/location.dart'; import 'package:ride/constant/colors.dart'; import 'package:ride/constant/style.dart'; import 'package:ride/views/home/map_page_passenger.dart'; import 'package:ride/views/home/map_widget.dart/form_serch_multiy_point.dart'; import '../../constant/api_key.dart'; import '../../constant/box_name.dart'; import '../../constant/info.dart'; import '../../constant/links.dart'; import '../../main.dart'; import '../../models/model/locations.dart'; import '../../views/Rate/rate_captain.dart'; import '../../views/widgets/elevated_btn.dart'; import '../firebase/firbase_messge.dart'; import '../functions/crud.dart'; import '../functions/launch.dart'; import '../functions/secure_storage.dart'; import '../payment/payment_controller.dart'; class MapPassengerController extends GetxController { bool isLoading = true; TextEditingController placeDestinationController = TextEditingController(); TextEditingController placeStartController = TextEditingController(); TextEditingController wayPoint0Controller = TextEditingController(); TextEditingController wayPoint1Controller = TextEditingController(); TextEditingController wayPoint2Controller = TextEditingController(); TextEditingController wayPoint3Controller = TextEditingController(); TextEditingController wayPoint4Controller = TextEditingController(); TextEditingController sosPhonePassengerProfile = TextEditingController(); final sosFormKey = GlobalKey(); List data = []; List bounds = []; List placesStart = []; List allTextEditingPlaces = []; List placesDestination = []; List wayPoint0 = []; List wayPoint1 = []; List wayPoint2 = []; List wayPoint3 = []; List wayPoint4 = []; List> placeListResponseAll = []; List placeListResponse = [ formSearchPlaces1(), formSearchPlaces2(), formSearchPlaces3(), formSearchPlaces4(), ]; LatLngBounds? boundsdata; List markers = []; List polyLines = []; late LatLng myLocation; late LatLng newMyLocation = const LatLng(32.115295, 36.064773); late LatLng newStartPointLocation = const LatLng(32.115295, 36.064773); late LatLng newPointLocation0 = const LatLng(32.115295, 36.064773); late LatLng newPointLocation1 = const LatLng(32.115295, 36.064773); late LatLng newPointLocation2 = const LatLng(32.115295, 36.064773); late LatLng newPointLocation3 = const LatLng(32.115295, 36.064773); late LatLng newPointLocation4 = const LatLng(32.115295, 36.064773); LatLng myDestination = const LatLng(32.115295, 36.064773); final List polylineCoordinates = []; List carsLocationByPassenger = []; List driverCarsLocationToPassengerAfterApplied = []; BitmapDescriptor markerIcon = BitmapDescriptor.defaultMarker; BitmapDescriptor tripIcon = BitmapDescriptor.defaultMarker; BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker; double height = 150; DateTime currentTime = DateTime.now(); final location = Location(); late LocationData currentLocation; double heightMenu = 0; double widthMenu = 0; double heightPickerContainer = 90; double heightPointsPageForRider = 0; double mainBottomMenuMapHeight = Get.height * .2; double wayPointSheetHeight = 0; bool startLocationFromMap = false; bool startLocationFromMap0 = false; bool startLocationFromMap1 = false; bool startLocationFromMap2 = false; bool startLocationFromMap3 = false; bool startLocationFromMap4 = false; bool heightMenuBool = false; bool isPickerShown = false; bool isPointsPageForRider = false; bool isBottomSheetShown = false; bool mapType = false; bool mapTrafficON = false; bool isCancelRidePageShown = false; bool isCashConfirmPageShown = false; bool isPaymentMethodPageShown = false; bool isRideFinished = false; bool rideConfirm = false; bool isMainBottomMenuMap = true; bool isWayPointSheet = false; double heightBottomSheetShown = 0; double cashConfirmPageShown = 250; late String driverId; double widthMapTypeAndTraffic = 50; double paymentPageShown = Get.height * .6; late LatLng southwest; late LatLng northeast; List carLocations = []; var dataCarsLocationByPassenger; var datadriverCarsLocationToPassengerAfterApplied; CarLocation? nearestCar; late Timer markerReloadingTimer; bool shouldFetch = true; // Flag to determine if fetch should be executed int selectedPassengerCount = 1; double progress = 0; double progressTimerToPassengerFromDriverAfterApplied = 0; int durationTimer = 25; late int durationToRide; int remainingTime = 25; int remainingTimeToPassengerFromDriverAfterApplied = 60; int timeToPassengerFromDriverAfterApplied = 0; Timer? timerToPassengerFromDriverAfterApplied; bool rideTimerBegin = false; double progressTimerRideBegin = 0; int remainingTimeTimerRideBegin = 60; String stringRemainingTimeRideBegin = ''; String hintTextStartPoint = 'Search for your Start point'.tr; String hintTextwayPoint0 = 'Search for waypoint'.tr; String hintTextwayPoint1 = 'Search for waypoint'.tr; String hintTextwayPoint2 = 'Search for waypoint'.tr; String hintTextwayPoint3 = 'Search for waypoint'.tr; String hintTextwayPoint4 = 'Search for waypoint'.tr; String currentLocationString = 'Current Location'.tr; String currentLocationString0 = 'Current Location'.tr; String currentLocationString1 = 'Current Location 1'.tr; String currentLocationString2 = 'Current Location 2'.tr; String currentLocationString3 = 'Current Location 3'.tr; String currentLocationString4 = 'Current Location 4'.tr; List currentLocationStringAll = []; String hintTextDestinationPoint = 'Search for your destination'.tr; late String rideId; bool noCarString = false; bool isCashSelectedBeforeConfirmRide = false; bool isPassengerChosen = false; bool currentLocationToFormPlaces = false; bool currentLocationToFormPlaces0 = false; bool currentLocationToFormPlaces1 = false; bool currentLocationToFormPlaces2 = false; bool currentLocationToFormPlaces3 = false; bool currentLocationToFormPlaces4 = false; late String driverToken; int carsOrder = 0; String? mapAPIKEY; late double totalME = 0; late double tax = 0; late double totalPassenger = 0; late double totalDriver = 0; late double averageDuration = 0; late double costDuration = 0; late double cost = 0; late double distance = 0; late double duration = 0; late Duration durationToAdd; late DateTime newTime = DateTime.now(); void onChangedPassengerCount(int newValue) { selectedPassengerCount = newValue; update(); } void onChangedPassengersChoose() { isPassengerChosen = true; update(); } void getCurrentLocationFormString() async { currentLocationToFormPlaces = true; currentLocationString = 'Waiting for your location'.tr; await getLocation(); currentLocationString = myLocation.toString(); newStartPointLocation = myLocation; update(); } void convertHintTextStartNewPlaces(int index) { if (placesStart.isEmpty) { hintTextStartPoint = 'Search for your Start point'.tr; update(); } else { hintTextStartPoint = placesStart[index]['name']; double lat = placesStart[index]['geometry']['location']['lat']; double lng = placesStart[index]['geometry']['location']['lng']; newStartPointLocation = LatLng(lat, lng); update(); } } void convertHintTextPlaces0(int index) { if (wayPoint0.isEmpty) { hintTextwayPoint0 = 'Search for your Start point'.tr; update(); } else { hintTextwayPoint0 = wayPoint0[index]['name']; currentLocationString0 = wayPoint1[index]['name']; double lat = wayPoint0[index]['geometry']['location']['lat']; double lng = wayPoint0[index]['geometry']['location']['lng']; newPointLocation0 = LatLng(lat, lng); update(); } } void convertHintTextPlaces1(int index) { if (wayPoint1.isEmpty) { hintTextwayPoint1 = 'Search for your Start point'.tr; update(); } else { hintTextwayPoint1 = wayPoint1[index]['name']; currentLocationString1 = wayPoint1[index]['name']; double lat = wayPoint1[index]['geometry']['location']['lat']; double lng = wayPoint1[index]['geometry']['location']['lng']; newPointLocation1 = LatLng(lat, lng); update(); } } void convertHintTextPlaces2(int index) { if (wayPoint1.isEmpty) { hintTextwayPoint2 = 'Search for your Start point'.tr; update(); } else { hintTextwayPoint2 = wayPoint2[index]['name']; currentLocationString2 = wayPoint1[index]['name']; double lat = wayPoint2[index]['geometry']['location']['lat']; double lng = wayPoint2[index]['geometry']['location']['lng']; newPointLocation2 = LatLng(lat, lng); update(); } } void convertHintTextPlaces3(int index) { if (wayPoint1.isEmpty) { hintTextwayPoint3 = 'Search for your Start point'.tr; update(); } else { hintTextwayPoint3 = wayPoint3[index]['name']; currentLocationString3 = wayPoint1[index]['name']; double lat = wayPoint3[index]['geometry']['location']['lat']; double lng = wayPoint3[index]['geometry']['location']['lng']; newPointLocation3 = LatLng(lat, lng); update(); } } void convertHintTextPlaces4(int index) { if (wayPoint1.isEmpty) { hintTextwayPoint4 = 'Search for your Start point'.tr; update(); } else { hintTextwayPoint4 = wayPoint4[index]['name']; currentLocationString4 = wayPoint1[index]['name']; double lat = wayPoint4[index]['geometry']['location']['lat']; double lng = wayPoint4[index]['geometry']['location']['lng']; newPointLocation4 = LatLng(lat, lng); update(); } } void convertHintTextDestinationNewPlaces(int index) { if (placesDestination.isEmpty) { hintTextDestinationPoint = 'Search for your destination'.tr; update(); } else { hintTextDestinationPoint = placesDestination[index]['name']; double lat = placesDestination[index]['geometry']['location']['lat']; double lng = placesDestination[index]['geometry']['location']['lng']; newMyLocation = LatLng(lat, lng); update(); } } // final mainBottomMenuMap = GlobalKey(); void changeBottomSheetShown() { isBottomSheetShown = !isBottomSheetShown; heightBottomSheetShown = isBottomSheetShown == true ? 250 : 0; update(); } void changeCashConfirmPageShown() { isCashConfirmPageShown = !isCashConfirmPageShown; isCashSelectedBeforeConfirmRide = true; cashConfirmPageShown = isCashConfirmPageShown == true ? 250 : 0; update(); } void changePaymentMethodPageShown() { isPaymentMethodPageShown = !isPaymentMethodPageShown; paymentPageShown = isPaymentMethodPageShown == true ? Get.height * .6 : 0; update(); } void changeMapType() { mapType = !mapType; // heightButtomSheetShown = isButtomSheetShown == true ? 240 : 0; update(); } void changeMapTraffic() { mapTrafficON = !mapTrafficON; update(); } void sendSMS(String to) async { // Get the driver's phone number. String driverPhone = dataCarsLocationByPassenger['message'][carsOrder]['phone'].toString(); // Format the message. String message = 'Hi! This is ${box.read(BoxName.name)}. I am using ${box.read(AppInformation.appName)} to ride with ${dataCarsLocationByPassenger['message'][carsOrder]['first_name'].toString()} as the driver. ${dataCarsLocationByPassenger['message'][carsOrder]['first_name'].toString()} is driving a ${dataCarsLocationByPassenger['message'][carsOrder]['model'].toString()} with license plate ${dataCarsLocationByPassenger['message'][carsOrder]['license_plate'].toString()}. I am currently located at $myLocation. If you need to reach me, please contact the driver directly at $driverPhone.'; // Launch the URL to send the SMS. launchCommunication('sms', to, message); } void sendWhatsapp(String to) async { // Get the driver's phone number. String driverPhone = dataCarsLocationByPassenger['message'][carsOrder]['phone'].toString(); // Format the message. String message = 'Hi! This is ${box.read(BoxName.name)}.\n I am using ${box.read(AppInformation.appName)} to ride with ${dataCarsLocationByPassenger['message'][carsOrder]['first_name'].toString()} as the driver. ${dataCarsLocationByPassenger['message'][carsOrder]['first_name'].toString()} \nis driving a ${dataCarsLocationByPassenger['message'][carsOrder]['model'].toString()}\n with license plate ${dataCarsLocationByPassenger['message'][carsOrder]['license_plate'].toString()}.\n I am currently located at $myLocation.\n If you need to reach me, please contact the driver directly at\n\n $driverPhone.'; // Launch the URL to send the SMS. launchCommunication('whatsapp', to, message); } void changeCancelRidePageShow() { // rideConfirm == true // ? isCancelRidePageShown = !isCancelRidePageShown; // : cancelRide(); update(); } void getDrawerMenu() { heightMenuBool = !heightMenuBool; widthMapTypeAndTraffic = heightMenuBool == true ? 0 : 50; heightMenu = heightMenuBool == true ? 100 : 0; widthMenu = heightMenuBool == true ? 110 : 0; update(); } String stringRemainingTimeToPassenger = ''; void startTimerToPassengerFromDriverAfterApplied() async { for (int i = 0; i <= timeToPassengerFromDriverAfterApplied; i++) { await Future.delayed(const Duration(seconds: 1)); progressTimerToPassengerFromDriverAfterApplied = i / timeToPassengerFromDriverAfterApplied; remainingTimeToPassengerFromDriverAfterApplied = timeToPassengerFromDriverAfterApplied - i; if (remainingTimeToPassengerFromDriverAfterApplied < 69) { if (rideTimerBegin == false) { getBeginRideFromDriver(); } } int minutes = (remainingTimeToPassengerFromDriverAfterApplied / 60).floor(); int seconds = remainingTimeToPassengerFromDriverAfterApplied % 60; stringRemainingTimeToPassenger = '$minutes:${seconds.toString().padLeft(2, '0')}'; update(); } } void rideIsBeginPassengerTimer() async { for (int i = 0; i <= durationToRide; i++) { await Future.delayed(const Duration(seconds: 1)); progressTimerRideBegin = i / durationToRide; remainingTimeTimerRideBegin = durationToRide - i; int minutes = (remainingTimeTimerRideBegin / 60).floor(); int seconds = remainingTimeTimerRideBegin % 60; stringRemainingTimeRideBegin = '$minutes:${seconds.toString().padLeft(2, '0')}'; update(); } rideTimerBegin = false; isRideFinished = true; update(); print('rideTimerBegin: $rideTimerBegin'); print('isRideFinished: $isRideFinished'); await CRUD().post(link: AppLink.addPassengersWallet, payload: { 'passenger_id': box.read(BoxName.passengerID).toString(), 'balance': ((-1) * totalPassenger).toString() }); Get.to(() => RateCaptainFromPassenger(), arguments: { 'driverId': driverId.toString(), 'rideId': rideId.toString(), }); } void getBeginRideFromDriver() async { var res = await CRUD() .get(link: AppLink.getRideStatusBegin, payload: {'ride_id': rideId}); var decode = jsonDecode(res); if (decode['data']['status'] == 'Begin') { timeToPassengerFromDriverAfterApplied = 0; remainingTime = 0; remainingTimeToPassengerFromDriverAfterApplied = 0; // isCancelRidePageShown = true; rideIsBeginPassengerTimer(); // print('rideTimerBegin: $rideTimerBegin'); rideTimerBegin = true; update(); } } void driverArrivePassenger() { timeToPassengerFromDriverAfterApplied = 0; remainingTime = 0; // isCancelRidePageShown = true; update(); rideIsBeginPassengerTimer(); } void cancelTimerToPassengerFromDriverAfterApplied() { timerToPassengerFromDriverAfterApplied?.cancel(); } void clearPlacesDestination() { placesDestination = []; hintTextDestinationPoint = 'Search for your destination'.tr; update(); } void clearPlacesStart() { placesStart = []; hintTextStartPoint = 'Search for your Start point'.tr; update(); } void clearPlaces0() { wayPoint0 = []; hintTextwayPoint0 = 'Search for waypoint'.tr; update(); } void clearPlaces1() { wayPoint1 = []; hintTextwayPoint1 = 'Search for waypoint'.tr; update(); } void clearPlaces2() { wayPoint2 = []; hintTextwayPoint2 = 'Search for waypoint'.tr; update(); } void clearPlaces3() { wayPoint3 = []; hintTextwayPoint3 = 'Search for waypoint'.tr; update(); } void clearPlaces4() { wayPoint4 = []; hintTextwayPoint4 = 'Search for waypoint'.tr; update(); } int selectedReason = -1; String? cancelNote; void selectReason(int index, String note) { selectedReason = index; cancelNote = note; update(); } changeConfirmRide() async { if (dataCarsLocationByPassenger != 'failure') { driverToken = dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(); PaymentController paymentController = Get.find(); rideConfirm = true; shouldFetch = true; isBottomSheetShown = false; timeToPassengerFromDriverAfterApplied = 60; update(); // print('rideConfirm= $rideConfirm'); await getCarsLocationByPassenger(); await CRUD().post(link: AppLink.addRides, payload: { "start_location": //'${data[0]['start_address']}', '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}', "end_location": //'${data[0]['end_address']}', '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}', "date": DateTime.now().toString(), "time": DateTime.now().toString(), "endtime": durationToAdd.toString(), "price": totalPassenger.toString(), "passenger_id": box.read(BoxName.passengerID).toString(), "driver_id": dataCarsLocationByPassenger['message'][carsOrder] ['driver_id'] .toString(), "status": "waiting", "price_for_driver": totalPassenger.toString(), "price_for_passenger": totalME.toString(), "distance": distance.toString() }).then((value) { // print(jsonDecode(value)['message']); // List body = [ rideId = jsonDecode(value)['message']; List body = [ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}', '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}', totalPassenger.toString(), totalDriver.toString(), duration.toString(), distance.toString(), dataCarsLocationByPassenger['message'][carsOrder]['driver_id'] .toString(), box.read(BoxName.passengerID).toString(), box.read(BoxName.name).toString(), box.read(BoxName.tokenFCM).toString(), box.read(BoxName.phone).toString(), durationByPassenger.toString(), distanceByPassenger.toString(), paymentController.isWalletChecked.toString(), dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(), duration1.toString(), rideId, rideTimerBegin.toString(), dataCarsLocationByPassenger['message'][carsOrder]['driver_id'] .toString(), durationToRide.toString() ]; FirebaseMessagesController().sendNotificationToDriverMAP( 'Order', jsonDecode(value)['message'].toString(), dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(), body, ); // print(dataCarsLocationByPassenger); // print(dataCarsLocationByPassenger['message'][0]['token'].toString()); }); delayAndFetchRideStatus(rideId); if (shouldFetch == false) { startTimer(); update(); } update(); } else { Get.defaultDialog( title: 'No Car or Driver Found in your area.'.tr, titleStyle: AppStyle.title, middleText: 'Please Try anther time '.tr, middleTextStyle: AppStyle.title.copyWith(color: AppColor.yellowColor), confirm: MyElevatedButton(title: 'Ok'.tr, onPressed: () => Get.back())); } } void delayAndFetchRideStatus(String rideId) { Timer(const Duration(milliseconds: 200), () async { if (shouldFetch) { // print('shouldFetch is =$shouldFetch'); var res = await CRUD() .get(link: AppLink.getRideStatus, payload: {'order_id': rideId}); var decod = jsonDecode(res); print(' 0000000000000000000000000000000000000000000000000'); print(decod['data']); if (decod['data'].toString() == 'Apply') { shouldFetch = false; // Stop further fetches rideConfirm = false; update(); startTimer(); } else if (decod['data'].toString() == 'Refused') { carsOrder = carsOrder + 1; update(); print(dataCarsLocationByPassenger['message'].length); print(dataCarsLocationByPassenger['message']); print(carsOrder); if (carsOrder < dataCarsLocationByPassenger['message'].length) { print('55555555555555555555'); changeConfirmRide(); } else { Get.defaultDialog( title: 'There no Driver Aplly your order sorry for that '.tr, middleText: 'try next time .', confirm: MyElevatedButton( title: 'Back', onPressed: () => Get.offAll(const MapPagePassenger()), )); cancelRideAfterRejectFromAll(); } } else { delayAndFetchRideStatus( rideId); // Repeat the delay and fetch operation update(); } } }); } void startTimer() async { for (int i = 0; i <= durationTimer; i++) { await Future.delayed(const Duration(seconds: 1)); progress = i / durationTimer; remainingTime = durationTimer - i; if (remainingTime == 0) { rideConfirm = false; // print(timeToPassengerFromDriverAfterApplied); timeToPassengerFromDriverAfterApplied += duration1; // print(duration1); // print('timeToPassengerFromDriverAfterApplied====' + // timeToPassengerFromDriverAfterApplied.toString()); startTimerToPassengerFromDriverAfterApplied(); update(); } update(); } timerEnded(); } void timerEnded() async { print('Timer ended'); runEvery30SecondsUntilConditionMet(); isCancelRidePageShown = false; update(); } Future getRideStatus(int rideId) async { final response = await CRUD() .get(link: AppLink.getRideStatus, payload: {'order_id': rideId}); return response['status']; } Future getCarsLocationByPassenger() async { // if (rideConfirm == false) { carsLocationByPassenger = []; LatLngBounds bounds = calculateBounds(myLocation.latitude, myLocation.longitude, 8000); print( 'Southwest: ${bounds.southwest.latitude}, ${bounds.southwest.longitude}'); print( 'Northeast: ${bounds.northeast.latitude}, ${bounds.northeast.longitude}'); var res = await CRUD().get(link: AppLink.getCarsLocationByPassenger, payload: { 'southwestLat': bounds.southwest.latitude.toString(), 'southwestLon': bounds.southwest.longitude.toString(), 'northeastLat': bounds.northeast.latitude.toString(), 'northeastLon': bounds.northeast.longitude.toString(), }); if (res == 'failure') { noCarString = true; dataCarsLocationByPassenger = res; update(); } else { noCarString = false; dataCarsLocationByPassenger = jsonDecode(res); print(dataCarsLocationByPassenger); // if (dataCarsLocationByPassenger.length > carsOrder) { driverId = dataCarsLocationByPassenger['message'][carsOrder]['driver_id'] .toString(); // } // print('driverId==============$driverId'); for (var i = 0; i < dataCarsLocationByPassenger['message'].length; i++) { carsLocationByPassenger.add(LatLng( double.parse(dataCarsLocationByPassenger['message'][i]['latitude']), double.parse( dataCarsLocationByPassenger['message'][i]['longitude']))); update(); } update(); // } } } Future getDriverCarsLocationToPassengerAfterApplied() async { driverCarsLocationToPassengerAfterApplied = []; var res = await CRUD().get( link: AppLink.getDriverCarsLocationToPassengerAfterApplied, payload: { 'driver_id': dataCarsLocationByPassenger['message'][carsOrder] ['driver_id'] }); datadriverCarsLocationToPassengerAfterApplied = jsonDecode(res); driverCarsLocationToPassengerAfterApplied.add(LatLng( double.parse(datadriverCarsLocationToPassengerAfterApplied['message'] [carsOrder]['latitude']), double.parse(datadriverCarsLocationToPassengerAfterApplied['message'] [carsOrder]['longitude']))); update(); } Future runEvery30SecondsUntilConditionMet() async { // Calculate the duration of the trip in minutes. double tripDurationInMinutes = duration1 / 20; int loopCount = tripDurationInMinutes.ceil(); // If the trip duration is less than or equal to 50 minutes, then break the loop. for (var i = 0; i < loopCount; i++) { // Wait for 50 seconds. await Future.delayed(const Duration( seconds: 31)); // Run the `getDriverCarsLocationToPassengerAfterApplied()` function. await getDriverCarsLocationToPassengerAfterApplied(); reloadMarkerDriverCarsLocationToPassengerAfterApplied(); } } void reloadMarkerDriverCarsLocationToPassengerAfterApplied() { // Clear existing markers markers.clear(); update(); for (var i = 0; i < driverCarsLocationToPassengerAfterApplied.length; i++) { // } // for (var item in driverCarsLocationToPassengerAfterApplied) { final marker = Marker( infoWindow: InfoWindow( title: '${driverCarsLocationToPassengerAfterApplied[i].latitude} minutes'), markerId: MarkerId( datadriverCarsLocationToPassengerAfterApplied['message'][0]['id'] .toString()), position: LatLng(driverCarsLocationToPassengerAfterApplied[i].latitude, driverCarsLocationToPassengerAfterApplied[i].longitude), ); markers.add(marker); update(); mapController?.animateCamera(CameraUpdate.newLatLng(LatLng( driverCarsLocationToPassengerAfterApplied[i].latitude, driverCarsLocationToPassengerAfterApplied[i].longitude))); update(); } // Update the map with the new markers } restCounter() { clearPlacesDestination(); clearPolyline(); data = []; rideConfirm = false; shouldFetch = false; timeToPassengerFromDriverAfterApplied = 0; update(); } Future cancelRideAfterRejectFromAll() async { clearPlacesDestination(); clearPolyline(); data = []; await CRUD().post(link: AppLink.updateDriverOrder, payload: { "order_id": rideId.toString(), // Convert to String "status": 'Cancel' }); rideConfirm = false; shouldFetch = false; isPassengerChosen = false; isCashConfirmPageShown = false; isCashSelectedBeforeConfirmRide = false; timeToPassengerFromDriverAfterApplied = 0; changeCancelRidePageShow(); remainingTime = 0; update(); } Future cancelRide() async { print("rideConfirm=$rideConfirm"); if (rideConfirm == false) { clearPlacesDestination(); clearPolyline(); data = []; changeCancelRidePageShow(); rideConfirm = false; shouldFetch = false; isCashConfirmPageShown = false; isPassengerChosen = false; isCashSelectedBeforeConfirmRide = false; isPickerShown = false; timeToPassengerFromDriverAfterApplied = 0; update(); } else { clearPlacesDestination(); clearPolyline(); data = []; await CRUD().post(link: AppLink.updateDriverOrder, payload: { "order_id": rideId.toString(), // Convert to String "status": 'Cancel' }); isPickerShown = false; rideConfirm = false; shouldFetch = false; isPassengerChosen = false; isCashConfirmPageShown = false; isCashSelectedBeforeConfirmRide = false; timeToPassengerFromDriverAfterApplied = 0; changeCancelRidePageShow(); remainingTime = 0; update(); } } void changePickerShown() { isPickerShown = !isPickerShown; heightPickerContainer = isPickerShown == true ? 150 : 90; update(); } void changeHeightPointsPageForRider() { isPointsPageForRider = !isPointsPageForRider; heightPointsPageForRider = isPointsPageForRider == true ? Get.height : 0; update(); } void changeMainBottomMenuMap() { isMainBottomMenuMap = !isMainBottomMenuMap; mainBottomMenuMapHeight = isMainBottomMenuMap == true ? Get.height * .2 : Get.height * .7; if (heightMenuBool == true) { getDrawerMenu(); } update(); } void changeWayPointSheet() { isWayPointSheet = !isWayPointSheet; wayPointSheetHeight = isWayPointSheet == false ? 0 : Get.height * .7; // if (heightMenuBool == true) { // getDrawerMenu(); // } update(); } changeHeightPlaces() { if (placesDestination.isEmpty) { height = 0; update(); } height = 150; update(); } changeHeightStartPlaces() { if (placesStart.isEmpty) { height = 0; update(); } height = 150; update(); } changeHeightPlaces0() { if (wayPoint0.isEmpty) { height = 0; update(); } height = 150; update(); } changeHeightPlaces1() { if (wayPoint1.isEmpty) { height = 0; update(); } height = 150; update(); } changeHeightPlaces2() { if (wayPoint2.isEmpty) { height = 0; update(); } height = 150; update(); } changeHeightPlaces3() { if (wayPoint3.isEmpty) { height = 0; update(); } height = 150; update(); } changeHeightPlaces4() { if (wayPoint4.isEmpty) { height = 0; update(); } height = 150; update(); } hidePlaces() { height = 0; update(); } Future getPlaces() async { var url = // '${AppLink.googleMapsLink}place/nearbysearch/json?location=${mylocation.longitude}&radius=25000&language=ar&keyword=&key=${placeController.text}${AK.mapAPIKEY}'; '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${placeDestinationController.text}&location=${myLocation.latitude},${myLocation.longitude}&radius=50000&language=en&key=${AK.mapAPIKEY.toString()}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); placesDestination = response['results']; print(placesDestination); update(); } Future getPlacesStart() async { var url = // '${AppLink.googleMapsLink}place/nearbysearch/json?location=${mylocation.longitude}&radius=25000&language=ar&keyword=&key=${placeController.text}${AK.mapAPIKEY}'; '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${placeStartController.text}&location=${myLocation.latitude},${myLocation.longitude}&radius=50000&language=en&key=${AK.mapAPIKEY.toString()}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); placesStart = response['results']; print(placesStart); update(); } Future getPlacesListsWayPoint0() async { var url = '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint0Controller.text}&location=${myLocation.latitude},${myLocation.longitude}&radius=50000&language=en&key=${AK.mapAPIKEY.toString()}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); wayPoint0 = response['results']; print(wayPoint0); update(); } Future getPlacesListsWayPoint1() async { var url = '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint1Controller.text}&location=${myLocation.latitude},${myLocation.longitude}&radius=50000&language=en&key=${AK.mapAPIKEY.toString()}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); wayPoint1 = response['results']; print(wayPoint1); update(); } Future getPlacesListsWayPoint2() async { var url = '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint2Controller.text}&location=${myLocation.latitude},${myLocation.longitude}&radius=50000&language=en&key=${AK.mapAPIKEY.toString()}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); wayPoint2 = response['results']; print(wayPoint2); update(); } Future getPlacesListsWayPoint3() async { var url = '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint3Controller.text}&location=${myLocation.latitude},${myLocation.longitude}&radius=50000&language=en&key=${AK.mapAPIKEY.toString()}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); wayPoint3 = response['results']; print(wayPoint3); update(); } Future getPlacesListsWayPoint4() async { var url = '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint4Controller.text}&location=${myLocation.latitude},${myLocation.longitude}&radius=50000&language=en&key=${AK.mapAPIKEY.toString()}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); wayPoint4 = response['results']; print(wayPoint4); update(); } LatLng fromString(String location) { List parts = location.split(','); double lat = double.parse(parts[0]); double lng = double.parse(parts[1]); return LatLng(lat, lng); } void clearPolyline() { polyLines = []; polylineCoordinates.clear(); update(); } void addCustomPicker() { ImageConfiguration config = const ImageConfiguration( size: Size(20, 20), // scale: 1.0, ); BitmapDescriptor.fromAssetImage(config, 'assets/images/picker.png') .then((value) { markerIcon = value; update(); }); } void addCustomTripIcon() { ImageConfiguration config = ImageConfiguration( size: Size(Get.width * .6, Get.height * .6), ); BitmapDescriptor.fromAssetImage(config, 'assets/images/brand.png') .then((value) { tripIcon = value; update(); }); } void addCustomCarIcon() { ImageConfiguration config = ImageConfiguration( size: Size(Get.width * .6, Get.height * .6), // size: Size(20, 20), // scale: 1.0, ); BitmapDescriptor.fromAssetImage(config, 'assets/images/car.png') .then((value) { carIcon = value; update(); }); } Future getLocation() async { isLoading = true; update(); bool serviceEnabled; PermissionStatus permissionGranted; // Check if location services are enabled serviceEnabled = await location.serviceEnabled(); if (!serviceEnabled) { serviceEnabled = await location.requestService(); if (!serviceEnabled) { // Location services are still not enabled, handle the error return; } } // Check if the app has permission to access location permissionGranted = await location.hasPermission(); if (permissionGranted == PermissionStatus.denied) { permissionGranted = await location.requestPermission(); if (permissionGranted != PermissionStatus.granted) { // Location permission is still not granted, handle the error return; } } // Configure location accuracy LocationAccuracy desiredAccuracy = LocationAccuracy.high; // Get the current location LocationData _locationData = await location.getLocation(); myLocation = (_locationData.latitude != null && _locationData.longitude != null ? LatLng(_locationData.latitude!, _locationData.longitude!) : null)!; // Print location details // print('Accuracy: ${_locationData.accuracy}'); // print('Latitude: ${_locationData.latitude}'); // print('Longitude: ${_locationData.longitude}'); // print('Time: ${_locationData.time}'); isLoading = false; update(); } LatLngBounds calculateBounds( double centerLat, double centerLng, double radius) { // double radius = 4000; // 10 km in meters southwest = LatLng( centerLat - (radius / 111000), centerLng - (radius / (111000 * cos(centerLat))), ); northeast = LatLng( centerLat + (radius / 111000), centerLng + (radius / (111000 * cos(centerLat))), ); return LatLngBounds(southwest: southwest, northeast: northeast); } GoogleMapController? mapController; void onMapCreated(GoogleMapController controller) { mapController = controller; controller.getVisibleRegion(); controller.animateCamera( CameraUpdate.newLatLng(myLocation), ); update(); } // void startMarkerReloading() { // int count = 0; // markerReloadingTimer = Timer.periodic(const Duration(seconds: 30), (timer) { // print('timer=============================='); // reloadMarkers(); // // count++; // if (count == 10) { // timer.cancel(); // } // }); // } late Timer markerReloadingTimer2; late Timer markerReloadingTimer1; late int duration1; void startMarkerReloading() { // Schedule timer 1 to reload markers at a specific time DateTime scheduledTime1 = DateTime.now().add(const Duration(seconds: 20)); markerReloadingTimer1 = Timer(scheduledTime1.difference(DateTime.now()), () { print('timer 1 =============================='); reloadMarkers(); }); // Schedule timer 2 to reload markers at a specific time DateTime scheduledTime2 = DateTime.now().add(const Duration(seconds: 40)); markerReloadingTimer2 = Timer(scheduledTime2.difference(DateTime.now()), () { print('timer 2 =============================='); reloadMarkers(); }); } void reloadMarkers() async { await getCarsLocationByPassenger(); // Clear existing markers // mapController!.showMarkerInfoWindow(MarkerId('g')); markers.clear(); update(); // if (rideConfirm) { getNearestDriverByPassengerLocation(); // } // Add new markers // Example: Add a marker for each item in a list for (var item in carsLocationByPassenger) { final marker = Marker( infoWindow: InfoWindow(title: '${item.latitude} minutes'), markerId: MarkerId(duration1.toString()), position: LatLng(item.latitude, item.longitude), // Other properties for the marker, such as icon, info window, etc. ); markers.add(marker); } // Update the map with the new markers mapController?.animateCamera(CameraUpdate.newLatLng( LatLng(myLocation.latitude, myLocation.longitude))); } String durationByPassenger = ''; late DateTime newTime1 = DateTime.now(); late DateTime timeFromDriverToPassenger = DateTime.now(); String distanceByPassenger = ''; late Duration durationFromDriverToPassenger; void getNearestDriverByPassengerLocation() async { if (polyLines.isEmpty || data.isEmpty) { if (rideConfirm == false) { double nearestDistance = double.infinity; if (dataCarsLocationByPassenger['message'].length > 0) { for (var i = 0; i < dataCarsLocationByPassenger['message'].length; i++) { var carLocation = dataCarsLocationByPassenger['message'][i]; // double distance1 = Geolocator.distanceBetween( // mylocation.latitude, // mylocation.longitude, // double.parse(carLocation['latitude']), // double.parse(carLocation['longitude']), // ); // if (distance1 < nearestDistance) { // nearestDistance = distance1; // // nearestCarLocation = carLocation; // nearestCar = CarLocation( // distance: distance1, // id: carLocation['driver_id'], // latitude: double.parse(carLocation['latitude']), // longitude: double.parse(carLocation['longitude']), // ); // } // isloading = true; update(); // Make API request to get exact distance and duration String apiUrl = '${AppLink.googleMapsLink}distancematrix/json?destinations=${carLocation['latitude']},${carLocation['longitude']}&origins=${myLocation.latitude},${myLocation.longitude}&units=metric&key=${AK.mapAPIKEY}'; var response = await CRUD().getGoogleApi(link: apiUrl, payload: {}); if (response['status'] == "OK") { var data = response; // Extract distance and duration from the response and handle accordingly int distance1 = data['rows'][0]['elements'][0]['distance']['value']; distanceByPassenger = data['rows'][0]['elements'][0]['distance']['text']; duration1 = data['rows'][0]['elements'][0]['duration']['value']; durationFromDriverToPassenger = Duration(seconds: duration1.toInt()); newTime1 = currentTime.add(durationFromDriverToPassenger); timeFromDriverToPassenger = newTime1.add(Duration(minutes: 2.toInt())); durationByPassenger = data['rows'][0]['elements'][0]['duration']['text']; update(); if (distance1 < nearestDistance) { nearestDistance = distance1.toDouble(); nearestCar = CarLocation( distance: distance1.toDouble(), duration: duration1.toDouble(), id: carLocation['driver_id'], latitude: double.parse(carLocation['latitude']), longitude: double.parse(carLocation['longitude']), ); // isloading = false; update(); } } // Handle the distance and duration as needed else { print( 'Failed to retrieve distance and duration: ${response['status']}'); // Handle the failure case } } } } } print(nearestCar!.distance); print(nearestCar!.duration); print(nearestCar!.latitude); print(nearestCar!.longitude); print(nearestCar!.id); } late LatLngBounds boundsData; getMap(String origin, destination) async { var origin1 = fromString(origin); var destination1 = fromString(destination); isLoading = true; update(); myDestination = destination1; myLocation = origin1; await getCarsLocationByPassenger(); // print(carsLocationByPassenger); isLoading = false; update(); var url = ('${AppLink.googleMapsLink}directions/json?&language=en&avoid=tolls|ferries&destination=$destination&origin=$origin&key=${AK.mapAPIKEY}'); var response = await CRUD().getGoogleApi(link: url, payload: {}); data = response['routes'][0]['legs']; print(data); isLoading = false; update(); durationToRide = data[0]['duration']['value']; final points = decodePolyline(response["routes"][0]["overview_polyline"]["points"]); for (int i = 0; i < points.length; i++) { double lat = points[i][0].toDouble(); double lng = points[i][1].toDouble(); polylineCoordinates.add(LatLng(lat, lng)); } // Define the northeast and southwest coordinates final bounds = response["routes"][0]["bounds"]; LatLng northeast = LatLng(bounds['northeast']['lat'], bounds['northeast']['lng']); LatLng southwest = LatLng(bounds['southwest']['lat'], bounds['southwest']['lng']); // Create the LatLngBounds object boundsData = LatLngBounds(northeast: northeast, southwest: southwest); // Calculate the zoom level based on the distance and screen size double distanceOfDestnation = getDistanceFromText(data[0]['distance']['text']); // Animate the camera to the adjusted bounds if (distanceOfDestnation <= 5) { mapController!.animateCamera(CameraUpdate.newLatLngZoom(myLocation, 14)); } else if (distanceOfDestnation > 5 && distanceOfDestnation <= 8) { mapController!.animateCamera(CameraUpdate.newLatLngZoom(myLocation, 13)); } else if (distanceOfDestnation > 8 && distanceOfDestnation < 16) { mapController!.animateCamera(CameraUpdate.newLatLngZoom(myLocation, 12)); } else if (distanceOfDestnation >= 16 && distanceOfDestnation < 30) { mapController!.animateCamera(CameraUpdate.newLatLngZoom(myLocation, 11)); } else if (distanceOfDestnation >= 30 && distanceOfDestnation < 100) { mapController!.animateCamera(CameraUpdate.newLatLngZoom(myLocation, 10)); } else if (distanceOfDestnation >= 100) { mapController!.animateCamera(CameraUpdate.newLatLngZoom(myLocation, 7)); } if (polyLines.isNotEmpty) { clearPolyline(); } else { var polyline = Polyline( polylineId: PolylineId(response["routes"][0]["summary"]), points: polylineCoordinates, width: 10, color: Colors.blue, ); polyLines.add(polyline); rideConfirm = false; update(); } } showBottomSheet1() async { bottomSheet(); isBottomSheetShown = true; heightBottomSheetShown = 250; update(); } final promo = TextEditingController(); bool promoTaken = false; void applyPromoCodeToPassenger() async { //TAWJIHI CRUD().get(link: AppLink.getPassengersPromo, payload: { 'promo_code': promo.text, }).then((value) { if (value == 'failure') { Get.defaultDialog( title: 'Promo End !'.tr, confirm: MyElevatedButton( title: 'Back', onPressed: () { Get.back(); Get.back(); }, )); } var decode = jsonDecode(value); if (decode["status"] == "success") { print(totalPassenger); var firstElement = decode["message"][0]; totalPassenger = totalPassenger - (totalPassenger * int.parse(firstElement['amount']) / 100); promoTaken = true; update(); print(totalPassenger); Get.back(); } }); } double getDistanceFromText(String distanceText) { // Remove any non-digit characters from the distance text String distanceValue = distanceText.replaceAll(RegExp(r'[^0-9.]+'), ''); // Parse the extracted numerical value as a double double distance = double.parse(distanceValue); return distance; } Future bottomSheet() async { if (data.isNotEmpty) { String distanceText = await data[0]['distance']['text']; String durationText = await data[0]['duration']['text']; print(data[0]['duration']['text']); print('================================='); distance = getDistanceFromText(distanceText); duration = getDistanceFromText(durationText); durationToAdd = Duration(minutes: duration.toInt()); DateTime currentTime = DateTime.now(); newTime = currentTime.add(durationToAdd); averageDuration = duration / distance; costDuration = duration * averageDuration * 0.016; var totalDriver1 = cost + costDuration; totalPassenger = totalDriver1 + (totalDriver1 * .16); totalDriver = totalDriver1 + (totalDriver1 * .16); tax = totalPassenger * .04; totalME = totalPassenger - totalDriver - tax; update(); if (currentTime.hour >= 21) { if (distanceText.contains('km')) { cost = distance * 0.23; update(); } else { cost = distance * 0.23 / 1000; update(); } } else if (currentTime.hour < 5) { if (distanceText.contains('km')) { cost = distance * 0.25; update(); } else { cost = distance * 0.25 / 1000; update(); } } else if (currentTime.hour >= 13 && currentTime.hour <= 16) { if (averageDuration > 2.5) { if (distanceText.contains('km')) { cost = distance * 0.23; update(); } else { cost = distance * 0.25 / 1000; update(); } } else { if (distanceText.contains('km')) { cost = distance * 0.21; update(); } else { cost = distance * 0.21 / 1000; update(); } } } else { if (distanceText.contains('km')) { cost = distance * 0.21; update(); } else { cost = distance * 0.21 / 1000; update(); } } if (totalPassenger < 1) { totalPassenger = 1; update(); if (totalDriver < .5) { totalDriver = .80; totalME = .16; update(); } else { totalDriver = .90; totalME = .06; update(); } } // buttomSheetMapPage(); changeBottomSheetShown(); } } addToken() async { await CRUD().post(link: AppLink.addTokens, payload: { 'token': box.read(BoxName.tokenFCM), 'passengerID': box.read(BoxName.passengerID).toString() }).then((value) => print('cccc')); } List polylineCoordinate = []; String? cardNumber; void readyWayPoints() { allTextEditingPlaces = [ wayPoint0Controller, wayPoint1Controller, wayPoint2Controller, wayPoint3Controller, wayPoint4Controller, ]; placeListResponseAll = [ wayPoint0, wayPoint1, wayPoint2, wayPoint3, wayPoint4 ]; currentLocationStringAll = [ currentLocationString0, currentLocationString1, currentLocationString2, currentLocationString3, currentLocationString4, ]; // placeListResponse.add(wayPoint0); // placeListResponse.add(wayPoint1); // placeListResponse.add(wayPoint2); // placeListResponse.add(wayPoint3); // placeListResponse.add(wayPoint4); } @override void onInit() async { mapAPIKEY = await storage.read(key: BoxName.mapAPIKEY); await getLocation(); await addToken(); await getCarsLocationByPassenger(); getNearestDriverByPassengerLocation(); addCustomPicker(); addCustomCarIcon(); addCustomTripIcon(); startMarkerReloading(); cardNumber = await SecureStorage().readData(BoxName.cardNumber); readyWayPoints(); super.onInit(); } } class CarLocation { final String id; final double latitude; final double longitude; final double distance; final double duration; CarLocation({ required this.id, required this.latitude, required this.longitude, this.distance = 10000, this.duration = 10000, }); }