This commit is contained in:
Hamza-Ayed
2024-10-03 22:25:44 +03:00
parent 79b14ab9cc
commit 8889780a6f
24 changed files with 853 additions and 734 deletions

View File

@@ -54,8 +54,8 @@ android {
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdk = 23 minSdk = 23
targetSdk = flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode = 103 versionCode = 104
versionName = '1.5.03' versionName = '1.5.04'
multiDexEnabled =true multiDexEnabled =true
} }

View File

@@ -27,6 +27,7 @@
<uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" /> <uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application <application
android:allowBackup="true" android:allowBackup="true"

View File

@@ -1,15 +1,9 @@
<resources> <resources>
<string name="app_name">My App</string> <string name="app_name">My App</string>
<!-- <string name="default_notification_channel_id">ride_channel</string> --> <string name="default_notification_channel_id">high_importance_channel</string>
<string name="default_notification_channel_id">default_channel</string>
<string name="api_key">AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0</string> <string name="api_key">AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0</string>
<string name="channel_name">FCM Notifications</string> <string name="channel_name">FCM Notifications</string>
<string name="channel_description">Notifications from Firebase Cloud Messaging</string> <string name="channel_description">Notifications from Firebase Cloud Messaging</string>
<!-- <string name="app_name">auth_app</string> -->
<!-- <string name="facebook_app_id">1749628025888168</string>
<string name="fb_login_protocol_scheme">fb1749628025888168</string>
<string name="facebook_client_token">af5af0a2c8feffe25c27755977bb9ff7</string> -->
</resources> </resources>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -13,14 +13,6 @@ PODS:
- Flutter - Flutter
- device_info_plus (0.0.1): - device_info_plus (0.0.1):
- Flutter - Flutter
- FBAEMKit (17.0.3):
- FBSDKCoreKit_Basics (= 17.0.3)
- FBSDKCoreKit (17.0.3):
- FBAEMKit (= 17.0.3)
- FBSDKCoreKit_Basics (= 17.0.3)
- FBSDKCoreKit_Basics (17.0.3)
- FBSDKLoginKit (17.0.3):
- FBSDKCoreKit (= 17.0.3)
- Firebase/Auth (10.28.0): - Firebase/Auth (10.28.0):
- Firebase/CoreOnly - Firebase/CoreOnly
- FirebaseAuth (~> 10.28.0) - FirebaseAuth (~> 10.28.0)
@@ -71,9 +63,6 @@ PODS:
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_contacts (0.0.1): - flutter_contacts (0.0.1):
- Flutter - Flutter
- flutter_facebook_auth (7.0.1):
- FBSDKLoginKit (~> 17.0.2)
- Flutter
- flutter_image_compress_common (1.0.0): - flutter_image_compress_common (1.0.0):
- Flutter - Flutter
- Mantle - Mantle
@@ -297,7 +286,6 @@ DEPENDENCIES:
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_contacts (from `.symlinks/plugins/flutter_contacts/ios`) - flutter_contacts (from `.symlinks/plugins/flutter_contacts/ios`)
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
- flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`) - flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
@@ -329,10 +317,6 @@ DEPENDENCIES:
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- AppAuth - AppAuth
- FBAEMKit
- FBSDKCoreKit
- FBSDKCoreKit_Basics
- FBSDKLoginKit
- Firebase - Firebase
- FirebaseAppCheckInterop - FirebaseAppCheckInterop
- FirebaseAuth - FirebaseAuth
@@ -390,8 +374,6 @@ EXTERNAL SOURCES:
:path: Flutter :path: Flutter
flutter_contacts: flutter_contacts:
:path: ".symlinks/plugins/flutter_contacts/ios" :path: ".symlinks/plugins/flutter_contacts/ios"
flutter_facebook_auth:
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
flutter_image_compress_common: flutter_image_compress_common:
:path: ".symlinks/plugins/flutter_image_compress_common/ios" :path: ".symlinks/plugins/flutter_image_compress_common/ios"
flutter_local_notifications: flutter_local_notifications:
@@ -453,10 +435,6 @@ SPEC CHECKSUMS:
background_location: 1b80c1fe3abd9912bca298618f6e365abf6f588f background_location: 1b80c1fe3abd9912bca298618f6e365abf6f588f
camera_avfoundation: dd002b0330f4981e1bbcb46ae9b62829237459a4 camera_avfoundation: dd002b0330f4981e1bbcb46ae9b62829237459a4
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
FBAEMKit: 9900b2edd99a2d21629a6277e6166f14c6215799
FBSDKCoreKit: 0791f8f68a8630931a4c12aa23a56cc021551596
FBSDKCoreKit_Basics: 46d6b472c0dd0a5a7e972c025033d1c567f54eb4
FBSDKLoginKit: b4a4eba1d62eb452544411824f41689adabd5bd2
Firebase: 5121c624121af81cbc81df3bda414b3c28c4f3c3 Firebase: 5121c624121af81cbc81df3bda414b3c28c4f3c3
firebase_auth: e778ee89483b86fe4200d1f8e9a1c52aa5fb64a8 firebase_auth: e778ee89483b86fe4200d1f8e9a1c52aa5fb64a8
firebase_core: a9d0180d5285527884d07a41eb4a9ec9ed12cdb6 firebase_core: a9d0180d5285527884d07a41eb4a9ec9ed12cdb6
@@ -469,7 +447,6 @@ SPEC CHECKSUMS:
FirebaseMessaging: 087a7c7cadef7b9239f005bc4db823894844f323 FirebaseMessaging: 087a7c7cadef7b9239f005bc4db823894844f323
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_contacts: edb1c5ce76aa433e20e6cb14c615f4c0b66e0983 flutter_contacts: edb1c5ce76aa433e20e6cb14c615f4c0b66e0983
flutter_facebook_auth: 4fa1dc3fa624284a5ddfdf9e4a2b7945b3835949
flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086 flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12

View File

@@ -33,7 +33,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>62</string> <string>64</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
@@ -48,7 +48,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>4.0.62</string> <string>4.0.64</string>
<key>FirebaseAppDelegateProxyEnabled</key> <key>FirebaseAppDelegateProxyEnabled</key>
<string>NO</string> <string>NO</string>
<key>GMSApiKey</key> <key>GMSApiKey</key>

View File

@@ -94,138 +94,139 @@ class RegisterCaptainController extends GetxController {
return validPrefixes.hasMatch(phoneNumber); return validPrefixes.hasMatch(phoneNumber);
} }
// sendOtpMessage() async {
// SmsEgyptController smsEgyptController = Get.put(SmsEgyptController());
// isLoading = true;
// update();
// int randomNumber = Random().nextInt(100000) + 1;
// isLoading = true;
// update();
// if (formKey3.currentState!.validate()) {
// if (box.read(BoxName.countryCode) == 'Egypt') {
// if (isValidEgyptianPhoneNumber(phoneController.text)) {
// var responseCheker = await CRUD()
// .post(link: AppLink.checkPhoneNumberISVerfiedDriver, payload: {
// 'phone_number': '+2${phoneController.text}',
// });
// if (responseCheker != 'failure') {
// var d = jsonDecode(responseCheker);
// if (d['message'][0]['is_verified'].toString() == '1') {
// Get.snackbar('Phone number is verified before'.tr, '',
// backgroundColor: AppColor.greenColor);
// box.write(BoxName.phoneVerified, '1');
// box.write(BoxName.phone, '+2${phoneController.text}');
// await Get.put(LoginDriverController()).loginUsingCredentials(
// box.read(BoxName.driverID).toString(),
// box.read(BoxName.emailDriver).toString(),
// );
// } else {
// await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
// 'phone_number': '+2${phoneController.text}',
// 'token_code': randomNumber.toString(),
// "driverId": box.read(BoxName.driverID),
// "email": box.read(BoxName.emailDriver),
// });
// await smsEgyptController.sendSmsEgypt(
// phoneController.text.toString(), randomNumber.toString());
// isSent = true;
// isLoading = false;
// update();
// }
// } else {
// await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
// 'phone_number': '+2${phoneController.text}',
// 'token_code': randomNumber.toString(),
// "driverId": box.read(BoxName.driverID),
// "email": box.read(BoxName.emailDriver),
// });
// await smsEgyptController.sendSmsEgypt(
// phoneController.text.toString(), randomNumber.toString());
// isSent = true;
// isLoading = false;
// update();
// }
// } else {
// Get.snackbar('Phone Number wrong'.tr, '',
// backgroundColor: AppColor.redColor);
// }
// }
// }
// isLoading = false;
// update();
// }
DateTime? lastOtpSentTime; // Store the last OTP sent time
int otpResendInterval = 300; // 5 minutes in seconds
// Main function to handle OTP sending
sendOtpMessage() async { sendOtpMessage() async {
if (_isOtpResendAllowed()) { SmsEgyptController smsEgyptController = Get.put(SmsEgyptController());
isLoading = true;
update();
int randomNumber = Random().nextInt(100000) + 1;
isLoading = true; isLoading = true;
update(); update();
if (formKey3.currentState!.validate()) { if (formKey3.currentState!.validate()) {
String countryCode = box.read(BoxName.countryCode); if (box.read(BoxName.countryCode) == 'Egypt') {
String phoneNumber = phoneController.text; if (isValidEgyptianPhoneNumber(phoneController.text)) {
var responseCheker = await CRUD()
if (countryCode == 'Egypt' && isValidEgyptianPhoneNumber(phoneNumber)) { .post(link: AppLink.checkPhoneNumberISVerfiedDriver, payload: {
await _checkAndSendOtp(phoneNumber); 'phone_number': '+2${phoneController.text}',
});
if (responseCheker != 'failure') {
var d = jsonDecode(responseCheker);
if (d['message'][0]['is_verified'].toString() == '1') {
Get.snackbar('Phone number is verified before'.tr, '',
backgroundColor: AppColor.greenColor);
box.write(BoxName.phoneVerified, '1');
box.write(BoxName.phone, '+2${phoneController.text}');
await Get.put(LoginDriverController()).loginUsingCredentials(
box.read(BoxName.driverID).toString(),
box.read(BoxName.emailDriver).toString(),
);
} else { } else {
_showErrorMessage('Phone Number is not Egypt phone '.tr); await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
'phone_number': '+2${phoneController.text}',
'token_code': randomNumber.toString(),
"driverId": box.read(BoxName.driverID),
"email": box.read(BoxName.emailDriver),
});
await smsEgyptController.sendSmsEgypt(
phoneController.text.toString(), randomNumber.toString());
isSent = true;
isLoading = false;
update();
}
} else {
await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
'phone_number': '+2${phoneController.text}',
'token_code': randomNumber.toString(),
"driverId": box.read(BoxName.driverID),
"email": box.read(BoxName.emailDriver),
});
await smsEgyptController.sendSmsEgypt(
phoneController.text.toString(), randomNumber.toString());
isSent = true;
isLoading = false;
update();
}
} else {
Get.snackbar('Phone Number wrong'.tr, '',
backgroundColor: AppColor.redColor);
}
} }
} }
isLoading = false; isLoading = false;
update(); update();
} else {
_showCooldownMessage();
}
} }
DateTime? lastOtpSentTime; // Store the last OTP sent time
int otpResendInterval = 300; // 5 minutes in seconds
// Main function to handle OTP sending
// sendOtpMessage() async {
// if (_isOtpResendAllowed()) {
// isLoading = true;
// update();
// if (formKey3.currentState!.validate()) {
// String countryCode = box.read(BoxName.countryCode);
// String phoneNumber = phoneController.text;
// if (countryCode == 'Egypt' && isValidEgyptianPhoneNumber(phoneNumber)) {
// await _checkAndSendOtp(phoneNumber);
// } else {
// _showErrorMessage('Phone Number is not Egypt phone '.tr);
// }
// }
// isLoading = false;
// update();
// } else {
// _showCooldownMessage();
// }
// }
// Check if the resend OTP request is allowed (5 minutes cooldown) // Check if the resend OTP request is allowed (5 minutes cooldown)
bool _isOtpResendAllowed() { // bool _isOtpResendAllowed() {
if (lastOtpSentTime == null) return true; // if (lastOtpSentTime == null) return true;
final int elapsedTime = // final int elapsedTime =
DateTime.now().difference(lastOtpSentTime!).inSeconds; // DateTime.now().difference(lastOtpSentTime!).inSeconds;
return elapsedTime >= otpResendInterval; // return elapsedTime >= otpResendInterval;
} // }
// Show message when user tries to resend OTP too soon // // Show message when user tries to resend OTP too soon
void _showCooldownMessage() { // void _showCooldownMessage() {
int remainingTime = otpResendInterval - // int remainingTime = otpResendInterval -
DateTime.now().difference(lastOtpSentTime!).inSeconds; // DateTime.now().difference(lastOtpSentTime!).inSeconds;
Get.snackbar( // Get.snackbar(
'Please wait ${remainingTime ~/ 60}:${(remainingTime % 60).toString().padLeft(2, '0')} minutes before requesting again', // 'Please wait ${remainingTime ~/ 60}:${(remainingTime % 60).toString().padLeft(2, '0')} minutes before requesting again',
'', // '',
backgroundColor: AppColor.redColor, // backgroundColor: AppColor.redColor,
); // );
} // }
// Check if the phone number has been verified, and send OTP if not verified // // Check if the phone number has been verified, and send OTP if not verified
_checkAndSendOtp(String phoneNumber) async { // _checkAndSendOtp(String phoneNumber) async {
var responseChecker = await CRUD().post( // var responseChecker = await CRUD().post(
link: AppLink.checkPhoneNumberISVerfiedDriver, // link: AppLink.checkPhoneNumberISVerfiedDriver,
payload: { // payload: {
'phone_number': '+2$phoneNumber', // 'phone_number': '+2$phoneNumber',
}, // },
); // );
if (responseChecker != 'failure') { // if (responseChecker != 'failure') {
var responseData = jsonDecode(responseChecker); // var responseData = jsonDecode(responseChecker);
if (_isPhoneVerified(responseData)) { // if (_isPhoneVerified(responseData)) {
_handleAlreadyVerified(); // _handleAlreadyVerified();
} else { // } else {
await _sendOtpAndSms(phoneNumber); // await _sendOtpAndSms(phoneNumber);
} // }
} else { // } else {
await _sendOtpAndSms(phoneNumber); // await _sendOtpAndSms(phoneNumber);
} // }
} // }
// Check if the phone number is already verified // Check if the phone number is already verified
bool _isPhoneVerified(dynamic responseData) { bool _isPhoneVerified(dynamic responseData) {

View File

@@ -115,7 +115,7 @@ class FirebaseMessagesController extends GetxController {
Future<void> fireBaseTitles(RemoteMessage message) async { Future<void> fireBaseTitles(RemoteMessage message) async {
if (message.notification!.title! == 'Order'.tr) { if (message.notification!.title! == 'Order'.tr) {
if (Platform.isAndroid) { if (Platform.isAndroid) {
NotificationController1().showNotification('Order'.tr, '', 'order', ''); NotificationController().showNotification('Order'.tr, '', 'order', '');
} }
// await FirebaseMessagesController().showOverlayNotification(message); // await FirebaseMessagesController().showOverlayNotification(message);
var myListString = message.data['DriverList']; var myListString = message.data['DriverList'];
@@ -156,6 +156,8 @@ class FirebaseMessagesController extends GetxController {
}); });
// Get.to(const VipOrderPage()); // Get.to(const VipOrderPage());
} else if (message.notification!.title! == 'message From passenger'.tr) {
passengerDialog(message.notification!.body!);
} else if (message.notification!.title == 'Cancel') { } else if (message.notification!.title == 'Cancel') {
cancelTripDialog1(); cancelTripDialog1();
} else if (message.notification!.title! == 'token change') { } else if (message.notification!.title! == 'token change') {
@@ -163,15 +165,6 @@ class FirebaseMessagesController extends GetxController {
// .showNotification('token change'.tr, 'token change', 'cancel'); // .showNotification('token change'.tr, 'token change', 'cancel');
// GoogleSignInHelper.signOut(); // GoogleSignInHelper.signOut();
GoogleSignInHelper.signOut(); GoogleSignInHelper.signOut();
} else if (message.notification!.title! == 'message From passenger') {
// print('sdfd');
// if (Platform.isAndroid) {
// NotificationController1()
// .showNotification('message From passenger'.tr, ''.tr, 'tone2', '');
// }
passengerDialog(message.notification!.body!);
update();
} else if (message.notification!.title! == 'face detect') { } else if (message.notification!.title! == 'face detect') {
if (Platform.isAndroid) { if (Platform.isAndroid) {
NotificationController1() NotificationController1()

View File

@@ -15,7 +15,7 @@ import '../home/captin/home_captain_controller.dart';
class NotificationController extends GetxController { class NotificationController extends GetxController {
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin(); FlutterLocalNotificationsPlugin();
// Initializes the local notifications plugin
Future<void> initNotifications() async { Future<void> initNotifications() async {
const AndroidInitializationSettings android = const AndroidInitializationSettings android =
AndroidInitializationSettings('@mipmap/launcher_icon'); AndroidInitializationSettings('@mipmap/launcher_icon');
@@ -26,14 +26,13 @@ class NotificationController extends GetxController {
await _flutterLocalNotificationsPlugin.initialize( await _flutterLocalNotificationsPlugin.initialize(
initializationSettings, initializationSettings,
onDidReceiveNotificationResponse: onDidReceiveNotificationResponse, onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,
onDidReceiveBackgroundNotificationResponse: onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
onDidReceiveBackgroundNotificationResponse,
); );
// Create a notification channel // Create a notification channel
const AndroidNotificationChannel channel = AndroidNotificationChannel( const AndroidNotificationChannel channel = AndroidNotificationChannel(
'your channel id', 'high_importance_channel', // Use the same ID as in strings.xml
'your channel name', 'High Importance Notifications',
description: 'This channel is used for important notifications.', description: 'This channel is used for important notifications.',
importance: Importance.high, importance: Importance.high,
); );
@@ -56,7 +55,8 @@ class NotificationController extends GetxController {
); );
AndroidNotificationDetails android = AndroidNotificationDetails( AndroidNotificationDetails android = AndroidNotificationDetails(
'high_importance_channel', 'High Importance Notifications', 'high_importance_channel', // Use the same ID as before
'High Importance Notifications',
importance: Importance.high, importance: Importance.high,
priority: Priority.high, priority: Priority.high,
styleInformation: bigTextStyleInformation, styleInformation: bigTextStyleInformation,
@@ -94,17 +94,17 @@ class NotificationController extends GetxController {
// Callback when the notification is tapped // Callback when the notification is tapped
void onDidReceiveNotificationResponse(NotificationResponse response) { void onDidReceiveNotificationResponse(NotificationResponse response) {
_handleNotificationResponse(response); handleNotificationResponse(response);
} }
// Callback when the notification is tapped while the app is in the background // Callback when the notification is tapped while the app is in the background
void onDidReceiveBackgroundNotificationResponse( void onDidReceiveBackgroundNotificationResponse(
NotificationResponse response) { NotificationResponse response) {
_handleNotificationResponse(response); handleNotificationResponse(response);
} }
// Handle notification response for both foreground and background // Handle notification response for both foreground and background
void _handleNotificationResponse(NotificationResponse response) { void handleNotificationResponse(NotificationResponse response) {
print('Notification tapped!'); print('Notification tapped!');
Log.print('response.payload: ${response.payload}'); Log.print('response.payload: ${response.payload}');
if (response.payload != null) { if (response.payload != null) {

View File

@@ -24,6 +24,7 @@ class HomeCaptainController extends GetxController {
Duration activeDuration = Duration.zero; Duration activeDuration = Duration.zero;
Timer? activeTimer; Timer? activeTimer;
Map data = {}; Map data = {};
BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker;
bool isLoading = true; bool isLoading = true;
late double kazan = 0; late double kazan = 0;
double latePrice = 0; double latePrice = 0;
@@ -69,6 +70,19 @@ class HomeCaptainController extends GetxController {
update(); update();
} }
void addCustomCarIcon() {
ImageConfiguration config = ImageConfiguration(
size: const Size(30, 35), devicePixelRatio: Get.pixelRatio);
BitmapDescriptor.asset(
config,
'assets/images/car.png',
// mipmaps: false,
).then((value) {
carIcon = value;
update();
});
}
String stringActiveDuration = ''; String stringActiveDuration = '';
void onButtonSelected() { void onButtonSelected() {
// totalPoints = Get.find<CaptainWalletController>().totalPoints; // totalPoints = Get.find<CaptainWalletController>().totalPoints;
@@ -170,15 +184,23 @@ class HomeCaptainController extends GetxController {
// CameraUpdate.newLatLng(Get.find<LocationController>().myLocation), // CameraUpdate.newLatLng(Get.find<LocationController>().myLocation),
// ); // );
// } // }
GoogleMapController? mapHomeCaptainController; // Initialize to null GoogleMapController? mapHomeCaptainController; // Nullable controller
void onMapCreated(GoogleMapController controller) { void onMapCreated(GoogleMapController controller) {
mapHomeCaptainController = controller; mapHomeCaptainController = controller;
// Optional: Check if the controller is still null (just for safety)
if (mapHomeCaptainController != null) {
// Get the visible region
controller.getVisibleRegion(); controller.getVisibleRegion();
// Animate camera to user location (optional) // Animate camera to user location (optional)
controller.animateCamera( controller.animateCamera(
CameraUpdate.newLatLng(Get.find<LocationController>().myLocation), CameraUpdate.newLatLng(Get.find<LocationController>().myLocation),
); );
} else {
print("Controller is null, cannot proceed.");
}
} }
void savePeriod(Duration period) { void savePeriod(Duration period) {
@@ -223,6 +245,7 @@ class HomeCaptainController extends GetxController {
await getlocation(); await getlocation();
onButtonSelected(); onButtonSelected();
getDriverRate(); getDriverRate();
addCustomCarIcon();
getKazanPercent(); getKazanPercent();
getPaymentToday(); getPaymentToday();
getCountRideToday(); getCountRideToday();

View File

@@ -105,8 +105,8 @@ class MapDriverController extends GetxController {
late LatLng latLngPassengerDestination = LatLng(0, 0); late LatLng latLngPassengerDestination = LatLng(0, 0);
void onMapCreated(GoogleMapController controller) async { void onMapCreated(GoogleMapController controller) async {
myLocation = Get.find<LocationController>().location as LatLng; myLocation = Get.find<LocationController>().myLocation;
myLocation = myLocation; // myLocation = myLocation;
mapController = controller; mapController = controller;
controller.getVisibleRegion(); controller.getVisibleRegion();
controller.animateCamera( controller.animateCamera(
@@ -454,9 +454,10 @@ class MapDriverController extends GetxController {
} }
addWaitingTimeCostFromPassengerToDriverWallet() async { addWaitingTimeCostFromPassengerToDriverWallet() async {
double distance2 = calculateDistanceBetweenDriverAndPassengerLocation(); double distance2 =
await calculateDistanceBetweenDriverAndPassengerLocation();
if (distance2 > 40) { if (distance2 > 60) {
Get.defaultDialog( Get.defaultDialog(
title: 'Your are far from passenger location'.tr, title: 'Your are far from passenger location'.tr,
middleText: middleText:
@@ -893,12 +894,11 @@ class MapDriverController extends GetxController {
void addCustomCarIcon() { void addCustomCarIcon() {
ImageConfiguration config = ImageConfiguration( ImageConfiguration config = ImageConfiguration(
size: const Size(30, 30), devicePixelRatio: Get.pixelRatio size: const Size(30, 35), devicePixelRatio: Get.pixelRatio);
// scale: 1.0,
);
BitmapDescriptor.asset( BitmapDescriptor.asset(
config, config,
'assets/images/car.png', 'assets/images/car.png',
// mipmaps: false,
).then((value) { ).then((value) {
carIcon = value; carIcon = value;
update(); update();
@@ -999,11 +999,10 @@ class MapDriverController extends GetxController {
LatLng(bounds['southwest']['lat'], bounds['southwest']['lng']); LatLng(bounds['southwest']['lat'], bounds['southwest']['lng']);
// Create the LatLngBounds object // Create the LatLngBounds object
LatLngBounds boundsData = boundsData = LatLngBounds(northeast: northeast, southwest: southwest);
LatLngBounds(northeast: northeast, southwest: southwest);
// Fit the camera to the bounds // Fit the camera to the bounds
var cameraUpdate = CameraUpdate.newLatLngBounds(boundsData, 140); var cameraUpdate = CameraUpdate.newLatLngBounds(boundsData!, 140);
mapController!.animateCamera(cameraUpdate); mapController!.animateCamera(cameraUpdate);
update(); update();
} }

View File

@@ -161,12 +161,25 @@ class MyTranslation extends Translations {
"You dont have money in your Wallet": "ليس لديك أموال في محفظتك", "You dont have money in your Wallet": "ليس لديك أموال في محفظتك",
"You dont have money in your Wallet or you should less transfer 5 LE to activate": "You dont have money in your Wallet or you should less transfer 5 LE to activate":
"ليس لديك أموال في محفظتك أو يجب عليك تحويل 5 جنيهات على الأقل لتفعيل الحساب", "ليس لديك أموال في محفظتك أو يجب عليك تحويل 5 جنيهات على الأقل لتفعيل الحساب",
'I Arrive': "لقد وصلت",
'Rejected Orders Count': "عدد الطلبات المرفوضة",
'This is the total number of rejected orders per day after accepting the orders':
'هذا هو العدد الإجمالي للطلبات المرفوضة يوميًا بعد قبول الطلبات',
'You are not near the passenger location':
"أنت لست بالقرب من موقع الراكب",
'If you need assistance, contact us':
"إذا كنت بحاجة إلى المساعدة، تواصل معنا",
'You Can Cancel the Trip and get Cost From ':
"يمكنك إلغاء الرحلة والحصول على التكلفة من",
'Please go to the pickup location exactly':
"يرجى الذهاب إلى موقع الالتقاط بالضبط",
"Approaching your area. Should be there in 3 minutes.": "Approaching your area. Should be there in 3 minutes.":
"اقترب من منطقتك. يجب أن أكون هناك خلال 3 دقائق.", "اقترب من منطقتك. يجب أن أكون هناك خلال 3 دقائق.",
"There's heavy traffic here. Can you suggest an alternate pickup point?": "There's heavy traffic here. Can you suggest an alternate pickup point?":
"هناك حركة مرور كثيفة هنا. هل يمكنك اقتراح نقطة استلام بديلة؟", "هناك حركة مرور كثيفة هنا. هل يمكنك اقتراح نقطة استلام بديلة؟",
"This ride is already taken by another driver.": "This ride is already taken by another driver.":
"تم حجز هذه الرحلة من قبل سائق آخر.", "تم حجز هذه الرحلة من قبل سائق آخر.",
'Type Any thing': "اكتب أي شيء",
'Price: ': 'السعر ', 'Price: ': 'السعر ',
'Add Question': "أضف سؤالاً", 'Add Question': "أضف سؤالاً",
"Please enter a valid card 16-digit number.": "Please enter a valid card 16-digit number.":

View File

@@ -7,6 +7,7 @@ import 'package:SEFER/views/home/Captin/orderCaptin/order_request_page.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart'; import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_stripe/flutter_stripe.dart'; import 'package:flutter_stripe/flutter_stripe.dart';
@@ -59,7 +60,7 @@ Future<void> backgroundMessageHandler(RemoteMessage message) async {
} }
await Future.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
NotificationController1().showNotification( NotificationController().showNotification(
message.notification!.title.toString(), message.notification!.title.toString(),
message.notification!.body.toString(), message.notification!.body.toString(),
'order', 'order',
@@ -70,11 +71,11 @@ Future<void> backgroundMessageHandler(RemoteMessage message) async {
if (isOverlayActive) { if (isOverlayActive) {
await FlutterOverlayWindow.closeOverlay(); await FlutterOverlayWindow.closeOverlay();
} }
await FlutterOverlayWindow.shareData(myList);
await FlutterOverlayWindow.showOverlay( await FlutterOverlayWindow.showOverlay(
enableDrag: true, enableDrag: true,
flag: OverlayFlag.focusPointer, flag: OverlayFlag.focusPointer,
visibility: NotificationVisibility.visibilityPublic, // visibility: NotificationVisibility.visibilityPublic,
positionGravity: PositionGravity.auto, positionGravity: PositionGravity.auto,
height: 700, height: 700,
width: WindowSize.matchParent, width: WindowSize.matchParent,
@@ -89,6 +90,14 @@ Future<void> backgroundMessageHandler(RemoteMessage message) async {
} }
} }
@pragma('vm:entry-point')
void notificationTapBackground(NotificationResponse notificationResponse) {
// handle background notification taps here
print('Notification tapped in background!');
NotificationController().handleNotificationResponse(notificationResponse);
// You can add your logic here to handle the notification tap
}
@pragma('vm:entry-point') @pragma('vm:entry-point')
void overlayMain() async { void overlayMain() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
@@ -99,8 +108,12 @@ void overlayMain() async {
)); ));
} }
void closeOverLay() { Future<void> closeOverLay() async {
FlutterOverlayWindow.closeOverlay(); // FlutterOverlayWindow.closeOverlay();
bool isOverlayActive = await FlutterOverlayWindow.isActive();
if (isOverlayActive) {
await FlutterOverlayWindow.closeOverlay();
}
} }
void main() async { void main() async {
@@ -122,8 +135,11 @@ void main() async {
await FirebaseMessagesController().requestFirebaseMessagingPermission(); await FirebaseMessagesController().requestFirebaseMessagingPermission();
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
NotificationController1().initNotifications(); // NotificationController1().initNotifications();
// NotificationController().initNotifications(); // NotificationController().initNotifications();
if (Platform.isAndroid) {
await Get.put(NotificationController()).initNotifications();
}
await Future.wait([ await Future.wait([
FirebaseMessagesController().getNotificationSettings(), FirebaseMessagesController().getNotificationSettings(),

View File

@@ -1,6 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:SEFER/controller/auth/facebook_login.dart'; import 'package:SEFER/controller/auth/facebook_login.dart';
import 'package:SEFER/views/auth/captin/contact_us_page.dart';
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -258,10 +259,14 @@ class LoginCaptin extends StatelessWidget {
), ),
))), ))),
// Text( GestureDetector(
// 'if you don\'t have account'.tr, onTap: () => Get.to(() => ContactUsPage()),
// style: AppStyle.subtitle, child: Text(
// ), 'If you need assistance, contact us'
.tr, // Improved wording
style: AppStyle.subtitle,
),
),
// AnimatedTextKit( // AnimatedTextKit(
// onTap: () => Get.to(() => const RegisterCaptin()), // onTap: () => Get.to(() => const RegisterCaptin()),
// animatedTexts: [ // animatedTexts: [

View File

@@ -33,9 +33,11 @@ class PassengerLocationMapPage extends StatelessWidget {
.startTimerToShowPassengerInfoWindowFromDriver(); .startTimerToShowPassengerInfoWindowFromDriver();
} }
return MyScafolld( return Scaffold(
title: 'Map Passenger'.tr, // title: 'Map Passenger'.tr,
body: [ body: SafeArea(
child: Stack(
children: [
GoogleDriverMap(locationController: locationController), GoogleDriverMap(locationController: locationController),
const PassengerInfoWindow(), const PassengerInfoWindow(),
CancelWidget(mapDriverController: mapDriverController), CancelWidget(mapDriverController: mapDriverController),
@@ -45,7 +47,8 @@ class PassengerLocationMapPage extends StatelessWidget {
const GoogleMapApp(), const GoogleMapApp(),
const PricesWindow(), const PricesWindow(),
], ],
isleading: false); ),
));
} }
} }
@@ -81,7 +84,8 @@ class CancelWidget extends StatelessWidget {
], ],
), ),
confirm: MyElevatedButton( confirm: MyElevatedButton(
title: 'OK'.tr, title: 'Ok'.tr,
kolor: AppColor.redColor,
onPressed: () async { onPressed: () async {
// todo add cancel and inform passenger to get new driver // todo add cancel and inform passenger to get new driver
await mapDriverController await mapDriverController
@@ -89,8 +93,8 @@ class CancelWidget extends StatelessWidget {
Get.back(); Get.back();
}), }),
cancel: MyElevatedButton( cancel: MyElevatedButton(
title: 'NO'.tr, title: 'No'.tr,
kolor: AppColor.redColor, // kolor: AppColor.redColor,
onPressed: () { onPressed: () {
Get.back(); Get.back();
})); }));

View File

@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:SEFER/constant/box_name.dart'; import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/home/captin/map_driver_controller.dart'; import 'package:SEFER/controller/home/captin/map_driver_controller.dart';
import 'package:SEFER/views/notification/available_rides_page.dart'; import 'package:SEFER/views/notification/available_rides_page.dart';
import 'package:SEFER/views/widgets/mydialoug.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -56,7 +57,8 @@ class HomeCaptain extends StatelessWidget {
child: Text( child: Text(
orderRequestController.countRefuse.toString(), orderRequestController.countRefuse.toString(),
style: AppStyle.title, style: AppStyle.title,
))), )),
),
// IconButton( // IconButton(
// // onPressed: () => Get.find<OrderRequestController>().getSQL(), // // onPressed: () => Get.find<OrderRequestController>().getSQL(),
// onPressed: () => sql.deleteAllData(TableName.driverOrdersRefuse), // onPressed: () => sql.deleteAllData(TableName.driverOrdersRefuse),
@@ -84,9 +86,17 @@ class HomeCaptain extends StatelessWidget {
target: locationController.myLocation, target: locationController.myLocation,
zoom: 15, zoom: 15,
), ),
markers: {
mapType: Marker(
controller.mapType ? MapType.satellite : MapType.normal, markerId: MarkerId('MyLocation'.tr),
position: locationController.myLocation,
draggable: false,
icon: controller.carIcon,
rotation: locationController.heading)
},
mapType: controller.mapType
? MapType.satellite
: MapType.terrain,
myLocationButtonEnabled: true, myLocationButtonEnabled: true,
// liteModeEnabled: true, tiltGesturesEnabled: false, // liteModeEnabled: true, tiltGesturesEnabled: false,
@@ -95,7 +105,7 @@ class HomeCaptain extends StatelessWidget {
buildingsEnabled: true, buildingsEnabled: true,
mapToolbarEnabled: true, mapToolbarEnabled: true,
myLocationEnabled: true, myLocationEnabled: false,
// liteModeEnabled: true, // liteModeEnabled: true,
), ),
), ),

View File

@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:SEFER/constant/box_name.dart'; import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/firebase/local_notification.dart'; import 'package:SEFER/controller/firebase/local_notification.dart';
import 'package:SEFER/main.dart'; import 'package:SEFER/main.dart';
@@ -8,6 +10,7 @@ import 'package:SEFER/views/home/Captin/driver_map_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:bubble_head/bubble.dart'; import 'package:bubble_head/bubble.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart'; import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart';
@@ -178,18 +181,49 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
), ),
), ),
), ),
// AnimatedContainer(
// duration: const Duration(microseconds: 200), const SizedBox(
// width: controller.widthMapTypeAndTraffic, height: 5,
// decoration: BoxDecoration( ),
// color: AppColor.secondaryColor, Platform.isAndroid
// border: Border.all(color: AppColor.blueColor), ? AnimatedContainer(
// borderRadius: BorderRadius.circular(15)), duration: const Duration(microseconds: 200),
// child: Builder(builder: (context) { width: controller.widthMapTypeAndTraffic,
// return IconButton( decoration: BoxDecoration(
// onPressed: () async { color: AppColor.secondaryColor,
// // Get.to(() => EgyptCardAI()); border: Border.all(color: AppColor.blueColor),
// // print(box.read(BoxName.myList)); borderRadius: BorderRadius.circular(15)),
child: Builder(builder: (context) {
return IconButton(
onPressed: () async {
bool isOverlayActive =
await FlutterOverlayWindow.isActive();
if (isOverlayActive) {
await FlutterOverlayWindow.closeOverlay();
}
// print(box.read(BoxName.tokenDriver));
},
icon: const Icon(
FontAwesome5.window_close,
size: 29,
color: AppColor.blueColor,
),
);
}),
)
: const SizedBox(),
AnimatedContainer(
duration: const Duration(microseconds: 200),
width: controller.widthMapTypeAndTraffic,
decoration: BoxDecoration(
color: AppColor.secondaryColor,
border: Border.all(color: AppColor.blueColor),
borderRadius: BorderRadius.circular(15)),
child: Builder(builder: (context) {
return IconButton(
onPressed: () async {
Get.to(() => LoginCaptin());
// print(box.read(BoxName.myList));
// List<String> d = [ // List<String> d = [
// "30.003028,31.2419628", // "30.003028,31.2419628",
@@ -234,76 +268,31 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
// 'fKBBB4_1R0q18-byySHUeG:APA91bHk2RmjjMt6eKr7KQnqh4CK02yW3H5E8g_beVcQFgiCG50j9KCtSU1O8PtvS_gA5xuJLhaorDV9AeslcyLFJFf302tICKMiKgsDP5pWkF5WXNw0-4NsoD-BnJxf0-Do9Vs1Zbpq', // 'fKBBB4_1R0q18-byySHUeG:APA91bHk2RmjjMt6eKr7KQnqh4CK02yW3H5E8g_beVcQFgiCG50j9KCtSU1O8PtvS_gA5xuJLhaorDV9AeslcyLFJFf302tICKMiKgsDP5pWkF5WXNw0-4NsoD-BnJxf0-Do9Vs1Zbpq',
// d, // d,
// 'order.wav'); // 'order.wav');
// // NotificationController() // NotificationController()
// // .showNotification('VIP Order'.tr, '', 'order', ''); // .showNotification('VIP Order'.tr, '', 'order', '');
// // try {} catch (e) { // try {} catch (e) {
// // print('Error showing overlay: $e'); // print('Error showing overlay: $e');
// // } // }
// // final Bubble _bubble = Bubble(showCloseButton: true); // final Bubble _bubble = Bubble(showCloseButton: true);
// // try { // try {
// // await _bubble.startBubbleHead(sendAppToBackground: false); // await _bubble.startBubbleHead(sendAppToBackground: false);
// // } on PlatformException { // } on PlatformException {
// // print('Failed to call startBubbleHead'); // print('Failed to call startBubbleHead');
// // } // }
// // Bubble().startBubbleHead(sendAppToBackground: true);
// // }
// // Future<void> stopBubbleHead() async {
// // try {
// // await _bubble.stopBubbleHead();
// // } on PlatformException {
// // print('Failed to call stopBubbleHead');
// // }
// // }
// //
// // // // send data to ovelay
// },
// icon: const Icon(
// FontAwesome5.grin_tears,
// size: 29,
// color: AppColor.blueColor,
// ),
// );
// }),
// ),
AnimatedContainer(
duration: const Duration(microseconds: 200),
width: controller.widthMapTypeAndTraffic,
decoration: BoxDecoration(
color: AppColor.secondaryColor,
border: Border.all(color: AppColor.blueColor),
borderRadius: BorderRadius.circular(15)),
child: Builder(builder: (context) {
return IconButton(
onPressed: () async {
// FirebaseMessagesController().sendNotificationToAnyWithoutData(
// 'Order'.tr,
// 'from: ',
// // jsonDecode(value)['message'].toString(),
// 'fKBBB4_1R0q18-byySHUeG:APA91bHk2RmjjMt6eKr7KQnqh4CK02yW3H5E8g_beVcQFgiCG50j9KCtSU1O8PtvS_gA5xuJLhaorDV9AeslcyLFJFf302tICKMiKgsDP5pWkF5WXNw0-4NsoD-BnJxf0-Do9Vs1Zbpq',
// 'order.wav');
NotificationController1().showNotification(
'sdf'.tr,
'We regret to inform you that another driver has accepted this order.'
.tr,
'',
'');
// requestLocationPermission();
// Get.to(() => PassengerLocationMapPage(),
// arguments: box.read(BoxName.rideArguments));
print(box.read(BoxName.tokenDriver));
}, },
icon: const Icon( icon: const Icon(
FontAwesome5.closed_captioning, FontAwesome5.grin_tears,
size: 29, size: 29,
color: AppColor.blueColor, color: AppColor.blueColor,
), ),
); );
}), }),
), ),
const SizedBox(
height: 5,
),
], ],
)), ),
),
); );
} }

View File

@@ -21,14 +21,14 @@ GetBuilder<MapDriverController> driverEndRideBar() {
decoration: AppStyle.boxDecoration1, decoration: AppStyle.boxDecoration1,
height: mapDriverController.remainingTimeTimerRideBegin < 60 height: mapDriverController.remainingTimeTimerRideBegin < 60
? mapDriverController.driverEndPage = 190 ? mapDriverController.driverEndPage = 190
: mapDriverController.carType == 'Mashwari' : mapDriverController.carType == 'Mishwar Vip'
? 120 ? 120
: 170, : 170,
// width: 240, // width: 240,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
mapDriverController.carType != 'Mashwari' mapDriverController.carType != 'Mishwar Vip'
? Row( ? Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
@@ -63,8 +63,8 @@ GetBuilder<MapDriverController> driverEndRideBar() {
) )
: const SizedBox(), : const SizedBox(),
mapDriverController.carType != 'Speed' && mapDriverController.carType != 'Speed' &&
mapDriverController.carType != 'Delivery' && mapDriverController.carType != 'Awfar Car' &&
mapDriverController.carType != 'Balash' mapDriverController.carType != 'Scooter'
? Row( ? Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
@@ -168,7 +168,7 @@ GetBuilder<MapDriverController> driverEndRideBar() {
], ],
), ),
mapDriverController.carType != 'Comfort' && mapDriverController.carType != 'Comfort' &&
mapDriverController.carType != 'Mashwari' && mapDriverController.carType != 'Mishwar Vip' &&
mapDriverController.carType != 'Lady' mapDriverController.carType != 'Lady'
? Stack( ? Stack(
children: [ children: [

View File

@@ -20,28 +20,37 @@ class GoogleDriverMap extends StatelessWidget {
return Padding( return Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: GetBuilder<MapDriverController>( child: GetBuilder<MapDriverController>(
builder: (controller) => GoogleMap( builder: (controller) => Column(
children: [
SizedBox(
height: Get.height * .6,
child: GoogleMap(
onMapCreated: controller.onMapCreated, onMapCreated: controller.onMapCreated,
zoomControlsEnabled: true,
initialCameraPosition: CameraPosition( initialCameraPosition: CameraPosition(
// bearing: 45, // bearing: 45,
target: locationController.myLocation, target: locationController.myLocation,
zoom: 16, zoom: 13,
tilt: 40, tilt: 40,
), ),
onCameraMoveStarted: () {}, // onCameraMoveStarted: () {},
cameraTargetBounds: CameraTargetBounds(controller.boundsData),
onCameraMove: (position) { onCameraMove: (position) {
locationController.myLocation = position.target; locationController.myLocation = position.target;
controller.mapController! controller.mapController!
.animateCamera(CameraUpdate.newCameraPosition(position)); .animateCamera(CameraUpdate.newCameraPosition(position));
}, },
minMaxZoomPreference: const MinMaxZoomPreference(6, 18), minMaxZoomPreference: const MinMaxZoomPreference(8, 15),
myLocationEnabled: true, myLocationEnabled: true, myLocationButtonEnabled: true,
compassEnabled: true, compassEnabled: true,
mapType: MapType.normal, mapType: MapType.terrain,
trafficEnabled: true, rotateGesturesEnabled: true,
scrollGesturesEnabled: true,
trafficEnabled: false,
// liteModeEnabled: true,
buildingsEnabled: true, buildingsEnabled: true,
mapToolbarEnabled: true, mapToolbarEnabled: true,
zoomControlsEnabled: true, // zoomControlsEnabled: true,
fortyFiveDegreeImageryEnabled: true, fortyFiveDegreeImageryEnabled: true,
zoomGesturesEnabled: true, zoomGesturesEnabled: true,
polylines: { polylines: {
@@ -54,8 +63,8 @@ class GoogleDriverMap extends StatelessWidget {
visible: true, visible: true,
polylineId: const PolylineId('route1'), polylineId: const PolylineId('route1'),
points: controller.polylineCoordinates, points: controller.polylineCoordinates,
color: AppColor.yellowColor, color: const Color.fromARGB(255, 163, 81, 246),
width: 4, width: 5,
), ),
Polyline( Polyline(
zIndex: 2, zIndex: 2,
@@ -66,8 +75,8 @@ class GoogleDriverMap extends StatelessWidget {
visible: true, visible: true,
polylineId: const PolylineId('route'), polylineId: const PolylineId('route'),
points: controller.polylineCoordinatesDestination, points: controller.polylineCoordinatesDestination,
color: AppColor.primaryColor, color: const Color.fromARGB(255, 10, 29, 126),
width: 4, width: 5,
), ),
}, },
markers: { markers: {
@@ -92,6 +101,9 @@ class GoogleDriverMap extends StatelessWidget {
}, },
), ),
), ),
],
),
),
); );
} }
} }

View File

@@ -29,7 +29,7 @@ class PassengerInfoWindow extends StatelessWidget {
// left: 8, // left: 8,
child: AnimatedContainer( child: AnimatedContainer(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
height: Get.height * .35, height: Get.height * .4,
width: Get.width, width: Get.width,
decoration: AppStyle.boxDecoration1, decoration: AppStyle.boxDecoration1,
child: Padding( child: Padding(
@@ -289,80 +289,137 @@ class PassengerInfoWindow extends StatelessWidget {
), ),
], ],
)), )),
Row( Column(
mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Container( // First Row: Trip Info (Duration, Distance, Passenger Name)
decoration: AppStyle.boxDecoration1,
width: Get.width * .22,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
controller.hours > 1
? '⌚️ ${controller.hours}h ${controller.minutes}m' // Ride Duration with emoji
: '⌚️ ${controller.minutes}m', // Short ride duration
style: AppStyle.number,
),
),
),
const SizedBox(
width: 10.0), // Add spacing between sections
Container(
decoration: AppStyle.boxDecoration1,
width: Get.width * .22,
child: Padding(
padding: const EdgeInsets.all(4),
child: Text(
' ${controller.distance} km', // Distance with emoji
style: AppStyle.number,
),
),
),
const SizedBox(
width: 16.0), // Add spacing between sections
Container(
decoration: AppStyle.boxDecoration1,
width: Get.width * .35,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
controller
.passengerName, // Passenger name with emoji
style: AppStyle.title,
),
),
),
],
),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [ children: [
// Ride Duration
Container( Container(
decoration: AppStyle.boxDecoration1, decoration: AppStyle.boxDecoration1,
width: Get.width * .4, width: Get.width * .28,
child: Padding( child: Padding(
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(6.0),
child: Row( child: Row(
children: [ children: [
Text("cost is ".tr, Icon(Icons.timer,
style: AppStyle.title), color: Colors
.grey[700]), // Duration Icon
const SizedBox(width: 6),
Text( Text(
controller.totalPricePassenger controller.hours > 1
.toString(), ? '${controller.hours}h ${controller.minutes}${'m'.tr}'
: '${controller.minutes}${'m'.tr}',
style: AppStyle.number, style: AppStyle.number,
), ),
], ],
), ),
), ),
), ),
// Ride Distance
Container( Container(
decoration: AppStyle.boxDecoration1, decoration: AppStyle.boxDecoration1,
width: Get.width * .4, width: Get.width * .28,
child: Padding( child: Padding(
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(6.0),
child: Text(controller.carType.tr, child: Row(
style: AppStyle.title), children: [
Icon(Icons.map,
color: Colors
.grey[700]), // Distance Icon
const SizedBox(width: 6),
Text(
'${controller.distance} km',
style: AppStyle.number,
), ),
],
),
),
),
// Passenger Name
Container(
decoration: AppStyle.boxDecoration1,
width: Get.width * .38,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: [
Icon(Icons.person,
color: Colors
.grey[700]), // Passenger Icon
const SizedBox(width: 6),
Text(
controller.passengerName,
style: AppStyle.title,
),
],
),
),
),
],
),
const SizedBox(
height: 16), // Spacing between rows
// Second Row: Cost & Car Type
Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
// Ride Cost
Container(
decoration: AppStyle.boxDecoration1,
width: Get.width * .45,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(Icons.attach_money,
color: Colors
.grey[700]), // Cost Icon
const SizedBox(width: 6),
Text("cost is ".tr,
style: AppStyle.title),
],
),
Text(
controller.totalPricePassenger,
style: AppStyle.number,
),
],
),
),
),
// Car Type
Container(
decoration: AppStyle.boxDecoration1,
width: Get.width * .45,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: [
Icon(Icons.directions_car,
color:
Colors.grey[700]), // Car Icon
const SizedBox(width: 6),
Text(controller.carType.tr,
style: AppStyle.title),
],
),
),
),
],
), ),
], ],
), ),
@@ -370,82 +427,94 @@ class PassengerInfoWindow extends StatelessWidget {
? const SizedBox() ? const SizedBox()
: Column( : Column(
children: [ children: [
// First Row: Start Ride or Arrive at Location
Row( Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.spaceAround, MainAxisAlignment.spaceAround,
children: [ children: [
// Start Ride Button
MyElevatedButton( MyElevatedButton(
title: 'Start the Ride'.tr, title: 'Start the Ride'.tr,
kolor: AppColor.greenColor, kolor: AppColor.greenColor,
onPressed: () { onPressed: () {
Get.defaultDialog( Get.defaultDialog(
title: title:
'Is the Passenger in your Car ?' 'Is the Passenger in your Car?'
.tr, .tr,
titleStyle: AppStyle.title, titleStyle: AppStyle.title,
middleText: middleText:
"don't start trip if not" "Don't start trip if not".tr,
.tr, middleTextStyle: AppStyle.title,
middleTextStyle:
AppStyle.title,
confirm: MyElevatedButton( confirm: MyElevatedButton(
title: 'OK'.tr, title: 'OK'.tr,
kolor: kolor: AppColor.greenColor,
AppColor.greenColor,
onPressed: () async { onPressed: () async {
await controller await controller
.startRideFromDriver(); .startRideFromDriver();
Get.back(); Get.back(); // Close dialog after confirmation
}), },
),
cancel: MyElevatedButton( cancel: MyElevatedButton(
title: title: 'No, still Waiting.'.tr,
'No ,still Waiting.'
.tr,
kolor: AppColor.redColor, kolor: AppColor.redColor,
onPressed: () { onPressed: () {
Get.back(); Get.back(); // Close dialog without action
})); },
}), ),
);
},
),
// Arrive Notification Button
controller.isArrivedSend controller.isArrivedSend
? MyElevatedButton( ? MyElevatedButton(
title: 'I arrive you'.tr, title: 'I Arrive'.tr,
kolor: AppColor.yellowColor, kolor: AppColor.yellowColor,
onPressed: () async { onPressed: () async {
if (controller if (await controller
.calculateDistanceBetweenDriverAndPassengerLocation() < .calculateDistanceBetweenDriverAndPassengerLocation() <
40) { 40) {
// Notify Passenger
FirebaseMessagesController() FirebaseMessagesController()
.sendNotificationToPassengerToken( .sendNotificationToPassengerToken(
'Hi ,I Arrive your site', 'Hi, I Arrive at your site',
'I Arrive your site' 'I Arrive at your site'
.tr, .tr,
controller controller.tokenPassenger,
.tokenPassenger,
[], [],
'start.wav'); 'start.wav',
);
controller controller
.startTimerToShowDriverWaitPassengerDuration(); .startTimerToShowDriverWaitPassengerDuration();
controller.isArrivedSend = controller.isArrivedSend =
false; false;
} else { } else {
// Show error dialog if the driver is far from passenger
Get.defaultDialog( Get.defaultDialog(
title: title:
'You are not in near to passenger location' 'You are not near the passenger location'
.tr, .tr,
middleText: middleText:
'please go to picker location exactly' 'Please go to the pickup location exactly'
.tr, .tr,
confirm: confirm: MyElevatedButton(
MyElevatedButton(
title: 'Ok'.tr, title: 'Ok'.tr,
onPressed: () { onPressed: () {
Get.back(); Get.back();
})); },
),
);
} }
}) },
: const SizedBox() )
: const SizedBox(), // Hide if already sent
], ],
), ),
// const SizedBox(
// height: 16), // Space between rows
// Progress Bar for Waiting Time
controller.remainingTimeInPassengerLocatioWait < controller.remainingTimeInPassengerLocatioWait <
300 && 300 &&
controller controller
@@ -474,44 +543,57 @@ class PassengerInfoWindow extends StatelessWidget {
.stringRemainingTimeWaitingPassenger, .stringRemainingTimeWaitingPassenger,
style: AppStyle.title, style: AppStyle.title,
), ),
) ),
], ],
) )
: controller.isdriverWaitTimeEnd : const SizedBox(),
const SizedBox(
height:
16), // Space between progress and next section
// Cancel Trip and Charge Passenger
controller.isdriverWaitTimeEnd
? MyElevatedButton( ? MyElevatedButton(
title: 'You Can Cancel Trip And get Cost of Trip From' title:
'You Can Cancel the Trip and get Cost From '
.tr + .tr +
' ${AppInformation.appName}' AppInformation.appName.tr,
.tr, kolor: AppColor.deepPurpleAccent,
kolor:
AppColor.deepPurpleAccent,
onPressed: () { onPressed: () {
Get.defaultDialog( Get.defaultDialog(
title: title: 'Are you sure to cancel?'
'Are you sure to cancel?'
.tr, .tr,
titleStyle: titleStyle: AppStyle.title,
AppStyle.title,
middleText: '', middleText: '',
confirm: MyElevatedButton( confirm: MyElevatedButton(
title: 'Yes'.tr, title: 'Yes'.tr,
onPressed: () async { onPressed: () async {
FirebaseMessagesController() FirebaseMessagesController()
.sendNotificationToPassengerToken( .sendNotificationToPassengerToken(
'Driver Cancel Your Trip', 'Driver Cancelled Your Trip',
'You will be pay the cost to driver or we will get it from you on next trip' 'You will need to pay the cost to the driver, or it will be deducted from your next trip'
.tr, .tr,
controller controller.tokenPassenger,
.tokenPassenger,
[], [],
'cancel.wav'); 'cancel.wav',
);
await controller await controller
.addWaitingTimeCostFromPassengerToDriverWallet(); .addWaitingTimeCostFromPassengerToDriverWallet();
controller controller
.isdriverWaitTimeEnd = .isdriverWaitTimeEnd =
false; false;
})); },
}) ),
cancel: MyElevatedButton(
title: 'No'.tr,
onPressed: () {
Get.back();
},
),
);
},
)
: const SizedBox(), : const SizedBox(),
], ],
), ),

View File

@@ -9,6 +9,7 @@ import '../../../../constant/links.dart';
import '../../../../constant/style.dart'; import '../../../../constant/style.dart';
import '../../../../controller/functions/crud.dart'; import '../../../../controller/functions/crud.dart';
import '../../../../main.dart'; import '../../../../main.dart';
import '../../../../print.dart';
class OrderOverlay extends StatefulWidget { class OrderOverlay extends StatefulWidget {
const OrderOverlay({Key? key}) : super(key: key); const OrderOverlay({Key? key}) : super(key: key);
@@ -166,6 +167,7 @@ class _OrderOverlayState extends State<OrderOverlay>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String duration = (double.parse(d[4].toString()) / 60).toStringAsFixed(0); String duration = (double.parse(d[4].toString()) / 60).toStringAsFixed(0);
Log.print('duration: ${duration}');
String price = d[2].toString().split('.')[0]; String price = d[2].toString().split('.')[0];
return Material( return Material(
color: Colors.transparent, color: Colors.transparent,

View File

@@ -39,22 +39,6 @@ class OrderRequestPage extends StatelessWidget {
myList = arguments['DriverList']; myList = arguments['DriverList'];
} }
// Future.delayed(const Duration(milliseconds: 500));
// if (res.toString() == 'Apply' || res.toString() == 'Finished') {
// WidgetsBinding.instance.addPostFrameCallback((_) {
// Get.defaultDialog(
// barrierDismissible: false,
// title: 'This trip is taken'.tr,
// middleText: '',
// confirm: MyElevatedButton(
// title: 'Ok'.tr,
// onPressed: () {
// Get.back();
// }));
// });
// }
// final pointsList = arguments['PolylineJson'];
// final body = arguments['body'];
Duration durationToAdd = Duration(seconds: int.parse(myList[4])); Duration durationToAdd = Duration(seconds: int.parse(myList[4]));
int hours = durationToAdd.inHours; int hours = durationToAdd.inHours;
int minutes = (durationToAdd.inMinutes % 60).round(); int minutes = (durationToAdd.inMinutes % 60).round();

View File

@@ -26,9 +26,15 @@ class OrderSpeedRequest extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final arguments = Get.arguments; final arguments = Get.arguments;
var myList;
final myListString = arguments['myListString']; final myListString = arguments['myListString'];
final myList = arguments['DriverList']; // final myList = arguments['DriverList'];
// final pointsList = arguments['PolylineJson']; if (arguments['DriverList'] == null || arguments['DriverList'].isEmpty) {
myList = jsonDecode(myListString);
} else {
myList = arguments['DriverList'];
}
final body = arguments['body']; final body = arguments['body'];
Duration durationToAdd = Duration(seconds: int.parse(myList[4])); Duration durationToAdd = Duration(seconds: int.parse(myList[4]));
int hours = durationToAdd.inHours; int hours = durationToAdd.inHours;

View File

@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:SEFER/constant/colors.dart'; import 'package:SEFER/constant/colors.dart';
import 'mydialoug.dart';
class MyCircleContainer extends StatelessWidget { class MyCircleContainer extends StatelessWidget {
final Widget child; final Widget child;
final Color backgroundColor; final Color backgroundColor;
@@ -22,6 +24,12 @@ class MyCircleContainer extends StatelessWidget {
builder: ((controller) => GestureDetector( builder: ((controller) => GestureDetector(
onTap: () { onTap: () {
controller.changeColor(); controller.changeColor();
MyDialog().getDialog(
'Rejected Orders Count'.tr,
'This is the total number of rejected orders per day after accepting the orders'
.tr, () {
Get.back();
});
}, },
child: AnimatedContainer( child: AnimatedContainer(
onEnd: () { onEnd: () {