diff --git a/.vscode/launch.json b/.vscode/launch.json index 7157bcd..5f2d9f7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,25 +1,33 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Ride", - "request": "launch", - "type": "dart" - }, - { - "name": "Ride (profile mode)", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "Ride (release mode)", - "request": "launch", - "type": "dart", - "flutterMode": "release" - } - ] -} \ No newline at end of file + "version": "0.2.0", + "configurations": [ + { + "name": "Ride", + "request": "launch", + "type": "dart", + "logCatArguments": ["-s", "flutter", "-v", "error"] + }, + { + "name": "Ride (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile", + "logCatArguments": ["-s", "flutter", "-v", "error"] + }, + { + "name": "Ride (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release", + "logCatArguments": ["-s", "flutter", "-v", "error"] + }, + { + "name": "driver_sefer (Flutter)", + "program": "lib/main.dart", + "request": "launch", + "type": "dart", + // "args": ["--verbose", "--no-sound-null-safety"], + "logCatArguments": ["-s", "flutter", "-v", "error"] + } + ] +} diff --git a/android/app/build.gradle b/android/app/build.gradle index 8f7ee31..8f9f263 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 = 90 - versionName = '1.5.90`' + versionCode = 94 + versionName = '1.5.94' multiDexEnabled =true } diff --git a/android/app/src/main/res/drawable/launcher_icon.png b/android/app/src/main/res/drawable/launcher_icon.png index ce698d8..cb1d9cd 100644 Binary files a/android/app/src/main/res/drawable/launcher_icon.png and b/android/app/src/main/res/drawable/launcher_icon.png differ diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 0108f81..b49c983 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -33,7 +33,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 58 + 61 CFBundleSignature ???? CFBundleURLTypes @@ -48,7 +48,7 @@ CFBundleVersion - 4.0.58 + 4.0.61 FirebaseAppDelegateProxyEnabled NO GMSApiKey diff --git a/lib/constant/box_name.dart b/lib/constant/box_name.dart index 9dbb404..6817d85 100644 --- a/lib/constant/box_name.dart +++ b/lib/constant/box_name.dart @@ -42,6 +42,7 @@ class BoxName { static const String passengerID = "pasengerID"; static const String phone = "phone"; static const String phoneDriver = "phoneDriver"; + static const String lastOtpTime = "lastOtpTime"; static const String bankCodeDriver = "bankCodeDriver"; static const String accountBankNumberDriver = "accountBankNumberDriver"; static const String dobDriver = "dobDriver"; diff --git a/lib/constant/links.dart b/lib/constant/links.dart index 4068bd7..8be5015 100644 --- a/lib/constant/links.dart +++ b/lib/constant/links.dart @@ -128,7 +128,8 @@ class AppLink { static String addWaitingRide = "$ride/notificationCaptain/addWaitingRide.php"; static String updateWaitingRide = "$ride/notificationCaptain/updateWaitingTrip.php"; - static String getRideWaiting = "$ride/notificationCaptain/getRideWaiting.php"; + static String getRideWaiting = + "$endPoint/ride/notificationCaptain/getRideWaiting.php"; static String getNotificationCaptain = "$ride/notificationCaptain/get.php"; static String updateNotificationCaptain = "$ride/notificationCaptain/update.php"; diff --git a/lib/controller/auth/captin/login_captin_controller.dart b/lib/controller/auth/captin/login_captin_controller.dart index 4cd34d9..d9f3d8e 100644 --- a/lib/controller/auth/captin/login_captin_controller.dart +++ b/lib/controller/auth/captin/login_captin_controller.dart @@ -112,6 +112,22 @@ class LoginDriverController extends GetxController { 'token': box.read(BoxName.tokenDriver), 'captain_id': box.read(BoxName.driverID).toString() }); + CRUD().post( + link: + "${AppLink.seferAlexandriaServer}/ride/firebase/addDriver.php", + payload: { + 'token': box.read(BoxName.tokenDriver), + 'captain_id': + box.read(BoxName.driverID).toString() + }); + CRUD().post( + link: + "${AppLink.seferGizaServer}/ride/firebase/addDriver.php", + payload: { + 'token': box.read(BoxName.tokenDriver), + 'captain_id': + box.read(BoxName.driverID).toString() + }); Get.back(); })); } @@ -139,5 +155,17 @@ class LoginDriverController extends GetxController { 'token': box.read(BoxName.tokenDriver).toString(), 'captain_id': box.read(BoxName.driverID).toString() }); + CRUD().post( + link: "${AppLink.seferAlexandriaServer}/ride/firebase/addDriver.php", + payload: { + 'token': box.read(BoxName.tokenDriver), + 'captain_id': box.read(BoxName.driverID).toString() + }); + CRUD().post( + link: "${AppLink.seferGizaServer}/ride/firebase/addDriver.php", + payload: { + 'token': box.read(BoxName.tokenDriver), + 'captain_id': box.read(BoxName.driverID).toString() + }); } } diff --git a/lib/controller/auth/captin/register_captin_controller.dart b/lib/controller/auth/captin/register_captin_controller.dart index 95ea1eb..bd41b19 100644 --- a/lib/controller/auth/captin/register_captin_controller.dart +++ b/lib/controller/auth/captin/register_captin_controller.dart @@ -94,13 +94,96 @@ 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), + // }); + + // await smsEgyptController.sendSmsEgypt( + // phoneController.text.toString(), randomNumber.toString()); + + // 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), + // }); + + // await smsEgyptController.sendSmsEgypt( + // phoneController.text.toString(), randomNumber.toString()); + + // isSent = true; + + // isLoading = false; + // update(); + // } + // } else { + // Get.snackbar('Phone Number wrong'.tr, '', + // backgroundColor: AppColor.redColor); + // } + // } + // } + // isLoading = false; + // update(); + // } sendOtpMessage() async { SmsEgyptController smsEgyptController = Get.put(SmsEgyptController()); isLoading = true; update(); + int randomNumber = Random().nextInt(100000) + 1; isLoading = true; update(); + + // Get the current time and the last OTP time (if it exists) + DateTime currentTime = DateTime.now(); + DateTime? lastOtpTime = box.read(BoxName.lastOtpTime); + + // Check if the last OTP was sent within 5 minutes (300 seconds) + if (lastOtpTime != null && + currentTime.difference(lastOtpTime).inSeconds < 300) { + Get.snackbar( + 'Please wait'.tr, 'You can send another OTP after 5 minutes.'.tr, + backgroundColor: AppColor.redColor); + isLoading = false; + update(); + return; + } + if (formKey3.currentState!.validate()) { if (box.read(BoxName.countryCode) == 'Egypt') { if (isValidEgyptianPhoneNumber(phoneController.text)) { @@ -108,6 +191,7 @@ class RegisterCaptainController extends GetxController { .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') { @@ -120,36 +204,10 @@ class RegisterCaptainController extends GetxController { 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()); - - isSent = true; - - isLoading = false; - update(); + await _sendOtp(randomNumber, smsEgyptController); } } 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()); - - isSent = true; - - isLoading = false; - update(); + await _sendOtp(randomNumber, smsEgyptController); } } else { Get.snackbar('Phone Number wrong'.tr, '', @@ -157,6 +215,26 @@ class RegisterCaptainController extends GetxController { } } } + + isLoading = false; + update(); + } + + _sendOtp(int randomNumber, SmsEgyptController smsEgyptController) async { + 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()); + + // Save the current time as the last OTP time + box.write(BoxName.lastOtpTime, DateTime.now()); + + isSent = true; isLoading = false; update(); } diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart index 658eebb..724b99c 100644 --- a/lib/controller/firebase/firbase_messge.dart +++ b/lib/controller/firebase/firbase_messge.dart @@ -551,80 +551,8 @@ class FirebaseMessagesController extends GetxController { // } //android/app/src/main/res/raw/iphone_ringtone.wav void sendNotificationToPassengerToken( - String title, body, token, List map, String tone) async { - try { - String serviceAccountKeyJson = '''{ - "type": "service_account", - "project_id": "ride-b1bd8", - "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249", - "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n", - "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com", - "client_id": "111210077025005706623", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com", - "universe_domain": "googleapis.com" -} -'''; // As defined above - - // Initialize AccessTokenManager - final accessTokenManager = AccessTokenManager(serviceAccountKeyJson); - - // Obtain an OAuth 2.0 access token - final accessToken = await accessTokenManager.getAccessToken(); - - // Send the notification - final response = await http.post( - Uri.parse( - 'https://fcm.googleapis.com/v1/projects/ride-b1bd8/messages:send'), - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer $accessToken', - }, - body: jsonEncode({ - 'message': { - 'token': token, - 'notification': { - 'title': title, - 'body': body, - }, - 'data': { - 'passengerList': map, - }, - 'android': { - 'priority': 'high', // Set priority to high - 'notification': { - 'sound': tone, - }, - }, - 'apns': { - 'headers': { - 'apns-priority': '10', // Set APNs priority to 10 - }, - 'payload': { - 'aps': { - 'sound': tone, - }, - }, - }, - }, - }), - ); - - if (response.statusCode == 200) { - // Notification sent successfully - } else { - // Handle error response - 'Failed to send notification. Status code: ${response.statusCode}'; - } - } catch (e) { - // Handle other exceptions - } - } - - void sendNotificationToPassengerTokenCALL( - String title, body, token, List map, String tone) async { + String title, body, token, List map, String tone, + {int retryCount = 2}) async { try { String serviceAccountKeyJson = '''{ "type": "service_account", @@ -692,15 +620,31 @@ class FirebaseMessagesController extends GetxController { } else { print( 'Failed to send notification. Status code: ${response.statusCode}'); + print('Response body: ${response.body}'); + if (retryCount > 0) { + print('Retrying... Attempts remaining: $retryCount'); + await Future.delayed( + const Duration(seconds: 2)); // Optional delay before retrying + return sendNotificationToPassengerToken(title, body, token, map, tone, + retryCount: retryCount - 1); + } } } catch (e) { print('Error sending notification: $e'); + if (retryCount > 0) { + print('Retrying... Attempts remaining: $retryCount'); + await Future.delayed( + const Duration(seconds: 2)); // Optional delay before retrying + return sendNotificationToPassengerToken(title, body, token, map, tone, + retryCount: retryCount - 1); + } } } - void sendNotificationToAnyWithoutData( - String title, String body, String token, String tone) async { + void sendNotificationToPassengerTokenCALL( + String title, body, token, List map, String tone, + {int retryCount = 2}) async { try { String serviceAccountKeyJson = '''{ "type": "service_account", @@ -739,7 +683,7 @@ class FirebaseMessagesController extends GetxController { 'body': body, }, 'data': { - 'DriverList': jsonEncode([]), + 'passengerList': jsonEncode(map), }, 'android': { 'priority': 'high', // Set priority to high @@ -768,15 +712,125 @@ class FirebaseMessagesController extends GetxController { } else { print( 'Failed to send notification. Status code: ${response.statusCode}'); + print('Response body: ${response.body}'); + if (retryCount > 0) { + print('Retrying... Attempts remaining: $retryCount'); + await Future.delayed( + const Duration(seconds: 2)); // Optional delay before retrying + return sendNotificationToPassengerTokenCALL( + title, body, token, map, tone, + retryCount: retryCount - 1); + } } } catch (e) { print('Error sending notification: $e'); + if (retryCount > 0) { + print('Retrying... Attempts remaining: $retryCount'); + await Future.delayed( + const Duration(seconds: 2)); // Optional delay before retrying + return sendNotificationToPassengerTokenCALL( + title, body, token, map, tone, + retryCount: retryCount - 1); + } } } - void sendNotificationToDriverMAP(String title, String body, String token, - List data, String tone) async { + void sendNotificationToAnyWithoutData( + String title, String body, String token, String tone, + {int retryCount = 2}) async { + try { + String serviceAccountKeyJson = '''{ + "type": "service_account", + "project_id": "ride-b1bd8", + "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249", + "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n", + "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com", + "client_id": "111210077025005706623", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com", + "universe_domain": "googleapis.com" +} +'''; // As defined above + + // Initialize AccessTokenManager + final accessTokenManager = AccessTokenManager(serviceAccountKeyJson); + + // Obtain an OAuth 2.0 access token + final accessToken = await accessTokenManager.getAccessToken(); + + // Send the notification + final response = await http.post( + Uri.parse( + 'https://fcm.googleapis.com/v1/projects/ride-b1bd8/messages:send'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer $accessToken', + }, + body: jsonEncode({ + 'message': { + 'token': token, + 'notification': { + 'title': title, + 'body': body, + }, + // 'data': { + // 'DriverList': jsonEncode([]), + // }, + 'android': { + 'priority': 'high', // Set priority to high + 'notification': { + 'sound': tone, + }, + }, + 'apns': { + 'headers': { + 'apns-priority': '10', // Set APNs priority to 10 + }, + 'payload': { + 'aps': { + 'sound': tone, + }, + }, + }, + }, + }), + ); + + if (response.statusCode == 200) { + print( + 'Notification sent successfully. Status code: ${response.statusCode}'); + print('Response body: ${response.body}'); + } else { + print( + 'Failed to send notification. Status code: ${response.statusCode}'); + + print('Response body: ${response.body}'); + if (retryCount > 0) { + print('Retrying... Attempts remaining: $retryCount'); + await Future.delayed( + const Duration(seconds: 2)); // Optional delay before retrying + return sendNotificationToAnyWithoutData(title, body, token, tone, + retryCount: retryCount - 1); + } + } + } catch (e) { + print('Error sending notification: $e'); + if (retryCount > 0) { + print('Retrying... Attempts remaining: $retryCount'); + await Future.delayed( + const Duration(seconds: 2)); // Optional delay before retrying + return sendNotificationToAnyWithoutData(title, body, token, tone, + retryCount: retryCount - 1); + } + } + } + + void sendNotificationToDriverMAP( + String title, String body, String token, List data, String tone, + {int retryCount = 2}) async { try { String serviceAccountKeyJson = '''{ "type": "service_account", @@ -844,10 +898,27 @@ class FirebaseMessagesController extends GetxController { } else { print( 'Failed to send notification. Status code: ${response.statusCode}'); + print('Response body: ${response.body}'); + if (retryCount > 0) { + print('Retrying... Attempts remaining: $retryCount'); + await Future.delayed( + const Duration(seconds: 2)); // Optional delay before retrying + return sendNotificationToPassengerTokenCALL( + title, body, token, data, tone, + retryCount: retryCount - 1); + } } } catch (e) { print('Error sending notification: $e'); + if (retryCount > 0) { + print('Retrying... Attempts remaining: $retryCount'); + await Future.delayed( + const Duration(seconds: 2)); // Optional delay before retrying + return sendNotificationToPassengerTokenCALL( + title, body, token, data, tone, + retryCount: retryCount - 1); + } } } @@ -935,19 +1006,19 @@ class OverlayContent extends StatelessWidget { Widget build(BuildContext context) { return Material( child: Container( - padding: EdgeInsets.all(16.0), + padding: const EdgeInsets.all(16.0), color: Colors.white, child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( title, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), - SizedBox(height: 8.0), + const SizedBox(height: 8.0), Text( body, - style: TextStyle(fontSize: 16), + style: const TextStyle(fontSize: 16), ), ], ), diff --git a/lib/controller/firebase/local_notification.dart b/lib/controller/firebase/local_notification.dart index f28f0c5..cc4fa69 100644 --- a/lib/controller/firebase/local_notification.dart +++ b/lib/controller/firebase/local_notification.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:typed_data'; import 'package:SEFER/constant/colors.dart'; import 'package:SEFER/views/home/Captin/orderCaptin/order_request_page.dart'; @@ -31,11 +32,10 @@ class NotificationController extends GetxController { // Create a notification channel const AndroidNotificationChannel channel = AndroidNotificationChannel( - 'dynamic_channel', // Channel ID - 'Dynamic Notifications', // Channel name - description: - 'This channel is used for various types of notifications.', // Channel description - importance: Importance.max, + 'high_importance_channel', + 'High Importance Notifications', + description: 'This channel is used for important notifications.', + importance: Importance.high, ); // Register the channel with the system @@ -55,31 +55,36 @@ class NotificationController extends GetxController { htmlFormatContentTitle: true, ); - AndroidNotificationDetails android = - AndroidNotificationDetails('dynamic_channel', 'Dynamic Notifications', - importance: Importance.max, - priority: Priority.high, - styleInformation: bigTextStyleInformation, - playSound: true, - sound: RawResourceAndroidNotificationSound(tone), - audioAttributesUsage: AudioAttributesUsage.alarm, - visibility: NotificationVisibility.public, - autoCancel: false, - color: AppColor.primaryColor, - showProgress: true, - showWhen: true, - timeoutAfter: title == 'Order' ? 14500 : 6000, - subText: message, - actions: [ - AndroidNotificationAction( - allowGeneratedReplies: true, - 'id', - title.tr, - titleColor: AppColor.bronze, - showsUserInterface: true, - ) - ], - category: AndroidNotificationCategory.call); + AndroidNotificationDetails android = AndroidNotificationDetails( + 'high_importance_channel', 'High Importance Notifications', + importance: Importance.high, + priority: Priority.high, + styleInformation: bigTextStyleInformation, + playSound: true, + sound: RawResourceAndroidNotificationSound(tone), + // audioAttributesUsage: AudioAttributesUsage.alarm, + visibility: NotificationVisibility.public, + autoCancel: false, + color: AppColor.primaryColor, + showProgress: true, + showWhen: true, + ongoing: true, + enableVibration: true, + vibrationPattern: Int64List.fromList([0, 1000, 500, 1000]), + timeoutAfter: 14500, + setAsGroupSummary: true, + subText: message, fullScreenIntent: true, + actions: [ + AndroidNotificationAction( + allowGeneratedReplies: true, + 'id', + title.tr, + titleColor: AppColor.bronze, + showsUserInterface: true, + ) + ], + category: AndroidNotificationCategory.progress, + ); NotificationDetails details = NotificationDetails(android: android); @@ -175,30 +180,30 @@ class NotificationController extends GetxController { } } -// class NotificationController extends GetxController { -// final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = -// FlutterLocalNotificationsPlugin(); +class NotificationController1 extends GetxController { + final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = + FlutterLocalNotificationsPlugin(); -// // Initializes the local notifications plugin -// Future initNotifications() async { -// const AndroidInitializationSettings android = -// AndroidInitializationSettings('@mipmap/launcher_icon'); -// const InitializationSettings initializationSettings = -// InitializationSettings(android: android); -// await _flutterLocalNotificationsPlugin.initialize(initializationSettings); -// } + // Initializes the local notifications plugin + Future initNotifications() async { + const AndroidInitializationSettings android = + AndroidInitializationSettings('@mipmap/launcher_icon'); + const InitializationSettings initializationSettings = + InitializationSettings(android: android); + await _flutterLocalNotificationsPlugin.initialize(initializationSettings); + } -// // Displays a notification with the given title and message -// void showNotification( -// String title, String message, String tone, String payLoad) async { -// AndroidNotificationDetails android = AndroidNotificationDetails( -// 'your channel id', 'your channel name', -// importance: Importance.max, -// priority: Priority.high, -// showWhen: false, -// sound: RawResourceAndroidNotificationSound(tone)); + // Displays a notification with the given title and message + void showNotification( + String title, String message, String tone, String payLoad) async { + AndroidNotificationDetails android = AndroidNotificationDetails( + 'your channel id', 'your channel name', + importance: Importance.max, + priority: Priority.high, + showWhen: false, + sound: RawResourceAndroidNotificationSound(tone)); -// NotificationDetails details = NotificationDetails(android: android); -// await _flutterLocalNotificationsPlugin.show(0, title, message, details); -// } -// } + NotificationDetails details = NotificationDetails(android: android); + await _flutterLocalNotificationsPlugin.show(0, title, message, details); + } +} diff --git a/lib/controller/functions/gemeni.dart b/lib/controller/functions/gemeni.dart index 3c75d33..ae6abd2 100644 --- a/lib/controller/functions/gemeni.dart +++ b/lib/controller/functions/gemeni.dart @@ -355,12 +355,12 @@ class AI extends GetxController { if (status1['status'] == 'success') { isDriverSaved = true; - // CRUD().post( - // link: '${AppLink.seferGizaServer}/auth/captin/register.php', - // payload: payload); - // CRUD().post( - // link: '${AppLink.seferAlexandriaServer}/auth/captin/register.php', - // payload: payload); + CRUD().post( + link: '${AppLink.seferGizaServer}/auth/captin/register.php', + payload: payload); + CRUD().post( + link: '${AppLink.seferAlexandriaServer}/auth/captin/register.php', + payload: payload); Get.snackbar('Success', 'Driver data saved successfully', backgroundColor: AppColor.greenColor); } else { @@ -416,55 +416,55 @@ class AI extends GetxController { isCarSaved = true; Get.snackbar('Success', 'message', backgroundColor: AppColor.greenColor); - // CRUD().post( - // link: - // '${AppLink.seferAlexandriaServer}/ride/RegisrationCar/add.php', - // payload: { - // 'driverID': box.read(BoxName.driverID), - // 'vin': responseIdCardDriverEgyptBack['chassis'].toString(), - // 'car_plate': - // responseIdCardDriverEgyptFront['car_plate'].toString(), - // 'make': responseIdCardDriverEgyptBack['make'].toString(), - // 'model': responseIdCardDriverEgyptBack['model'], - // 'year': responseIdCardDriverEgyptBack['year'].toString(), - // 'expiration_date': - // responseIdCardDriverEgyptFront['LicenseExpirationDate'] - // .toString(), - // 'color': responseIdCardDriverEgyptBack['color'], - // 'owner': responseIdCardDriverEgyptFront['owner'], - // 'color_hex': - // responseIdCardDriverEgyptBack['color_hex'].toString(), - // 'address': responseIdCardDriverEgyptFront['address'].toString(), - // 'displacement': - // responseIdCardDriverEgyptBack['engine'].toString(), - // 'fuel': responseIdCardDriverEgyptBack['fuel'].toString(), - // 'registration_date': - // '${responseIdCardDriverEgyptBack['inspection_date']}', - // }); - // CRUD().post( - // link: '${AppLink.seferGizaServer}/ride/RegisrationCar/add.php', - // payload: { - // 'driverID': box.read(BoxName.driverID), - // 'vin': responseIdCardDriverEgyptBack['chassis'].toString(), - // 'car_plate': - // responseIdCardDriverEgyptFront['car_plate'].toString(), - // 'make': responseIdCardDriverEgyptBack['make'].toString(), - // 'model': responseIdCardDriverEgyptBack['model'], - // 'year': responseIdCardDriverEgyptBack['year'].toString(), - // 'expiration_date': - // responseIdCardDriverEgyptFront['LicenseExpirationDate'] - // .toString(), - // 'color': responseIdCardDriverEgyptBack['color'], - // 'owner': responseIdCardDriverEgyptFront['owner'], - // 'color_hex': - // responseIdCardDriverEgyptBack['color_hex'].toString(), - // 'address': responseIdCardDriverEgyptFront['address'].toString(), - // 'displacement': - // responseIdCardDriverEgyptBack['engine'].toString(), - // 'fuel': responseIdCardDriverEgyptBack['fuel'].toString(), - // 'registration_date': - // '${responseIdCardDriverEgyptBack['inspection_date']}', - // }); + CRUD().post( + link: + '${AppLink.seferAlexandriaServer}/ride/RegisrationCar/add.php', + payload: { + 'driverID': box.read(BoxName.driverID), + 'vin': responseIdCardDriverEgyptBack['chassis'].toString(), + 'car_plate': + responseIdCardDriverEgyptFront['car_plate'].toString(), + 'make': responseIdCardDriverEgyptBack['make'].toString(), + 'model': responseIdCardDriverEgyptBack['model'], + 'year': responseIdCardDriverEgyptBack['year'].toString(), + 'expiration_date': + responseIdCardDriverEgyptFront['LicenseExpirationDate'] + .toString(), + 'color': responseIdCardDriverEgyptBack['color'], + 'owner': responseIdCardDriverEgyptFront['owner'], + 'color_hex': + responseIdCardDriverEgyptBack['color_hex'].toString(), + 'address': responseIdCardDriverEgyptFront['address'].toString(), + 'displacement': + responseIdCardDriverEgyptBack['engine'].toString(), + 'fuel': responseIdCardDriverEgyptBack['fuel'].toString(), + 'registration_date': + '${responseIdCardDriverEgyptBack['inspection_date']}', + }); + CRUD().post( + link: '${AppLink.seferGizaServer}/ride/RegisrationCar/add.php', + payload: { + 'driverID': box.read(BoxName.driverID), + 'vin': responseIdCardDriverEgyptBack['chassis'].toString(), + 'car_plate': + responseIdCardDriverEgyptFront['car_plate'].toString(), + 'make': responseIdCardDriverEgyptBack['make'].toString(), + 'model': responseIdCardDriverEgyptBack['model'], + 'year': responseIdCardDriverEgyptBack['year'].toString(), + 'expiration_date': + responseIdCardDriverEgyptFront['LicenseExpirationDate'] + .toString(), + 'color': responseIdCardDriverEgyptBack['color'], + 'owner': responseIdCardDriverEgyptFront['owner'], + 'color_hex': + responseIdCardDriverEgyptBack['color_hex'].toString(), + 'address': responseIdCardDriverEgyptFront['address'].toString(), + 'displacement': + responseIdCardDriverEgyptBack['engine'].toString(), + 'fuel': responseIdCardDriverEgyptBack['fuel'].toString(), + 'registration_date': + '${responseIdCardDriverEgyptBack['inspection_date']}', + }); } } catch (e) {} } diff --git a/lib/controller/functions/location_background_controller.dart b/lib/controller/functions/location_background_controller.dart index c5456ea..e822d5f 100644 --- a/lib/controller/functions/location_background_controller.dart +++ b/lib/controller/functions/location_background_controller.dart @@ -8,19 +8,13 @@ class LocationBackgroundController extends GetxController { void onInit() { super.onInit(); requestLocationPermission(); + configureBackgroundLocation(); } Future requestLocationPermission() async { var status = await Permission.locationAlways.status; if (!status.isGranted) { - status = await Permission.locationAlways.request(); - } - - if (status.isGranted) { - configureBackgroundLocation(); - } else { - // Handle permission denial - print("Location permission denied"); + await Permission.locationAlways.request(); } } @@ -31,36 +25,29 @@ class LocationBackgroundController extends GetxController { icon: '@mipmap/launcher_icon', ); - // Set the location update interval to 5 seconds - BackgroundLocation.setAndroidConfiguration(5000); + BackgroundLocation.setAndroidConfiguration(3000); BackgroundLocation.startLocationService(); - BackgroundLocation.getLocationUpdates((location) { // Handle location updates here - print("Latitude: ${location.latitude}, Longitude: ${location.longitude}"); - }); - - startBackLocation(); - } - - void startBackLocation() async { - Timer.periodic(const Duration(seconds: 5), (timer) async { - await getBackgroundLocation(); }); } - Future getBackgroundLocation() async { + startBackLocation() async { + Timer.periodic(const Duration(seconds: 3), (timer) { + getBackgroundLocation(); + }); + } + + getBackgroundLocation() async { var status = await Permission.locationAlways.status; if (status.isGranted) { - // The location service is already started in configureBackgroundLocation - // No need to call startLocationService again - BackgroundLocation.getLocationUpdates((location) { - // Handle location updates here - print( - "Latitude: ${location.latitude}, Longitude: ${location.longitude}"); - }); + await BackgroundLocation.startLocationService( + distanceFilter: 20, forceAndroidLocationManager: true); + BackgroundLocation.setAndroidConfiguration( + Duration.microsecondsPerSecond); // Set interval to 5 seconds + + BackgroundLocation.getLocationUpdates((location1) {}); } else { - // Request permission if not granted await Permission.locationAlways.request(); } } diff --git a/lib/controller/functions/location_controller.dart b/lib/controller/functions/location_controller.dart index 00f8937..9131754 100644 --- a/lib/controller/functions/location_controller.dart +++ b/lib/controller/functions/location_controller.dart @@ -53,7 +53,7 @@ class LocationController extends GetxController { } else if (latitude >= 29.904975 && latitude <= 30.143372 && longitude >= 30.787030 && - longitude <= 31.238843) { + longitude <= 31.215009) { return 'Giza'; } else if (latitude >= 30.396286 && latitude <= 31.654458 && @@ -61,7 +61,7 @@ class LocationController extends GetxController { longitude <= 32.626259) { return 'Alexandria'; } else { - return 'Outside'; + return 'Cairo'; } } @@ -102,15 +102,7 @@ class LocationController extends GetxController { endpoint = AppLink.addCarsLocationAlexandriaEndpoint; Log.print('Endpoint: $endpoint'); break; - case 'Outside': - // Handle cases outside of Cairo, Giza, and Alexandria - print('Location outside Cairo, Giza, or Alexandria'); - box.write(BoxName.serverChosen, AppLink.seferCairoServer); - endpoint = AppLink - .addCarsLocationCairoEndpoint; // Fallback to Cairo endpoint - Log.print('Fallback Endpoint: $endpoint'); - break; default: // Handle any other unexpected cases print('Unknown location area'); diff --git a/lib/controller/functions/location_permission.dart b/lib/controller/functions/location_permission.dart index 9bbf33c..98436f8 100644 --- a/lib/controller/functions/location_permission.dart +++ b/lib/controller/functions/location_permission.dart @@ -1,16 +1,60 @@ -import 'package:location/location.dart'; import 'package:get/get.dart'; +import 'package:permission_handler/permission_handler.dart'; + +import '../../constant/box_name.dart'; +import '../../main.dart'; +import '../../print.dart'; +import '../../views/widgets/mydialoug.dart'; +import '../auth/captin/login_captin_controller.dart'; class LocationPermissions { - late Location location; + // late Location location; - Future locationPermissions() async { - location = Location(); - var permissionStatus = await location.requestPermission(); - if (permissionStatus == PermissionStatus.denied) { - // The user denied the location permission. - Get.defaultDialog(title: 'GPS Required Allow !.'.tr, middleText: ''); - return null; - } + // Future locationPermissions() async { + // location = Location(); + // var permissionStatus = await location.requestPermission(); + // if (permissionStatus == PermissionStatus.denied) { + // // The user denied the location permission. + // Get.defaultDialog(title: 'GPS Required Allow !.'.tr, middleText: ''); + // return null; + // } + // } +} + +Future getPermissionLocation() async { + final PermissionStatus status = await Permission.locationAlways.status; + if (!await Permission.locationAlways.serviceStatus.isEnabled) { + Log.print('status.isGranted: ${status.isGranted}'); + // box.write(BoxName.locationPermission, 'true'); + await Permission.locationAlways.request(); + Get.put(LoginDriverController()).update(); + MyDialog().getDialog( + 'Enable Location Permission'.tr, // {en:ar} + 'Allowing location access will help us display orders near you. Please enable it now.' + .tr, // {en:ar} + () async { + Get.back(); + box.write(BoxName.locationPermission, 'true'); + await Permission.locationAlways.request(); + }, + ); + } +} + +Future getPermissionLocation1() async { + PermissionStatus status = await Permission.locationWhenInUse.request(); + + if (status.isGranted) { + // After granting when in use, request "always" location permission + status = await Permission.locationAlways.request(); + + if (status.isGranted) { + print("Background location permission granted"); + } else { + print("Background location permission denied"); + } + } else { + print("Location permission denied"); + await openAppSettings(); } } diff --git a/lib/controller/functions/overlay_permisssion.dart b/lib/controller/functions/overlay_permisssion.dart index 032d89d..4088f93 100644 --- a/lib/controller/functions/overlay_permisssion.dart +++ b/lib/controller/functions/overlay_permisssion.dart @@ -3,10 +3,12 @@ import 'dart:io'; import 'package:SEFER/views/widgets/mydialoug.dart'; import 'package:flutter_overlay_window/flutter_overlay_window.dart'; import 'package:get/get.dart'; -import 'package:permission_handler/permission_handler.dart'; +import 'package:location/location.dart'; +// import 'package:permission_handler/permission_handler.dart'; import '../../constant/box_name.dart'; import '../../main.dart'; +import '../../print.dart'; import '../auth/captin/login_captin_controller.dart'; Future getPermissionOverlay() async { @@ -26,24 +28,55 @@ Future getPermissionOverlay() async { } } -Future getPermissionLocation() async { - final PermissionStatus status = await Permission.location.status; - if (!status.isGranted) { - // Log.print('status.isGranted: ${status.isGranted}'); - box.write(BoxName.locationPermission, 'true'); - await Permission.location.request(); - Get.find().update(); - // MyDialog().getDialog( - // 'Enable Location Permission'.tr, // {en:ar} - // 'Allowing location access will help us display orders near you. Please enable it now.' - // .tr, // {en:ar} - // () async { - // Get.back(); - // box.write(BoxName.locationPermission, 'true'); - // await Permission.location.request(); - // }, - // ); +// Future getPermissionLocation() async { +// // final PermissionStatus status = await Permission.location.status; +// // if (!status.isGranted) { +// // Log.print('status.isGranted: ${status.isGranted}'); +// // // box.write(BoxName.locationPermission, 'true'); +// // await Permission.location.request(); +// // Get.find().update(); +// // MyDialog().getDialog( +// // 'Enable Location Permission'.tr, // {en:ar} +// // 'Allowing location access will help us display orders near you. Please enable it now.' +// // .tr, // {en:ar} +// // () async { +// // Get.back(); +// // box.write(BoxName.locationPermission, 'true'); +// // await Permission.location.request(); +// // }, +// // ); +// // } +// } +final location = Location(); +Future getLocationPermission() async { + bool serviceEnabled; + PermissionStatus permissionGranted; + + // Check if location services are enabled + serviceEnabled = await location.serviceEnabled(); + if (!serviceEnabled) { + serviceEnabled = await location.requestService(); + if (!serviceEnabled) { + // Location services are still not enabled, handle the error + return; + } } + + // Check if the app has permission to access location + permissionGranted = await location.hasPermission(); + if (permissionGranted == PermissionStatus.denied) { + permissionGranted = await location.requestPermission(); + if (permissionGranted != PermissionStatus.granted) { + // Location permission is still not granted, handle the error + permissionGranted = await location.requestPermission(); + return; + } + } + if (permissionGranted.toString() == 'PermissionStatus.granted') { + box.write(BoxName.locationPermission, 'true'); + Get.find().update(); + } + // update(); } Future getOverLay(String myListString) async { diff --git a/lib/controller/home/captin/home_captain_controller.dart b/lib/controller/home/captin/home_captain_controller.dart index d7c5633..1f30941 100644 --- a/lib/controller/home/captin/home_captain_controller.dart +++ b/lib/controller/home/captin/home_captain_controller.dart @@ -240,6 +240,18 @@ class HomeCaptainController extends GetxController { 'token': box.read(BoxName.tokenDriver), 'captain_id': box.read(BoxName.driverID).toString() }); + CRUD().post( + link: "${AppLink.seferAlexandriaServer}/ride/firebase/addDriver.php", + payload: { + 'token': box.read(BoxName.tokenDriver), + 'captain_id': box.read(BoxName.driverID).toString() + }); + CRUD().post( + link: "${AppLink.seferGizaServer}/ride/firebase/addDriver.php", + payload: { + 'token': box.read(BoxName.tokenDriver), + 'captain_id': box.read(BoxName.driverID).toString() + }); MapDriverController().driverCallPassenger(); // box.write(BoxName.statusDriverLocation, 'off'); } diff --git a/lib/controller/home/captin/order_request_controller.dart b/lib/controller/home/captin/order_request_controller.dart index 25971af..76c9a9d 100644 --- a/lib/controller/home/captin/order_request_controller.dart +++ b/lib/controller/home/captin/order_request_controller.dart @@ -184,6 +184,20 @@ class OrderRequestController extends GetxController { 'status': 'Refused', 'driver_id': box.read(BoxName.driverID), }); + CRUD().post( + link: '${AppLink.seferAlexandriaServer}/rides/update.php', + payload: { + 'id': orderID, + // 'rideTimeStart': DateTime.now().toString(), + 'status': 'Refused', + 'driver_id': box.read(BoxName.driverID), + }); + CRUD().post(link: '${AppLink.seferGizaServer}/rides/update.php', payload: { + 'id': orderID, + // 'rideTimeStart': DateTime.now().toString(), + 'status': 'Refused', + 'driver_id': box.read(BoxName.driverID), + }); // applied = true; // if (box.read(BoxName.gender).toString() != 'Female') { @@ -229,5 +243,41 @@ class OrderRequestController extends GetxController { 'distance': distance, 'duration': duration, }); + CRUD().post( + link: + '${AppLink.seferAlexandriaServer}/notificationCaptain/addWaitingRide.php', + payload: { + 'id': orderID, + 'start_location': startLocation, + 'end_location': endLocation, + 'date': date, + 'time': time, + 'price': price, + 'passenger_id': passengerId, + 'status': status, + 'carType': carType, + 'passengerRate': passengerRate, + 'price_for_passenger': priceForPassenger, + 'distance': distance, + 'duration': duration, + }); + CRUD().post( + link: + '${AppLink.seferGizaServer}/notificationCaptain/addWaitingRide.php', + payload: { + 'id': orderID, + 'start_location': startLocation, + 'end_location': endLocation, + 'date': date, + 'time': time, + 'price': price, + 'passenger_id': passengerId, + 'status': status, + 'carType': carType, + 'passengerRate': passengerRate, + 'price_for_passenger': priceForPassenger, + 'distance': distance, + 'duration': duration, + }); } } diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart index c562094..f3eeda5 100644 --- a/lib/controller/local/translations.dart +++ b/lib/controller/local/translations.dart @@ -154,6 +154,7 @@ class MyTranslation extends Translations { "لقد اخترت التأمين الصحي بنجاح.", "Please enter a health insurance status.": "يرجى إدخال حالة التأمين الصحي", + "Sefer Driver": "سفر السائق", "The 3000 points equal 3000 L.E for you \nSo go and gain your money": "3000 نقطة تساوي 3000 جنيه لك \nلذا اذهب واحصل على أموالك", "Info": "معلومات", diff --git a/lib/controller/rate/rate_conroller.dart b/lib/controller/rate/rate_conroller.dart index f73f1df..780dabe 100644 --- a/lib/controller/rate/rate_conroller.dart +++ b/lib/controller/rate/rate_conroller.dart @@ -127,7 +127,24 @@ class RateController extends GetxController { middleText: '', confirm: MyElevatedButton(title: 'Ok', onPressed: () => Get.back())); } else { - await CRUD().post(link: AppLink.addRateToPassenger, payload: { + await CRUD() + .post(link: "${AppLink.seferCairoServer}/rate/add.php", payload: { + 'passenger_id': passengerId, + 'driverID': box.read(BoxName.driverID).toString(), + 'rideId': rideId, + 'rating': selectedRateItemId.toString(), + 'comment': comment.text, + }); + CRUD().post( + link: "${AppLink.seferAlexandriaServer}/rate/add.php", + payload: { + 'passenger_id': passengerId, + 'driverID': box.read(BoxName.driverID).toString(), + 'rideId': rideId, + 'rating': selectedRateItemId.toString(), + 'comment': comment.text, + }); + CRUD().post(link: AppLink.seferGizaServer, payload: { 'passenger_id': passengerId, 'driverID': box.read(BoxName.driverID).toString(), 'rideId': rideId, diff --git a/lib/main.dart b/lib/main.dart index f1cc48a..86bcb69 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -130,6 +130,7 @@ void main() async { FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); NotificationController().initNotifications(); + NotificationController1().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 d57fe1f..452d90d 100644 --- a/lib/views/auth/captin/login_captin.dart +++ b/lib/views/auth/captin/login_captin.dart @@ -14,6 +14,7 @@ import '../../../constant/style.dart'; import '../../../controller/auth/apple_sigin.dart'; import '../../../controller/auth/captin/login_captin_controller.dart'; import '../../../controller/auth/google_sign.dart'; +import '../../../controller/functions/location_permission.dart'; import '../../../controller/functions/overlay_permisssion.dart'; import '../../../main.dart'; import '../../widgets/elevated_btn.dart'; @@ -416,7 +417,9 @@ class LoginCaptin extends StatelessWidget { await Permission.location.status; if (!status.isGranted) { // WidgetsBinding.instance.addPostFrameCallback((_) { - getPermissionLocation(); + // getPermissionLocation(); + // getPermissionLocation(); + getLocationPermission(); // }); return; } diff --git a/lib/views/home/Captin/home_captain/home_captin.dart b/lib/views/home/Captin/home_captain/home_captin.dart index 1b9cab8..fb92fc8 100644 --- a/lib/views/home/Captin/home_captain/home_captin.dart +++ b/lib/views/home/Captin/home_captain/home_captin.dart @@ -16,6 +16,7 @@ import '../../../../constant/colors.dart'; import '../../../../constant/info.dart'; import '../../../../constant/style.dart'; import '../../../../controller/functions/location_controller.dart'; +import '../../../../controller/functions/location_permission.dart'; import '../../../../controller/functions/overlay_permisssion.dart'; import '../../../../controller/functions/package_info.dart'; import '../../../../controller/home/captin/home_captain_controller.dart'; @@ -41,6 +42,7 @@ class HomeCaptain extends StatelessWidget { WidgetsBinding.instance.addPostFrameCallback((_) { checkForUpdate(context); getPermissionOverlay(); + // getPermissionLocation1(); _showFirstTimeOfferNotification(context); }); return Scaffold( 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 94c1764..f426df2 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 @@ -13,6 +13,8 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; import '../../../../../constant/colors.dart'; import '../../../../../constant/links.dart'; import '../../../../../controller/firebase/firbase_messge.dart'; +import '../../../../../controller/functions/location_permission.dart'; +import '../../../../../controller/functions/overlay_permisssion.dart'; import '../../../../../print.dart'; import '../../../../Rate/ride_calculate_driver.dart'; import '../../../../../controller/functions/location_controller.dart'; @@ -140,6 +142,8 @@ GetBuilder leftMainMenuCaptainIcons() { borderRadius: BorderRadius.circular(15)), child: IconButton( onPressed: () { + NotificationController() + .showNotification('Sefer Driver'.tr, ''.tr, '', ''); final now = DateTime.now(); DateTime? lastRequestTime = box.read(BoxName.lastTimeStaticThrottle); @@ -155,8 +159,13 @@ GetBuilder leftMainMenuCaptainIcons() { // Optionally show a message or handle the throttling case final minutesLeft = 2 - now.difference(lastRequestTime).inMinutes; - Get.snackbar( + // 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', ''); } }, @@ -266,17 +275,21 @@ GetBuilder leftMainMenuCaptainIcons() { // child: Builder(builder: (context) { // return IconButton( // onPressed: () async { - // FirebaseMessagesController().sendNotificationToAnyWithoutData( - // 'Order'.tr, - // 'from: ', - // // jsonDecode(value)['message'].toString(), - // 'dEugS-JOT4Ka5riF4s5TEN:APA91bEDL_W7BuEQGbyL-RMaKiMWDlURXhFuaybe5WurTUV8K5eIooSGe22yY22_U2hEZcfPr46ig1v--l00dbOGiivazxvmTyhUyQQW6lJsuIN-wordGtBxtREyeYtEKvxIa1J4ApEu', - // 'order.wav' - - // // polylineCoordinates.toString() - // ); + // // FirebaseMessagesController().sendNotificationToAnyWithoutData( + // // 'Order'.tr, + // // 'from: ', + // // // jsonDecode(value)['message'].toString(), + // // 'dqK5wNrPTr20HQ8qa5KsgL:APA91bHwPW_XzCIxQtg_IkJmHg1JRd8NRMquvsgedBaHAIgErTs6Uzpw1IX0EIJqkTaZq5dxd1u2z7NVdLlvcmEzrpjjWt1pUsZaa5UU7Cpx6hUzJMUdXvhNlAYFGklM8bWUG4ZXSRf1', + // // 'order.wav'); + // // NotificationController().showNotification( + // // 'Order'.tr, + // // 'We regret to inform you that another driver has accepted this order.' + // // .tr, + // // 'order', + // // ''); + // // requestLocationPermission(); // // Get.to(SmsSignupEgypt()); - // // print(AppLink.addDriverPaymentPoints); + // // print(box.read(BoxName.tokenDriver)); // }, // icon: const Icon( // FontAwesome5.closed_captioning, diff --git a/lib/views/home/Captin/orderCaptin/order_over_lay.dart b/lib/views/home/Captin/orderCaptin/order_over_lay.dart index 9436cc7..c58f67e 100644 --- a/lib/views/home/Captin/orderCaptin/order_over_lay.dart +++ b/lib/views/home/Captin/orderCaptin/order_over_lay.dart @@ -5,7 +5,9 @@ import 'package:flutter_overlay_window/flutter_overlay_window.dart'; import 'package:get/get.dart'; import 'package:just_audio/just_audio.dart'; import '../../../../constant/box_name.dart'; +import '../../../../constant/links.dart'; import '../../../../constant/style.dart'; +import '../../../../controller/functions/crud.dart'; import '../../../../main.dart'; class OrderOverlay extends StatefulWidget { @@ -111,6 +113,56 @@ class _OrderOverlayState extends State super.dispose(); } + void refuseOrder( + orderID, + ) async { + await CRUD().postFromDialogue(link: AppLink.addDriverOrder, payload: { + //TODO need review + 'driver_id': box.read(BoxName.driverID), + // box.read(BoxName.driverID).toString(), + 'order_id': orderID, + 'status': 'Refused' + }); + await CRUD().post(link: AppLink.updateRides, payload: { + 'id': orderID, + // 'rideTimeStart': DateTime.now().toString(), + 'status': 'Refused', + 'driver_id': box.read(BoxName.driverID), + }); + } + + addRideToNotificationDriverString( + orderID, + String startLocation, + String endLocation, + String date, + String time, + String price, + String passengerId, + String status, + String carType, + String passengerRate, + String priceForPassenger, + String distance, + String duration, + ) async { + await CRUD().post(link: AppLink.addWaitingRide, payload: { + 'id': orderID, + 'start_location': startLocation, + 'end_location': endLocation, + 'date': date, + 'time': time, + 'price': price, + 'passenger_id': passengerId, + 'status': status, + 'carType': carType, + 'passengerRate': passengerRate, + 'price_for_passenger': priceForPassenger, + 'distance': distance, + 'duration': duration, + }); + } + @override Widget build(BuildContext context) { String duration = (double.parse(d[4].toString()) / 60).toStringAsFixed(0); @@ -306,6 +358,23 @@ class _OrderOverlayState extends State void _rejectOrder() async { box.write(BoxName.rideStatus, 'reject'); + refuseOrder( + d[16].toString(), + ); + addRideToNotificationDriverString( + d[16].toString(), + d[29].toString(), + d[30].toString(), + '${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day}', + '${DateTime.now().hour}:${DateTime.now().minute}', + d[2].toString(), + d[7].toString(), + 'wait', + d[31].toString(), + d[33].toString(), + d[2].toString(), + d[5].toString(), + d[4].toString()); // bool isOverlayActive = await FlutterOverlayWindow.isActive(); if (isOverlayActive) { await FlutterOverlayWindow.closeOverlay(); diff --git a/lib/views/home/Captin/orderCaptin/order_request_page.dart b/lib/views/home/Captin/orderCaptin/order_request_page.dart index 34ffbb4..6913c83 100644 --- a/lib/views/home/Captin/orderCaptin/order_request_page.dart +++ b/lib/views/home/Captin/orderCaptin/order_request_page.dart @@ -379,6 +379,27 @@ class OrderRequestPage extends StatelessWidget { 'order_id': myList[16].toString(), 'status': 'Apply' }); + CRUD().postFromDialogue( + link: + '${AppLink.seferAlexandriaServer}/driver_order/add.php', + payload: { + 'driver_id': myList[6].toString(), + // box.read(BoxName.driverID).toString(), + 'order_id': myList[16].toString(), + 'status': 'Apply' + }); + + CRUD().postFromDialogue( + link: + '${AppLink.seferGizaServer}/driver_order/add.php', + payload: { + 'driver_id': myList[6].toString(), + // box.read(BoxName.driverID).toString(), + 'order_id': myList[16].toString(), + 'status': 'Apply' + }); + + /// var res = await CRUD().post( link: AppLink.updateRideAndCheckIfApplied, payload: { @@ -387,6 +408,24 @@ class OrderRequestPage extends StatelessWidget { 'status': 'Apply', 'driver_id': myList[6].toString(), }); + CRUD().post( + link: + '${AppLink.seferAlexandriaServer}/rides/updateRideAndCheckIfApplied.php', + payload: { + 'id': myList[16], + 'rideTimeStart': DateTime.now().toString(), + 'status': 'Apply', + 'driver_id': myList[6].toString(), + }); + CRUD().post( + link: + '${AppLink.seferAlexandriaServer}/rides/updateRideAndCheckIfApplied.php', + payload: { + 'id': myList[16], + 'rideTimeStart': DateTime.now().toString(), + 'status': 'Apply', + 'driver_id': myList[6].toString(), + }); if (res == 'failure') { MyDialog().getDialog( "This ride is already applied by another driver." diff --git a/lib/views/home/Captin/orderCaptin/order_speed_request.dart b/lib/views/home/Captin/orderCaptin/order_speed_request.dart index 5b4ec06..838b6bf 100644 --- a/lib/views/home/Captin/orderCaptin/order_speed_request.dart +++ b/lib/views/home/Captin/orderCaptin/order_speed_request.dart @@ -346,6 +346,24 @@ class OrderSpeedRequest extends StatelessWidget { 'status': 'Apply', 'driver_id': box.read(BoxName.driverID), }); + CRUD().post( + link: + "${AppLink.seferAlexandriaServer}/rides/updateStausFromSpeed.php", + payload: { + 'id': myList[16], + 'rideTimeStart': DateTime.now().toString(), + 'status': 'Apply', + 'driver_id': box.read(BoxName.driverID), + }); + CRUD().post( + link: + "${AppLink.seferGizaServer}/rides/updateStausFromSpeed.php", + payload: { + 'id': myList[16], + 'rideTimeStart': DateTime.now().toString(), + 'status': 'Apply', + 'driver_id': box.read(BoxName.driverID), + }); // .then((value) { // var json = jsonDecode(res); if (res == "failure") { @@ -379,6 +397,24 @@ class OrderSpeedRequest extends StatelessWidget { 'order_id': body.toString(), 'status': 'Apply' }); + CRUD().postFromDialogue( + link: + '${AppLink.seferAlexandriaServer}/driver_order/add.php', + payload: { + 'driver_id': myList[6].toString(), + // box.read(BoxName.driverID).toString(), + 'order_id': body.toString(), + 'status': 'Apply' + }); + CRUD().postFromDialogue( + link: + '${AppLink.seferGizaServer}/driver_order/add.php', + payload: { + 'driver_id': myList[6].toString(), + // box.read(BoxName.driverID).toString(), + 'order_id': body.toString(), + 'status': 'Apply' + }); FirebaseMessagesController() .sendNotificationToPassengerToken( 'Apply Ride', diff --git a/lib/views/notification/available_rides_page.dart b/lib/views/notification/available_rides_page.dart index 0bbae68..5a1c2cd 100644 --- a/lib/views/notification/available_rides_page.dart +++ b/lib/views/notification/available_rides_page.dart @@ -117,6 +117,28 @@ class AvailableRidesPage extends StatelessWidget { 'driver_id': box.read(BoxName.driverID), }); + CRUD().post( + link: + '${AppLink.seferAlexandriaServer}rides/updateStausFromSpeed.php', + payload: { + 'id': list['id'], + 'rideTimeStart': + DateTime.now().toString(), + 'status': 'Apply', + 'driver_id': + box.read(BoxName.driverID), + }); + CRUD().post( + link: + '${AppLink.seferGizaServer}rides/updateStausFromSpeed.php', + payload: { + 'id': list['id'], + 'rideTimeStart': + DateTime.now().toString(), + 'status': 'Apply', + 'driver_id': + box.read(BoxName.driverID), + }); // .then((value) { // var json = jsonDecode(res); if (res == "failure") { @@ -126,20 +148,6 @@ class AvailableRidesPage extends StatelessWidget { '', () { Get.back(); }); - // Get.defaultDialog( - // title: - // "This ride is already taken by another driver." - // .tr, - // middleText: '', - // titleStyle: AppStyle.title, - // middleTextStyle: AppStyle.title, - // confirm: MyElevatedButton( - // title: 'Ok'.tr, - // onPressed: () { - // Get.back(); - // // Get.back(); - // // Get.back(); - // })); } else if (jsonDecode(res)['status'] == "success") { List bodyToPassenger = [ @@ -160,6 +168,26 @@ class AvailableRidesPage extends StatelessWidget { 'order_id': list['id'], 'status': 'Apply' }); + CRUD().postFromDialogue( + link: + '${AppLink.seferAlexandriaServer}/driver_order/add.php', + payload: { + 'driver_id': + box.read(BoxName.driverID), + // box.read(BoxName.driverID).toString(), + 'order_id': list['id'], + 'status': 'Apply' + }); + CRUD().postFromDialogue( + link: + '${AppLink.seferGizaServer}/driver_order/add.php', + payload: { + 'driver_id': + box.read(BoxName.driverID), + // box.read(BoxName.driverID).toString(), + 'order_id': list['id'], + 'status': 'Apply' + }); await CRUD().post( link: AppLink.updateRides, payload: { @@ -168,6 +196,24 @@ class AvailableRidesPage extends StatelessWidget { DateTime.now().toString(), 'status': 'Applied' }); + CRUD().post( + link: + '${AppLink.seferAlexandriaServer}/rides/update.php', + payload: { + 'id': list['id'], + 'DriverIsGoingToPassenger': + DateTime.now().toString(), + 'status': 'Applied' + }); + CRUD().post( + link: + '${AppLink.seferGizaServer}/rides/update.php', + payload: { + 'id': list['id'], + 'DriverIsGoingToPassenger': + DateTime.now().toString(), + 'status': 'Applied' + }); await CRUD().post( link: AppLink.updateWaitingRide, payload: {