Fixes & Updates - 2026-06-01: Integrate Back-End v3 updates, fix call/connection issues across apps
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user