25-8-4-1
This commit is contained in:
@@ -1,11 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:sefer_driver/views/widgets/my_textField.dart';
|
||||
import 'package:sefer_driver/views/widgets/mydialoug.dart';
|
||||
import 'package:bubble_head/bubble.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_font_icons/flutter_font_icons.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sefer_driver/constant/colors.dart';
|
||||
import 'package:sefer_driver/constant/info.dart';
|
||||
@@ -15,373 +9,97 @@ import 'package:sefer_driver/views/widgets/elevated_btn.dart';
|
||||
|
||||
import '../../../../constant/box_name.dart';
|
||||
import '../../../../constant/style.dart';
|
||||
import '../../../../controller/functions/launch.dart';
|
||||
import '../../../../main.dart';
|
||||
import '../../../../print.dart';
|
||||
|
||||
// Changed: إعادة تصميم كاملة لتصبح شريط معلومات علوي مدمج
|
||||
class PassengerInfoWindow extends StatelessWidget {
|
||||
const PassengerInfoWindow({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<MapDriverController>(
|
||||
builder: (controller) => controller.isPassengerInfoWindow == true
|
||||
? Positioned(
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10,
|
||||
child: Card(
|
||||
elevation: 5,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Go to passenger Location'.tr,
|
||||
style: AppStyle.title.copyWith(
|
||||
color: AppColor.greenColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
if (!controller.isRideBegin)
|
||||
Wrap(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
controller.isSocialPressed = true;
|
||||
await controller.driverCallPassenger();
|
||||
makePhoneCall(
|
||||
controller.passengerPhone.toString());
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.phone,
|
||||
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),
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.message,
|
||||
color: AppColor.redColor,
|
||||
),
|
||||
tooltip: 'Send Message',
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
if (Platform.isAndroid) {
|
||||
Bubble().startBubbleHead(
|
||||
sendAppToBackground: true);
|
||||
}
|
||||
await controller
|
||||
.openGoogleMapFromDriverToPassenger();
|
||||
},
|
||||
icon: const Icon(
|
||||
MaterialCommunityIcons.map_marker_radius,
|
||||
size: 28,
|
||||
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(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Expanded(
|
||||
child: MyElevatedButton(
|
||||
title: 'Start the Ride'.tr,
|
||||
kolor: AppColor.greenColor,
|
||||
onPressed: () {
|
||||
MyDialog().getDialog(
|
||||
"Is the Passenger in your Car?".tr,
|
||||
"Don't start trip if passenger not in your car"
|
||||
.tr,
|
||||
() async {
|
||||
await controller
|
||||
.startRideFromDriver();
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
if (controller.isArrivedSend)
|
||||
Expanded(
|
||||
child: MyElevatedButton(
|
||||
title: 'I Arrive'.tr,
|
||||
kolor: AppColor.yellowColor,
|
||||
onPressed: () async {
|
||||
if (await controller
|
||||
.calculateDistanceBetweenDriverAndPassengerLocation() <
|
||||
140) {
|
||||
Get.find<FirebaseMessagesController>()
|
||||
.sendNotificationToDriverMAP(
|
||||
'Hi ,I Arrive your site',
|
||||
'I Arrive at your site'.tr,
|
||||
controller.tokenPassenger,
|
||||
[],
|
||||
'ding.wav',
|
||||
);
|
||||
controller
|
||||
.startTimerToShowDriverWaitPassengerDuration();
|
||||
controller.isArrivedSend = false;
|
||||
} else {
|
||||
MyDialog().getDialog(
|
||||
'You are not near the passenger location'
|
||||
.tr,
|
||||
'Please go to the pickup location exactly'
|
||||
.tr, () {
|
||||
Get.back();
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
if (controller.remainingTimeInPassengerLocatioWait <
|
||||
300 &&
|
||||
controller
|
||||
.remainingTimeInPassengerLocatioWait !=
|
||||
0)
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
LinearProgressIndicator(
|
||||
backgroundColor: AppColor.greyColor,
|
||||
color: controller
|
||||
.remainingTimeInPassengerLocatioWait <
|
||||
60
|
||||
? AppColor.redColor
|
||||
: AppColor.greenColor,
|
||||
minHeight: 20,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
value: controller
|
||||
.progressInPassengerLocationFromDriver
|
||||
.toDouble(),
|
||||
),
|
||||
Text(
|
||||
controller
|
||||
.stringRemainingTimeWaitingPassenger,
|
||||
style: AppStyle.title,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
if (controller.isdriverWaitTimeEnd)
|
||||
MyElevatedButton(
|
||||
title:
|
||||
'You Can Cancel the Trip and get Cost From '
|
||||
.tr +
|
||||
AppInformation.appName.tr,
|
||||
kolor: AppColor.deepPurpleAccent,
|
||||
onPressed: () {
|
||||
MyDialog().getDialog(
|
||||
'Are you sure to cancel?'.tr, '',
|
||||
() async {
|
||||
Get.find<FirebaseMessagesController>()
|
||||
.sendNotificationToDriverMAP(
|
||||
'Driver Cancelled Your Trip',
|
||||
'You will need to pay the cost to the driver, or it will be deducted from your next trip'
|
||||
.tr,
|
||||
controller.tokenPassenger,
|
||||
[],
|
||||
'cancel.wav',
|
||||
);
|
||||
Log.print(
|
||||
'rideStatus from passenge info 261 : ${box.read(BoxName.rideStatus)}');
|
||||
box.write(BoxName.rideStatus, 'Cancel');
|
||||
await controller
|
||||
.addWaitingTimeCostFromPassengerToDriverWallet();
|
||||
controller.isdriverWaitTimeEnd = false;
|
||||
Get.back();
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
builder: (controller) => AnimatedPositioned(
|
||||
duration: const Duration(milliseconds: 400),
|
||||
curve: Curves.easeInOut,
|
||||
// Changed: تم تغيير الموضع من الأسفل إلى الأعلى
|
||||
top: controller.isPassengerInfoWindow ? 15.0 : -200.0,
|
||||
left: 15.0,
|
||||
right: 15.0,
|
||||
child: Card(
|
||||
elevation: 8,
|
||||
shadowColor: Colors.black.withOpacity(0.3),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// New: صف علوي للمعلومات الأساسية
|
||||
_buildTopInfoRow(controller),
|
||||
const Divider(height: 16),
|
||||
|
||||
// Changed: الأزرار الآن في صف أفقي ومدمج
|
||||
if (!controller.isRideBegin) _buildActionButtons(controller),
|
||||
|
||||
// New: مؤشر انتظار الراكب المدمج
|
||||
if (controller.remainingTimeInPassengerLocatioWait < 300 &&
|
||||
controller.remainingTimeInPassengerLocatioWait != 0 &&
|
||||
!controller.isRideBegin) ...[
|
||||
const SizedBox(height: 10),
|
||||
_buildWaitingIndicator(controller),
|
||||
],
|
||||
|
||||
// زر الإلغاء بعد انتهاء وقت الانتظار
|
||||
if (controller.isdriverWaitTimeEnd &&
|
||||
!controller.isRideBegin) ...[
|
||||
const SizedBox(height: 10),
|
||||
_buildCancelAfterWaitButton(controller),
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// New: ودجت لعرض المعلومات العلوية بشكل مدمج
|
||||
Widget _buildTopInfoRow(MapDriverController controller) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// معلومات الراكب
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Go to passenger:'.tr,
|
||||
style: AppStyle.title
|
||||
.copyWith(color: Colors.grey[600], fontSize: 13),
|
||||
),
|
||||
)
|
||||
: 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: () {
|
||||
Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
|
||||
'message From Driver',
|
||||
"Where are you, sir?".tr,
|
||||
controller.tokenPassenger,
|
||||
[],
|
||||
'ding.wav',
|
||||
);
|
||||
Get.back();
|
||||
},
|
||||
Text(
|
||||
controller.passengerName,
|
||||
style: AppStyle.title
|
||||
.copyWith(fontWeight: FontWeight.bold, fontSize: 18),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
_buildMessageTile(
|
||||
text: "I've been trying to reach you but your phone is off.".tr,
|
||||
onTap: () {
|
||||
Get.find<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: () {
|
||||
Get.find<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: () {
|
||||
Get.find<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: () {
|
||||
Get.find<FirebaseMessagesController>()
|
||||
.sendNotificationToDriverMAP(
|
||||
'message From Driver',
|
||||
controller.messageToPassenger.text,
|
||||
controller.tokenPassenger,
|
||||
[],
|
||||
'ding.wav',
|
||||
);
|
||||
controller.messageToPassenger.clear();
|
||||
Get.back();
|
||||
},
|
||||
icon: const Icon(Icons.send),
|
||||
_buildInfoChip(Icons.map_outlined, '${controller.distance} km'),
|
||||
const SizedBox(width: 8),
|
||||
_buildInfoChip(
|
||||
Icons.timer_outlined,
|
||||
controller.hours > 1
|
||||
? '${controller.hours}h ${controller.minutes}m'
|
||||
: '${controller.minutes}m',
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -389,19 +107,145 @@ class PassengerInfoWindow extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
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),
|
||||
// New: ودجت مخصص لعرض المعلومات بشكل أنيق
|
||||
Widget _buildInfoChip(IconData icon, String text) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.primaryColor.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, color: AppColor.primaryColor, size: 16),
|
||||
const SizedBox(width: 4),
|
||||
Text(text,
|
||||
style: TextStyle(
|
||||
color: AppColor.primaryColor, fontWeight: FontWeight.bold)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Changed: إعادة تصميم أزرار الإجراءات لتكون أكثر دمجًا
|
||||
Widget _buildActionButtons(MapDriverController controller) {
|
||||
return Row(
|
||||
children: [
|
||||
if (controller.isArrivedSend)
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.location_on, size: 18),
|
||||
label: Text('I Arrive'.tr),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColor.yellowColor,
|
||||
foregroundColor: Colors.black,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
onPressed: () async {
|
||||
if (await controller
|
||||
.calculateDistanceBetweenDriverAndPassengerLocation() <
|
||||
140) {
|
||||
Get.find<FirebaseMessagesController>()
|
||||
.sendNotificationToDriverMAP(
|
||||
'Hi ,I Arrive your site',
|
||||
'I Arrive at your site'.tr,
|
||||
controller.tokenPassenger,
|
||||
[],
|
||||
'ding.wav',
|
||||
);
|
||||
controller.startTimerToShowDriverWaitPassengerDuration();
|
||||
controller.isArrivedSend = false;
|
||||
} else {
|
||||
MyDialog().getDialog(
|
||||
'You are not near the passenger location'.tr,
|
||||
'Please go to the pickup location exactly'.tr,
|
||||
() => Get.back());
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
if (controller.isArrivedSend) const SizedBox(width: 8),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.play_arrow_rounded, size: 20),
|
||||
label: Text('Start the Ride'.tr,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColor.greenColor,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
onPressed: () {
|
||||
MyDialog().getDialog(
|
||||
"Is the Passenger in your Car?".tr,
|
||||
"Don't start trip if passenger not in your car".tr,
|
||||
() async {
|
||||
await controller.startRideFromDriver();
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// Changed: مؤشر الانتظار الآن أكثر دمجًا
|
||||
Widget _buildWaitingIndicator(MapDriverController controller) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
LinearProgressIndicator(
|
||||
backgroundColor: AppColor.greyColor.withOpacity(0.3),
|
||||
color: controller.remainingTimeInPassengerLocatioWait < 60
|
||||
? AppColor.redColor
|
||||
: AppColor.greenColor,
|
||||
minHeight: 25,
|
||||
value: controller.progressInPassengerLocationFromDriver.toDouble(),
|
||||
),
|
||||
Text(
|
||||
controller.stringRemainingTimeWaitingPassenger,
|
||||
style: AppStyle.title.copyWith(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 13,
|
||||
shadows: [
|
||||
Shadow(color: Colors.black.withOpacity(0.5), blurRadius: 2)
|
||||
]),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// New: زر الإلغاء بعد انتهاء الانتظار
|
||||
Widget _buildCancelAfterWaitButton(MapDriverController controller) {
|
||||
return MyElevatedButton(
|
||||
title: 'You Can Cancel the Trip and get Cost From '.tr +
|
||||
AppInformation.appName.tr,
|
||||
kolor: AppColor.deepPurpleAccent,
|
||||
onPressed: () {
|
||||
MyDialog().getDialog('Are you sure to cancel?'.tr, '', () async {
|
||||
Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
|
||||
'Driver Cancelled Your Trip',
|
||||
'You will need to pay the cost to the driver, or it will be deducted from your next trip'
|
||||
.tr,
|
||||
controller.tokenPassenger,
|
||||
[],
|
||||
'cancel.wav');
|
||||
box.write(BoxName.rideStatus, 'Cancel');
|
||||
await controller.addWaitingTimeCostFromPassengerToDriverWallet();
|
||||
controller.isdriverWaitTimeEnd = false;
|
||||
Get.back();
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user