25-8-4-1
This commit is contained in:
@@ -1,263 +1,491 @@
|
||||
import 'dart:io';
|
||||
// import 'dart:io';
|
||||
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter/services.dart';
|
||||
// import 'package:get/get.dart';
|
||||
// import 'package:slide_to_act/slide_to_act.dart';
|
||||
// import 'package:vibration/vibration.dart';
|
||||
|
||||
// import '../../../../constant/colors.dart';
|
||||
// import '../../../../constant/style.dart';
|
||||
// import '../../../../controller/home/captin/map_driver_controller.dart';
|
||||
// import '../../../widgets/elevated_btn.dart';
|
||||
|
||||
// GetBuilder<MapDriverController> driverEndRideBar() {
|
||||
// return GetBuilder<MapDriverController>(
|
||||
// builder: (mapDriverController) => mapDriverController.isRideStarted
|
||||
// ? Positioned(
|
||||
// left: 5,
|
||||
// top: 5,
|
||||
// right: 5,
|
||||
// child: Container(
|
||||
// decoration: AppStyle.boxDecoration1.copyWith(
|
||||
// borderRadius: BorderRadius.circular(15),
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: Colors.black.withOpacity(0.1),
|
||||
// blurRadius: 10,
|
||||
// offset: Offset(0, 5),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// padding: const EdgeInsets.all(10),
|
||||
// height: mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
// ? mapDriverController.driverEndPage = 190
|
||||
// : mapDriverController.carType == 'Mishwar Vip'
|
||||
// ? 120
|
||||
// : 170,
|
||||
// child: Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
// children: [
|
||||
// if (mapDriverController.carType != 'Mishwar Vip')
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
// children: [
|
||||
// _buildInfoColumn(
|
||||
// icon: Icons.social_distance,
|
||||
// text: '${mapDriverController.distance} ${'KM'.tr}',
|
||||
// ),
|
||||
// _buildInfoColumn(
|
||||
// icon: Icons.timelapse,
|
||||
// text: mapDriverController.hours > 1
|
||||
// ? '${mapDriverController.hours} ${'H and'.tr} ${mapDriverController.minutes} m'
|
||||
// : '${mapDriverController.minutes} ${'m'.tr}',
|
||||
// ),
|
||||
// _buildInfoColumn(
|
||||
// icon: Icons.money_sharp,
|
||||
// text:
|
||||
// '${mapDriverController.paymentAmount} ${'\$'.tr}',
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// if (mapDriverController.carType != 'Speed' &&
|
||||
// mapDriverController.carType != 'Awfar Car' &&
|
||||
// mapDriverController.carType != 'Scooter')
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
// children: [
|
||||
// _buildInfoBox(
|
||||
// icon: Icons.timer,
|
||||
// text:
|
||||
// mapDriverController.stringRemainingTimeRideBegin1,
|
||||
// ),
|
||||
// _buildInfoBox(
|
||||
// icon: Icons.location_on,
|
||||
// text:
|
||||
// '${mapDriverController.recentDistanceToDash.toStringAsFixed(0)} ${'KM'.tr}',
|
||||
// ),
|
||||
// _buildInfoBox(
|
||||
// icon: Icons.attach_money,
|
||||
// text: mapDriverController.price.toStringAsFixed(2),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// _builtTimerAndCarType(),
|
||||
// Container(
|
||||
// width: Get.width * 0.8,
|
||||
// decoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(15),
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: AppColor.redColor.withOpacity(0.3),
|
||||
// blurRadius: 8,
|
||||
// offset: Offset(0, 4),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// child: SlideAction(
|
||||
// height: 50,
|
||||
// borderRadius: 15,
|
||||
// elevation: 4,
|
||||
// text: 'Slide to End Trip'.tr,
|
||||
// textStyle: AppStyle.title.copyWith(
|
||||
// fontSize: 18,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// outerColor: AppColor.redColor,
|
||||
// innerColor: Colors.white,
|
||||
// sliderButtonIcon: const Icon(
|
||||
// Icons.arrow_forward_ios,
|
||||
// color: AppColor.redColor,
|
||||
// size: 24,
|
||||
// ),
|
||||
// sliderRotate: false,
|
||||
// onSubmit: () {
|
||||
// HapticFeedback.mediumImpact();
|
||||
// mapDriverController.finishRideFromDriver();
|
||||
// },
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// )
|
||||
// : const SizedBox(),
|
||||
// );
|
||||
// }
|
||||
|
||||
// class _builtTimerAndCarType extends StatelessWidget {
|
||||
// const _builtTimerAndCarType({
|
||||
// super.key,
|
||||
// });
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// final mapDriverController = Get.find<MapDriverController>();
|
||||
// return Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
// children: [
|
||||
// Container(
|
||||
// decoration: AppStyle.boxDecoration1.copyWith(
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: AppColor.accentColor.withOpacity(0.2),
|
||||
// blurRadius: 8,
|
||||
// offset: Offset(0, 4),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
// child: Text(
|
||||
// mapDriverController.carType,
|
||||
// style: AppStyle.title,
|
||||
// ),
|
||||
// ),
|
||||
// if (mapDriverController.carType != 'Comfort' &&
|
||||
// mapDriverController.carType != 'Mishwar Vip' &&
|
||||
// mapDriverController.carType != 'Lady')
|
||||
// Container(
|
||||
// width: Get.width * 0.6,
|
||||
// decoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(12),
|
||||
// gradient: LinearGradient(
|
||||
// colors: [
|
||||
// mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
// ? AppColor.redColor.withOpacity(0.8)
|
||||
// : AppColor.greenColor.withOpacity(0.8),
|
||||
// mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
// ? AppColor.redColor
|
||||
// : AppColor.greenColor,
|
||||
// ],
|
||||
// begin: Alignment.centerLeft,
|
||||
// end: Alignment.centerRight,
|
||||
// ),
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: (mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
// ? AppColor.redColor
|
||||
// : AppColor.greenColor)
|
||||
// .withOpacity(0.3),
|
||||
// blurRadius: 8,
|
||||
// offset: Offset(0, 4),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// child: ClipRRect(
|
||||
// borderRadius: BorderRadius.circular(12),
|
||||
// child: Stack(
|
||||
// children: [
|
||||
// LinearProgressIndicator(
|
||||
// backgroundColor: Colors.white.withOpacity(0.2),
|
||||
// valueColor: AlwaysStoppedAnimation<Color>(
|
||||
// Colors.white.withOpacity(0.5),
|
||||
// ),
|
||||
// minHeight: 40,
|
||||
// value:
|
||||
// mapDriverController.progressTimerRideBegin.toDouble(),
|
||||
// ),
|
||||
// Center(
|
||||
// child: AnimatedDefaultTextStyle(
|
||||
// duration: Duration(milliseconds: 300),
|
||||
// style: AppStyle.title.copyWith(
|
||||
// color: Colors.white,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontSize:
|
||||
// mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
// ? 18
|
||||
// : 16,
|
||||
// shadows: [
|
||||
// Shadow(
|
||||
// color: Colors.black26,
|
||||
// offset: Offset(0, 2),
|
||||
// blurRadius: 4,
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// child: Text(
|
||||
// mapDriverController.stringRemainingTimeRideBegin,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// Widget _buildInfoColumn({required IconData icon, required String text}) {
|
||||
// return Column(
|
||||
// children: [
|
||||
// Icon(icon),
|
||||
// Text(
|
||||
// text,
|
||||
// style: AppStyle.title,
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
|
||||
// Widget _buildInfoBox({required IconData icon, required String text}) {
|
||||
// return Container(
|
||||
// width: Get.width * .2,
|
||||
// decoration: AppStyle.boxDecoration1,
|
||||
// padding: const EdgeInsets.all(4),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Icon(icon),
|
||||
// SizedBox(width: 4),
|
||||
// Text(
|
||||
// text,
|
||||
// style: AppStyle.number,
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
// GetBuilder<MapDriverController> speedCircle() {
|
||||
// if (Get.find<MapDriverController>().speed > 100) {
|
||||
// if (Platform.isIOS) {
|
||||
// HapticFeedback.selectionClick();
|
||||
// } else {
|
||||
// Vibration.vibrate(duration: 1000);
|
||||
// }
|
||||
// Get.defaultDialog(
|
||||
// barrierDismissible: false,
|
||||
// titleStyle: AppStyle.title,
|
||||
// title: 'Speed Over'.tr,
|
||||
// middleText: 'Please slow down'.tr,
|
||||
// middleTextStyle: AppStyle.title,
|
||||
// confirm: MyElevatedButton(
|
||||
// title: 'I will slow down'.tr,
|
||||
// onPressed: () => Get.back(),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// return GetBuilder<MapDriverController>(
|
||||
// builder: (mapDriverController) {
|
||||
// return mapDriverController.isRideStarted
|
||||
// ? Positioned(
|
||||
// bottom: 25,
|
||||
// right: 100,
|
||||
// child: Container(
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// color: mapDriverController.speed > 100
|
||||
// ? Colors.red
|
||||
// : AppColor.secondaryColor,
|
||||
// border: Border.all(width: 3, color: AppColor.redColor),
|
||||
// ),
|
||||
// height: 60,
|
||||
// width: 60,
|
||||
// child: Center(
|
||||
// child: Text(
|
||||
// mapDriverController.speed.toStringAsFixed(0),
|
||||
// style: AppStyle.number,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// )
|
||||
// : const SizedBox();
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:slide_to_act/slide_to_act.dart';
|
||||
import 'package:vibration/vibration.dart';
|
||||
import 'dart:io';
|
||||
|
||||
import '../../../../constant/colors.dart';
|
||||
import '../../../../constant/style.dart';
|
||||
import '../../../../controller/home/captin/map_driver_controller.dart';
|
||||
import '../../../widgets/elevated_btn.dart';
|
||||
|
||||
// Changed: إعادة تصميم كاملة للشريط ليصبح شريطًا علويًا عند بدء الرحلة
|
||||
GetBuilder<MapDriverController> driverEndRideBar() {
|
||||
return GetBuilder<MapDriverController>(
|
||||
builder: (mapDriverController) => mapDriverController.isRideStarted
|
||||
? Positioned(
|
||||
left: 5,
|
||||
top: 5,
|
||||
right: 5,
|
||||
child: Container(
|
||||
decoration: AppStyle.boxDecoration1.copyWith(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 5),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(10),
|
||||
height: mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
? mapDriverController.driverEndPage = 190
|
||||
: mapDriverController.carType == 'Mishwar Vip'
|
||||
? 120
|
||||
: 170,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
if (mapDriverController.carType != 'Mishwar Vip')
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_buildInfoColumn(
|
||||
icon: Icons.social_distance,
|
||||
text: '${mapDriverController.distance} ${'KM'.tr}',
|
||||
),
|
||||
_buildInfoColumn(
|
||||
icon: Icons.timelapse,
|
||||
text: mapDriverController.hours > 1
|
||||
? '${mapDriverController.hours} ${'H and'.tr} ${mapDriverController.minutes} m'
|
||||
: '${mapDriverController.minutes} ${'m'.tr}',
|
||||
),
|
||||
_buildInfoColumn(
|
||||
icon: Icons.money_sharp,
|
||||
text:
|
||||
'${mapDriverController.paymentAmount} ${'\$'.tr}',
|
||||
),
|
||||
],
|
||||
builder: (controller) => AnimatedPositioned(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
// New: يظهر الشريط من الأعلى عندما تبدأ الرحلة
|
||||
top: controller.isRideStarted ? 0 : -200,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Card(
|
||||
margin: EdgeInsets.zero,
|
||||
elevation: 10,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(bottom: Radius.circular(24)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
|
||||
child: Column(
|
||||
children: [
|
||||
// -- معلومات الرحلة --
|
||||
if (controller.carType != 'Mishwar Vip')
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_buildInfoColumn(
|
||||
icon: Icons.social_distance,
|
||||
text: '${controller.distance} ${'KM'.tr}',
|
||||
label: 'Distance'.tr,
|
||||
),
|
||||
if (mapDriverController.carType != 'Speed' &&
|
||||
mapDriverController.carType != 'Awfar Car' &&
|
||||
mapDriverController.carType != 'Scooter')
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_buildInfoBox(
|
||||
icon: Icons.timer,
|
||||
text:
|
||||
mapDriverController.stringRemainingTimeRideBegin1,
|
||||
),
|
||||
_buildInfoBox(
|
||||
icon: Icons.location_on,
|
||||
text:
|
||||
'${mapDriverController.recentDistanceToDash.toStringAsFixed(0)} ${'KM'.tr}',
|
||||
),
|
||||
_buildInfoBox(
|
||||
icon: Icons.attach_money,
|
||||
text: mapDriverController.price.toStringAsFixed(2),
|
||||
),
|
||||
],
|
||||
_buildInfoColumn(
|
||||
icon: Icons.timelapse,
|
||||
text: controller.hours > 1
|
||||
? '${controller.hours}h ${controller.minutes}m'
|
||||
: '${controller.minutes}m',
|
||||
label: 'Time'.tr,
|
||||
),
|
||||
_builtTimerAndCarType(),
|
||||
Container(
|
||||
width: Get.width * 0.8,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.redColor.withOpacity(0.3),
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
_buildInfoColumn(
|
||||
icon: Icons.money_sharp,
|
||||
text: '${controller.paymentAmount} ${'\$'.tr}',
|
||||
label: 'Price'.tr,
|
||||
),
|
||||
child: SlideAction(
|
||||
height: 50,
|
||||
borderRadius: 15,
|
||||
elevation: 4,
|
||||
text: 'Slide to End Trip'.tr,
|
||||
textStyle: AppStyle.title.copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
outerColor: AppColor.redColor,
|
||||
innerColor: Colors.white,
|
||||
sliderButtonIcon: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: AppColor.redColor,
|
||||
size: 24,
|
||||
),
|
||||
sliderRotate: false,
|
||||
onSubmit: () {
|
||||
HapticFeedback.mediumImpact();
|
||||
mapDriverController.finishRideFromDriver();
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
);
|
||||
}
|
||||
],
|
||||
),
|
||||
if (controller.carType != 'Mishwar Vip')
|
||||
const Divider(height: 20),
|
||||
|
||||
class _builtTimerAndCarType extends StatelessWidget {
|
||||
const _builtTimerAndCarType({
|
||||
super.key,
|
||||
});
|
||||
// -- مؤقت الرحلة المتبقي (إن وجد) --
|
||||
_builtTimerAndCarType(),
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final mapDriverController = Get.find<MapDriverController>();
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Container(
|
||||
decoration: AppStyle.boxDecoration1.copyWith(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.accentColor.withOpacity(0.2),
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 4),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// -- زر إنهاء الرحلة المنزلق --
|
||||
SlideAction(
|
||||
height: 55,
|
||||
borderRadius: 15,
|
||||
elevation: 4,
|
||||
text: 'Slide to End Trip'.tr,
|
||||
textStyle: AppStyle.title.copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
outerColor: AppColor.redColor,
|
||||
innerColor: Colors.white,
|
||||
sliderButtonIcon: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: AppColor.redColor,
|
||||
size: 24,
|
||||
),
|
||||
sliderRotate: false,
|
||||
onSubmit: () {
|
||||
HapticFeedback.mediumImpact();
|
||||
controller.finishRideFromDriver();
|
||||
return null; // New: onSubmit now returns null
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// New: ودجت لعرض معلومات الرحلة في الشريط العلوي
|
||||
Widget _buildInfoColumn(
|
||||
{required IconData icon, required String text, required String label}) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, color: AppColor.primaryColor),
|
||||
const SizedBox(height: 4),
|
||||
Text(text, style: AppStyle.title.copyWith(fontWeight: FontWeight.bold)),
|
||||
Text(label,
|
||||
style:
|
||||
AppStyle.title.copyWith(color: Colors.grey[600], fontSize: 12)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// Changed: تم تعديل تصميم ودجت عرض المؤقت ونوع السيارة
|
||||
class _builtTimerAndCarType extends StatelessWidget {
|
||||
const _builtTimerAndCarType();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final controller = Get.find<MapDriverController>();
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// -- نوع السيارة --
|
||||
Container(
|
||||
decoration: AppStyle.boxDecoration1.copyWith(color: Colors.grey[200]),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: Text(
|
||||
mapDriverController.carType,
|
||||
style: AppStyle.title,
|
||||
controller.carType,
|
||||
style: AppStyle.title.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
if (mapDriverController.carType != 'Comfort' &&
|
||||
mapDriverController.carType != 'Mishwar Vip' &&
|
||||
mapDriverController.carType != 'Lady')
|
||||
Container(
|
||||
width: Get.width * 0.6,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
? AppColor.redColor.withOpacity(0.8)
|
||||
: AppColor.greenColor.withOpacity(0.8),
|
||||
mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
? AppColor.redColor
|
||||
: AppColor.greenColor,
|
||||
],
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: (mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
? AppColor.redColor
|
||||
: AppColor.greenColor)
|
||||
.withOpacity(0.3),
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 4),
|
||||
// -- مؤقت الرحلة --
|
||||
if (controller.carType != 'Comfort' &&
|
||||
controller.carType != 'Mishwar Vip' &&
|
||||
controller.carType != 'Lady') ...[
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
controller.remainingTimeTimerRideBegin < 60
|
||||
? AppColor.redColor.withOpacity(0.8)
|
||||
: AppColor.greenColor.withOpacity(0.8),
|
||||
controller.remainingTimeTimerRideBegin < 60
|
||||
? AppColor.redColor
|
||||
: AppColor.greenColor,
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Stack(
|
||||
children: [
|
||||
LinearProgressIndicator(
|
||||
backgroundColor: Colors.white.withOpacity(0.2),
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
Colors.white.withOpacity(0.5),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
LinearProgressIndicator(
|
||||
backgroundColor: Colors.transparent,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
Colors.white.withOpacity(0.2)),
|
||||
minHeight: 40,
|
||||
value: controller.progressTimerRideBegin.toDouble(),
|
||||
),
|
||||
minHeight: 40,
|
||||
value:
|
||||
mapDriverController.progressTimerRideBegin.toDouble(),
|
||||
),
|
||||
Center(
|
||||
child: AnimatedDefaultTextStyle(
|
||||
duration: Duration(milliseconds: 300),
|
||||
Text(
|
||||
controller.stringRemainingTimeRideBegin,
|
||||
style: AppStyle.title.copyWith(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize:
|
||||
mapDriverController.remainingTimeTimerRideBegin < 60
|
||||
? 18
|
||||
: 16,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black26,
|
||||
offset: Offset(0, 2),
|
||||
blurRadius: 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Text(
|
||||
mapDriverController.stringRemainingTimeRideBegin,
|
||||
),
|
||||
color: Colors.white, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildInfoColumn({required IconData icon, required String text}) {
|
||||
return Column(
|
||||
children: [
|
||||
Icon(icon),
|
||||
Text(
|
||||
text,
|
||||
style: AppStyle.title,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInfoBox({required IconData icon, required String text}) {
|
||||
return Container(
|
||||
width: Get.width * .2,
|
||||
decoration: AppStyle.boxDecoration1,
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(icon),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
text,
|
||||
style: AppStyle.number,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Changed: تم تعديل مكان ومظهر دائرة السرعة
|
||||
GetBuilder<MapDriverController> speedCircle() {
|
||||
if (Get.find<MapDriverController>().speed > 100) {
|
||||
if (Platform.isIOS) {
|
||||
@@ -278,25 +506,36 @@ GetBuilder<MapDriverController> speedCircle() {
|
||||
);
|
||||
}
|
||||
return GetBuilder<MapDriverController>(
|
||||
builder: (mapDriverController) {
|
||||
return mapDriverController.isRideStarted
|
||||
builder: (controller) {
|
||||
return controller.isRideStarted
|
||||
? Positioned(
|
||||
// New: تم وضع دائرة السرعة في الأسفل يمينًا
|
||||
bottom: 25,
|
||||
right: 100,
|
||||
left: 16,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: mapDriverController.speed > 100
|
||||
? Colors.red
|
||||
: AppColor.secondaryColor,
|
||||
border: Border.all(width: 3, color: AppColor.redColor),
|
||||
color: Colors.white,
|
||||
boxShadow: [BoxShadow(blurRadius: 5, color: Colors.black26)],
|
||||
border: Border.all(
|
||||
width: 4,
|
||||
color: controller.speed > 100
|
||||
? Colors.red
|
||||
: AppColor.greenColor,
|
||||
),
|
||||
),
|
||||
height: 60,
|
||||
width: 60,
|
||||
height: 70,
|
||||
width: 70,
|
||||
child: Center(
|
||||
child: Text(
|
||||
mapDriverController.speed.toStringAsFixed(0),
|
||||
style: AppStyle.number,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
controller.speed.toStringAsFixed(0),
|
||||
style: AppStyle.number.copyWith(fontSize: 24),
|
||||
),
|
||||
Text("km/h", style: TextStyle(fontSize: 10)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,3 +1,117 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:get/get.dart';
|
||||
// import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
|
||||
// import '../../../../controller/functions/location_controller.dart';
|
||||
// import '../../../../controller/home/captin/map_driver_controller.dart';
|
||||
|
||||
// class GoogleDriverMap extends StatelessWidget {
|
||||
// const GoogleDriverMap({
|
||||
// super.key,
|
||||
// required this.locationController,
|
||||
// });
|
||||
|
||||
// final LocationController locationController;
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// Get.put(MapDriverController());
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.all(8.0),
|
||||
// child: GetBuilder<MapDriverController>(
|
||||
// builder: (controller) => Column(
|
||||
// children: [
|
||||
// SizedBox(
|
||||
// height: Get.height * .92,
|
||||
// child: GoogleMap(
|
||||
// onMapCreated: controller.onMapCreated,
|
||||
// zoomControlsEnabled: true,
|
||||
// // initialCameraPosition: CameraPosition(
|
||||
// // target: locationController.myLocation,
|
||||
// // zoom: 13,
|
||||
// // bearing: locationController.heading,
|
||||
// // tilt: 40,
|
||||
// // ),
|
||||
// initialCameraPosition: CameraPosition(
|
||||
// target: locationController.myLocation,
|
||||
// zoom: 17,
|
||||
// bearing: locationController.heading, // استخدام اتجاه السائق
|
||||
// tilt: 60, // زاوية ميل
|
||||
// ),
|
||||
// cameraTargetBounds:
|
||||
// CameraTargetBounds.unbounded, // Allow unrestricted movement
|
||||
// onCameraMove: (position) {
|
||||
// CameraPosition(
|
||||
// target: locationController.myLocation,
|
||||
// zoom: 13,
|
||||
// bearing: locationController.heading,
|
||||
// tilt: 40,
|
||||
// );
|
||||
// //todo
|
||||
// // locationController.myLocation = position.target;
|
||||
// //
|
||||
// // controller.mapController
|
||||
// // ?.animateCamera(CameraUpdate.newCameraPosition(position));
|
||||
// },
|
||||
// minMaxZoomPreference: const MinMaxZoomPreference(8, 15),
|
||||
// myLocationEnabled: true,
|
||||
// myLocationButtonEnabled: true,
|
||||
// compassEnabled: true,
|
||||
// mapType: MapType.terrain,
|
||||
// rotateGesturesEnabled: true,
|
||||
// scrollGesturesEnabled: true,
|
||||
// trafficEnabled: false,
|
||||
// buildingsEnabled: true,
|
||||
// mapToolbarEnabled: true,
|
||||
// fortyFiveDegreeImageryEnabled: true,
|
||||
// zoomGesturesEnabled: true,
|
||||
// polylines: {
|
||||
// Polyline(
|
||||
// zIndex: 2,
|
||||
// geodesic: true,
|
||||
// polylineId: const PolylineId('route1'),
|
||||
// points: controller.polylineCoordinates,
|
||||
// color: const Color.fromARGB(255, 163, 81, 246),
|
||||
// width: 5,
|
||||
// ),
|
||||
// Polyline(
|
||||
// zIndex: 2,
|
||||
// geodesic: true,
|
||||
// polylineId: const PolylineId('route'),
|
||||
// points: controller.polylineCoordinatesDestination,
|
||||
// color: const Color.fromARGB(255, 10, 29, 126),
|
||||
// width: 5,
|
||||
// ),
|
||||
// },
|
||||
// markers: {
|
||||
// Marker(
|
||||
// markerId: MarkerId('MyLocation'.tr),
|
||||
// position: locationController.myLocation,
|
||||
// draggable: true,
|
||||
// icon: controller.carIcon,
|
||||
// rotation: locationController.heading,
|
||||
// ),
|
||||
// Marker(
|
||||
// markerId: MarkerId('start'.tr),
|
||||
// position: controller.latLngPassengerLocation,
|
||||
// draggable: true,
|
||||
// icon: controller.startIcon,
|
||||
// ),
|
||||
// Marker(
|
||||
// markerId: MarkerId('end'.tr),
|
||||
// position: controller.latLngPassengerDestination,
|
||||
// draggable: true,
|
||||
// icon: controller.endIcon,
|
||||
// ),
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
@@ -15,93 +129,88 @@ class GoogleDriverMap extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Get.put(MapDriverController());
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: GetBuilder<MapDriverController>(
|
||||
builder: (controller) => Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: Get.height * .92,
|
||||
child: GoogleMap(
|
||||
onMapCreated: controller.onMapCreated,
|
||||
zoomControlsEnabled: true,
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: locationController.myLocation,
|
||||
zoom: 13,
|
||||
bearing: locationController.heading,
|
||||
tilt: 40,
|
||||
),
|
||||
cameraTargetBounds:
|
||||
CameraTargetBounds.unbounded, // Allow unrestricted movement
|
||||
onCameraMove: (position) {
|
||||
CameraPosition(
|
||||
target: locationController.myLocation,
|
||||
zoom: 13,
|
||||
bearing: locationController.heading,
|
||||
tilt: 40,
|
||||
);
|
||||
//todo
|
||||
// locationController.myLocation = position.target;
|
||||
//
|
||||
// controller.mapController
|
||||
// ?.animateCamera(CameraUpdate.newCameraPosition(position));
|
||||
},
|
||||
minMaxZoomPreference: const MinMaxZoomPreference(8, 15),
|
||||
myLocationEnabled: true,
|
||||
myLocationButtonEnabled: true,
|
||||
compassEnabled: true,
|
||||
mapType: MapType.terrain,
|
||||
rotateGesturesEnabled: true,
|
||||
scrollGesturesEnabled: true,
|
||||
trafficEnabled: false,
|
||||
buildingsEnabled: true,
|
||||
mapToolbarEnabled: true,
|
||||
fortyFiveDegreeImageryEnabled: true,
|
||||
zoomGesturesEnabled: true,
|
||||
polylines: {
|
||||
Polyline(
|
||||
zIndex: 2,
|
||||
geodesic: true,
|
||||
polylineId: const PolylineId('route1'),
|
||||
points: controller.polylineCoordinates,
|
||||
color: const Color.fromARGB(255, 163, 81, 246),
|
||||
width: 5,
|
||||
),
|
||||
Polyline(
|
||||
zIndex: 2,
|
||||
geodesic: true,
|
||||
polylineId: const PolylineId('route'),
|
||||
points: controller.polylineCoordinatesDestination,
|
||||
color: const Color.fromARGB(255, 10, 29, 126),
|
||||
width: 5,
|
||||
),
|
||||
},
|
||||
markers: {
|
||||
Marker(
|
||||
markerId: MarkerId('MyLocation'.tr),
|
||||
position: locationController.myLocation,
|
||||
draggable: true,
|
||||
icon: controller.carIcon,
|
||||
rotation: locationController.heading,
|
||||
),
|
||||
Marker(
|
||||
markerId: MarkerId('start'.tr),
|
||||
position: controller.latLngPassengerLocation,
|
||||
draggable: true,
|
||||
icon: controller.startIcon,
|
||||
),
|
||||
Marker(
|
||||
markerId: MarkerId('end'.tr),
|
||||
position: controller.latLngPassengerDestination,
|
||||
draggable: true,
|
||||
icon: controller.endIcon,
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
final MapDriverController controller = Get.put(MapDriverController());
|
||||
|
||||
// New: تحديد قيمة الـ padding لتحريك مركز الخريطة للأعلى
|
||||
final double mapPaddingBottom = MediaQuery.of(context).size.height * 0.3;
|
||||
|
||||
return GetBuilder<MapDriverController>(
|
||||
builder: (controller) => GoogleMap(
|
||||
onMapCreated: (mapController) {
|
||||
controller.onMapCreated(mapController);
|
||||
// New: تطبيق الـ padding بعد إنشاء الخريطة مباشرة
|
||||
mapController.setMapStyle('[]'); // يمكنك إضافة تصميم مخصص للخريطة هنا
|
||||
// يمكنك استخدام CameraUpdate.scrollBy لتحريك الكاميرا إذا رغبت بذلك:
|
||||
// controller.mapController!.animateCamera(CameraUpdate.scrollBy(0, mapPaddingBottom));
|
||||
},
|
||||
// New: إضافة padding لتحريك مركز الخريطة للأعلى، مما يجعل أيقونة السائق تظهر في الأسفل
|
||||
|
||||
zoomControlsEnabled: false, // Changed: تم إخفاء أزرار الزوم الافتراضية
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: locationController.myLocation,
|
||||
zoom: 17,
|
||||
bearing: locationController.heading, // استخدام اتجاه السائق
|
||||
tilt: 60, // زاوية ميل
|
||||
),
|
||||
onCameraMove: (position) {
|
||||
CameraPosition(
|
||||
target: locationController.myLocation,
|
||||
zoom: 17.5,
|
||||
tilt: 50.0,
|
||||
bearing: locationController.heading,
|
||||
);
|
||||
},
|
||||
padding: EdgeInsets.only(bottom: 50, top: Get.height * 0.7),
|
||||
minMaxZoomPreference: const MinMaxZoomPreference(8, 18),
|
||||
myLocationEnabled: false, // Changed: تم الاعتماد على ماركر مخصص
|
||||
myLocationButtonEnabled: true,
|
||||
compassEnabled: true,
|
||||
mapType: MapType.terrain,
|
||||
trafficEnabled: true, // Changed: تفعيل عرض حركة المرور
|
||||
buildingsEnabled: true,
|
||||
polylines: {
|
||||
Polyline(
|
||||
zIndex: 2,
|
||||
|
||||
polylineId: const PolylineId('route1'),
|
||||
points: controller.polylineCoordinates,
|
||||
color: const Color.fromARGB(255, 163, 81, 246),
|
||||
width: 6, // Changed: زيادة عرض الخط
|
||||
startCap: Cap.roundCap,
|
||||
endCap: Cap.roundCap,
|
||||
),
|
||||
Polyline(
|
||||
zIndex: 2,
|
||||
|
||||
polylineId: const PolylineId('route'),
|
||||
points: controller.polylineCoordinatesDestination,
|
||||
color: const Color.fromARGB(255, 10, 29, 126),
|
||||
width: 6, // Changed: زيادة عرض الخط
|
||||
startCap: Cap.roundCap,
|
||||
endCap: Cap.roundCap,
|
||||
),
|
||||
},
|
||||
markers: {
|
||||
Marker(
|
||||
markerId: MarkerId('MyLocation'.tr),
|
||||
position: locationController.myLocation,
|
||||
draggable: false, // Changed: لا يمكن سحب ماركر السائق
|
||||
icon: controller.carIcon,
|
||||
rotation: locationController.heading,
|
||||
anchor: const Offset(
|
||||
0.5, 0.5), // New: وضع نقطة ارتكاز الأيقونة في المنتصف
|
||||
),
|
||||
Marker(
|
||||
markerId: MarkerId('start'.tr),
|
||||
position: controller.latLngPassengerLocation,
|
||||
icon: controller.startIcon,
|
||||
),
|
||||
Marker(
|
||||
markerId: MarkerId('end'.tr),
|
||||
position: controller.latLngPassengerDestination,
|
||||
icon: controller.endIcon,
|
||||
),
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,93 +1,287 @@
|
||||
import 'dart:io';
|
||||
// import 'dart:io';
|
||||
|
||||
// import 'package:bubble_head/bubble.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_font_icons/flutter_font_icons.dart';
|
||||
// import 'package:get/get.dart';
|
||||
// import 'package:sefer_driver/constant/info.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/my_textField.dart';
|
||||
// import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
// import '../../../../constant/box_name.dart';
|
||||
// import '../../../../constant/colors.dart';
|
||||
// import '../../../../constant/style.dart';
|
||||
// import '../../../../controller/functions/launch.dart';
|
||||
// import '../../../../controller/home/captin/map_driver_controller.dart';
|
||||
// import '../../../../main.dart';
|
||||
|
||||
// class SosConnect extends StatelessWidget {
|
||||
// const SosConnect({super.key});
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return GetBuilder<MapDriverController>(
|
||||
// builder: (mapDriverController) => mapDriverController.isRideStarted
|
||||
// ? Positioned(
|
||||
// left: 16,
|
||||
// bottom: 16,
|
||||
// child: Card(
|
||||
// elevation: 4,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(12),
|
||||
// ),
|
||||
// child: SizedBox(
|
||||
// height: 60,
|
||||
// width: 180,
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
// children: [
|
||||
// IconButton(
|
||||
// onPressed: () {
|
||||
// _handleSosCall(mapDriverController);
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.sos_sharp,
|
||||
// size: 32,
|
||||
// color: AppColor.redColor,
|
||||
// ),
|
||||
// tooltip: 'SOS - Call Emergency',
|
||||
// ),
|
||||
// VerticalDivider(
|
||||
// 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) {
|
||||
// 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
|
||||
// launchCommunication(
|
||||
// 'phone', box.read(BoxName.sosPhoneDriver), '');
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// } else {
|
||||
// launchCommunication('phone', box.read(BoxName.sosPhoneDriver), '');
|
||||
// }
|
||||
// }
|
||||
|
||||
// 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}.",
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
import 'package:bubble_head/bubble.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_font_icons/flutter_font_icons.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sefer_driver/constant/info.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/my_textField.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../../../constant/box_name.dart';
|
||||
import '../../../../constant/colors.dart';
|
||||
import '../../../../constant/style.dart';
|
||||
import '../../../../controller/firebase/firbase_messge.dart';
|
||||
import '../../../../controller/functions/launch.dart';
|
||||
import '../../../../controller/home/captin/map_driver_controller.dart';
|
||||
import '../../../../main.dart';
|
||||
|
||||
// Changed: إعادة تصميم وتغيير موضع أزرار التواصل والطوارئ
|
||||
class SosConnect extends StatelessWidget {
|
||||
const SosConnect({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<MapDriverController>(
|
||||
builder: (mapDriverController) => mapDriverController.isRideStarted
|
||||
? Positioned(
|
||||
left: 16,
|
||||
bottom: 16,
|
||||
child: Card(
|
||||
elevation: 4,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
builder: (controller) {
|
||||
// New: تجميع الأزرار في عمود واحد على الجانب الأيمن
|
||||
return Positioned(
|
||||
bottom: 110, // New: فوق عداد السرعة
|
||||
right: 16,
|
||||
child: Column(
|
||||
children: [
|
||||
// زر الاتصال بالراكب (يظهر قبل بدء الرحلة)
|
||||
if (!controller.isRideBegin && controller.isPassengerInfoWindow)
|
||||
_buildSocialButton(
|
||||
icon: Icons.phone,
|
||||
color: AppColor.blueColor,
|
||||
tooltip: 'Call Passenger',
|
||||
onPressed: () async {
|
||||
controller.isSocialPressed = true;
|
||||
await controller.driverCallPassenger();
|
||||
makePhoneCall(controller.passengerPhone.toString());
|
||||
},
|
||||
),
|
||||
child: SizedBox(
|
||||
height: 60,
|
||||
width: 180,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
_handleSosCall(mapDriverController);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.sos_sharp,
|
||||
size: 32,
|
||||
color: AppColor.redColor,
|
||||
),
|
||||
tooltip: 'SOS - Call Emergency',
|
||||
),
|
||||
VerticalDivider(
|
||||
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',
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// زر الرسائل للراكب (يظهر قبل بدء الرحلة)
|
||||
if (!controller.isRideBegin && controller.isPassengerInfoWindow)
|
||||
const SizedBox(height: 12),
|
||||
if (!controller.isRideBegin && controller.isPassengerInfoWindow)
|
||||
_buildSocialButton(
|
||||
icon: Icons.message,
|
||||
color: AppColor.greenColor,
|
||||
tooltip: 'Send Message',
|
||||
onPressed: () {
|
||||
// الكود الخاص بنافذة الرسائل السريعة
|
||||
_showMessageOptions(context, controller);
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
|
||||
// زر الطوارئ (SOS) (يظهر بعد بدء الرحلة)
|
||||
if (controller.isRideStarted)
|
||||
_buildSocialButton(
|
||||
icon: Icons.sos_sharp,
|
||||
color: AppColor.redColor,
|
||||
tooltip: 'SOS - Call Emergency',
|
||||
onPressed: () => _handleSosCall(controller),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// New: ودجت منفصل لبناء أزرار التواصل
|
||||
Widget _buildSocialButton(
|
||||
{required IconData icon,
|
||||
required Color color,
|
||||
required String tooltip,
|
||||
required VoidCallback onPressed}) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white,
|
||||
boxShadow: [BoxShadow(blurRadius: 5, color: Colors.black26)],
|
||||
),
|
||||
child: IconButton(
|
||||
icon: Icon(icon, color: color, size: 28),
|
||||
tooltip: tooltip,
|
||||
onPressed: onPressed,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// الكود الخاص بنافذة إدخال رقم الطوارئ
|
||||
void _handleSosCall(MapDriverController mapDriverController) {
|
||||
if (box.read(BoxName.sosPhoneDriver) == null) {
|
||||
Get.defaultDialog(
|
||||
@@ -107,7 +301,7 @@ class SosConnect extends StatelessWidget {
|
||||
if (mapDriverController.formKey1.currentState!.validate()) {
|
||||
box.write(BoxName.sosPhoneDriver,
|
||||
mapDriverController.sosEmergincyNumberCotroller.text);
|
||||
Get.back(); // Close the dialog
|
||||
Get.back();
|
||||
launchCommunication(
|
||||
'phone', box.read(BoxName.sosPhoneDriver), '');
|
||||
}
|
||||
@@ -119,75 +313,99 @@ class SosConnect extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// New: الكود الخاص بنافذة الرسائل السريعة (مستخرج من passenger_info_window.dart)
|
||||
void _showMessageOptions(
|
||||
BuildContext context, MapDriverController controller) {
|
||||
Get.bottomSheet(
|
||||
backgroundColor: Colors.white,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: _buildMessageOptions(controller),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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';
|
||||
}
|
||||
}();
|
||||
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();
|
||||
}),
|
||||
_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();
|
||||
}),
|
||||
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),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
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}.",
|
||||
);
|
||||
}
|
||||
Widget _buildMessageTile(
|
||||
{required String text, required VoidCallback onTap}) {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user