This commit is contained in:
Hamza-Ayed
2025-08-04 22:43:04 +03:00
parent 83a97baed1
commit ba02d41e6d
35 changed files with 3437 additions and 2959 deletions

View File

@@ -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)),
],
),
),
),

View File

@@ -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,
),
},
),
);
}

View File

@@ -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();
});
},
);
}
}

View File

@@ -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),
),
);
}
}