24-12/26/1

This commit is contained in:
Hamza-Ayed
2024-12-26 00:58:41 +03:00
parent 970e444f4a
commit 186cd3aa54
14 changed files with 2912 additions and 3466 deletions

View File

@@ -18,472 +18,34 @@ class ApplyOrderWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
Color _parseColor(String colorHex) {
if (colorHex.isEmpty) {
return Colors.grey; // Fallback for empty color
}
// Ensure the string starts with '0xff' for ARGB format
if (colorHex.isEmpty) return Colors.grey;
String processedHex = colorHex.replaceFirst('#', '0xff').trim();
if (!processedHex.startsWith('0xff')) {
processedHex = '0xff$processedHex'; // Add '0xff' if missing
}
return Color(int.parse(processedHex));
return Color(int.parse(processedHex.startsWith('0xff')
? processedHex
: '0xff$processedHex'));
}
return GetBuilder<MapPassengerController>(builder: (controller) {
if (controller.statusRide == 'Apply' &&
controller.isSearchingWindow == false) {
// double _height = Get.height * .2;
if (controller.statusRide == 'Apply' && !controller.isSearchingWindow) {
return Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
decoration: AppStyle.boxDecoration,
height: Get.height * .36,
child: ListView(
decoration: BoxDecoration(
// More modern BoxDecoration
color: Theme.of(context).cardColor,
borderRadius:
const BorderRadius.vertical(top: Radius.circular(20)),
boxShadow: [BoxShadow(blurRadius: 10, color: Colors.black12)],
),
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
InkWell(
onTap: () {
if (box.read(BoxName.carType) == 'Speed' ||
box.read(BoxName.carType) == 'Awfar Car' ||
box.read(BoxName.carType) == 'Delivery') {
Get.snackbar(
'This price is'.tr +
' ${controller.totalPassenger.toStringAsFixed(2)}'
.tr,
'This ride type does not allow changes to the destination or additional stops'
.tr,
snackPosition: SnackPosition.BOTTOM,
duration: const Duration(seconds: 2),
backgroundColor: AppColor.yellowColor,
);
} else {
Get.snackbar(
'This price may be changed'.tr,
'This ride type allows changes, but the price may increase'
.tr,
snackPosition: SnackPosition.BOTTOM,
duration: const Duration(seconds: 2),
backgroundColor: AppColor.yellowColor,
);
}
},
child: Text.rich(
TextSpan(
children: [
TextSpan(
text: '${'The driver accept your order for'.tr} ',
style: AppStyle.title,
),
TextSpan(
text: controller.totalPassenger.toStringAsFixed(2),
style: AppStyle.title.copyWith(
fontWeight: FontWeight.bold,
// fontSize: 22,
color: AppColor.redColor,
),
),
TextSpan(
text: ' ${'LE'.tr}',
style: AppStyle.title,
),
],
),
textAlign: TextAlign.center,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
width: 10,
),
Container(
height: Get.height * .31,
width: Get.width * .9,
decoration: AppStyle.boxDecoration,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
// 'Comfort',
box.read(BoxName.carType
.toString()), //car type fro box after selected
style: AppStyle.title,
),
const SizedBox(
width: 10,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
// ColorFiltered(
// colorFilter: ColorFilter.mode(
// _parseColor(controller.colorHex),
// BlendMode.srcIn,
// ),
// child: Image.asset(
// box.read(BoxName.carType) == 'Comfort'
// ? 'assets/images/blob.png'
// : box.read(BoxName.carType) == 'Lady'
// ? 'assets/images/lady.png' // Assuming there's an image for Lady
// : box.read(BoxName.carType) == 'Speed'
// ? 'assets/images/carspeed.png'
// : box.read(BoxName.carType) ==
// 'Scooter'
// ? 'assets/images/moto.png'
// : box.read(BoxName.carType) ==
// 'Mishwar Vip'
// ? 'assets/images/freeRide.png'
// : box.read(BoxName
// .carType) ==
// 'Awfar Car'
// ? 'assets/images/balash.png'
// : box.read(BoxName
// .carType) ==
// 'Pink Bike'
// ? 'assets/images/pinkBike.png'
// : box.read(BoxName
// .carType) ==
// 'Rayeh Gai'
// ? 'assets/images/roundtrip.png'
// : 'assets/images/carspeed.png', // Default image if none of the above
// width: 80,
// ),
// ),
Column(
children: [
Text(
// 'Toyota Camry',
controller.model.toString(),
style: AppStyle.title,
),
Text(
// 'ر ل 2323',
controller.licensePlate.toString(),
style: AppStyle.title,
),
],
),
const SizedBox(
width: 10,
),
Text(
// 'Black',
controller.carColor.toString(),
style: AppStyle.title,
),
const SizedBox(
width: 10,
),
ColorFiltered(
colorFilter: ColorFilter.mode(
_parseColor(controller.colorHex),
BlendMode.srcIn,
),
child: Image.asset(
box.read(BoxName.carType) == 'Scooter' ||
box.read(BoxName.carType) ==
'Pink Bike'
? 'assets/images/moto.png'
: 'assets/images/car3.png',
width: 80,
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CircleAvatar(
radius: 25,
backgroundImage: NetworkImage(
'${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg',
),
child: Builder(
builder: (context) {
return Image.network(
'${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg',
fit: BoxFit.cover,
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child; // Image is loaded
} else {
return Center(
child: CircularProgressIndicator(
value: loadingProgress
.expectedTotalBytes !=
null
? loadingProgress
.cumulativeBytesLoaded /
(loadingProgress
.expectedTotalBytes ??
1)
: null,
),
);
}
},
errorBuilder: (BuildContext context,
Object error,
StackTrace? stackTrace) {
return const Icon(
Icons
.person, // Icon to show when image fails to load
size:
25, // Adjust the size as needed
color: AppColor
.blueColor, // Color for the error icon
);
},
);
},
),
),
Column(
children: [
Text(
// 'fadi ahmad',
controller.driverName,
style: AppStyle.title,
),
Text(
// '⭐ 4.8',
'${controller.driverRate}',
style: AppStyle.title,
),
],
),
IconButton(
onPressed: () async {
Get.defaultDialog(
title: 'Select one message',
titleStyle: AppStyle.title,
content: SizedBox(
width: 300,
height: Get.height * .5,
child: ListView(
children: [
InkWell(
onTap: () {
FirebaseMessagesController()
.sendNotificationToDriverMAP(
'message From passenger',
'Hello, I\'m at the agreed-upon location'
.tr,
controller.driverToken
.toString(),
[],
'ding.wav',
);
Get.back();
},
child: Container(
decoration:
AppStyle.boxDecoration,
child: Padding(
padding:
const EdgeInsets.all(
10),
child: Text(
'Hello, I\'m at the agreed-upon location'
.tr,
style: AppStyle.title,
),
),
),
),
const SizedBox(
height: 5,
),
InkWell(
onTap: () {
FirebaseMessagesController()
.sendNotificationToDriverMAP(
'message From passenger',
'My location is correct. You can search for me using the navigation app'
.tr,
controller.driverToken,
[],
'ding.wav',
);
Get.back();
},
child: Container(
decoration:
AppStyle.boxDecoration,
child: Padding(
padding:
const EdgeInsets.all(
10),
child: Text(
'My location is correct. You can search for me using the navigation app'
.tr,
style: AppStyle.title,
),
),
),
),
const SizedBox(
height: 5,
),
InkWell(
onTap: () {
FirebaseMessagesController()
.sendNotificationToDriverMAP(
'message From passenger',
'My location is correct. You can search for me using the navigation app'
.tr,
controller.driverToken,
[],
'ding.wav',
);
Get.back();
},
child: Container(
decoration:
AppStyle.boxDecoration,
child: Padding(
padding:
const EdgeInsets.all(
10),
child: Text(
'I\'m waiting for you'.tr,
style: AppStyle.title,
),
),
),
),
const SizedBox(
height: 5,
),
InkWell(
onTap: () {
FirebaseMessagesController()
.sendNotificationToDriverMAP(
'message From passenger',
"How much longer will you be?"
.tr,
controller.driverToken,
[],
'ding.wav',
);
Get.back();
},
child: Container(
decoration:
AppStyle.boxDecoration,
child: Padding(
padding:
const EdgeInsets.all(
10),
child: Text(
"How much longer will you be?"
.tr,
style: AppStyle.title,
),
),
),
),
const SizedBox(
height: 5,
),
SizedBox(
width: 190,
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Form(
key: controller
.messagesFormKey,
child: SizedBox(
width: 160,
child: MyTextForm(
controller: controller
.messageToDriver,
label:
'Type Any thing'
.tr,
hint:
'Type Any thing'
.tr,
type:
TextInputType
.name),
)),
IconButton(
onPressed: () {
FirebaseMessagesController()
.sendNotificationToDriverMAP(
'message From passenger',
controller
.messageToDriver
.text,
controller
.driverToken,
[],
'ding.wav');
controller
.messageToDriver
.clear();
Get.back();
},
icon: const Icon(
Icons.send))
],
),
)
],
),
));
},
icon: const Icon(
Icons.message,
color: AppColor.blueColor,
size: 35,
),
),
IconButton(
onPressed: () async {
HapticFeedback.heavyImpact();
// Get.to(() => const CallPage());
// Get.to(() => PassengerCallPage());
makePhoneCall(controller.driverPhone);
},
icon: const Icon(
Icons.call,
color: AppColor.greenColor,
size: 35,
),
),
],
),
),
controller.isDriverArrivePassenger
? const DriverArrivePassengerAndWaitMinute()
: const TimeDriverToPassenger()
],
),
),
const SizedBox(
width: 10,
),
],
)
_buildPriceInfo(context, controller),
const SizedBox(height: 16),
_buildDriverInfoCard(context, controller, _parseColor),
],
),
),
@@ -493,45 +55,296 @@ class ApplyOrderWidget extends StatelessWidget {
}
});
}
Widget _buildPriceInfo(
BuildContext context, MapPassengerController controller) {
return InkWell(
onTap: () {
String message;
if (box.read(BoxName.carType) == 'Speed' ||
box.read(BoxName.carType) == 'Awfar Car' ||
box.read(BoxName.carType) == 'Delivery') {
message =
'This ride type does not allow changes to the destination or additional stops'
.tr;
} else {
message =
'This ride type allows changes, but the price may increase'.tr;
}
Get.snackbar(
'This price is'.tr +
' ${controller.totalPassenger.toStringAsFixed(2)}'.tr,
message,
snackPosition: SnackPosition.BOTTOM,
duration: const Duration(seconds: 2),
backgroundColor:
AppColor.yellowColor.withOpacity(0.8), // More subtle background
);
},
child: Center(
child: Text.rich(
TextSpan(
children: [
TextSpan(
text: '${'The driver accepted your order for'.tr} ',
style: AppStyle.title),
TextSpan(
text: controller.totalPassenger.toStringAsFixed(2),
style: AppStyle.title.copyWith(
fontWeight: FontWeight.bold, color: AppColor.redColor),
),
TextSpan(text: ' ${'LE'.tr}', style: AppStyle.title),
],
),
textAlign: TextAlign.center,
),
),
);
}
Widget _buildDriverInfoCard(BuildContext context,
MapPassengerController controller, Color Function(String) parseColor) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.grey.shade200),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(box.read(BoxName.carType.toString()),
style:
AppStyle.title.copyWith(fontWeight: FontWeight.w500)),
Row(
children: [
_buildCarDetails(context, controller),
const SizedBox(width: 10),
_buildCarImage(controller, parseColor),
],
),
],
),
),
const Divider(height: 1, thickness: 1, color: Colors.grey),
Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildDriverAvatarAndInfo(controller),
_buildContactButtons(context, controller),
],
),
),
Padding(
padding:
const EdgeInsets.only(left: 12.0, right: 12.0, bottom: 12.0),
child: controller.isDriverArrivePassenger
? const DriverArrivePassengerAndWaitMinute()
: const TimeDriverToPassenger(),
),
],
),
);
}
Widget _buildCarDetails(
BuildContext context, MapPassengerController controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(controller.model.toString(), style: AppStyle.title),
Text(controller.licensePlate.toString(),
style: Theme.of(context).textTheme.bodyMedium),
Text(controller.carColor.toString(),
style: Theme.of(context).textTheme.bodyMedium),
],
);
}
Widget _buildCarImage(
MapPassengerController controller, Color Function(String) parseColor) {
return ColorFiltered(
colorFilter:
ColorFilter.mode(parseColor(controller.colorHex), BlendMode.srcIn),
child: Image.asset(
box.read(BoxName.carType) == 'Scooter' ||
box.read(BoxName.carType) == 'Pink Bike'
? 'assets/images/moto.png'
: 'assets/images/car3.png',
height: 60,
),
);
}
Widget _buildDriverAvatarAndInfo(MapPassengerController controller) {
return Row(
children: [
CircleAvatar(
radius: 30,
backgroundImage: NetworkImage(
'${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg'),
onBackgroundImageError: (exception, stackTrace) =>
const Icon(Icons.person, size: 30, color: AppColor.blueColor),
),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(controller.driverName,
style: AppStyle.title.copyWith(fontWeight: FontWeight.w500)),
Text('${controller.driverRate}',
style: const TextStyle(fontSize: 16, color: Colors.grey)),
],
),
],
);
}
Widget _buildContactButtons(
BuildContext context, MapPassengerController controller) {
return Row(
children: [
IconButton(
onPressed: () => _showContactOptionsDialog(context, controller),
icon: const Icon(Icons.message, color: AppColor.blueColor, size: 28),
),
IconButton(
onPressed: () {
HapticFeedback.heavyImpact();
makePhoneCall(controller.driverPhone);
},
icon: const Icon(Icons.call, color: AppColor.greenColor, size: 28),
),
],
);
}
void _showContactOptionsDialog(
BuildContext context, MapPassengerController controller) {
Get.defaultDialog(
title: 'Contact Options'.tr,
content: SizedBox(
width: 300,
height: Get.height * .4,
child: ListView(
// shrinkWrap: true,
children: [
..._buildPredefinedMessages(controller),
const SizedBox(height: 8),
_buildCustomMessageInput(controller, context),
],
),
),
);
}
List<Widget> _buildPredefinedMessages(MapPassengerController controller) {
const messages = [
'Hello, I\'m at the agreed-upon location',
'My location is correct. You can search for me using the navigation app',
'I\'m waiting for you',
"How much longer will you be?",
];
return messages
.map((message) => Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: ElevatedButton(
onPressed: () {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From passenger',
message.tr,
controller.driverToken.toString(),
[],
'ding.wav',
);
Get.back();
},
child: Text(message.tr),
),
))
.toList();
}
Widget _buildCustomMessageInput(
MapPassengerController controller, BuildContext context) {
return Row(
children: [
Expanded(
child: Form(
key: controller.messagesFormKey,
child: MyTextForm(
controller: controller.messageToDriver,
label: 'Send a custom message'.tr,
hint: 'Type your message'.tr,
type: TextInputType.text,
),
),
),
IconButton(
onPressed: () {
if (controller.messagesFormKey.currentState!.validate()) {
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From passenger',
controller.messageToDriver.text,
controller.driverToken,
[],
'ding.wav',
);
controller.messageToDriver.clear();
Get.back();
}
},
icon: const Icon(Icons.send),
),
],
);
}
}
class DriverArrivePassengerAndWaitMinute extends StatelessWidget {
const DriverArrivePassengerAndWaitMinute({
super.key,
});
const DriverArrivePassengerAndWaitMinute({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetBuilder<MapPassengerController>(builder: (controller) {
return Stack(
return Column(
children: [
LinearProgressIndicator(
backgroundColor: AppColor.accentColor,
color: controller.remainingTimeDriverWaitPassenger5Minute < 60
? AppColor.redColor
: AppColor.greenColor,
minHeight: 25,
ClipRRect(
borderRadius: BorderRadius.circular(15),
value:
controller.progressTimerDriverWaitPassenger5Minute.toDouble(),
child: LinearProgressIndicator(
backgroundColor: AppColor.accentColor.withOpacity(0.3),
color: controller.remainingTimeDriverWaitPassenger5Minute < 60
? AppColor.redColor
: AppColor.greenColor,
minHeight: 20,
value:
controller.progressTimerDriverWaitPassenger5Minute.toDouble(),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'The driver waiting you in picked location .'.tr,
style: AppStyle.subtitle,
textAlign: TextAlign.center,
const SizedBox(height: 4),
Center(
child: Text.rich(
TextSpan(
children: [
TextSpan(
text: '${'Driver is waiting at pickup.'.tr} ',
style: AppStyle.subtitle),
TextSpan(
text: controller
.stringRemainingTimeDriverWaitPassenger5Minute,
style: AppStyle.title),
],
),
const SizedBox(
width: 20,
),
Text(
controller.stringRemainingTimeDriverWaitPassenger5Minute,
style: AppStyle.title,
),
],
)
textAlign: TextAlign.center,
),
),
],
);
});
@@ -539,77 +352,50 @@ class DriverArrivePassengerAndWaitMinute extends StatelessWidget {
}
class TimeDriverToPassenger extends StatelessWidget {
const TimeDriverToPassenger({
super.key,
});
const TimeDriverToPassenger({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetBuilder<MapPassengerController>(builder: (controller) {
return controller.isDriverInPassengerWay == false ||
controller.timeToPassengerFromDriverAfterApplied > 0
? Container(
decoration: AppStyle.boxDecoration,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1),
child: Stack(
children: [
Container(
decoration: AppStyle.boxDecoration,
width: Get.width * .7,
height: 15,
// color: AppColor.yellowColor,
),
Stack(
? Column(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: LinearProgressIndicator(
backgroundColor: AppColor.accentColor.withOpacity(0.3),
color: controller
.remainingTimeToPassengerFromDriverAfterApplied <
60
? AppColor.redColor
: AppColor.greenColor,
minHeight: 20,
value: controller
.progressTimerToPassengerFromDriverAfterApplied
.toDouble()
.clamp(0.0, 1.0),
),
),
const SizedBox(height: 4),
Center(
child: Text.rich(
TextSpan(
children: [
LinearProgressIndicator(
backgroundColor: AppColor.accentColor,
color: controller
.remainingTimeToPassengerFromDriverAfterApplied <
60
? AppColor.redColor
: AppColor.greenColor,
minHeight: 25,
borderRadius: BorderRadius.circular(15),
value: () {
// Ensure valid value between 0.0 and 1.0
double progress = controller
.progressTimerToPassengerFromDriverAfterApplied
.toDouble();
if (progress.isNaN || progress.isInfinite) {
// Handle invalid progress (e.g., set to 0.0)
return 0.0;
} else {
return progress.clamp(
0.0, 1.0); // Clamp to valid range
}
}(),
TextSpan(
text: '${'Driver is on the way'.tr} ',
style: AppStyle.subtitle,
),
TextSpan(
text: controller.stringRemainingTimeToPassenger,
style: AppStyle.title,
),
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'The driver on your way'.tr,
style: AppStyle.title
.copyWith(color: AppColor.yellowColor),
textAlign: TextAlign.center,
),
const SizedBox(
width: 20,
),
Text(
controller.stringRemainingTimeToPassenger,
style: AppStyle.title,
),
],
),
)
],
),
],
textAlign: TextAlign.center,
),
),
),
],
)
: const SizedBox();
});