25-12-1/1

This commit is contained in:
Hamza-Ayed
2025-12-01 07:52:54 +03:00
parent b1b8efdd7d
commit 9b1008a0bf
40 changed files with 2471 additions and 2039 deletions

View File

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