diff --git a/android/app/build.gradle b/android/app/build.gradle
index 6c13091..4386811 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -148,8 +148,8 @@ android {
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdk = 23
targetSdk = flutter.targetSdkVersion
- versionCode = 82
- versionName = '1.5.82'
+ versionCode = 93
+ versionName = '1.5.93'
multiDexEnabled =true
// manifestPlaceholders can be specified here if needed
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 6759204..cbffd52 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -10,6 +10,12 @@
+
+
+
+
+
+
@@ -59,6 +65,17 @@
+
+
+
+
+
+
+
+
+
8.0)
- nanopb (~> 3.30910.0)
- Flutter (1.0.0)
+ - flutter_contacts (0.0.1):
+ - Flutter
- flutter_local_notifications (0.0.1):
- Flutter
- flutter_secure_storage (6.0.0):
@@ -221,6 +223,7 @@ DEPENDENCIES:
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
+ - flutter_contacts (from `.symlinks/plugins/flutter_contacts/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- flutter_tts (from `.symlinks/plugins/flutter_tts/ios`)
@@ -292,6 +295,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_messaging/ios"
Flutter:
:path: Flutter
+ flutter_contacts:
+ :path: ".symlinks/plugins/flutter_contacts/ios"
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_secure_storage:
@@ -360,6 +365,7 @@ SPEC CHECKSUMS:
FirebaseInstallations: 771177d89d6c451dc6e50085ec82e2fc77ed0a4a
FirebaseMessaging: d2d1d9c62c46dd2db49a952f7deb5b16ad2c9742
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
+ flutter_contacts: edb1c5ce76aa433e20e6cb14c615f4c0b66e0983
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 9c0b524..ad2e15e 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -2,6 +2,10 @@
+ NSContactsUsageDescription
+ This app requires contacts access to function properly.
+ LSMinimumSystemVersion
+ 12.0
CFBundleURLTypes
@@ -37,11 +41,11 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 59
+ 67
CFBundleSignature
????
CFBundleVersion
- 4.3.59
+ 4.3.67
NSHumanReadableCopyright
FirebaseAppDelegateProxyEnabled
diff --git a/lib/constant/box_name.dart b/lib/constant/box_name.dart
index 7db29cd..0113597 100644
--- a/lib/constant/box_name.dart
+++ b/lib/constant/box_name.dart
@@ -12,6 +12,7 @@ class BoxName {
static const String packagInfo = "packagInfo";
static const String isVerified = 'isVerified';
static const String isFirstTime = 'isFirstTime';
+ static const String isSavedPhones = 'isSavedPhones';
static const String statusDriverLocation = "statusDriverLocation";
static const String isTest = "isTest";
static const String password = "password";
diff --git a/lib/constant/links.dart b/lib/constant/links.dart
index 78c4f36..803a4bb 100644
--- a/lib/constant/links.dart
+++ b/lib/constant/links.dart
@@ -57,17 +57,21 @@ class AppLink {
static String deletePassengersPromo = "$promo/delete.php";
static String updatePassengersPromo = "$promo/update.php";
+ //===============contact==========================
+ static String savePhones = "$server/ride/egyptPhones/add.php";
+ static String getPhones = "$server/ride/egyptPhones/get.php";
+
////=======================cancelRide===================
static String ride = '$server/ride';
static String addCancelRideFromPassenger = "$server/ride/cancelRide/add.php";
static String cancelRide = "$server/ride/cancelRide/get.php";
//-----------------ridessss------------------
static String addRides = "$ride/rides/add.php";
- static String getRides = "$server/ride/rides/get.php";
- static String getRideOrderID = "$server/ride/rides/getRideOrderID.php";
- static String getRideStatus = "$server/ride/rides/getRideStatus.php";
+ static String getRides = "$endPoint/ride/rides/get.php";
+ static String getRideOrderID = "$endPoint/ride/rides/getRideOrderID.php";
+ static String getRideStatus = "$endPoint/ride/rides/getRideStatus.php";
static String getRideStatusBegin =
- "$server/ride/rides/getRideStatusBegin.php";
+ "$endPoint/ride/rides/getRideStatusBegin.php";
static String getRideStatusFromStartApp =
"$ride/rides/getRideStatusFromStartApp.php";
static String updateRides = "$server/ride/rides/update.php";
@@ -116,6 +120,17 @@ class AppLink {
"$ride/notificationCaptain/update.php";
static String deleteNotificationCaptain =
"$ride/notificationCaptain/delete.php";
+ //-----------------invitor------------------
+
+ static String addInviteDriver = "$server/ride/invitor/add.php";
+ static String addInvitationPassenger =
+ "$server/ride/invitor/addInvitationPassenger.php";
+ static String getInviteDriver = "$server/ride/invitor/get.php";
+ static String getDriverInvitationToPassengers =
+ "$server/ride/invitor/getDriverInvitationToPassengers.php";
+ static String updateInviteDriver = "$server/ride/invitor/update.php";
+ static String updatePassengerGift =
+ "$server/ride/invitor/updatePassengerGift.php";
//-----------------Api Key------------------
static String addApiKey = "$ride/apiKey/add.php";
static String getApiKey = "$ride/apiKey/get.php";
@@ -125,6 +140,7 @@ class AppLink {
//-----------------Feed Back------------------
static String addFeedBack = "$ride/feedBack/add.php";
+ static String uploadAudio = "$ride/feedBack/upload_audio.php";
static String getFeedBack = "$ride/feedBack/get.php";
static String updateFeedBack = "$ride/feedBack/updateFeedBack.php";
diff --git a/lib/constant/notification.dart b/lib/constant/notification.dart
new file mode 100644
index 0000000..7ede7a2
--- /dev/null
+++ b/lib/constant/notification.dart
@@ -0,0 +1,22 @@
+List messages = [
+ "🚗 عروض مميزة: استمتع بأقل الأسعار وأفضل العروض! افتح تطبيق سفر الآن لتحصل على المزيد من الخيارات. 🌟",
+ "💸 وفر الآن: وفر مع تطبيق سفر! عروض مستمرة وخيارات متعددة تناسب احتياجاتك. 🔥",
+ "🔒 أمان وراحة: مع تطبيق سفر، احصل على أمان وراحة بأفضل الأسعار! 🚕",
+ "💼 خيارات متنوعة: استفد من خيارات متنوعة وأسعار تنافسية على تطبيق سفر، الأفضل دائماً. 🌐",
+ "💵 توفير مضمون: حافظ على ميزانيتك وسافر بأمان مع تطبيق سفر – العروض لا تتوقف! 🎉",
+ "🌍 وجهات مميزة: أفضل وجهات السفر، بأقل الأسعار مع تطبيق سفر – تابعنا الآن! 🛤️",
+ "🛣️ سهولة وراحة: رحلاتك أصبحت أسهل وأرخص – سافر معنا وتمتع بأفضل التجارب. 🎊",
+ "📲 حجز سهل: احجز رحلتك بسهولة وأمان مع سفر – المزيد من الخصومات في انتظارك! 🎁",
+ "👑 فئة مميزة: خليك من الفئة المميزة واستفد بأفضل الأسعار مع تطبيق سفر. 💯",
+ "💡 خيارات متعددة: نوفر لك خيارات متعددة وسعر مناسب – جرب تطبيق سفر الآن! 🚖",
+ "✨ عروض متجددة: العروض لا تتوقف على تطبيق سفر – احجز رحلتك الآن وتمتع بالمزيد! 📅",
+ "🚀 سهولة الوصول: السفر أصبح أسهل وأسرع مع تطبيق سفر – كن مستعدًا لأفضل التجارب! 🌠",
+ "🧳 راحة وأمان: تطبيق سفر يقدم لك أمان وراحة بأقل الأسعار! 📉",
+ "🔥 عروض فورية: احجز الآن واستمتع بعروض لا تُفوّت على تطبيق سفر! 🚘",
+ "🚖 أسعار تنافسية: اختر رحلتك الآن بأسعار تنافسية وتمتع بالراحة والأمان مع تطبيق سفر. ✅",
+ "💥 أسعار خاصة: أسعار خاصة بانتظارك على تطبيق سفر! افتح التطبيق الآن واحجز رحلتك. 🌐",
+ "🌟 راحة البال: انطلق بأمان وراحة مع تطبيق سفر – استمتع بأفضل الأسعار. 💸",
+ "📍 خصومات حصرية: استفد من الخصومات الحصرية والعروض المستمرة على تطبيق سفر! 🛤️",
+ "🛫 تجربة سهلة: رحلاتك أصبحت أفضل وأسهل مع تطبيق سفر – افتح التطبيق واستمتع بالتجربة. ✨",
+ "🔔 عروض لا مثيل لها: كن جاهزًا لعروض لا مثيل لها! تطبيق سفر يقدم لك أفضل الخيارات بأقل الأسعار. 🎉",
+];
diff --git a/lib/constant/style.dart b/lib/constant/style.dart
index 9d13b27..10975c7 100644
--- a/lib/constant/style.dart
+++ b/lib/constant/style.dart
@@ -43,7 +43,9 @@ class AppStyle {
static BoxDecoration boxDecoration = const BoxDecoration(
boxShadow: [
BoxShadow(
- color: AppColor.accentColor, blurRadius: 5, offset: Offset(2, 4)),
+ color: Color.fromARGB(255, 218, 218, 255),
+ blurRadius: 5,
+ offset: Offset(2, 4)),
BoxShadow(
color: AppColor.accentColor, blurRadius: 5, offset: Offset(-2, -2))
],
diff --git a/lib/controller/auth/login_controller.dart b/lib/controller/auth/login_controller.dart
index 851ffbd..d2f4745 100644
--- a/lib/controller/auth/login_controller.dart
+++ b/lib/controller/auth/login_controller.dart
@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:SEFER/constant/info.dart';
import 'package:SEFER/controller/firebase/firbase_messge.dart';
+import 'package:SEFER/controller/functions/add_error.dart';
import 'package:SEFER/views/auth/login_page.dart';
import 'package:SEFER/views/auth/sms_verfy_page.dart';
import 'package:SEFER/views/widgets/my_dialog.dart';
@@ -15,6 +16,7 @@ import 'package:SEFER/main.dart';
import 'package:SEFER/views/home/map_page_passenger.dart';
import 'package:location/location.dart';
+import '../../print.dart';
import '../functions/package_info.dart';
class LoginController extends GetxController {
@@ -90,23 +92,22 @@ class LoginController extends GetxController {
} else {
var jsonDecoeded = jsonDecode(res);
if (jsonDecoeded.isNotEmpty) {
+ var d = jsonDecoeded['data'][0];
if (jsonDecoeded['status'] == 'success' &&
- jsonDecoeded['data'][0]['verified'].toString() == '1') {
+ d['verified'].toString() == '1') {
//
+
box.write(BoxName.isVerified, '1');
- box.write(BoxName.email, jsonDecoeded['data'][0]['email']);
- box.write(BoxName.phone, jsonDecoeded['data'][0]['phone']);
+ box.write(BoxName.email, d['email']);
+ box.write(BoxName.phone, d['phone']);
box.write(BoxName.isTest, '1');
- box.write(BoxName.package, jsonDecoeded['data'][0]['package']);
- box.write(BoxName.promo, jsonDecoeded['data'][0]['promo']);
- box.write(BoxName.discount, jsonDecoeded['data'][0]['discount']);
- box.write(BoxName.validity, jsonDecoeded['data'][0]['validity']);
- box.write(BoxName.isInstall,
- jsonDecoeded['data'][0]['isInstall'] ?? 'none');
- box.write(BoxName.isGiftToken,
- jsonDecoeded['data'][0]['isGiftToken'] ?? 'none');
- box.write(BoxName.inviteCode,
- jsonDecoeded['data'][0]['inviteCode'] ?? 'none');
+ box.write(BoxName.package, d['package']);
+ box.write(BoxName.promo, d['promo']);
+ box.write(BoxName.discount, d['discount']);
+ box.write(BoxName.validity, d['validity']);
+ box.write(BoxName.isInstall, d['isInstall'] ?? 'none');
+ box.write(BoxName.isGiftToken, d['isGiftToken'] ?? 'none');
+ box.write(BoxName.inviteCode, d['inviteCode'] ?? 'none');
var token = await CRUD().get(link: AppLink.getTokens, payload: {
'passengerID': box.read(BoxName.passengerID).toString()
@@ -114,11 +115,11 @@ class LoginController extends GetxController {
if (token != 'failure') {
if (jsonDecode(token)['data'][0]['token'] !=
box.read(BoxName.tokenFCM)) {
- Get.put(FirebaseMessagesController())
- .sendNotificationToAnyWithoutData(
+ Get.put(FirebaseMessagesController()).sendNotificationToDriverMAP(
'token change'.tr,
'change device'.tr,
jsonDecode(token)['data'][0]['token'].toString(),
+ [],
'cancel.wav',
);
Future.delayed(const Duration(seconds: 1));
@@ -153,10 +154,10 @@ class LoginController extends GetxController {
Get.offAll(() => const MapPagePassenger());
},
);
+ } else {
+ print('same');
}
} // Logging to check if inviteCode is written correctly
- print("Invite Code in Box: ${box.read(BoxName.inviteCode)}");
- print("Is Install: ${box.read(BoxName.isInstall)}");
if (box.read(BoxName.inviteCode).toString() != 'none' &&
box.read(BoxName.isInstall).toString() != '1') {
@@ -171,15 +172,22 @@ class LoginController extends GetxController {
middleText: "Your invite code was successfully applied!"
.tr, // Automatically translates based on the current locale
onConfirm: () {
- CRUD().post(link: AppLink.addPassengersPromo, payload: {
- "promoCode":
- 'S-${box.read(BoxName.name).toString().split(' ')[0]}',
- "amount": '25',
- "passengerID": box.read(BoxName.passengerID).toString(),
- "description": 'promo first'
- });
- Get.offAll(() =>
- const MapPagePassenger()); // Navigate to MapPagePassenger after confirmation
+ try {
+ CRUD().post(link: AppLink.addPassengersPromo, payload: {
+ "promoCode":
+ 'S-${box.read(BoxName.name).toString().split(' ')[0]}',
+ "amount": '25',
+ "passengerID": box.read(BoxName.passengerID).toString(),
+ "description": 'promo first'
+ });
+ } catch (e) {
+ addError(e.toString(),
+ 'passenger Invitation Used dialogu as promo line 185 login_controller');
+ } finally {
+ // Continue with the rest of your flow, regardless of errors
+ // For example, navigate to the next page
+ Get.offAll(() => const MapPagePassenger());
+ }
},
textConfirm: "OK".tr, // Confirm button text
);
@@ -200,34 +208,6 @@ class LoginController extends GetxController {
}
}
- // void adminDashboardOpen() async {
- // if (formKeyAdmin.currentState!.validate()) {
- // await DeviceInfoPlus.getDeviceInfo();
- // if (Platform.isAndroid) {
- // // var res = await CRUD().get(link: AppLink.getAdminUser, payload: {
- // // // 'device_number': DeviceInfoPlus.deviceData['serialNumber'].toString(),
- // // });
- // // var d = jsonDecode(res);
- // // // if (DeviceInfoPlus.deviceData['serialNumber'] ==
- // // d['message']['device_number']) {
- // Get.back();
- // Get.to(() => const AdminHomePage());
- // // }
- // }
- // if (Platform.isIOS) {
- // // var res = await CRUD().get(link: AppLink.getAdminUser, payload: {
- // // 'device_number': DeviceInfoPlus.deviceData['identifierForVendor'].toString(),
- // // });
- // // var d = jsonDecode(res);
- // // if (DeviceInfoPlus.deviceData['serialNumber'] ==
- // // d['message']['device_number']) {
- // Get.back();
- // Get.to(() => const AdminHomePage());
- // // }
- // }
- // }
- // }
-
void login() async {
isloading = true;
update();
diff --git a/lib/controller/auth/register_controller.dart b/lib/controller/auth/register_controller.dart
index cb03dcc..2cd19d4 100644
--- a/lib/controller/auth/register_controller.dart
+++ b/lib/controller/auth/register_controller.dart
@@ -4,6 +4,7 @@ import 'dart:math';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/controller/auth/login_controller.dart';
+import 'package:SEFER/controller/functions/add_error.dart';
import 'package:SEFER/controller/local/phone_intel/phone_number.dart';
import 'package:SEFER/views/home/map_page_passenger.dart';
import 'package:SEFER/views/widgets/my_dialog.dart';
@@ -134,66 +135,51 @@ class RegisterController extends GetxController {
String phoneNumber = phoneController.text;
// Check if the phone number is from Egypt (Assuming Egyptian numbers start with +20)
- bool isEgyptianNumber = phoneNumber.startsWith('+20');
- // print('dfdf${phoneNumber.toString().split('+2')[1]}');
- if (isEgyptianNumber && phoneNumber.length == 13) {
- // Check if the phone number is already verified
- var responseChecker = await CRUD().post(
- link: AppLink.checkPhoneNumberISVerfiedPassenger,
- payload: {
- 'phone_number': phoneNumber,
- 'email': box.read(BoxName.email),
- },
- );
- if (responseChecker != 'failure') {
- var data = jsonDecode(responseChecker);
+ if (phoneController.text.isNotEmpty) {
+ bool isEgyptianNumber = phoneNumber.startsWith('+20');
+ if (isEgyptianNumber && phoneNumber.length == 13) {
+ // Check if the phone number is already verified
+ var responseChecker = await CRUD().post(
+ link: AppLink.checkPhoneNumberISVerfiedPassenger,
+ payload: {
+ 'phone_number': phoneNumber,
+ 'email': box.read(BoxName.email),
+ },
+ );
- // If the phone number is already verified
- if (data['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, phoneNumber);
- Get.offAll(const MapPagePassenger());
+ if (responseChecker != 'failure') {
+ var data = jsonDecode(responseChecker);
+
+ // If the phone number is already verified
+ if (data['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, phoneNumber);
+ Get.offAll(const MapPagePassenger());
+ } else {
+ await sendOtp(phoneNumber, randomNumber, isEgyptianNumber,
+ smsEgyptController);
+ }
} else {
- // If the phone number is not verified, send OTP
- // if (isEgyptianNumber) {
- // if (isValidEgyptianPhoneNumber(
- // phoneNumber.toString().split('+2')[1])) {
await sendOtp(phoneNumber, randomNumber, isEgyptianNumber,
smsEgyptController);
- // }
- // }
}
} else {
- // If verification check fails, still send OTP
- // if (isEgyptianNumber) {
- // if (isValidEgyptianPhoneNumber(
- // phoneNumber.toString().split('+2')[1])) {
- await sendOtp(
+ sendOtp(
phoneNumber, randomNumber, isEgyptianNumber, smsEgyptController);
- // } else {
- // MyDialog().getDialog(
- // 'Error'.tr, "Phone number isn't an Egyptian phone number".tr,
- // () {
- // Get.back();
- // });
- // }
- // }
}
} else {
- // MyDialog().getDialog(
- // 'Error'.tr, 'Phone number must be exactly 11 digits long'.tr, () {
- // Get.back();
- // });
- sendOtp(
- phoneNumber, randomNumber, isEgyptianNumber, smsEgyptController);
- print(phoneNumber);
+ MyDialog().getDialog(
+ 'Error'.tr, 'Phone number must be exactly 11 digits long'.tr, () {
+ Get.back();
+ });
+ // sendOtp(
+ // phoneNumber, randomNumber, isEgyptianNumber, smsEgyptController);
}
} catch (e) {
// Handle error
- print('Error: $e');
} finally {
isLoading = false;
update();
@@ -205,34 +191,14 @@ class RegisterController extends GetxController {
SmsEgyptController controller) async {
// Trim any leading or trailing whitespace from the phone number
phoneNumber = phoneNumber.trim();
- Log.print('phoneNumber: ${phoneNumber}');
-
+ await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
+ 'phone_number': phoneNumber,
+ 'token': otp.toString(),
+ });
if (isEgyptian) {
- // // Check if the phone number has exactly 11 digits
- // if (phoneNumber.length == 11 &&
- // RegExp(r'^\d{11}$').hasMatch(phoneNumber)) {
- // Send SMS for Egyptian phone numbers
- await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
- 'phone_number': phoneNumber,
- 'token': otp.toString(),
- // 'urlImage': box.read(BoxName.passengerPhotoUrl),
- // 'name': box.read(BoxName.name),
- });
-
await controller.sendSmsEgypt(phoneNumber, otp.toString());
- print('SMS sent to Egyptian phone number: $phoneNumber');
} else {
- // // Show error dialog if phone number is invalid
- // MyDialog().getDialog('Invalid Phone Number',
- // 'The phone number must be exactly 11 digits long.', () {
- // Get.back();
- // });
- // }
-
- // else {
- // Send WhatsApp message for non-Egyptian phone numbers
await CRUD().sendWhatsAppAuth(phoneNumber, otp.toString());
- print('WhatsApp message sent to non-Egyptian phone number: $phoneNumber');
}
isLoading = false;
@@ -243,98 +209,72 @@ class RegisterController extends GetxController {
}
verifySMSCode() async {
- // if (formKey3.currentState!.validate()) {
- Log.print('phoneController.text: ${phoneController.text}');
- // if (isValidEgyptianPhoneNumber(phoneController.text)) {
- var res = await CRUD().post(link: AppLink.verifyOtpMessage, payload: {
- 'phone_number': phoneController.text,
- 'token': verifyCode.text.toString(),
- });
- if (res != 'failure') {
- // var dec = jsonDecode(res);
- box.write(BoxName.phoneDriver, phoneController.text);
- var payload = {
- 'id': box.read(BoxName.passengerID),
- 'phone': phoneController.text,
- 'email': box.read(BoxName.email),
- 'password': 'unknown',
- 'gender': 'unknown',
- 'birthdate': '2002-01-01',
- 'site': box.read(BoxName.passengerPhotoUrl) ?? 'unknown',
- 'first_name': box.read(BoxName.name).toString().split(' ')[0],
- 'last_name': box.read(BoxName.name).toString().split(' ')[1],
- };
+ try {
+ if (formKey3.currentState!.validate()) {
+ var res = await CRUD().post(link: AppLink.verifyOtpMessage, payload: {
+ 'phone_number': phoneController.text,
+ 'token': verifyCode.text.toString(),
+ });
- var res1 = await CRUD().post(
- link: AppLink.signUp,
- payload: payload,
- );
- if (res1 != 'failure') {
- CRUD().post(
- link: '${AppLink.seferAlexandriaServer}/auth/signup.php',
- payload: payload,
- );
- CRUD().post(
- link: '${AppLink.seferGizaServer}/auth/signup.php',
- payload: payload,
- );
- box.write(BoxName.isVerified, '1');
- box.write(BoxName.isFirstTime, '0');
- box.write(BoxName.phone, phoneController.text);
- // Get.offAll(const MapPagePassenger());
- Get.put(LoginController()).loginUsingCredentials(
- box.read(BoxName.passengerID).toString(),
- box.read(BoxName.email).toString(),
- );
+ if (res != 'failure') {
+ box.write(BoxName.phoneDriver, phoneController.text);
+ var nameParts = box.read(BoxName.name).toString().split(' ');
+ var firstName = nameParts.isNotEmpty ? nameParts[0] : 'unknown';
+ var lastName = nameParts.length > 1 ? nameParts[1] : 'unknown';
+
+ var payload = {
+ 'id': box.read(BoxName.passengerID),
+ 'phone': phoneController.text,
+ 'email': box.read(BoxName.email),
+ 'password': 'unknown',
+ 'gender': 'unknown',
+ 'birthdate': '2002-01-01',
+ 'site': box.read(BoxName.passengerPhotoUrl) ?? 'unknown',
+ 'first_name': firstName,
+ 'last_name': lastName,
+ };
+
+ var res1 = await CRUD().post(
+ link: AppLink.signUp,
+ payload: payload,
+ );
+
+ if (res1 != 'failure') {
+ await CRUD().post(
+ link: '${AppLink.seferAlexandriaServer}/auth/signup.php',
+ payload: payload,
+ );
+ await CRUD().post(
+ link: '${AppLink.seferGizaServer}/auth/signup.php',
+ payload: payload,
+ );
+
+ box.write(BoxName.isVerified, '1');
+ box.write(BoxName.isFirstTime, '0');
+ box.write(BoxName.phone, phoneController.text);
+
+ Get.put(LoginController()).loginUsingCredentials(
+ box.read(BoxName.passengerID).toString(),
+ box.read(BoxName.email).toString(),
+ );
+ } else {
+ Get.snackbar('Error'.tr,
+ "The email or phone number is already registered.".tr,
+ backgroundColor: Colors.redAccent);
+ }
+ } else {
+ Get.snackbar('Error'.tr, "phone not verified".tr,
+ backgroundColor: Colors.redAccent);
+ }
+ } else {
+ Get.snackbar('Error'.tr, "you must insert token code".tr,
+ backgroundColor: AppColor.redColor);
}
- } else {
- Get.snackbar(
- 'Error'.tr, "The email or phone number is already registered.".tr,
+ } catch (e) {
+ addError(e.toString(), 'passenger sign up ');
+ Get.snackbar('Error'.tr, "Something went wrong. Please try again.".tr,
backgroundColor: Colors.redAccent);
}
- // } else {
- // var res = await CRUD().post(link: AppLink.verifyOtpMessage, payload: {
- // 'phone_number': phoneController.text,
- // 'token': verifyCode.text.toString(),
- // });
- // if (res != 'failure') {
- // // var dec = jsonDecode(res);
- // box.write(BoxName.phoneDriver, '+${phoneController.text}');
- // var payload = {
- // 'id': box.read(BoxName.passengerID),
- // 'phone': phoneController.text,
- // 'email': box.read(BoxName.email),
- // 'password': 'unknown',
- // 'gender': 'unknown',
- // 'birthdate': '2002-01-01',
- // 'site': 'unknown',
- // 'first_name': box.read(BoxName.name).toString().split(' ')[0],
- // 'last_name': box.read(BoxName.name).toString().split(' ')[1],
- // };
-
- // var res1 = await CRUD().post(
- // link: AppLink.signUp,
- // payload: payload,
- // );
- // if (res1 != 'failure') {
- // CRUD().post(
- // link: '${AppLink.seferAlexandriaServer}/auth/signup.php',
- // payload: payload,
- // );
- // CRUD().post(
- // link: '${AppLink.seferGizaServer}/auth/signup.php',
- // payload: payload,
- // );
- // box.write(BoxName.isVerified, '1');
- // box.write(BoxName.phone, '+${phoneController.text}');
- // Get.offAll(const MapPagePassenger());
- // }
- // } else {
- // Get.snackbar(
- // 'Error'.tr, "The email or phone number is already registered.".tr,
- // backgroundColor: Colors.redAccent);
- // }
- // }
}
sendVerifications() async {
diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart
index 60ec7e2..a8227a3 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';
@@ -65,6 +66,9 @@ class FirebaseMessagesController extends GetxController {
}
}
+ NotificationController notificationController =
+ Get.find();
+
Future getTokens() async {
String? basicAuthCredentials =
await storage.read(key: BoxName.basicAuthCredentials);
@@ -118,6 +122,10 @@ class FirebaseMessagesController extends GetxController {
void fireBaseTitles(RemoteMessage message) {
if (message.notification!.title! == 'Order'.tr) {
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Order', message.notification!.body!, 'Order');
+ }
} else if (message.notification!.title! == 'Apply Ride'.tr) {
var passengerList = message.data['passengerList'];
@@ -128,20 +136,22 @@ class FirebaseMessagesController extends GetxController {
Get.find().isSearchingWindow == false;
Get.find().update();
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
'Apply Order'.tr, 'Driver Applied the Ride for You'.tr, 'order1');
+ //notificationController.showNotification(
+ // 'Apply Order'.tr, 'Driver Applied the Ride for You'.tr, 'order1');
}
// driverAppliedTripSnakBar();
} else if (message.notification!.title! == 'Promo'.tr) {
if (Platform.isAndroid) {
- NotificationController()
- .showNotification('Promo', 'Show latest promo'.tr, 'promo');
+ notificationController.showNotification(
+ 'Promo', 'Show latest promo'.tr, 'promo');
}
Get.to(const PromosPassengerPage());
} else if (message.notification!.title! == 'Trip Monitoring'.tr) {
if (Platform.isAndroid) {
- NotificationController()
- .showNotification('Trip Monitoring'.tr, '', 'iphone_ringtone');
+ notificationController.showNotification(
+ 'Trip Monitoring'.tr, '', 'iphone_ringtone');
}
var myListString = message.data['passengerList'];
var myList = jsonDecode(myListString) as List;
@@ -151,65 +161,67 @@ class FirebaseMessagesController extends GetxController {
});
} else if (message.notification!.title! == 'token change'.tr) {
if (Platform.isAndroid) {
- NotificationController()
- .showNotification('token change'.tr, 'token change'.tr, 'cancel');
+ notificationController.showNotification(
+ 'token change'.tr, 'token change'.tr, 'cancel');
}
GoogleSignInHelper.signOut();
} else if (message.notification!.title! == 'DriverIsGoingToPassenger'.tr) {
Get.find().isDriverInPassengerWay = true;
Get.find().update();
if (Platform.isAndroid) {
- NotificationController().showNotification('Driver is Going To You'.tr,
+ notificationController.showNotification('Driver is Going To You'.tr,
'Please stay on the picked point.'.tr, 'tone1');
}
// Get.snackbar('Driver is Going To Passenger', '',
// backgroundColor: AppColor.greenColor);
} else if (message.notification!.title! == 'message From passenger') {
if (Platform.isAndroid) {
- NotificationController()
- .showNotification('message From passenger'.tr, ''.tr, 'tone2');
+ notificationController.showNotification(
+ 'message From passenger'.tr, ''.tr, 'tone2');
}
passengerDialog(message.notification!.body!);
update();
} else if (message.notification!.title! == 'message From Driver') {
- passengerDialog(message.notification!.body!);
if (Platform.isAndroid) {
- NotificationController()
- .showNotification('message From passenger'.tr, ''.tr, 'tone2');
+ notificationController.showNotification(
+ 'message From passenger'.tr, ''.tr, 'tone2');
}
+ passengerDialog(message.notification!.body!);
update();
} else if (message.notification!.title! == 'RideIsBegin'.tr) {
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Trip is Begin'.tr, ''.tr, 'start');
+ }
Get.find().getBeginRideFromDriver();
// Get.snackbar('RideIsBegin', '', backgroundColor: AppColor.greenColor);
box.write(BoxName.passengerWalletTotal, '0');
update();
- if (Platform.isAndroid) {
- NotificationController()
- .showNotification('Trip is Begin'.tr, ''.tr, 'start');
- }
} else if (message.notification!.title! == 'Hi ,I will go now'.tr) {
// Get.snackbar('Hi ,I will go now', '',
// backgroundColor: AppColor.greenColor);
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'tone2');
}
update();
} else if (message.notification!.title! == 'Hi ,I Arrive your site'.tr) {
driverArrivePassengerDialoge();
if (Platform.isAndroid) {
- NotificationController()
- .showNotification('Hi ,I Arrive your site'.tr, ''.tr, 'tone2');
+ notificationController.showNotification(
+ 'Hi ,I Arrive your site'.tr, ''.tr, 'tone2');
}
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,
+ middleText: "We will look for a new driver.\nPlease wait.".tr,
confirm: MyElevatedButton(
+ kolor: AppColor.greenColor,
title: 'Ok'.tr,
onPressed: () async {
Get.back();
@@ -219,6 +231,7 @@ class FirebaseMessagesController extends GetxController {
),
cancel: MyElevatedButton(
title: 'Cancel'.tr,
+ kolor: AppColor.redColor,
onPressed: () {
Get.offAll(const MapPagePassenger());
},
@@ -230,7 +243,7 @@ class FirebaseMessagesController extends GetxController {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List;
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
'Driver Finish Trip'.tr,
'you will pay to Driver'.tr + ' ${driverList[3].toString()} \$'.tr,
'tone1');
@@ -267,7 +280,7 @@ class FirebaseMessagesController extends GetxController {
var driverList = jsonDecode(myListString) as List;
// if (Platform.isAndroid) {
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
'Call Income'.tr,
message.notification!.body!,
'iphone_ringtone',
@@ -287,7 +300,7 @@ class FirebaseMessagesController extends GetxController {
var driverList = jsonDecode(myListString) as List;
// if (Platform.isAndroid) {
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
'Call Income'.tr,
message.notification!.body!,
'iphone_ringtone',
@@ -305,7 +318,7 @@ class FirebaseMessagesController extends GetxController {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List;
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
'Call End'.tr,
message.notification!.body!,
'tone2',
@@ -321,7 +334,7 @@ class FirebaseMessagesController extends GetxController {
// 'message',
// backgroundColor: AppColor.redColor);
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
'Driver Cancel Your Trip'.tr,
'you will pay to Driver you will be pay the cost of driver time look to your SEFER Wallet'
.tr,
@@ -346,7 +359,7 @@ class FirebaseMessagesController extends GetxController {
else if (message.notification!.title! == 'Order Applied'.tr) {
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
'The order Accepted by another Driver'.tr,
'We regret to inform you that another driver has accepted this order.'
.tr,
@@ -604,120 +617,6 @@ class FirebaseMessagesController extends GetxController {
}
}
- void sendNotificationToAnyWithoutData(
- String title, String body, String token, 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();
- // Log.print('accessToken: ${accessToken}');
-
- // 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,
- },
- '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 token: ${token}');
- } else {
- print(
- 'Failed to send notification. Status code: ${response.statusCode}');
- print('Response body: ${response.body}');
- }
- } catch (e) {
- print('Error sending notification: $e');
- }
- }
-
- // void sendNotificationToDriverMAP(String title, String body, String token,
- // List data, String tone) async {
- // try {
- // final response = await http.post(
- // // Uri.parse(
- // // 'https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send'),
- // Uri.parse('https://fcm.googleapis.com/fcm/send'),
- // headers: {
- // 'Content-Type': 'application/json',
- // // 'Authorization': 'Bearer 104815009508844392546'
- // 'Authorization': 'key=${AK.serverAPI}'
- // },
- // body: jsonEncode({
- // 'notification': {
- // 'title': title,
- // 'body': body,
- // 'sound': tone
- // },
- // 'data': {
- // 'DriverList': data,
- // },
- // 'priority': 'high',
- // 'to': token,
- // }),
- // );
-
- // if (response.statusCode == 200) {
- // Log.print(
- // 'Notification sent successfully. Status code: ${response.statusCode}');
- // Log.print('Response body: ${response.body}');
- // } else {
- // Log.print(
- // 'Failed to send notification. Status code: ${response.statusCode}');
- // Log.print('Response body: ${response.body}');
- // }
- // } catch (e) {
- // Log.print('Error sending notification: $e');
- // }
- // }
-
Future sendNotificationToDriverMAP(
String title, String body, String token, List data, String tone,
{int retryCount = 2}) async {
@@ -809,79 +708,6 @@ class FirebaseMessagesController extends GetxController {
}
}
}
-
- void sendNotificationToDriverMapPolyline(String title, String body,
- String token, List data, String polylineJson, 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': {
- 'DriverList': jsonEncode(data),
- },
- '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
- }
- }
}
class DriverTipWidget extends StatelessWidget {
diff --git a/lib/controller/firebase/local_notification.dart b/lib/controller/firebase/local_notification.dart
index 5fc0484..b6d8c93 100644
--- a/lib/controller/firebase/local_notification.dart
+++ b/lib/controller/firebase/local_notification.dart
@@ -1,29 +1,219 @@
+// import 'package:flutter_local_notifications/flutter_local_notifications.dart';
+// import 'package:get/get.dart';
+// import 'package:timezone/data/latest.dart' as tz;
+// import 'package:timezone/timezone.dart' as tz;
+
+// class NotificationController 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);
+// }
+
+// // Displays a notification with the given title and message
+// void showNotification(String title, String message, String tone) async {
+// AndroidNotificationDetails android = AndroidNotificationDetails(
+// 'high_importance_channel',
+// 'High Importance Notifications',
+// importance: Importance.max,
+// priority: Priority.high,
+// showWhen: false,
+// sound: RawResourceAndroidNotificationSound(tone),
+// );
+// DarwinNotificationDetails ios = const DarwinNotificationDetails(
+// sound: 'default',
+// presentAlert: true,
+// presentBadge: true,
+// presentSound: true,
+// );
+// NotificationDetails details =
+// NotificationDetails(android: android, iOS: ios);
+// await _flutterLocalNotificationsPlugin.show(0, title, message, details);
+// }
+
+// // Schedules a notification after 1 minute
+// void scheduleNotificationAfter1Minute(
+// String title, String message, String tone) async {
+// AndroidNotificationDetails android = AndroidNotificationDetails(
+// 'high_importance_channel', 'High Importance Notifications',
+// importance: Importance.max,
+// priority: Priority.high,
+// showWhen: false,
+// sound: RawResourceAndroidNotificationSound(tone));
+
+// DarwinNotificationDetails ios = const DarwinNotificationDetails(
+// sound: 'default',
+// presentAlert: true,
+// presentBadge: true,
+// presentSound: true,
+// );
+
+// NotificationDetails details =
+// NotificationDetails(android: android, iOS: ios);
+
+// // Schedule the notification to be shown after 1 minute
+// final now = tz.TZDateTime.now(tz.local);
+// final scheduledTime = now.add(const Duration(minutes: 1));
+
+// await _flutterLocalNotificationsPlugin.zonedSchedule(
+// 0,
+// title,
+// message,
+// scheduledTime,
+// details,
+// androidAllowWhileIdle: true,
+// uiLocalNotificationDateInterpretation:
+// UILocalNotificationDateInterpretation.absoluteTime,
+// matchDateTimeComponents: DateTimeComponents.time,
+// );
+// }
+// }
+import 'dart:async';
+import 'dart:io';
+
+import 'package:SEFER/constant/box_name.dart';
+import 'package:SEFER/main.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
+import 'package:permission_handler/permission_handler.dart';
+import 'package:timezone/data/latest.dart' as tz;
+import 'package:timezone/timezone.dart' as tz;
class NotificationController extends GetxController {
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
+ @override
+ void onInit() {
+ super.onInit();
+ initNotifications();
+ }
+
// Initializes the local notifications plugin
Future initNotifications() async {
const AndroidInitializationSettings android =
AndroidInitializationSettings('@mipmap/launcher_icon');
- const InitializationSettings initializationSettings =
- InitializationSettings(android: android);
+ DarwinInitializationSettings ios = DarwinInitializationSettings(
+ requestAlertPermission: true,
+ requestBadgePermission: true,
+ requestSoundPermission: true,
+ onDidReceiveLocalNotification:
+ (int id, String? title, String? body, String? payload) async {},
+ );
+ InitializationSettings initializationSettings =
+ InitializationSettings(android: android, iOS: ios);
await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
+
+ tz.initializeTimeZones();
+ print('Notifications initialized');
}
// Displays a notification with the given title and message
void showNotification(String title, String message, String tone) async {
- AndroidNotificationDetails android = AndroidNotificationDetails(
- 'high_importance_channel', 'High Importance Notifications',
- importance: Importance.max,
- priority: Priority.high,
- showWhen: false,
- sound: RawResourceAndroidNotificationSound(tone));
+ final AndroidNotificationDetails android = AndroidNotificationDetails(
+ 'high_importance_channel',
+ 'High Importance Notifications',
+ importance: Importance.max,
+ priority: Priority.high,
+ showWhen: false,
+ sound: RawResourceAndroidNotificationSound(tone),
+ );
- NotificationDetails details = NotificationDetails(android: android);
+ const DarwinNotificationDetails ios = DarwinNotificationDetails(
+ sound: 'default',
+ presentAlert: true,
+ presentBadge: true,
+ presentSound: true,
+ );
+
+ final NotificationDetails details =
+ NotificationDetails(android: android, iOS: ios);
await _flutterLocalNotificationsPlugin.show(0, title, message, details);
+ print('Notification shown: $title - $message');
+ }
+
+ void scheduleDailyNotifications(
+ String title, String message, String tone) async {
+ final AndroidNotificationDetails android = AndroidNotificationDetails(
+ 'high_importance_channel',
+ 'High Importance Notifications',
+ importance: Importance.max,
+ priority: Priority.high,
+ sound: RawResourceAndroidNotificationSound(tone),
+ );
+
+ const DarwinNotificationDetails ios = DarwinNotificationDetails(
+ sound: 'default',
+ presentAlert: true,
+ presentBadge: true,
+ presentSound: true,
+ );
+
+ final NotificationDetails details =
+ NotificationDetails(android: android, iOS: ios);
+
+ // Check for the exact alarm permission on Android 12 and above
+ if (Platform.isAndroid) {
+ if (await Permission.scheduleExactAlarm.isDenied) {
+ if (await Permission.scheduleExactAlarm.request().isGranted) {
+ print('SCHEDULE_EXACT_ALARM permission granted');
+ } else {
+ print('SCHEDULE_EXACT_ALARM permission denied');
+ return;
+ }
+ }
+ }
+
+ // Schedule notifications for 10:00 AM and 3:00 PM daily
+ await _scheduleNotificationForTime(8, 0, title, message, details);
+ await _scheduleNotificationForTime(15, 0, title, message, details);
+ await _scheduleNotificationForTime(20, 0, title, message, details);
+ // await _scheduleNotificationForTime(0, 22, title, message, details);
+
+ print('Daily notifications scheduled successfully');
+ }
+
+// Helper function to get the next instance of a specific hour and minute
+ Future _scheduleNotificationForTime(int hour, int minute, String title,
+ String message, NotificationDetails details) async {
+ // Initialize and set Cairo timezone
+ tz.initializeTimeZones();
+ var cairoLocation;
+ if (box.read(BoxName.countryCode).toString() == 'Egypt') {
+ cairoLocation = tz.getLocation('Africa/Cairo');
+ } else {} // todo get for location country
+ // Set Cairo timezone
+
+ final now = tz.TZDateTime.now(
+ cairoLocation); // Use Cairo timezone for the current time
+ tz.TZDateTime scheduledDate = tz.TZDateTime(
+ cairoLocation, now.year, now.month, now.day, hour, minute);
+
+ // If scheduled time is already past today, schedule it for the next day
+ if (scheduledDate.isBefore(now)) {
+ scheduledDate = scheduledDate.add(const Duration(days: 1));
+ }
+
+ print('Current time (Cairo): $now');
+ print('Scheduling notification for: $scheduledDate');
+
+ await _flutterLocalNotificationsPlugin.zonedSchedule(
+ 0, // Use unique IDs if you want to manage each notification separately
+ title,
+ message,
+ scheduledDate,
+ details,
+ androidAllowWhileIdle: true,
+ uiLocalNotificationDateInterpretation:
+ UILocalNotificationDateInterpretation.absoluteTime,
+ matchDateTimeComponents: DateTimeComponents.time,
+ );
+ print('Notification scheduled successfully for Cairo timezone');
}
}
diff --git a/lib/controller/functions/add_error.dart b/lib/controller/functions/add_error.dart
new file mode 100644
index 0000000..320a996
--- /dev/null
+++ b/lib/controller/functions/add_error.dart
@@ -0,0 +1,19 @@
+import '../../constant/box_name.dart';
+import '../../constant/links.dart';
+import '../../main.dart';
+import 'crud.dart';
+
+addError(String error, where) async {
+ CRUD().post(link: AppLink.addError, payload: {
+ 'error': error.toString(), // Example error description
+ 'userId': box.read(BoxName.driverID) ??
+ box.read(BoxName.passengerID), // Example user ID
+ 'userType': box.read(BoxName.driverID) != null
+ ? 'Driver'
+ : 'passenger', // Example user type
+ 'phone': box.read(BoxName.phone) ??
+ box.read(BoxName.phoneDriver), // Example phone number
+
+ 'device': where
+ });
+}
diff --git a/lib/controller/functions/crud.dart b/lib/controller/functions/crud.dart
index 1525659..8c0e3a3 100644
--- a/lib/controller/functions/crud.dart
+++ b/lib/controller/functions/crud.dart
@@ -1,15 +1,21 @@
import 'dart:convert';
+import 'dart:io';
+import 'dart:ui';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/links.dart';
import 'package:SEFER/main.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:SEFER/env/env.dart';
+import 'package:http_parser/http_parser.dart';
+import 'package:mime/mime.dart';
import '../../constant/api_key.dart';
+import '../../constant/colors.dart';
import '../../print.dart';
import '../../views/widgets/elevated_btn.dart';
+import 'add_error.dart';
import 'upload_image.dart';
class CRUD {
@@ -29,8 +35,9 @@ class CRUD {
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
},
);
- Log.print('payload: ${payload}');
+
Log.print('response.request: ${response.request}');
+ Log.print('payload: ${payload}');
Log.print('response.reasonPhrase: ${response.reasonPhrase}');
Log.print('response.body: ${response.body}');
@@ -44,7 +51,6 @@ class CRUD {
return jsonData['status'];
}
- // }
Future getTokenParent({
required String link,
Map? payload,
@@ -264,36 +270,83 @@ class CRUD {
} else {}
}
+ // Future post({
+ // required String link,
+ // Map? payload,
+ // }) async {
+ // // String? basicAuthCredentials =
+ // // await storage.read(key: BoxName.basicAuthCredentials);
+ // var url = Uri.parse(
+ // link,
+ // );
+ // var response = await http.post(
+ // url,
+ // body: payload,
+ // headers: {
+ // "Content-Type": "application/x-www-form-urlencoded",
+ // 'Authorization':
+ // 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
+ // },
+ // );
+ // Log.print('payload: ${payload}');
+ // Log.print('response.request: ${response.request}');
+ // Log.print('response.body: ${response.body}');
+ // var jsonData = jsonDecode(response.body);
+ // if (response.statusCode == 200) {
+ // if (jsonData['status'] == 'success') {
+ // return response.body;
+ // } else {
+ // return (jsonData['status']);
+ // }
+ // } else {
+ // return response.statusCode;
+ // }
+ // }
Future post({
required String link,
Map? payload,
}) async {
- // String? basicAuthCredentials =
- // await storage.read(key: BoxName.basicAuthCredentials);
- var url = Uri.parse(
- link,
- );
- var response = await http.post(
- url,
- body: payload,
- headers: {
- "Content-Type": "application/x-www-form-urlencoded",
- 'Authorization':
- 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
- },
- );
- Log.print('payload: ${payload}');
- Log.print('response.request: ${response.request}');
- Log.print('response.body: ${response.body}');
- var jsonData = jsonDecode(response.body);
- if (response.statusCode == 200) {
- if (jsonData['status'] == 'success') {
- return response.body;
+ var url = Uri.parse(link);
+ try {
+ var response = await http.post(
+ url,
+ body: payload,
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ 'Authorization':
+ 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
+ },
+ );
+
+ Log.print('Response.request: ${response.request}');
+ Log.print('Payload: $payload');
+ // Log.print('Response.statusCode: ${response.statusCode}');
+ Log.print('Response.body: ${response.body}');
+
+ if (response.statusCode == 200) {
+ try {
+ var jsonData = jsonDecode(response.body);
+
+ if (jsonData['status'] == 'success') {
+ return jsonData;
+ } else {
+ return jsonData['status'];
+ }
+ } catch (e) {
+ Log.print('JSON parsing error: $e');
+ addError(e.toString(), 'crud().post');
+ return 'failure'; // Return a recognizable failure string for JSON errors
+ }
} else {
- return (jsonData['status']);
+ Log.print('Non-200 response code: ${response.statusCode}');
+ addError(
+ 'Non-200 response code: ${response.statusCode}', 'crud().post');
+ return 'failure'; // Handle unexpected status codes as failures
}
- } else {
- return response.statusCode;
+ } catch (e) {
+ Log.print('HTTP request error: $e');
+ addError('HTTP request error: $e', 'crud().post');
+ return 'failure'; // Handle HTTP request errors as failures
}
}
diff --git a/lib/controller/functions/sms_controller.dart b/lib/controller/functions/sms_controller.dart
index fc0ec9c..53e3422 100644
--- a/lib/controller/functions/sms_controller.dart
+++ b/lib/controller/functions/sms_controller.dart
@@ -29,7 +29,7 @@ class SmsEgyptController extends GetxController {
Future sendSmsEgypt(String phone, otp) async {
String sender = await getSender();
var body = jsonEncode({
- "username": AppInformation.appName,
+ "username": 'Sefer',
"password": AK.smsPasswordEgypt,
"message": "${AppInformation.appName} app code is $otp\ncopy it to app",
"language": box.read(BoxName.lang) == 'en' ? "e" : 'r',
diff --git a/lib/controller/functions/tts.dart b/lib/controller/functions/tts.dart
index c541c4f..5bd1b6a 100644
--- a/lib/controller/functions/tts.dart
+++ b/lib/controller/functions/tts.dart
@@ -1,49 +1,50 @@
import 'package:SEFER/constant/box_name.dart';
-import 'package:SEFER/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:get/get.dart';
+import '../../main.dart';
+
class TextToSpeechController extends GetxController {
final flutterTts = FlutterTts();
- // Initialize TTS in initState
@override
void onInit() {
super.onInit();
initTts();
}
- // Dispose of TTS when controller is closed
@override
void onClose() {
+ flutterTts.stop(); // Stop any ongoing TTS
super.onClose();
- flutterTts.completionHandler;
}
- // Function to initialize TTS engine
+ // Initialize TTS engine with language check
Future initTts() async {
- String? lang =
- WidgetsBinding.instance.platformDispatcher.locale.countryCode;
- await flutterTts
- .setLanguage(box.read(BoxName.lang).toString()); //'en-US' Set language
- // await flutterTts.setLanguage('ar-SA'); //'en-US' Set language
- // await flutterTts.setLanguage(lang!); //'en-US' Set language
- await flutterTts.setSpeechRate(0.5); // Adjust speech rate
- await flutterTts.setVolume(1.0); // Set volume
+ try {
+ String langCode = box.read(BoxName.lang) ?? 'en-US';
+ bool isAvailable = await flutterTts.isLanguageAvailable(langCode);
+
+ // If language is unavailable, default to 'en-US'
+ if (!isAvailable) {
+ langCode = 'en-US';
+ }
+
+ await flutterTts.setLanguage(langCode);
+ await flutterTts.setSpeechRate(0.5); // Adjust speech rate
+ await flutterTts.setVolume(1.0); // Set volume
+ } catch (error) {
+ Get.snackbar('Error', 'Failed to initialize TTS: $error');
+ }
}
// Function to speak the given text
Future speakText(String text) async {
try {
await flutterTts.awaitSpeakCompletion(true);
- var result = await flutterTts.speak(text);
- if (result == 1) {
- // TTS operation has started
- // You can perform additional operations here, if needed
- }
+ await flutterTts.speak(text);
} catch (error) {
- // Handle error gracefully, e.g., show a message
Get.snackbar('Error', 'Failed to speak text: $error');
}
}
diff --git a/lib/controller/home/map_passenger_controller.dart b/lib/controller/home/map_passenger_controller.dart
index 36e5dbd..a500876 100644
--- a/lib/controller/home/map_passenger_controller.dart
+++ b/lib/controller/home/map_passenger_controller.dart
@@ -769,7 +769,8 @@ class MapPassengerController extends GetxController {
if (res != 'failure') {
var decode = jsonDecode(res);
- if (decode['data']['status'] != 'Apply') {
+ // if (decode['data']['status'] != 'Apply') {
+ if (decode['data']['status'] == 'Begin') {
timeToPassengerFromDriverAfterApplied = 0;
remainingTime = 0;
remainingTimeToPassengerFromDriverAfterApplied = 0;
@@ -1077,7 +1078,7 @@ class MapPassengerController extends GetxController {
// licensePlate = nearestDriverData['car_plate'].toString();
// startCarLocationSearch(box.read(BoxName.carType));
await getCarsLocationByPassengerAndReloadMarker(
- box.read(BoxName.carType), 4500);
+ box.read(BoxName.carType), 3000);
// await getCarsLocationByPassengerAndReloadMarker(
// box.read(BoxName.carType), 7000);
// await getNearestDriverByPassengerLocation();
@@ -1112,26 +1113,28 @@ class MapPassengerController extends GetxController {
isDriversTokensSend = false;
update();
- await CRUD()
- .post(link: "${AppLink.endPoint}/ride/rides/add.php", payload: {
- "start_location": //'${data[0]['start_address']}',
- '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
- "end_location": //'${data[0]['end_address']}',
- '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
- "date": DateTime.now().toString(),
- "time": DateTime.now().toString(),
- "endtime": durationToAdd.toString(),
- "price": totalPassenger.toStringAsFixed(2),
- "passenger_id": box.read(BoxName.passengerID).toString(),
- "driver_id": dataCarsLocationByPassenger['data'][carsOrder]['driver_id']
- .toString(),
- "status": "waiting",
- 'carType': box.read(BoxName.carType),
- "price_for_driver": totalPassenger.toString(),
- "price_for_passenger": totalME.toString(),
- "distance": distance.toString(),
- "paymentMethod": paymentController.isWalletChecked.toString(),
- }).then((value) {
+ await CRUD().post(
+ link: "${AppLink.seferCairoServer}/ride/rides/add.php",
+ payload: {
+ "start_location": //'${data[0]['start_address']}',
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "end_location": //'${data[0]['end_address']}',
+ '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "endtime": durationToAdd.toString(),
+ "price": totalPassenger.toStringAsFixed(2),
+ "passenger_id": box.read(BoxName.passengerID).toString(),
+ "driver_id": dataCarsLocationByPassenger['data'][carsOrder]
+ ['driver_id']
+ .toString(),
+ "status": "waiting",
+ 'carType': box.read(BoxName.carType),
+ "price_for_driver": totalPassenger.toString(),
+ "price_for_passenger": totalME.toString(),
+ "distance": distance.toString(),
+ "paymentMethod": paymentController.isWalletChecked.toString(),
+ }).then((value) {
// List body = [
rideId = jsonDecode(value)['message'];
List body = [
@@ -1188,6 +1191,29 @@ class MapPassengerController extends GetxController {
Log.print(
'dataCarsLocationByPassenger[data]: ${dataCarsLocationByPassenger['data'][carsOrder]['token']}');
});
+
+ if (AppLink.endPoint != AppLink.seferCairoServer) {
+ CRUD().post(link: "${AppLink.endPoint}/ride/rides/add.php", payload: {
+ "start_location": //'${data[0]['start_address']}',
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "end_location": //'${data[0]['end_address']}',
+ '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "endtime": durationToAdd.toString(),
+ "price": totalPassenger.toStringAsFixed(2),
+ "passenger_id": box.read(BoxName.passengerID).toString(),
+ "driver_id": dataCarsLocationByPassenger['data'][carsOrder]
+ ['driver_id']
+ .toString(),
+ "status": "waiting",
+ 'carType': box.read(BoxName.carType),
+ "price_for_driver": totalPassenger.toString(),
+ "price_for_passenger": totalME.toString(),
+ "distance": distance.toString(),
+ "paymentMethod": paymentController.isWalletChecked.toString(),
+ });
+ }
delayAndFetchRideStatus(rideId, box.read(BoxName.carType));
if (shouldFetch == false) {
startTimer();
@@ -1211,10 +1237,11 @@ class MapPassengerController extends GetxController {
}
}
+ String driverOrderStatus = 'yet';
bool isDriversTokensSend = false;
- confirmRideForAllDriverAvailable() async {
+ confirmRideForAllDriverAvailable0() async {
await getCarsLocationByPassengerAndReloadMarker(
- box.read(BoxName.carType), 4500);
+ box.read(BoxName.carType), 3500);
if (dataCarsLocationByPassenger != 'failure') {
// driversToken.remove(driverToken);
PaymentController paymentController = Get.find();
@@ -1291,33 +1318,38 @@ class MapPassengerController extends GetxController {
// Log.print('body: ${body}');
FirebaseMessagesController().sendNotificationToDriverMAP(
- 'OrderSpeed',
- rideId.toString(),
- dataCarsLocationByPassenger['data'][i]['token'].toString(),
- body,
- 'order.wav');
+ 'OrderSpeed',
+ rideId.toString(),
+ dataCarsLocationByPassenger['data'][i]['token'].toString(),
+ body,
+ 'order.wav',
+ );
+ driverOrderStatus = 'recive';
}
});
(rideId); //
- CRUD().post(link: '${AppLink.endPoint}/ride/rides/add.php', payload: {
- "start_location": //'${data[0]['start_address']}',
- '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
- "end_location": //'${data[0]['end_address']}',
- '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
- "date": DateTime.now().toString(),
- "time": DateTime.now().toString(),
- "endtime": durationToAdd.toString(),
- "price": totalPassenger.toStringAsFixed(2),
- "passenger_id": box.read(BoxName.passengerID).toString(),
- "driver_id": dataCarsLocationByPassenger['data'][carsOrder]['driver_id']
- .toString(),
- "status": "waiting",
- 'carType': box.read(BoxName.carType),
- "price_for_driver": totalPassenger.toString(),
- "price_for_passenger": totalME.toString(),
- "distance": distance.toString(),
- "paymentMethod": paymentController.isWalletChecked.toString(),
- });
+ if (AppLink.endPoint != AppLink.seferCairoServer) {
+ CRUD().post(link: '${AppLink.endPoint}/ride/rides/add.php', payload: {
+ "start_location": //'${data[0]['start_address']}',
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "end_location": //'${data[0]['end_address']}',
+ '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "endtime": durationToAdd.toString(),
+ "price": totalPassenger.toStringAsFixed(2),
+ "passenger_id": box.read(BoxName.passengerID).toString(),
+ "driver_id": dataCarsLocationByPassenger['data'][carsOrder]
+ ['driver_id']
+ .toString(),
+ "status": "waiting",
+ 'carType': box.read(BoxName.carType),
+ "price_for_driver": totalPassenger.toString(),
+ "price_for_passenger": totalME.toString(),
+ "distance": distance.toString(),
+ "paymentMethod": paymentController.isWalletChecked.toString(),
+ });
+ }
delayAndFetchRideStatusForAllDriverAvailable(rideId);
update();
@@ -1330,6 +1362,344 @@ class MapPassengerController extends GetxController {
}
}
+ Set notifiedDrivers = {};
+
+ confirmRideForAllDriverAvailable() async {
+ // Fetch car locations
+ await getCarsLocationByPassengerAndReloadMarker(
+ box.read(BoxName.carType), 3000);
+
+ // Ensure dataCarsLocationByPassenger is not 'failure' or null
+ if (dataCarsLocationByPassenger != 'failure' &&
+ dataCarsLocationByPassenger != null) {
+ // Check if 'data' key exists and is not null
+ if (dataCarsLocationByPassenger.containsKey('data') &&
+ dataCarsLocationByPassenger['data'] != null) {
+ PaymentController paymentController = Get.find();
+ rideConfirm = true;
+ shouldFetch = true;
+ isBottomSheetShown = false;
+ timeToPassengerFromDriverAfterApplied = 60;
+
+ // Add ride to database
+ await CRUD().post(
+ link: "${AppLink.seferCairoServer}/ride/rides/add.php",
+ payload: {
+ "start_location":
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "end_location":
+ '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "endtime": durationToAdd.toString(),
+ "price": totalPassenger.toStringAsFixed(2),
+ "passenger_id": box.read(BoxName.passengerID).toString(),
+ "driver_id": dataCarsLocationByPassenger['data'][carsOrder]
+ ['driver_id']
+ .toString(),
+ "status": "waiting",
+ 'carType': box.read(BoxName.carType),
+ "price_for_driver": totalPassenger.toString(),
+ "price_for_passenger": totalME.toString(),
+ "distance": distance.toString(),
+ "paymentMethod": paymentController.isWalletChecked.toString(),
+ }).then((value) {
+ if (value is String) {
+ final parsedValue = jsonDecode(value);
+ rideId = parsedValue['message'];
+ } else if (value is Map) {
+ rideId = value['message'];
+ } else {
+ Log.print('Unexpected response type: ${value.runtimeType}');
+ }
+ // Log.print('value: ${value}');
+ // rideId = jsonDecode(value)['message'];
+ // rideId = jsonDecode(value)['message'].toString();
+
+ // Timer for 5 iterations, runs every 2 seconds
+ int iteration = 0;
+ Timer.periodic(const Duration(seconds: 2), (timer) async {
+ if (iteration >= 5) {
+ timer.cancel();
+ return;
+ }
+ iteration++;
+
+ // Reload driver locations
+ await getCarsLocationByPassengerAndReloadMarker(
+ box.read(BoxName.carType), 3000);
+
+ // Ensure dataCarsLocationByPassenger and data key are still valid
+ if (dataCarsLocationByPassenger != null &&
+ dataCarsLocationByPassenger.containsKey('data') &&
+ dataCarsLocationByPassenger['data'] != null) {
+ // Notify only new drivers
+ for (var driverData in dataCarsLocationByPassenger['data']) {
+ String driverId = driverData['driver_id'].toString();
+ if (!notifiedDrivers.contains(driverId)) {
+ notifiedDrivers.add(driverId);
+
+ // Prepare body payload for notification
+ List body = [
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ totalPassenger.toStringAsFixed(2),
+ totalDriver.toStringAsFixed(2),
+ durationToRide.toString(),
+ distance.toStringAsFixed(2),
+ driverId,
+ box.read(BoxName.passengerID).toString(),
+ box.read(BoxName.name).toString(),
+ box.read(BoxName.tokenFCM).toString(),
+ box.read(BoxName.phone).toString(),
+ durationByPassenger.toString(),
+ distanceByPassenger.toString(),
+ paymentController.isWalletChecked.toString(),
+ driverData['token'].toString(),
+ durationToPassenger.toString(),
+ rideId,
+ rideTimerBegin.toString(),
+ driverId,
+ durationToRide.toString(),
+ Get.find().wayPoints.length > 1
+ ? 'haveSteps'
+ : 'startEnd',
+ placesCoordinate[0],
+ placesCoordinate[1],
+ placesCoordinate[2],
+ placesCoordinate[3],
+ placesCoordinate[4],
+ costForDriver.toStringAsFixed(2),
+ (double.parse(box.read(BoxName.passengerWalletTotal)) < 0
+ ? double.parse(box.read(BoxName.passengerWalletTotal))
+ .toStringAsFixed(2)
+ : '0'),
+ box.read(BoxName.email).toString(),
+ data[0]['start_address'],
+ data[0]['end_address'],
+ box.read(BoxName.carType),
+ kazan.toStringAsFixed(0),
+ passengerRate.toStringAsFixed(2),
+ ];
+
+ // Send notification to the driver
+ FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'OrderSpeed',
+ rideId,
+ driverData['token'].toString(),
+ body,
+ 'order.wav',
+ );
+ }
+ }
+ }
+ });
+ });
+
+ // Check for additional server endpoint
+ if (AppLink.endPoint != AppLink.seferCairoServer) {
+ CRUD().post(link: '${AppLink.endPoint}/ride/rides/add.php', payload: {
+ "start_location":
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "end_location":
+ '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "endtime": durationToAdd.toString(),
+ "price": totalPassenger.toStringAsFixed(2),
+ "passenger_id": box.read(BoxName.passengerID).toString(),
+ "driver_id": dataCarsLocationByPassenger['data'][carsOrder]
+ ['driver_id']
+ .toString(),
+ "status": "waiting",
+ 'carType': box.read(BoxName.carType),
+ "price_for_driver": totalPassenger.toString(),
+ "price_for_passenger": totalME.toString(),
+ "distance": distance.toString(),
+ "paymentMethod": paymentController.isWalletChecked.toString(),
+ });
+ }
+ delayAndFetchRideStatusForAllDriverAvailable(rideId);
+ update();
+ } else {
+ // Show dialog if no drivers found in data key
+ MyDialog().getDialog("No Car or Driver Found in your area.".tr,
+ "No Car or Driver Found in your area.".tr, () {
+ Get.back();
+ Get.offAll(const MapPagePassenger());
+ });
+ }
+ } else {
+ // Show dialog if dataCarsLocationByPassenger is 'failure' or null
+ MyDialog().getDialog("No Car or Driver Found in your area.".tr,
+ "No Car or Driver Found in your area.".tr, () {
+ Get.back();
+ Get.offAll(const MapPagePassenger());
+ });
+ }
+ }
+
+ confirmRideForAllDriverAvailable1() async {
+ int attempts = 0;
+ const int maxAttempts = 4;
+ const Duration delayDuration = Duration(seconds: 2);
+
+ // Initial data fetch
+ await getCarsLocationByPassengerAndReloadMarker(
+ box.read(BoxName.carType), 3000);
+
+ if (dataCarsLocationByPassenger != null &&
+ dataCarsLocationByPassenger != 'failure') {
+ PaymentController paymentController = Get.find();
+ rideConfirm = true;
+ shouldFetch = true;
+ isBottomSheetShown = false;
+ timeToPassengerFromDriverAfterApplied = 60;
+
+ // Create a set to keep track of notified driver IDs
+ Set notifiedDriverIds = {};
+
+ // Send the initial ride request once
+ rideId = await CRUD().post(
+ link: "${AppLink.seferCairoServer}/ride/rides/add.php",
+ payload: {
+ "start_location":
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "end_location":
+ '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "endtime": durationToAdd.toString(),
+ "price": totalPassenger.toStringAsFixed(2),
+ "passenger_id": box.read(BoxName.passengerID).toString(),
+ "driver_id": dataCarsLocationByPassenger['data'][carsOrder]
+ ['driver_id']
+ .toString(),
+ "status": "waiting",
+ 'carType': box.read(BoxName.carType),
+ "price_for_driver": totalPassenger.toString(),
+ "price_for_passenger": totalME.toString(),
+ "distance": distance.toString(),
+ "paymentMethod": paymentController.isWalletChecked.toString(),
+ }).then((value) => jsonDecode(value)['message']);
+
+ if (AppLink.endPoint != AppLink.seferCairoServer) {
+ CRUD().post(link: '${AppLink.endPoint}/ride/rides/add.php', payload: {
+ "start_location": //'${data[0]['start_address']}',
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "end_location": //'${data[0]['end_address']}',
+ '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "endtime": durationToAdd.toString(),
+ "price": totalPassenger.toStringAsFixed(2),
+ "passenger_id": box.read(BoxName.passengerID).toString(),
+ "driver_id": dataCarsLocationByPassenger['data'][carsOrder]
+ ['driver_id']
+ .toString(),
+ "status": "waiting",
+ 'carType': box.read(BoxName.carType),
+ "price_for_driver": totalPassenger.toString(),
+ "price_for_passenger": totalME.toString(),
+ "distance": distance.toString(),
+ "paymentMethod": paymentController.isWalletChecked.toString(),
+ });
+ }
+ // Add the initially available drivers to the notified set
+ for (var driver in dataCarsLocationByPassenger['data']) {
+ notifiedDriverIds.add(driver['driver_id'].toString());
+ }
+
+ // Periodically check for new drivers
+ Timer.periodic(delayDuration, (Timer timer) async {
+ attempts++;
+
+ await getCarsLocationByPassengerAndReloadMarker(
+ box.read(BoxName.carType), 3000);
+
+ if (dataCarsLocationByPassenger != 'failure') {
+ // Check for new drivers and notify them
+ for (var driver in dataCarsLocationByPassenger['data']) {
+ String driverId = driver['driver_id'].toString();
+
+ // Only notify new drivers
+ if (!notifiedDriverIds.contains(driverId)) {
+ notifiedDriverIds.add(driverId);
+
+ // Prepare notification body
+ List body = [
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ totalPassenger.toStringAsFixed(2),
+ totalDriver.toStringAsFixed(2),
+ durationToRide.toString(),
+ distance.toStringAsFixed(2),
+ driverId,
+ box.read(BoxName.passengerID).toString(),
+ box.read(BoxName.name).toString(),
+ box.read(BoxName.tokenFCM).toString(),
+ box.read(BoxName.phone).toString(),
+ durationByPassenger.toString(),
+ distanceByPassenger.toString(),
+ paymentController.isWalletChecked.toString(),
+ driver['token'].toString(),
+ durationToPassenger.toString(),
+ rideId,
+ rideTimerBegin.toString(),
+ durationToRide.toString(),
+ Get.find().wayPoints.length > 1
+ ? 'haveSteps'
+ : 'startEnd',
+ placesCoordinate[0],
+ placesCoordinate[1],
+ placesCoordinate[2],
+ placesCoordinate[3],
+ placesCoordinate[4],
+ costForDriver.toStringAsFixed(2),
+ double.parse(box.read(BoxName.passengerWalletTotal)) < 0
+ ? double.parse(box.read(BoxName.passengerWalletTotal))
+ .toStringAsFixed(2)
+ : '0',
+ box.read(BoxName.email).toString(),
+ data[0]['start_address'],
+ data[0]['end_address'],
+ box.read(BoxName.carType),
+ kazan.toStringAsFixed(0),
+ passengerRate.toStringAsFixed(2),
+ ];
+
+ // Send notification to the new driver
+ FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'OrderSpeed',
+ rideId.toString(),
+ driver['token'].toString(),
+ body,
+ 'order.wav',
+ );
+ }
+ }
+ } else {
+ MyDialog().getDialog("No Car or Driver Found in your area.".tr,
+ "No Car or Driver Found in your area.".tr, () {
+ Get.back();
+ Get.offAll(const MapPagePassenger());
+ });
+ }
+
+ // Stop after max attempts
+ if (attempts >= maxAttempts) {
+ timer.cancel();
+ }
+ });
+ } else {
+ MyDialog().getDialog("No Car or Driver Found in your area.".tr,
+ "No Car or Driver Found in your area.".tr, () {
+ Get.back();
+ Get.offAll(const MapPagePassenger());
+ });
+ }
+ }
+
icreaseForSameRideAndDelay() {
PaymentController paymentController = Get.find();
rideConfirm = true;
@@ -1398,19 +1768,20 @@ class MapPassengerController extends GetxController {
String res = await getRideStatus(rideId);
Log.print('tick: $tick');
-
- if ((res.toString() == 'waiting' || res.toString() == 'Refused') &&
+ String rideStatusDelayed = res.toString();
+ if ((rideStatusDelayed == 'waiting' ||
+ rideStatusDelayed == 'Refused') &&
tick >= 15) {
timer.cancel(); // Stop the current timer
showAndResearchForCaptain();
//TODO add to wait
- await getCarsLocationByPassengerAndReloadMarker(carType, 4500);
+ await getCarsLocationByPassengerAndReloadMarker(carType, 3000);
// await getNearestDriverByPassengerLocationAPIGOOGLE();
// getCarForFirstConfirm(carType);
confirmRideForAllDriverAvailable();
// delayAndFetchRideStatusForAllDriverAvailable(rideId);
- } else if (res.toString() == 'Apply') {
- Log.print('res.toString() == Apply: ${res.toString()}');
+ } else if (rideStatusDelayed == 'Apply') {
+ Log.print('rideStatusDelayed == Apply: ${rideStatusDelayed}');
// todo play sound
Get.find()
.playSoundFromAssets('assets/start.wav');
@@ -1422,7 +1793,7 @@ class MapPassengerController extends GetxController {
isSearchingWindow = false;
update();
startTimerFromDriverToPassengerAfterApplied();
- } else if (res.toString() == 'Refused') {
+ } else if (rideStatusDelayed == 'Refused') {
statusRide = 'Refused';
if (isDriversTokensSend == false) {
confirmRideForAllDriverAvailable();
@@ -1473,17 +1844,22 @@ class MapPassengerController extends GetxController {
attemptCounter++;
tick++;
var res = await getRideStatus(rideId);
+ String rideStatusDelayed = res.toString();
- if (res.toString() == 'Apply' || res.toString() == 'Applied') {
+ if (rideStatusDelayed == 'Apply' || rideStatusDelayed == 'Applied') {
await getUpdatedRideForDriverApply(rideId);
isApplied = true;
shouldFetch = false;
statusRide = 'Apply';
rideConfirm = false;
isSearchingWindow = false;
+
+ startTimer();
+
update();
startTimerFromDriverToPassengerAfterApplied();
- } else if (attemptCounter >= maxAttempts && statusRide != 'Cancel') {
+ } else if (attemptCounter >= maxAttempts &&
+ rideStatusDelayed != 'Cancel') {
shouldFetch = false;
// If the status is still not "Apply" after 15 attempts
MyDialog().getDialog('upgrade price'.tr,
@@ -1573,7 +1949,7 @@ class MapPassengerController extends GetxController {
reSearchAfterCanceledFromDriver() async {
await getCarsLocationByPassengerAndReloadMarker(
- box.read(BoxName.carType), 4500);
+ box.read(BoxName.carType), 3000);
confirmRideForAllDriverAvailable();
shouldFetch = true; // Stop further fetches
@@ -1616,8 +1992,9 @@ class MapPassengerController extends GetxController {
}
Future getRideStatus(String rideId) async {
- final response =
- await CRUD().get(link: AppLink.getRideStatus, payload: {'id': rideId});
+ final response = await CRUD().get(
+ link: "${AppLink.endPoint}/ride/rides/getRideStatus.php",
+ payload: {'id': rideId});
return jsonDecode(response)['data'];
}
@@ -1638,7 +2015,7 @@ class MapPassengerController extends GetxController {
make = response['data']['make'];
licensePlate = response['data']['car_plate'];
firstName = response['data']['first_name'];
- driverName = response['data']['driverName'];
+ driverName = response['data']['driverName'].toString().split(' ')[0];
driverToken = response['data']['token'];
Log.print('driverToken updated: $driverToken');
carYear = response['data']['year'];
@@ -1646,10 +2023,11 @@ class MapPassengerController extends GetxController {
}
// driversToken.remove(driverToken);
// for (var i = 1; i < driversToken.length; i++) {
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
+ FirebaseMessagesController().sendNotificationToDriverMAP(
'Order Applied'.tr,
'$driverName Apply order\nTake attention in other order'.tr,
driverToken,
+ [],
'start.wav',
);
// }
@@ -1871,6 +2249,7 @@ class MapPassengerController extends GetxController {
longitude >= 31.215009 &&
longitude <= 31.532186) {
box.write(BoxName.serverChosen, AppLink.seferCairoServer);
+
return 'Cairo';
} else if (latitude >= 29.904975 &&
latitude <= 30.143372 &&
@@ -2380,12 +2759,13 @@ class MapPassengerController extends GetxController {
double tripDurationInMinutes = durationToRide / 6;
int loopCount = tripDurationInMinutes.ceil();
// If the trip duration is less than or equal to 50 minutes, then break the loop.
+ clearMarkersExceptStartEnd();
for (var i = 0; i < loopCount; i++) {
// Wait for 50 seconds.
await Future.delayed(const Duration(seconds: 4));
- if (rideTimerBegin == true && statusRide == 'Apply') {
- await getDriverCarsLocationToPassengerAfterApplied();
- }
+ // if (rideTimerBegin == true && statusRide == 'Apply') {
+ await getDriverCarsLocationToPassengerAfterApplied();
+ // }
reloadMarkerDriverCarsLocationToPassengerAfterApplied();
}
}
@@ -2517,79 +2897,66 @@ class MapPassengerController extends GetxController {
}
Future cancelRide() async {
- if (rideConfirm == false && statusRide == 'Apply' ||
- statusRide == 'Applied' ||
- statusRide == 'waiting') {
- clearPlacesDestination();
- clearPolyline();
- // clearPolylineAll();
- data = [];
- changeCancelRidePageShow();
- if (rideId != 'yet') {
- await CRUD().post(link: AppLink.updateDriverOrder, payload: {
- "order_id": rideId.toString(), // Convert to String
- "status": 'Cancel'
- });
- FirebaseMessagesController().sendNotificationToDriverMAP(
- 'Cancel Trip',
- 'Trip Cancelled'.tr,
- driverToken,
- [],
- 'cancel.wav',
- );
- if (AppLink.endPoint != AppLink.seferCairoServer) {
- CRUD().post(
- link: "$AppLink.endPoint/ride/driver_order/update.php",
- payload: {
- "order_id": rideId.toString(), // Convert to String
- "status": 'Cancel'
- });
- }
- await CRUD().post(link: AppLink.updateRides, payload: {
+ // if (rideConfirm == true ||
+ // statusRide == 'Apply' ||
+ // statusRide == 'Applied' ||
+ // statusRide == 'wait' ||
+ // statusRide == 'waiting') {
+ clearPlacesDestination();
+ clearPolyline();
+ // clearPolylineAll();
+ data = [];
+ changeCancelRidePageShow();
+ if (rideId != 'yet') {
+ Log.print('cancelRide: 1');
+ FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'Cancel Trip'.tr,
+ 'Trip Cancelled'.tr,
+ driverToken,
+ [],
+ 'cancel.wav',
+ );
+
+ await Future.wait([
+ CRUD().post(link: AppLink.updateRides, payload: {
"id": rideId.toString(), // Convert to String
"status": 'Cancel'
- });
- if (AppLink.endPoint != AppLink.seferCairoServer) {
- CRUD().post(
- link: "${AppLink.endPoint}/ride/rides/update.php",
- payload: {
- "id": rideId.toString(), // Convert to String
- "status": 'Cancel'
- });
- }
-
+ }),
+ CRUD().post(link: AppLink.updateDriverOrder, payload: {
+ "order_id": rideId.toString(), // Convert to String
+ "status": 'Cancel'
+ }),
CRUD().post(link: AppLink.updateWaitingTrip, payload: {
"id": rideId.toString(), // Convert to String
"status": 'Cancel'
+ }),
+ ]);
+
+ if (AppLink.endPoint != AppLink.seferCairoServer) {
+ CRUD().post(
+ link: "${AppLink.endPoint}/ride/driver_order/update.php",
+ payload: {
+ "order_id": rideId.toString(), // Convert to String
+ "status": 'Cancel'
+ });
+ CRUD()
+ .post(link: "${AppLink.endPoint}/ride/rides/update.php", payload: {
+ "id": rideId.toString(), // Convert to String
+ "status": 'Cancel'
});
- if (AppLink.endPoint != AppLink.seferCairoServer) {
- CRUD().post(
- link:
- "${AppLink.endPoint}/ride/notificationCaptain/updateWaitingTrip.php",
- payload: {
- "id": rideId.toString(), // Convert to String
- "status": 'Cancel'
- });
- }
-
- print('Cancel');
+ CRUD().post(
+ link:
+ "${AppLink.endPoint}/ride/notificationCaptain/updateWaitingTrip.php",
+ payload: {
+ "id": rideId.toString(), // Convert to String
+ "status": 'Cancel'
+ });
}
-
- Get.offAll(const MapPagePassenger());
- } else {
- clearPlacesDestination();
- clearPolyline();
- data = [];
- // await CRUD().post(link: AppLink.updateDriverOrder, payload: {
- // "order_id": rideId.toString(), // Convert to String
- // "status": 'Cancel'
- // });
- // await CRUD().post(link: AppLink.updateRides, payload: {
- // "id": rideId.toString(), // Convert to String
- // "status": 'Cancel'
- // });
- Get.offAll(const MapPagePassenger());
+ print('Cancel');
+ // }
}
+ Future.delayed(const Duration(seconds: 1));
+ Get.offAll(() => const MapPagePassenger());
}
void changePickerShown() {
@@ -2942,28 +3309,28 @@ class MapPassengerController extends GetxController {
? LatLng(_locationData.latitude!, _locationData.longitude!)
: null)!;
getLocationArea(passengerLocation.latitude, passengerLocation.longitude);
+ Log.print('AppLink.endPoint: ${AppLink.endPoint}');
+ // Log.print('BoxName.serverChosen: ${box.read(BoxName.serverChosen)}');
+
newStartPointLocation = passengerLocation;
+ Log.print('passengerLocation: ${passengerLocation}');
speed = _locationData.speed!;
// //print location details
isLoading = false;
update();
}
- LatLngBounds calculateBounds(
- double centerLat, double centerLng, double radius) {
- // double radius = 4000; // 10 km in meters
+ LatLngBounds calculateBounds(double lat, double lng, double radiusInMeters) {
+ const double earthRadius = 6378137.0; // Earth's radius in meters
- southwest = LatLng(
- centerLat - (radius / 111000),
- centerLng - (radius / (111000 * cos(centerLat))),
+ double latDelta = radiusInMeters / earthRadius * (180 / pi);
+ double lngDelta =
+ radiusInMeters / (earthRadius * cos(pi * lat / 180)) * (180 / pi);
+
+ return LatLngBounds(
+ southwest: LatLng(lat - latDelta, lng - lngDelta),
+ northeast: LatLng(lat + latDelta, lng + lngDelta),
);
-
- northeast = LatLng(
- centerLat + (radius / 111000),
- centerLng + (radius / (111000 * cos(centerLat))),
- );
-
- return LatLngBounds(southwest: southwest, northeast: northeast);
}
GoogleMapController? mapController;
@@ -2992,8 +3359,6 @@ class MapPassengerController extends GetxController {
bool reloadStartApp = false;
int reloadCount = 0;
startMarkerReloading() async {
- Log.print('AppLink.endPoint: ${AppLink.endPoint}');
-
if (reloadStartApp == false) {
Timer.periodic(const Duration(seconds: 5), (timer) async {
reloadCount++;
@@ -3233,7 +3598,7 @@ class MapPassengerController extends GetxController {
remainingTime = 25; //to make cancel every call
// startCarLocationSearch(box.read(BoxName.carType));
await getCarsLocationByPassengerAndReloadMarker(
- box.read(BoxName.carType), 7000);
+ box.read(BoxName.carType), 5000);
// await getCarsLocationByPassengerAndReloadMarker();
var coordDestination = destination.split(',');
double latPassengerDestination = double.parse(coordDestination[0]);
@@ -4093,55 +4458,77 @@ class MapPassengerController extends GetxController {
try {
// Prepare trip data
Map tripData = {
- 'id': driver['id'],
+ 'id': driver['id'].toString(), // Ensure the id is a string
'phone': driver['phone'],
'gender': driver['gender'],
- 'name': driver['name'],
+ 'name': driver['NAME'],
'name_english': driver['name_english'],
'address': driver['address'],
'religion': driver['religion'],
- 'age': driver['age'],
+ 'age': driver['age'].toString(), // Convert age to String
'education': driver['education'],
'license_type': driver['license_type'],
'national_number': driver['national_number'],
'car_plate': driver['car_plate'],
'make': driver['make'],
'model': driver['model'],
- 'year': driver['year'],
+ 'year': driver['year'].toString(), // Convert year to String
'color': driver['color'],
'color_hex': driver['color_hex'],
'displacement': driver['displacement'],
'fuel': driver['fuel'],
'token': driver['token'],
- 'rating': driver['rating'],
- 'countRide': driver['countRide'],
+ 'rating': driver['rating'].toString(), // Convert rating to String
+ 'countRide':
+ driver['countRide'].toString(), // Convert countRide to String
'passengerId': box.read(BoxName.passengerID),
'timeSelected': tripDateTime.toIso8601String(),
- 'status': 'pending', // Or other appropriate status
+ 'status': 'pending',
};
+ // Log.print('tripData: $tripData');
// Send data to server
var response =
await CRUD().post(link: AppLink.addMishwari, payload: tripData);
+ // Log.print('response: $response');
if (response != 'failure') {
// Trip saved successfully
Get.snackbar('Success'.tr, 'Trip booked successfully'.tr);
+ var id = response['message'].toString();
if (AppLink.endPoint != AppLink.seferCairoServer) {
- CRUD().post(
+ await CRUD().post(
link: "${AppLink.endPoint}/ride/mishwari/add.php",
payload: tripData);
}
- // Set up local notification
+ // Optionally, set up local notification or send a push notification
// await setLocalNotification(tripDateTime);
-
- // Send notification to driver
- // await FirebaseMessagesController().sendNotificationToDriverMAP();
+ await FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'OrderVIP',
+ rideId.toString(),
+ driver['token'].toString(),
+ [
+ id,
+ driver['id'],
+ passengerLocation.latitude.toString(),
+ passengerLocation.longitude.toString(),
+ box.read(BoxName.name).toString(),
+ box.read(BoxName.passengerID).toString(),
+ box.read(BoxName.phone).toString(),
+ box.read(BoxName.email).toString(),
+ box.read(BoxName.passengerPhotoUrl).toString(),
+ box.read(BoxName.tokenFCM).toString(),
+ driver['token'].toString(),
+ ],
+ 'order.wav');
} else {
throw Exception('Failed to save trip');
}
} catch (e) {
- Get.snackbar('Error'.tr, 'Failed to book trip: $e'.tr);
+ // Show error message with more details for debugging
+ Get.snackbar('Error'.tr, 'Failed to book trip: $e'.tr,
+ backgroundColor: AppColor.redColor);
+ Log.print('Error: $e');
}
}
@@ -4253,8 +4640,8 @@ class MapPassengerController extends GetxController {
addCustomStepIcon();
addCustomStartIcon();
addCustomEndIcon();
- addToken();
- getLocation();
+ // addToken();
+ await getLocation();
getPassengerLocationUniversity();
_initializePolygons();
// await addToken();
diff --git a/lib/controller/home/profile/complaint_controller.dart b/lib/controller/home/profile/complaint_controller.dart
index b3f774f..3e3aa42 100644
--- a/lib/controller/home/profile/complaint_controller.dart
+++ b/lib/controller/home/profile/complaint_controller.dart
@@ -1,7 +1,10 @@
import 'dart:convert';
+import 'dart:io';
+import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
+import 'package:http/http.dart' as http;
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/links.dart';
@@ -9,11 +12,38 @@ import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/functions/crud.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
+import 'package:http_parser/http_parser.dart';
+import 'package:mime/mime.dart';
+
+import '../../../constant/api_key.dart';
+import '../../../print.dart';
class ComplaintController extends GetxController {
bool isLoading = false;
final formKey = GlobalKey();
final complaintController = TextEditingController();
+ final suggestionController = TextEditingController();
+ List feedBack = [];
+ @override
+ void onInit() {
+ super.onInit();
+ getLatestRidesForPassengers();
+ }
+
+ getLatestRidesForPassengers() async {
+ isLoading = true;
+ update();
+ var res = await CRUD().get(link: AppLink.getFeedBack, payload: {
+ 'passengerId': box.read(BoxName.passengerID).toString(),
+ });
+ if (res != 'failure') {
+ var d = jsonDecode(res)['message'];
+ feedBack = d;
+ }
+
+ isLoading = false;
+ update();
+ }
void addComplaint() async {
isLoading = true;
@@ -34,11 +64,175 @@ class ComplaintController extends GetxController {
title: 'Ok'.tr,
onPressed: () {
Get.back();
- Get.back();
+ // Get.back();
}));
}
isLoading = false;
update();
}
+
+ var isUploading = false.obs;
+ var uploadSuccess = false.obs;
+ late String audioLink = '';
+ Future uploadAudioFile(File audioFile) async {
+ try {
+ isUploading.value = true;
+
+ // Prepare the file upload
+ var uri = Uri.parse('${AppLink.seferCairoServer}/upload_audio.php');
+ var request = http.MultipartRequest('POST', uri);
+
+ // Add the file to the request with MIME type
+ var mimeType = lookupMimeType(audioFile.path);
+ request.headers.addAll({
+ 'Authorization':
+ 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
+ });
+ request.files.add(
+ await http.MultipartFile.fromPath(
+ 'audio',
+ audioFile.path,
+ contentType: mimeType != null ? MediaType.parse(mimeType) : null,
+ ),
+ );
+
+ // Send the request
+ var response = await request.send();
+
+ // Convert response to string for parsing
+ var responseBody = await http.Response.fromStream(response);
+
+ // After the upload request
+ if (response.statusCode == 200) {
+ var jsonResponse = jsonDecode(responseBody.body);
+
+ if (jsonResponse['status'] == 'Audio file uploaded successfully.') {
+ uploadSuccess.value = true;
+ audioLink = jsonResponse['link']; // Get the audio link
+ Get.back();
+ Get.snackbar('Success'.tr, 'Audio uploaded successfully.'.tr,
+ backgroundColor: const Color.fromARGB(255, 89, 185, 115));
+ } else {
+ uploadSuccess.value = false;
+ }
+ } else {
+ uploadSuccess.value = false;
+ }
+ } catch (e) {
+ uploadSuccess.value = false;
+ } finally {
+ isUploading.value = false;
+ }
+ }
+
+ var customerServiceSolutions;
+ var passengerReport;
+ var driverReport;
+ var isloading = false;
+ Future geminiAudio(payload, String audioLink, String complain) async {
+ String prompt = '''
+ Analyze the following complaint between a passenger and driver in a ride-hailing service. The complaint includes an audio link for reference. Provide two possible solutions for customer service to resolve the issue, and generate a detailed report for both the passenger and the driver.
+
+ Complaint details:
+ - Passenger: $complain
+ - Driver: [Driver's complaint]
+ - Ride Information: {ride details such as start_location, end_location, date, price, status, and rating details}
+ - Audio Link: [$audioLink]
+
+ Output the result in JSON format with the following structure:
+ {
+ "customerServiceSolutions": [
+ "solution1",
+ "solution2"
+ ],
+ "passengerReport": {
+ "solution": "Passenger's solution" if passenger right,
+ "complaint": "Passenger's complaint",
+ "rideDetails": {detailed ride info}
+ },
+ "driverReport": {
+ "complaint": "Driver's complaint",
+ "rideDetails": {detailed ride info}
+ }
+ } the response in arabic language with egypt
+ ''';
+
+ var requestBody = jsonEncode({
+ "contents": [
+ {
+ "parts": [
+ {"text": "$payload $prompt"}
+ ]
+ }
+ ],
+ "generationConfig": {
+ "temperature": 1,
+ "topK": 64,
+ "topP": 0.95,
+ "maxOutputTokens": 8192,
+ "stopSequences": []
+ },
+ "safetySettings": [
+ {
+ "category": "HARM_CATEGORY_HARASSMENT",
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
+ },
+ {
+ "category": "HARM_CATEGORY_HATE_SPEECH",
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
+ },
+ {
+ "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
+ },
+ {
+ "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
+ }
+ ]
+ });
+
+ final response = await http.post(
+ Uri.parse(
+ 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro:generateContent?key=${AK.geminiApi}'),
+ headers: {'Content-Type': 'application/json'},
+ body: requestBody,
+ );
+
+ if (response.statusCode == 200) {
+ var responseData = jsonDecode(response.body);
+ var result = responseData['candidates'][0]['content']['parts'][0]['text'];
+ Log.print('result: ${result}');
+
+ // Clean up the result by removing surrounding backticks if they exist
+ result = result.replaceAll(RegExp(r'^```json\s*|\s*```$'), '');
+
+ // Attempt to decode the cleaned result as JSON
+ try {
+ var jsonResult = jsonDecode(result);
+
+ // Access customer service solutions and reports for both passenger and driver
+ customerServiceSolutions = jsonResult['customerServiceSolutions'];
+ passengerReport = jsonResult['passengerReport'];
+ driverReport = jsonResult['driverReport'];
+ update();
+ // Use the data accordingly
+ // For example, log the reports or display them in a UI dialog
+
+ update();
+ } catch (e) {
+ MyDialog().getDialog(
+ 'Error'.tr,
+ 'Unable to parse the response as JSON. Please check the format and try again.'
+ .tr, () {
+ Get.back();
+ });
+ }
+ } else {
+ Get.snackbar(
+ 'Error', "Request failed with status: ${response.statusCode}",
+ backgroundColor: AppColor.redColor);
+ }
+ }
}
diff --git a/lib/controller/home/profile/invit_controller.dart b/lib/controller/home/profile/invit_controller.dart
new file mode 100644
index 0000000..50ed888
--- /dev/null
+++ b/lib/controller/home/profile/invit_controller.dart
@@ -0,0 +1,280 @@
+import 'dart:convert';
+
+import 'package:SEFER/constant/box_name.dart';
+import 'package:SEFER/constant/colors.dart';
+import 'package:SEFER/constant/links.dart';
+import 'package:SEFER/controller/functions/crud.dart';
+import 'package:SEFER/controller/home/payment/captain_wallet_controller.dart';
+import 'package:SEFER/controller/payment/payment_controller.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_contacts/contact.dart';
+import 'package:flutter_contacts/flutter_contacts.dart';
+import 'package:get/get.dart';
+import 'package:share/share.dart';
+
+import '../../../main.dart';
+import '../../../views/widgets/my_dialog.dart';
+import '../../functions/launch.dart';
+import '../../notification/notification_captain_controller.dart';
+
+class InviteController extends GetxController {
+ final TextEditingController invitePhoneController = TextEditingController();
+ List driverInvitationData = [];
+ List driverInvitationDataToPassengers = [];
+ String? couponCode;
+ String? driverCouponCode;
+
+ int selectedTab = 0;
+ PassengerStats passengerStats = PassengerStats();
+ void updateSelectedTab(int index) {
+ selectedTab = index;
+ update();
+ }
+
+ Future shareCouponCode() async {
+ // TODO: Implement sharing functionality
+ // You can use share_plus package to share the coupon code
+ }
+ Future shareDriverCode() async {
+ if (driverCouponCode != null) {
+ final String shareText = '''
+Join SEFER as a driver using my referral code!
+Use code: $driverCouponCode
+Download the SEFER Driver app now and earn rewards!
+''';
+ await Share.share(shareText);
+ }
+ }
+
+ Future sharePassengerCode() async {
+ if (couponCode != null) {
+ final String shareText = '''
+Get a discount on your first SEFER ride!
+Use my referral code: $couponCode
+Download the SEFER app now and enjoy your ride!
+''';
+ await Share.share(shareText);
+ }
+ }
+
+ @override
+ void onInit() {
+ super.onInit();
+ // fetchDriverStats();
+ }
+
+ void fetchDriverStats() async {
+ try {
+ var response = await CRUD().get(link: AppLink.getInviteDriver, payload: {
+ "driverId": box.read(BoxName.driverID),
+ });
+ if (response != 'failure') {
+ var data = jsonDecode(response);
+ driverInvitationData = data['message'];
+ update();
+ }
+ } catch (e) {}
+ }
+
+ void fetchDriverStatsPassengers() async {
+ try {
+ var response = await CRUD()
+ .get(link: AppLink.getDriverInvitationToPassengers, payload: {
+ "driverId": box.read(BoxName.passengerID),
+ });
+ if (response != 'failure') {
+ var data = jsonDecode(response);
+ driverInvitationDataToPassengers = data['message'];
+ update();
+ }
+ } catch (e) {}
+ }
+
+ void selectPhone(String phone) {
+ if (box.read(BoxName.countryCode) == 'Egypt') {
+ invitePhoneController.text = phone;
+ update();
+ Get.back();
+ }
+ }
+
+ Future saveContactsToServer() async {
+ try {
+ // TODO: Implement the actual server upload logic here
+ // Simulating a server request
+ await Future.delayed(Duration(seconds: 2));
+ Get.snackbar('Success'.tr,
+ '${selectedContacts.length} contacts saved to server'.tr);
+ } catch (e) {
+ Get.snackbar('Error'.tr,
+ 'An error occurred while saving contacts to server: $e'.tr);
+ }
+ }
+
+ List contacts = [];
+ List selectedContacts = [];
+ RxList