diff --git a/android/app/build.gradle b/android/app/build.gradle index fd3f507..f7fbf78 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -55,8 +55,8 @@ android { // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion 23 targetSdkVersion 34 - versionCode 51 - versionName '1.5.51' + versionCode 53 + versionName '1.5.53' // manifestPlaceholders = [mapsApiKey: 'android/app/src/main/AndroidManifest.xml'] } diff --git a/android/app/google-services.json b/android/app/google-services.json index 3ded064..55da396 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -5,6 +5,78 @@ "storage_bucket": "ride-b1bd8.appspot.com" }, "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:594687661098:android:8ec72f5f8b0b0ab8595f53", + "android_client_info": { + "package_name": "com.example.sefer_admin1" + } + }, + "oauth_client": [ + { + "client_id": "594687661098-2u640akrb3k7sak5t0nqki6f4v6hq1bq.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "594687661098-2hfb9gumub3j60vb7mqtq794k8spihuh.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "594687661098-8e26699cris2k3nj5msj1osi59it9kpf.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.mobileapp.store.ride" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:594687661098:android:f81fcce13962121a595f53", + "android_client_info": { + "package_name": "com.example.service" + } + }, + "oauth_client": [ + { + "client_id": "594687661098-2u640akrb3k7sak5t0nqki6f4v6hq1bq.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "594687661098-2hfb9gumub3j60vb7mqtq794k8spihuh.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "594687661098-8e26699cris2k3nj5msj1osi59it9kpf.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.mobileapp.store.ride" + } + } + ] + } + } + }, { "client_info": { "mobilesdk_app_id": "1:594687661098:android:683982cbf71fa423595f53", @@ -12,6 +84,50 @@ "package_name": "com.mobileapp.store.ride" } }, + "oauth_client": [ + { + "client_id": "594687661098-2dhoogl7be9phobfbu8bbg1sj567iv88.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.mobileapp.store.ride", + "certificate_hash": "9bf3876c66e490f30cd7982fa972d8e52e0edbb6" + } + }, + { + "client_id": "594687661098-2u640akrb3k7sak5t0nqki6f4v6hq1bq.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "594687661098-2hfb9gumub3j60vb7mqtq794k8spihuh.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "594687661098-8e26699cris2k3nj5msj1osi59it9kpf.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.mobileapp.store.ride" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:594687661098:android:b7ce96c17eb928ca595f53", + "android_client_info": { + "package_name": "com.sefer.driver" + } + }, "oauth_client": [ { "client_id": "594687661098-2u640akrb3k7sak5t0nqki6f4v6hq1bq.apps.googleusercontent.com", @@ -49,6 +165,14 @@ } }, "oauth_client": [ + { + "client_id": "594687661098-op7a9cpgm9dilgh8nl48bu6aor55f7qj.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.sefer_driver", + "certificate_hash": "6f83a0b80b7e1b30b3dd42811cbc2c60ee931a3b" + } + }, { "client_id": "594687661098-2u640akrb3k7sak5t0nqki6f4v6hq1bq.apps.googleusercontent.com", "client_type": 3 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/assets/images/cardid.jpg b/assets/images/cardid.jpg deleted file mode 100644 index 608f2d1..0000000 Binary files a/assets/images/cardid.jpg and /dev/null differ diff --git a/assets/images/logo.gif b/assets/images/logo.gif index 1d8abc8..02c031e 100644 Binary files a/assets/images/logo.gif and b/assets/images/logo.gif differ diff --git a/firebase.json b/firebase.json index dd162f6..7ca734b 100644 --- a/firebase.json +++ b/firebase.json @@ -1 +1 @@ -{"functions":[{"source":"functions","codebase":"default","ignore":["node_modules",".git","firebase-debug.log","firebase-debug.*.log"],"predeploy":["npm --prefix \"$RESOURCE_DIR\" run lint"]}],"flutter":{"platforms":{"android":{"default":{"projectId":"ride-b1bd8","appId":"1:594687661098:android:683982cbf71fa423595f53","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"ride-b1bd8","configurations":{"android":"1:594687661098:android:683982cbf71fa423595f53","ios":"1:594687661098:ios:6f69eee1449be943595f53"}}}}}} \ No newline at end of file +{"functions":[{"source":"functions","codebase":"default","ignore":["node_modules",".git","firebase-debug.log","firebase-debug.*.log"],"predeploy":["npm --prefix \"$RESOURCE_DIR\" run lint"]}],"flutter":{"platforms":{"android":{"default":{"projectId":"ride-b1bd8","appId":"1:594687661098:android:683982cbf71fa423595f53","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"ride-b1bd8","configurations":{"android":"1:594687661098:android:683982cbf71fa423595f53","ios":"1:594687661098:ios:6f69eee1449be943595f53","macos":"1:594687661098:ios:6f69eee1449be943595f53","web":"1:594687661098:web:62d8388476ec91ec595f53","windows":"1:594687661098:web:d9f43a2091395d87595f53"}}},"ios":{"default":{"projectId":"ride-b1bd8","appId":"1:594687661098:ios:6f69eee1449be943595f53","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"macos":{"default":{"projectId":"ride-b1bd8","appId":"1:594687661098:ios:6f69eee1449be943595f53","uploadDebugSymbols":false,"fileOutput":"macos/Runner/GoogleService-Info.plist"}}}}} \ No newline at end of file diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist new file mode 100644 index 0000000..e61bc7a --- /dev/null +++ b/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,36 @@ + + + + + CLIENT_ID + 594687661098-8e26699cris2k3nj5msj1osi59it9kpf.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.594687661098-8e26699cris2k3nj5msj1osi59it9kpf + ANDROID_CLIENT_ID + 594687661098-2dhoogl7be9phobfbu8bbg1sj567iv88.apps.googleusercontent.com + API_KEY + AIzaSyCf2mW2h0HD8ZYjwh4VOa2ladw6MJkCDTM + GCM_SENDER_ID + 594687661098 + PLIST_VERSION + 1 + BUNDLE_ID + com.mobileapp.store.ride + PROJECT_ID + ride-b1bd8 + STORAGE_BUCKET + ride-b1bd8.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:594687661098:ios:6f69eee1449be943595f53 + + \ No newline at end of file diff --git a/lib/constant/links.dart b/lib/constant/links.dart index 8035c5c..a68a43f 100644 --- a/lib/constant/links.dart +++ b/lib/constant/links.dart @@ -172,6 +172,7 @@ class AppLink { static String location = '$server/ride/location'; static String getCarsLocationByPassenger = "$location/get.php"; static String getCarsLocationByPassengerSpeed = "$location/getSpeed.php"; + static String getCarsLocationByPassengerComfort = "$location/getComfort.php"; static String getCarsLocationByPassengerDelivery = "$location/getDelivery.php"; static String getLocationParents = "$location/getLocationParents.php"; @@ -244,5 +245,8 @@ class AppLink { static String sendvalidity = "https://sms.kazumi.me/api/sms/send-validity"; static String sendmany = "https://sms.kazumi.me/api/sms/send-many"; static String checkCredit = "https://sms.kazumi.me/api/sms/check-credit"; + static String getSender = "$server/auth/sms/getSender.php"; static String checkStatus = "https://sms.kazumi.me/api/sms/check-status"; + static String updatePhoneInvalidSMSPassenger = + "$server/auth/sms/updatePhoneInvalidSMSPassenger.php"; } diff --git a/lib/controller/auth/register_controller.dart b/lib/controller/auth/register_controller.dart index d635832..6746b71 100644 --- a/lib/controller/auth/register_controller.dart +++ b/lib/controller/auth/register_controller.dart @@ -81,6 +81,21 @@ class RegisterController extends GetxController { update(); } + bool isValidEgyptianPhoneNumber(String phoneNumber) { + // Remove any whitespace from the phone number + phoneNumber = phoneNumber.replaceAll(RegExp(r'\s+'), ''); + + // Check if the phone number has exactly 11 digits + if (phoneNumber.length != 11) { + return false; + } + + // Check if the phone number starts with 010, 011, 012, or 015 + RegExp validPrefixes = RegExp(r'^01[0125]\d{8}$'); + + return validPrefixes.hasMatch(phoneNumber); + } + sendOtpMessage() async { SmsEgyptController smsEgyptController = Get.put(SmsEgyptController()); @@ -89,18 +104,33 @@ class RegisterController extends GetxController { update(); if (formKey3.currentState!.validate()) { if (box.read(BoxName.countryCode) == 'Egypt') { - var responseCheker = await CRUD() - .post(link: AppLink.checkPhoneNumberISVerfiedPassenger, payload: { - 'phone_number': '+2${phoneController.text}', - }); - if (responseCheker != 'failure') { - var d = jsonDecode(responseCheker); - if (d['message'][0]['verified'].toString() == '1') { - Get.snackbar('Phone number is verified before'.tr, '', - backgroundColor: AppColor.greenColor); - box.write(BoxName.isVerified, '1'); - box.write(BoxName.phone, '+2${phoneController.text}'); - Get.offAll(const MapPagePassenger()); + if (isValidEgyptianPhoneNumber(phoneController.text)) { + var responseCheker = await CRUD() + .post(link: AppLink.checkPhoneNumberISVerfiedPassenger, payload: { + 'phone_number': '+2${phoneController.text}', + }); + if (responseCheker != 'failure') { + var d = jsonDecode(responseCheker); + if (d['message'][0]['verified'].toString() == '1') { + Get.snackbar('Phone number is verified before'.tr, '', + backgroundColor: AppColor.greenColor); + box.write(BoxName.isVerified, '1'); + box.write(BoxName.phone, '+2${phoneController.text}'); + Get.offAll(const MapPagePassenger()); + } else { + await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { + 'phone_number': '+2${phoneController.text}', + 'token': randomNumber.toString(), + }); + + await smsEgyptController.sendSmsEgypt( + phoneController.text.toString(), randomNumber.toString()); + isSent = true; + remainingTime = 300; // Reset to 5 minutes + startTimer(); + isLoading = false; + update(); + } } else { await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { 'phone_number': '+2${phoneController.text}', @@ -114,22 +144,12 @@ class RegisterController extends GetxController { startTimer(); isLoading = false; update(); + + // Get.snackbar(responseCheker, 'message'); } } else { - await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { - 'phone_number': '+2${phoneController.text}', - 'token': randomNumber.toString(), - }); - - await smsEgyptController.sendSmsEgypt( - phoneController.text.toString(), randomNumber.toString()); - isSent = true; - remainingTime = 300; // Reset to 5 minutes - startTimer(); - isLoading = false; - update(); - - // Get.snackbar(responseCheker, 'message'); + Get.snackbar('Phone Number wrong'.tr, '', + backgroundColor: AppColor.redColor); } } } diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart index fbac8c0..d03d60f 100644 --- a/lib/controller/firebase/firbase_messge.dart +++ b/lib/controller/firebase/firbase_messge.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:io'; +import 'package:SEFER/views/widgets/my_dialog.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -13,6 +14,7 @@ import '../../constant/colors.dart'; import '../../constant/links.dart'; import '../../constant/style.dart'; import '../../main.dart'; +import '../../print.dart'; import '../../views/Rate/rate_captain.dart'; import '../../views/home/map_page_passenger.dart'; import '../../views/home/profile/promos_passenger_page.dart'; @@ -183,6 +185,29 @@ class FirebaseMessagesController extends GetxController { driverArrivePassengerDialoge(); update(); + } else if (message.notification!.title! == "Cancel Trip from driver".tr) { + Get.back(); + Get.defaultDialog( + title: "The driver canceled your ride.".tr, + middleText: "We will look for a new driver.\nPlease wait.".tr, + confirm: MyElevatedButton( + title: 'Ok'.tr, + onPressed: () async { + Get.back(); + Get.find() + .delayAndFetchRideStatusForAllDriverAvailable( + Get.find().rideId); + }, + ), + cancel: MyElevatedButton( + title: 'Cancel'.tr, + onPressed: () { + Get.offAll(const MapPagePassenger()); + }, + ) + // Get.find() + // .searchNewDriverAfterRejectingFromDriver(); + ); } else if (message.notification!.title! == 'Driver Finish Trip'.tr) { var myListString = message.data['passengerList']; var driverList = jsonDecode(myListString) as List; @@ -547,7 +572,6 @@ class FirebaseMessagesController extends GetxController { 'notification': { 'title': title, 'body': body, - // 'sound': 'tone2.wav', 'sound': tone }, 'data': { @@ -559,13 +583,16 @@ class FirebaseMessagesController extends GetxController { ); if (response.statusCode == 200) { - // Notification sent successfully + Log.print( + 'Notification sent successfully. Status code: ${response.statusCode}'); + Log.print('Response body: ${response.body}'); } else { - // Handle error response - 'Failed to send notification. Status code: ${response.statusCode}'; + Log.print( + 'Failed to send notification. Status code: ${response.statusCode}'); + Log.print('Response body: ${response.body}'); } } catch (e) { - // Handle other exceptions + Log.print('Error sending notification: $e'); } } diff --git a/lib/controller/functions/crud.dart b/lib/controller/functions/crud.dart index 06f2b64..ffe5a8c 100644 --- a/lib/controller/functions/crud.dart +++ b/lib/controller/functions/crud.dart @@ -8,6 +8,7 @@ import 'package:SEFER/env/env.dart'; import '../../constant/api_key.dart'; +import '../../print.dart'; import 'upload_image.dart'; class CRUD { @@ -28,6 +29,7 @@ class CRUD { }, ); print(response.request); + Log.print('payload: ${payload}'); print(response.body); // print(payload); // if (response.statusCode == 200) { diff --git a/lib/controller/functions/sms_controller.dart b/lib/controller/functions/sms_controller.dart index 928f06b..03bb9fd 100644 --- a/lib/controller/functions/sms_controller.dart +++ b/lib/controller/functions/sms_controller.dart @@ -4,21 +4,35 @@ import 'package:SEFER/constant/api_key.dart'; import 'package:SEFER/constant/box_name.dart'; import 'package:SEFER/constant/info.dart'; import 'package:SEFER/constant/links.dart'; +import 'package:SEFER/controller/auth/login_controller.dart'; import 'package:SEFER/main.dart'; import 'package:SEFER/views/widgets/elevated_btn.dart'; import 'package:get/get.dart'; import 'package:http/http.dart' as http; +import '../auth/register_controller.dart'; +import 'crud.dart'; + class SmsEgyptController extends GetxController { var headers = {'Content-Type': 'application/json'}; + Future getSender() async { + var res = await CRUD().get(link: AppLink.getSender, payload: {}); + if (res != 'failure') { + var d = jsonDecode(res)['message'][0]['senderId'].toString(); + return d; + } else { + return "Sefer Egy"; + } + } Future sendSmsEgypt(String phone, otp) async { + String sender = await getSender(); var body = jsonEncode({ "username": AppInformation.appName, "password": AK.smsPasswordEgypt, "message": "${AppInformation.appName} app code is $otp\ncopy it to app", "language": box.read(BoxName.lang) == 'en' ? "e" : 'r', - "sender": "Sefer Egy", + "sender": sender, //"Sefer Egy", "receiver": "2$phone" }); @@ -28,9 +42,23 @@ class SmsEgyptController extends GetxController { headers: headers, ); - if (res.statusCode == 200) { + if (jsonDecode(res.body)['message'].toString() == + "Invalid Sender with Connection") { + await CRUD().post(link: AppLink.updatePhoneInvalidSMSPassenger, payload: { + "phone_number": + '+2${Get.find().phoneController.text}' + }); + box.write(BoxName.phoneDriver, + '+2${Get.find().phoneController.text}'); + box.write(BoxName.isVerified, '1'); + + await Get.put(LoginController()).loginUsingCredentials( + box.read(BoxName.driverID).toString(), + box.read(BoxName.emailDriver).toString(), + ); + } else { Get.defaultDialog( - title: 'You will recieve code in sms message'.tr, + title: 'You will receive code in sms message'.tr, middleText: '', confirm: MyElevatedButton( title: 'OK'.tr, diff --git a/lib/controller/home/map_passenger_controller.dart b/lib/controller/home/map_passenger_controller.dart index cea551c..73419db 100644 --- a/lib/controller/home/map_passenger_controller.dart +++ b/lib/controller/home/map_passenger_controller.dart @@ -5,6 +5,7 @@ import 'dart:math' as math; import 'package:SEFER/controller/functions/tts.dart'; import 'package:SEFER/views/home/map_page_passenger.dart'; +import 'package:SEFER/views/widgets/my_dialog.dart'; import 'package:SEFER/views/widgets/my_textField.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; @@ -739,7 +740,10 @@ class MapPassengerController extends GetxController { var res = await CRUD().get( link: AppLink.getRideStatusFromStartApp, payload: {'passenger_id': box.read(BoxName.passengerID)}); - if (res == 'failure') {} + if (res == 'failure') { + print( + "No rides found for the given passenger ID within the last hour."); + } rideStatusFromStartApp = jsonDecode(res); if (rideStatusFromStartApp['data']['status'] == 'Begin') { statusRide = 'Begin'; @@ -968,12 +972,6 @@ class MapPassengerController extends GetxController { } } -// Example usage - void someFunction() { - String whatsAppLink = 'https://maps.google.com/maps?q=37.4220,-122.0841'; - handleWhatsAppLink(whatsAppLink); - } - void goToWhatappLocation() async { if (sosFormKey.currentState!.validate()) { changeIsWhatsAppOrder(true); @@ -999,7 +997,8 @@ class MapPassengerController extends GetxController { late String make = ''; late String licensePlate = ''; confirmRideForFirstDriver() async { - await getCarsLocationByPassengerAndReloadMarker(); + startCarLocationSearch(box.read(BoxName.carType)); + // await getCarsLocationByPassengerAndReloadMarker(); await getNearestDriverByPassengerLocationAPIGOOGLE(); if (dataCarsLocationByPassenger != 'failure') { @@ -1097,10 +1096,12 @@ class MapPassengerController extends GetxController { box.read(BoxName.carType), kazan.toStringAsFixed(0), passengerRate.toStringAsFixed(2), - ]; // + ]; + Log.print('body: ${body}'); FirebaseMessagesController().sendNotificationToDriverMAP( 'Order'.tr, - jsonDecode(value)['message'].toString(), + 'from: $startNameAddress\nto: $startNameAddress\ndistanceFromMe: $distanceByPassenger\nDistance :$distance\nPrice ; $totalPassenger', + // jsonDecode(value)['message'].toString(), dataCarsLocationByPassenger['message'][carsOrder]['token'] .toString(), body, @@ -1108,6 +1109,8 @@ class MapPassengerController extends GetxController { // polylineCoordinates.toString() ); + Log.print( + 'body: ${dataCarsLocationByPassenger['message'][carsOrder]['token']}'); }); delayAndFetchRideStatus(rideId); if (shouldFetch == false) { @@ -1135,12 +1138,13 @@ class MapPassengerController extends GetxController { bool isDriversTokensSend = false; confirmRideForAllDriverAvailable() async { // isDriversTokensSend = true; + driversToken.remove(driverToken); PaymentController paymentController = Get.find(); rideConfirm = true; shouldFetch = true; isBottomSheetShown = false; timeToPassengerFromDriverAfterApplied = 60; - driversToken.remove(driverToken); + List body = [ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}', '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}', @@ -1196,44 +1200,57 @@ class MapPassengerController extends GetxController { update(); } + int tick = 0; // Move tick outside the function to maintain its state + void delayAndFetchRideStatus(String rideId) { - Timer(const Duration(seconds: 1), () async { + Timer.periodic(const Duration(seconds: 1), (timer) async { if (shouldFetch) { if (remainingTimeToPassengerFromDriverAfterApplied > 0) { - var res = await getRideStatus(rideId); + String res = await getRideStatus(rideId); - // var decod = jsonDecode(res); - if (res.toString() == 'Apply') { - // getUpdatedRideForDriverApply(rideId); + Log.print('tick: $tick'); + + if (res.toString() == 'waiting' && tick == 15) { + timer.cancel(); // Stop the current timer + delayAndFetchRideStatusForAllDriverAvailable(rideId); + } else if (res.toString() == 'Apply') { + timer.cancel(); // Stop the current timer shouldFetch = false; // Stop further fetches statusRide = 'Apply'; rideConfirm = false; isSearchingWindow = false; update(); startTimerFromDriverToPassengerAfterApplied(); - // startTimer(); } else if (res.toString() == 'Refused') { statusRide = 'Refused'; - // isDriversTokensSend = false; if (isDriversTokensSend == false) { confirmRideForAllDriverAvailable(); isDriversTokensSend = true; - } + } // Start 15-second timer } else if (isDriversTokensSend == false) { - delayAndFetchRideStatus( - rideId); // Repeat the delay and fetch operation + // No need to recall delayAndFetchRideStatus as Timer.periodic is already running update(); } + tick++; + } else { + timer + .cancel(); // Stop the timer if remainingTimeToPassengerFromDriverAfterApplied <= 0 } + } else { + timer.cancel(); // Stop the timer if shouldFetch is false } }); } void delayAndFetchRideStatusForAllDriverAvailable(String rideId) { - Timer(const Duration(milliseconds: 1000), () async { - if (shouldFetch) { + int attemptCounter = 0; + const int maxAttempts = 15; + + void fetchRideStatus() async { + if (shouldFetch && attemptCounter < maxAttempts) { + attemptCounter++; var res = await getRideStatus(rideId); - // var decod = jsonDecode(res); + if (res.toString() == 'Apply') { getUpdatedRideForDriverApply(rideId); @@ -1243,10 +1260,28 @@ class MapPassengerController extends GetxController { isSearchingWindow = false; update(); startTimerFromDriverToPassengerAfterApplied(); - } else if (res.toString() == 'Refused') { - delayAndFetchRideStatusForAllDriverAvailable(rideId); + } else { + Timer(const Duration(seconds: 2), + fetchRideStatus); // Continue fetching for other statuses } + } else { + // Stop fetching after maxAttempts or if shouldFetch is false + shouldFetch = false; + MyDialog().getDialog('upgrade price'.tr, + 'You can upgrade price to may driver accept your order'.tr, () { + Get.back(); + }); + update(); + print('Stopped fetching ride status after 30 seconds.'); } + } + + fetchRideStatus(); // Initial call to start the process + } + + void start15SecondTimer(String rideId) { + Timer(const Duration(seconds: 15), () { + delayAndFetchRideStatusForAllDriverAvailable(rideId); }); } @@ -1431,89 +1466,134 @@ class MapPassengerController extends GetxController { Map _animationTimers = {}; final int updateIntervalMs = 100; // Update every 100ms final double minMovementThreshold = - 1.0; // Minimum movement in meters to trigger update + 10; // Minimum movement in meters to trigger update - Future getCarsLocationByPassengerAndReloadMarker() async { + void startCarLocationSearch(String carType) { + int searchInterval = 5; // Interval in seconds + int boundIncreaseStep = 4500; // Initial bounds in meters + int maxAttempts = 3; // Maximum attempts to increase bounds + int attempt = 0; // Current attempt + + Timer.periodic(Duration(seconds: searchInterval), (Timer timer) async { + if (attempt >= maxAttempts) { + timer.cancel(); + noCarString = true; + dataCarsLocationByPassenger = 'failure'; + update(); + return; + } + + bool foundCars = await getCarsLocationByPassengerAndReloadMarker( + carType, boundIncreaseStep); + + if (foundCars) { + timer.cancel(); + } else { + attempt++; + boundIncreaseStep = boundIncreaseStep + 1500; // Increase bounds + } + }); + } + + Future getCarsLocationByPassengerAndReloadMarker( + String carType, int boundIncreaseStep) async { if (statusRide == 'wait') { - LatLngBounds bounds = calculateBounds( - passengerLocation.latitude, passengerLocation.longitude, 7000); + carsLocationByPassenger = []; + LatLngBounds bounds = calculateBounds(passengerLocation.latitude, + passengerLocation.longitude, boundIncreaseStep.toDouble()); + var res; - var res = await _fetchCarLocations(bounds); + switch (carType) { + case 'Lady': + res = await CRUD() + .get(link: AppLink.getFemalDriverLocationByPassenger, payload: { + 'southwestLat': bounds.southwest.latitude.toString(), + 'southwestLon': bounds.southwest.longitude.toString(), + 'northeastLat': bounds.northeast.latitude.toString(), + 'northeastLon': bounds.northeast.longitude.toString(), + }); + break; + case 'Comfort': + res = await CRUD() + .get(link: AppLink.getCarsLocationByPassengerComfort, payload: { + 'southwestLat': bounds.southwest.latitude.toString(), + 'southwestLon': bounds.southwest.longitude.toString(), + 'northeastLat': bounds.northeast.latitude.toString(), + 'northeastLon': bounds.northeast.longitude.toString(), + }); + break; + case 'Speed': + res = await CRUD() + .get(link: AppLink.getCarsLocationByPassengerSpeed, payload: { + 'southwestLat': bounds.southwest.latitude.toString(), + 'southwestLon': bounds.southwest.longitude.toString(), + 'northeastLat': bounds.northeast.latitude.toString(), + 'northeastLon': bounds.northeast.longitude.toString(), + }); + break; + case 'Delivery': + res = await CRUD() + .get(link: AppLink.getCarsLocationByPassengerDelivery, payload: { + 'southwestLat': bounds.southwest.latitude.toString(), + 'southwestLon': bounds.southwest.longitude.toString(), + 'northeastLat': bounds.northeast.latitude.toString(), + 'northeastLon': bounds.northeast.longitude.toString(), + }); + break; + default: + res = await CRUD() + .get(link: AppLink.getCarsLocationByPassenger, payload: { + 'southwestLat': bounds.southwest.latitude.toString(), + 'southwestLon': bounds.southwest.longitude.toString(), + 'northeastLat': bounds.northeast.latitude.toString(), + 'northeastLon': bounds.northeast.longitude.toString(), + }); + } if (res == 'failure') { - noCarString = true; - dataCarsLocationByPassenger = res; + // noCarString = true; + // dataCarsLocationByPassenger = res; + // update(); + return false; } else { noCarString = false; dataCarsLocationByPassenger = jsonDecode(res); - driverId = dataCarsLocationByPassenger['message'][carsOrder] ['driver_id'] .toString(); gender = dataCarsLocationByPassenger['message'][carsOrder]['gender'] .toString(); - _updateMarkers(dataCarsLocationByPassenger['message']); + carsLocationByPassenger.clear(); // Clear existing markers + + for (var i = 0; + i < dataCarsLocationByPassenger['message'].length; + i++) { + var json = dataCarsLocationByPassenger['message'][i]; + _updateOrCreateMarker( + MarkerId(json['latitude']).toString(), + LatLng(double.parse(json['latitude']), + double.parse(json['longitude'])), + double.parse(json['heading']), + _getIconForCar(json), + ); + + driversToken.add(json['token']); + } + update(); + return true; } - - update(); } - } - - Future _fetchCarLocations(LatLngBounds bounds) async { - var payload = { - 'southwestLat': bounds.southwest.latitude.toString(), - 'southwestLon': bounds.southwest.longitude.toString(), - 'northeastLat': bounds.northeast.latitude.toString(), - 'northeastLon': bounds.northeast.longitude.toString(), - }; - - String link; - switch (box.read(BoxName.carType)) { - case 'Lady': - link = AppLink.getFemalDriverLocationByPassenger; - break; - case 'Speed': - link = AppLink.getCarsLocationByPassengerSpeed; - break; - case 'Delivery': - link = AppLink.getCarsLocationByPassengerDelivery; - break; - default: - link = AppLink.getCarsLocationByPassenger; - } - - return await CRUD().get(link: link, payload: payload); - } - - void _updateMarkers(List carsData) { - driversToken.clear(); - - for (var json in carsData) { - String markerId = json['driver_id'].toString(); - LatLng newPosition = LatLng( - double.parse(json['latitude']), - double.parse(json['longitude']), - ); - double newHeading = double.parse(json['heading']); - BitmapDescriptor icon = _getIconForCar(json); - - _updateOrCreateMarker(markerId, newPosition, newHeading, icon); - driversToken.add(json['token']); - } - - // Remove markers for cars that are no longer present - markers.removeWhere((marker) => !carsData - .any((car) => car['driver_id'].toString() == marker.markerId.value)); + return false; } BitmapDescriptor _getIconForCar(Map carData) { if (carData['model'].toString().contains('دراجة')) { return motoIcon; - } else if (carData['gender'] == 'Male'.tr) { - return carIcon; - } else { + } else if (carData['gender'] == 'Female') { return ladyIcon; + } else { + return carIcon; } } @@ -1611,6 +1691,8 @@ class MapPassengerController extends GetxController { 'sosPhone': sosPhonePassengerProfile.text, }, ); + box.write( + BoxName.sosPhonePassenger, sosPhonePassengerProfile.text); } })); } @@ -1714,12 +1796,12 @@ class MapPassengerController extends GetxController { Future runEvery30SecondsUntilConditionMet() async { // Calculate the duration of the trip in minutes. - double tripDurationInMinutes = durationToPassenger / 6; + double tripDurationInMinutes = durationToPassenger / 5; int loopCount = tripDurationInMinutes.ceil(); // If the trip duration is less than or equal to 50 minutes, then break the loop. for (var i = 0; i < loopCount; i++) { // Wait for 50 seconds. - await Future.delayed(const Duration(seconds: 4)); + await Future.delayed(const Duration(seconds: 5)); if (rideTimerBegin == true || statusRide == 'Apply') { await getDriverCarsLocationToPassengerAfterApplied(); reloadMarkerDriverCarsLocationToPassengerAfterApplied(); @@ -1761,7 +1843,7 @@ class MapPassengerController extends GetxController { } void reloadMarkerDriverCarsLocationToPassengerAfterApplied() { - clearMarkersExceptStartEnd(); + // clearMarkersExceptStartEnd(); LatLng driverPosition = LatLng( double.parse(datadriverCarsLocationToPassengerAfterApplied['message'][0] @@ -1780,9 +1862,9 @@ class MapPassengerController extends GetxController { ? motoIcon : datadriverCarsLocationToPassengerAfterApplied['message'][0] ['gender'] == - 'Male'.tr - ? carIcon - : ladyIcon; + 'Female' + ? ladyIcon + : carIcon; _updateMarkerPosition(driverPosition, heading, icon); } @@ -1834,6 +1916,18 @@ class MapPassengerController extends GetxController { update(); } + searchNewDriverAfterRejectingFromDriver() { +// + + shouldFetch = true; // Stop further fetches + statusRide = 'wait'; + rideConfirm = true; + isSearchingWindow = true; + confirmRideForFirstDriver(); + + update(); + } + Future cancelRideAfterRejectFromAll() async { clearPlacesDestination(); clearPolyline(); @@ -1869,6 +1963,10 @@ class MapPassengerController extends GetxController { "order_id": rideId.toString(), // Convert to String "status": 'Cancel' }); + await CRUD().post(link: AppLink.updateRides, payload: { + "id": rideId.toString(), // Convert to String + "status": 'Cancel' + }); print('Cancel'); FirebaseMessagesController().sendNotificationToDriverMAP( 'Cancel Trip', @@ -2169,7 +2267,7 @@ class MapPassengerController extends GetxController { void addCustomCarIcon() { ImageConfiguration config = ImageConfiguration( - size: const Size(30, 30), devicePixelRatio: Get.pixelRatio); + size: const Size(30, 35), devicePixelRatio: Get.pixelRatio); BitmapDescriptor.asset( config, 'assets/images/car.png', @@ -2332,7 +2430,7 @@ class MapPassengerController extends GetxController { startMarkerReloading() async { int reloadCount = 0; - Timer.periodic(const Duration(seconds: 2), (timer) { + Timer.periodic(const Duration(seconds: 5), (timer) { reloadCount++; if (!rideConfirm) { @@ -2348,11 +2446,13 @@ class MapPassengerController extends GetxController { } reloadMarkers() async { - if (statusRide == 'wait') { - clearMarkersExceptStartEnd(); - await getCarsLocationByPassengerAndReloadMarker(); - await getNearestDriverByPassengerLocation(); - } + // if (statusRide == 'wait') { + clearMarkersExceptStartEnd(); + // _smoothlyUpdateMarker(); + startCarLocationSearch(box.read(BoxName.carType)); + // await getCarsLocationByPassengerAndReloadMarker(); + await getNearestDriverByPassengerLocation(); + // } } String durationByPassenger = ''; @@ -2361,6 +2461,7 @@ class MapPassengerController extends GetxController { 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 @@ -2380,7 +2481,7 @@ class MapPassengerController extends GetxController { double.parse(carLocation['latitude']), double.parse(carLocation['longitude']), ); - durationToPassenger = (distance * 35 * (1000 / 3600)) + durationToPassenger = (distance * 25 * (1000 / 3600)) .round(); //////35 is avg of speed in city // Update the UI with the distance and duration update(); @@ -2487,13 +2588,38 @@ class MapPassengerController extends GetxController { update(); } else { Get.defaultDialog( + barrierDismissible: false, title: 'The Driver Will be in your location soon .'.tr, middleText: 'The distance less than 500 meter.'.tr, - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - Get.back(); - }, + confirm: Column( + children: [ + MyElevatedButton( + kolor: AppColor.greenColor, + title: 'Ok'.tr, + onPressed: () { + Get.back(); + }, + ), + MyElevatedButton( + kolor: AppColor.redColor, + title: 'No, I want to cancel this trip'.tr, + onPressed: () { + Get.back(); + MyDialog().getDialog( + 'Attention'.tr, + 'You will be charged for the cost of the driver coming to your location.' + .tr, + () async { + Get.back(); + Get.find() + .payToDriverForCancelAfterAppliedAndHeNearYou(rideId); + // isCancelRidePageShown = true; + // update(); + }, + ); + }, + ), + ], ), ); // cancel: MyElevatedButton( @@ -2528,7 +2654,8 @@ class MapPassengerController extends GetxController { isLoading = true; update(); remainingTime = 25; //to make cancel every call - await getCarsLocationByPassengerAndReloadMarker(); + startCarLocationSearch(box.read(BoxName.carType)); + // await getCarsLocationByPassengerAndReloadMarker(); var coordDestination = destination.split(','); double latPassengerDestination = double.parse(coordDestination[0]); double lngPassengerDestination = double.parse(coordDestination[1]); @@ -2731,7 +2858,8 @@ class MapPassengerController extends GetxController { getMapPoints(String originSteps, String destinationSteps, int index) async { isWayPointStopsSheetUtilGetMap = false; // haveSteps = true; - await getCarsLocationByPassengerAndReloadMarker(); + startCarLocationSearch(box.read(BoxName.carType)); + // await getCarsLocationByPassengerAndReloadMarker(); // isLoading = true; update(); var url = diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart index 3cfb8f9..64ca329 100644 --- a/lib/controller/local/translations.dart +++ b/lib/controller/local/translations.dart @@ -44,11 +44,31 @@ class MyTranslation extends Translations { "Choose who this order is for": "اختر لمن هذا الطلب", "I want to order for myself": "أريد أن أطلب لنفسي", "I want to order for someone else": "أريد أن أطلب لشخص آخر", - + "Cancel Trip from driver": "إلغاء الرحلة من السائق", "If you want order to another person": "إذا كنت تريد الطلب لشخص آخر", - "Wehaven'tfoundanydriversyet.Considerincreasingyourtripfeetomakeyouroffermoreattractivetodrivers.": + "We will look for a new driver.\nPlease wait.": + "سنبحث عن سائق جديد.\nمن فضلك انتظر.", + "upgrade price": "رفع السعر", + "You can upgrade price to may driver accept your order": + "يمكنك رفع السعر حتى يقبل السائق طلبك", + + "No, I want to cancel this trip": "لا، أريد إلغاء هذه الرحلة", + 'Trip Cancelled. The cost of the trip will be added to your wallet.': + "تم إلغاء الرحلة. سيتم إضافة تكلفة الرحلة إلى محفظتك.", + + "Attention": "تنبيه", + "Trip Cancelled. The cost of the trip will be deducted from your wallet.": + "تم إلغاء الرحلة. سيتم خصم تكلفة الرحلة من محفظتك.", + "You will be charged for the cost of the driver coming to your location.": + "سيتم خصم تكلفة قدوم السائق إلى موقعك.", + "reject your order.": "رفض طلبك.", + "Order Under Review": "الطلب قيد المراجعة", + "is reviewing your order. They may need more information or a higher price.": + "يتم مراجعة طلبك. قد يحتاجون إلى مزيد من المعلومات أو سعر أعلى.", + "The driver canceled your ride.": "ألغى السائق رحلتك.", + "We haven't found any drivers yet. Consider increasing your trip fee to make your offer more attractive to drivers.": "لم نجد أي سائقين بعد. ضع في اعتبارك زيادة رسوم رحلتك لجعل عرضك أكثر جاذبية للسائقين.", - "IncreaseYourTripFee(Optional)": "زيادة رسوم رحلتك (اختياري)", + "Increase Your Trip Fee (Optional)": "زيادة رسوم رحلتك (اختياري)", 'Vibration': "اهتزاز‏", 'Resend code': "إعادة إرسال الرمز", "Sign in with Apple": "تسجيل الدخول باستخدام Apple", diff --git a/lib/controller/payment/payment_controller.dart b/lib/controller/payment/payment_controller.dart index f95a2e4..4eb96d4 100644 --- a/lib/controller/payment/payment_controller.dart +++ b/lib/controller/payment/payment_controller.dart @@ -1,8 +1,10 @@ import 'dart:convert'; import 'package:SEFER/constant/api_key.dart'; import 'package:SEFER/constant/style.dart'; +import 'package:SEFER/controller/firebase/firbase_messge.dart'; import 'package:SEFER/controller/functions/tts.dart'; import 'package:SEFER/controller/payment/paymob/paymob_response.dart'; +import 'package:SEFER/views/home/map_page_passenger.dart'; import 'package:SEFER/views/widgets/elevated_btn.dart'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; @@ -101,6 +103,54 @@ class PaymentController extends GetxController { }); } + payToDriverForCancelAfterAppliedAndHeNearYou(String rideId) async { + { + double costOfWaiting5Minute = box.read(BoxName.countryCode) == 'Egypt' + ? (4 * .08) + (5 * 1) + // 4 indicate foe 4 km ditance from driver start move to passenger + : (4 * .06) + (5 * .06); //for Eygpt other like jordan .06 per minute + var paymentTokenWait = + await generateTokenDriver(costOfWaiting5Minute.toString()); + var res = await CRUD().post(link: AppLink.addDrivePayment, payload: { + 'rideId': rideId, + 'amount': costOfWaiting5Minute.toString(), + 'payment_method': 'cancel-from-near', + 'passengerID': box.read(BoxName.passengerID).toString(), + 'token': paymentTokenWait, + 'driverID': Get.find().driverId.toString(), + }); + var paymentTokenWait1 = + await generateTokenDriver(costOfWaiting5Minute.toString()); + var res1 = + await CRUD().post(link: AppLink.addDriversWalletPoints, payload: { + 'paymentID': 'rideId$rideId', + 'amount': (costOfWaiting5Minute).toStringAsFixed(0), + 'paymentMethod': 'cancel-from-near', + 'token': paymentTokenWait1, + 'driverID': Get.find().driverId.toString(), + }); + + if (res != 'failure') { + FirebaseMessagesController().sendNotificationToDriverMAP( + 'Cancel', + 'Trip Cancelled. The cost of the trip will be added to your wallet.' + .tr, + Get.find().driverToken, + [], + 'cancel.wav', + ); + } + var paymentTokenWaitPassenger1 = + await generateTokenPassenger((costOfWaiting5Minute * -1).toString()); + await CRUD().post(link: AppLink.addPassengersWallet, payload: { + 'passenger_id': box.read(BoxName.passengerID).toString(), + 'balance': (costOfWaiting5Minute * -1).toString(), + 'token': paymentTokenWaitPassenger1, + }); + Get.offAll(const MapPagePassenger()); + } + } + addPassengerWallet() async { isLoading = true; update(); diff --git a/lib/controller/payment/paymob.dart b/lib/controller/payment/paymob.dart index 6be873a..9e09cf7 100644 --- a/lib/controller/payment/paymob.dart +++ b/lib/controller/payment/paymob.dart @@ -6,6 +6,7 @@ import 'package:url_launcher/url_launcher.dart'; import '../../constant/api_key.dart'; import '../../main.dart'; +import '../../print.dart'; class PaymobManager extends GetxController { String authanticationToken1 = ""; @@ -95,6 +96,7 @@ class PaymobManager extends GetxController { 'username': AK.usernamePayMob, "password": AK.passwordPayMob, }); + Log.print('token: ${response}'); return response.data["token"]; } @@ -111,6 +113,7 @@ class PaymobManager extends GetxController { "delivery_needed": "false", "items": [], }); + Log.print('id: ${response}'); return response.data["id"]; } @@ -126,16 +129,15 @@ class PaymobManager extends GetxController { "auth_token": authanticationToken.toString(), "order_id": orderId.toString(), "integration_id": - 4556056, ////todo wallet or online card int.parse(AK.integrationIdPayMob), + 4601103, ////todo wallet or online card int.parse(AK.integrationIdPayMob), "lock_order_when_paid": "false", "amount_cents": amount, "currency": currency, "billing_data": { - "first_name": box.read(BoxName.nameDriver) ?? box.read(BoxName.name), - "last_name": box.read(BoxName.lastNameDriver) ?? box.read(BoxName.name), - "email": box.read(BoxName.emailDriver) ?? box.read(BoxName.email), - "phone_number": - box.read(BoxName.phoneDriver) ?? box.read(BoxName.phone), + "first_name": box.read(BoxName.name), + "last_name": box.read(BoxName.name), + "email": box.read(BoxName.email), + "phone_number": box.read(BoxName.phone), "apartment": "NA", "floor": "NA", "street": "NA", @@ -147,7 +149,7 @@ class PaymobManager extends GetxController { "state": "NA" }, }); - + Log.print('token: ${response}'); return response.data["token"]; } } diff --git a/lib/controller/payment/paymob/paymob_wallet.dart b/lib/controller/payment/paymob/paymob_wallet.dart index b80f39e..3e8c3c7 100644 --- a/lib/controller/payment/paymob/paymob_wallet.dart +++ b/lib/controller/payment/paymob/paymob_wallet.dart @@ -4,6 +4,8 @@ import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; +import '../../../print.dart'; + class PaymobResponseWallet { final bool success; final String? transactionID; @@ -142,9 +144,7 @@ class PaymobPaymentWallet { }) async { final Map data = { "source": { - "identifier": box - .read(BoxName.phone) - .toString(), // Replace with actual source identifier + "identifier": box.read(BoxName.phone).toString(), "subtype": "WALLET", }, "payment_token": paymentToken, @@ -219,6 +219,7 @@ class PaymobPaymentWallet { ), ); final urlWallet = await _getWalletUrl(paymentToken: purchaseToken); + Log.print('urlWallet: ${urlWallet}'); if (context.mounted) { final response = await PaymobIFrameWallet.show( diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart index eb64b6f..8d1894c 100644 --- a/lib/firebase_options.dart +++ b/lib/firebase_options.dart @@ -17,10 +17,7 @@ import 'package:flutter/foundation.dart' class DefaultFirebaseOptions { static FirebaseOptions get currentPlatform { if (kIsWeb) { - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for web - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); + return web; } switch (defaultTargetPlatform) { case TargetPlatform.android: @@ -28,15 +25,9 @@ class DefaultFirebaseOptions { case TargetPlatform.iOS: return ios; case TargetPlatform.macOS: - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for macos - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); + return macos; case TargetPlatform.windows: - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for windows - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); + return windows; case TargetPlatform.linux: throw UnsupportedError( 'DefaultFirebaseOptions have not been configured for linux - ' @@ -63,8 +54,40 @@ class DefaultFirebaseOptions { messagingSenderId: '594687661098', projectId: 'ride-b1bd8', storageBucket: 'ride-b1bd8.appspot.com', - iosClientId: - '594687661098-8e26699cris2k3nj5msj1osi59it9kpf.apps.googleusercontent.com', + androidClientId: '594687661098-2dhoogl7be9phobfbu8bbg1sj567iv88.apps.googleusercontent.com', + iosClientId: '594687661098-8e26699cris2k3nj5msj1osi59it9kpf.apps.googleusercontent.com', iosBundleId: 'com.mobileapp.store.ride', ); -} + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyAVtyV7YVMeLbwA1UlNPxV9FhCzT0kjeAE', + appId: '1:594687661098:web:62d8388476ec91ec595f53', + messagingSenderId: '594687661098', + projectId: 'ride-b1bd8', + authDomain: 'ride-b1bd8.firebaseapp.com', + storageBucket: 'ride-b1bd8.appspot.com', + measurementId: 'G-Y3HFEC6F4N', + ); + + static const FirebaseOptions macos = FirebaseOptions( + apiKey: 'AIzaSyCf2mW2h0HD8ZYjwh4VOa2ladw6MJkCDTM', + appId: '1:594687661098:ios:6f69eee1449be943595f53', + messagingSenderId: '594687661098', + projectId: 'ride-b1bd8', + storageBucket: 'ride-b1bd8.appspot.com', + androidClientId: '594687661098-2dhoogl7be9phobfbu8bbg1sj567iv88.apps.googleusercontent.com', + iosClientId: '594687661098-8e26699cris2k3nj5msj1osi59it9kpf.apps.googleusercontent.com', + iosBundleId: 'com.mobileapp.store.ride', + ); + + static const FirebaseOptions windows = FirebaseOptions( + apiKey: 'AIzaSyAVtyV7YVMeLbwA1UlNPxV9FhCzT0kjeAE', + appId: '1:594687661098:web:d9f43a2091395d87595f53', + messagingSenderId: '594687661098', + projectId: 'ride-b1bd8', + authDomain: 'ride-b1bd8.firebaseapp.com', + storageBucket: 'ride-b1bd8.appspot.com', + measurementId: 'G-C3DWQ8Z062', + ); + +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 6308e02..095fe52 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,7 +11,6 @@ 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'; import 'controller/firebase/firbase_messge.dart'; import 'controller/firebase/local_notification.dart'; 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 4d8d8c2..52adbe2 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 @@ -6,6 +6,7 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; import '../../../constant/char_map.dart'; import '../../../constant/colors.dart'; import '../../../constant/credential.dart'; +import '../../../controller/firebase/firbase_messge.dart'; import '../../../controller/functions/tts.dart'; import '../../../controller/home/map_passenger_controller.dart'; import '../../../main.dart'; @@ -103,26 +104,32 @@ GetBuilder leftMainMenuIcons() { // ), // ), // ), - // AnimatedContainer( - // duration: const Duration(microseconds: 200), - // width: controller.widthMapTypeAndTraffic, - // decoration: BoxDecoration( - // color: AppColor.secondaryColor, - // border: Border.all(), - // borderRadius: BorderRadius.circular(15)), - // child: IconButton( - // onPressed: () async { - // var phone = box.read(BoxName.countryCode) == 'Egypt' - // ? '+2${box.read(BoxName.sosPhonePassenger)}' - // : '+962${box.read(BoxName.sosPhonePassenger)}'; - // controller.sendWhatsapp(phone); - // }, - // icon: const Icon( - // Icons.chat, - // size: 29, - // ), - // ), - // ), + AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTraffic, + decoration: BoxDecoration( + color: AppColor.secondaryColor, + border: Border.all(), + borderRadius: BorderRadius.circular(15)), + child: IconButton( + onPressed: () async { + FirebaseMessagesController().sendNotificationToDriverMAP( + '', + 'from: ', + // jsonDecode(value)['message'].toString(), + 'cXavJMQgRACEfYdOnSLDU4:APA91bE_7aB5kLUcCgolp6BTy3girf7NCxR49dRt9wMDCu3C3td9V-KwZqsbJvYyIqgkI9oxZCiqyVv9ZnVG7rN0LBf7Nxe9AEcatgHNo0fEomaMWB3ff_SagtNkUuYeHc-GaPETq6Oa', + [], + 'order.wav' + + // polylineCoordinates.toString() + ); + }, + icon: const Icon( + Icons.chat, + size: 29, + ), + ), + ), // AnimatedContainer( // duration: const Duration(microseconds: 200), // width: controller.widthMapTypeAndTraffic, diff --git a/lib/views/widgets/my_dialog.dart b/lib/views/widgets/my_dialog.dart index 5fb23b7..0608a88 100644 --- a/lib/views/widgets/my_dialog.dart +++ b/lib/views/widgets/my_dialog.dart @@ -14,6 +14,7 @@ class MyDialog extends GetxController { Get.defaultDialog( title: title, titleStyle: AppStyle.title, + barrierDismissible: false, middleTextStyle: AppStyle.title, content: Column( children: [ diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 670b3e4..9f840d8 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 643B04D2AB43F88CA67B4296 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DDF4384B47D24C01FF9439DD /* GoogleService-Info.plist */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -64,7 +65,7 @@ 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* ride.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ride.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* ride.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ride.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -78,6 +79,7 @@ 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + DDF4384B47D24C01FF9439DD /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -125,6 +127,7 @@ 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + DDF4384B47D24C01FF9439DD /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -284,6 +287,7 @@ files = ( 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + 643B04D2AB43F88CA67B4296 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/macos/Runner/GoogleService-Info.plist b/macos/Runner/GoogleService-Info.plist index a9e1b89..e61bc7a 100644 --- a/macos/Runner/GoogleService-Info.plist +++ b/macos/Runner/GoogleService-Info.plist @@ -3,9 +3,11 @@ CLIENT_ID - 594687661098-od4d3lpsdba79shpjmala0a3lrps4spi.apps.googleusercontent.com + 594687661098-8e26699cris2k3nj5msj1osi59it9kpf.apps.googleusercontent.com REVERSED_CLIENT_ID - com.googleusercontent.apps.594687661098-od4d3lpsdba79shpjmala0a3lrps4spi + com.googleusercontent.apps.594687661098-8e26699cris2k3nj5msj1osi59it9kpf + ANDROID_CLIENT_ID + 594687661098-2dhoogl7be9phobfbu8bbg1sj567iv88.apps.googleusercontent.com API_KEY AIzaSyCf2mW2h0HD8ZYjwh4VOa2ladw6MJkCDTM GCM_SENDER_ID @@ -13,7 +15,7 @@ PLIST_VERSION 1 BUNDLE_ID - com.mobileapp.store.ride.RunnerTests + com.mobileapp.store.ride PROJECT_ID ride-b1bd8 STORAGE_BUCKET @@ -29,6 +31,6 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:594687661098:ios:e8ca02ed508d4737595f53 + 1:594687661098:ios:6f69eee1449be943595f53 \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index bebc317..f445950 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -389,10 +389,10 @@ packages: dependency: transitive description: name: file_selector_windows - sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0 + sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69" url: "https://pub.dev" source: hosted - version: "0.9.3+1" + version: "0.9.3+2" firebase_auth: dependency: "direct main" description: @@ -482,10 +482,10 @@ packages: dependency: transitive description: name: flutter_cache_manager - sha256: "395d6b7831f21f3b989ebedbb785545932adb9afe2622c1ffacf7f4b53a7e544" + sha256: ceff65d74d907b1b772e22cf04daad60fb472461638977d9fae8b00a63e01e3d url: "https://pub.dev" source: hosted - version: "3.3.2" + version: "3.3.3" flutter_font_icons: dependency: "direct main" description: @@ -1004,10 +1004,10 @@ packages: dependency: transitive description: name: image_picker_android - sha256: cea2bd5b9fcff039a4901d3b13c67fe747f940be9ba76bde1bcd218d168eeb7f + sha256: a26dc9a03fe042440c1e4be554fb0fceae2bf6d887d7467fc48c688fa4a81889 url: "https://pub.dev" source: hosted - version: "0.8.12+6" + version: "0.8.12+7" image_picker_for_web: dependency: transitive description: @@ -1188,10 +1188,10 @@ packages: dependency: transitive description: name: local_auth_windows - sha256: "505ba3367ca781efb1c50d3132e44a2446bccc4163427bc203b9b4d8994d97ea" + sha256: bc4e66a29b0fdf751aafbec923b5bed7ad6ed3614875d8151afe2578520b2ab5 url: "https://pub.dev" source: hosted - version: "1.0.10" + version: "1.0.11" location: dependency: "direct main" description: @@ -1532,10 +1532,10 @@ packages: dependency: transitive description: name: rxdart - sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" url: "https://pub.dev" source: hosted - version: "0.27.7" + version: "0.28.0" sanitize_html: dependency: transitive description: @@ -1832,10 +1832,10 @@ packages: dependency: transitive description: name: url_launcher_windows - sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 + sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" uuid: dependency: transitive description: