24-12/26/1

This commit is contained in:
Hamza-Ayed
2024-12-26 18:27:30 +03:00
parent 7751866428
commit d0dd09dc6c
10 changed files with 594 additions and 672 deletions

View File

@@ -35,7 +35,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>84</string> <string>85</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
@@ -50,7 +50,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>4.0.84</string> <string>4.0.85</string>
<key>FirebaseAppDelegateProxyEnabled</key> <key>FirebaseAppDelegateProxyEnabled</key>
<string>NO</string> <string>NO</string>
<key>GMSApiKey</key> <key>GMSApiKey</key>

View File

@@ -415,8 +415,12 @@ class MapDriverController extends GetxController {
'status': 'Begin' 'status': 'Begin'
}); });
} }
FirebaseMessagesController().sendNotificationToDriverMAP('RideIsBegin', FirebaseMessagesController().sendNotificationToDriverMAP(
box.read(BoxName.name).toString(), tokenPassenger, [], 'start.wav'); 'Trip is Begin'.tr,
box.read(BoxName.name).toString(),
tokenPassenger,
[],
'start.wav');
rideIsBeginPassengerTimer(); rideIsBeginPassengerTimer();
// var d = jsonDecode(res); // var d = jsonDecode(res);
@@ -725,7 +729,7 @@ class MapDriverController extends GetxController {
}); });
Future.delayed(const Duration(milliseconds: 300)); Future.delayed(const Duration(milliseconds: 300));
FirebaseMessagesController().sendNotificationToDriverMAP( FirebaseMessagesController().sendNotificationToDriverMAP(
'Driver Finish Trip', "Driver Finish Trip".tr,
'${'you will pay to Driver'.tr} $paymentAmount \$', '${'you will pay to Driver'.tr} $paymentAmount \$',
tokenPassenger, tokenPassenger,
[ [

View File

@@ -4,6 +4,38 @@ class MyTranslation extends Translations {
@override @override
Map<String, Map<String, String>> get keys => { Map<String, Map<String, String>> get keys => {
"ar": { "ar": {
"Call Passenger": "اتصل بالراكب",
"Send Message": "إرسال رسالة",
"Open in Maps": "فتح في الخرائط",
"Duration": "المدة",
"Distance": "المسافة",
"Passenger": "الراكب",
"Cost": "التكلفة",
"Car Type": "نوع ‏الطلب",
"Start the Ride": "ابدأ الرحلة",
"Is the Passenger in your Car?": "هل الراكب في سيارتك؟",
"Don't start trip if passenger not in your car":
"لا تبدأ الرحلة إذا لم يكن الراكب في سيارتك",
"I Arrive": "لقد وصلت", "Trip is Begin": "بدأت الرحلة",
"You are not near the passenger location":
"أنت لست بالقرب من موقع الراكب",
"Driver Finish Trip": "السواق أنهى الرحلة",
"Please go to the pickup location exactly":
"يرجى الذهاب إلى موقع الالتقاط بالضبط",
"You Can Cancel the Trip and get Cost From":
"يمكنك إلغاء الرحلة واسترداد التكلفة من",
"Are you sure to cancel?": "هل أنت متأكد من الإلغاء؟",
"Driver Cancelled Your Trip": "السائق ألغى رحلتك",
"You will need to pay the cost to the driver, or it will be deducted from your next trip":
"سيتم دفع التكلفة للسائق أو خصمها من رحلتك القادمة",
"Select a quick message": "اختر رسالة سريعة",
"Where are you, sir?": "أين أنت يا سيدي؟",
"I've been trying to reach you but your phone is off.":
"كنت أحاول الوصول إليك لكن هاتفك مغلق.",
"Please don't be late, I'm waiting for you at the specified location.":
"يرجى عدم التأخير، أنا في انتظارك في الموقع المحدد.",
"Please don't be late": "يرجى عدم التأخير",
"Type something": "اكتب شيئًا",
'Passenger Information': 'معلومات الراكب', 'Passenger Information': 'معلومات الراكب',
'Name': 'الاسم', 'Name': 'الاسم',
"wallet_updated": "تم تحديث المحفظة", "wallet_updated": "تم تحديث المحفظة",
@@ -857,11 +889,11 @@ Store your money with us and receive it in your bank as a monthly salary.''':
"Cancel Trip": "إلغاء الرحلة", "Cancel Trip": "إلغاء الرحلة",
"Passenger Cancel Trip": "الرحلة ألغيت من قبل المسافر", "Passenger Cancel Trip": "الرحلة ألغيت من قبل المسافر",
"Please stay on the picked point.": "يرجى البقاء على النقطة المحددة.", "Please stay on the picked point.": "يرجى البقاء على النقطة المحددة.",
"Trip is Begin": "الرحلة بدأت",
"Hi ,I will go now": "مرحبًا، سأذهب الآن", "Hi ,I will go now": "مرحبًا، سأذهب الآن",
"Passenger come to you": "الراكب يأتي إليك", "Passenger come to you": "الراكب يأتي إليك",
"Hi ,I Arrive your site": "مرحبًا، لقد وصلت إلى موقعك.", "Hi ,I Arrive your site": "مرحبًا، لقد وصلت إلى موقعك.",
"Driver Finish Trip": "انتهاء الرحلة للسائق",
"you will pay to Driver": "سوف تدفع للسائق", "you will pay to Driver": "سوف تدفع للسائق",
"Driver Cancel Your Trip": "ألغِ رحلتك، سائق.", "Driver Cancel Your Trip": "ألغِ رحلتك، سائق.",
"you will pay to Driver you will be pay the cost of driver time look to your SEFER Wallet": "you will pay to Driver you will be pay the cost of driver time look to your SEFER Wallet":

View File

@@ -48,7 +48,7 @@ class PassengerLocationMapPage extends StatelessWidget {
driverEndRideBar(), driverEndRideBar(),
const SosConnect(), const SosConnect(),
speedCircle(), speedCircle(),
const GoogleMapApp(), // const GoogleMapApp(),
const PricesWindow(), const PricesWindow(),
], ],
), ),

View File

@@ -66,7 +66,11 @@ class HomeCaptain extends StatelessWidget {
), ),
title: Row( title: Row(
children: [ children: [
Image.asset('assets/images/logo.png', height: 32), Image.asset(
'assets/images/logo.gif',
height: 32,
width: 35,
),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
'SEFER'.tr, 'SEFER'.tr,

View File

@@ -14,7 +14,7 @@ class GoogleMapApp extends StatelessWidget {
return GetBuilder<MapDriverController>( return GetBuilder<MapDriverController>(
builder: (mapDriverController) => mapDriverController.isRideStarted builder: (mapDriverController) => mapDriverController.isRideStarted
? Positioned( ? Positioned(
left: 125, left: 150,
bottom: 20, bottom: 20,
child: Container( child: Container(
decoration: AppStyle.boxDecoration, decoration: AppStyle.boxDecoration,

View File

@@ -17,480 +17,179 @@ import '../../../../constant/style.dart';
import '../../../../controller/functions/launch.dart'; import '../../../../controller/functions/launch.dart';
class PassengerInfoWindow extends StatelessWidget { class PassengerInfoWindow extends StatelessWidget {
const PassengerInfoWindow({ const PassengerInfoWindow({super.key});
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Get.put(MapDriverController());
return GetBuilder<MapDriverController>( return GetBuilder<MapDriverController>(
builder: (controller) => controller.isPassengerInfoWindow == true builder: (controller) => controller.isPassengerInfoWindow == true
? Stack( ? Positioned(
children: [ bottom: 10,
Positioned( left: 10,
bottom: 5, right: 10,
// left: 8, child: Card(
child: AnimatedContainer( elevation: 5,
duration: const Duration(milliseconds: 300), shape: RoundedRectangleBorder(
height: Get.height * .4, borderRadius: BorderRadius.circular(15),
width: Get.width, ),
decoration: AppStyle.boxDecoration1,
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(16.0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
DefaultTextStyle( Row(
style: AppStyle.title, mainAxisAlignment: MainAxisAlignment.spaceBetween,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'Go to passenger Location'.tr, 'Go to passenger Location'.tr,
style: AppStyle.title style: AppStyle.title.copyWith(
.copyWith(color: AppColor.greenColor), color: AppColor.greenColor,
fontWeight: FontWeight.bold,
), ),
controller.isRideBegin ),
? const SizedBox() if (!controller.isRideBegin)
: Row( Wrap(
mainAxisAlignment: spacing: 16.0,
MainAxisAlignment.spaceAround,
children: [ children: [
GestureDetector(
onTap: () async {
controller.isSocialPressed =
true;
await controller
.driverCallPassenger(); // to check from scam
// Get.to(
// () => const CallPage());
makePhoneCall(controller
.passengerPhone
.toString());
// launchCommunication(
// 'phone',
// controller.passengerPhone
// ,
// '');
},
child: const Icon(
Icons.phone,
color: AppColor.blueColor,
)),
const SizedBox(
width: 25,
),
GestureDetector(
onTap: () async {
Get.defaultDialog(
title:
'Select one message'
.tr,
titleStyle:
AppStyle.title,
content: SizedBox(
height: Get.height * .5,
width: Get.width * .6,
child: ListView(
// mainAxisAlignment:
// MainAxisAlignment
// .spaceEvenly,
children: [
InkWell(
onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Where are you, sir?"
.tr,
controller
.tokenPassenger,
[],
'ding.wav');
Get.back();
},
child: Container(
decoration: AppStyle
.boxDecoration1,
child: Padding(
padding:
const EdgeInsets
.all(
10),
child: Text(
"Where are you, sir?"
.tr,
style: AppStyle
.title,
),
),
),
),
const SizedBox(
height: 5,
),
InkWell(
onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"I've been trying to reach you but your phone is off."
.tr,
controller
.tokenPassenger,
[],
'ding.wav');
Get.back();
},
child: Container(
decoration: AppStyle
.boxDecoration1,
child: Padding(
padding:
const EdgeInsets
.all(
10),
child: Text(
"I've been trying to reach you but your phone is off."
.tr,
style: AppStyle
.title,
),
),
),
),
const SizedBox(
height: 5,
),
InkWell(
onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Please don't be late, I'm waiting for you at the specified location."
.tr,
controller
.tokenPassenger,
[],
'ding.wav');
Get.back();
},
child: Container(
decoration: AppStyle
.boxDecoration1,
child: Padding(
padding:
const EdgeInsets
.all(
10),
child: Text(
"Please don't be late, I'm waiting for you at the specified location."
.tr,
style: AppStyle
.title,
),
),
),
),
const SizedBox(
height: 5,
),
InkWell(
onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Please don't be late"
.tr,
controller
.tokenPassenger,
[],
'cancel.wav');
Get.back();
},
child: Container(
decoration: AppStyle
.boxDecoration1,
child: Padding(
padding:
const EdgeInsets
.all(
10),
child: Text(
"Please don't be late"
.tr,
style: AppStyle
.title,
),
),
),
),
const SizedBox(
height: 5,
),
SizedBox(
width: 200,
child: Row(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Form(
key: controller
.formKey2,
child:
SizedBox(
width:
160,
child: MyTextForm(
controller:
controller.messageToPassenger,
label: 'Type Any thing'.tr,
hint: 'Type Any thing'.tr,
type: TextInputType.name),
)),
IconButton( IconButton(
onPressed: onPressed: () async {
() { controller.isSocialPressed = true;
FirebaseMessagesController().sendNotificationToDriverMAP( await controller.driverCallPassenger();
'message From Driver', makePhoneCall(
controller.messageToPassenger.text, controller.passengerPhone.toString());
controller.tokenPassenger,
[],
'ding.wav');
controller
.messageToPassenger
.clear();
Get.back();
}, },
icon: const Icon( icon: const Icon(
Icons Icons.phone,
.send)) color: AppColor.blueColor,
],
), ),
) tooltip: 'Call Passenger',
],
), ),
)); IconButton(
onPressed: () {
Get.bottomSheet(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20)),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: _buildMessageOptions(controller),
),
);
}, },
child: const Icon( icon: const Icon(
Icons.message, Icons.message,
color: AppColor.redColor, color: AppColor.redColor,
)),
const SizedBox(
width: 25,
), ),
Container( tooltip: 'Send Message',
decoration: ),
AppStyle.boxDecoration, IconButton(
child: IconButton(
onPressed: () async { onPressed: () async {
if (Platform.isAndroid) { if (Platform.isAndroid) {
Bubble().startBubbleHead( Bubble().startBubbleHead(
sendAppToBackground: sendAppToBackground: true);
true);
} }
await controller await controller
.openGoogleMapFromDriverToPassenger(); .openGoogleMapFromDriverToPassenger();
}, },
icon: const Icon( icon: const Icon(
MaterialCommunityIcons MaterialCommunityIcons.map_marker_radius,
.map_marker_radius, size: 28,
size: 35,
color: AppColor.blueColor, color: AppColor.blueColor,
), ),
)), tooltip: 'Open in Maps',
),
], ],
), ),
], ],
)), ),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildInfoTile(
icon: Icons.timer,
text: controller.hours > 1
? '${controller.hours}h ${controller.minutes}m'
: '${controller.minutes}m',
label: 'Duration',
),
_buildInfoTile(
icon: Icons.map,
text: '${controller.distance} km',
label: 'Distance',
),
_buildInfoTile(
icon: Icons.person,
text: controller.passengerName,
label: 'Passenger',
),
],
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildInfoTile(
icon: Icons.attach_money,
text: controller.totalPricePassenger,
label: 'Cost',
),
_buildInfoTile(
icon: Icons.directions_car,
text: controller.carType.tr,
label: 'Car Type',
),
],
),
const SizedBox(height: 16),
if (!controller.isRideBegin)
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// First Row: Trip Info (Duration, Distance, Passenger Name)
Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
// Ride Duration
Container(
decoration: AppStyle.boxDecoration1,
width: Get.width * .28,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: [
Icon(Icons.timer,
color: Colors
.grey[700]), // Duration Icon
const SizedBox(width: 6),
Text(
controller.hours > 1
? '${controller.hours}h ${controller.minutes}${'m'.tr}'
: '${controller.minutes}${'m'.tr}',
style: AppStyle.number,
),
],
),
),
),
// Ride Distance
Container(
decoration: AppStyle.boxDecoration1,
width: Get.width * .28,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: [
Icon(Icons.map,
color: Colors
.grey[700]), // Distance Icon
const SizedBox(width: 6),
Text(
'${controller.distance} km',
style: AppStyle.number,
),
],
),
),
),
// Passenger Name
Container(
decoration: AppStyle.boxDecoration1,
width: Get.width * .38,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: [
Icon(Icons.person,
color: Colors
.grey[700]), // Passenger Icon
const SizedBox(width: 6),
Text(
controller.passengerName,
style: AppStyle.title,
),
],
),
),
),
],
),
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: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
Icon(Icons.attach_money, Expanded(
color: Colors child: MyElevatedButton(
.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),
],
),
),
),
],
),
],
),
controller.isRideBegin
? const SizedBox()
: Column(
children: [
// First Row: Start Ride or Arrive at Location
Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
// Start Ride Button
MyElevatedButton(
title: 'Start the Ride'.tr, title: 'Start the Ride'.tr,
kolor: AppColor.greenColor, kolor: AppColor.greenColor,
onPressed: () { onPressed: () {
MyDialog().getDialog( MyDialog().getDialog(
"Is the Passenger in your Car?" "Is the Passenger in your Car?".tr,
.tr, // "هل الراكب في سيارتك؟"
"Don't start trip if passenger not in your car" "Don't start trip if passenger not in your car"
.tr, // "لا تبدأ الرحلة إذا لم يكن الراكب في سيارتك" .tr,
() async { () async {
await controller await controller
.startRideFromDriver(); .startRideFromDriver();
Get.back(); Get.back();
// Close dialog after confirmation
}, },
); );
}, },
), ),
),
// Arrive Notification Button const SizedBox(width: 8),
controller.isArrivedSend if (controller.isArrivedSend)
? MyElevatedButton( Expanded(
child: MyElevatedButton(
title: 'I Arrive'.tr, title: 'I Arrive'.tr,
kolor: AppColor.yellowColor, kolor: AppColor.yellowColor,
onPressed: () async { onPressed: () async {
if (await controller if (await controller
.calculateDistanceBetweenDriverAndPassengerLocation() < .calculateDistanceBetweenDriverAndPassengerLocation() <
140) { 140) {
// Notify Passenger
FirebaseMessagesController() FirebaseMessagesController()
.sendNotificationToDriverMAP( .sendNotificationToDriverMAP(
'Hi ,I Arrive your site', 'Hi ,I Arrive your site',
'I Arrive at your site' 'I Arrive at your site'.tr,
.tr,
controller.tokenPassenger, controller.tokenPassenger,
[], [],
'ding.wav', 'ding.wav',
); );
controller controller
.startTimerToShowDriverWaitPassengerDuration(); .startTimerToShowDriverWaitPassengerDuration();
controller.isArrivedSend = controller.isArrivedSend = false;
false;
} else { } else {
MyDialog().getDialog( MyDialog().getDialog(
'You are not near the passenger location' 'You are not near the passenger location'
@@ -499,58 +198,44 @@ class PassengerInfoWindow extends StatelessWidget {
.tr, () { .tr, () {
Get.back(); Get.back();
}); });
// Show error dialog if the driver is far from passenger
} }
}, },
) ),
: const SizedBox(), // Hide if already sent ),
], ],
), ),
const SizedBox(height: 12),
// const SizedBox( if (controller.remainingTimeInPassengerLocatioWait <
// height: 16), // Space between rows
// Progress Bar for Waiting Time
controller.remainingTimeInPassengerLocatioWait <
300 && 300 &&
controller controller
.remainingTimeInPassengerLocatioWait != .remainingTimeInPassengerLocatioWait !=
0 0)
? Stack( Stack(
alignment: Alignment.center,
children: [ children: [
LinearProgressIndicator( LinearProgressIndicator(
backgroundColor: backgroundColor: AppColor.greyColor,
AppColor.greyColor,
color: controller color: controller
.remainingTimeInPassengerLocatioWait < .remainingTimeInPassengerLocatioWait <
60 60
? AppColor.redColor ? AppColor.redColor
: AppColor.greenColor, : AppColor.greenColor,
minHeight: 25, minHeight: 20,
borderRadius: borderRadius: BorderRadius.circular(10),
BorderRadius.circular(15),
value: controller value: controller
.progressInPassengerLocationFromDriver .progressInPassengerLocationFromDriver
.toDouble(), .toDouble(),
), ),
Center( Text(
child: Text(
controller controller
.stringRemainingTimeWaitingPassenger, .stringRemainingTimeWaitingPassenger,
style: AppStyle.title, style: AppStyle.title,
), ),
),
], ],
) ),
: const SizedBox(), const SizedBox(height: 12),
if (controller.isdriverWaitTimeEnd)
const SizedBox( MyElevatedButton(
height:
16), // Space between progress and next section
// Cancel Trip and Charge Passenger
controller.isdriverWaitTimeEnd
? MyElevatedButton(
title: title:
'You Can Cancel the Trip and get Cost From ' 'You Can Cancel the Trip and get Cost From '
.tr + .tr +
@@ -558,8 +243,8 @@ class PassengerInfoWindow extends StatelessWidget {
kolor: AppColor.deepPurpleAccent, kolor: AppColor.deepPurpleAccent,
onPressed: () { onPressed: () {
MyDialog().getDialog( MyDialog().getDialog(
'Are you sure to cancel?'.tr, 'Are you sure to cancel?'.tr, '',
'', () async { () async {
FirebaseMessagesController() FirebaseMessagesController()
.sendNotificationToDriverMAP( .sendNotificationToDriverMAP(
'Driver Cancelled Your Trip', 'Driver Cancelled Your Trip',
@@ -571,23 +256,145 @@ class PassengerInfoWindow extends StatelessWidget {
); );
await controller await controller
.addWaitingTimeCostFromPassengerToDriverWallet(); .addWaitingTimeCostFromPassengerToDriverWallet();
controller.isdriverWaitTimeEnd = controller.isdriverWaitTimeEnd = false;
false;
Get.back(); Get.back();
}); });
}, },
) ),
: const SizedBox(),
], ],
), ),
], ],
), ),
), ),
), ),
),
],
) )
: const SizedBox(), : const SizedBox(),
); );
} }
Widget _buildInfoTile({
required IconData icon,
required String text,
required String label,
}) {
return Column(
children: [
Icon(icon, color: Colors.grey[700]),
const SizedBox(height: 4),
Text(text, style: AppStyle.title.copyWith(fontWeight: FontWeight.bold)),
Text(label.tr, style: AppStyle.title),
],
);
}
Widget _buildMessageOptions(MapDriverController controller) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Select a quick message'.tr, style: AppStyle.title),
const SizedBox(height: 16),
_buildMessageTile(
text: "Where are you, sir?".tr,
onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Where are you, sir?".tr,
controller.tokenPassenger,
[],
'ding.wav',
);
Get.back();
},
),
_buildMessageTile(
text: "I've been trying to reach you but your phone is off.".tr,
onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"I've been trying to reach you but your phone is off.".tr,
controller.tokenPassenger,
[],
'ding.wav',
);
Get.back();
},
),
_buildMessageTile(
text:
"Please don't be late, I'm waiting for you at the specified location."
.tr,
onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Please don't be late, I'm waiting for you at the specified location."
.tr,
controller.tokenPassenger,
[],
'ding.wav',
);
Get.back();
},
),
_buildMessageTile(
text: "Please don't be late".tr,
onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Please don't be late".tr,
controller.tokenPassenger,
[],
'cancel.wav',
);
Get.back();
},
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: Form(
key: controller.formKey2,
child: MyTextForm(
controller: controller.messageToPassenger,
label: 'Type something'.tr,
hint: 'Type something'.tr,
type: TextInputType.text,
),
),
),
IconButton(
onPressed: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
controller.messageToPassenger.text,
controller.tokenPassenger,
[],
'ding.wav',
);
controller.messageToPassenger.clear();
Get.back();
},
icon: const Icon(Icons.send),
),
],
),
],
);
}
Widget _buildMessageTile(
{required String text, required VoidCallback onTap}) {
return InkWell(
onTap: onTap,
child: Container(
padding: const EdgeInsets.all(12),
margin: const EdgeInsets.symmetric(vertical: 4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.grey[100],
),
child: Text(text, style: AppStyle.title),
),
);
}
} }

View File

@@ -1,3 +1,6 @@
import 'dart:io';
import 'package:bubble_head/bubble.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:get/get.dart'; import 'package:get/get.dart';
@@ -5,6 +8,7 @@ import 'package:sefer_driver/constant/info.dart';
import 'package:sefer_driver/controller/functions/location_controller.dart'; import 'package:sefer_driver/controller/functions/location_controller.dart';
import 'package:sefer_driver/views/widgets/elevated_btn.dart'; import 'package:sefer_driver/views/widgets/elevated_btn.dart';
import 'package:sefer_driver/views/widgets/my_textField.dart'; import 'package:sefer_driver/views/widgets/my_textField.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../../constant/box_name.dart'; import '../../../../constant/box_name.dart';
import '../../../../constant/colors.dart'; import '../../../../constant/colors.dart';
@@ -14,104 +18,176 @@ import '../../../../controller/home/captin/map_driver_controller.dart';
import '../../../../main.dart'; import '../../../../main.dart';
class SosConnect extends StatelessWidget { class SosConnect extends StatelessWidget {
const SosConnect({ const SosConnect({super.key});
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GetBuilder<MapDriverController>( return GetBuilder<MapDriverController>(
builder: (mapDriverController) => mapDriverController.isRideStarted builder: (mapDriverController) => mapDriverController.isRideStarted
? Positioned( ? Positioned(
left: 5, left: 16,
bottom: 20, bottom: 16,
child: Container( child: Card(
decoration: AppStyle.boxDecoration, elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: SizedBox(
height: 60, height: 60,
width: 110, width: 180,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
InkWell( IconButton(
onTap: () {
if (box.read(BoxName.sosPhoneDriver) == null) {
Get.defaultDialog(
title: 'Insert Emergincy Number'.tr,
content: Form(
key: mapDriverController.formKey1,
child: MyTextForm(
controller: mapDriverController
.sosEmergincyNumberCotroller,
label: 'Insert Emergency Number'.tr,
hint: 'Insert Emergency Number'.tr,
type: TextInputType.phone),
),
confirm: MyElevatedButton(
title: 'Insert'.tr,
onPressed: () { onPressed: () {
if (mapDriverController _handleSosCall(mapDriverController);
.formKey1.currentState!
.validate()) {
box.write(
BoxName.sosPhoneDriver,
mapDriverController
.sosEmergincyNumberCotroller
.text);
}
}));
}
launchCommunication(
'phone', box.read(BoxName.sosPhoneDriver), '');
}, },
child: const Icon( icon: const Icon(
Icons.sos_sharp, Icons.sos_sharp,
size: 45, size: 32,
color: AppColor.redColor, color: AppColor.redColor,
), ),
tooltip: 'SOS - Call Emergency',
), ),
InkWell( VerticalDivider(
onTap: () { color: Colors.grey[300],
thickness: 1,
),
IconButton(
onPressed: () {
_handleWhatsApp(mapDriverController);
},
icon: const Icon(
FontAwesome.whatsapp,
color: AppColor.greenColor,
size: 32,
),
tooltip: 'SOS - Send WhatsApp Message',
),
VerticalDivider(
color: Colors.grey[300],
thickness: 1,
),
IconButton(
onPressed: () {
_handleGoogleMap(mapDriverController);
},
icon: const Icon(
MaterialCommunityIcons.map_marker_radius,
color: AppColor.primaryColor,
size: 32,
),
tooltip: 'Google Maps - Navigate',
),
],
),
),
),
)
: const SizedBox(),
);
}
void _handleSosCall(MapDriverController mapDriverController) {
if (box.read(BoxName.sosPhoneDriver) == null) { if (box.read(BoxName.sosPhoneDriver) == null) {
Get.defaultDialog( Get.defaultDialog(
title: 'Insert Emergency Number'.tr, title: 'Insert Emergency Number'.tr,
content: Form( content: Form(
key: mapDriverController.formKey1, key: mapDriverController.formKey1,
child: MyTextForm( child: MyTextForm(
controller: mapDriverController controller: mapDriverController.sosEmergincyNumberCotroller,
.sosEmergincyNumberCotroller, label: 'Emergency Number'.tr,
label: 'Insert Emergency Number'.tr, hint: 'Enter phone number'.tr,
hint: 'Insert Emergency Number'.tr, type: TextInputType.phone,
type: TextInputType.phone), ),
), ),
confirm: MyElevatedButton( confirm: MyElevatedButton(
title: 'Insert'.tr, title: 'Save'.tr,
onPressed: () { onPressed: () {
if (mapDriverController if (mapDriverController.formKey1.currentState!.validate()) {
.formKey1.currentState! box.write(BoxName.sosPhoneDriver,
.validate()) { mapDriverController.sosEmergincyNumberCotroller.text);
box.write( Get.back(); // Close the dialog
BoxName.sosPhoneDriver,
mapDriverController
.sosEmergincyNumberCotroller
.text);
}
}));
} else {
launchCommunication( launchCommunication(
'whatsapp', 'phone', box.read(BoxName.sosPhoneDriver), '');
'+2${box.read(BoxName.sosPhoneDriver)}', //todo add number from driver
"${"Hello this is Driver".tr} ${box.read(BoxName.nameDriver)}.${" My current location is:".tr} https://www.google.com/maps/place/${Get.find<LocationController>().myLocation.latitude},${Get.find<LocationController>().myLocation.longitude}${" \nand I have a trip on".tr} ${AppInformation.appName} ${"App \nwith Passenger ".tr}${mapDriverController.passengerName}");
} }
}, },
child: const Icon(
FontAwesome.whatsapp,
color: AppColor.greenColor,
size: 45,
), ),
), );
], } else {
), launchCommunication('phone', box.read(BoxName.sosPhoneDriver), '');
)) }
: const SizedBox()); }
void _handleWhatsApp(MapDriverController mapDriverController) {
if (box.read(BoxName.sosPhoneDriver) == null) {
Get.defaultDialog(
title: 'Insert Emergency Number'.tr,
content: Form(
key: mapDriverController.formKey1,
child: MyTextForm(
controller: mapDriverController.sosEmergincyNumberCotroller,
label: 'Emergency Number'.tr,
hint: 'Enter phone number'.tr,
type: TextInputType.phone,
),
),
confirm: MyElevatedButton(
title: 'Save'.tr,
onPressed: () {
if (mapDriverController.formKey1.currentState!.validate()) {
box.write(BoxName.sosPhoneDriver,
mapDriverController.sosEmergincyNumberCotroller.text);
Get.back(); // Close the dialog
_sendWhatsAppMessage(mapDriverController);
}
},
),
);
} else {
_sendWhatsAppMessage(mapDriverController);
}
}
void _handleGoogleMap(MapDriverController mapDriverController) {
() async {
if (Platform.isAndroid) {
Bubble().startBubbleHead(sendAppToBackground: true);
}
var startLat =
Get.find<MapDriverController>().latLngPassengerLocation.latitude;
var startLng =
Get.find<MapDriverController>().latLngPassengerLocation.longitude;
var endLat =
Get.find<MapDriverController>().latLngPassengerDestination.latitude;
var endLng =
Get.find<MapDriverController>().latLngPassengerDestination.longitude;
String url =
'https://www.google.com/maps/dir/$startLat,$startLng/$endLat,$endLng/&directionsmode=driving';
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
} else {
throw 'Could not launch google maps';
}
};
}
void _sendWhatsAppMessage(MapDriverController mapDriverController) {
final sosNumber = box.read(BoxName.sosPhoneDriver);
if (sosNumber != null) {
launchCommunication(
'whatsapp',
'+2$sosNumber', // Consider international format
"${"Hello, this is Driver".tr} ${box.read(BoxName.nameDriver)}. "
"${"My current location is:".tr} "
"https://www.google.com/maps/place/"
"${Get.find<LocationController>().myLocation.latitude},"
"${Get.find<LocationController>().myLocation.longitude} "
"${"\nI have a trip on".tr} ${AppInformation.appName} "
"${"app with passenger".tr} ${mapDriverController.passengerName}.",
);
}
} }
} }

View File

@@ -429,6 +429,35 @@ class _OrderRequestPageState extends State<OrderRequestPage> {
box.write(BoxName.statusDriverLocation, 'on'); box.write(BoxName.statusDriverLocation, 'on');
orderRequestController.endTimer(); orderRequestController.endTimer();
orderRequestController.changeApplied(); orderRequestController.changeApplied();
///
var res = await CRUD().post(
link: AppLink.updateStausFromSpeed,
payload: {
'id': orderRequestController.myList[16],
'rideTimeStart': DateTime.now().toString(),
'status': 'Apply',
'driver_id': box.read(BoxName.driverID),
});
if (AppLink.endPoint != AppLink.seferCairoServer) {
CRUD().post(
link:
"${AppLink.endPoint}/ride/rides/updateStausFromSpeed.php",
payload: {
'id': orderRequestController.myList[16],
'rideTimeStart': DateTime.now().toString(),
'status': 'Apply',
'driver_id': box.read(BoxName.driverID),
});
}
if (res == 'failure') {
MyDialog().getDialog(
"This ride is already applied by another driver."
.tr,
'', () {
Get.back();
});
} else {
await CRUD().postFromDialogue( await CRUD().postFromDialogue(
link: AppLink.addDriverOrder, link: AppLink.addDriverOrder,
payload: { payload: {
@@ -448,36 +477,6 @@ class _OrderRequestPageState extends State<OrderRequestPage> {
'status': 'Apply' 'status': 'Apply'
}); });
} }
///
var res = await CRUD().post(
link: AppLink.updateRideAndCheckIfApplied,
payload: {
'id': myList[16],
'rideTimeStart': DateTime.now().toString(),
'status': 'Apply',
'driver_id': myList[6].toString(),
});
if (AppLink.endPoint != AppLink.seferCairoServer) {
CRUD().post(
link:
'${AppLink.endPoint}/rides/updateRideAndCheckIfApplied.php',
payload: {
'id': myList[16],
'rideTimeStart': DateTime.now().toString(),
'status': 'Apply',
'driver_id': myList[6].toString(),
});
}
if (res == 'failure') {
MyDialog().getDialog(
"This ride is already applied by another driver."
.tr,
'', () {
Get.back();
});
} else {
List<String> bodyToPassenger = [ List<String> bodyToPassenger = [
myList[6].toString(), //driver id myList[6].toString(), //driver id
myList[8].toString(), // driver name myList[8].toString(), // driver name

View File

@@ -27,7 +27,7 @@ class MyElevatedButton extends StatelessWidget {
bool vibrate = box.read(BoxName.isvibrate) ?? true; bool vibrate = box.read(BoxName.isvibrate) ?? true;
return ElevatedButton( return ElevatedButton(
style: ButtonStyle( style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(AppColor.blueColor), backgroundColor: WidgetStateProperty.all(kolor),
shadowColor: WidgetStateProperty.all(Colors.transparent), shadowColor: WidgetStateProperty.all(Colors.transparent),
shape: WidgetStateProperty.all( shape: WidgetStateProperty.all(
RoundedRectangleBorder( RoundedRectangleBorder(