diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 18f01c9..ce878b4 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,13 @@ + + + + + diff --git a/assets/images/blob.png b/assets/images/blob.png new file mode 100644 index 0000000..e45e42c Binary files /dev/null and b/assets/images/blob.png differ diff --git a/assets/images/car.png b/assets/images/car.png index e011b66..a37a93e 100644 Binary files a/assets/images/car.png and b/assets/images/car.png differ diff --git a/assets/images/carspeed.png b/assets/images/carspeed.png new file mode 100644 index 0000000..b8b2d37 Binary files /dev/null and b/assets/images/carspeed.png differ diff --git a/assets/images/moto.png b/assets/images/moto.png new file mode 100644 index 0000000..0cb9559 Binary files /dev/null and b/assets/images/moto.png differ diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index a34bc20..37834e0 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -11,6 +11,17 @@ NSFaceIDUsageDescription Use Face ID to securely authenticate payment accounts. + + + NSLocationAlwaysUsageDescription + This app needs access to location. + + UIBackgroundModes + + fetch + location + + NSMicrophoneUsageDescription This app requires access to your microphone to record audio, allowing you to add voice recordings to your photos and videos and access to connect to a call. NSCameraUsageDescription diff --git a/lib/constant/box_name.dart b/lib/constant/box_name.dart index d04d59d..dcc9db9 100644 --- a/lib/constant/box_name.dart +++ b/lib/constant/box_name.dart @@ -4,6 +4,7 @@ class BoxName { static const String googlaMapApp = "googlaMapApp"; static const String lang = "lang"; + static const String carType = "carType"; static const String statusDriverLocation = "statusDriverLocation"; static const String password = "password"; static const String passwordDriver = "passwordDriver"; diff --git a/lib/constant/style.dart b/lib/constant/style.dart index fdbea1c..3b721b7 100644 --- a/lib/constant/style.dart +++ b/lib/constant/style.dart @@ -45,7 +45,7 @@ class AppStyle { fontWeight: FontWeight.bold, fontSize: 20, color: AppColor.primaryColor, - fontFamily: GoogleFonts.josefinSans().fontFamily); + fontFamily: GoogleFonts.averiaSansLibre().fontFamily); static BoxDecoration boxDecoration = const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(12)), @@ -64,4 +64,16 @@ class AppStyle { spreadRadius: 0, blurStyle: BlurStyle.outer) ]); + static BoxDecoration boxDecoration1 = const BoxDecoration( + boxShadow: [ + BoxShadow( + color: AppColor.accentColor, blurRadius: 5, offset: Offset(2, 4)), + BoxShadow( + color: AppColor.accentColor, blurRadius: 5, offset: Offset(-2, -2)) + ], + color: AppColor.secondaryColor, + borderRadius: BorderRadius.all( + Radius.elliptical(15, 30), + ), + ); } diff --git a/lib/constant/table_names.dart b/lib/constant/table_names.dart index 4c25042..47cd831 100644 --- a/lib/constant/table_names.dart +++ b/lib/constant/table_names.dart @@ -3,6 +3,7 @@ class TableName { static const String recentLocations = "recentLocations"; static const String carLocations = "carLocations"; static const String driverOrdersRefuse = "driverOrdersRefuse"; + static const String rideLocation = "rideLocation"; static const String faceDetectTimes = "faceDetectTimes"; static const String captainNotification = "captainNotification"; } diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart index 2c5fa08..e7b6055 100644 --- a/lib/controller/firebase/firbase_messge.dart +++ b/lib/controller/firebase/firbase_messge.dart @@ -16,6 +16,7 @@ import '../../constant/style.dart'; import '../../main.dart'; import '../../views/Rate/rate_captain.dart'; import '../../views/home/Captin/home_captain/home_captin.dart'; +import '../../views/home/Captin/orderCaptin/order_speed_request.dart'; import '../../views/home/map_page_passenger.dart'; import '../../views/home/map_widget.dart/call_passenger_page.dart'; import '../../views/home/profile/promos_passenger_page.dart'; @@ -105,10 +106,6 @@ class FirebaseMessagesController extends GetxController { }); FirebaseMessaging.onMessage.listen((RemoteMessage message) { - // if (message.notification != null && message.data.isNotEmpty) { - // fireBaseTitles(message); - // } - // If the app is in the background or terminated, show a system tray message RemoteNotification? notification = message.notification; AndroidNotification? android = notification?.android; @@ -117,13 +114,6 @@ class FirebaseMessagesController extends GetxController { fireBaseTitles(message); } }); - - // FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { - // // print( - // // 'onMessageOpenedApp: ${message.notification!.title} ${message.notification!.body}'); - // RemoteNotification? notification = message.notification; - // fireBaseTitles(message); - // }); } void fireBaseTitles(RemoteMessage message) { @@ -132,14 +122,17 @@ class FirebaseMessagesController extends GetxController { NotificationController().showNotification('Order', '', 'order'); } var myListString = message.data['DriverList']; + // var points = message.data['PolylineJson']; var myList = jsonDecode(myListString) as List; + // var myPoints = jsonDecode(points) as List; driverToken = myList[14].toString(); update(); // print('driverToken==============$driverToken'); Get.to(() => OrderRequestPage(), arguments: { 'myListString': myListString, 'DriverList': myList, + // 'PolylineJson': myPoints, 'body': message.notification!.body }); } else if (message.notification!.title! == 'Apply Ride') { @@ -228,6 +221,28 @@ class FirebaseMessagesController extends GetxController { 'order'); Get.find().restCounter(); Get.offAll(const MapPagePassenger()); + } else if (message.notification!.title! == 'Order Applied') { + Get.snackbar( + "The order has been accepted by another driver.", // Corrected grammar + "Be more mindful next time to avoid dropping orders.", // Improved sentence structure + backgroundColor: AppColor.yellowColor, + snackPosition: SnackPosition.BOTTOM, + ); + } else if (message.notification!.title! == 'OrderSpeed') { + var myListString = message.data['DriverList']; + // var points = message.data['PolylineJson']; + + var myList = jsonDecode(myListString) as List; + // var myPoints = jsonDecode(points) as List; + driverToken = myList[14].toString(); + update(); + // print('driverToken==============$driverToken'); + Get.to(() => OrderSpeedRequest(), arguments: { + 'myListString': myListString, + 'DriverList': myList, + // 'PolylineJson': myPoints, + 'body': message.notification!.body + }); } } @@ -517,6 +532,45 @@ class FirebaseMessagesController extends GetxController { print('sendNotification() error: $e'); } } + + void sendNotificationToDriverMapPolyline(String title, String body, + String token, List data, String polylineJson) async { + try { + final response = await http.post( + Uri.parse('https://fcm.googleapis.com/fcm/send'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'key=${AK.serverAPI}' + }, + body: jsonEncode({ + 'notification': { + 'title': title, + 'body': body, + // 'sound': 'tone2.wav', + 'sound': 'order.wav' + }, + 'data': { + 'DriverList': data, + 'PolylineJson': polylineJson, + }, + 'priority': 'high', + 'to': token, + }), + ); + + if (response.statusCode == 200) { + // Notification sent successfully + print('Notification sent successfully'); + } else { + // Handle error response + print( + 'Failed to send notification. Status code: ${response.statusCode}'); + } + } catch (e) { + // Handle other exceptions + print('sendNotification() error: $e'); + } + } } class DriverTipWidget extends StatelessWidget { diff --git a/lib/controller/functions/location_controller.dart b/lib/controller/functions/location_controller.dart index 8ff374b..c7fe620 100644 --- a/lib/controller/functions/location_controller.dart +++ b/lib/controller/functions/location_controller.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:SEFER/constant/table_names.dart'; import 'package:get/get.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:location/location.dart'; @@ -25,35 +26,46 @@ class LocationController extends GetxController { super.onInit(); location = Location(); getLocation(); - // myLocation=getLocation(); + // startLocationUpdates(); totalPoints = Get.put(CaptainWalletController()).totalPoints; } - void startLocationUpdates() async { - _locationTimer = Timer.periodic(const Duration(seconds: 5), (timer) async { - try { - totalPoints = Get.find().totalPoints; + Future startLocationUpdates() async { + if (box.read(BoxName.driverID) != null) { + _locationTimer = + Timer.periodic(const Duration(seconds: 5), (timer) async { + try { + totalPoints = Get.find().totalPoints; - // if (isActive) { - if (double.parse(totalPoints) > -500) { - print('total point is $totalPoints'); - await getLocation(); + // if (isActive) { + if (double.parse(totalPoints) > -300) { + print('total point is $totalPoints'); + await getLocation(); - await CRUD().post(link: AppLink.addCarsLocationByPassenger, payload: { - 'driver_id': box.read(BoxName.driverID).toString(), - 'latitude': myLocation.latitude.toString(), - 'longitude': myLocation.longitude.toString(), - 'status': box.read(BoxName.statusDriverLocation).toString() - }); + await CRUD() + .post(link: AppLink.addCarsLocationByPassenger, payload: { + 'driver_id': box.read(BoxName.driverID).toString(), + 'latitude': myLocation.latitude.toString(), + 'longitude': myLocation.longitude.toString(), + 'status': box.read(BoxName.statusDriverLocation).toString() + }); + await sql.insertData({ + 'driver_id': box.read(BoxName.driverID), + 'latitude': myLocation.latitude.toString(), + 'longitude': myLocation.longitude.toString(), + 'created_at': DateTime.now().toString(), + }, TableName.carLocations); + // + } + + // } + } catch (e) { + // Handle the error gracefully + print('Error during location updates: $e'); } - - // } - } catch (e) { - // Handle the error gracefully - print('Error during location updates: $e'); - } - }); + }); + } } void stopLocationUpdates() { diff --git a/lib/controller/home/captin/home_captain_controller.dart b/lib/controller/home/captin/home_captain_controller.dart index 17c787f..ae2a31a 100644 --- a/lib/controller/home/captin/home_captain_controller.dart +++ b/lib/controller/home/captin/home_captain_controller.dart @@ -58,7 +58,7 @@ class HomeCaptainController extends GetxController { isActive = !isActive; if (isActive) { - if (double.parse(totalPoints) > -500) { + if (double.parse(totalPoints) > -300) { locationController.startLocationUpdates(); activeStartTime = DateTime.now(); activeTimer = Timer.periodic(const Duration(seconds: 1), (timer) { @@ -105,7 +105,7 @@ class HomeCaptainController extends GetxController { await sql.getCustomQuery(customQuery); countRefuse = results[0]['count'].toString(); update(); - if (int.parse(countRefuse) > 3 || double.parse(totalPoints) <= -500) { + if (int.parse(countRefuse) > 3 || double.parse(totalPoints) <= -300) { print('total point is $totalPoints'); locationController.stopLocationUpdates(); activeStartTime = null; @@ -202,8 +202,8 @@ class HomeCaptainController extends GetxController { getAllPayment(); startPeriodicExecution(); onMapCreated(mapHomeCaptaiController); - getRefusedOrderByCaptain(); totalPoints = Get.find().totalPoints; + getRefusedOrderByCaptain(); // LocationController().getLocation(); super.onInit(); } diff --git a/lib/controller/home/captin/map_driver_controller.dart b/lib/controller/home/captin/map_driver_controller.dart index af7e42f..d46d3e7 100644 --- a/lib/controller/home/captin/map_driver_controller.dart +++ b/lib/controller/home/captin/map_driver_controller.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'dart:convert'; - +import 'dart:math' as math; +import 'dart:math' show cos; +import 'package:SEFER/constant/table_names.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:get/get.dart'; @@ -49,10 +51,10 @@ class MapDriverController extends GetxController { late String duration; late String totalCost; late String distance; - late String name; - late String email; + late String passengerName; + late String passengerEmail; late String totalPassenger; - late String phone; + late String passengerPhone; late String rideId; late String isHaveSteps; late String paymentAmount; @@ -72,6 +74,7 @@ class MapDriverController extends GetxController { bool isdriverWaitTimeEnd = false; bool isRideFinished = false; bool isRideStarted = false; + bool isPriceWindow = false; double passengerInfoWindow = Get.height * .39; double driverEndPage = 100; double progress = 0; @@ -177,29 +180,29 @@ class MapDriverController extends GetxController { } void startTimerToShowPassengerInfoWindowFromDriver() async { - for (int i = 0; - i <= progressTimerToShowPassengerInfoWindowFromDriver; - i++) { - await Future.delayed(const Duration(seconds: 1)); - if (canelString != 'Cancel') { - cancelCheckRidefromPassenger(); - progress = i / progressTimerToShowPassengerInfoWindowFromDriver; - remainingTimeToShowPassengerInfoWindowFromDriver = - progressTimerToShowPassengerInfoWindowFromDriver - i; + // for (int i = 0; + // i <= progressTimerToShowPassengerInfoWindowFromDriver; + // i++) { + // await Future.delayed(const Duration(seconds: 1)); + // if (canelString != 'Cancel') { + // cancelCheckRidefromPassenger(); + // progress = i / progressTimerToShowPassengerInfoWindowFromDriver; + // remainingTimeToShowPassengerInfoWindowFromDriver = + // progressTimerToShowPassengerInfoWindowFromDriver - i; - if (remainingTimeToShowPassengerInfoWindowFromDriver == 0) { - isPassengerInfoWindow = true; - print(isPassengerInfoWindow); - update(); - startTimerToShowDriverToPassengerDuration(); - } - print(isPassengerInfoWindow); - print(remainingTimeToShowPassengerInfoWindowFromDriver); - update(); - } else { - Get.off(HomeCaptain()); - } - } + // if (remainingTimeToShowPassengerInfoWindowFromDriver == 0) { + isPassengerInfoWindow = true; + // print(isPassengerInfoWindow); + update(); + startTimerToShowDriverToPassengerDuration(); + // } + // print(isPassengerInfoWindow); + // print(remainingTimeToShowPassengerInfoWindowFromDriver); + // update(); + // } else { + // Get.off(HomeCaptain()); + // } + // } } String stringRemainingTimeToPassenger = ''; @@ -312,6 +315,16 @@ class MapDriverController extends GetxController { Position? currentPosition; + calculateDistanceAndTimeSPEEDOMETER() async { +/* todo +save to sql +calculate distance and duration +get from sql +update ui for totla results + +*/ + } + void startRideFromDriver() async { double _distance = await calculateDistanseBetweenDriverAndPassengerLocation(); @@ -371,14 +384,34 @@ class MapDriverController extends GetxController { } } + calcualateDistsanceInMetet(LatLng prev, LatLng current) async { + double distance2 = Geolocator.distanceBetween( + prev.latitude, + prev.longitude, + current.latitude, + current.longitude, + ); + return distance2; + } + + double speedoMeter = 0; void updateLocation() async { StreamSubscription? locationSubscription; try { + LatLng? latestPosition; // Initialize outside the loop for (var i = 0; i < remainingTimeTimerRideBegin; i++) { await Future.delayed(const Duration(seconds: 2)); locationSubscription = Geolocator.getPositionStream().listen((Position position) { + latestPosition = position as LatLng?; // Update latest position + + // Calculate distance using the latest position + double distance = calcualateDistsanceInMetet( + currentPosition as LatLng, latestPosition!); + speedoMeter = distance + speedoMeter; + print('distance is $distance'); + print('SpedoMeter is $speedoMeter'); currentPosition = position; // Update camera position on the map mapController!.animateCamera( @@ -466,6 +499,7 @@ class MapDriverController extends GetxController { // if (distanceToDestination < 50) { isRideFinished = true; isRideStarted = false; + isPriceWindow = false; box.write(BoxName.statusDriverLocation, 'off'); // changeRideToBeginToPassenger(); @@ -500,11 +534,7 @@ class MapDriverController extends GetxController { box.read(BoxName.tokenDriver), ], ); - Get.to(() => RatePassenger(), arguments: { - 'rideId': rideId, - 'passengerId': passengerId, - 'driverId': driverId - }); + // } else { // Get.defaultDialog( // title: 'You don\'t arrive destenation yet .'.tr, @@ -516,7 +546,7 @@ class MapDriverController extends GetxController { // })); // } // add wallet from passenger from driver - + Get.to(() => RatePassenger()); // Get.back(); } @@ -576,19 +606,76 @@ class MapDriverController extends GetxController { } } - void updateMarker() { + double calculateDistanceBetweenLocations(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 dLat = endLat - startLat; + double dLon = endLon - startLon; + + double a = math.pow(math.sin(dLat / 2), 2) + + math.cos(startLat) * math.cos(endLat) * math.pow(math.sin(dLon / 2), 2); + double c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)); + double distance = 6371000 * c; // Distance in meters + + return distance; + } + + 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; + } + + double recentDistanceToDash = 0; + double recentAngelToMarker = 0; + void updateMarker() async { // Remove the existing marker with the ID `MyLocation`. - markers.remove(MarkerId('MyLocation'.tr)); + markers.remove(MarkerId('MyLocation')); // Add a new marker with the ID `MyLocation` at the current location of the user. LocationController locationController = Get.find(); myLocation = locationController.myLocation; + final previousLocationOfDrivers = await sql.getCustomQuery( + 'Select * from ${TableName.carLocations} where order_id =$rideId Order by created_at DESC limit 1'); + +//get from sql + if (previousLocationOfDrivers.isNotEmpty) { + var lat = double.parse(previousLocationOfDrivers[0]['lat']); + var lng = double.parse(previousLocationOfDrivers[0]['lng']); + LatLng prev = LatLng(lat, lng); + recentAngelToMarker = calculateAngleBetweenLocations(prev, myLocation); + recentDistanceToDash = + calculateDistanceBetweenLocations(prev, myLocation); + } + sql.insertData({ + 'order_id': rideId, + 'created_at': DateTime.now().microsecondsSinceEpoch.toString(), + 'lat': myLocation.latitude.toString(), + 'lng': myLocation.longitude.toString(), + }, TableName.rideLocation); + markers.add( Marker( markerId: MarkerId('MyLocation'.tr), position: locationController.myLocation, draggable: true, icon: carIcon, + rotation: recentAngelToMarker, // infoWindow: const InfoWindow( // title: 'Time', // ), @@ -795,10 +882,10 @@ class MapDriverController extends GetxController { passengerId = Get.arguments['passengerId']; driverId = Get.arguments['driverId']; distance = Get.arguments['Distance']; - name = Get.arguments['name']; - email = Get.arguments['email']; + passengerName = Get.arguments['name']; + passengerEmail = Get.arguments['email']; totalPassenger = Get.arguments['totalPassenger']; - phone = Get.arguments['phone']; + passengerPhone = Get.arguments['phone']; walletChecked = Get.arguments['WalletChecked']; tokenPassenger = Get.arguments['tokenPassenger']; direction = Get.arguments['direction']; diff --git a/lib/controller/home/captin/order_request_controller.dart b/lib/controller/home/captin/order_request_controller.dart index c4dc0d2..b8bedf2 100644 --- a/lib/controller/home/captin/order_request_controller.dart +++ b/lib/controller/home/captin/order_request_controller.dart @@ -12,8 +12,11 @@ import '../../functions/location_controller.dart'; class OrderRequestController extends GetxController { double progress = 0; - int duration = 20; + double progressSpeed = 0; + int duration = 10; + int durationSpeed = 20; int remainingTime = 0; + int remainingTimeSpeed = 0; String countRefuse = '0'; bool applied = false; final locationController = Get.put(LocationController()); @@ -81,19 +84,43 @@ class OrderRequestController extends GetxController { if (applied == false) { print('applied========================='); print(applied); - refuseOrder(driverID, orderID); + refuseOrder(orderID); } } } - void refuseOrder(String driverID, orderID) async { + void startTimerSpeed(String driverID, orderID) async { + for (int i = 0; i <= durationSpeed; i++) { + await Future.delayed(const Duration(seconds: 1)); + progressSpeed = i / durationSpeed; + remainingTimeSpeed = durationSpeed - i; + + update(); + } + if (remainingTimeSpeed == 0) { + if (applied == false) { + print('applied========================='); + print(applied); + Get.back(); + // refuseOrder(box.read(BoxName.driverID), orderID); + } + } + } + + void refuseOrder(orderID) async { await CRUD().postFromDialogue(link: AppLink.addDriverOrder, payload: { //TODO need review - 'driver_id': box.read(BoxName.driverID).toString(), + 'driver_id': box.read(BoxName.driverID), // box.read(BoxName.driverID).toString(), 'order_id': orderID, 'status': 'Refused' }); + await CRUD().post(link: AppLink.updateRides, payload: { + 'id': orderID, + 'rideTimeStart': DateTime.now().toString(), + 'status': 'Refused', + 'driver_id': box.read(BoxName.driverID), + }); Get.back(); // applied = true; sql.insertData({ diff --git a/lib/controller/home/captin/widget/call_page.dart b/lib/controller/home/captin/widget/call_page.dart index 472c758..917a8bb 100644 --- a/lib/controller/home/captin/widget/call_page.dart +++ b/lib/controller/home/captin/widget/call_page.dart @@ -64,7 +64,7 @@ GetBuilder callPage() { Column( children: [ Text(callController.status), - Text(Get.find().name.toString()), + Text(Get.find().passengerName.toString()), ], ), GestureDetector( diff --git a/lib/controller/home/captin/widget/connect.dart b/lib/controller/home/captin/widget/connect.dart index 08ff3df..3e5ff04 100644 --- a/lib/controller/home/captin/widget/connect.dart +++ b/lib/controller/home/captin/widget/connect.dart @@ -25,19 +25,19 @@ class ConnectWidget extends StatelessWidget { builder: (homeCaptainController) => int.parse( orderRequestController.countRefuse) > 3 || - double.parse(captainWalletController.totalPoints) < -500 + double.parse(captainWalletController.totalPoints) < -300 ? CupertinoButton( onPressed: () { Get.defaultDialog( // backgroundColor: CupertinoColors.destructiveRed, barrierDismissible: false, title: double.parse(captainWalletController.totalPoints) < - -500 + -300 ? 'You dont have Points'.tr : 'You Are Stopped For this Day !'.tr, titleStyle: AppStyle.title, content: Text( - double.parse(captainWalletController.totalPoints) < -500 + double.parse(captainWalletController.totalPoints) < -300 ? 'You must be recharge your Account'.tr : 'You Refused 3 Rides this Day that is the reason \nSee you Tomorrow!' .tr, @@ -45,7 +45,7 @@ class ConnectWidget extends StatelessWidget { ), confirm: double.parse(captainWalletController.totalPoints) < - -500 + -300 ? MyElevatedButton( title: 'Recharge my Account'.tr, onPressed: () { diff --git a/lib/controller/home/captin/widget/left_menu_map_captain.dart b/lib/controller/home/captin/widget/left_menu_map_captain.dart index 7d67f86..27e06d8 100644 --- a/lib/controller/home/captin/widget/left_menu_map_captain.dart +++ b/lib/controller/home/captin/widget/left_menu_map_captain.dart @@ -3,9 +3,11 @@ import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:get/get.dart'; import 'package:SEFER/controller/home/captin/home_captain_controller.dart'; import 'package:SEFER/controller/home/captin/widget/zones_controller.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; import '../../../../constant/colors.dart'; import '../../../../views/Rate/ride_calculate_driver.dart'; +import '../../../functions/location_controller.dart'; GetBuilder leftMainMenuCaptainIcons() { return GetBuilder( @@ -78,6 +80,27 @@ GetBuilder leftMainMenuCaptainIcons() { const SizedBox( height: 5, ), + AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTraffic, + decoration: BoxDecoration( + color: AppColor.secondaryColor, + border: Border.all(), + borderRadius: BorderRadius.circular(15)), + child: IconButton( + onPressed: () { + controller.mapHomeCaptaiController + .animateCamera(CameraUpdate.newLatLng(LatLng( + Get.find().myLocation.latitude, + Get.find().myLocation.longitude, + ))); + }, + icon: const Icon( + Icons.location_on, + size: 29, + ), + ), + ), AnimatedContainer( duration: const Duration(microseconds: 200), width: controller.widthMapTypeAndTraffic, diff --git a/lib/controller/home/map_passenger_controller.dart b/lib/controller/home/map_passenger_controller.dart index 59ce480..f20aed1 100644 --- a/lib/controller/home/map_passenger_controller.dart +++ b/lib/controller/home/map_passenger_controller.dart @@ -3,6 +3,7 @@ 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:flutter/services.dart'; import 'package:geolocator/geolocator.dart'; @@ -20,8 +21,10 @@ 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'; @@ -32,6 +35,7 @@ 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(); @@ -40,9 +44,14 @@ class MapPassengerController extends GetxController { 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 = []; @@ -50,7 +59,7 @@ class MapPassengerController extends GetxController { List wayPoint2 = []; List wayPoint3 = []; List wayPoint4 = []; - + final textToSpeechController = Get.put(TextToSpeechController()); List> placeListResponseAll = []; List placeListResponse = [ @@ -123,7 +132,7 @@ class MapPassengerController extends GetxController { bool isMainBottomMenuMap = true; late Timer markerReloadingTimer2; late Timer markerReloadingTimer1; - late int duration1; + late int durationToPassenger = 0; bool isWayPointSheet = false; bool isWayPointStopsSheet = false; bool isWayPointStopsSheetUtilGetMap = false; @@ -145,7 +154,7 @@ class MapPassengerController extends GetxController { double progress = 0; double progressTimerToPassengerFromDriverAfterApplied = 0; double progressTimerDriverWaitPassenger5Minute = 0; - int durationTimer = 25; + int durationTimer = 9; int durationToRide = 0; int remainingTime = 25; int remainingTimeToPassengerFromDriverAfterApplied = 60; @@ -181,6 +190,7 @@ class MapPassengerController extends GetxController { bool noCarString = false; bool isCashSelectedBeforeConfirmRide = false; bool isPassengerChosen = false; + bool isSearchingWindow = false; bool currentLocationToFormPlaces = false; bool currentLocationToFormPlaces0 = false; bool currentLocationToFormPlaces1 = false; @@ -196,6 +206,9 @@ class MapPassengerController extends GetxController { 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; @@ -306,6 +319,22 @@ class MapPassengerController extends GetxController { } } + 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; @@ -397,6 +426,9 @@ class MapPassengerController extends GetxController { isCashConfirmPageShown = !isCashConfirmPageShown; isCashSelectedBeforeConfirmRide = true; cashConfirmPageShown = isCashConfirmPageShown == true ? 250 : 0; + // to get or sure picker point for origin //todo + // isPickerShown = true; + // clickPointPosition(); update(); } @@ -459,8 +491,22 @@ class MapPassengerController extends GetxController { 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; i++) { + for (int i = 0; + i <= timeToPassengerFromDriverAfterApplied && + isTimerFromDriverToPassengerAfterAppliedRunning; + i++) { await Future.delayed(const Duration(seconds: 1)); progressTimerToPassengerFromDriverAfterApplied = i / timeToPassengerFromDriverAfterApplied; @@ -483,7 +529,14 @@ class MapPassengerController extends GetxController { } } + // Function to stop the timer + void stopTimerFromDriverToPassengerAfterApplied() { + isTimerFromDriverToPassengerAfterAppliedRunning = false; + update(); + } + void startTimerDriverWaitPassenger5Minute() async { + stopTimerFromDriverToPassengerAfterApplied(); isDriverArrivePassenger = true; isDriverInPassengerWay = false; timeToPassengerFromDriverAfterApplied = 0; @@ -572,7 +625,7 @@ class MapPassengerController extends GetxController { var res = await CRUD() .get(link: AppLink.getRideStatusBegin, payload: {'ride_id': rideId}); if (res == 'failure') { - //print(res); + // print(res); } var decode = jsonDecode(res); @@ -685,13 +738,17 @@ class MapPassengerController extends GetxController { update(); } + int currentTimeSearchingCaptainWindow = 0; late String driverPhone; + late String driverRate; late String firstName; + late String carColor; + late String carYear; late String model; late String licensePlate; - changeConfirmRide() async { + confirmRideForFirstDriver() async { await getCarsLocationByPassenger(); - await getNearestDriverByPassengerLocation(); + await getNearestDriverByPassengerLocationAPIGOOGLE(); if (dataCarsLocationByPassenger != 'failure') { driverToken = @@ -701,10 +758,17 @@ class MapPassengerController extends GetxController { 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'].toString(); + '${dataCarsLocationByPassenger['message'][carsOrder]['model']} - ${dataCarsLocationByPassenger['message'][carsOrder]['make']}'; licensePlate = dataCarsLocationByPassenger['message'][carsOrder] - ['license_plate'] + ['car_plate'] .toString(); PaymentController paymentController = Get.find(); @@ -712,6 +776,7 @@ class MapPassengerController extends GetxController { shouldFetch = true; isBottomSheetShown = false; timeToPassengerFromDriverAfterApplied = 60; + isDriversTokensSend = false; update(); // //print('rideConfirm= $rideConfirm'); @@ -754,7 +819,7 @@ class MapPassengerController extends GetxController { distanceByPassenger.toString(), paymentController.isWalletChecked.toString(), dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(), - duration1.toString(), + durationToPassenger.toString(), rideId, rideTimerBegin.toString(), dataCarsLocationByPassenger['message'][carsOrder]['driver_id'] @@ -775,12 +840,13 @@ class MapPassengerController extends GetxController { : '0', box.read(BoxName.email).toString(), ]; - FirebaseMessagesController().sendNotificationToDriverMAP( - 'Order', - jsonDecode(value)['message'].toString(), - dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(), - body, - ); + FirebaseMessagesController().sendNotificationToDriverMapPolyline( + 'Order', + jsonDecode(value)['message'].toString(), + dataCarsLocationByPassenger['message'][carsOrder]['token'] + .toString(), + body, + polylineCoordinates.toString()); // //print(dataCarsLocationByPassenger); // //print(dataCarsLocationByPassenger['message'][0]['token'].toString()); }); @@ -801,42 +867,130 @@ class MapPassengerController extends GetxController { } } + bool isDriversTokensSend = false; + confirmRideForAllDriverAvailable() async { + // isDriversTokensSend = true; + PaymentController paymentController = Get.find(); + rideConfirm = true; + shouldFetch = true; + isBottomSheetShown = false; + timeToPassengerFromDriverAfterApplied = 60; + + 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(), + ]; + print('driversToken'); + print(driversToken); + for (var i = 0; i < driversToken.length; i++) { + FirebaseMessagesController().sendNotificationToDriverMapPolyline( + 'OrderSpeed', + rideId.toString(), + driversToken[i], + body, + polylineCoordinates.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())); + // } + } + + String statusRide = 'wait'; 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}); + .get(link: AppLink.getRideStatus, payload: {'id': rideId}); + print(res); var decod = jsonDecode(res); - //print(' 0000000000000000000000000000000000000000000000000'); - //print(decod['data']); + print(' 0000000000000000000000000000000000000000000000000'); + print(decod['data']); if (decod['data'].toString() == 'Apply') { + getUpdatedRideForDriverApply(rideId); shouldFetch = false; // Stop further fetches + statusRide = 'Apply'; rideConfirm = false; + isSearchingWindow = 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( - barrierDismissible: false, - 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(); + // isDriversTokensSend = false; + if (isDriversTokensSend == false) { + confirmRideForAllDriverAvailable(); + isDriversTokensSend = true; } + // else{ + // j + // } + // else { + // Get.defaultDialog( + // barrierDismissible: false, + // title: 'There no Driver Aplly your order sorry for that '.tr, + // // middleText: 'try next time .'.tr, + // content: IconButton( + // onPressed: () { + // textToSpeechController.speakText( + // 'There no Driver Aplly your order sorry for that '.tr); + // }, + // icon: const Icon( + // Icons.headphones, + // size: 40, + // ), + // ), + // titleStyle: AppStyle.title, + // confirm: MyElevatedButton( + // title: 'Back', + // onPressed: () => Get.offAll(const MapPagePassenger()), + // )); + + // cancelRideAfterRejectFromAll(); + // } } else { delayAndFetchRideStatus( rideId); // Repeat the delay and fetch operation @@ -855,7 +1009,7 @@ class MapPassengerController extends GetxController { rideConfirm = false; // //print(timeToPassengerFromDriverAfterApplied); - timeToPassengerFromDriverAfterApplied += duration1; + timeToPassengerFromDriverAfterApplied += durationToPassenger; // //print(duration1); // //print('timeToPassengerFromDriverAfterApplied====' + @@ -883,15 +1037,36 @@ class MapPassengerController extends GetxController { return response['status']; } + late String driverCarModel, driverCarMake, driverLicensePlate, driverName; + getUpdatedRideForDriverApply(String rideId) async { + // if (isDriversTokensSend) { + final response = + await CRUD().get(link: AppLink.getRideOrderID, payload: {'id': rideId}); + if (response != 'failure') { + driverId = response['data']['driver_id']; + driverPhone = response['data']['phone']; + driverCarMake = response['data']['make']; + driverCarModel = response['data']['model']; + driverLicensePlate = response['data']['license_plate']; + driverName = response['data']['first_name']; + driverToken = response['data']['token']; + } + 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; Future getCarsLocationByPassenger() async { // if (rideConfirm == false) { carsLocationByPassenger = []; LatLngBounds bounds = calculateBounds( - passengerLocation.latitude, passengerLocation.longitude, 4000); - //print( - // 'Southwest: ${bounds.southwest.latitude}, ${bounds.southwest.longitude}'); - //print( - // 'Northeast: ${bounds.northeast.latitude}, ${bounds.northeast.longitude}'); + passengerLocation.latitude, passengerLocation.longitude, 7000); var res = await CRUD().get(link: AppLink.getCarsLocationByPassenger, payload: { @@ -916,20 +1091,36 @@ class MapPassengerController extends GetxController { // } // //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++) { - carsLocationByPassenger.add(LatLng( - double.parse(dataCarsLocationByPassenger['message'][i]['latitude']), - double.parse( - dataCarsLocationByPassenger['message'][i]['longitude']))); - update(); + currentDriverLocation = LatLng( + double.parse(dataCarsLocationByPassenger['message'][i]['latitude']), + double.parse(dataCarsLocationByPassenger['message'][i]['longitude']), + ); + + // Update lastDriverLocation on each iteration + previousLocationOfDrivers = currentDriverLocation; + + carsLocationByPassenger.add(currentDriverLocation); + driversToken.add(dataCarsLocationByPassenger['message'][i]['token']); } - update(); + // // Calculate rotation angle here (explained below) + // if (previousLocationOfDrivers != null) { + // angleDegrees = calculateAngleBetweenLocations( + // previousLocationOfDrivers, currentDriverLocation); + // // Use rotationAngle for marker rotation logic // } + + update(); } } - late LatLng driverLocationToPassenger = LatLng(32, 35); + LatLng driverLocationToPassenger = LatLng(32, 35); Future getDriverCarsLocationToPassengerAfterApplied() async { driverCarsLocationToPassengerAfterApplied = []; @@ -954,7 +1145,7 @@ class MapPassengerController extends GetxController { Future runEvery30SecondsUntilConditionMet() async { // Calculate the duration of the trip in minutes. - double tripDurationInMinutes = duration1 / 4; + 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++) { @@ -972,7 +1163,13 @@ class MapPassengerController extends GetxController { for (var i = 0; i < driverCarsLocationToPassengerAfterApplied.length; i++) { // } // for (var item in driverCarsLocationToPassengerAfterApplied) { - final marker = Marker( + double rotationCar = calculateAngleBetweenLocations( + LatLng(driverCarsLocationToPassengerAfterApplied[i - 1].latitude, + driverCarsLocationToPassengerAfterApplied[i - 1].longitude), + LatLng(driverCarsLocationToPassengerAfterApplied[i].latitude, + driverCarsLocationToPassengerAfterApplied[i].longitude)); + final driverAcceptedMarker = Marker( + onTap: () => print('marker pressed'), infoWindow: InfoWindow( title: '${driverCarsLocationToPassengerAfterApplied[i].latitude} minutes'), @@ -981,8 +1178,9 @@ class MapPassengerController extends GetxController { .toString()), position: LatLng(driverCarsLocationToPassengerAfterApplied[i].latitude, driverCarsLocationToPassengerAfterApplied[i].longitude), + rotation: rotationCar, ); - markers.add(marker); + markers.add(driverAcceptedMarker); update(); mapController?.animateCamera(CameraUpdate.newLatLng(LatLng( driverCarsLocationToPassengerAfterApplied[i].latitude, @@ -1042,6 +1240,7 @@ class MapPassengerController extends GetxController { rideConfirm = false; shouldFetch = false; isCashConfirmPageShown = false; + isSearchingWindow = false; isPassengerChosen = false; isCashSelectedBeforeConfirmRide = false; isPickerShown = false; @@ -1068,6 +1267,7 @@ class MapPassengerController extends GetxController { rideConfirm = false; shouldFetch = false; isCashConfirmPageShown = false; + isSearchingWindow = false; isPassengerChosen = false; isCashSelectedBeforeConfirmRide = false; haveSteps = false; @@ -1104,7 +1304,7 @@ class MapPassengerController extends GetxController { } else { isMainBottomMenuMap = !isMainBottomMenuMap; mainBottomMenuMapHeight = - isMainBottomMenuMap == true ? Get.height * .2 : Get.height * .6; + isMainBottomMenuMap == true ? Get.height * .2 : Get.height * .45; isWayPointSheet = false; if (heightMenuBool == true) { getDrawerMenu(); @@ -1423,47 +1623,58 @@ class MapPassengerController extends GetxController { // }); // } - void startMarkerReloading() { + Future startMarkerReloading() async { int reloadCount = 0; - Timer.periodic(const Duration(seconds: 12), (timer) { + Timer.periodic(const Duration(seconds: 3), (timer) { reloadCount++; //print('Reloading markers ($reloadCount)'); reloadMarkers(); - if (reloadCount >= 6) { + if (reloadCount >= 70) { timer.cancel(); // Stop the timer after 5 reloads //print('Marker reloading completed.'); } }); } - void reloadMarkers() async { - await getCarsLocationByPassenger(); + reloadMarkers() async { + if (statusRide == 'wait') { + await getCarsLocationByPassenger(); + await getNearestDriverByPassengerLocation(); + // markers.clear(); - // 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(); + // if (rideConfirm) { + + // } + // Add new markers + // Example: Add a marker for each item in a list + for (var item in carsLocationByPassenger) { + // if (previousLocationOfDrivers != null) { + // angleDegrees = calculateAngleBetweenLocations( + // previousLocationOfDrivers, currentLocationOfDrivers); + // // Use the calculated angle for rotation, if needed + // print('angleDegrees $angleDegrees'); + // print('previousLocationOfDrivers $previousLocationOfDrivers'); + // print('currentLocationOfDrivers $currentLocationOfDrivers'); + // } + final marker = Marker( + infoWindow: InfoWindow(title: '${item.latitude} minutes'), + markerId: MarkerId(durationToPassenger.toString()), + position: LatLng(item.latitude, item.longitude), + rotation: math.Random().nextDouble() * 360, + // Other properties for the marker, such as icon, info window, etc. + ); + markers.add(marker); + update(); + } + + // Update the map with the new markers + // mapController?.animateCamera(CameraUpdate.newLatLng( + // LatLng(passengerLocation.latitude, passengerLocation.longitude))); } - - // Update the map with the new markers - // mapController?.animateCamera(CameraUpdate.newLatLng( - // LatLng(passengerLocation.latitude, passengerLocation.longitude))); } String durationByPassenger = ''; @@ -1471,8 +1682,57 @@ class MapPassengerController extends GetxController { late DateTime timeFromDriverToPassenger = DateTime.now(); String distanceByPassenger = ''; late Duration durationFromDriverToPassenger; + double nearestDistance = double.infinity; + Future 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']), + ); - getNearestDriverByPassengerLocation() async { + // 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 } @@ -1499,10 +1759,11 @@ class MapPassengerController extends GetxController { data['rows'][0]['elements'][0]['distance']['value']; distanceByPassenger = data['rows'][0]['elements'][0]['distance']['text']; - duration1 = data['rows'][0]['elements'][0]['duration']['value']; + durationToPassenger = + data['rows'][0]['elements'][0]['duration']['value']; durationFromDriverToPassenger = - Duration(seconds: duration1.toInt()); + Duration(seconds: durationToPassenger.toInt()); newTime1 = currentTime.add(durationFromDriverToPassenger); timeFromDriverToPassenger = newTime1.add(Duration(minutes: 2.toInt())); @@ -1514,7 +1775,7 @@ class MapPassengerController extends GetxController { nearestCar = CarLocation( distance: distance1.toDouble(), - duration: duration1.toDouble(), + duration: durationToPassenger.toDouble(), id: carLocation['driver_id'], latitude: double.parse(carLocation['latitude']), longitude: double.parse(carLocation['longitude']), @@ -1541,7 +1802,7 @@ class MapPassengerController extends GetxController { //print(nearestCar!.id); } - calculateDistanceBetweenPassengerAndDriverBeforecancelRide() async { + calculateDistanceBetweenPassengerAndDriverBeforeCancelRide() async { await getDriverCarsLocationToPassengerAfterApplied(); double distance = Geolocator.distanceBetween( passengerLocation.latitude, @@ -1569,6 +1830,23 @@ class MapPassengerController extends GetxController { } 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; getMap(String origin, destination) async { @@ -1579,9 +1857,10 @@ class MapPassengerController extends GetxController { double latPassengerDestination = double.parse(coordDestination[0]); double lngPassengerDestination = double.parse(coordDestination[1]); myDestination = LatLng(latPassengerDestination, lngPassengerDestination); - // if (origin.isEmpty) { - // origin = passengerLocation.toString(); //todo - // } + if (origin.isEmpty) { + origin = + '${passengerLocation.latitude.toString().split(',')[0]},${passengerLocation.longitude.toString().split(',')[1]}'; //todo + } isLoading = false; update(); var url = @@ -1622,23 +1901,7 @@ class MapPassengerController extends GetxController { double distanceOfTrip = (data[0]['distance']['value']) / 1000; distance = distanceOfTrip; // updateCameraForDistanceAfterGetMap(); - for (var step in data[0]['steps']) { - var startLat = step['start_location']['lat']; - var startLng = step['start_location']['lng']; - var endLat = step['end_location']['lat']; - var endLng = step['end_location']['lng']; - - // Calculate heading - var y = math.sin(endLng - startLng) * math.cos(endLat); - var x = math.cos(startLat) * math.sin(endLat) - - math.sin(startLat) * math.cos(endLat) * math.cos(endLng - startLng); - var theta = math.atan2(y, x); - - // Add to list - headingAngles.add(theta); - } - print(headingAngles); if (polyLines.isNotEmpty) { clearPolyline(); } else { @@ -1799,6 +2062,15 @@ class MapPassengerController extends GetxController { 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; @@ -1834,9 +2106,11 @@ class MapPassengerController extends GetxController { 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 - @@ -1874,46 +2148,57 @@ class MapPassengerController extends GetxController { print('costDistance----- $costDistance'); print( 'passengerWalletTotal----- ${box.read(BoxName.passengerWalletTotal)}'); + + update(); + if (currentTime.hour >= 22) { + costDistance = distance * 3.7; + update(); + } else if (currentTime.hour < 5) { + costDistance = distance * 3.8; + update(); + } else if (currentTime.hour >= 13 && currentTime.hour <= 16) { + if (averageDuration > 2.5) { + costDistance = distance * 3.9; + update(); + } else { + costDistance = distance * 3.5; + update(); + } + } else { + costDistance = distance * 3.4; + 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 * .16); + totalPassenger = totalCostPassenger; + totalPassengerComfort = totalCostPassenger + (totalCostPassenger * .2); + totalPassengerComfortDiscount = + totalPassengerComfort + totalPassengerComfort * 12 / 100; + totalPassengerMotoDelivery = + totalCostPassenger - (totalCostPassenger * .35); totalDriver = totalDriver1 + (totalDriver1 * .16); tax = totalCostPassenger * .16; totalME = totalCostPassenger - tax; - if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) { - totalPassenger = totalCostPassenger + - (-1) * (double.parse(box.read(BoxName.passengerWalletTotal))); - } else { - totalPassenger = totalCostPassenger; - } - - update(); - if (currentTime.hour >= 22) { - costDistance = distance * 0.23; - update(); - } else if (currentTime.hour < 5) { - costDistance = distance * 0.25; - update(); - } else if (currentTime.hour >= 13 && currentTime.hour <= 16) { - if (averageDuration > 2.5) { - costDistance = distance * 0.25; - update(); - } else { - costDistance = distance * 0.21; - update(); - } - } else { - costDistance = distance * 0.21; - update(); - } - //print('cost $cost'); 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(); @@ -2011,20 +2296,27 @@ class MapPassengerController extends GetxController { } } + late List recentPlaces = []; + getFavioratePlaces() async { + recentPlaces = await sql.getAllData(TableName.recentLocations); + } + @override void onInit() async { mapAPIKEY = await storage.read(key: BoxName.mapAPIKEY); + getFavioratePlaces(); readyWayPoints(); await getLocation(); await addToken(); - await getCarsLocationByPassenger(); - getNearestDriverByPassengerLocation(); + await startMarkerReloading(); + // await getCarsLocationByPassenger(); + // await getNearestDriverByPassengerLocation(); addCustomPicker(); addCustomCarIcon(); addCustomStepIcon(); addCustomStartIcon(); addCustomEndIcon(); - startMarkerReloading(); + initilizeGetStorage(); cardNumber = await SecureStorage().readData(BoxName.cardNumber); diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart index 9a4187a..1661e22 100644 --- a/lib/controller/local/translations.dart +++ b/lib/controller/local/translations.dart @@ -370,11 +370,36 @@ class MyTranslation extends Translations { 'Admin DashBoard': "لوحة تحكم المدير", 'Your name': "إسمك", 'Your password': "كلمة المرور الخاصة بك", + 'H and': 'ساعه و', + 'LE': 'جنيه', + 'm': 'دقيقه', + "We search nearst Driver to you": "بنبحث عن أقرب سائق ليك", + "please wait till driver accept your order": + "الرجاء الانتظار حتى يقبل السائق طلبك", + "No accepted orders? Try raising your trip fee to attract riders.": + "مفيش طلبات مقبولة؟ حاول رفع سعر الرحلة لجذب الركاب", + "You should select one": "يجب عليك اختيار واحد", + "The driver accept your order for": "قبل السائق طلبك بمبلغ", + "Increase Fee": "ارفع السعر", + "No, thanks": "لا شكرا", + 'The driver on your way': 'الكابتن في طريقه اليك', + 'Total price from ': 'المبلغ المطلوب من ', + 'Order Details Speed': 'طلب سريع', + 'Order Applied': "نفذ الطلب", + "The order has been accepted by another driver.": + 'الطلب اتاخد من سواق تاني.', + "Be more mindful next time to avoid dropping orders.": + "خليك أسرع المرة الجاية عشان متتخسرش سفريات تانية. ", + 'Order Details': 'تفاصيل الطلب', + "We haven't found any drivers yet. Consider increasing your trip fee to make your offer more attractive to drivers.": + "مفيش سواقين لحد دلوقتي. حاول رفع سعر الرحلة عشان تجذب سواقين أكتر.", + "Increase Your Trip Fee (Optional)": "ارفع سعر الرحلة (اختياري)", 'title': "العنوان", "To ensure you receive the most accurate information for your location, please select your country below. This will help tailor the app experience and content to your country.": "لكي يتم تقديم أفضل خدمة ومحتوى متخصص لك، نطلب منك تحديد بلدك حتى نتمكن من تخصيص التطبيق بناءًا على مكان سكنك. سوف تساعدنا هذه الخطوة في ضمان حصولك على أحدث المعلومات والتحديثات المتعلقة بدولتك.", 'If You Want be Driver \nClick Here.': "إذا كنت تريد أن تكون سائقًا \nانقر هنا.", + 'Are you want to go this site': 'هل تريد الذهاب الى هذا المكان', 'Enter your City': "أدخل مدينتك", "Select Your Country": "تحديد دولتك", 'History Page': "ارشيف الرحلات", diff --git a/lib/controller/rate/rate_conroller.dart b/lib/controller/rate/rate_conroller.dart index 0c890b7..fab0d67 100644 --- a/lib/controller/rate/rate_conroller.dart +++ b/lib/controller/rate/rate_conroller.dart @@ -56,12 +56,12 @@ class RateController extends GetxController { Get.find().passengerLocation.toString(), 'endLocation': Get.find().passengerDestination.toString(), - 'name': Get.find().name.toString(), + 'name': Get.find().passengerName.toString(), 'timeOfTrip': Get.find().timeOfOrder.toString(), 'fee': Get.find().totalPassenger.toString(), 'duration': Get.find().duration.toString(), - 'phone': Get.find().phone.toString(), - 'email': Get.find().email.toString(), + 'phone': Get.find().passengerPhone.toString(), + 'email': Get.find().passengerEmail.toString(), }); // homeCaptainController.isActive = true; // update(); diff --git a/lib/main.dart b/lib/main.dart index ef15bab..bf69988 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,7 +8,7 @@ import 'package:flutter_stripe/flutter_stripe.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:flutter/services.dart'; - +import 'package:wakelock_plus/wakelock_plus.dart'; import 'constant/api_key.dart'; import 'constant/credential.dart'; import 'constant/info.dart'; @@ -33,6 +33,7 @@ Future backgroundMessageHandler(RemoteMessage message) async { void main() async { WidgetsFlutterBinding.ensureInitialized(); + WakelockPlus.enable(); if (Platform.isAndroid) { await NotificationController().initNotifications(); } @@ -65,7 +66,6 @@ void main() async { DeviceOrientation.portraitDown, ]); } - // MapPassengerController().initilizeGetStorage(); runApp(const MyApp()); } diff --git a/lib/models/db_sql.dart b/lib/models/db_sql.dart index 099f236..0fafa4a 100644 --- a/lib/models/db_sql.dart +++ b/lib/models/db_sql.dart @@ -21,8 +21,7 @@ class DbSql { path, version: 1, onCreate: (db, version) async { - await db.execute( - ''' + await db.execute(''' CREATE TABLE IF NOT EXISTS ${TableName.carLocations}( id INTEGER PRIMARY KEY AUTOINCREMENT, driver_id TEXT, @@ -32,8 +31,7 @@ class DbSql { updated_at TEXT ) '''); - await db.execute( - ''' + await db.execute(''' CREATE TABLE IF NOT EXISTS ${TableName.placesFavorite}( id INTEGER PRIMARY KEY AUTOINCREMENT, latitude REAL, @@ -42,8 +40,7 @@ class DbSql { rate TEXT ) '''); - await db.execute( - ''' + await db.execute(''' CREATE TABLE IF NOT EXISTS ${TableName.recentLocations}( id INTEGER PRIMARY KEY AUTOINCREMENT, latitude REAL, @@ -52,8 +49,7 @@ class DbSql { rate TEXT ) '''); - await db.execute( - ''' + await db.execute(''' CREATE TABLE IF NOT EXISTS ${TableName.driverOrdersRefuse}( id INTEGER PRIMARY KEY AUTOINCREMENT, order_id TEXT UNIQUE, @@ -61,15 +57,22 @@ class DbSql { driver_id TEXT ) '''); - await db.execute( - ''' + await db.execute(''' + CREATE TABLE IF NOT EXISTS ${TableName.rideLocation}( + id INTEGER PRIMARY KEY AUTOINCREMENT, + order_id TEXT UNIQUE, + created_at TEXT, + lat TEXT, + lng TEXT + ) + '''); + await db.execute(''' CREATE TABLE IF NOT EXISTS ${TableName.faceDetectTimes}( id INTEGER PRIMARY KEY AUTOINCREMENT, faceDetectTimes INTEGER ) '''); - await db.execute( - ''' + await db.execute(''' CREATE TABLE IF NOT EXISTS ${TableName.captainNotification}( id INTEGER PRIMARY KEY AUTOINCREMENT, faceDetectTimes INTEGER diff --git a/lib/views/Rate/rate_passenger.dart b/lib/views/Rate/rate_passenger.dart index 3b2aa44..d494635 100644 --- a/lib/views/Rate/rate_passenger.dart +++ b/lib/views/Rate/rate_passenger.dart @@ -1,3 +1,4 @@ +import 'package:SEFER/controller/home/captin/map_driver_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:get/get.dart'; @@ -26,6 +27,35 @@ class RatePassenger extends StatelessWidget { decoration: AppStyle.boxDecoration, child: Column( children: [ + Padding( + padding: const EdgeInsets.all(4), + child: Container( + height: Get.height * .25, + decoration: AppStyle.boxDecoration1, + child: Column( + children: [ + Text( + '${'Total price from '.tr}${Get.find().passengerName}', + style: AppStyle.title, + ), + Container( + decoration: BoxDecoration( + border: Border.all( + width: 2, + color: AppColor.greenColor, + )), + child: Padding( + padding: const EdgeInsets.all(4), + child: Text( + Get.find() + .totalPassenger, + style: AppStyle.number, + ), + ), + ), + ], + )), + ), Center( child: RatingBar.builder( initialRating: 0, diff --git a/lib/views/auth/verify_email_page.dart b/lib/views/auth/verify_email_page.dart index d3da8b2..64cdc19 100644 --- a/lib/views/auth/verify_email_page.dart +++ b/lib/views/auth/verify_email_page.dart @@ -18,6 +18,7 @@ class VerifyEmailPage extends StatelessWidget { Positioned( top: 10, left: 20, + right: 20, child: Text( 'We sent 5 digit to your Email provided'.tr, style: AppStyle.title.copyWith(fontSize: 20), diff --git a/lib/views/home/Captin/driver_map_page.dart b/lib/views/home/Captin/driver_map_page.dart index 9804a8d..847d5a2 100644 --- a/lib/views/home/Captin/driver_map_page.dart +++ b/lib/views/home/Captin/driver_map_page.dart @@ -1,9 +1,12 @@ +import 'package:SEFER/constant/style.dart'; +import 'package:SEFER/views/widgets/elevated_btn.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:SEFER/controller/home/captin/map_driver_controller.dart'; import 'package:SEFER/views/widgets/my_scafold.dart'; import '../../../controller/functions/location_controller.dart'; +import '../../Rate/rate_passenger.dart'; import 'mapDriverWidgets/driver_end_ride_bar.dart'; import 'mapDriverWidgets/google_driver_map_page.dart'; import 'mapDriverWidgets/google_map_app.dart'; @@ -25,7 +28,57 @@ class PassengerLocationMapPage extends StatelessWidget { driverEndRideBar(), const SosConnect(), const GoogleMapApp(), + PricesWindow(), ], isleading: false); } } + +class PricesWindow extends StatelessWidget { + const PricesWindow({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return GetBuilder(builder: (mapDriverController) { + return mapDriverController.isPriceWindow + ? Positioned( + bottom: Get.height * 1.2, + // top: Get.height * 3, + left: Get.height * 1, + right: Get.height * 1, + child: Container( + height: Get.height * 3, + decoration: AppStyle.boxDecoration1, + child: Column( + children: [ + Container( + decoration: AppStyle.boxDecoration1, + child: Padding( + padding: const EdgeInsets.all(3), + child: Text( + 'Total Price is '.tr, + style: AppStyle.headTitle2, + textAlign: TextAlign.center, + ), + )), + const SizedBox( + height: 20, + ), + MyElevatedButton( + title: 'ok'.tr, + onPressed: () => + Get.to(() => RatePassenger(), arguments: { + 'rideId': mapDriverController.rideId, + 'passengerId': mapDriverController.passengerId, + 'driverId': mapDriverController.driverId + })) + ], + ), + ), + ) + : const SizedBox(); + }); + } +} diff --git a/lib/views/home/Captin/home_captain/call_controller.dart b/lib/views/home/Captin/home_captain/call_controller.dart index 878c52e..9ef3ccf 100644 --- a/lib/views/home/Captin/home_captain/call_controller.dart +++ b/lib/views/home/Captin/home_captain/call_controller.dart @@ -23,7 +23,7 @@ class CallController extends GetxController { void onInit() { super.onInit(); channelName = Get.find().rideId; // 'sefer300'; // - remoteUid = int.parse(Get.find().phone); + remoteUid = int.parse(Get.find().passengerPhone); uid = int.parse(box.read(BoxName.phoneDriver)); // initAgoraFull(); } @@ -76,7 +76,7 @@ class CallController extends GetxController { }, onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) { // Get.snackbar("Remote user uid:$remoteUid joined the channel", ''); - status = '${Get.find().name}' + status = '${Get.find().passengerName}' ' joined' .tr .tr; diff --git a/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart b/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart index 3703358..49e79e4 100644 --- a/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart +++ b/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart @@ -1,4 +1,3 @@ -import 'package:SEFER/controller/functions/location_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart'; @@ -10,12 +9,10 @@ import 'package:SEFER/controller/firebase/firbase_messge.dart'; import 'package:SEFER/controller/home/captin/map_driver_controller.dart'; import 'package:SEFER/main.dart'; import 'package:SEFER/views/widgets/elevated_btn.dart'; -import 'package:url_launcher/url_launcher.dart'; import '../../../../constant/style.dart'; import '../../../../controller/functions/launch.dart'; import '../../../../controller/home/captin/widget/call_page.dart'; -import 'google_map_app.dart'; class PassengerInfoWindow extends StatelessWidget { const PassengerInfoWindow({ @@ -83,7 +80,7 @@ class PassengerInfoWindow extends StatelessWidget { true; launchCommunication( 'email', - controller.phone + controller.passengerPhone .toString(), '${'Hello this is Driver'.tr} ${box.read(BoxName.nameDriver)}'); }, @@ -155,7 +152,7 @@ class PassengerInfoWindow extends StatelessWidget { Text('Name of the Passenger is '.tr, style: AppStyle.title), Text( - controller.name.toString(), + controller.passengerName.toString(), style: AppStyle.title, ), ], @@ -353,49 +350,49 @@ class PassengerInfoWindow extends StatelessWidget { ), ], ) - : controller.remainingTimeToShowPassengerInfoWindowFromDriver > 0 // - ? Positioned( - bottom: Get.height * .2, - left: 15, - child: Container( - decoration: AppStyle.boxDecoration, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - Stack( - alignment: Alignment.center, - children: [ - const CircularProgressIndicator( - backgroundColor: AppColor.redColor, - strokeWidth: 10, - color: AppColor.redColor, - value: 1, - ), - CircularProgressIndicator( - value: controller.progress, - // Set the color based on the "isNearEnd" condition - color: AppColor.yellowColor, - ), - Text( - '${controller.remainingTimeToShowPassengerInfoWindowFromDriver}', - style: AppStyle.number, - ), - ], - ), - const SizedBox( - width: 10, - ), - Text( - 'Please Wait If passenger want To Cancel!'.tr, - style: AppStyle.title, - ), - ], - ), - ), - ), - ) - : const SizedBox(), + // : controller.remainingTimeToShowPassengerInfoWindowFromDriver > 0 // + // ? Positioned( + // bottom: Get.height * .2, + // left: 15, + // child: Container( + // decoration: AppStyle.boxDecoration, + // child: Padding( + // padding: const EdgeInsets.all(8.0), + // child: Row( + // children: [ + // Stack( + // alignment: Alignment.center, + // children: [ + // const CircularProgressIndicator( + // backgroundColor: AppColor.redColor, + // strokeWidth: 10, + // color: AppColor.redColor, + // value: 1, + // ), + // CircularProgressIndicator( + // value: controller.progress, + // // Set the color based on the "isNearEnd" condition + // color: AppColor.yellowColor, + // ), + // Text( + // '${controller.remainingTimeToShowPassengerInfoWindowFromDriver}', + // style: AppStyle.number, + // ), + // ], + // ), + // const SizedBox( + // width: 10, + // ), + // Text( + // 'Please Wait If passenger want To Cancel!'.tr, + // style: AppStyle.title, + // ), + // ], + // ), + // ), + // ), + // ) + : const SizedBox(), ); } } diff --git a/lib/views/home/Captin/mapDriverWidgets/sos_connect.dart b/lib/views/home/Captin/mapDriverWidgets/sos_connect.dart index d92fc7a..9a5f6c6 100644 --- a/lib/views/home/Captin/mapDriverWidgets/sos_connect.dart +++ b/lib/views/home/Captin/mapDriverWidgets/sos_connect.dart @@ -100,7 +100,7 @@ class SosConnect extends StatelessWidget { launchCommunication( 'whatsapp', '+962${box.read(BoxName.sosPhoneDriver)}', //todo add number from driver - "${"Hello this is Driver".tr} ${box.read(BoxName.nameDriver)}.${" My current location is:".tr} https://www.google.com/maps/place/${Get.find().myLocation.latitude},${Get.find().myLocation.longitude}${" \nand I have a trip on".tr} ${AppInformation.appName} ${"App \nwith Passenger ".tr}${mapDriverController.name}"); + "${"Hello this is Driver".tr} ${box.read(BoxName.nameDriver)}.${" My current location is:".tr} https://www.google.com/maps/place/${Get.find().myLocation.latitude},${Get.find().myLocation.longitude}${" \nand I have a trip on".tr} ${AppInformation.appName} ${"App \nwith Passenger ".tr}${mapDriverController.passengerName}"); } }, child: const Icon( diff --git a/lib/views/home/Captin/orderCaptin/order_request_page.dart b/lib/views/home/Captin/orderCaptin/order_request_page.dart index 67a8060..5d0cc82 100644 --- a/lib/views/home/Captin/orderCaptin/order_request_page.dart +++ b/lib/views/home/Captin/orderCaptin/order_request_page.dart @@ -1,3 +1,4 @@ +import 'package:SEFER/controller/home/captin/home_captain_controller.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:SEFER/constant/box_name.dart'; @@ -5,7 +6,8 @@ import 'package:SEFER/controller/firebase/firbase_messge.dart'; import 'package:SEFER/main.dart'; import 'package:SEFER/views/home/Captin/driver_map_page.dart'; import 'package:SEFER/views/widgets/my_scafold.dart'; - +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'dart:math' as math; import '../../../../constant/colors.dart'; import '../../../../constant/links.dart'; import '../../../../constant/style.dart'; @@ -23,18 +25,93 @@ class OrderRequestPage extends StatelessWidget { final arguments = Get.arguments; final myListString = arguments['myListString']; final myList = arguments['DriverList']; + // final pointsList = arguments['PolylineJson']; final body = arguments['body']; Duration durationToAdd = Duration(seconds: int.parse(myList[4])); int hours = durationToAdd.inHours; int minutes = (durationToAdd.inMinutes % 60).round(); orderRequestController.startTimer(myList[6].toString(), body.toString()); + var coords = myList[0].split(','); + var coordDestination = myList[1].split(','); + +// Parse to double + double latPassengerLocation = double.parse(coords[0]); + double lngPassengerLocation = double.parse(coords[1]); + double latPassengerDestination = double.parse(coordDestination[0]); + double lngPassengerDestination = double.parse(coordDestination[1]); + + List pointsDirection = [ + LatLng(latPassengerLocation, lngPassengerLocation), + LatLng(latPassengerDestination, lngPassengerDestination) + ]; // Calculate the midpoint between the two points + // Calculate the minimum and maximum latitude and longitude values + double minLatitude = + math.min(pointsDirection[0].latitude, pointsDirection[1].latitude); + double maxLatitude = + math.max(pointsDirection[0].latitude, pointsDirection[1].latitude); + double minLongitude = + math.min(pointsDirection[0].longitude, pointsDirection[1].longitude); + double maxLongitude = + math.max(pointsDirection[0].longitude, pointsDirection[1].longitude); +// Create a bounding box using the calculated values + LatLngBounds bounds = LatLngBounds( + southwest: LatLng(minLatitude, minLongitude), + northeast: LatLng(maxLatitude, maxLongitude), + ); return MyScafolld( - title: 'Order Request Page'.tr, + title: 'Order Details'.tr, body: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + // SizedBox(height: 200, child: Text(pointsList.toString())), // Text(message.notification!.body.toString()), + SizedBox( + height: 200, + child: GoogleMap( + initialCameraPosition: CameraPosition( + zoom: 12, + target: Get.find().myLocation), + cameraTargetBounds: CameraTargetBounds(bounds), + myLocationButtonEnabled: true, + trafficEnabled: true, + buildingsEnabled: true, + mapToolbarEnabled: true, + myLocationEnabled: true, + markers: { + Marker( + markerId: MarkerId('MyLocation'.tr), + position: + LatLng(latPassengerLocation, lngPassengerLocation), + draggable: true, + icon: BitmapDescriptor.defaultMarkerWithHue( + BitmapDescriptor.hueGreen), + ), + Marker( + markerId: MarkerId('Destination'.tr), + position: LatLng( + latPassengerDestination, lngPassengerDestination), + draggable: true, + icon: BitmapDescriptor.defaultMarkerWithHue( + BitmapDescriptor.hueBlue), + ), + }, + polylines: { + Polyline( + zIndex: 1, + consumeTapEvents: true, + geodesic: true, + endCap: Cap.buttCap, + startCap: Cap.buttCap, + visible: true, + polylineId: const PolylineId('routeOrder'), + points: pointsDirection, + color: AppColor.primaryColor, + width: 2, + ), + }, + ), + ), Padding( padding: const EdgeInsets.all(8.0), child: Card( @@ -201,7 +278,8 @@ class OrderRequestPage extends StatelessWidget { await CRUD().post(link: AppLink.updateRides, payload: { 'id': myList[16], 'rideTimeStart': DateTime.now().toString(), - 'status': 'Apply' + 'status': 'Apply', + 'driver_id': box.read(BoxName.driverID), }); // Get.back(); List bodyToPassenger = [ @@ -291,7 +369,8 @@ class OrderRequestPage extends StatelessWidget { bodyToPassenger, ); orderRequestController.refuseOrder( - myList[16].toString(), body.toString()); + myList[16].toString(), + ); }, kolor: AppColor.redColor, ), diff --git a/lib/views/home/Captin/orderCaptin/order_speed_request.dart b/lib/views/home/Captin/orderCaptin/order_speed_request.dart new file mode 100644 index 0000000..3eb7695 --- /dev/null +++ b/lib/views/home/Captin/orderCaptin/order_speed_request.dart @@ -0,0 +1,370 @@ +import 'package:SEFER/controller/home/captin/home_captain_controller.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:SEFER/constant/box_name.dart'; +import 'package:SEFER/controller/firebase/firbase_messge.dart'; +import 'package:SEFER/main.dart'; +import 'package:SEFER/views/home/Captin/driver_map_page.dart'; +import 'package:SEFER/views/widgets/my_scafold.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'dart:math' as math; +import '../../../../constant/colors.dart'; +import '../../../../constant/links.dart'; +import '../../../../constant/style.dart'; +import '../../../../controller/functions/crud.dart'; +import '../../../../controller/functions/launch.dart'; +import '../../../../controller/home/captin/order_request_controller.dart'; +import '../../../widgets/elevated_btn.dart'; + +class OrderSpeedRequest extends StatelessWidget { + OrderSpeedRequest({super.key}); + OrderRequestController orderRequestController = + Get.put(OrderRequestController()); + @override + Widget build(BuildContext context) { + final arguments = Get.arguments; + final myListString = arguments['myListString']; + final myList = arguments['DriverList']; + // final pointsList = arguments['PolylineJson']; + final body = arguments['body']; + Duration durationToAdd = Duration(seconds: int.parse(myList[4])); + int hours = durationToAdd.inHours; + int minutes = (durationToAdd.inMinutes % 60).round(); + orderRequestController.startTimer(myList[6].toString(), body.toString()); + var coords = myList[0].split(','); + var coordDestination = myList[1].split(','); + +// Parse to double + double latPassengerLocation = double.parse(coords[0]); + double lngPassengerLocation = double.parse(coords[1]); + double latPassengerDestination = double.parse(coordDestination[0]); + double lngPassengerDestination = double.parse(coordDestination[1]); + + List pointsDirection = [ + LatLng(latPassengerLocation, lngPassengerLocation), + LatLng(latPassengerDestination, lngPassengerDestination) + ]; // Calculate the midpoint between the two points + // Calculate the minimum and maximum latitude and longitude values + double minLatitude = + math.min(pointsDirection[0].latitude, pointsDirection[1].latitude); + double maxLatitude = + math.max(pointsDirection[0].latitude, pointsDirection[1].latitude); + double minLongitude = + math.min(pointsDirection[0].longitude, pointsDirection[1].longitude); + double maxLongitude = + math.max(pointsDirection[0].longitude, pointsDirection[1].longitude); +// Create a bounding box using the calculated values + LatLngBounds bounds = LatLngBounds( + southwest: LatLng(minLatitude, minLongitude), + northeast: LatLng(maxLatitude, maxLongitude), + ); + return MyScafolld( + title: 'Order Details Speed'.tr, + body: [ + Container( + color: AppColor.accentColor, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // SizedBox(height: 200, child: Text(pointsList.toString())), + // Text(message.notification!.body.toString()), + SizedBox( + height: 200, + child: GoogleMap( + initialCameraPosition: CameraPosition( + zoom: 12, + target: Get.find().myLocation), + cameraTargetBounds: CameraTargetBounds(bounds), + myLocationButtonEnabled: true, + trafficEnabled: true, + buildingsEnabled: true, + mapToolbarEnabled: true, + myLocationEnabled: true, + markers: { + Marker( + markerId: MarkerId('MyLocation'.tr), + position: + LatLng(latPassengerLocation, lngPassengerLocation), + draggable: true, + icon: BitmapDescriptor.defaultMarkerWithHue( + BitmapDescriptor.hueGreen), + ), + Marker( + markerId: MarkerId('Destination'.tr), + position: LatLng( + latPassengerDestination, lngPassengerDestination), + draggable: true, + icon: BitmapDescriptor.defaultMarkerWithHue( + BitmapDescriptor.hueBlue), + ), + }, + polylines: { + Polyline( + zIndex: 1, + consumeTapEvents: true, + geodesic: true, + endCap: Cap.buttCap, + startCap: Cap.buttCap, + visible: true, + polylineId: const PolylineId('routeOrder'), + points: pointsDirection, + color: AppColor.primaryColor, + width: 2, + ), + }, + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Card( + elevation: 3, + color: myList[20].toString() == 'haveSteps' + ? AppColor.greenColor + : AppColor.secondaryColor, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextButton.icon( + onPressed: () { + String mapUrl = + 'https://www.google.com/maps/dir/${myList[0]}/${myList[1]}/'; + print(mapUrl); + showInBrowser(mapUrl); + }, + icon: const Icon(Icons.map), + label: myList[20].toString() == 'haveSteps' + ? Text( + 'Trip has Steps'.tr, + style: AppStyle.title, + ) + : Text('Rouats of Trip'.tr, + style: AppStyle.title)), + Container( + color: myList[13].toString() == 'true' + ? AppColor.deepPurpleAccent + : AppColor.greenColor, + child: myList[13].toString() == + 'true' //Visa or Cash Method from notify to driver + ? Text( + 'Visa', + style: AppStyle.title, + ) + : Text('Cash', style: AppStyle.title), + ) + ], + ), + ), + ), + + Padding( + padding: const EdgeInsets.all(8.0), + child: RichText( + text: TextSpan( + text: 'Passenger Name is '.tr, + style: AppStyle.title, + children: [ + TextSpan(text: myList[8], style: AppStyle.headTitle2), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: RichText( + text: TextSpan( + text: 'Total From Passenger is '.tr, + style: AppStyle.title, + children: [ + TextSpan( + text: double.parse(myList[2]).toStringAsFixed(2), + style: AppStyle.headTitle2), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: RichText( + text: TextSpan( + text: 'Duration To Passenger is '.tr, + style: AppStyle.title, + children: [ + TextSpan( + text: myList[11].toString(), + style: AppStyle.headTitle2), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: RichText( + text: TextSpan( + text: 'Distance To Passenger is '.tr, + style: AppStyle.title, + children: [ + TextSpan( + text: myList[12].toString(), + style: AppStyle.headTitle2), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + color: AppColor.deepPurpleAccent, + child: RichText( + text: TextSpan( + text: 'Cost Of Trip IS '.tr, + style: AppStyle.title, + children: [ + TextSpan( + text: double.parse(myList[26]).toStringAsFixed(2), + style: AppStyle.headTitle2), + ], + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: RichText( + text: TextSpan( + text: 'Distance from Passenger to destination is '.tr, + style: AppStyle.title, + children: [ + TextSpan( + text: myList[5].toString(), + style: AppStyle.headTitle2), + TextSpan(text: ' KM'.tr, style: AppStyle.title), + ]), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: RichText( + text: TextSpan( + text: 'Duration of Trip is '.tr, + style: AppStyle.title, + children: [ + TextSpan( + text: hours > 1 + ? '${'Your Ride Duration is '.tr}$hours${' H and'.tr} $minutes m' + : '${'Your Ride Duration is '.tr} $minutes m', + style: AppStyle.title), + TextSpan(text: ' Minutes'.tr, style: AppStyle.title), + ]), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + MyElevatedButton( + kolor: AppColor.greenColor, + title: 'Accept Order'.tr, + onPressed: () async { + box.write(BoxName.statusDriverLocation, 'on'); + + orderRequestController.changeApplied(); + await CRUD().postFromDialogue( + link: AppLink.addDriverOrder, + payload: { + 'driver_id': box.read( + BoxName.driverID), //myList[6].toString(), + // box.read(BoxName.driverID).toString(), + 'order_id': + myList[16].toString(), //body.toString(), + 'status': 'Apply' + }); + await CRUD() + .post(link: AppLink.updateRides, payload: { + 'id': myList[16], + 'rideTimeStart': DateTime.now().toString(), + 'status': 'Apply', + 'driver_id': box.read(BoxName.driverID), + }); + // Get.back(); + List bodyToPassenger = [ + box.read(BoxName.driverID).toString(), + box.read(BoxName.nameDriver).toString(), + box.read(BoxName.tokenDriver).toString(), + ]; + // print(bodyToPassenger); + FirebaseMessagesController() + .sendNotificationToPassengerToken( + 'Apply Ride', + arguments['DriverList'][9].toString(), + arguments['DriverList'][9].toString(), + // box.read(BoxName.tokenDriver).toString(), + bodyToPassenger, + ); + Get.back(); + Get.to(() => PassengerLocationMapPage(), arguments: { + 'passengerLocation': myList[0].toString(), + 'passengerDestination': myList[1].toString(), + 'Duration': myList[4].toString(), + 'totalCost': myList[26].toString(), + 'Distance': myList[5].toString(), + 'name': myList[8].toString(), + 'phone': myList[10].toString(), + 'email': myList[28].toString(), + 'WalletChecked': myList[13].toString(), + 'tokenPassenger': myList[9].toString(), + 'direction': + 'https://www.google.com/maps/dir/${myList[0]}/${myList[1]}/', + 'DurationToPassenger': myList[15].toString(), + 'rideId': myList[16].toString(), + 'passengerId': myList[7].toString(), + 'driverId': myList[18].toString(), + 'durationOfRideValue': myList[19].toString(), + 'paymentAmount': myList[2].toString(), + 'paymentMethod': myList[13].toString() == 'true' + ? 'visa' + : 'cash', + 'isHaveSteps': myList[20].toString(), + 'step0': myList[21].toString(), + 'step1': myList[22].toString(), + 'step2': myList[23].toString(), + 'step3': myList[24].toString(), + 'step4': myList[25].toString(), + 'passengerWalletBurc': myList[26].toString(), + 'timeOfOrder': DateTime.now().toString(), + 'totalPassenger': myList[2].toString(), + }); + }, + ), + GetBuilder( + builder: (timerController) { + final isNearEnd = + timerController.remainingTimeSpeed <= + 5; // Define a threshold for "near end" + + return Stack( + alignment: Alignment.center, + children: [ + CircularProgressIndicator( + value: timerController.progressSpeed, + // Set the color based on the "isNearEnd" condition + color: isNearEnd ? Colors.red : Colors.blue, + ), + Text( + '${timerController.remainingTimeSpeed}', + style: AppStyle.number, + ), + ], + ); + }, + ), + ], + ), + ) + ], + ), + ) + ], + isleading: true); + } +} diff --git a/lib/views/home/map_page_passenger.dart b/lib/views/home/map_page_passenger.dart index d0b61c4..df8c53c 100644 --- a/lib/views/home/map_page_passenger.dart +++ b/lib/views/home/map_page_passenger.dart @@ -8,7 +8,9 @@ import '../../views/home/map_widget.dart/cancel_raide_page.dart'; import '../../views/home/map_widget.dart/ride_begin_passenger.dart'; import '../../controller/home/menu_controller.dart'; +import 'map_widget.dart/apply_order_widget.dart'; import 'map_widget.dart/buttom_sheet_map_show.dart'; +import 'map_widget.dart/car_details_widget_to_go.dart'; import 'map_widget.dart/cash_confirm_bottom_page.dart'; import 'map_widget.dart/driver_card_from_passenger.dart'; import 'map_widget.dart/google_map_passenger_widget.dart'; @@ -18,6 +20,7 @@ import 'map_widget.dart/map_menu_widget.dart'; import 'map_widget.dart/menu_map_page.dart'; import 'map_widget.dart/payment_method.page.dart'; import 'map_widget.dart/points_page_for_rider.dart'; +import 'map_widget.dart/searching_captain_window.dart'; import 'map_widget.dart/timer_for_cancell_trip_from_passenger.dart'; import 'map_widget.dart/timer_to_passenger_from_driver.dart'; @@ -41,13 +44,16 @@ class MapPagePassenger extends StatelessWidget { const MapMenuWidget(), const MenuIconMapPageWidget(), buttomSheetMapPage(), - hexagonClipper(), + const CarDetailsTypeToChoose(), + const ApplyOrderWidget(), + // hexagonClipper(), const CancelRidePageShow(), CashConfirmPageShown(), const PaymentMethodPage(), - timerForCancelTripFromPassenger(), + const SearchingCaptainWindow(), + // timerForCancelTripFromPassenger(), // const DriverTimeArrivePassengerPage(), - const TimerToPassengerFromDriver(), + // const TimerToPassengerFromDriver(), const RideBeginPassenger(), cancelRidePage(), PointsPageForRider() diff --git a/lib/views/home/map_widget.dart/apply_order_widget.dart b/lib/views/home/map_widget.dart/apply_order_widget.dart new file mode 100644 index 0000000..abb17b9 --- /dev/null +++ b/lib/views/home/map_widget.dart/apply_order_widget.dart @@ -0,0 +1,284 @@ +import 'package:SEFER/constant/colors.dart'; +import 'package:SEFER/constant/style.dart'; +import 'package:SEFER/controller/home/map_passenger_controller.dart'; +import 'package:SEFER/main.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; + +import '../../../constant/box_name.dart'; + +class ApplyOrderWidget extends StatelessWidget { + const ApplyOrderWidget({super.key}); + + @override + Widget build(BuildContext context) { + return GetBuilder(builder: (controller) { + if (controller.statusRide == 'Apply') { + double _height = 250; + return Positioned( + bottom: 0, + left: 0, + right: 0, + child: Container( + decoration: AppStyle.boxDecoration1, + height: _height, + child: ListView( + children: [ + Text.rich( + TextSpan( + children: [ + TextSpan( + text: '${'The driver accept your order for'.tr} ', + style: AppStyle.title, + ), + TextSpan( + text: controller.totalPassenger.toStringAsFixed(2), + style: AppStyle.title.copyWith( + fontWeight: FontWeight.bold, + // fontSize: 22, + color: AppColor.redColor, + ), + ), + TextSpan( + text: ' ${'LE'.tr}', + style: AppStyle.title, + ), + ], + ), + textAlign: TextAlign.center, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox( + width: 10, + ), + Container( + height: 200, + width: Get.width * .9, + decoration: AppStyle.boxDecoration1, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + // 'Comfort', + box.read(BoxName.carType + .toString()), //car type fro box after selected + style: AppStyle.title, + ), + const SizedBox( + width: 10, + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Image.asset( + 'assets/images/blob.png', + width: 100, + ), + Column( + children: [ + Text( + // 'Toyota Camry', + controller.model.toString(), + style: AppStyle.title, + ), + Text( + // 'ر ل 2323', + controller.licensePlate.toString(), + style: AppStyle.title, + ), + ], + ), + Text( + // 'Black', + controller.carColor, + style: AppStyle.title, + ), + const SizedBox( + width: 10, + ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CircleAvatar( + radius: 30, + backgroundImage: NetworkImage( + // '', + // ), + 'https://ride.mobile-app.store/portrate_captain_image/${controller.driverId}.jpg'), + ), + Column( + children: [ + Text( + // 'fadi ahmad', + controller.firstName, + style: AppStyle.title, + ), + Text( + // '⭐ 4.8', + '⭐ ${controller.driverRate}', + style: AppStyle.title, + ), + ], + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.message, + color: AppColor.blueColor, + size: 35, + ), + ), + IconButton( + onPressed: () { + HapticFeedback.heavyImpact(); + }, + icon: const Icon( + Icons.call, + color: AppColor.greenColor, + size: 35, + ), + ), + ], + ), + ), + controller.isDriverArrivePassenger + ? DriverArrivePassengerAndWaitMinute() + : const TimeDriverToPassenger() + ], + ), + ), + const SizedBox( + width: 10, + ), + ], + ) + ], + ), + ), + ); + } else { + return const SizedBox(); + } + }); + } +} + +class DriverArrivePassengerAndWaitMinute extends StatelessWidget { + const DriverArrivePassengerAndWaitMinute({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return GetBuilder(builder: (controller) { + return Stack( + children: [ + LinearProgressIndicator( + backgroundColor: AppColor.accentColor, + color: controller.remainingTimeDriverWaitPassenger5Minute < 60 + ? AppColor.redColor + : AppColor.greenColor, + minHeight: 30, + borderRadius: BorderRadius.circular(15), + value: + controller.progressTimerDriverWaitPassenger5Minute.toDouble(), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'The driver waitting you in picked location .'.tr, + style: AppStyle.title, + textAlign: TextAlign.center, + ), + const SizedBox( + width: 20, + ), + Text( + controller.stringRemainingTimeDriverWaitPassenger5Minute, + style: AppStyle.title, + ), + ], + ) + ], + ); + }); + } +} + +class TimeDriverToPassenger extends StatelessWidget { + const TimeDriverToPassenger({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return GetBuilder(builder: (controller) { + return controller.isDriverInPassengerWay == false || + controller.timeToPassengerFromDriverAfterApplied > 0 + ? Container( + decoration: AppStyle.boxDecoration1, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), + child: Stack( + children: [ + Container( + decoration: AppStyle.boxDecoration1, + width: Get.width * .7, + height: 35, + // color: AppColor.yellowColor, + ), + Stack( + children: [ + LinearProgressIndicator( + backgroundColor: AppColor.accentColor, + color: controller + .remainingTimeToPassengerFromDriverAfterApplied < + 60 + ? AppColor.redColor + : AppColor.greenColor, + minHeight: 25, + borderRadius: BorderRadius.circular(15), + value: controller + .progressTimerToPassengerFromDriverAfterApplied + .toDouble(), + ), + Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'The driver on your way'.tr, + textAlign: TextAlign.center, + ), + const SizedBox( + width: 20, + ), + Text( + controller.stringRemainingTimeToPassenger, + style: AppStyle.title, + ), + ], + ), + ) + ], + ), + ], + ), + ), + ) + : const SizedBox(); + }); + } +} diff --git a/lib/views/home/map_widget.dart/buttom_sheet_map_show.dart b/lib/views/home/map_widget.dart/buttom_sheet_map_show.dart index 192986f..e2c6669 100644 --- a/lib/views/home/map_widget.dart/buttom_sheet_map_show.dart +++ b/lib/views/home/map_widget.dart/buttom_sheet_map_show.dart @@ -87,7 +87,8 @@ GetBuilder buttomSheetMapPage() { child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: controller - .dataCarsLocationByPassenger.length, + .dataCarsLocationByPassenger.length - + 1, itemBuilder: (BuildContext context, int index) { return Container( @@ -122,8 +123,8 @@ GetBuilder buttomSheetMapPage() { MainAxisAlignment.spaceEvenly, children: [ Text( - controller.hours > 1 - ? '${'Your Ride Duration is '.tr}${controller.hours} H and ${controller.minutes} m' + controller.hours > 0 + ? '${'Your Ride Duration is '.tr}${controller.hours} ${'H and'.tr} ${controller.minutes} ${'m'.tr}' : '${'Your Ride Duration is '.tr} ${controller.minutes} m', style: AppStyle.subtitle, ), @@ -132,7 +133,7 @@ GetBuilder buttomSheetMapPage() { // style: AppStyle.subtitle, // ), Text( - '${'Your trip distance is'.tr} ${controller.distance.toStringAsFixed(2)} KM', + '${'Your trip distance is'.tr} ${controller.distance.toStringAsFixed(2)} ${'KM'.tr}', style: AppStyle.subtitle, ) ], @@ -486,7 +487,7 @@ GetBuilder buttomSheetMapPage() { .tr, onPressed: () { controller - .changeConfirmRide(); + .confirmRideForFirstDriver(); }, ), ], diff --git a/lib/views/home/map_widget.dart/car_details_widget_to_go.dart b/lib/views/home/map_widget.dart/car_details_widget_to_go.dart new file mode 100644 index 0000000..72579c4 --- /dev/null +++ b/lib/views/home/map_widget.dart/car_details_widget_to_go.dart @@ -0,0 +1,222 @@ +import 'package:SEFER/constant/box_name.dart'; +import 'package:SEFER/constant/colors.dart'; +import 'package:SEFER/constant/style.dart'; +import 'package:SEFER/main.dart'; +import 'package:SEFER/views/widgets/elevated_btn.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../controller/home/map_passenger_controller.dart'; + +class CarType { + final String carType; + final String carDetail; + final String image; + bool isSelected = false; // Track selection state + + CarType( + {required this.carType, required this.carDetail, required this.image}); +} + +List carTypes = [ + CarType( + carType: 'Comfort'.tr, + carDetail: 'Comfort choice'.tr, + image: 'assets/images/blob.png'), + CarType( + carType: 'Speed'.tr, + carDetail: 'Better for long trips choice'.tr, + image: 'assets/images/carspeed.png'), + CarType( + carType: 'Delivery'.tr, + carDetail: 'Delivery service'.tr, + image: 'assets/images/moto.png'), +]; + +class CarDetailsTypeToChoose extends StatelessWidget { + const CarDetailsTypeToChoose({super.key}); + + @override + Widget build(BuildContext context) { + return GetBuilder( + builder: (mapPassengerController) { + return mapPassengerController.data.isNotEmpty && + mapPassengerController.isBottomSheetShown && + mapPassengerController.rideConfirm == false + ? Positioned( + bottom: 0, + left: 5, + right: 5, + child: Container( + decoration: const BoxDecoration( + color: Color.fromARGB(255, 255, 255, 255), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8), + topRight: Radius.circular(8), + ), + ), + height: Get.height * .4, + child: Column( + children: [ + SizedBox( + height: Get.height * .3, + child: ListView.builder( + itemCount: carTypes.length, + itemBuilder: (context, index) { + final carType = carTypes[index]; + return ListTile( + title: Container( + decoration: BoxDecoration( + color: AppColor.secondaryColor, + borderRadius: const BorderRadius.all( + Radius.circular(20)), + boxShadow: [ + carType.isSelected + ? const BoxShadow( + spreadRadius: 3, + blurStyle: BlurStyle.solid, + color: AppColor.accentColor, + blurRadius: 3, + offset: Offset(1, 3)) + : const BoxShadow(), + ]), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Image.asset( + carType.image, + width: 60, + height: 60, + ), + SizedBox( + width: Get.width * .5, + child: Column( + children: [ + Text( + carType.carType, + style: AppStyle.title.copyWith( + fontWeight: FontWeight.bold, + fontSize: 20), + ), + Text( + carType.carDetail, + style: AppStyle.subtitle, + ), + ], + ), + ), + Column( + children: [ + Text( + carType.carType == 'Comfort' + ? mapPassengerController + .totalPassengerComfort + .toStringAsFixed(2) + : carType.carType == 'Speed' + ? mapPassengerController + .totalPassenger + .toStringAsFixed(2) + : mapPassengerController + .totalPassengerMotoDelivery + .toStringAsFixed(2), + style: AppStyle.title + .copyWith(fontSize: 20), + ), + carType.carType == 'Comfort' + ? Row( + children: [ + Container( + decoration: + const BoxDecoration( + color: AppColor + .greenColor, + borderRadius: + BorderRadius + .all(Radius + .circular( + 5))), + child: Text( + '-12%', + style: AppStyle.subtitle + .copyWith( + color: AppColor + .secondaryColor), + )), + const SizedBox( + width: 10, + ), + Text( + mapPassengerController + .totalPassengerComfortDiscount + .toStringAsFixed(2), + style: + AppStyle.title.copyWith( + decoration: TextDecoration + .lineThrough, // Strikethrough line + ), + ) + ], + ) + : const SizedBox( + width: 3, + ), + ], + ), + const SizedBox( + width: 4, + ) + ], + ), + ), + + selected: mapPassengerController.selectedIndex == + index, // Set selected based on index + selectedColor: + Colors.blue, // Color for selected item + + onTap: () { + mapPassengerController.selectCarFromList(index); + }, + ); + }, + ), + ), + MyElevatedButton( + title: 'Next'.tr, + onPressed: () { + if (mapPassengerController.selectedIndex != -1) { + // Get.snackbar('You should select one'.tr, '', + // backgroundColor: AppColor.greenColor); + if (mapPassengerController.selectedIndex == 0) { + box.write(BoxName.carType, 'Comfort'); + mapPassengerController.totalPassenger = + mapPassengerController.totalPassengerComfort; + } else if (mapPassengerController.selectedIndex == + 1) { + box.write(BoxName.carType, 'Speed'); + } else if (mapPassengerController.selectedIndex == + 2) { + box.write(BoxName.carType, 'Delivery'); + mapPassengerController.totalPassenger = + mapPassengerController + .totalPassengerMotoDelivery; + } + mapPassengerController.isBottomSheetShown = false; + mapPassengerController.update(); + mapPassengerController.changeCashConfirmPageShown(); + // mapPassengerController.confirmRideForFirstDriver(); + } else { + Get.snackbar('You should select one'.tr, '', + backgroundColor: AppColor.redColor); + } + }) + ], + ), + ), + ) + : const SizedBox(); + // ; + }); + } +} diff --git a/lib/views/home/map_widget.dart/cash_confirm_bottom_page.dart b/lib/views/home/map_widget.dart/cash_confirm_bottom_page.dart index e5ac450..75e6fd1 100644 --- a/lib/views/home/map_widget.dart/cash_confirm_bottom_page.dart +++ b/lib/views/home/map_widget.dart/cash_confirm_bottom_page.dart @@ -102,8 +102,12 @@ class CashConfirmPageShown extends StatelessWidget { width: 20, ), InkWell( - onTap: () => - controller.changeCashConfirmPageShown(), + onTap: () { + controller.changeCashConfirmPageShown(); + controller.isSearchingWindow = true; + controller.confirmRideForFirstDriver(); + controller.update(); + }, child: Text( 'CASH', style: AppStyle.title, @@ -161,6 +165,9 @@ class CashConfirmPageShown extends StatelessWidget { paymentController.isWalletChecked = false; paymentController.update(); controller.changeCashConfirmPageShown(); + controller.isSearchingWindow = true; + controller.confirmRideForFirstDriver(); + controller.update(); }, ), ], @@ -169,6 +176,8 @@ class CashConfirmPageShown extends StatelessWidget { title: 'Next'.tr, onPressed: () { controller.changeCashConfirmPageShown(); + controller.confirmRideForFirstDriver(); + controller.update(); }, ), // Add a fallback widget if none of the conditions are met ) diff --git a/lib/views/home/map_widget.dart/form_search_start.dart b/lib/views/home/map_widget.dart/form_search_start.dart index a3b799d..171ec03 100644 --- a/lib/views/home/map_widget.dart/form_search_start.dart +++ b/lib/views/home/map_widget.dart/form_search_start.dart @@ -103,6 +103,12 @@ GetBuilder formSearchPlacesStart() { // controller.myLocation = // controller.newStartPointLocation; // } + await sql.insertData({ + 'latitude': res['geometry']['location']['lat'], + 'longitude': res['geometry']['location']['lng'], + 'name': res['name'].toString(), + 'rate': res['rating'].toString(), + }, TableName.recentLocations); controller.convertHintTextStartNewPlaces(index); controller.currentLocationString = res['name']; diff --git a/lib/views/home/map_widget.dart/google_map_passenger_widget.dart b/lib/views/home/map_widget.dart/google_map_passenger_widget.dart index cc5e463..f89bf14 100644 --- a/lib/views/home/map_widget.dart/google_map_passenger_widget.dart +++ b/lib/views/home/map_widget.dart/google_map_passenger_widget.dart @@ -19,306 +19,321 @@ class GoogleMapPassengerWidget extends StatelessWidget { return GetBuilder( builder: (controller) => controller.isLoading ? const MyCircularProgressIndicator() - : GoogleMap( - onMapCreated: controller.onMapCreated, - cameraTargetBounds: CameraTargetBounds(controller.boundsdata), - minMaxZoomPreference: const MinMaxZoomPreference(6, 18), - onLongPress: (argument) { - Get.defaultDialog( - title: 'Are you want to go to this site'.tr, - content: Column( - children: [ - Text('${argument.latitude},${argument.longitude}'), - ], - ), - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () async { - controller.clearPolyline(); - if (controller.dataCarsLocationByPassenger != null) { - await controller.getMap( - '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', - '${argument.latitude.toString()},${argument.longitude.toString()}'); + : Positioned( + bottom: Get.height * .2, + top: 0, + left: 0, + right: 0, + child: GoogleMap( + onMapCreated: controller.onMapCreated, + cameraTargetBounds: CameraTargetBounds(controller.boundsdata), + minMaxZoomPreference: const MinMaxZoomPreference(6, 18), + onLongPress: (argument) { + Get.defaultDialog( + title: 'Are you want to go to this site'.tr, + content: Column( + children: [ + Text('${argument.latitude},${argument.longitude}'), + ], + ), + confirm: MyElevatedButton( + title: 'Ok'.tr, + onPressed: () async { + controller.clearPolyline(); + if (controller.dataCarsLocationByPassenger != null) { + await controller.getMap( + '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', + '${argument.latitude.toString()},${argument.longitude.toString()}'); - Get.back(); - controller.bottomSheet(); - controller.showBottomSheet1(); - } else { - Get.back(); - Get.snackbar( - 'We Are Sorry That we dont have cars in your Location!' - .tr, - '', - colorText: AppColor.redColor, - duration: const Duration(seconds: 11), - instantInit: true, - snackPosition: SnackPosition.TOP, - titleText: Text( - 'Error'.tr, - style: const TextStyle(color: AppColor.redColor), - ), - messageText: Text( + Get.back(); + controller.bottomSheet(); + controller.showBottomSheet1(); + } else { + Get.back(); + Get.snackbar( 'We Are Sorry That we dont have cars in your Location!' .tr, - style: AppStyle.title, - ), - icon: const Icon(Icons.error), - shouldIconPulse: true, - maxWidth: double.infinity, - margin: const EdgeInsets.all(16), - padding: const EdgeInsets.all(16), - borderRadius: 8, - borderColor: AppColor.redColor, - borderWidth: 2, - backgroundColor: AppColor.secondaryColor, - leftBarIndicatorColor: AppColor.redColor, - boxShadows: [ - BoxShadow( - color: Colors.black.withOpacity(0.25), - blurRadius: 4, - spreadRadius: 2, - offset: const Offset(0, 4), + '', + colorText: AppColor.redColor, + duration: const Duration(seconds: 11), + instantInit: true, + snackPosition: SnackPosition.TOP, + titleText: Text( + 'Error'.tr, + style: + const TextStyle(color: AppColor.redColor), ), - ], - backgroundGradient: const LinearGradient( - colors: [AppColor.redColor, AppColor.accentColor], - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - // mainButton: TextButton( - // onPressed: () { - // controller.getCarsLocationByPassenger(); - // }, - // child: Text( - // 'Try Again'.tr, - // style: const TextStyle( - // color: AppColor.secondaryColor), - // ), - // ), - onTap: (GetSnackBar snackBar) { - // Do something when the snackbar is tapped. - }, - isDismissible: true, - showProgressIndicator: false, - dismissDirection: DismissDirection.up, - progressIndicatorController: null, - progressIndicatorBackgroundColor: - Colors.transparent, - progressIndicatorValueColor: null, - snackStyle: SnackStyle.GROUNDED, - forwardAnimationCurve: Curves.easeInToLinear, - reverseAnimationCurve: Curves.easeInOut, - animationDuration: - const Duration(milliseconds: 4000), - barBlur: 8, - overlayBlur: 0, - snackbarStatus: null, - overlayColor: - AppColor.primaryColor.withOpacity(0.5), - userInputForm: null, - ); - } + messageText: Text( + 'We Are Sorry That we dont have cars in your Location!' + .tr, + style: AppStyle.title, + ), + icon: const Icon(Icons.error), + shouldIconPulse: true, + maxWidth: double.infinity, + margin: const EdgeInsets.all(16), + padding: const EdgeInsets.all(16), + borderRadius: 8, + borderColor: AppColor.redColor, + borderWidth: 2, + backgroundColor: AppColor.secondaryColor, + leftBarIndicatorColor: AppColor.redColor, + boxShadows: [ + BoxShadow( + color: Colors.black.withOpacity(0.25), + blurRadius: 4, + spreadRadius: 2, + offset: const Offset(0, 4), + ), + ], + backgroundGradient: const LinearGradient( + colors: [ + AppColor.redColor, + AppColor.accentColor + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + // mainButton: TextButton( + // onPressed: () { + // controller.getCarsLocationByPassenger(); + // }, + // child: Text( + // 'Try Again'.tr, + // style: const TextStyle( + // color: AppColor.secondaryColor), + // ), + // ), + onTap: (GetSnackBar snackBar) { + // Do something when the snackbar is tapped. + }, + isDismissible: true, + showProgressIndicator: false, + dismissDirection: DismissDirection.up, + progressIndicatorController: null, + progressIndicatorBackgroundColor: + Colors.transparent, + progressIndicatorValueColor: null, + snackStyle: SnackStyle.GROUNDED, + forwardAnimationCurve: Curves.easeInToLinear, + reverseAnimationCurve: Curves.easeInOut, + animationDuration: + const Duration(milliseconds: 4000), + barBlur: 8, + overlayBlur: 0, + snackbarStatus: null, + overlayColor: + AppColor.primaryColor.withOpacity(0.5), + userInputForm: null, + ); + } - // - }), - ); - }, + // + }), + ); + }, - onTap: (argument) { - controller.hidePlaces(); + onTap: (argument) { + controller.hidePlaces(); - // controller.changeBottomSheetShown(); - // controller.bottomSheet(); - }, - initialCameraPosition: CameraPosition( - target: controller.passengerLocation, - zoom: 15, - ), - markers: { - for (var carLocation in controller.carsLocationByPassenger) - Marker( + // controller.changeBottomSheetShown(); + // controller.bottomSheet(); + }, + initialCameraPosition: CameraPosition( + target: controller.passengerLocation, + zoom: 15, + ), + markers: { + // controller.carMarkerAplied, + for (var carLocation in controller.carsLocationByPassenger) + Marker( // anchor: const Offset(4, 4), position: carLocation, icon: controller.carIcon, - markerId: MarkerId(carLocation.toString())), - for (var carLocation - in controller.driverCarsLocationToPassengerAfterApplied) - Marker( - // anchor: const Offset(4, 4), - position: carLocation, - icon: controller.carIcon, - markerId: MarkerId(carLocation.toString())), - for (int i = 1; - i < controller.coordinatesWithoutEmpty.length - 1; - i++) - Marker( - // anchor: const Offset(4, 4), + markerId: MarkerId(carLocation.toString()), + rotation: controller.angleDegrees, + ), /////////////////// + // controller.carMarrkerAplied, + for (var carLocation + in controller.driverCarsLocationToPassengerAfterApplied) + Marker( + // anchor: const Offset(4, 4), + position: carLocation, + icon: controller.carIcon, + markerId: MarkerId(carLocation.toString())), + for (int i = 1; + i < controller.coordinatesWithoutEmpty.length - 1; + i++) + Marker( + // anchor: const Offset(4, 4), + position: LatLng( + double.parse(controller.coordinatesWithoutEmpty[i] + .split(',')[0]), + double.parse(controller.coordinatesWithoutEmpty[i] + .split(',')[1])), + icon: controller.tripIcon, + markerId: MarkerId( + controller.coordinatesWithoutEmpty[i].toString())), + if (controller.isMarkersShown) + Marker( + markerId: MarkerId('MyLocation'.tr), + position: controller.newStartPointLocation, + draggable: true, + icon: controller.startIcon, + ), + if (controller.isMarkersShown) + Marker( + markerId: MarkerId('Destination'.tr), + position: controller.myDestination, + draggable: true, + icon: controller.endIcon, + ), + if (controller.haveSteps) + Marker( + markerId: MarkerId('StartSteps'.tr), position: LatLng( - double.parse(controller.coordinatesWithoutEmpty[i] - .split(',')[0]), - double.parse(controller.coordinatesWithoutEmpty[i] - .split(',')[1])), - icon: controller.tripIcon, - markerId: MarkerId( - controller.coordinatesWithoutEmpty[i].toString())), - if (controller.isMarkersShown) - Marker( - markerId: MarkerId('MyLocation'.tr), - position: controller.newStartPointLocation, - draggable: true, - icon: controller.startIcon, + double.parse( + controller.placesCoordinate[0].split(',')[0]), + double.parse( + controller.placesCoordinate[0].split(',')[1])), + draggable: true, + icon: controller.startIcon, + ), + if (controller.haveSteps) + Marker( + markerId: MarkerId('EndSteps'.tr), + position: controller.latestPosition, + draggable: true, + icon: controller.endIcon, + ), + }, + polylines: { + Polyline( + zIndex: 2, + consumeTapEvents: true, + geodesic: true, + endCap: Cap.buttCap, + startCap: Cap.buttCap, + visible: true, + polylineId: const PolylineId('route'), + points: controller.polylineCoordinates, + color: AppColor.primaryColor, + width: 5, ), - if (controller.isMarkersShown) - Marker( - markerId: MarkerId('Destination'.tr), - position: controller.myDestination, - draggable: true, - icon: controller.endIcon, + + Polyline( + zIndex: 1, + consumeTapEvents: true, + geodesic: true, + endCap: Cap.buttCap, + startCap: Cap.buttCap, + visible: true, + polylineId: const PolylineId('route0'), + points: controller.polylineCoordinatesPointsAll[0], + color: AppColor.blueColor, + width: 5, ), - if (controller.haveSteps) - Marker( - markerId: MarkerId('StartSteps'.tr), - position: LatLng( - double.parse( - controller.placesCoordinate[0].split(',')[0]), - double.parse( - controller.placesCoordinate[0].split(',')[1])), - draggable: true, - icon: controller.startIcon, + Polyline( + zIndex: 2, + consumeTapEvents: true, + geodesic: true, + endCap: Cap.buttCap, + startCap: Cap.buttCap, + visible: true, + polylineId: const PolylineId('route1'), + points: controller.polylineCoordinatesPointsAll[1], + color: AppColor.yellowColor, + width: 5, ), - if (controller.haveSteps) - Marker( - markerId: MarkerId('EndSteps'.tr), - position: controller.latestPosition, - draggable: true, - icon: controller.endIcon, + Polyline( + zIndex: 2, + consumeTapEvents: true, + geodesic: true, + endCap: Cap.buttCap, + startCap: Cap.buttCap, + visible: true, + polylineId: const PolylineId('route2'), + points: controller.polylineCoordinatesPointsAll[2], + color: AppColor.greenColor, + width: 5, ), - }, - polylines: { - Polyline( - zIndex: 2, - consumeTapEvents: true, - geodesic: true, - endCap: Cap.buttCap, - startCap: Cap.buttCap, - visible: true, - polylineId: const PolylineId('route'), - points: controller.polylineCoordinates, - color: AppColor.primaryColor, - width: 5, - ), + Polyline( + zIndex: 2, + consumeTapEvents: true, + geodesic: true, + endCap: Cap.buttCap, + startCap: Cap.buttCap, + visible: true, + polylineId: const PolylineId('route3'), + points: controller.polylineCoordinatesPointsAll[2], + color: AppColor.deepPurpleAccent, + width: 5, + ), + // Polyline( + // zIndex: 2, + // consumeTapEvents: true, + // geodesic: true, + // endCap: Cap.buttCap, + // startCap: Cap.buttCap, + // visible: true, + // polylineId: PolylineId('g'), + // points: [ + // LatLng(controller.southwest.latitude, + // controller.southwest.longitude), + // LatLng(controller.northeast.latitude, + // controller.northeast.longitude) + // ], + // color: AppColor.primaryColor, + // width: 5, + // ), + }, + // circles: { + // Circle( + // circleId: const CircleId('kk'), + // center: controller.mylocation, + // radius: 60, + // fillColor: AppColor.primaryColor,) + // }, - Polyline( - zIndex: 1, - consumeTapEvents: true, - geodesic: true, - endCap: Cap.buttCap, - startCap: Cap.buttCap, - visible: true, - polylineId: const PolylineId('route0'), - points: controller.polylineCoordinatesPointsAll[0], - color: AppColor.blueColor, - width: 5, - ), - Polyline( - zIndex: 2, - consumeTapEvents: true, - geodesic: true, - endCap: Cap.buttCap, - startCap: Cap.buttCap, - visible: true, - polylineId: const PolylineId('route1'), - points: controller.polylineCoordinatesPointsAll[1], - color: AppColor.yellowColor, - width: 5, - ), - Polyline( - zIndex: 2, - consumeTapEvents: true, - geodesic: true, - endCap: Cap.buttCap, - startCap: Cap.buttCap, - visible: true, - polylineId: const PolylineId('route2'), - points: controller.polylineCoordinatesPointsAll[2], - color: AppColor.greenColor, - width: 5, - ), - Polyline( - zIndex: 2, - consumeTapEvents: true, - geodesic: true, - endCap: Cap.buttCap, - startCap: Cap.buttCap, - visible: true, - polylineId: const PolylineId('route3'), - points: controller.polylineCoordinatesPointsAll[2], - color: AppColor.deepPurpleAccent, - width: 5, - ), - // Polyline( - // zIndex: 2, - // consumeTapEvents: true, - // geodesic: true, - // endCap: Cap.buttCap, - // startCap: Cap.buttCap, - // visible: true, - // polylineId: PolylineId('g'), - // points: [ - // LatLng(controller.southwest.latitude, - // controller.southwest.longitude), - // LatLng(controller.northeast.latitude, - // controller.northeast.longitude) - // ], - // color: AppColor.primaryColor, - // width: 5, - // ), - }, - // circles: { - // Circle( - // circleId: const CircleId('kk'), - // center: controller.mylocation, - // radius: 60, - // fillColor: AppColor.primaryColor,) - // }, + circles: { + Circle( + circleId: const CircleId('circle_id'), + center: controller.passengerLocation, + radius: 100, + fillColor: Colors.blue.withOpacity(0.3), + strokeColor: Colors.blue, + strokeWidth: 2, + ), + }, - circles: { - Circle( - circleId: const CircleId('circle_id'), - center: controller.passengerLocation, - radius: 100, - fillColor: Colors.blue.withOpacity(0.3), - strokeColor: Colors.blue, - strokeWidth: 2, - ), - }, + mapType: + controller.mapType ? MapType.satellite : MapType.normal, + myLocationButtonEnabled: true, + // liteModeEnabled: true, tiltGesturesEnabled: false, - mapType: controller.mapType ? MapType.satellite : MapType.normal, - myLocationButtonEnabled: true, - // liteModeEnabled: true, tiltGesturesEnabled: false, + // indoorViewEnabled: true, + trafficEnabled: controller.mapTrafficON, + buildingsEnabled: true, + mapToolbarEnabled: true, + onCameraMove: (position) { + int waypointsLength = + Get.find().wayPoints.length; + int index = controller.wayPointIndex; + if (waypointsLength > 0) { + controller.placesCoordinate[index] = + '${position.target.latitude.toString()},${position.target.longitude}'; + } + if (controller.startLocationFromMap == true) { + controller.newStartPointLocation = position.target; + } + controller.newMyLocation = position.target; - // indoorViewEnabled: true, - trafficEnabled: controller.mapTrafficON, - buildingsEnabled: true, - mapToolbarEnabled: true, - onCameraMove: (position) { - int waypointsLength = - Get.find().wayPoints.length; - int index = controller.wayPointIndex; - if (waypointsLength > 0) { - controller.placesCoordinate[index] = - '${position.target.latitude.toString()},${position.target.longitude}'; - } - if (controller.startLocationFromMap == true) { - controller.newStartPointLocation = position.target; - } - controller.newMyLocation = position.target; - - // print('my' + controller.mylocation.toString()); - // print('new' + controller.newMylocation.toString()); - }, - myLocationEnabled: true, - // liteModeEnabled: true, + // print('my' + controller.mylocation.toString()); + // print('new' + controller.newMylocation.toString()); + }, + myLocationEnabled: true, + // liteModeEnabled: true, + ), ), ); } diff --git a/lib/views/home/map_widget.dart/left_main_menu_icons.dart b/lib/views/home/map_widget.dart/left_main_menu_icons.dart index 8a59919..75bc513 100644 --- a/lib/views/home/map_widget.dart/left_main_menu_icons.dart +++ b/lib/views/home/map_widget.dart/left_main_menu_icons.dart @@ -114,14 +114,15 @@ GetBuilder leftMainMenuIcons() { onPressed: () { // NotificationController() // .showNotification('Order', 'hi this is', 'tone1'); - Get.to(() => DriverCallPage()); + // Get.to(() => DriverCallPage()); + print(controller.polylineCoordinates.toString()); // PassengerCallPage( // channelName: '', // token: '', // remoteID: '', // ) // Get.to(() => const CallPage()); - print(box.read(BoxName.lang)); + // print(box.read(BoxName.lang)); }, icon: const Icon( Icons.call, diff --git a/lib/views/home/map_widget.dart/main_bottom_Menu_map.dart b/lib/views/home/map_widget.dart/main_bottom_Menu_map.dart index bbb041b..08079a0 100644 --- a/lib/views/home/map_widget.dart/main_bottom_Menu_map.dart +++ b/lib/views/home/map_widget.dart/main_bottom_Menu_map.dart @@ -10,6 +10,7 @@ import 'package:SEFER/views/widgets/elevated_btn.dart'; import '../../../constant/colors.dart'; import '../../../constant/table_names.dart'; import '../../../controller/functions/toast.dart'; +import '../../../controller/functions/tts.dart'; import 'form_search_start.dart'; class MainBottomMenuMap extends StatelessWidget { @@ -23,298 +24,313 @@ class MainBottomMenuMap extends StatelessWidget { bottom: 3, left: 5, right: 5, - child: AnimatedContainer( - duration: const Duration(milliseconds: 500), - height: controller.mainBottomMenuMapHeight, - decoration: AppStyle.boxDecoration, - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.all(15), - child: InkWell( - onTap: () => controller.changeMainBottomMenuMap(), - child: Container( - width: Get.width * .8, - height: Get.height * .1, - decoration: const BoxDecoration( - boxShadow: [ - BoxShadow( - color: AppColor.accentColor, - blurRadius: 5, - offset: Offset(2, 4)), - BoxShadow( - color: AppColor.accentColor, - blurRadius: 5, - offset: Offset(-2, -2)) - ], - color: AppColor.secondaryColor, - borderRadius: BorderRadius.all( - Radius.elliptical(15, 30), - ), - ), - child: DefaultTextStyle( - style: AppStyle.title, - child: Center( - child: controller.isPickerShown - ? TextButton( - onPressed: () async { - controller.clearPolyline(); - controller.data = []; - if (controller - .startLocationFromMap == - true) { - controller.newMyLocation = - controller - .newStartPointLocation; - controller.hintTextStartPoint = - '${controller.newStartPointLocation.latitude.toStringAsFixed(4)} , ${controller.newStartPointLocation.longitude.toStringAsFixed(4)}'; - controller.startLocationFromMap = - false; - controller.isPickerShown = false; - } else if (controller - .workLocationFromMap == - true) { - controller - .hintTextDestinationPoint = - 'To Work'.tr; - box.write(BoxName.addWork, - '${controller.newMyLocation.latitude.toStringAsFixed(4)} , ${controller.newMyLocation.longitude.toStringAsFixed(4)}'); - controller.newMyLocation = - controller.newMyLocation; - controller.isPickerShown = false; - controller.workLocationFromMap = - false; - Toast.show( - context, - 'Work Saved'.tr, - AppColor.greenColor); - } else if (controller - .homeLocationFromMap == - true) { - controller - .hintTextDestinationPoint = - 'To Home'.tr; - box.write(BoxName.addHome, - '${controller.newMyLocation.latitude.toStringAsFixed(4)} , ${controller.newMyLocation.longitude.toStringAsFixed(4)}'); - controller.newMyLocation = - controller.newMyLocation; - controller.isPickerShown = false; - controller.homeLocationFromMap = - false; - controller.update(); - Toast.show( - context, - 'Home Saved'.tr, - AppColor.greenColor); - } else { - controller - .hintTextDestinationPoint = - '${controller.newMyLocation.latitude.toStringAsFixed(4)} , ${controller.newMyLocation.longitude.toStringAsFixed(4)}'; - controller.newMyLocation = - controller.newMyLocation; - controller.isPickerShown = false; - } + child: GestureDetector( + onVerticalDragUpdate: (DragUpdateDetails details) { + // Update the size of the GestureDetector based on the user's finger position. - controller.placesDestination = []; - controller - .placeDestinationController - .clear(); - - controller.showBottomSheet1(); - Get.back(); - controller.showBottomSheet1(); - controller - .changeMainBottomMenuMap(); - }, - child: Row( - children: [ - IconButton( - onPressed: () { - controller - .changeMainBottomMenuMap(); - }, - icon: controller - .isMainBottomMenuMap - ? const Icon( - Icons - .arrow_circle_up_rounded, - size: 35, - ) - : const Icon( - Icons - .arrow_circle_down_rounded, - size: 35, - ), - ), - Text( - "Click here point".tr, - style: AppStyle.title, - ), - ], - ), - ) - : Row( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - children: [ - IconButton( - onPressed: () { - controller - .changeMainBottomMenuMap(); - }, - icon: - controller.isMainBottomMenuMap - ? const Icon( - Icons.ads_click, - size: 35, - ) - : const Icon( - Icons - .arrow_circle_down_rounded, - size: 35, - ), - ), - Column( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - SizedBox( - height: 30, - child: Text( - '${'Where to'.tr} ${box.read(BoxName.name)}')), - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - controller.noCarString == - false - ? Text( - 'Nearest Car for you about ' - .tr) - : Container( - decoration: - BoxDecoration( - borderRadius: - BorderRadius - .circular( - 12), - color: AppColor - .redColor, - ), - child: Padding( - padding: - const EdgeInsets - .all(6), - child: Text( - 'No Car in your site. Sorry!' - .tr, - style: AppStyle - .title - .copyWith( - color: AppColor - .secondaryColor), - ), - ), - ), - controller.noCarString == - false - ? Container( - decoration: BoxDecoration( - border: Border.all( - color: AppColor - .redColor, - width: 3)), - child: Padding( - padding: - const EdgeInsets - .all(4), - child: Text((controller - .nearestCar != - null - ? controller - .durationByPassenger - .toString() - : 'N/A')), - ), - ) - : const SizedBox(), - ], - ) - ], - ), - ], + // _height = details.globalPosition.dy; + controller.changeMainBottomMenuMap(); + }, + child: AnimatedContainer( + duration: const Duration(milliseconds: 500), + height: controller.mainBottomMenuMapHeight, + decoration: AppStyle.boxDecoration, + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + controller.isMainBottomMenuMap + ? Padding( + padding: const EdgeInsets.all(15), + child: InkWell( + onTap: () => + controller.changeMainBottomMenuMap(), + child: Container( + width: Get.width * .8, + height: Get.height * .1, + decoration: AppStyle.boxDecoration1, + child: DefaultTextStyle( + style: AppStyle.title, + child: Center( + child: controller.isPickerShown + ? clickPointPosition( + controller, context) + : whereWidgetsmall(controller), ), + )), ), - )), - ), - ), - controller.isMainBottomMenuMap - ? const FavioratePlacesDialogu() - : const SizedBox(), - controller.isMainBottomMenuMap - ? const SizedBox() - : InkWell( - onTap: () async { - controller.getCurrentLocationFormString(); - }, - child: Text( - 'From :'.tr + - ' ${controller.currentLocationString}'.tr, - style: AppStyle.subtitle, + ) + : IconButton( + onPressed: () { + controller.changeMainBottomMenuMap(); + }, + icon: controller.isMainBottomMenuMap + ? const Icon( + Icons.ads_click, + size: 35, + ) + : const Icon( + Icons.arrow_circle_down_rounded, + size: 35, + ), ), - ), - controller.isMainBottomMenuMap - ? const SizedBox() - : Column( - children: [ - controller.currentLocationToFormPlaces - ? const SizedBox() - : formSearchPlacesStart(), - formSearchPlacesDestenation(), - const SizedBox( - height: 10, + controller.isMainBottomMenuMap + ? recentPlacesWidget(controller) + : const SizedBox(), + controller.isMainBottomMenuMap + ? const SizedBox() + : InkWell( + onTap: () async { + controller.getCurrentLocationFormString(); + }, + child: Text( + 'From :'.tr + + ' ${controller.currentLocationString}'.tr, + style: AppStyle.subtitle, ), - MyElevatedButton( - title: 'Get Details of Trip'.tr, - onPressed: () async { - controller.changeMainBottomMenuMap(); - - await controller.getMap( - '${controller.newStartPointLocation.latitude},${controller.newStartPointLocation.longitude}', - '${controller.newMyLocation.latitude},${controller.newMyLocation.longitude}', - ); - controller.currentLocationToFormPlaces = - false; - controller.placesDestination = []; - // controller.isCancelRidePageShown = true; - controller.clearPlacesStart(); - controller.clearPlacesDestination(); - - controller.showBottomSheet1(); - Get.back(); - controller.showBottomSheet1(); - }), - TextButton( - onPressed: () { - controller.changeMainBottomMenuMap(); - controller.changeWayPointSheet(); - }, - child: Text( - "If you want add stop click here".tr, - style: AppStyle.title, + ), + controller.isMainBottomMenuMap + ? const SizedBox() + : Column( + children: [ + controller.currentLocationToFormPlaces + ? const SizedBox() + : formSearchPlacesStart(), + formSearchPlacesDestenation(), + const SizedBox( + height: 10, ), - ), - ], - ) - ], + MyElevatedButton( + title: 'Get Details of Trip'.tr, + onPressed: () async { + controller.changeMainBottomMenuMap(); + + await controller.getMap( + '${controller.newStartPointLocation.latitude},${controller.newStartPointLocation.longitude}', + '${controller.newMyLocation.latitude},${controller.newMyLocation.longitude}', + ); + controller.currentLocationToFormPlaces = + false; + controller.placesDestination = []; + // controller.isCancelRidePageShown = true; + controller.clearPlacesStart(); + controller.clearPlacesDestination(); + + controller.showBottomSheet1(); + Get.back(); + controller.showBottomSheet1(); + }), + TextButton( + onPressed: () { + controller.changeMainBottomMenuMap(); + controller.changeWayPointSheet(); + }, + child: Text( + "If you want add stop click here".tr, + style: AppStyle.title, + ), + ), + ], + ) + ], + ), ), ), ), )); } + + SizedBox recentPlacesWidget(MapPassengerController controller) { + final textToSpeechController = Get.put(TextToSpeechController()); + return SizedBox( + height: 50, + child: ListView.builder( + itemCount: controller.recentPlaces.length, + scrollDirection: Axis.horizontal, + itemBuilder: (BuildContext context, int index) { + return TextButton( + onPressed: () { + Get.defaultDialog( + title: 'Are you want to go this site'.tr, + titleStyle: AppStyle.title, + middleText: '', + content: IconButton( + onPressed: () { + textToSpeechController + .speakText('Are you want to go this site'.tr); + }, + icon: const Icon( + Icons.headphones, + size: 45, + ), + ), + confirm: MyElevatedButton( + title: 'Yes'.tr, + onPressed: () async { + await controller.getLocation(); + await controller.getMap( + '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', + '${controller.recentPlaces[index]['latitude']},${controller.recentPlaces[index]['longitude']}', + ); + // controller.changePickerShown(); + controller.showBottomSheet1(); + + // controller.showBottomSheet1(); + Get.back(); + }, + )); + }, + child: Container( + decoration: AppStyle.boxDecoration1, + child: Padding( + padding: const EdgeInsets.all(2), + child: Text( + controller.recentPlaces[index]['name'], + style: AppStyle.title, + ), + ), + ), + ); + }, + ), + ); + } + + TextButton clickPointPosition( + MapPassengerController controller, BuildContext context) { + return TextButton( + onPressed: () async { + controller.clearPolyline(); + controller.data = []; + if (controller.startLocationFromMap == true) { + controller.newMyLocation = controller.newStartPointLocation; + controller.hintTextStartPoint = + '${controller.newStartPointLocation.latitude.toStringAsFixed(4)} , ${controller.newStartPointLocation.longitude.toStringAsFixed(4)}'; + controller.startLocationFromMap = false; + controller.isPickerShown = false; + } else if (controller.workLocationFromMap == true) { + controller.hintTextDestinationPoint = 'To Work'.tr; + box.write(BoxName.addWork, + '${controller.newMyLocation.latitude.toStringAsFixed(4)} , ${controller.newMyLocation.longitude.toStringAsFixed(4)}'); + controller.newMyLocation = controller.newMyLocation; + controller.isPickerShown = false; + controller.workLocationFromMap = false; + Get.snackbar('Work Saved'.tr, '', + backgroundColor: AppColor.greenColor); + } else if (controller.homeLocationFromMap == true) { + controller.hintTextDestinationPoint = 'To Home'.tr; + box.write(BoxName.addHome, + '${controller.newMyLocation.latitude.toStringAsFixed(4)} , ${controller.newMyLocation.longitude.toStringAsFixed(4)}'); + controller.newMyLocation = controller.newMyLocation; + controller.isPickerShown = false; + controller.homeLocationFromMap = false; + controller.update(); + Get.snackbar('Home Saved'.tr, '', + backgroundColor: AppColor.greenColor); + } else { + controller.hintTextDestinationPoint = + '${controller.newMyLocation.latitude.toStringAsFixed(4)} , ${controller.newMyLocation.longitude.toStringAsFixed(4)}'; + controller.newMyLocation = controller.newMyLocation; + controller.isPickerShown = false; + } + + controller.placesDestination = []; + controller.placeDestinationController.clear(); + + controller.showBottomSheet1(); + Get.back(); + controller.showBottomSheet1(); + controller.changeMainBottomMenuMap(); + }, + child: Row( + children: [ + IconButton( + onPressed: () { + controller.changeMainBottomMenuMap(); + }, + icon: controller.isMainBottomMenuMap + ? const Icon( + Icons.arrow_circle_up_rounded, + size: 35, + ) + : const Icon( + Icons.arrow_circle_down_rounded, + size: 35, + ), + ), + Text( + "Click here point".tr, + style: AppStyle.title, + ), + ], + ), + ); + } + + Row whereWidgetsmall(MapPassengerController controller) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + IconButton( + onPressed: () { + controller.changeMainBottomMenuMap(); + }, + icon: controller.isMainBottomMenuMap + ? const Icon( + Icons.ads_click, + size: 35, + ) + : const Icon( + Icons.arrow_circle_down_rounded, + size: 35, + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + height: 30, + child: Text('${'Where to'.tr} ${box.read(BoxName.name)}')), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + controller.noCarString == false + ? Text('Nearest Car for you about '.tr) + : Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: AppColor.redColor, + ), + child: Padding( + padding: const EdgeInsets.all(6), + child: Text( + 'No Car in your site. Sorry!'.tr, + style: AppStyle.title + .copyWith(color: AppColor.secondaryColor), + ), + ), + ), + controller.noCarString == false + ? Container( + decoration: BoxDecoration( + border: + Border.all(color: AppColor.redColor, width: 3)), + child: Padding( + padding: const EdgeInsets.all(4), + child: Text((controller.nearestCar != null + ? controller.nearestDistance.toStringAsFixed(0) + : 'N/A')), + ), + ) + : const SizedBox(), + ], + ) + ], + ), + ], + ); + } } class FavioratePlacesDialogu extends StatelessWidget { diff --git a/lib/views/home/map_widget.dart/searching_captain_window.dart b/lib/views/home/map_widget.dart/searching_captain_window.dart new file mode 100644 index 0000000..24b32eb --- /dev/null +++ b/lib/views/home/map_widget.dart/searching_captain_window.dart @@ -0,0 +1,211 @@ +import 'dart:async'; + +import 'package:SEFER/constant/colors.dart'; +import 'package:SEFER/constant/style.dart'; +import 'package:SEFER/controller/home/map_passenger_controller.dart'; +import 'package:SEFER/views/widgets/elevated_btn.dart'; +import 'package:SEFER/views/widgets/my_textField.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class SearchingCaptainWindow extends StatelessWidget { + const SearchingCaptainWindow({super.key}); + + @override + Widget build(BuildContext context) { + return GetBuilder( + builder: (mapPassengerController) { + return mapPassengerController.isSearchingWindow + ? Positioned( + bottom: 0, + left: 0, + right: 0, + child: Container( + decoration: AppStyle.boxDecoration1, + height: Get.height * .2, + child: Column( + // Use Stack for overlapping widgets + children: [ + // Text elements + SizedBox( + width: Get.width * .7, + child: const LinearProgressIndicator( + minHeight: 6, + backgroundColor: AppColor.yellowColor, + color: AppColor.secondaryColor, + ), + ), + Text( + 'We search nearst Driver to you'.tr, + style: AppStyle.headTitle2, + ), + Text( + 'please wait till driver accept your order'.tr, + style: AppStyle.title, + ), // Timer logic + _buildTimer(mapPassengerController), + ], + ), + ), + ) + : const SizedBox(); + }, + ); + } +} + +Widget _buildTimer(MapPassengerController mapPassengerController) { + // Start timer at 0 + Timer? timer; + + return StreamBuilder( + // Use StreamBuilder for timer updates + stream: Stream.periodic(const Duration(seconds: 1)) + .map((_) => ++mapPassengerController.currentTimeSearchingCaptainWindow), + initialData: 0, + builder: (context, snapshot) { + if (snapshot.hasData && snapshot.data! > 30) { + timer?.cancel(); // Cancel timer after 60 seconds + return GestureDetector( + onTap: () { + Get.defaultDialog( + barrierDismissible: false, + title: "Increase Your Trip Fee (Optional)".tr, + titleStyle: AppStyle.title, + content: Column( + children: [ + Text( + "We haven't found any drivers yet. Consider increasing your trip fee to make your offer more attractive to drivers." + .tr, + style: AppStyle.title, + textAlign: TextAlign.center, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + IconButton( + onPressed: () { + mapPassengerController.increasFeeFromPassenger.text = + (mapPassengerController.totalPassenger + 3) + .toStringAsFixed(1); + // mapPassengerController.increasFeeFromPassenger.text = + // mapPassengerController.totalPassenger + // .toStringAsFixed(1); + mapPassengerController.update(); + }, + icon: Column( + children: [ + Text( + '3', + style: AppStyle.number, + ), + Container( + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: AppColor.greenColor), + child: const Icon( + Icons.arrow_circle_up, + size: 30, + color: AppColor.secondaryColor, + ), + ), + ], + ), + ), + SizedBox( + width: 100, + child: Form( + key: mapPassengerController.increasFeeFormKey, + child: MyTextForm( + controller: mapPassengerController + .increasFeeFromPassenger, + label: mapPassengerController.totalPassenger + .toStringAsFixed(2), + hint: mapPassengerController.totalPassenger + .toStringAsFixed(2), + type: TextInputType.number), + ), + ), + IconButton( + onPressed: () { + // if ((double.parse(mapPassengerController + // .increasFeeFromPassenger.text) > + // totalPassenger)) {} + mapPassengerController.increasFeeFromPassenger.text = + (mapPassengerController.totalPassenger - 3) + .toStringAsFixed(1); + // mapPassengerController.increasFeeFromPassenger.text = + // mapPassengerController.totalPassenger + // .toStringAsFixed(1); + mapPassengerController.update(); + }, + icon: Column( + children: [ + Text( + '3', + style: AppStyle.number, + ), + Container( + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: AppColor.redColor), + child: const Icon( + Icons.arrow_drop_down_circle_outlined, + size: 30, + color: AppColor.secondaryColor, + ), + ), + ], + ), + ), + ], + ) + ], + ), + actions: [ + MyElevatedButton( + title: "No, thanks", + onPressed: () { + Get.back(); + }), + MyElevatedButton( + title: "Increase Fee".tr, + onPressed: () { + mapPassengerController.increaseFeeByPassengerAndReOrder(); + }) + ], + ); + }, + child: Text( + "No accepted orders? Try raising your trip fee to attract riders." + .tr, + style: AppStyle.title.copyWith(color: AppColor.blueColor), + ), + ); + } + + // Update progress for circular indicator (0.0 to 1.0) + final double progress = + snapshot.data!.toDouble() / 30.0; // Normalize progress + + return Stack( + children: [ + Center( + child: CircularProgressIndicator( + value: progress, // Use calculated progress + color: AppColor.blueColor, + backgroundColor: AppColor.yellowColor, + ), + ), + Center( + child: Text( + '${snapshot.data} ', // Display elapsed time + style: AppStyle.title.copyWith( + color: AppColor.greenColor), // Adjust color for timer + ), + ) + ], + ); + }, + ); +} diff --git a/lib/views/home/map_widget.dart/timer_to_passenger_from_driver.dart b/lib/views/home/map_widget.dart/timer_to_passenger_from_driver.dart index 179ff8d..065a7d7 100644 --- a/lib/views/home/map_widget.dart/timer_to_passenger_from_driver.dart +++ b/lib/views/home/map_widget.dart/timer_to_passenger_from_driver.dart @@ -76,7 +76,7 @@ class TimerToPassengerFromDriver extends StatelessWidget { title: 'You can cancel trip'.tr, onPressed: () async { await controller - .calculateDistanceBetweenPassengerAndDriverBeforecancelRide(); + .calculateDistanceBetweenPassengerAndDriverBeforeCancelRide(); }) : const SizedBox() ], diff --git a/lib/views/home/my_wallet/passenger_wallet_dialoge.dart b/lib/views/home/my_wallet/passenger_wallet_dialoge.dart index 159586b..9cb6547 100644 --- a/lib/views/home/my_wallet/passenger_wallet_dialoge.dart +++ b/lib/views/home/my_wallet/passenger_wallet_dialoge.dart @@ -148,9 +148,9 @@ class PassengerWalletDialoge extends StatelessWidget { controller.makePaymentStripe( controller.selectedAmount! .toDouble(), // Convert int to double - box.read(BoxName.countryCode) == 'Jordan'.tr - ? 'USD' - : 'EGP', () { + box.read(BoxName.countryCode) != 'Egypt'.tr + ? 'EGP' + : 'USD', () { controller.addPassengerWallet(); controller.changePromoSheetDialogue(); controller.getPassengerWallet(); diff --git a/lib/views/home/my_wallet/walet_captain.dart b/lib/views/home/my_wallet/walet_captain.dart index 207896e..78f0e68 100644 --- a/lib/views/home/my_wallet/walet_captain.dart +++ b/lib/views/home/my_wallet/walet_captain.dart @@ -43,19 +43,19 @@ class WaletCaptain extends StatelessWidget { 0 && double.parse(captainWalletController .totalPoints) > - -500 + -300 ? AppColor.yellowColor : double.parse(captainWalletController .totalPoints) < - -500 + -300 ? AppColor.redColor : AppColor.greenColor, ), child: InkWell( onTap: () { Get.snackbar( - 'the 500 points equal 30 JOD'.tr, - 'the 500 points equal 30 JOD for you \nSo go and gain your money' + 'the 300 points equal 30 JOD'.tr, + 'the 300 points equal 30 JOD for you \nSo go and gain your money' .tr, backgroundColor: AppColor.greenColor, snackPosition: SnackPosition.BOTTOM, @@ -77,7 +77,7 @@ class WaletCaptain extends StatelessWidget { ), double.parse(captainWalletController.totalPoints .toString()) < - -500 + -300 ? MyElevatedButton( title: 'Charge your Account'.tr, onPressed: () {}) @@ -258,7 +258,7 @@ class WaletCaptain extends StatelessWidget { PointsCaptain( kolor: AppColor.blueColor, pricePoint: 5.6, - countPoint: '500', + countPoint: '300', ), PointsCaptain( kolor: Colors.green, diff --git a/lib/views/widgets/elevated_btn.dart b/lib/views/widgets/elevated_btn.dart index 7f2fdb0..3d0145f 100644 --- a/lib/views/widgets/elevated_btn.dart +++ b/lib/views/widgets/elevated_btn.dart @@ -1,5 +1,9 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:SEFER/constant/style.dart'; +import 'package:flutter/services.dart'; +import 'package:vibration/vibration.dart'; import '../../constant/colors.dart'; @@ -7,11 +11,13 @@ class MyElevatedButton extends StatelessWidget { final String title; final VoidCallback onPressed; final Color kolor; + final int vibrateDuration; const MyElevatedButton({ Key? key, required this.title, required this.onPressed, this.kolor = AppColor.primaryColor, + this.vibrateDuration = 100, }) : super(key: key); @override @@ -20,7 +26,18 @@ class MyElevatedButton extends StatelessWidget { style: ButtonStyle( backgroundColor: MaterialStateProperty.all(kolor), ), - onPressed: onPressed, + onPressed: () async { + // Handle haptic feedback for both iOS and Android + if (Platform.isIOS) { + HapticFeedback.selectionClick(); + } else { + Vibration.vibrate(duration: 100); + // Vibrate.vibrateWithPauses(pauses); + } + + // Ensure the onPressed callback is called after haptic feedback + onPressed(); + }, child: Text( title, textAlign: TextAlign.center, diff --git a/pubspec.lock b/pubspec.lock index b2330f1..2b110e3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -73,6 +73,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.18" + background_location: + dependency: "direct main" + description: + name: background_location + sha256: fbb83ceb8cefcc6793f0a362f12773c28fc290a5e2c76cb593ee592ec7b6cb32 + url: "https://pub.dev" + source: hosted + version: "0.13.0" boolean_selector: dependency: transitive description: @@ -1829,6 +1837,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vibration: + dependency: "direct main" + description: + name: vibration + sha256: "778ace40e84852e6cf6017cdbaf6790a837d73ff3dd50b27da9ac232a19de8fc" + url: "https://pub.dev" + source: hosted + version: "1.8.4" video_player: dependency: transitive description: @@ -1878,7 +1894,7 @@ packages: source: hosted version: "13.0.0" wakelock_plus: - dependency: transitive + dependency: "direct main" description: name: wakelock_plus sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d diff --git a/pubspec.yaml b/pubspec.yaml index 91e14aa..66e713b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,6 +54,9 @@ dependencies: flutter_tts: ^3.8.5 permission_handler: ^11.3.0 google_generative_ai: ^0.0.1-dev + vibration: ^1.8.4 + wakelock_plus: + background_location: ^0.13.0