diff --git a/android/app/build.gradle b/android/app/build.gradle index 237ecf9..41a0ed9 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -54,8 +54,8 @@ android { // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdk = 23 targetSdk = flutter.targetSdkVersion - versionCode = 103 - versionName = '1.5.03' + versionCode = 104 + versionName = '1.5.04' multiDexEnabled =true } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d1e44f5..f879353 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -27,6 +27,7 @@ + My App - - default_channel + high_importance_channel AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0 FCM Notifications Notifications from Firebase Cloud Messaging - - - \ No newline at end of file diff --git a/assets/images/car.png b/assets/images/car.png index b5beb73..2e7085d 100644 Binary files a/assets/images/car.png and b/assets/images/car.png differ diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 92c2bc7..a496cb0 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -13,14 +13,6 @@ PODS: - Flutter - device_info_plus (0.0.1): - Flutter - - FBAEMKit (17.0.3): - - FBSDKCoreKit_Basics (= 17.0.3) - - FBSDKCoreKit (17.0.3): - - FBAEMKit (= 17.0.3) - - FBSDKCoreKit_Basics (= 17.0.3) - - FBSDKCoreKit_Basics (17.0.3) - - FBSDKLoginKit (17.0.3): - - FBSDKCoreKit (= 17.0.3) - Firebase/Auth (10.28.0): - Firebase/CoreOnly - FirebaseAuth (~> 10.28.0) @@ -71,9 +63,6 @@ PODS: - Flutter (1.0.0) - flutter_contacts (0.0.1): - Flutter - - flutter_facebook_auth (7.0.1): - - FBSDKLoginKit (~> 17.0.2) - - Flutter - flutter_image_compress_common (1.0.0): - Flutter - Mantle @@ -297,7 +286,6 @@ DEPENDENCIES: - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - Flutter (from `Flutter`) - flutter_contacts (from `.symlinks/plugins/flutter_contacts/ios`) - - flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`) - flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) @@ -329,10 +317,6 @@ DEPENDENCIES: SPEC REPOS: trunk: - AppAuth - - FBAEMKit - - FBSDKCoreKit - - FBSDKCoreKit_Basics - - FBSDKLoginKit - Firebase - FirebaseAppCheckInterop - FirebaseAuth @@ -390,8 +374,6 @@ EXTERNAL SOURCES: :path: Flutter flutter_contacts: :path: ".symlinks/plugins/flutter_contacts/ios" - flutter_facebook_auth: - :path: ".symlinks/plugins/flutter_facebook_auth/ios" flutter_image_compress_common: :path: ".symlinks/plugins/flutter_image_compress_common/ios" flutter_local_notifications: @@ -453,10 +435,6 @@ SPEC CHECKSUMS: background_location: 1b80c1fe3abd9912bca298618f6e365abf6f588f camera_avfoundation: dd002b0330f4981e1bbcb46ae9b62829237459a4 device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d - FBAEMKit: 9900b2edd99a2d21629a6277e6166f14c6215799 - FBSDKCoreKit: 0791f8f68a8630931a4c12aa23a56cc021551596 - FBSDKCoreKit_Basics: 46d6b472c0dd0a5a7e972c025033d1c567f54eb4 - FBSDKLoginKit: b4a4eba1d62eb452544411824f41689adabd5bd2 Firebase: 5121c624121af81cbc81df3bda414b3c28c4f3c3 firebase_auth: e778ee89483b86fe4200d1f8e9a1c52aa5fb64a8 firebase_core: a9d0180d5285527884d07a41eb4a9ec9ed12cdb6 @@ -469,7 +447,6 @@ SPEC CHECKSUMS: FirebaseMessaging: 087a7c7cadef7b9239f005bc4db823894844f323 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_contacts: edb1c5ce76aa433e20e6cb14c615f4c0b66e0983 - flutter_facebook_auth: 4fa1dc3fa624284a5ddfdf9e4a2b7945b3835949 flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086 flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 14408e4..17abe8c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -33,7 +33,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 62 + 64 CFBundleSignature ???? CFBundleURLTypes @@ -48,7 +48,7 @@ CFBundleVersion - 4.0.62 + 4.0.64 FirebaseAppDelegateProxyEnabled NO GMSApiKey diff --git a/lib/controller/auth/captin/register_captin_controller.dart b/lib/controller/auth/captin/register_captin_controller.dart index 1b7dc1d..2fb27ec 100644 --- a/lib/controller/auth/captin/register_captin_controller.dart +++ b/lib/controller/auth/captin/register_captin_controller.dart @@ -94,138 +94,139 @@ class RegisterCaptainController extends GetxController { return validPrefixes.hasMatch(phoneNumber); } - // sendOtpMessage() async { - // SmsEgyptController smsEgyptController = Get.put(SmsEgyptController()); - // isLoading = true; - // update(); - // int randomNumber = Random().nextInt(100000) + 1; - // isLoading = true; - // update(); - // if (formKey3.currentState!.validate()) { - // if (box.read(BoxName.countryCode) == 'Egypt') { - // if (isValidEgyptianPhoneNumber(phoneController.text)) { - // var responseCheker = await CRUD() - // .post(link: AppLink.checkPhoneNumberISVerfiedDriver, payload: { - // 'phone_number': '+2${phoneController.text}', - // }); - // if (responseCheker != 'failure') { - // var d = jsonDecode(responseCheker); - // if (d['message'][0]['is_verified'].toString() == '1') { - // Get.snackbar('Phone number is verified before'.tr, '', - // backgroundColor: AppColor.greenColor); - // box.write(BoxName.phoneVerified, '1'); - // box.write(BoxName.phone, '+2${phoneController.text}'); - // await Get.put(LoginDriverController()).loginUsingCredentials( - // box.read(BoxName.driverID).toString(), - // box.read(BoxName.emailDriver).toString(), - // ); - // } else { - // await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { - // 'phone_number': '+2${phoneController.text}', - // 'token_code': randomNumber.toString(), - // "driverId": box.read(BoxName.driverID), - // "email": box.read(BoxName.emailDriver), - // }); + sendOtpMessage() async { + SmsEgyptController smsEgyptController = Get.put(SmsEgyptController()); + isLoading = true; + update(); + int randomNumber = Random().nextInt(100000) + 1; + isLoading = true; + update(); + if (formKey3.currentState!.validate()) { + if (box.read(BoxName.countryCode) == 'Egypt') { + if (isValidEgyptianPhoneNumber(phoneController.text)) { + var responseCheker = await CRUD() + .post(link: AppLink.checkPhoneNumberISVerfiedDriver, payload: { + 'phone_number': '+2${phoneController.text}', + }); + if (responseCheker != 'failure') { + var d = jsonDecode(responseCheker); + if (d['message'][0]['is_verified'].toString() == '1') { + Get.snackbar('Phone number is verified before'.tr, '', + backgroundColor: AppColor.greenColor); + box.write(BoxName.phoneVerified, '1'); + box.write(BoxName.phone, '+2${phoneController.text}'); + await Get.put(LoginDriverController()).loginUsingCredentials( + box.read(BoxName.driverID).toString(), + box.read(BoxName.emailDriver).toString(), + ); + } else { + await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { + 'phone_number': '+2${phoneController.text}', + 'token_code': randomNumber.toString(), + "driverId": box.read(BoxName.driverID), + "email": box.read(BoxName.emailDriver), + }); - // await smsEgyptController.sendSmsEgypt( - // phoneController.text.toString(), randomNumber.toString()); + await smsEgyptController.sendSmsEgypt( + phoneController.text.toString(), randomNumber.toString()); - // isSent = true; + isSent = true; - // isLoading = false; - // update(); - // } - // } else { - // await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { - // 'phone_number': '+2${phoneController.text}', - // 'token_code': randomNumber.toString(), - // "driverId": box.read(BoxName.driverID), - // "email": box.read(BoxName.emailDriver), - // }); + isLoading = false; + update(); + } + } else { + await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { + 'phone_number': '+2${phoneController.text}', + 'token_code': randomNumber.toString(), + "driverId": box.read(BoxName.driverID), + "email": box.read(BoxName.emailDriver), + }); - // await smsEgyptController.sendSmsEgypt( - // phoneController.text.toString(), randomNumber.toString()); + await smsEgyptController.sendSmsEgypt( + phoneController.text.toString(), randomNumber.toString()); - // isSent = true; + isSent = true; + + isLoading = false; + update(); + } + } else { + Get.snackbar('Phone Number wrong'.tr, '', + backgroundColor: AppColor.redColor); + } + } + } + isLoading = false; + update(); + } - // isLoading = false; - // update(); - // } - // } else { - // Get.snackbar('Phone Number wrong'.tr, '', - // backgroundColor: AppColor.redColor); - // } - // } - // } - // isLoading = false; - // update(); - // } DateTime? lastOtpSentTime; // Store the last OTP sent time int otpResendInterval = 300; // 5 minutes in seconds // Main function to handle OTP sending - sendOtpMessage() async { - if (_isOtpResendAllowed()) { - isLoading = true; - update(); + // sendOtpMessage() async { + // if (_isOtpResendAllowed()) { + // isLoading = true; + // update(); - if (formKey3.currentState!.validate()) { - String countryCode = box.read(BoxName.countryCode); - String phoneNumber = phoneController.text; + // if (formKey3.currentState!.validate()) { + // String countryCode = box.read(BoxName.countryCode); + // String phoneNumber = phoneController.text; - if (countryCode == 'Egypt' && isValidEgyptianPhoneNumber(phoneNumber)) { - await _checkAndSendOtp(phoneNumber); - } else { - _showErrorMessage('Phone Number is not Egypt phone '.tr); - } - } - isLoading = false; - update(); - } else { - _showCooldownMessage(); - } - } + // if (countryCode == 'Egypt' && isValidEgyptianPhoneNumber(phoneNumber)) { + // await _checkAndSendOtp(phoneNumber); + // } else { + // _showErrorMessage('Phone Number is not Egypt phone '.tr); + // } + // } + // isLoading = false; + // update(); + // } else { + // _showCooldownMessage(); + // } + // } // Check if the resend OTP request is allowed (5 minutes cooldown) - bool _isOtpResendAllowed() { - if (lastOtpSentTime == null) return true; +// bool _isOtpResendAllowed() { +// if (lastOtpSentTime == null) return true; - final int elapsedTime = - DateTime.now().difference(lastOtpSentTime!).inSeconds; - return elapsedTime >= otpResendInterval; - } +// final int elapsedTime = +// DateTime.now().difference(lastOtpSentTime!).inSeconds; +// return elapsedTime >= otpResendInterval; +// } -// Show message when user tries to resend OTP too soon - void _showCooldownMessage() { - int remainingTime = otpResendInterval - - DateTime.now().difference(lastOtpSentTime!).inSeconds; - Get.snackbar( - 'Please wait ${remainingTime ~/ 60}:${(remainingTime % 60).toString().padLeft(2, '0')} minutes before requesting again', - '', - backgroundColor: AppColor.redColor, - ); - } +// // Show message when user tries to resend OTP too soon +// void _showCooldownMessage() { +// int remainingTime = otpResendInterval - +// DateTime.now().difference(lastOtpSentTime!).inSeconds; +// Get.snackbar( +// 'Please wait ${remainingTime ~/ 60}:${(remainingTime % 60).toString().padLeft(2, '0')} minutes before requesting again', +// '', +// backgroundColor: AppColor.redColor, +// ); +// } -// Check if the phone number has been verified, and send OTP if not verified - _checkAndSendOtp(String phoneNumber) async { - var responseChecker = await CRUD().post( - link: AppLink.checkPhoneNumberISVerfiedDriver, - payload: { - 'phone_number': '+2$phoneNumber', - }, - ); +// // Check if the phone number has been verified, and send OTP if not verified +// _checkAndSendOtp(String phoneNumber) async { +// var responseChecker = await CRUD().post( +// link: AppLink.checkPhoneNumberISVerfiedDriver, +// payload: { +// 'phone_number': '+2$phoneNumber', +// }, +// ); - if (responseChecker != 'failure') { - var responseData = jsonDecode(responseChecker); - if (_isPhoneVerified(responseData)) { - _handleAlreadyVerified(); - } else { - await _sendOtpAndSms(phoneNumber); - } - } else { - await _sendOtpAndSms(phoneNumber); - } - } +// if (responseChecker != 'failure') { +// var responseData = jsonDecode(responseChecker); +// if (_isPhoneVerified(responseData)) { +// _handleAlreadyVerified(); +// } else { +// await _sendOtpAndSms(phoneNumber); +// } +// } else { +// await _sendOtpAndSms(phoneNumber); +// } +// } // Check if the phone number is already verified bool _isPhoneVerified(dynamic responseData) { diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart index e0a4414..bcd9342 100644 --- a/lib/controller/firebase/firbase_messge.dart +++ b/lib/controller/firebase/firbase_messge.dart @@ -115,7 +115,7 @@ class FirebaseMessagesController extends GetxController { Future fireBaseTitles(RemoteMessage message) async { if (message.notification!.title! == 'Order'.tr) { if (Platform.isAndroid) { - NotificationController1().showNotification('Order'.tr, '', 'order', ''); + NotificationController().showNotification('Order'.tr, '', 'order', ''); } // await FirebaseMessagesController().showOverlayNotification(message); var myListString = message.data['DriverList']; @@ -156,6 +156,8 @@ class FirebaseMessagesController extends GetxController { }); // Get.to(const VipOrderPage()); + } else if (message.notification!.title! == 'message From passenger'.tr) { + passengerDialog(message.notification!.body!); } else if (message.notification!.title == 'Cancel') { cancelTripDialog1(); } else if (message.notification!.title! == 'token change') { @@ -163,15 +165,6 @@ class FirebaseMessagesController extends GetxController { // .showNotification('token change'.tr, 'token change', 'cancel'); // GoogleSignInHelper.signOut(); GoogleSignInHelper.signOut(); - } else if (message.notification!.title! == 'message From passenger') { - // print('sdfd'); - // if (Platform.isAndroid) { - // NotificationController1() - // .showNotification('message From passenger'.tr, ''.tr, 'tone2', ''); - // } - passengerDialog(message.notification!.body!); - - update(); } else if (message.notification!.title! == 'face detect') { if (Platform.isAndroid) { NotificationController1() diff --git a/lib/controller/firebase/local_notification.dart b/lib/controller/firebase/local_notification.dart index 027ab08..cf94801 100644 --- a/lib/controller/firebase/local_notification.dart +++ b/lib/controller/firebase/local_notification.dart @@ -15,7 +15,7 @@ import '../home/captin/home_captain_controller.dart'; class NotificationController extends GetxController { final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); - // Initializes the local notifications plugin + Future initNotifications() async { const AndroidInitializationSettings android = AndroidInitializationSettings('@mipmap/launcher_icon'); @@ -26,14 +26,13 @@ class NotificationController extends GetxController { await _flutterLocalNotificationsPlugin.initialize( initializationSettings, onDidReceiveNotificationResponse: onDidReceiveNotificationResponse, - onDidReceiveBackgroundNotificationResponse: - onDidReceiveBackgroundNotificationResponse, + onDidReceiveBackgroundNotificationResponse: notificationTapBackground, ); // Create a notification channel const AndroidNotificationChannel channel = AndroidNotificationChannel( - 'your channel id', - 'your channel name', + 'high_importance_channel', // Use the same ID as in strings.xml + 'High Importance Notifications', description: 'This channel is used for important notifications.', importance: Importance.high, ); @@ -56,7 +55,8 @@ class NotificationController extends GetxController { ); AndroidNotificationDetails android = AndroidNotificationDetails( - 'high_importance_channel', 'High Importance Notifications', + 'high_importance_channel', // Use the same ID as before + 'High Importance Notifications', importance: Importance.high, priority: Priority.high, styleInformation: bigTextStyleInformation, @@ -94,17 +94,17 @@ class NotificationController extends GetxController { // Callback when the notification is tapped void onDidReceiveNotificationResponse(NotificationResponse response) { - _handleNotificationResponse(response); + handleNotificationResponse(response); } // Callback when the notification is tapped while the app is in the background void onDidReceiveBackgroundNotificationResponse( NotificationResponse response) { - _handleNotificationResponse(response); + handleNotificationResponse(response); } // Handle notification response for both foreground and background - void _handleNotificationResponse(NotificationResponse response) { + void handleNotificationResponse(NotificationResponse response) { print('Notification tapped!'); Log.print('response.payload: ${response.payload}'); if (response.payload != null) { diff --git a/lib/controller/home/captin/home_captain_controller.dart b/lib/controller/home/captin/home_captain_controller.dart index 1f30941..c52e9ef 100644 --- a/lib/controller/home/captin/home_captain_controller.dart +++ b/lib/controller/home/captin/home_captain_controller.dart @@ -24,6 +24,7 @@ class HomeCaptainController extends GetxController { Duration activeDuration = Duration.zero; Timer? activeTimer; Map data = {}; + BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker; bool isLoading = true; late double kazan = 0; double latePrice = 0; @@ -69,6 +70,19 @@ class HomeCaptainController extends GetxController { update(); } + void addCustomCarIcon() { + ImageConfiguration config = ImageConfiguration( + size: const Size(30, 35), devicePixelRatio: Get.pixelRatio); + BitmapDescriptor.asset( + config, + 'assets/images/car.png', + // mipmaps: false, + ).then((value) { + carIcon = value; + update(); + }); + } + String stringActiveDuration = ''; void onButtonSelected() { // totalPoints = Get.find().totalPoints; @@ -170,15 +184,23 @@ class HomeCaptainController extends GetxController { // CameraUpdate.newLatLng(Get.find().myLocation), // ); // } - GoogleMapController? mapHomeCaptainController; // Initialize to null + GoogleMapController? mapHomeCaptainController; // Nullable controller void onMapCreated(GoogleMapController controller) { mapHomeCaptainController = controller; - controller.getVisibleRegion(); - // Animate camera to user location (optional) - controller.animateCamera( - CameraUpdate.newLatLng(Get.find().myLocation), - ); + + // Optional: Check if the controller is still null (just for safety) + if (mapHomeCaptainController != null) { + // Get the visible region + controller.getVisibleRegion(); + + // Animate camera to user location (optional) + controller.animateCamera( + CameraUpdate.newLatLng(Get.find().myLocation), + ); + } else { + print("Controller is null, cannot proceed."); + } } void savePeriod(Duration period) { @@ -223,6 +245,7 @@ class HomeCaptainController extends GetxController { await getlocation(); onButtonSelected(); getDriverRate(); + addCustomCarIcon(); getKazanPercent(); getPaymentToday(); getCountRideToday(); diff --git a/lib/controller/home/captin/map_driver_controller.dart b/lib/controller/home/captin/map_driver_controller.dart index fbf0754..f177230 100644 --- a/lib/controller/home/captin/map_driver_controller.dart +++ b/lib/controller/home/captin/map_driver_controller.dart @@ -105,8 +105,8 @@ class MapDriverController extends GetxController { late LatLng latLngPassengerDestination = LatLng(0, 0); void onMapCreated(GoogleMapController controller) async { - myLocation = Get.find().location as LatLng; - myLocation = myLocation; + myLocation = Get.find().myLocation; + // myLocation = myLocation; mapController = controller; controller.getVisibleRegion(); controller.animateCamera( @@ -454,9 +454,10 @@ class MapDriverController extends GetxController { } addWaitingTimeCostFromPassengerToDriverWallet() async { - double distance2 = calculateDistanceBetweenDriverAndPassengerLocation(); + double distance2 = + await calculateDistanceBetweenDriverAndPassengerLocation(); - if (distance2 > 40) { + if (distance2 > 60) { Get.defaultDialog( title: 'Your are far from passenger location'.tr, middleText: @@ -893,12 +894,11 @@ class MapDriverController extends GetxController { void addCustomCarIcon() { ImageConfiguration config = ImageConfiguration( - size: const Size(30, 30), devicePixelRatio: Get.pixelRatio - // scale: 1.0, - ); + size: const Size(30, 35), devicePixelRatio: Get.pixelRatio); BitmapDescriptor.asset( config, 'assets/images/car.png', + // mipmaps: false, ).then((value) { carIcon = value; update(); @@ -999,11 +999,10 @@ class MapDriverController extends GetxController { LatLng(bounds['southwest']['lat'], bounds['southwest']['lng']); // Create the LatLngBounds object - LatLngBounds boundsData = - LatLngBounds(northeast: northeast, southwest: southwest); + boundsData = LatLngBounds(northeast: northeast, southwest: southwest); // Fit the camera to the bounds - var cameraUpdate = CameraUpdate.newLatLngBounds(boundsData, 140); + var cameraUpdate = CameraUpdate.newLatLngBounds(boundsData!, 140); mapController!.animateCamera(cameraUpdate); update(); } diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart index f3eeda5..adc012a 100644 --- a/lib/controller/local/translations.dart +++ b/lib/controller/local/translations.dart @@ -161,12 +161,25 @@ class MyTranslation extends Translations { "You dont have money in your Wallet": "ليس لديك أموال في محفظتك", "You dont have money in your Wallet or you should less transfer 5 LE to activate": "ليس لديك أموال في محفظتك أو يجب عليك تحويل 5 جنيهات على الأقل لتفعيل الحساب", + 'I Arrive': "لقد وصلت", + 'Rejected Orders Count': "عدد الطلبات المرفوضة", + 'This is the total number of rejected orders per day after accepting the orders': + 'هذا هو العدد الإجمالي للطلبات المرفوضة يوميًا بعد قبول الطلبات', + 'You are not near the passenger location': + "أنت لست بالقرب من موقع الراكب", + 'If you need assistance, contact us': + "إذا كنت بحاجة إلى المساعدة، تواصل معنا", + 'You Can Cancel the Trip and get Cost From ': + "يمكنك إلغاء الرحلة والحصول على التكلفة من", + 'Please go to the pickup location exactly': + "يرجى الذهاب إلى موقع الالتقاط بالضبط", "Approaching your area. Should be there in 3 minutes.": "اقترب من منطقتك. يجب أن أكون هناك خلال 3 دقائق.", "There's heavy traffic here. Can you suggest an alternate pickup point?": "هناك حركة مرور كثيفة هنا. هل يمكنك اقتراح نقطة استلام بديلة؟", "This ride is already taken by another driver.": "تم حجز هذه الرحلة من قبل سائق آخر.", + 'Type Any thing': "اكتب أي شيء", 'Price: ': 'السعر ', 'Add Question': "أضف سؤالاً", "Please enter a valid card 16-digit number.": diff --git a/lib/main.dart b/lib/main.dart index 2028b8d..37f3565 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'package:SEFER/views/home/Captin/orderCaptin/order_request_page.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_overlay_window/flutter_overlay_window.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_stripe/flutter_stripe.dart'; @@ -59,7 +60,7 @@ Future backgroundMessageHandler(RemoteMessage message) async { } await Future.delayed(const Duration(seconds: 1)); - NotificationController1().showNotification( + NotificationController().showNotification( message.notification!.title.toString(), message.notification!.body.toString(), 'order', @@ -70,11 +71,11 @@ Future backgroundMessageHandler(RemoteMessage message) async { if (isOverlayActive) { await FlutterOverlayWindow.closeOverlay(); } - + await FlutterOverlayWindow.shareData(myList); await FlutterOverlayWindow.showOverlay( enableDrag: true, flag: OverlayFlag.focusPointer, - visibility: NotificationVisibility.visibilityPublic, + // visibility: NotificationVisibility.visibilityPublic, positionGravity: PositionGravity.auto, height: 700, width: WindowSize.matchParent, @@ -89,6 +90,14 @@ Future backgroundMessageHandler(RemoteMessage message) async { } } +@pragma('vm:entry-point') +void notificationTapBackground(NotificationResponse notificationResponse) { + // handle background notification taps here + print('Notification tapped in background!'); + NotificationController().handleNotificationResponse(notificationResponse); + // You can add your logic here to handle the notification tap +} + @pragma('vm:entry-point') void overlayMain() async { WidgetsFlutterBinding.ensureInitialized(); @@ -99,8 +108,12 @@ void overlayMain() async { )); } -void closeOverLay() { - FlutterOverlayWindow.closeOverlay(); +Future closeOverLay() async { + // FlutterOverlayWindow.closeOverlay(); + bool isOverlayActive = await FlutterOverlayWindow.isActive(); + if (isOverlayActive) { + await FlutterOverlayWindow.closeOverlay(); + } } void main() async { @@ -122,8 +135,11 @@ void main() async { await FirebaseMessagesController().requestFirebaseMessagingPermission(); FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); - NotificationController1().initNotifications(); + // NotificationController1().initNotifications(); // NotificationController().initNotifications(); + if (Platform.isAndroid) { + await Get.put(NotificationController()).initNotifications(); + } await Future.wait([ FirebaseMessagesController().getNotificationSettings(), diff --git a/lib/views/auth/captin/login_captin.dart b/lib/views/auth/captin/login_captin.dart index 10e25e7..f0be904 100644 --- a/lib/views/auth/captin/login_captin.dart +++ b/lib/views/auth/captin/login_captin.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:SEFER/controller/auth/facebook_login.dart'; +import 'package:SEFER/views/auth/captin/contact_us_page.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -258,10 +259,14 @@ class LoginCaptin extends StatelessWidget { ), ))), - // Text( - // 'if you don\'t have account'.tr, - // style: AppStyle.subtitle, - // ), + GestureDetector( + onTap: () => Get.to(() => ContactUsPage()), + child: Text( + 'If you need assistance, contact us' + .tr, // Improved wording + style: AppStyle.subtitle, + ), + ), // AnimatedTextKit( // onTap: () => Get.to(() => const RegisterCaptin()), // animatedTexts: [ diff --git a/lib/views/home/Captin/driver_map_page.dart b/lib/views/home/Captin/driver_map_page.dart index 9c0fd55..949fb3b 100644 --- a/lib/views/home/Captin/driver_map_page.dart +++ b/lib/views/home/Captin/driver_map_page.dart @@ -33,9 +33,11 @@ class PassengerLocationMapPage extends StatelessWidget { .startTimerToShowPassengerInfoWindowFromDriver(); } - return MyScafolld( - title: 'Map Passenger'.tr, - body: [ + return Scaffold( + // title: 'Map Passenger'.tr, + body: SafeArea( + child: Stack( + children: [ GoogleDriverMap(locationController: locationController), const PassengerInfoWindow(), CancelWidget(mapDriverController: mapDriverController), @@ -45,7 +47,8 @@ class PassengerLocationMapPage extends StatelessWidget { const GoogleMapApp(), const PricesWindow(), ], - isleading: false); + ), + )); } } @@ -81,7 +84,8 @@ class CancelWidget extends StatelessWidget { ], ), confirm: MyElevatedButton( - title: 'OK'.tr, + title: 'Ok'.tr, + kolor: AppColor.redColor, onPressed: () async { // todo add cancel and inform passenger to get new driver await mapDriverController @@ -89,8 +93,8 @@ class CancelWidget extends StatelessWidget { Get.back(); }), cancel: MyElevatedButton( - title: 'NO'.tr, - kolor: AppColor.redColor, + title: 'No'.tr, + // kolor: AppColor.redColor, onPressed: () { Get.back(); })); diff --git a/lib/views/home/Captin/home_captain/home_captin.dart b/lib/views/home/Captin/home_captain/home_captin.dart index fb92fc8..c989c1d 100644 --- a/lib/views/home/Captin/home_captain/home_captin.dart +++ b/lib/views/home/Captin/home_captain/home_captin.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:SEFER/constant/box_name.dart'; import 'package:SEFER/controller/home/captin/map_driver_controller.dart'; import 'package:SEFER/views/notification/available_rides_page.dart'; +import 'package:SEFER/views/widgets/mydialoug.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; @@ -52,11 +53,12 @@ class HomeCaptain extends StatelessWidget { title: Text('Home'.tr), actions: [ GetBuilder( - builder: (orderRequestController) => MyCircleContainer( - child: Text( - orderRequestController.countRefuse.toString(), - style: AppStyle.title, - ))), + builder: (orderRequestController) => MyCircleContainer( + child: Text( + orderRequestController.countRefuse.toString(), + style: AppStyle.title, + )), + ), // IconButton( // // onPressed: () => Get.find().getSQL(), // onPressed: () => sql.deleteAllData(TableName.driverOrdersRefuse), @@ -84,9 +86,17 @@ class HomeCaptain extends StatelessWidget { target: locationController.myLocation, zoom: 15, ), - - mapType: - controller.mapType ? MapType.satellite : MapType.normal, + markers: { + Marker( + markerId: MarkerId('MyLocation'.tr), + position: locationController.myLocation, + draggable: false, + icon: controller.carIcon, + rotation: locationController.heading) + }, + mapType: controller.mapType + ? MapType.satellite + : MapType.terrain, myLocationButtonEnabled: true, // liteModeEnabled: true, tiltGesturesEnabled: false, @@ -95,7 +105,7 @@ class HomeCaptain extends StatelessWidget { buildingsEnabled: true, mapToolbarEnabled: true, - myLocationEnabled: true, + myLocationEnabled: false, // liteModeEnabled: true, ), ), diff --git a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart index f346ca5..7659adf 100644 --- a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart +++ b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:SEFER/constant/box_name.dart'; import 'package:SEFER/controller/firebase/local_notification.dart'; import 'package:SEFER/main.dart'; @@ -8,6 +10,7 @@ import 'package:SEFER/views/home/Captin/driver_map_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:bubble_head/bubble.dart'; +import 'package:flutter_overlay_window/flutter_overlay_window.dart'; import 'package:get/get.dart'; import 'package:SEFER/controller/home/captin/home_captain_controller.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; @@ -24,286 +27,272 @@ import '../../../../../controller/functions/location_controller.dart'; GetBuilder leftMainMenuCaptainIcons() { return GetBuilder( builder: (controller) => Positioned( - bottom: Get.height * .2, - left: 6, - child: Column( - children: [ - // AnimatedContainer( - // duration: const Duration(microseconds: 200), - // width: controller.widthMapTypeAndTraffic, - // decoration: BoxDecoration( - // border: Border.all(color: AppColor.blueColor), - // color: AppColor.secondaryColor, - // borderRadius: BorderRadius.circular(15)), - // child: IconButton( - // onPressed: () { - // // key.forEach((key, apiKey) { - // // Get.to(() => SmsSignupEgypt()); - // // keys.forEach((key, apiKey) { - // String apikey = AK.secretKeyStripe; - // Log.print('apikey: ${apikey}'); + bottom: Get.height * .2, + left: 6, + child: Column( + children: [ + // AnimatedContainer( + // duration: const Duration(microseconds: 200), + // width: controller.widthMapTypeAndTraffic, + // decoration: BoxDecoration( + // border: Border.all(color: AppColor.blueColor), + // color: AppColor.secondaryColor, + // borderRadius: BorderRadius.circular(15)), + // child: IconButton( + // onPressed: () { + // // key.forEach((key, apiKey) { + // // Get.to(() => SmsSignupEgypt()); + // // keys.forEach((key, apiKey) { + // String apikey = AK.secretKeyStripe; + // Log.print('apikey: ${apikey}'); - // String encryptedApiKey = X.c(X.c(X.c(apikey, cs), cC), cn); - // Log.print('encryptedApiKey: ${encryptedApiKey}'); + // String encryptedApiKey = X.c(X.c(X.c(apikey, cs), cC), cn); + // Log.print('encryptedApiKey: ${encryptedApiKey}'); - // String decryptedApiKey = - // X.r(X.r(X.r(encryptedApiKey, cn), cC), cs); - // Log.print('decryptedApiKey: ${decryptedApiKey}'); + // String decryptedApiKey = + // X.r(X.r(X.r(encryptedApiKey, cn), cC), cs); + // Log.print('decryptedApiKey: ${decryptedApiKey}'); - // // if (decryptedApiKey == retrievedStringS) { - // // } else { - // // } - // // } - // // ); - // }, - // icon: const Icon( - // FontAwesome.map_signs, - // size: 24, - // color: Colors.black, - // )), - // ), + // // if (decryptedApiKey == retrievedStringS) { + // // } else { + // // } + // // } + // // ); + // }, + // icon: const Icon( + // FontAwesome.map_signs, + // size: 24, + // color: Colors.black, + // )), + // ), - // const SizedBox( - // height: 5, - // ), - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTraffic, - decoration: BoxDecoration( - border: Border.all(color: AppColor.blueColor), - color: AppColor.secondaryColor, - borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - controller.changeMapType(); - // Toast.show(context, 'This is a toast message!'); + // const SizedBox( + // height: 5, + // ), + AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTraffic, + decoration: BoxDecoration( + border: Border.all(color: AppColor.blueColor), + color: AppColor.secondaryColor, + borderRadius: BorderRadius.circular(15)), + child: IconButton( + onPressed: () { + controller.changeMapType(); + // Toast.show(context, 'This is a toast message!'); + }, + icon: const Icon( + Icons.satellite_alt, + size: 29, + color: AppColor.blueColor, + ), + ), + ), + const SizedBox( + height: 5, + ), + AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTraffic, + decoration: BoxDecoration( + color: AppColor.secondaryColor, + border: Border.all(color: AppColor.blueColor), + borderRadius: BorderRadius.circular(15)), + child: IconButton( + onPressed: () { + controller.changeMapTraffic(); + // Toast.show(context, 'This is a toast message!'); + }, + icon: const Icon( + Icons.streetview_sharp, + size: 29, + color: AppColor.blueColor, + ), + ), + ), + const SizedBox( + height: 5, + ), + AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTraffic, + decoration: BoxDecoration( + color: AppColor.secondaryColor, + border: Border.all(color: AppColor.blueColor), + borderRadius: BorderRadius.circular(15)), + child: IconButton( + onPressed: () { + controller.mapHomeCaptainController! + .animateCamera(CameraUpdate.newLatLng(LatLng( + Get.find().myLocation.latitude, + Get.find().myLocation.longitude, + ))); + }, + icon: const Icon( + Icons.location_on, + size: 29, + color: AppColor.blueColor, + ), + ), + ), + const SizedBox( + height: 5, + ), + AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTraffic, + decoration: BoxDecoration( + color: AppColor.secondaryColor, + border: Border.all(color: AppColor.blueColor), + borderRadius: BorderRadius.circular(15)), + child: IconButton( + onPressed: () { + NotificationController1() + .showNotification('Sefer Driver'.tr, ''.tr, '', ''); + final now = DateTime.now(); + DateTime? lastRequestTime = + box.read(BoxName.lastTimeStaticThrottle); + + if (lastRequestTime == null || + now.difference(lastRequestTime).inMinutes >= 2) { + // Update the last request time to now + lastRequestTime = now; + box.write(BoxName.lastTimeStaticThrottle, lastRequestTime); + // Navigate to the RideCalculateDriver page + Get.to(() => RideCalculateDriver()); + } else { + // Optionally show a message or handle the throttling case + final minutesLeft = + 2 - now.difference(lastRequestTime).inMinutes; + // Get.snackbar( + // '${'Please wait'.tr} $minutesLeft ${"minutes before trying again.".tr}', + // ''); + NotificationController1().showNotification( + 'Sefer Driver'.tr, + '${'Please wait'.tr} $minutesLeft ${"minutes before trying again.".tr}', + 'ding', + ''); + } + }, + icon: const Icon( + FontAwesome5.chart_bar, + size: 29, + color: AppColor.blueColor, + ), + ), + ), + + const SizedBox( + height: 5, + ), + Platform.isAndroid + ? AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTraffic, + decoration: BoxDecoration( + color: AppColor.secondaryColor, + border: Border.all(color: AppColor.blueColor), + borderRadius: BorderRadius.circular(15)), + child: Builder(builder: (context) { + return IconButton( + onPressed: () async { + bool isOverlayActive = + await FlutterOverlayWindow.isActive(); + if (isOverlayActive) { + await FlutterOverlayWindow.closeOverlay(); + } + // print(box.read(BoxName.tokenDriver)); + }, + icon: const Icon( + FontAwesome5.window_close, + size: 29, + color: AppColor.blueColor, + ), + ); + }), + ) + : const SizedBox(), + AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTraffic, + decoration: BoxDecoration( + color: AppColor.secondaryColor, + border: Border.all(color: AppColor.blueColor), + borderRadius: BorderRadius.circular(15)), + child: Builder(builder: (context) { + return IconButton( + onPressed: () async { + Get.to(() => LoginCaptin()); + // print(box.read(BoxName.myList)); + + // List d = [ + // "30.003028,31.2419628", + // "30.0955661,31.2665336", + // "160.00", + // "25.92", + // "1488", + // "16.93", + // "114243034311436865474", + // "113172279072358305645", + // "hamza ayed", + // "rlMbi4Hc8L1STMPE99iPKqK4Gddwv8r9qZOCadsz9qTEJZ6KLEE9ruTJI6N8dKfK4CXez5pme5WIs14-1QGo29s07fQOniZgIlJV5XFL3yqzPRSUmn3", + // "+201023248456", + // "1 min", + // "1 m", + // "false", + // "QwUMoyUtZ0J3oR6yXKUavrB_gBl9npUZe-qZtax-Raq4QBbdKv0AmtLKm0BfBd6N_592HBv4CVa41ii4122W3hr-BCUKKzJhzZcK8m0YjbWbtpvgJRD8uD_nuMk9", + // "0", + // "238", + // "false", + // "114243034311436865474", + // "1488", + // "startEnd", + // "30.049307749732176,31.274291574954987", + // "", + // "", + // "", + // "", + // "17.73", + // "0", + // "hamzaayedflutter@gmail.com", + // "الفسطاط، حي مصر القديمة، مصر", + // " الزاوية الحمراء، محافظة القاهرة، مصر", + // "Speed", + // "8", + // "5.00" + // ]; + // FirebaseMessagesController().sendNotificationToDriverMAP( + // 'Order'.tr, + // 'from: ', + // // jsonDecode(value)['message'].toString(), + // 'fKBBB4_1R0q18-byySHUeG:APA91bHk2RmjjMt6eKr7KQnqh4CK02yW3H5E8g_beVcQFgiCG50j9KCtSU1O8PtvS_gA5xuJLhaorDV9AeslcyLFJFf302tICKMiKgsDP5pWkF5WXNw0-4NsoD-BnJxf0-Do9Vs1Zbpq', + // d, + // 'order.wav'); + // NotificationController() + // .showNotification('VIP Order'.tr, '', 'order', ''); + // try {} catch (e) { + // print('Error showing overlay: $e'); + // } + // final Bubble _bubble = Bubble(showCloseButton: true); + // try { + // await _bubble.startBubbleHead(sendAppToBackground: false); + // } on PlatformException { + // print('Failed to call startBubbleHead'); + // } }, icon: const Icon( - Icons.satellite_alt, + FontAwesome5.grin_tears, size: 29, color: AppColor.blueColor, ), - ), - ), - const SizedBox( - height: 5, - ), - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTraffic, - decoration: BoxDecoration( - color: AppColor.secondaryColor, - border: Border.all(color: AppColor.blueColor), - borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - controller.changeMapTraffic(); - // Toast.show(context, 'This is a toast message!'); - }, - icon: const Icon( - Icons.streetview_sharp, - size: 29, - color: AppColor.blueColor, - ), - ), - ), - const SizedBox( - height: 5, - ), - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTraffic, - decoration: BoxDecoration( - color: AppColor.secondaryColor, - border: Border.all(color: AppColor.blueColor), - borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - controller.mapHomeCaptainController! - .animateCamera(CameraUpdate.newLatLng(LatLng( - Get.find().myLocation.latitude, - Get.find().myLocation.longitude, - ))); - }, - icon: const Icon( - Icons.location_on, - size: 29, - color: AppColor.blueColor, - ), - ), - ), - const SizedBox( - height: 5, - ), - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTraffic, - decoration: BoxDecoration( - color: AppColor.secondaryColor, - border: Border.all(color: AppColor.blueColor), - borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - NotificationController1() - .showNotification('Sefer Driver'.tr, ''.tr, '', ''); - final now = DateTime.now(); - DateTime? lastRequestTime = - box.read(BoxName.lastTimeStaticThrottle); - - if (lastRequestTime == null || - now.difference(lastRequestTime).inMinutes >= 2) { - // Update the last request time to now - lastRequestTime = now; - box.write(BoxName.lastTimeStaticThrottle, lastRequestTime); - // Navigate to the RideCalculateDriver page - Get.to(() => RideCalculateDriver()); - } else { - // Optionally show a message or handle the throttling case - final minutesLeft = - 2 - now.difference(lastRequestTime).inMinutes; - // Get.snackbar( - // '${'Please wait'.tr} $minutesLeft ${"minutes before trying again.".tr}', - // ''); - NotificationController1().showNotification( - 'Sefer Driver'.tr, - '${'Please wait'.tr} $minutesLeft ${"minutes before trying again.".tr}', - 'ding', - ''); - } - }, - icon: const Icon( - FontAwesome5.chart_bar, - size: 29, - color: AppColor.blueColor, - ), - ), - ), - // AnimatedContainer( - // duration: const Duration(microseconds: 200), - // width: controller.widthMapTypeAndTraffic, - // decoration: BoxDecoration( - // color: AppColor.secondaryColor, - // border: Border.all(color: AppColor.blueColor), - // borderRadius: BorderRadius.circular(15)), - // child: Builder(builder: (context) { - // return IconButton( - // onPressed: () async { - // // Get.to(() => EgyptCardAI()); - // // print(box.read(BoxName.myList)); - - // List d = [ - // "30.003028,31.2419628", - // "30.0955661,31.2665336", - // "160.00", - // "25.92", - // "1488", - // "16.93", - // "114243034311436865474", - // "113172279072358305645", - // "hamza ayed", - // "rlMbi4Hc8L1STMPE99iPKqK4Gddwv8r9qZOCadsz9qTEJZ6KLEE9ruTJI6N8dKfK4CXez5pme5WIs14-1QGo29s07fQOniZgIlJV5XFL3yqzPRSUmn3", - // "+201023248456", - // "1 min", - // "1 m", - // "false", - // "QwUMoyUtZ0J3oR6yXKUavrB_gBl9npUZe-qZtax-Raq4QBbdKv0AmtLKm0BfBd6N_592HBv4CVa41ii4122W3hr-BCUKKzJhzZcK8m0YjbWbtpvgJRD8uD_nuMk9", - // "0", - // "238", - // "false", - // "114243034311436865474", - // "1488", - // "startEnd", - // "30.049307749732176,31.274291574954987", - // "", - // "", - // "", - // "", - // "17.73", - // "0", - // "hamzaayedflutter@gmail.com", - // "الفسطاط، حي مصر القديمة، مصر", - // " الزاوية الحمراء، محافظة القاهرة، مصر", - // "Speed", - // "8", - // "5.00" - // ]; - // FirebaseMessagesController().sendNotificationToDriverMAP( - // 'Order'.tr, - // 'from: ', - // // jsonDecode(value)['message'].toString(), - // 'fKBBB4_1R0q18-byySHUeG:APA91bHk2RmjjMt6eKr7KQnqh4CK02yW3H5E8g_beVcQFgiCG50j9KCtSU1O8PtvS_gA5xuJLhaorDV9AeslcyLFJFf302tICKMiKgsDP5pWkF5WXNw0-4NsoD-BnJxf0-Do9Vs1Zbpq', - // d, - // 'order.wav'); - // // NotificationController() - // // .showNotification('VIP Order'.tr, '', 'order', ''); - // // try {} catch (e) { - // // print('Error showing overlay: $e'); - // // } - // // final Bubble _bubble = Bubble(showCloseButton: true); - // // try { - // // await _bubble.startBubbleHead(sendAppToBackground: false); - // // } on PlatformException { - // // print('Failed to call startBubbleHead'); - // // } - - // // Bubble().startBubbleHead(sendAppToBackground: true); - // // } - - // // Future stopBubbleHead() async { - // // try { - // // await _bubble.stopBubbleHead(); - // // } on PlatformException { - // // print('Failed to call stopBubbleHead'); - // // } - // // } - // // - // // // // send data to ovelay - // }, - // icon: const Icon( - // FontAwesome5.grin_tears, - // size: 29, - // color: AppColor.blueColor, - // ), - // ); - // }), - // ), - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTraffic, - decoration: BoxDecoration( - color: AppColor.secondaryColor, - border: Border.all(color: AppColor.blueColor), - borderRadius: BorderRadius.circular(15)), - child: Builder(builder: (context) { - return IconButton( - onPressed: () async { - // FirebaseMessagesController().sendNotificationToAnyWithoutData( - // 'Order'.tr, - // 'from: ', - // // jsonDecode(value)['message'].toString(), - // 'fKBBB4_1R0q18-byySHUeG:APA91bHk2RmjjMt6eKr7KQnqh4CK02yW3H5E8g_beVcQFgiCG50j9KCtSU1O8PtvS_gA5xuJLhaorDV9AeslcyLFJFf302tICKMiKgsDP5pWkF5WXNw0-4NsoD-BnJxf0-Do9Vs1Zbpq', - // 'order.wav'); - - NotificationController1().showNotification( - 'sdf'.tr, - 'We regret to inform you that another driver has accepted this order.' - .tr, - '', - ''); - // requestLocationPermission(); - // Get.to(() => PassengerLocationMapPage(), - // arguments: box.read(BoxName.rideArguments)); - print(box.read(BoxName.tokenDriver)); - }, - icon: const Icon( - FontAwesome5.closed_captioning, - size: 29, - color: AppColor.blueColor, - ), - ); - }), - ), - ], - )), + ); + }), + ), + const SizedBox( + height: 5, + ), + ], + ), + ), ); } diff --git a/lib/views/home/Captin/mapDriverWidgets/driver_end_ride_bar.dart b/lib/views/home/Captin/mapDriverWidgets/driver_end_ride_bar.dart index ab2b28b..f54ab49 100644 --- a/lib/views/home/Captin/mapDriverWidgets/driver_end_ride_bar.dart +++ b/lib/views/home/Captin/mapDriverWidgets/driver_end_ride_bar.dart @@ -21,14 +21,14 @@ GetBuilder driverEndRideBar() { decoration: AppStyle.boxDecoration1, height: mapDriverController.remainingTimeTimerRideBegin < 60 ? mapDriverController.driverEndPage = 190 - : mapDriverController.carType == 'Mashwari' + : mapDriverController.carType == 'Mishwar Vip' ? 120 : 170, // width: 240, child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - mapDriverController.carType != 'Mashwari' + mapDriverController.carType != 'Mishwar Vip' ? Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -63,8 +63,8 @@ GetBuilder driverEndRideBar() { ) : const SizedBox(), mapDriverController.carType != 'Speed' && - mapDriverController.carType != 'Delivery' && - mapDriverController.carType != 'Balash' + mapDriverController.carType != 'Awfar Car' && + mapDriverController.carType != 'Scooter' ? Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -168,7 +168,7 @@ GetBuilder driverEndRideBar() { ], ), mapDriverController.carType != 'Comfort' && - mapDriverController.carType != 'Mashwari' && + mapDriverController.carType != 'Mishwar Vip' && mapDriverController.carType != 'Lady' ? Stack( children: [ diff --git a/lib/views/home/Captin/mapDriverWidgets/google_driver_map_page.dart b/lib/views/home/Captin/mapDriverWidgets/google_driver_map_page.dart index 7d7f5e3..56d27eb 100644 --- a/lib/views/home/Captin/mapDriverWidgets/google_driver_map_page.dart +++ b/lib/views/home/Captin/mapDriverWidgets/google_driver_map_page.dart @@ -20,76 +20,88 @@ class GoogleDriverMap extends StatelessWidget { return Padding( padding: const EdgeInsets.all(8.0), child: GetBuilder( - builder: (controller) => GoogleMap( - onMapCreated: controller.onMapCreated, - initialCameraPosition: CameraPosition( - // bearing: 45, - target: locationController.myLocation, - zoom: 16, - tilt: 40, - ), - onCameraMoveStarted: () {}, - onCameraMove: (position) { - locationController.myLocation = position.target; - controller.mapController! - .animateCamera(CameraUpdate.newCameraPosition(position)); - }, - minMaxZoomPreference: const MinMaxZoomPreference(6, 18), - myLocationEnabled: true, - compassEnabled: true, - mapType: MapType.normal, - trafficEnabled: true, - buildingsEnabled: true, - mapToolbarEnabled: true, - zoomControlsEnabled: true, - fortyFiveDegreeImageryEnabled: true, - zoomGesturesEnabled: true, - polylines: { - Polyline( - zIndex: 2, - consumeTapEvents: true, - geodesic: true, - endCap: Cap.buttCap, - startCap: Cap.buttCap, - visible: true, - polylineId: const PolylineId('route1'), - points: controller.polylineCoordinates, - color: AppColor.yellowColor, - width: 4, + builder: (controller) => Column( + children: [ + SizedBox( + height: Get.height * .6, + child: GoogleMap( + onMapCreated: controller.onMapCreated, + zoomControlsEnabled: true, + initialCameraPosition: CameraPosition( + // bearing: 45, + target: locationController.myLocation, + zoom: 13, + tilt: 40, + ), + // onCameraMoveStarted: () {}, + cameraTargetBounds: CameraTargetBounds(controller.boundsData), + onCameraMove: (position) { + locationController.myLocation = position.target; + controller.mapController! + .animateCamera(CameraUpdate.newCameraPosition(position)); + }, + minMaxZoomPreference: const MinMaxZoomPreference(8, 15), + myLocationEnabled: true, myLocationButtonEnabled: true, + compassEnabled: true, + mapType: MapType.terrain, + rotateGesturesEnabled: true, + scrollGesturesEnabled: true, + trafficEnabled: false, + // liteModeEnabled: true, + buildingsEnabled: true, + mapToolbarEnabled: true, + // zoomControlsEnabled: true, + fortyFiveDegreeImageryEnabled: true, + zoomGesturesEnabled: true, + polylines: { + Polyline( + zIndex: 2, + consumeTapEvents: true, + geodesic: true, + endCap: Cap.buttCap, + startCap: Cap.buttCap, + visible: true, + polylineId: const PolylineId('route1'), + points: controller.polylineCoordinates, + color: const Color.fromARGB(255, 163, 81, 246), + width: 5, + ), + Polyline( + zIndex: 2, + consumeTapEvents: true, + geodesic: true, + endCap: Cap.buttCap, + startCap: Cap.buttCap, + visible: true, + polylineId: const PolylineId('route'), + points: controller.polylineCoordinatesDestination, + color: const Color.fromARGB(255, 10, 29, 126), + width: 5, + ), + }, + markers: { + Marker( + markerId: MarkerId('MyLocation'.tr), + position: locationController.myLocation, + draggable: true, + icon: controller.carIcon, + rotation: locationController.heading), + Marker( + markerId: MarkerId('start'.tr), + position: controller.latLngPassengerLocation, + draggable: true, + icon: controller.startIcon, + ), + Marker( + markerId: MarkerId('end'.tr), + position: controller.latLngPassengerDestination, + draggable: true, + icon: controller.endIcon, + ), + }, + ), ), - Polyline( - zIndex: 2, - consumeTapEvents: true, - geodesic: true, - endCap: Cap.buttCap, - startCap: Cap.buttCap, - visible: true, - polylineId: const PolylineId('route'), - points: controller.polylineCoordinatesDestination, - color: AppColor.primaryColor, - width: 4, - ), - }, - markers: { - Marker( - markerId: MarkerId('MyLocation'.tr), - position: locationController.myLocation, - draggable: true, - icon: controller.carIcon, - rotation: locationController.heading), - Marker( - markerId: MarkerId('start'.tr), - position: controller.latLngPassengerLocation, - draggable: true, - icon: controller.startIcon, - ), - Marker( - markerId: MarkerId('end'.tr), - position: controller.latLngPassengerDestination, - draggable: true, - icon: controller.endIcon, - ), - }, + ], ), ), ); diff --git a/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart b/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart index e1755c1..54c6008 100644 --- a/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart +++ b/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart @@ -29,7 +29,7 @@ class PassengerInfoWindow extends StatelessWidget { // left: 8, child: AnimatedContainer( duration: const Duration(milliseconds: 300), - height: Get.height * .35, + height: Get.height * .4, width: Get.width, decoration: AppStyle.boxDecoration1, child: Padding( @@ -289,80 +289,137 @@ class PassengerInfoWindow extends StatelessWidget { ), ], )), - Row( - mainAxisAlignment: MainAxisAlignment.center, + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - decoration: AppStyle.boxDecoration1, - width: Get.width * .22, - child: Padding( - padding: const EdgeInsets.all(4.0), - child: Text( - controller.hours > 1 - ? '⌚️ ${controller.hours}h ${controller.minutes}m' // Ride Duration with emoji - : '⌚️ ${controller.minutes}m', // Short ride duration - style: AppStyle.number, - ), - ), - ), - const SizedBox( - width: 10.0), // Add spacing between sections - Container( - decoration: AppStyle.boxDecoration1, - width: Get.width * .22, - child: Padding( - padding: const EdgeInsets.all(4), - child: Text( - ' ${controller.distance} km', // Distance with emoji - style: AppStyle.number, - ), - ), - ), - const SizedBox( - width: 16.0), // Add spacing between sections - Container( - decoration: AppStyle.boxDecoration1, - width: Get.width * .35, - child: Padding( - padding: const EdgeInsets.all(4.0), - child: Text( - controller - .passengerName, // Passenger name with emoji - style: AppStyle.title, - ), - ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Container( - decoration: AppStyle.boxDecoration1, - width: Get.width * .4, - child: Padding( - padding: const EdgeInsets.all(4), - child: Row( - children: [ - Text("cost is ".tr, - style: AppStyle.title), - Text( - controller.totalPricePassenger - .toString(), - style: AppStyle.number, + // First Row: Trip Info (Duration, Distance, Passenger Name) + Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + // Ride Duration + Container( + decoration: AppStyle.boxDecoration1, + width: Get.width * .28, + child: Padding( + padding: const EdgeInsets.all(6.0), + child: Row( + children: [ + Icon(Icons.timer, + color: Colors + .grey[700]), // Duration Icon + const SizedBox(width: 6), + Text( + controller.hours > 1 + ? '${controller.hours}h ${controller.minutes}${'m'.tr}' + : '${controller.minutes}${'m'.tr}', + style: AppStyle.number, + ), + ], ), - ], + ), ), - ), + + // Ride Distance + Container( + decoration: AppStyle.boxDecoration1, + width: Get.width * .28, + child: Padding( + padding: const EdgeInsets.all(6.0), + child: Row( + children: [ + Icon(Icons.map, + color: Colors + .grey[700]), // Distance Icon + const SizedBox(width: 6), + Text( + '${controller.distance} km', + style: AppStyle.number, + ), + ], + ), + ), + ), + + // Passenger Name + Container( + decoration: AppStyle.boxDecoration1, + width: Get.width * .38, + child: Padding( + padding: const EdgeInsets.all(6.0), + child: Row( + children: [ + Icon(Icons.person, + color: Colors + .grey[700]), // Passenger Icon + const SizedBox(width: 6), + Text( + controller.passengerName, + style: AppStyle.title, + ), + ], + ), + ), + ), + ], ), - Container( - decoration: AppStyle.boxDecoration1, - width: Get.width * .4, - child: Padding( - padding: const EdgeInsets.all(4), - child: Text(controller.carType.tr, - style: AppStyle.title), - ), + + const SizedBox( + height: 16), // Spacing between rows + + // Second Row: Cost & Car Type + Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + // Ride Cost + Container( + decoration: AppStyle.boxDecoration1, + width: Get.width * .45, + child: Padding( + padding: const EdgeInsets.all(6.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Icon(Icons.attach_money, + color: Colors + .grey[700]), // Cost Icon + const SizedBox(width: 6), + Text("cost is ".tr, + style: AppStyle.title), + ], + ), + Text( + controller.totalPricePassenger, + style: AppStyle.number, + ), + ], + ), + ), + ), + + // Car Type + Container( + decoration: AppStyle.boxDecoration1, + width: Get.width * .45, + child: Padding( + padding: const EdgeInsets.all(6.0), + child: Row( + children: [ + Icon(Icons.directions_car, + color: + Colors.grey[700]), // Car Icon + const SizedBox(width: 6), + Text(controller.carType.tr, + style: AppStyle.title), + ], + ), + ), + ), + ], ), ], ), @@ -370,82 +427,94 @@ class PassengerInfoWindow extends StatelessWidget { ? const SizedBox() : Column( children: [ + // First Row: Start Ride or Arrive at Location Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ + // Start Ride Button MyElevatedButton( - title: 'Start the Ride'.tr, - kolor: AppColor.greenColor, - onPressed: () { - Get.defaultDialog( - title: - 'Is the Passenger in your Car ?' - .tr, - titleStyle: AppStyle.title, - middleText: - "don't start trip if not" - .tr, - middleTextStyle: - AppStyle.title, - confirm: MyElevatedButton( - title: 'OK'.tr, - kolor: - AppColor.greenColor, - onPressed: () async { - await controller - .startRideFromDriver(); - Get.back(); - }), - cancel: MyElevatedButton( - title: - 'No ,still Waiting.' - .tr, - kolor: AppColor.redColor, - onPressed: () { - Get.back(); - })); - }), + title: 'Start the Ride'.tr, + kolor: AppColor.greenColor, + onPressed: () { + Get.defaultDialog( + title: + 'Is the Passenger in your Car?' + .tr, + titleStyle: AppStyle.title, + middleText: + "Don't start trip if not".tr, + middleTextStyle: AppStyle.title, + confirm: MyElevatedButton( + title: 'OK'.tr, + kolor: AppColor.greenColor, + onPressed: () async { + await controller + .startRideFromDriver(); + Get.back(); // Close dialog after confirmation + }, + ), + cancel: MyElevatedButton( + title: 'No, still Waiting.'.tr, + kolor: AppColor.redColor, + onPressed: () { + Get.back(); // Close dialog without action + }, + ), + ); + }, + ), + + // Arrive Notification Button controller.isArrivedSend ? MyElevatedButton( - title: 'I arrive you'.tr, + title: 'I Arrive'.tr, kolor: AppColor.yellowColor, onPressed: () async { - if (controller + if (await controller .calculateDistanceBetweenDriverAndPassengerLocation() < 40) { + // Notify Passenger FirebaseMessagesController() .sendNotificationToPassengerToken( - 'Hi ,I Arrive your site', - 'I Arrive your site' - .tr, - controller - .tokenPassenger, - [], - 'start.wav'); + 'Hi, I Arrive at your site', + 'I Arrive at your site' + .tr, + controller.tokenPassenger, + [], + 'start.wav', + ); controller .startTimerToShowDriverWaitPassengerDuration(); controller.isArrivedSend = false; } else { + // Show error dialog if the driver is far from passenger Get.defaultDialog( - title: - 'You are not in near to passenger location' - .tr, - middleText: - 'please go to picker location exactly' - .tr, - confirm: - MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.back(); - })); + title: + 'You are not near the passenger location' + .tr, + middleText: + 'Please go to the pickup location exactly' + .tr, + confirm: MyElevatedButton( + title: 'Ok'.tr, + onPressed: () { + Get.back(); + }, + ), + ); } - }) - : const SizedBox() + }, + ) + : const SizedBox(), // Hide if already sent ], ), + + // const SizedBox( + // height: 16), // Space between rows + + // Progress Bar for Waiting Time controller.remainingTimeInPassengerLocatioWait < 300 && controller @@ -474,45 +543,58 @@ class PassengerInfoWindow extends StatelessWidget { .stringRemainingTimeWaitingPassenger, style: AppStyle.title, ), - ) + ), ], ) - : controller.isdriverWaitTimeEnd - ? MyElevatedButton( - title: 'You Can Cancel Trip And get Cost of Trip From' + : const SizedBox(), + + const SizedBox( + height: + 16), // Space between progress and next section + + // Cancel Trip and Charge Passenger + controller.isdriverWaitTimeEnd + ? MyElevatedButton( + title: + 'You Can Cancel the Trip and get Cost From ' .tr + - ' ${AppInformation.appName}' - .tr, - kolor: - AppColor.deepPurpleAccent, - onPressed: () { - Get.defaultDialog( - title: - 'Are you sure to cancel?' - .tr, - titleStyle: - AppStyle.title, - middleText: '', - confirm: MyElevatedButton( - title: 'Yes'.tr, - onPressed: () async { - FirebaseMessagesController() - .sendNotificationToPassengerToken( - 'Driver Cancel Your Trip', - 'You will be pay the cost to driver or we will get it from you on next trip' - .tr, - controller - .tokenPassenger, - [], - 'cancel.wav'); - await controller - .addWaitingTimeCostFromPassengerToDriverWallet(); - controller - .isdriverWaitTimeEnd = - false; - })); - }) - : const SizedBox(), + AppInformation.appName.tr, + kolor: AppColor.deepPurpleAccent, + onPressed: () { + Get.defaultDialog( + title: 'Are you sure to cancel?' + .tr, + titleStyle: AppStyle.title, + middleText: '', + confirm: MyElevatedButton( + title: 'Yes'.tr, + onPressed: () async { + FirebaseMessagesController() + .sendNotificationToPassengerToken( + 'Driver Cancelled Your Trip', + 'You will need to pay the cost to the driver, or it will be deducted from your next trip' + .tr, + controller.tokenPassenger, + [], + 'cancel.wav', + ); + await controller + .addWaitingTimeCostFromPassengerToDriverWallet(); + controller + .isdriverWaitTimeEnd = + false; + }, + ), + cancel: MyElevatedButton( + title: 'No'.tr, + onPressed: () { + Get.back(); + }, + ), + ); + }, + ) + : const SizedBox(), ], ), ], diff --git a/lib/views/home/Captin/orderCaptin/order_over_lay.dart b/lib/views/home/Captin/orderCaptin/order_over_lay.dart index c58f67e..63ef132 100644 --- a/lib/views/home/Captin/orderCaptin/order_over_lay.dart +++ b/lib/views/home/Captin/orderCaptin/order_over_lay.dart @@ -9,6 +9,7 @@ import '../../../../constant/links.dart'; import '../../../../constant/style.dart'; import '../../../../controller/functions/crud.dart'; import '../../../../main.dart'; +import '../../../../print.dart'; class OrderOverlay extends StatefulWidget { const OrderOverlay({Key? key}) : super(key: key); @@ -166,6 +167,7 @@ class _OrderOverlayState extends State @override Widget build(BuildContext context) { String duration = (double.parse(d[4].toString()) / 60).toStringAsFixed(0); + Log.print('duration: ${duration}'); String price = d[2].toString().split('.')[0]; return Material( color: Colors.transparent, diff --git a/lib/views/home/Captin/orderCaptin/order_request_page.dart b/lib/views/home/Captin/orderCaptin/order_request_page.dart index 6913c83..eb88165 100644 --- a/lib/views/home/Captin/orderCaptin/order_request_page.dart +++ b/lib/views/home/Captin/orderCaptin/order_request_page.dart @@ -39,22 +39,6 @@ class OrderRequestPage extends StatelessWidget { myList = arguments['DriverList']; } - // Future.delayed(const Duration(milliseconds: 500)); - // if (res.toString() == 'Apply' || res.toString() == 'Finished') { - // WidgetsBinding.instance.addPostFrameCallback((_) { - // Get.defaultDialog( - // barrierDismissible: false, - // title: 'This trip is taken'.tr, - // middleText: '', - // confirm: MyElevatedButton( - // title: 'Ok'.tr, - // onPressed: () { - // Get.back(); - // })); - // }); - // } - // 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(); diff --git a/lib/views/home/Captin/orderCaptin/order_speed_request.dart b/lib/views/home/Captin/orderCaptin/order_speed_request.dart index 4202b94..22f102c 100644 --- a/lib/views/home/Captin/orderCaptin/order_speed_request.dart +++ b/lib/views/home/Captin/orderCaptin/order_speed_request.dart @@ -26,9 +26,15 @@ class OrderSpeedRequest extends StatelessWidget { @override Widget build(BuildContext context) { final arguments = Get.arguments; + var myList; final myListString = arguments['myListString']; - final myList = arguments['DriverList']; - // final pointsList = arguments['PolylineJson']; + // final myList = arguments['DriverList']; + if (arguments['DriverList'] == null || arguments['DriverList'].isEmpty) { + myList = jsonDecode(myListString); + } else { + myList = arguments['DriverList']; + } + final body = arguments['body']; Duration durationToAdd = Duration(seconds: int.parse(myList[4])); int hours = durationToAdd.inHours; diff --git a/lib/views/widgets/circle_container.dart b/lib/views/widgets/circle_container.dart index eb7fc21..e05bfb6 100644 --- a/lib/views/widgets/circle_container.dart +++ b/lib/views/widgets/circle_container.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:SEFER/constant/colors.dart'; +import 'mydialoug.dart'; + class MyCircleContainer extends StatelessWidget { final Widget child; final Color backgroundColor; @@ -22,6 +24,12 @@ class MyCircleContainer extends StatelessWidget { builder: ((controller) => GestureDetector( onTap: () { controller.changeColor(); + MyDialog().getDialog( + 'Rejected Orders Count'.tr, + 'This is the total number of rejected orders per day after accepting the orders' + .tr, () { + Get.back(); + }); }, child: AnimatedContainer( onEnd: () {