import 'dart:async'; import 'dart:convert'; import 'dart:math' show cos; import 'dart:math' as math; import 'package:SEFER/controller/functions/tts.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.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:intl/intl.dart'; import 'package:location/location.dart'; import 'package:SEFER/constant/colors.dart'; import 'package:SEFER/constant/style.dart'; import 'package:SEFER/controller/home/points_for_rider_controller.dart'; import 'package:SEFER/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 '../../constant/table_names.dart'; import '../../main.dart'; import '../../models/model/locations.dart'; import '../../views/home/map_widget.dart/car_details_widget_to_go.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 increasFeeFromPassenger = 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(); final increasFeeFormKey = GlobalKey(); List data = []; List bounds = []; List placesStart = []; List driversToken = []; LatLng previousLocationOfDrivers = LatLng(0, 0); double angleDegrees = 0; LatLng currentLocationOfDrivers = LatLng(0, 0); List allTextEditingPlaces = []; List placesDestination = []; List wayPoint0 = []; List wayPoint1 = []; List wayPoint2 = []; List wayPoint3 = []; List wayPoint4 = []; final textToSpeechController = Get.put(TextToSpeechController()); List> placeListResponseAll = []; List placeListResponse = [ formSearchPlaces(0), formSearchPlaces(1), formSearchPlaces(2), formSearchPlaces(3), ]; LatLngBounds? boundsdata; List markers = []; List polyLines = []; late LatLng passengerLocation = const LatLng(32, 34); 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); late LatLng myDestination; List polylineCoordinates = []; List polylineCoordinates0 = []; List polylineCoordinates1 = []; List polylineCoordinates2 = []; List polylineCoordinates3 = []; List polylineCoordinates4 = []; List> polylineCoordinatesPointsAll = []; List carsLocationByPassenger = []; List driverCarsLocationToPassengerAfterApplied = []; BitmapDescriptor markerIcon = BitmapDescriptor.defaultMarker; BitmapDescriptor tripIcon = BitmapDescriptor.defaultMarker; BitmapDescriptor startIcon = BitmapDescriptor.defaultMarker; BitmapDescriptor endIcon = 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; String stringRemainingTimeToPassenger = ''; String stringRemainingTimeDriverWaitPassenger5Minute = ''; bool isDriverInPassengerWay = false; bool isDriverArrivePassenger = false; bool startLocationFromMap = false; bool workLocationFromMap = false; bool homeLocationFromMap = false; bool startLocationFromMap0 = false; bool startLocationFromMap1 = false; bool startLocationFromMap2 = false; bool startLocationFromMap3 = false; bool startLocationFromMap4 = false; List startLocationFromMapAll = []; double latePrice = 0; double heavyPrice = 0; double naturePrice = 0; 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 isMarkersShown = false; bool isMainBottomMenuMap = true; late Timer markerReloadingTimer2; late Timer markerReloadingTimer1; late int durationToPassenger = 0; bool isWayPointSheet = false; bool isWayPointStopsSheet = false; bool isWayPointStopsSheetUtilGetMap = false; double heightBottomSheetShown = 0; double cashConfirmPageShown = 250; late String driverId; late String gender; double widthMapTypeAndTraffic = 50; double paymentPageShown = Get.height * .6; late LatLng southwest; late LatLng northeast; List carLocationsModels = []; 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; double progressTimerDriverWaitPassenger5Minute = 0; int durationTimer = 9; int durationToRide = 0; int remainingTime = 25; int remainingTimeToPassengerFromDriverAfterApplied = 60; int remainingTimeDriverWaitPassenger5Minute = 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 = 'Add Location 1'.tr; String currentLocationString2 = 'Add Location 2'.tr; String currentLocationString3 = 'Add Location 3'.tr; String currentLocationString4 = 'Add Location 4'.tr; String placesCoordinate0 = ''.tr; String placesCoordinate1 = ''.tr; String placesCoordinate2 = ''.tr; String placesCoordinate3 = ''.tr; String placesCoordinate4 = ''.tr; List currentLocationStringAll = []; List hintTextwayPointStringAll = []; var placesCoordinate = []; String hintTextDestinationPoint = 'Select your destination'.tr; late String rideId = 'yet'; bool noCarString = false; bool isCashSelectedBeforeConfirmRide = false; bool isPassengerChosen = false; bool isSearchingWindow = false; bool currentLocationToFormPlaces = false; bool currentLocationToFormPlaces0 = false; bool currentLocationToFormPlaces1 = false; bool currentLocationToFormPlaces2 = false; bool currentLocationToFormPlaces3 = false; bool currentLocationToFormPlaces4 = false; List currentLocationToFormPlacesAll = []; late String driverToken; int carsOrder = 0; int wayPointIndex = 0; late double kazan; String? mapAPIKEY; late double totalME = 0; late double tax = 0; late double totalPassenger = 0; late double totalCostPassenger = 0; late double totalPassengerComfort = 0; late double totalPassengerComfortDiscount = 0; late double totalPassengerMotoDelivery = 0; late double totalDriver = 0; late double averageDuration = 0; late double costDuration = 0; late double costDistance = 0; late double distance = 0; late double duration = 0; late Duration durationToAdd; late DateTime newTime = DateTime.now(); int hours = 0; int minutes = 0; 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 = passengerLocation.toString(); newStartPointLocation = passengerLocation; update(); } List coordinatesWithoutEmpty = []; void getMapPointsForAllMethods() async { print(placesCoordinate.toString()); clearPolyline(); isMarkersShown = false; isWayPointStopsSheetUtilGetMap = false; isWayPointSheet = false; durationToRide = 0; distanceOfDestnation = 0; wayPointSheetHeight = 0; remainingTime = 25; haveSteps = true; // Filter out empty value coordinatesWithoutEmpty = placesCoordinate.where((coord) => coord.isNotEmpty).toList(); latestPosition = LatLng( double.parse(coordinatesWithoutEmpty.last.split(',')[0]), double.parse(coordinatesWithoutEmpty.last.split(',')[1])); // print(coordinatesWithoutEmpty); for (var i = 0; i < coordinatesWithoutEmpty.length; i++) { if ((i + 1) < coordinatesWithoutEmpty.length) { await getMapPoints( coordinatesWithoutEmpty[i].toString(), coordinatesWithoutEmpty[i + 1].toString(), i, ); } } // isWayPointStopsSheet = false; if (haveSteps) { String latestWaypoint = placesCoordinate.lastWhere((coord) => coord.isNotEmpty); latestPosition = LatLng( double.parse(latestWaypoint.split(',')[0]), double.parse(latestWaypoint.split(',')[1]), ); } updateCameraForDistanceAfterGetMap(); changeWayPointStopsSheet(); bottomSheet(); showBottomSheet1(); 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 convertHintTextPlaces(int index, var res) { if (placeListResponseAll[index].isEmpty) { placeListResponseAll[index] = res; hintTextwayPointStringAll[index] = 'Search for your Start point'.tr; update(); } else { hintTextwayPointStringAll[index] = res['name']; currentLocationStringAll[index] = res['name']; placesCoordinate[index] = '${res['geometry']['location']['lat']},${res['geometry']['location']['lng']}'; placeListResponseAll[index] = []; allTextEditingPlaces[index].clear(); // double lat = wayPoint0[index]['geometry']['location']['lat']; // double lng = wayPoint0[index]['geometry']['location']['lng']; // newPointLocation0 = LatLng(lat, lng); update(); Get.back(); } } increaseFeeByPassengerAndReOrder() async { if (increasFeeFormKey.currentState!.validate()) { if (double.parse(increasFeeFromPassenger.text) > totalPassenger) { totalPassenger = double.parse(increasFeeFromPassenger.text); Get.back(); if (rideId != 'yet') { await CRUD().post(link: AppLink.updateDriverOrder, payload: { "order_id": rideId.toString(), // Convert to String "status": 'Cancel' }); } confirmRideForFirstDriver(); } } } 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(); } } void convertHintTextDestinationNewPlacesFromRecent( List recentLocations, int index) { hintTextDestinationPoint = recentLocations[index]['name']; double lat = recentLocations[index]['latitude']; double lng = recentLocations[index]['longitude']; 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; // to get or sure picker point for origin //todo // isPickerShown = true; // clickPointPosition(); 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)}.\n I am using ${box.read(AppInformation.appName)} to ride with $firstName as the driver. $firstName \nis driving a $model\n with license plate $licensePlate.\n I am currently located at $passengerLocation.\n If you need to reach me, please contact the driver directly at\n\n $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'.tr} ${box.read(BoxName.name)}.\n${' I am using'.tr}'} ${AppInformation.appName}${' to ride with'.tr} $firstName${' as the driver.'.tr} $firstName \n${'is driving a '.tr}$model\n${' with license plate '.tr}$licensePlate.\n${' I am currently located at '.tr} https://www.google.com/maps/place/${passengerLocation.latitude},${passengerLocation.longitude}.\n${' If you need to reach me, please contact the driver directly at'.tr}\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(); } calcualateDistsanceInMetet(LatLng prev, current) async { double distance2 = Geolocator.distanceBetween( prev.latitude, prev.longitude, current.latitude, current.longitude, ); return distance2; } bool isTimerFromDriverToPassengerAfterAppliedRunning = true; void startTimerFromDriverToPassengerAfterApplied() async { for (int i = 0; i <= timeToPassengerFromDriverAfterApplied && isTimerFromDriverToPassengerAfterAppliedRunning; 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(); } } // Function to stop the timer void stopTimerFromDriverToPassengerAfterApplied() { isTimerFromDriverToPassengerAfterAppliedRunning = false; update(); } void startTimerDriverWaitPassenger5Minute() async { stopTimerFromDriverToPassengerAfterApplied(); isDriverArrivePassenger = true; isDriverInPassengerWay = false; timeToPassengerFromDriverAfterApplied = 0; update(); for (int i = 0; i <= 300; i++) { await Future.delayed(const Duration(seconds: 1)); progressTimerDriverWaitPassenger5Minute = i / 300; remainingTimeDriverWaitPassenger5Minute = 300 - i; int minutes = (remainingTimeDriverWaitPassenger5Minute / 60).floor(); int seconds = remainingTimeDriverWaitPassenger5Minute % 60; stringRemainingTimeDriverWaitPassenger5Minute = '$minutes:${seconds.toString().padLeft(2, '0')}'; update(); } } // Create a StreamController to manage the timer values final timerController = StreamController(); // Start the timer when the ride begins void beginRideTimer() { // Set up the timer to run every second Timer.periodic(const Duration(seconds: 1), (timer) { // Update the timer value and notify listeners timerController.add(timer.tick); update(); }); } // Stop the timer when the ride ends void stopRideTimer() { timerController.close(); update(); } late String arrivalTime; void rideIsBeginPassengerTimer() async { // Calculate arrival time considering current time and duration DateTime now = DateTime.now(); DateTime arrivalTime1 = now.add(Duration(seconds: durationToRide)); arrivalTime = DateFormat('hh:mm').format(arrivalTime1); 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'); // if (Get.find().isWalletChecked == true && // Get.find().isCashChecked == false) { // if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) { // totalPassenger = totalCostPassenger + // double.parse(box.read(BoxName.passengerWalletTotal)); // } else { // totalPassenger = totalCostPassenger + 0; // } // await CRUD().post(link: AppLink.addPassengersWallet, payload: { // 'passenger_id': box.read(BoxName.passengerID).toString(), // 'balance': ((-1) * totalPassenger).toString() // }); // } } void tripFinishedFromDriver() async { isRideFinished = true; rideTimerBegin = false; remainingTimeTimerRideBegin = 0; update(); } void getBeginRideFromDriver() async { try { var res = await CRUD() .get(link: AppLink.getRideStatusBegin, payload: {'ride_id': rideId}); if (res == 'failure') { // print(res); } var decode = jsonDecode(res); if (decode['data']['status'] == 'Begin') { timeToPassengerFromDriverAfterApplied = 0; remainingTime = 0; remainingTimeToPassengerFromDriverAfterApplied = 0; remainingTimeDriverWaitPassenger5Minute = 0; rideTimerBegin = true; isDriverInPassengerWay = false; isDriverArrivePassenger = false; update(); // isCancelRidePageShown = true; rideIsBeginPassengerTimer(); // //print('rideTimerBegin: $rideTimerBegin'); } } catch (e) { //print('Error: $e'); // Handle the error or perform any necessary actions } } void getRideStatusFromStartApp() async { try { var res = await CRUD().get( link: AppLink.getRideStatusFromStartApp, payload: {'passenger_id': box.read(BoxName.passengerID)}); if (res == 'failure') { //print(res); } var decode = jsonDecode(res); if (decode['data']['status'] == 'Begin') { //todo from sql or get storage getMap( decode['data']['start_location'], decode['data']['end_location']); // timeToPassengerFromDriverAfterApplied = 0; // remainingTime = 0; // remainingTimeToPassengerFromDriverAfterApplied = 0; // // isCancelRidePageShown = true; // rideIsBeginPassengerTimer(); // // //print('rideTimerBegin: $rideTimerBegin'); // rideTimerBegin = true; update(); } } catch (e) { //print('Error: $e'); // Handle the error or perform any necessary actions } } 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 clearPlaces(int index) { placeListResponseAll[index] = []; hintTextwayPointStringAll[index] = '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(); } int currentTimeSearchingCaptainWindow = 0; late String driverPhone; late String driverRate; late String firstName; late String carColor; late String carYear; late String model; late String make; late String licensePlate; confirmRideForFirstDriver() async { await getCarsLocationByPassenger(); await getNearestDriverByPassengerLocationAPIGOOGLE(); if (dataCarsLocationByPassenger != 'failure') { driverToken = dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(); driverPhone = dataCarsLocationByPassenger['message'][carsOrder]['phone'].toString(); firstName = dataCarsLocationByPassenger['message'][carsOrder] ['first_name'] .toString(); carColor = dataCarsLocationByPassenger['message'][carsOrder]['color'].toString(); driverRate = dataCarsLocationByPassenger['message'][carsOrder] ['ratingDriver'] .toString(); carYear = dataCarsLocationByPassenger['message'][carsOrder]['year'].toString(); model = '${dataCarsLocationByPassenger['message'][carsOrder]['model']} - ${dataCarsLocationByPassenger['message'][carsOrder]['make']}'; licensePlate = dataCarsLocationByPassenger['message'][carsOrder] ['car_plate'] .toString(); PaymentController paymentController = Get.find(); rideConfirm = true; shouldFetch = true; isBottomSheetShown = false; timeToPassengerFromDriverAfterApplied = 60; isDriversTokensSend = false; update(); // //print('rideConfirm= $rideConfirm'); 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.toStringAsFixed(2), "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.toStringAsFixed(2), totalDriver.toStringAsFixed(2), durationToRide.toString(), distance.toStringAsFixed(2), 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(), durationToPassenger.toString(), rideId, rideTimerBegin.toString(), dataCarsLocationByPassenger['message'][carsOrder]['driver_id'] .toString(), durationToRide.toString(), Get.find().wayPoints.length > 1 ? 'haveSteps' : 'startEnd', placesCoordinate[0], placesCoordinate[1], placesCoordinate[2], placesCoordinate[3], placesCoordinate[4], costDistance.toStringAsFixed(2), double.parse(box.read(BoxName.passengerWalletTotal)) < 0 ? double.parse(box.read(BoxName.passengerWalletTotal)) .toStringAsFixed(2) : '0', box.read(BoxName.email).toString(), startNameAddress, endNameAddress, box.read(BoxName.carType), ]; print(body); FirebaseMessagesController().sendNotificationToDriverMapPolyline( 'Order', jsonDecode(value)['message'].toString(), dataCarsLocationByPassenger['message'][carsOrder]['token'] .toString(), body, polylineCoordinates.toString()); 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())); } } bool isDriversTokensSend = false; confirmRideForAllDriverAvailable() async { // isDriversTokensSend = true; PaymentController paymentController = Get.find(); rideConfirm = true; shouldFetch = true; isBottomSheetShown = false; timeToPassengerFromDriverAfterApplied = 60; driversToken.remove(driverToken); List body = [ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}', '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}', totalPassenger.toStringAsFixed(2), totalDriver.toStringAsFixed(2), durationToRide.toString(), distance.toStringAsFixed(2), 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(), durationToPassenger.toString(), rideId, rideTimerBegin.toString(), dataCarsLocationByPassenger['message'][carsOrder]['driver_id'].toString(), durationToRide.toString(), Get.find().wayPoints.length > 1 ? 'haveSteps' : 'startEnd', placesCoordinate[0], placesCoordinate[1], placesCoordinate[2], placesCoordinate[3], placesCoordinate[4], costDistance.toStringAsFixed(2), double.parse(box.read(BoxName.passengerWalletTotal)) < 0 ? double.parse(box.read(BoxName.passengerWalletTotal)) .toStringAsFixed(2) : '0', box.read(BoxName.email).toString(), startNameAddress, endNameAddress, box.read(BoxName.carType), ]; print('driversToken'); print(driversToken); for (var i = 0; i < driversToken.length; i++) { FirebaseMessagesController().sendNotificationToDriverMapPolyline( 'OrderSpeed', rideId.toString(), driversToken[i], body, polylineCoordinates.toString()); } delayAndFetchRideStatusForAllDriverAvailable(rideId); update(); } String statusRide = 'wait'; void delayAndFetchRideStatus(String rideId) { Timer(const Duration(milliseconds: 200), () async { if (shouldFetch) { // //print('shouldFetch is =$shouldFetch'); var res = await getRideStatus(rideId); // print(res); // var decod = jsonDecode(res); print(' 0000000000000000000000000000000000000000000000000'); print(res); if (res.toString() == 'Apply') { // getUpdatedRideForDriverApply(rideId); shouldFetch = false; // Stop further fetches statusRide = 'Apply'; rideConfirm = false; isSearchingWindow = false; update(); startTimerFromDriverToPassengerAfterApplied(); // startTimer(); } else if (res.toString() == 'Refused') { // isDriversTokensSend = false; if (isDriversTokensSend == false) { confirmRideForAllDriverAvailable(); isDriversTokensSend = true; } } else if (isDriversTokensSend == false) { delayAndFetchRideStatus( rideId); // Repeat the delay and fetch operation update(); } } }); } void delayAndFetchRideStatusForAllDriverAvailable(String rideId) { Timer(const Duration(milliseconds: 200), () async { if (shouldFetch) { // //print('shouldFetch is =$shouldFetch'); var res = await getRideStatus(rideId); print(res); // var decod = jsonDecode(res); // print(' 0000000000000000000000000000000000000000000000000'); // print(decod['data']); if (res.toString() == 'Apply') { getUpdatedRideForDriverApply(rideId); shouldFetch = false; // Stop further fetches statusRide = 'Apply'; rideConfirm = false; isSearchingWindow = false; update(); startTimerFromDriverToPassengerAfterApplied(); } else if (res.toString() == 'Refused') { delayAndFetchRideStatusForAllDriverAvailable(rideId); } } }); } 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 += durationToPassenger; // //print(duration1); // //print('timeToPassengerFromDriverAfterApplied====' + // timeToPassengerFromDriverAfterApplied.toString()); startTimerFromDriverToPassengerAfterApplied(); update(); } update(); } timerEnded(); } void timerEnded() async { //print('Timer ended'); runEvery30SecondsUntilConditionMet(); isCancelRidePageShown = false; update(); } Future getRideStatus(String rideId) async { final response = await CRUD().get(link: AppLink.getRideStatus, payload: {'id': rideId}); return jsonDecode(response)['data']; } late String driverCarModel, driverCarMake, driverLicensePlate, driverName; getUpdatedRideForDriverApply(String rideId) async { // if (isDriversTokensSend) { final res = await CRUD().get(link: AppLink.getRideOrderID, payload: {'id': rideId}); if (res != 'failure') { var response = jsonDecode(res); print('driverId: ${response['data']['driver_id']}'); print('driverPhone: ${response['data']['phone']}'); print('driverCarMake: ${response['data']['make']}'); print('model: ${response['data']['model']}'); print('make: ${response['data']['make']}'); print('licensePlate: ${response['data']['car_plate']}'); print('firstName: ${response['data']['first_name']}'); print('driverToken: ${response['data']['token']}'); print('carYear: ${response['data']['year']}'); print('driverRate: ${response['data']['ratingDriver']}'); driverId = response['data']['driver_id']; driverPhone = response['data']['phone']; driverCarMake = response['data']['make']; model = response['data']['model']; make = response['data']['make']; licensePlate = response['data']['car_plate']; firstName = response['data']['first_name']; driverToken = response['data']['token']; carYear = response['data']['year']; driverRate = response['data']['ratingDriver']; } driversToken.remove(driverToken); for (var i = 0; i < driversToken.length; i++) { FirebaseMessagesController().sendNotificationToAnyWithoutData( 'Order Applied', '$driverName Apply order\nTake attention in other order'.tr, driversToken[i]); } // } } late LatLng currentDriverLocation; late double headingList; Future getCarsLocationByPassenger() async { // if (rideConfirm == false) { carsLocationByPassenger = []; LatLngBounds bounds = calculateBounds( passengerLocation.latitude, passengerLocation.longitude, 7000); 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(); gender = dataCarsLocationByPassenger['message'][carsOrder]['gender'] .toString(); // } // //print('driverId==============$driverId'); carsLocationByPassenger.clear(); // Clear existing markers // late LatLng lastDriverLocation; // Initialize a variable for last location for (var i = 0; i < dataCarsLocationByPassenger['message'].length; i++) { var json = dataCarsLocationByPassenger['message'][i]; print(json); CarLocationModel model = CarLocationModel.fromJson(json); if (carLocationsModels.length < i + 1) { carLocationsModels.add(model); markers.add( Marker( markerId: MarkerId(json['latitude']), position: LatLng( double.parse(json['latitude']), double.parse(json['longitude']), ), rotation: double.parse(json['heading']), icon: carIcon, ), ); driversToken.add(json['token']); } else { carLocationsModels[i] = model; markers[i] = Marker( markerId: MarkerId(json['latitude']), position: LatLng( double.parse(json['latitude']), double.parse(json['longitude']), ), rotation: double.parse(json['heading']), icon: carIcon, ); driversToken[i] = json['token']; } } update(); } } LatLng driverLocationToPassenger = LatLng(32, 35); Future getDriverCarsLocationToPassengerAfterApplied() async { driverCarsLocationToPassengerAfterApplied = []; var res = await CRUD().get( link: AppLink.getDriverCarsLocationToPassengerAfterApplied, payload: {'driver_id': driverId}); datadriverCarsLocationToPassengerAfterApplied = jsonDecode(res); driverLocationToPassenger = LatLng( double.parse(datadriverCarsLocationToPassengerAfterApplied['message'][0] ['latitude']), double.parse(datadriverCarsLocationToPassengerAfterApplied['message'][0] ['longitude'])); driverCarsLocationToPassengerAfterApplied.add(LatLng( double.parse(datadriverCarsLocationToPassengerAfterApplied['message'][0] ['latitude']), double.parse(datadriverCarsLocationToPassengerAfterApplied['message'][0] ['longitude']))); CarLocationModel model = CarLocationModel.fromJson( datadriverCarsLocationToPassengerAfterApplied['message'][0]); carLocationsModels.add(model); update(); } Future runEvery30SecondsUntilConditionMet() async { // Calculate the duration of the trip in minutes. double tripDurationInMinutes = durationToPassenger / 4; 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: 4)); await getDriverCarsLocationToPassengerAfterApplied(); reloadMarkerDriverCarsLocationToPassengerAfterApplied(); } } void clearMarkersExceptStartEnd() { Set markersToRemove = markers .where((marker) => marker.markerId != MarkerId("start") && marker.markerId != MarkerId("end")) .toSet(); for (Marker marker in markersToRemove) { markers.remove(marker); update(); } } void reloadMarkerDriverCarsLocationToPassengerAfterApplied() { clearMarkersExceptStartEnd(); // for (var i = 0; i < driverCarsLocationToPassengerAfterApplied.length; i++) { LatLng driverPosition = LatLng( double.parse( datadriverCarsLocationToPassengerAfterApplied[0]['latitude']), double.parse( datadriverCarsLocationToPassengerAfterApplied[0]['longitude'])); final driverAcceptedMarker = Marker( markerId: const MarkerId('driverToPassengers'), position: driverPosition, rotation: double.parse( datadriverCarsLocationToPassengerAfterApplied['message'][0] ['heading']), icon: carIcon, ); markers.add(driverAcceptedMarker); // update(); mapController?.animateCamera(CameraUpdate.newLatLng(driverPosition)); 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.updateRides, payload: { "id": rideId.toString(), // Convert to String "status": 'notApplyFromAnyDriver' }); rideConfirm = false; shouldFetch = false; isPassengerChosen = false; isCashConfirmPageShown = false; // totalStepDurations = 0; isCashSelectedBeforeConfirmRide = false; timeToPassengerFromDriverAfterApplied = 0; changeCancelRidePageShow(); remainingTime = 0; update(); } Future cancelRide() async { //print("rideConfirm=$rideConfirm"); if (rideConfirm == false) { clearPlacesDestination(); clearPolyline(); // clearPolylineAll(); data = []; changeCancelRidePageShow(); if (rideId != 'yet') { await CRUD().post(link: AppLink.updateDriverOrder, payload: { "order_id": rideId.toString(), // Convert to String "status": 'Cancel' }); FirebaseMessagesController().sendNotificationToDriverMAP( 'Cancel Trip', 'Trip Cancelled'.tr, driverToken, []); } rideConfirm = false; shouldFetch = false; isCashConfirmPageShown = false; isSearchingWindow = false; isPassengerChosen = false; isCashSelectedBeforeConfirmRide = false; isPickerShown = false; isMarkersShown = false; haveSteps = false; isMarkersShown = false; // totalStepDurations = 0; timeToPassengerFromDriverAfterApplied = 0; remainingTime = 0; isWayPointStopsSheetUtilGetMap = false; update(); } else { clearPlacesDestination(); clearPolyline(); data = []; await CRUD().post(link: AppLink.updateDriverOrder, payload: { "order_id": rideId.toString(), // Convert to String "status": 'Cancel' }); FirebaseMessagesController().sendNotificationToDriverMAP( 'Cancel Trip', 'Trip Cancelled'.tr, driverToken, []); isPickerShown = false; isWayPointStopsSheetUtilGetMap = false; rideConfirm = false; shouldFetch = false; isCashConfirmPageShown = false; isSearchingWindow = false; isPassengerChosen = false; isCashSelectedBeforeConfirmRide = false; haveSteps = false; isMarkersShown = false; timeToPassengerFromDriverAfterApplied = 0; changeCancelRidePageShow(); clearPolyline(); remainingTime = 0; durationTimer = 0; update(); } } void changePickerShown() { isPickerShown = !isPickerShown; heightPickerContainer = isPickerShown == true ? 150 : 90; update(); } void changeHeightPointsPageForRider() { isPointsPageForRider = !isPointsPageForRider; heightPointsPageForRider = isPointsPageForRider == true ? Get.height : 0; update(); } getCoordinateFromMapWayPoints(int index) { placesCoordinate[index] = newStartPointLocation.toString(); update(); } void changeMainBottomMenuMap() { if (isWayPointStopsSheetUtilGetMap == true) { changeWayPointSheet(); } else { isMainBottomMenuMap = !isMainBottomMenuMap; mainBottomMenuMapHeight = isMainBottomMenuMap == true ? Get.height * .2 : Get.height * .45; isWayPointSheet = false; if (heightMenuBool == true) { getDrawerMenu(); } initilizeGetStorage(); update(); } } void downPoints() { if (Get.find().wayPoints.length < 2) { isWayPointStopsSheetUtilGetMap = false; isWayPointSheet = false; wayPointSheetHeight = isWayPointStopsSheet ? Get.height * .45 : 0; // changeWayPointStopsSheet(); update(); } // changeWayPointStopsSheet(); // isWayPointSheet = false; update(); } void changeWayPointSheet() { isWayPointSheet = !isWayPointSheet; wayPointSheetHeight = isWayPointSheet == false ? 0 : Get.height * .45; // if (heightMenuBool == true) { // getDrawerMenu(); // } update(); } void changeWayPointStopsSheet() { // int waypointsLength = Get.find().wayPoints.length; //print('isWayPointStopsSheet $wayPointIndex'); if (wayPointIndex > -1) { isWayPointStopsSheet = true; isWayPointStopsSheetUtilGetMap = true; } isWayPointStopsSheet = !isWayPointStopsSheet; wayPointSheetHeight = isWayPointStopsSheet ? Get.height * .45 : 0; // 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(); } changeHeightPlacesAll(int index) { if (placeListResponseAll[index].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=${passengerLocation.latitude},${passengerLocation.longitude}&radius=50000&language=${box.read(BoxName.lang)}&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=${passengerLocation.latitude},${passengerLocation.longitude}&radius=50000&language=${box.read(BoxName.lang)}&key=${AK.mapAPIKEY.toString()}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); placesStart = response['results']; //print(placesStart); update(); } Future getPlacesListsWayPoint(int index) async { var url = '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint0Controller.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=50000&language=${box.read(BoxName.lang)}&key=${AK.mapAPIKEY.toString()}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); wayPoint0 = response['results']; placeListResponseAll[index] = response['results']; //print(wayPoint0); 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(); // polylineCoordinates = []; polylineCoordinatesPointsAll[0].clear(); polylineCoordinatesPointsAll[1].clear(); polylineCoordinatesPointsAll[2].clear(); polylineCoordinatesPointsAll[3].clear(); polylineCoordinatesPointsAll[4].clear(); isMarkersShown = false; update(); } void addCustomPicker() { ImageConfiguration config = ImageConfiguration( size: const Size(30, 30), devicePixelRatio: Get.pixelRatio // scale: 1.0, ); BitmapDescriptor.fromAssetImage(config, 'assets/images/picker.png', mipmaps: false) .then((value) { markerIcon = value; update(); }); } void addCustomStartIcon() async { // Create the marker with the resized image ImageConfiguration config = ImageConfiguration( size: const Size(30, 30), devicePixelRatio: Get.pixelRatio); BitmapDescriptor.fromAssetImage(config, 'assets/images/A.png', mipmaps: false) .then((value) { startIcon = value; update(); }); } void addCustomEndIcon() { ImageConfiguration config = ImageConfiguration( size: const Size(30, 30), devicePixelRatio: Get.pixelRatio); BitmapDescriptor.fromAssetImage(config, 'assets/images/b.png', mipmaps: false) .then((value) { endIcon = value; update(); }); } void addCustomCarIcon() { ImageConfiguration config = ImageConfiguration( size: const Size(30, 30), devicePixelRatio: Get.pixelRatio); BitmapDescriptor.fromAssetImage(config, 'assets/images/car.png', mipmaps: false) .then((value) { carIcon = value; update(); }); } void addCustomStepIcon() { ImageConfiguration config = ImageConfiguration( size: const Size(30, 30), devicePixelRatio: Get.pixelRatio); BitmapDescriptor.fromAssetImage(config, 'assets/images/brand.png', mipmaps: false) .then((value) { tripIcon = 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(); passengerLocation = (_locationData.latitude != null && _locationData.longitude != null ? LatLng(_locationData.latitude!, _locationData.longitude!) : null)!; newStartPointLocation = passengerLocation; // //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) { // myLocation = Get.find().location as LatLng; // myLocation = myLocation; mapController = controller; controller.getVisibleRegion(); controller.animateCamera( CameraUpdate.newLatLng(passengerLocation), ); update(); } // void startMarkerReloading() { // int count = 0; // markerReloadingTimer = Timer.periodic(const Duration(seconds: 30), (timer) { // //print('timer=============================='); // reloadMarkers(); // // count++; // if (count == 10) { // timer.cancel(); // } // }); // } Future startMarkerReloading() async { int reloadCount = 0; Timer.periodic(const Duration(seconds: 2), (timer) { reloadCount++; //print('Reloading markers ($reloadCount)'); if (!rideConfirm) { reloadMarkers(); } if (reloadCount >= 35) { timer.cancel(); // Stop the timer after 5 reloads //print('Marker reloading completed.'); } }); } reloadMarkers() async { if (statusRide == 'wait') { await getCarsLocationByPassenger(); await getNearestDriverByPassengerLocation(); // markers.clear(); // update(); // if (rideConfirm) { // } // Add new markers // Example: Add a marker for each item in a list for (var item in carsLocationByPassenger) { // for (var i = 0; i getNearestDriverByPassengerLocation() async { if (polyLines.isEmpty || data.isEmpty) { return null; // Early return if data is empty } if (!rideConfirm) { if (dataCarsLocationByPassenger != 'failure') { if (dataCarsLocationByPassenger['message'].length > 0) { for (var i = 0; i < dataCarsLocationByPassenger['message'].length; i++) { var carLocation = dataCarsLocationByPassenger['message'][i]; durationToPassenger = 100; ////// // Calculate the distance between the passenger's location and the current driver's location final distance = Geolocator.distanceBetween( passengerLocation.latitude, passengerLocation.longitude, double.parse(carLocation['latitude']), double.parse(carLocation['longitude']), ); // Update the UI with the distance and duration update(); // If the distance is less than the nearest distance, update the nearest driver if (distance < nearestDistance) { nearestDistance = distance; nearestCar = CarLocation( distance: distance, duration: 0, // We don't have duration information from Geolocator id: carLocation['driver_id'], latitude: double.parse(carLocation['latitude']), longitude: double.parse(carLocation['longitude']), ); print('nearestCar ${nearestDistance.toStringAsFixed(0)}'); // Update the UI with the nearest driver update(); } } } } } // Return the nearest driver return nearestCar; } getNearestDriverByPassengerLocationAPIGOOGLE() async { if (polyLines.isEmpty || data.isEmpty) { return null; // Early return if data is empty } if (!rideConfirm) { double nearestDistance = double.infinity; if (dataCarsLocationByPassenger != 'failure') { if (dataCarsLocationByPassenger['message'].length > 0) { for (var i = 0; i < dataCarsLocationByPassenger['message'].length; i++) { var carLocation = dataCarsLocationByPassenger['message'][i]; // } // isloading = true; update(); // Make API request to get exact distance and duration String apiUrl = '${AppLink.googleMapsLink}distancematrix/json?destinations=${carLocation['latitude']},${carLocation['longitude']}&origins=${passengerLocation.latitude},${passengerLocation.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']; durationToPassenger = data['rows'][0]['elements'][0]['duration']['value']; durationFromDriverToPassenger = Duration(seconds: durationToPassenger.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: durationToPassenger.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); } calculateDistanceBetweenPassengerAndDriverBeforeCancelRide() async { await getDriverCarsLocationToPassengerAfterApplied(); double distance = Geolocator.distanceBetween( passengerLocation.latitude, passengerLocation.longitude, driverCarsLocationToPassengerAfterApplied.last.latitude, driverCarsLocationToPassengerAfterApplied.last.longitude, ); if (distance > 500) { isCancelRidePageShown = true; update(); } else { Get.defaultDialog( title: 'The Driver Will be in your location soon .'.tr, middleText: 'The distance less than 500 meter.'.tr, confirm: MyElevatedButton( title: 'Ok'.tr, onPressed: () { Get.back(); }, ), ); // cancel: MyElevatedButton( // title: 'No.Iwant Cancel Trip.'.tr, onPressed: () {})); } } List headingAngles = []; double calculateAngleBetweenLocations(LatLng start, LatLng end) { double startLat = start.latitude * math.pi / 180; double startLon = start.longitude * math.pi / 180; double endLat = end.latitude * math.pi / 180; double endLon = end.longitude * math.pi / 180; double dLon = endLon - startLon; double y = math.sin(dLon) * cos(endLat); double x = cos(startLat) * math.sin(endLat) - math.sin(startLat) * cos(endLat) * cos(dLon); double angle = math.atan2(y, x); double angleDegrees = angle * 180 / math.pi; return angleDegrees; } late LatLngBounds boundsData; late String startNameAddress; late String endNameAddress; getMap(String origin, destination) async { remainingTime = 25; //to make cancel every call await getCarsLocationByPassenger(); // //print(carsLocationByPassenger); var coordDestination = destination.split(','); double latPassengerDestination = double.parse(coordDestination[0]); double lngPassengerDestination = double.parse(coordDestination[1]); myDestination = LatLng(latPassengerDestination, lngPassengerDestination); if (origin.isEmpty) { origin = '${passengerLocation.latitude.toString().split(',')[0]},${passengerLocation.longitude.toString().split(',')[1]}'; //todo } isLoading = false; update(); var url = ('${AppLink.googleMapsLink}directions/json?&language=${box.read(BoxName.lang)}&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); startNameAddress = data[0]['start_address']; endNameAddress = data[0]['end_address']; isLoading = false; newStartPointLocation = LatLng( data[0]["start_location"]['lat'], data[0]["start_location"]['lng']); markers.add( Marker( markerId: MarkerId('start'), position: newStartPointLocation, icon: startIcon, ), ); markers.add( Marker( markerId: MarkerId('end'), position: LatLng( data[0]["end_location"]['lat'], data[0]["end_location"]['lng']), icon: endIcon, ), ); 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 // 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 LatLngBounds boundsData = LatLngBounds(northeast: northeast, southwest: southwest); // Fit the camera to the bounds var cameraUpdate = CameraUpdate.newLatLngBounds(boundsData, 160); mapController!.animateCamera(cameraUpdate); // getDistanceFromText(data[0]['distance']['text']); double distanceOfTrip = (data[0]['distance']['value']) / 1000; distance = distanceOfTrip; // updateCameraForDistanceAfterGetMap(); 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; isMarkersShown = true; update(); } } double distanceOfDestnation = 0; bool haveSteps = false; late LatLng latestPosition; // getMapPoints(String originSteps, String destinationSteps, int index) async { // isWayPointStopsSheetUtilGetMap = false; // haveSteps = true; // await getCarsLocationByPassenger(); // // isLoading = true; // update(); // String url = '${AppLink.googleMapsLink}directions/json' // '?origin=${coordinatesWithoutEmpty.first}' // '&destination=${coordinatesWithoutEmpty.last}'; // if (coordinatesWithoutEmpty.length > 2) { // String waypoints = ""; // for (int i = 1; i < coordinatesWithoutEmpty.length - 1; i++) { // waypoints += "${coordinatesWithoutEmpty[i]}|"; // } // waypoints = waypoints.substring(0, waypoints.length - 1); // url += "&waypoints=$waypoints"; // } // url += '&language=en' // '&avoid=tolls|ferries' // '&key=${AK.mapAPIKEY}'; // var response = await CRUD().getGoogleApi(link: url, payload: {}); // data = response['routes'][0]['legs']; // // //print(data); // // isLoading = false; // int durationToRide0 = data[0]['duration']['value']; // durationToRide = durationToRide + durationToRide0; // print(durationToRide0); // print('durationToRide = $durationToRide'); // distance = distanceOfDestnation + (data[0]['distance']['value']) / 1000; // update(); // final points = // decodePolyline(response["routes"][0]["overview_polyline"]["points"]); // for (int i = 0; i < points.length; i++) { // if (points[i][0].toString() != '') { // double lat = points[i][0].toDouble(); // double lng = points[i][1].toDouble(); // polylineCoordinatesPointsAll[index].add(LatLng(lat, lng)); // } // } // // Define the northeast and southwest coordinates // update(); // if (polyLines.isNotEmpty) { // // clearPolyline(); // } else { // var polyline = Polyline( // polylineId: PolylineId(response["routes"][0]["summary"]), // points: polylineCoordinatesPointsAll[index], // width: 10, // color: Colors.blue, // ); // polyLines.add(polyline); // rideConfirm = false; // // isMarkersShown = true; // update(); // } // } getMapPoints(String originSteps, String destinationSteps, int index) async { isWayPointStopsSheetUtilGetMap = false; // haveSteps = true; await getCarsLocationByPassenger(); // isLoading = true; update(); var url = ('${AppLink.googleMapsLink}directions/json?&language=${box.read(BoxName.lang)}&avoid=tolls|ferries&destination=$destinationSteps&origin=$originSteps&key=${AK.mapAPIKEY}'); // //print(url); var response = await CRUD().getGoogleApi(link: url, payload: {}); data = response['routes'][0]['legs']; // //print(data); // isLoading = false; int durationToRide0 = data[0]['duration']['value']; durationToRide = durationToRide + durationToRide0; print(durationToRide0); print('durationToRide = $durationToRide'); distance = distanceOfDestnation + (data[0]['distance']['value']) / 1000; update(); final points = decodePolyline(response["routes"][0]["overview_polyline"]["points"]); for (int i = 0; i < points.length; i++) { if (points[i][0].toString() != '') { double lat = points[i][0].toDouble(); double lng = points[i][1].toDouble(); polylineCoordinatesPointsAll[index].add(LatLng(lat, lng)); } } // Define the northeast and southwest coordinates if (polyLines.isNotEmpty) { // clearPolyline(); } else { var polyline = Polyline( polylineId: PolylineId(response["routes"][0]["summary"]), points: polylineCoordinatesPointsAll[index], width: 10, color: Colors.blue, ); polyLines.add(polyline); rideConfirm = false; // isMarkersShown = true; update(); } } void updateCameraForDistanceAfterGetMap() { LatLng coord1 = LatLng( double.parse(coordinatesWithoutEmpty.first.split(',')[0]), double.parse(coordinatesWithoutEmpty.first.split(',')[1])); LatLng coord2 = LatLng( double.parse(coordinatesWithoutEmpty.last.split(',')[0]), double.parse(coordinatesWithoutEmpty.last.split(',')[1])); LatLng northeast; LatLng southwest; if (coord1.latitude > coord2.latitude) { northeast = coord1; southwest = coord2; } else { northeast = coord2; southwest = coord1; } // Create the LatLngBounds object LatLngBounds bounds = LatLngBounds(northeast: northeast, southwest: southwest); print('boundsbounds'); print(bounds); print('boundsbounds'); // Fit the camera to the bounds var cameraUpdate = CameraUpdate.newLatLngBounds(bounds, 180); mapController!.animateCamera(cameraUpdate); update(); } int selectedIndex = -1; // Initialize with no selection void selectCarFromList(int index) { selectedIndex = index; // Update selected index carTypes.forEach( (element) => element.isSelected = false); // Reset selection flags carTypes[index].isSelected = true; 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]; if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) { totalPassenger = totalCostPassenger - (totalCostPassenger * int.parse(firstElement['amount']) / 100); update(); } else { totalPassenger = totalCostPassenger - (totalCostPassenger * int.parse(firstElement['amount']) / 100); update(); } totalDriver = totalDriver - (totalDriver * 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) { durationToAdd = Duration(seconds: durationToRide); print('durationToRide----- $durationToRide'); print('durationToAdd----- $durationToAdd'); hours = durationToAdd.inHours; minutes = (durationToAdd.inMinutes % 60).round(); DateTime currentTime = DateTime.now(); newTime = currentTime.add(durationToAdd); averageDuration = (durationToRide / 60) / distance; costDuration = (durationToRide / 60) * averageDuration * 0.016; print('costDuration----- $costDuration'); print('costDistance----- $costDistance'); print( 'passengerWalletTotal----- ${box.read(BoxName.passengerWalletTotal)}'); update(); if (currentTime.hour >= 22 && currentTime.hour < 5) { costDistance = distance * latePrice; update(); } else if (currentTime.hour >= 13 && currentTime.hour <= 16) { if (averageDuration > 2.5) { costDistance = distance * heavyPrice; update(); } else { costDistance = distance * naturePrice; update(); } } else { costDistance = distance * (naturePrice - .1); update(); } //print('cost $cost'); // if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) { // totalPassenger = totalCostPassenger + // (-1) * (double.parse(box.read(BoxName.passengerWalletTotal))); // update(); // } else { // totalPassenger = totalCostPassenger; // update(); // } var totalDriver1 = costDistance + costDuration; totalCostPassenger = totalDriver1 + (totalDriver1 * kazan / 100); totalPassenger = totalCostPassenger; totalPassengerComfort = totalCostPassenger + (totalCostPassenger * .2); totalPassengerComfortDiscount = totalPassengerComfort + totalPassengerComfort * (kazan - 4) / 100; totalPassengerMotoDelivery = totalCostPassenger - (totalCostPassenger * .35); totalDriver = totalDriver1 + (totalDriver1 * kazan / 100); tax = totalCostPassenger * kazan / 100; totalME = totalCostPassenger - tax; if (totalCostPassenger < 1) { totalCostPassenger = 1; if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) { totalPassenger = totalCostPassenger + (-1) * (double.parse(box.read(BoxName.passengerWalletTotal))); update(); } else { totalPassenger = totalCostPassenger; update(); } update(); // if (totalDriver < .5) { // totalDriver = .75; // totalME = .21; // 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() }); } List polylineCoordinate = []; String? cardNumber; void readyWayPoints() { hintTextwayPointStringAll = [ hintTextwayPoint0, hintTextwayPoint1, hintTextwayPoint2, hintTextwayPoint3, hintTextwayPoint4, ]; polylineCoordinatesPointsAll = [ polylineCoordinates0, polylineCoordinates1, polylineCoordinates2, polylineCoordinates3, polylineCoordinates4, ]; allTextEditingPlaces = [ wayPoint0Controller, wayPoint1Controller, wayPoint2Controller, wayPoint3Controller, wayPoint4Controller, ]; currentLocationToFormPlacesAll = [ currentLocationToFormPlaces0, currentLocationToFormPlaces1, currentLocationToFormPlaces2, currentLocationToFormPlaces3, currentLocationToFormPlaces4, ]; placeListResponseAll = [ wayPoint0, wayPoint1, wayPoint2, wayPoint3, wayPoint4 ]; startLocationFromMapAll = [ startLocationFromMap0, startLocationFromMap1, startLocationFromMap2, startLocationFromMap3, startLocationFromMap4, ]; currentLocationStringAll = [ currentLocationString0, currentLocationString1, currentLocationString2, currentLocationString3, currentLocationString4, ]; placesCoordinate = [ placesCoordinate0, placesCoordinate1, placesCoordinate2, placesCoordinate3, placesCoordinate4, ]; update(); } initilizeGetStorage() async { if (box.read(BoxName.addWork) == null) { box.write(BoxName.addWork, 'addWork'); } if (box.read(BoxName.addHome) == null) { box.write(BoxName.addHome, 'addHome'); } } late List recentPlaces = []; getFavioratePlaces() async { recentPlaces = await sql.getAllData(TableName.recentLocations); } getKazanPercent() async { var res = await CRUD().get(link: AppLink.getKazanPercent); if (res != 'failure') { kazan = double.parse(jsonDecode(res)['message'][0]['kazan']); naturePrice = double.parse(jsonDecode(res)['message'][0]['naturePrice']); heavyPrice = double.parse(jsonDecode(res)['message'][0]['heavyPrice']); latePrice = double.parse(jsonDecode(res)['message'][0]['latePrice']); } } @override void onInit() async { mapAPIKEY = await storage.read(key: BoxName.mapAPIKEY); getFavioratePlaces(); readyWayPoints(); await getLocation(); await addToken(); await getKazanPercent(); await startMarkerReloading(); // await getCarsLocationByPassenger(); // await getNearestDriverByPassengerLocation(); addCustomPicker(); addCustomCarIcon(); addCustomStepIcon(); addCustomStartIcon(); addCustomEndIcon(); initilizeGetStorage(); cardNumber = await SecureStorage().readData(BoxName.cardNumber); 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, }); }