25-12-1/1
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import 'package:sefer_driver/constant/box_name.dart';
|
||||
import 'package:sefer_driver/constant/style.dart';
|
||||
import 'package:sefer_driver/views/widgets/elevated_btn.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -6,6 +7,7 @@ import 'package:sefer_driver/controller/home/captin/map_driver_controller.dart';
|
||||
|
||||
import '../../../constant/colors.dart';
|
||||
import '../../../controller/functions/location_controller.dart';
|
||||
import '../../../main.dart';
|
||||
import '../../Rate/rate_passenger.dart';
|
||||
import '../../widgets/my_textField.dart';
|
||||
import 'mapDriverWidgets/driver_end_ride_bar.dart';
|
||||
@@ -14,114 +16,169 @@ import 'mapDriverWidgets/google_map_app.dart';
|
||||
import 'mapDriverWidgets/passenger_info_window.dart';
|
||||
import 'mapDriverWidgets/sos_connect.dart';
|
||||
|
||||
// Changed: تم إعادة بناء الصفحة بالكامل لتكون أكثر تنظيمًا
|
||||
class PassengerLocationMapPage extends StatelessWidget {
|
||||
PassengerLocationMapPage({super.key});
|
||||
final LocationController locationController = Get.put(LocationController());
|
||||
final MapDriverController mapDriverController =
|
||||
Get.put(MapDriverController());
|
||||
|
||||
// Helper function to show exit confirmation dialog
|
||||
Future<bool> showExitDialog() async {
|
||||
bool? result = await Get.defaultDialog(
|
||||
title: "Warning".tr,
|
||||
titleStyle: AppStyle.title.copyWith(color: AppColor.redColor),
|
||||
middleText:
|
||||
"You are in an active ride. Leaving this screen might stop tracking. Are you sure you want to exit?"
|
||||
.tr,
|
||||
middleTextStyle: AppStyle.title,
|
||||
barrierDismissible: false,
|
||||
confirm: MyElevatedButton(
|
||||
title: 'Stay'.tr,
|
||||
kolor: AppColor.greenColor,
|
||||
onPressed: () => Get.back(result: false), // Return false (Don't pop)
|
||||
),
|
||||
cancel: MyElevatedButton(
|
||||
title: 'Exit'.tr,
|
||||
kolor: AppColor.redColor,
|
||||
onPressed: () => Get.back(result: true), // Return true (Allow pop)
|
||||
),
|
||||
);
|
||||
return result ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// New: استخدام addPostFrameCallback لضمان أن تحميل البيانات يتم بعد بناء الواجهة
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (Get.arguments != null && Get.arguments is Map<String, dynamic>) {
|
||||
mapDriverController.argumentLoading();
|
||||
mapDriverController.startTimerToShowPassengerInfoWindowFromDriver();
|
||||
} else {
|
||||
// في حال عدم وجود arguments، يتم التعامل مع هذا الخطأ
|
||||
Get.snackbar("Error", "No order data found.");
|
||||
Get.back();
|
||||
}
|
||||
});
|
||||
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Stack(
|
||||
children: [
|
||||
// 1. الخريطة في الخلفية
|
||||
GoogleDriverMap(locationController: locationController),
|
||||
// ✅ Added PopScope to intercept back button
|
||||
return PopScope(
|
||||
canPop: false, // Prevents immediate popping
|
||||
onPopInvokedWithResult: (didPop, result) async {
|
||||
if (didPop) {
|
||||
return;
|
||||
}
|
||||
// Show dialog
|
||||
final shouldExit = await showExitDialog();
|
||||
if (shouldExit) {
|
||||
Get.back(); // Manually pop if confirmed
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
body: SafeArea(
|
||||
child: Stack(
|
||||
children: [
|
||||
// 1. Map
|
||||
GoogleDriverMap(locationController: locationController),
|
||||
|
||||
// 2. شريط تعليمات الطريق في الأعلى
|
||||
const InstructionsOfRoads(),
|
||||
// 2. Instructions
|
||||
const InstructionsOfRoads(),
|
||||
|
||||
// 4. نافذة معلومات الراكب في الأسفل (تظهر قبل بدء الرحلة)
|
||||
// 3. Passenger Info
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: PassengerInfoWindow(),
|
||||
),
|
||||
|
||||
PassengerInfoWindow(),
|
||||
// 3. زر إلغاء الرحلة في الأعلى يسارًا
|
||||
// 4. Cancel Widget
|
||||
CancelWidget(mapDriverController: mapDriverController),
|
||||
|
||||
CancelWidget(mapDriverController: mapDriverController),
|
||||
// Changed: تم تعديل تصميم زر الإلغاء ليكون أيقونة بسيطة في الأعلى
|
||||
// 5. شريط معلومات وإنهاء الرحلة (يظهر بعد بدء الرحلة)
|
||||
driverEndRideBar(),
|
||||
// 5. End Ride Bar
|
||||
driverEndRideBar(),
|
||||
|
||||
// 6. أزرار الطوارئ والاتصال
|
||||
SosConnect(),
|
||||
// 6. SOS
|
||||
SosConnect(),
|
||||
|
||||
// 7. دائرة عرض السرعة
|
||||
speedCircle(),
|
||||
GoogleMapApp(),
|
||||
// 8. نافذة عرض السعر النهائي (تظهر بعد انتهاء الرحلة)
|
||||
const PricesWindow(),
|
||||
],
|
||||
),
|
||||
));
|
||||
// 7. Speed
|
||||
speedCircle(),
|
||||
|
||||
// 8. External Map
|
||||
Positioned(
|
||||
bottom: 100,
|
||||
right: 10,
|
||||
child: GoogleMapApp(),
|
||||
),
|
||||
|
||||
// 9. Prices Window
|
||||
const PricesWindow(),
|
||||
],
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// New: تصميم جديد لشريط تعليمات الطريق في أعلى الشاشة
|
||||
// ... The rest of your widgets (InstructionsOfRoads, CancelWidget, etc.) remain unchanged ...
|
||||
// ... Keep the code below exactly as you had it in the previous snippet ...
|
||||
|
||||
class InstructionsOfRoads extends StatelessWidget {
|
||||
const InstructionsOfRoads({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<MapDriverController>(
|
||||
builder: (controller) =>
|
||||
// يتم إظهار التعليمات فقط إذا كانت متوفرة
|
||||
controller.currentInstruction.isNotEmpty
|
||||
? Positioned(
|
||||
bottom: 10,
|
||||
left: MediaQuery.of(context).size.width * 0.15,
|
||||
right: MediaQuery.of(context).size.width * 0.15,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
return Positioned(
|
||||
bottom: 10,
|
||||
left: MediaQuery.of(context).size.width * 0.15,
|
||||
right: MediaQuery.of(context).size.width * 0.15,
|
||||
child: GetBuilder<MapDriverController>(
|
||||
builder: (controller) => controller.currentInstruction.isNotEmpty
|
||||
? AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.directions,
|
||||
color: AppColor.primaryColor),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
controller.currentInstruction,
|
||||
style: AppStyle.title.copyWith(fontSize: 16),
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.directions, color: AppColor.primaryColor),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
controller.currentInstruction,
|
||||
style: AppStyle.title.copyWith(fontSize: 16),
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox(), // في حالة عدم وجود تعليمات، لا يظهر شيء
|
||||
const SizedBox(width: 10),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
controller.toggleTts();
|
||||
},
|
||||
child: Icon(
|
||||
controller.isTtsEnabled
|
||||
? Icons.volume_up
|
||||
: Icons.volume_off,
|
||||
color: controller.isTtsEnabled
|
||||
? AppColor.greenColor
|
||||
: Colors.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Changed: تم تعديل تصميم وموضع زر الإلغاء ليكون أيقونة بسيطة في الأعلى
|
||||
class CancelWidget extends StatelessWidget {
|
||||
const CancelWidget({
|
||||
super.key,
|
||||
@@ -137,7 +194,6 @@ class CancelWidget extends StatelessWidget {
|
||||
left: 10,
|
||||
child: GetBuilder<MapDriverController>(
|
||||
builder: (controller) {
|
||||
// يظهر زر الإلغاء فقط قبل انتهاء الرحلة
|
||||
if (controller.isRideFinished) return const SizedBox.shrink();
|
||||
|
||||
return GestureDetector(
|
||||
@@ -199,7 +255,6 @@ class CancelWidget extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// Changed: تم تعديل تصميم نافذة السعر لتكون أكثر وضوحًا
|
||||
class PricesWindow extends StatelessWidget {
|
||||
const PricesWindow({
|
||||
super.key,
|
||||
|
||||
Reference in New Issue
Block a user