Fixes & Updates - 2026-06-01: Integrate Back-End v3 updates, fix call/connection issues across apps

This commit is contained in:
Hamza-Ayed
2026-06-01 23:36:27 +03:00
parent 118781fd66
commit 97945aa362
76 changed files with 19806 additions and 10822 deletions

View File

@@ -1,7 +1,9 @@
import 'package:Intaleq/constant/colors.dart';
import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/constant/style.dart';
import 'package:Intaleq/controller/home/map_passenger_controller.dart';
import 'package:Intaleq/controller/home/map/ride_lifecycle_controller.dart';
import 'package:Intaleq/controller/home/map/ride_state.dart';
import 'package:Intaleq/controller/voice_call_controller.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
@@ -10,6 +12,7 @@ import 'package:intl/intl.dart';
import '../../../constant/box_name.dart';
import '../../../controller/firebase/notification_service.dart';
import '../../../controller/functions/launch.dart';
import '../../../controller/functions/crud.dart';
import '../../../main.dart';
class ApplyOrderWidget extends StatelessWidget {
@@ -29,7 +32,7 @@ class ApplyOrderWidget extends StatelessWidget {
}
return Obx(() {
final controller = Get.find<MapPassengerController>();
final controller = Get.find<RideLifecycleController>();
final bool isVisible =
controller.currentRideState.value == RideState.driverApplied ||
@@ -57,7 +60,7 @@ class ApplyOrderWidget extends StatelessWidget {
),
// تغيير: تقليل الحواف الخارجية بشكل كبير
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
child: GetBuilder<MapPassengerController>(
child: GetBuilder<RideLifecycleController>(
builder: (c) {
return Column(
mainAxisSize:
@@ -106,15 +109,18 @@ class ApplyOrderWidget extends StatelessWidget {
// [NEW] 1. صف الرأس المضغوط (يحتوي الحالة + الإحصائيات + السعر)
// ---------------------------------------------------------------------------
Widget _buildCompactHeaderRow(
BuildContext context, MapPassengerController controller) {
BuildContext context, RideLifecycleController controller) {
// تنسيق السعر
final formatter = NumberFormat("#,###");
String formattedPrice = formatter.format(controller.totalPassenger);
// حساب الدقائق
int minutes =
(controller.timeToPassengerFromDriverAfterApplied / 60).ceil();
if (minutes < 1) minutes = 1;
// حساب الدقائق من الوقت المتبقي الحي، وليس ETA الأصلي فقط.
final int secondsToPassenger =
controller.remainingTimeToPassengerFromDriverAfterApplied > 0
? controller.remainingTimeToPassengerFromDriverAfterApplied
: controller.timeToPassengerFromDriverAfterApplied;
final int minutes =
secondsToPassenger <= 0 ? 0 : (secondsToPassenger / 60).ceil();
// تنسيق المسافة
String distanceDisplay = "";
@@ -151,7 +157,7 @@ class ApplyOrderWidget extends StatelessWidget {
children: [
_buildMiniStatChip(
icon: Icons.access_time_filled_rounded,
text: "$minutes ${'min'.tr}",
text: minutes > 0 ? "$minutes ${'min'.tr}" : "--",
color: AppColor.primaryColor,
bgColor: AppColor.primaryColor.withOpacity(0.1),
),
@@ -229,7 +235,7 @@ class ApplyOrderWidget extends StatelessWidget {
// [MODIFIED] 2. كرت المعلومات المضغوط جداً
// ---------------------------------------------------------------------------
Widget _buildCompactInfoCard(BuildContext context,
MapPassengerController controller, Color Function(String) parseColor) {
RideLifecycleController controller, Color Function(String) parseColor) {
return Container(
// تقليل الحواف الداخلية للكرت
padding: const EdgeInsets.all(10),
@@ -312,7 +318,7 @@ class ApplyOrderWidget extends StatelessWidget {
}
Widget _buildMicroCarIcon(
MapPassengerController controller, Color Function(String) parseColor) {
RideLifecycleController controller, Color Function(String) parseColor) {
Color carColor = parseColor(controller.colorHex);
return Container(
height: 40, // تصغير من 50
@@ -343,9 +349,8 @@ class ApplyOrderWidget extends StatelessWidget {
color: Get.isDarkMode ? Colors.grey[850] : const Color(0xFFF5F5F5),
borderRadius: BorderRadius.circular(6),
border: Border.all(
color: Get.isDarkMode
? Colors.white10
: Colors.grey.withOpacity(0.3)),
color:
Get.isDarkMode ? Colors.white10 : Colors.grey.withOpacity(0.3)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -374,7 +379,7 @@ class ApplyOrderWidget extends StatelessWidget {
// [MODIFIED] 3. أزرار الاتصال (Slim Buttons)
// ---------------------------------------------------------------------------
Widget _buildCompactButtonsRow(
BuildContext context, MapPassengerController controller) {
BuildContext context, RideLifecycleController controller) {
return SizedBox(
height: 40, // تحديد ارتفاع ثابت وصغير للأزرار
child: Row(
@@ -397,7 +402,7 @@ class ApplyOrderWidget extends StatelessWidget {
bgColor: AppColor.greenColor,
onTap: () {
HapticFeedback.heavyImpact();
makePhoneCall(controller.driverPhone);
_showCallSelectionDialog(context, controller);
},
isPrimary: true,
),
@@ -407,6 +412,73 @@ class ApplyOrderWidget extends StatelessWidget {
);
}
void _showCallSelectionDialog(
BuildContext context, RideLifecycleController controller) {
Get.dialog(
Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Call Options'.tr,
style: AppStyle.title
.copyWith(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Text(
'Choose how you want to call the driver'.tr,
style: const TextStyle(color: Colors.grey, fontSize: 14),
textAlign: TextAlign.center,
),
const SizedBox(height: 20),
ListTile(
leading: CircleAvatar(
backgroundColor: AppColor.greenColor.withOpacity(0.1),
child: Icon(Icons.phone_android_rounded,
color: AppColor.greenColor),
),
title: Text('Standard Call'.tr,
style: const TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text('Uses cellular network'.tr,
style: const TextStyle(fontSize: 12)),
onTap: () {
Get.back();
makePhoneCall(controller.driverPhone);
},
),
const Divider(),
ListTile(
leading: CircleAvatar(
backgroundColor: AppColor.primaryColor.withOpacity(0.1),
child: Icon(Icons.wifi_calling_3_rounded,
color: AppColor.primaryColor),
),
title: Text('Free Call'.tr,
style: const TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text('Voice call over internet'.tr,
style: const TextStyle(fontSize: 12)),
onTap: () {
Get.back();
final voiceCtrl = Get.find<VoiceCallController>();
final passengerId = box.read(BoxName.passengerID).toString();
voiceCtrl.startCall(
rideIdVal: controller.rideId,
driverId: controller.driverId,
passengerId: passengerId,
remoteNameVal: controller.driverName,
);
},
),
],
),
),
),
);
}
Widget _buildSlimButton({
required String label,
required IconData icon,
@@ -444,7 +516,7 @@ class ApplyOrderWidget extends StatelessWidget {
// --- النوافذ المنبثقة للرسائل (نفس الكود السابق مع تحسين بسيط) ---
void _showContactOptionsDialog(
BuildContext context, MapPassengerController controller) {
BuildContext context, RideLifecycleController controller) {
Get.bottomSheet(
Container(
padding: const EdgeInsets.all(20),
@@ -470,7 +542,7 @@ class ApplyOrderWidget extends StatelessWidget {
);
}
List<Widget> _buildPredefinedMessages(MapPassengerController controller) {
List<Widget> _buildPredefinedMessages(RideLifecycleController controller) {
const messages = [
'Hello, I\'m at the agreed-upon location',
'I\'m waiting for you',
@@ -510,7 +582,7 @@ class ApplyOrderWidget extends StatelessWidget {
}
Widget _buildCustomMessageInput(
MapPassengerController controller, BuildContext context) {
RideLifecycleController controller, BuildContext context) {
return Row(
children: [
Expanded(
@@ -555,7 +627,22 @@ class ApplyOrderWidget extends StatelessWidget {
);
}
void _sendMessage(MapPassengerController controller, String text) {
void _sendMessage(RideLifecycleController controller, String text) async {
try {
await CRUD().post(
link: AppLink.sendChatMessage,
payload: {
'ride_id': controller.rideId.toString(),
'sender_id': box.read(BoxName.passengerID).toString(),
'receiver_id': controller.driverId.toString(),
'sender_type': 'passenger',
'message_content': text.tr,
},
);
} catch (e) {
// Ignore or log error
}
NotificationService.sendNotification(
category: 'MSG_FROM_PASSENGER',
target: controller.driverToken.toString(),
@@ -577,7 +664,7 @@ class DriverArrivePassengerAndWaitMinute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetBuilder<MapPassengerController>(builder: (controller) {
return GetBuilder<RideLifecycleController>(builder: (controller) {
return Column(
children: [
Row(
@@ -619,7 +706,7 @@ class TimeDriverToPassenger extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetBuilder<MapPassengerController>(builder: (controller) {
return GetBuilder<RideLifecycleController>(builder: (controller) {
if (controller.timeToPassengerFromDriverAfterApplied <= 0) {
return const SizedBox();
}