Update: 2026-06-10 18:11:50
This commit is contained in:
@@ -87,12 +87,6 @@ class FirebaseMessagesController extends GetxController {
|
||||
fireBaseTitles(message);
|
||||
}
|
||||
});
|
||||
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) async {
|
||||
// Handle background message
|
||||
if (message.data.isNotEmpty) {
|
||||
fireBaseTitles(message);
|
||||
}
|
||||
});
|
||||
|
||||
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
|
||||
if (message.data.isNotEmpty && message.notification != null) {
|
||||
|
||||
@@ -283,7 +283,7 @@ class MapSocketController extends GetxController {
|
||||
}
|
||||
|
||||
final dynamic distanceValue =
|
||||
data['distance_m'] ?? data['distance_meters'] ?? data['distance'];
|
||||
data['distance_m'] ?? data['distance_meters'];
|
||||
final double? distanceMeters =
|
||||
double.tryParse(distanceValue?.toString() ?? '');
|
||||
final int? etaSeconds = data['eta_seconds'] == null
|
||||
|
||||
@@ -112,6 +112,7 @@ class RideLifecycleController extends GetxController {
|
||||
late String driverId = '';
|
||||
late String make = '';
|
||||
late String model = '';
|
||||
late String gender = '';
|
||||
late String carColor = '';
|
||||
late String licensePlate = '';
|
||||
late String driverName = '';
|
||||
@@ -120,6 +121,9 @@ class RideLifecycleController extends GetxController {
|
||||
late String colorHex = '';
|
||||
late String carYear = '';
|
||||
late String driverRate = '5.0';
|
||||
late String driverRatingCount = '0';
|
||||
late String driverCompletedRides = '0';
|
||||
late String driverTier = 'Verified driver';
|
||||
late String driverToken = '';
|
||||
|
||||
double kazan = 8;
|
||||
@@ -1481,7 +1485,8 @@ class RideLifecycleController extends GetxController {
|
||||
|
||||
// إيقاف جلب السيارات المجاورة ومسحها، باستثناء السائق الذي قبل الطلب
|
||||
mapEngine.reloadStartApp = false;
|
||||
mapEngine.markers.removeWhere((marker) => marker.markerId.value != driverId.toString());
|
||||
mapEngine.markers
|
||||
.removeWhere((marker) => marker.markerId.value != driverId.toString());
|
||||
mapEngine.update();
|
||||
|
||||
await getDriverCarsLocationToPassengerAfterApplied();
|
||||
@@ -1490,8 +1495,7 @@ class RideLifecycleController extends GetxController {
|
||||
LatLng driverPos = driverCarsLocationToPassengerAfterApplied.last;
|
||||
Log.print(
|
||||
'[rideAppliedFromDriver] 📍 Driver at: $driverPos, Passenger at: $passengerLocation');
|
||||
await getInitialDriverDistanceAndDuration(driverPos, passengerLocation);
|
||||
await drawDriverPathOnly(driverPos, passengerLocation);
|
||||
await calculateDriverToPassengerRoute(driverPos, passengerLocation);
|
||||
mapEngine.fitCameraToPoints(driverPos, passengerLocation);
|
||||
}
|
||||
|
||||
@@ -1656,6 +1660,9 @@ class RideLifecycleController extends GetxController {
|
||||
driverToken = data['token']?.toString() ?? '';
|
||||
carYear = data['year']?.toString() ?? '';
|
||||
driverRate = data['ratingDriver']?.toString() ?? '5.0';
|
||||
driverRatingCount = data['ratingCount']?.toString() ?? '0';
|
||||
driverCompletedRides = data['completedRides']?.toString() ?? '0';
|
||||
driverTier = data['driverTier']?.toString() ?? 'Verified driver';
|
||||
|
||||
update();
|
||||
}
|
||||
@@ -2221,6 +2228,15 @@ class RideLifecycleController extends GetxController {
|
||||
polyLines = polyLines
|
||||
.where((p) => !p.polylineId.value.startsWith('driver_route'))
|
||||
.toSet();
|
||||
polyLines = {
|
||||
...polyLines,
|
||||
Polyline(
|
||||
polylineId: const PolylineId('main_route'),
|
||||
points: decodedPoints,
|
||||
color: const Color(0xFF2196F3),
|
||||
width: 6,
|
||||
)
|
||||
};
|
||||
} else {
|
||||
// مسح السلمات القديمة أولاً
|
||||
polyLines = polyLines
|
||||
@@ -2290,7 +2306,9 @@ class RideLifecycleController extends GetxController {
|
||||
_routeHeadingMismatchCount = 0;
|
||||
_isRecalculatingRoute = true;
|
||||
if (statusRide == 'Begin' ||
|
||||
currentRideState.value == RideState.inProgress) {
|
||||
statusRide == 'Arrived' ||
|
||||
currentRideState.value == RideState.inProgress ||
|
||||
currentRideState.value == RideState.driverArrived) {
|
||||
await calculateDriverToPassengerRoute(driverPos, myDestination,
|
||||
isBeginPhase: true);
|
||||
} else {
|
||||
@@ -2504,6 +2522,8 @@ class RideLifecycleController extends GetxController {
|
||||
String icon;
|
||||
if (model.contains('دراجة') || make.contains('دراجة')) {
|
||||
icon = mapEngine.motoIcon;
|
||||
} else if (gender == 'Female') {
|
||||
icon = mapEngine.ladyIcon;
|
||||
} else {
|
||||
icon = mapEngine.carIcon;
|
||||
}
|
||||
@@ -3026,6 +3046,17 @@ class RideLifecycleController extends GetxController {
|
||||
mapEngine.playRouteAnimation(
|
||||
mapEngine.polylineCoordinates, mapEngine.lastComputedBounds);
|
||||
}
|
||||
|
||||
if (driverCarsLocationToPassengerAfterApplied.isNotEmpty &&
|
||||
myDestination.latitude != 0 &&
|
||||
myDestination.longitude != 0) {
|
||||
await calculateDriverToPassengerRoute(
|
||||
driverCarsLocationToPassengerAfterApplied.last,
|
||||
myDestination,
|
||||
isBeginPhase: true,
|
||||
);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -3903,12 +3934,37 @@ class RideLifecycleController extends GetxController {
|
||||
|
||||
make = data['make']?.toString() ?? '';
|
||||
model = data['model']?.toString() ?? '';
|
||||
gender = data['gender']?.toString() ?? '';
|
||||
carColor = data['color']?.toString() ?? '';
|
||||
colorHex = data['color_hex']?.toString() ?? '';
|
||||
licensePlate = data['car_plate']?.toString() ?? '';
|
||||
carYear = data['year']?.toString() ?? '';
|
||||
|
||||
// المحاولة الفورية لرسم السائق إذا توفرت الإحداثيات في البيانات
|
||||
double lat = double.tryParse(
|
||||
data['latitude']?.toString() ?? data['lat']?.toString() ?? '0') ??
|
||||
0;
|
||||
double lng = double.tryParse(data['longitude']?.toString() ??
|
||||
data['lng']?.toString() ??
|
||||
'0') ??
|
||||
0;
|
||||
double heading = double.tryParse(data['heading']?.toString() ?? '0') ?? 0;
|
||||
|
||||
if (lat != 0 && lng != 0) {
|
||||
LatLng initialPos = LatLng(lat, lng);
|
||||
if (driverCarsLocationToPassengerAfterApplied.isEmpty) {
|
||||
driverCarsLocationToPassengerAfterApplied.add(initialPos);
|
||||
} else {
|
||||
driverCarsLocationToPassengerAfterApplied[0] = initialPos;
|
||||
}
|
||||
// تحديث الماركر فوراً لضمان ظهوره بشكل موثوق
|
||||
updateDriverMarker(initialPos, heading);
|
||||
}
|
||||
|
||||
driverRate = data['ratingDriver']?.toString() ?? '5.0';
|
||||
driverRatingCount = data['ratingCount']?.toString() ?? '0';
|
||||
driverCompletedRides = data['completedRides']?.toString() ?? '0';
|
||||
driverTier = data['driverTier']?.toString() ?? 'Verified driver';
|
||||
driverToken = data['token']?.toString() ?? '';
|
||||
|
||||
update();
|
||||
@@ -4185,55 +4241,6 @@ class RideLifecycleController extends GetxController {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getDistanceFromDriverAfterAcceptedRide(
|
||||
String origin, String destination) async {
|
||||
String apiKey = Env.mapKeyOsm;
|
||||
if (origin.isEmpty) {
|
||||
origin = '${passengerLocation.latitude},${passengerLocation.longitude}';
|
||||
}
|
||||
var uri = Uri.parse(
|
||||
'$dynamicApiUrl?origin=$origin&destination=$destination&steps=false&overview=false');
|
||||
Log.print('uri: $uri');
|
||||
|
||||
http.Response response;
|
||||
Map<String, dynamic> responseData;
|
||||
|
||||
try {
|
||||
response = await http.get(
|
||||
uri,
|
||||
headers: {
|
||||
'X-API-KEY': apiKey,
|
||||
},
|
||||
).timeout(const Duration(seconds: 20));
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
Log.print('Error from API: ${response.statusCode}');
|
||||
isLoading = false;
|
||||
update();
|
||||
return;
|
||||
}
|
||||
if (Get.isBottomSheetOpen ?? false) {
|
||||
Get.back();
|
||||
}
|
||||
isDrawingRoute = false;
|
||||
|
||||
responseData = json.decode(response.body);
|
||||
Log.print('responseData: $responseData');
|
||||
|
||||
if (responseData['status'] != 'ok') {
|
||||
Log.print('API returned an error: ${responseData['message']}');
|
||||
isLoading = false;
|
||||
update();
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
Log.print('Failed to get directions: $e');
|
||||
isLoading = false;
|
||||
update();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _stageNiceToHave() async {
|
||||
Log.print('🚀 MapPassengerController: Starting _stageNiceToHave');
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
|
||||
import '../../../constant/box_name.dart';
|
||||
import '../../../constant/colors.dart';
|
||||
@@ -15,19 +14,13 @@ import '../../../main.dart'; // contains global 'box'
|
||||
import '../../../print.dart';
|
||||
import '../../../services/emergency_signal_service.dart';
|
||||
import '../../../views/widgets/elevated_btn.dart';
|
||||
import '../../../views/widgets/mydialoug.dart';
|
||||
import '../../../views/widgets/my_textField.dart';
|
||||
import '../../../views/home/map_page_passenger.dart';
|
||||
import '../../../views/widgets/error_snakbar.dart';
|
||||
import '../../../models/model/painter_copoun.dart';
|
||||
import '../../functions/launch.dart';
|
||||
import '../../firebase/local_notification.dart';
|
||||
import '../../firebase/notification_service.dart';
|
||||
import '../../functions/crud.dart';
|
||||
import '../../functions/tts.dart';
|
||||
import 'ride_lifecycle_controller.dart';
|
||||
import 'location_search_controller.dart';
|
||||
import 'map_engine_controller.dart';
|
||||
|
||||
class UiInteractionsController extends GetxController {
|
||||
TextEditingController sosPhonePassengerProfile = TextEditingController();
|
||||
@@ -56,54 +49,54 @@ class UiInteractionsController extends GetxController {
|
||||
|
||||
sosPhonePassengerProfile.clear();
|
||||
Get.defaultDialog(
|
||||
title: 'Add SOS Phone'.tr,
|
||||
titleStyle: AppStyle.title,
|
||||
content: Form(
|
||||
key: sosFormKey,
|
||||
child: Column(
|
||||
children: [
|
||||
MyTextForm(
|
||||
controller: sosPhonePassengerProfile,
|
||||
label: 'insert sos phone'.tr,
|
||||
hint: 'e.g. 0912345678 (Default +963)'.tr,
|
||||
type: TextInputType.phone,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Note: If no country code is entered, it will be saved as Syrian (+963).".tr,
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
title: 'Add SOS Phone'.tr,
|
||||
titleStyle: AppStyle.title,
|
||||
content: Form(
|
||||
key: sosFormKey,
|
||||
child: Column(
|
||||
children: [
|
||||
MyTextForm(
|
||||
controller: sosPhonePassengerProfile,
|
||||
label: 'insert sos phone'.tr,
|
||||
hint: 'e.g. 0912345678 (Default +963)'.tr,
|
||||
type: TextInputType.phone,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Note: If no country code is entered, it will be saved as Syrian (+963)."
|
||||
.tr,
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
confirm: MyElevatedButton(
|
||||
title: 'Save'.tr,
|
||||
onPressed: () async {
|
||||
if (sosFormKey.currentState!.validate()) {
|
||||
Get.back();
|
||||
var numberPhone =
|
||||
formatSyrianPhoneNumber(sosPhonePassengerProfile.text);
|
||||
confirm: MyElevatedButton(
|
||||
title: 'Save'.tr,
|
||||
onPressed: () async {
|
||||
if (sosFormKey.currentState!.validate()) {
|
||||
Get.back();
|
||||
var numberPhone =
|
||||
formatSyrianPhoneNumber(sosPhonePassengerProfile.text);
|
||||
|
||||
await CRUD().post(
|
||||
link: AppLink.updateprofile,
|
||||
payload: {
|
||||
'id': box.read(BoxName.passengerID),
|
||||
'sosPhone': numberPhone,
|
||||
},
|
||||
);
|
||||
await CRUD().post(
|
||||
link: AppLink.updateprofile,
|
||||
payload: {
|
||||
'id': box.read(BoxName.passengerID),
|
||||
'sosPhone': numberPhone,
|
||||
},
|
||||
);
|
||||
|
||||
box.write(BoxName.sosPhonePassenger, numberPhone);
|
||||
onSuccess();
|
||||
}
|
||||
},
|
||||
),
|
||||
cancel: MyElevatedButton(
|
||||
title: 'Cancel'.tr,
|
||||
onPressed: () => Get.back(),
|
||||
kolor: AppColor.redColor,
|
||||
)
|
||||
);
|
||||
box.write(BoxName.sosPhonePassenger, numberPhone);
|
||||
onSuccess();
|
||||
}
|
||||
},
|
||||
),
|
||||
cancel: MyElevatedButton(
|
||||
title: 'Cancel'.tr,
|
||||
onPressed: () => Get.back(),
|
||||
kolor: AppColor.redColor,
|
||||
));
|
||||
}
|
||||
|
||||
void sosPassenger() {
|
||||
@@ -114,10 +107,12 @@ class UiInteractionsController extends GetxController {
|
||||
titleStyle: AppStyle.title.copyWith(color: AppColor.redColor),
|
||||
content: Column(
|
||||
children: [
|
||||
Icon(Icons.warning_amber_rounded, size: 50, color: AppColor.redColor),
|
||||
Icon(Icons.warning_amber_rounded,
|
||||
size: 50, color: AppColor.redColor),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Do you want to send an emergency message to your SOS contact?".tr,
|
||||
"Do you want to send an emergency message to your SOS contact?"
|
||||
.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppStyle.title,
|
||||
),
|
||||
|
||||
@@ -42,6 +42,7 @@ class MyTranslation extends Translations {
|
||||
"Arrived": "وصلنا",
|
||||
"Audio Recording": "تسجيل صوتي",
|
||||
"Call": "اتصال",
|
||||
"Call Options": "خيارات الاتصال",
|
||||
"Call Connected": "تم فتح الاتصال",
|
||||
"Call Support": "اتصل بالدعم",
|
||||
"Call left": "مكالمات متبقية",
|
||||
@@ -49,6 +50,8 @@ class MyTranslation extends Translations {
|
||||
"Change Photo": "تغيير الصورة",
|
||||
"Captain": "الكابتن",
|
||||
"Choose from Gallery": "اختر من المعرض",
|
||||
"Choose how you want to call the driver":
|
||||
"اختر طريقة الاتصال بالكابتن",
|
||||
"Choose from contact": "اختر من جهات الاتصال",
|
||||
"Click to track the trip": "اضغط لتتبع المشوار",
|
||||
"Close panel": "إغلاق اللوحة",
|
||||
@@ -92,6 +95,9 @@ class MyTranslation extends Translations {
|
||||
"Finished": "انتهى",
|
||||
"Fixed Price": "سعر ثابت",
|
||||
"Free Call": "مكالمة مجانية",
|
||||
"Professional driver": "كابتن محترف",
|
||||
"Trusted driver": "كابتن موثوق",
|
||||
"Verified driver": "كابتن موثق",
|
||||
"General": "عام",
|
||||
"Grant": "منح الإذن",
|
||||
"Have a Promo Code?": "معك كود خصم؟",
|
||||
@@ -178,6 +184,7 @@ class MyTranslation extends Translations {
|
||||
"Preferences": "التفضيلات",
|
||||
"Profile photo updated": "تم تحديث صورة الغلاف",
|
||||
"Quick Message": "رسالة سريعة",
|
||||
"reviews": "تقييم",
|
||||
"Rating is": "التقييم هو",
|
||||
"Received empty route data.": "تم استلام بيانات طريق فارغة.",
|
||||
"Record": "تسجيل",
|
||||
@@ -211,6 +218,7 @@ class MyTranslation extends Translations {
|
||||
"Set as Work": "تحديد كالشغل",
|
||||
"Share": "مشاركة",
|
||||
"Share Trip": "مشاركة المشوار",
|
||||
"Standard Call": "اتصال عادي",
|
||||
"Share your experience to help us improve...":
|
||||
"شاركنا تجربتك لنحسن خدمتنا...",
|
||||
"Something went wrong. Please try again.": "صار غلط. جرب مرة تانية.",
|
||||
@@ -271,6 +279,8 @@ class MyTranslation extends Translations {
|
||||
"to arrive you.": "ليوصلك.",
|
||||
"unknown": "غير معروف",
|
||||
"wait 1 minute to recive message": "استنى دقيقة لتستلم الرسالة",
|
||||
"Uses cellular network": "يستخدم شبكة الهاتف",
|
||||
"Voice call over internet": "مكالمة صوتية عبر الإنترنت",
|
||||
"with license plate": "برقم اللوحة",
|
||||
"witout zero": "بدون صفر",
|
||||
"you must insert token code": "لازم تدخل الكود",
|
||||
@@ -16885,7 +16895,8 @@ class MyTranslation extends Translations {
|
||||
"Support is Away": "سپورٹ اب دستیاب نہیں ہے",
|
||||
"Support is currently Online": "سپورٹ اب آن لائن ہے",
|
||||
"Voice Call": "صوتی کال",
|
||||
"We're here to help you 24/7": "ہم چوبیس گھنٹے آپ کی مدد کے لیے حاضر ہیں",
|
||||
"We're here to help you 24/7":
|
||||
"ہم چوبیس گھنٹے آپ کی مدد کے لیے حاضر ہیں",
|
||||
"Working Hours:": "کام کے اوقات:",
|
||||
"1 Passenger": "1 Passenger",
|
||||
"2 Passengers": "2 Passengers",
|
||||
@@ -18446,7 +18457,8 @@ class MyTranslation extends Translations {
|
||||
"Support is Away": "सहायता अभी उपलब्ध नहीं है",
|
||||
"Support is currently Online": "सहायता अभी ऑनलाइन है",
|
||||
"Voice Call": "वॉइस कॉल",
|
||||
"We're here to help you 24/7": "हम आपकी सहायता के लिए 24/7 उपलब्ध हैं",
|
||||
"We're here to help you 24/7":
|
||||
"हम आपकी सहायता के लिए 24/7 उपलब्ध हैं",
|
||||
"Working Hours:": "कार्य समय:",
|
||||
"1 Passenger": "1 Passenger",
|
||||
"2 Passengers": "2 Passengers",
|
||||
|
||||
@@ -250,19 +250,23 @@ class ApplyOrderWidget extends StatelessWidget {
|
||||
Row(
|
||||
children: [
|
||||
// صورة السائق (أصغر)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: AppColor.primaryColor.withOpacity(0.2), width: 2),
|
||||
),
|
||||
child: CircleAvatar(
|
||||
radius: 22, // تصغير من 28 إلى 22
|
||||
backgroundColor: Colors.grey[200],
|
||||
backgroundImage: NetworkImage(
|
||||
'${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg'),
|
||||
onBackgroundImageError: (_, __) =>
|
||||
const Icon(Icons.person, color: Colors.grey, size: 20),
|
||||
GestureDetector(
|
||||
onTap: () => _showDriverAvatarDialog(context, controller),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: AppColor.primaryColor.withOpacity(0.2),
|
||||
width: 2),
|
||||
),
|
||||
child: CircleAvatar(
|
||||
radius: 22, // تصغير من 28 إلى 22
|
||||
backgroundColor: Colors.grey[200],
|
||||
backgroundImage: NetworkImage(
|
||||
'${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg'),
|
||||
onBackgroundImageError: (_, __) =>
|
||||
const Icon(Icons.person, color: Colors.grey, size: 20),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -299,6 +303,32 @@ class ApplyOrderWidget extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Wrap(
|
||||
spacing: 6,
|
||||
runSpacing: 4,
|
||||
children: [
|
||||
_buildDriverBadge(
|
||||
icon: Icons.verified_rounded,
|
||||
text: controller.driverTier.tr,
|
||||
color: AppColor.primaryColor,
|
||||
),
|
||||
if (controller.driverCompletedRides != '0')
|
||||
_buildDriverBadge(
|
||||
icon: Icons.route_rounded,
|
||||
text:
|
||||
'${controller.driverCompletedRides} ${'rides'.tr}',
|
||||
color: Colors.teal,
|
||||
),
|
||||
if (controller.driverRatingCount != '0')
|
||||
_buildDriverBadge(
|
||||
icon: Icons.reviews_rounded,
|
||||
text:
|
||||
'${controller.driverRatingCount} ${'reviews'.tr}',
|
||||
color: Colors.amber.shade800,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -320,6 +350,11 @@ class ApplyOrderWidget extends StatelessWidget {
|
||||
Widget _buildMicroCarIcon(
|
||||
RideLifecycleController controller, Color Function(String) parseColor) {
|
||||
Color carColor = parseColor(controller.colorHex);
|
||||
final String vehicleText =
|
||||
'${controller.model} ${controller.make}'.toLowerCase();
|
||||
final bool isBike = vehicleText.contains('scooter') ||
|
||||
vehicleText.contains('bike') ||
|
||||
vehicleText.contains('دراجة');
|
||||
return Container(
|
||||
height: 40, // تصغير من 50
|
||||
width: 40,
|
||||
@@ -331,7 +366,8 @@ class ApplyOrderWidget extends StatelessWidget {
|
||||
child: ColorFiltered(
|
||||
colorFilter: ColorFilter.mode(carColor, BlendMode.srcIn),
|
||||
child: Image.asset(
|
||||
box.read(BoxName.carType) == 'Scooter' ||
|
||||
isBike ||
|
||||
box.read(BoxName.carType) == 'Scooter' ||
|
||||
box.read(BoxName.carType) == 'Pink Bike'
|
||||
? 'assets/images/moto.png'
|
||||
: 'assets/images/car3.png',
|
||||
@@ -341,6 +377,81 @@ class ApplyOrderWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDriverBadge({
|
||||
required IconData icon,
|
||||
required String text,
|
||||
required Color color,
|
||||
}) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, size: 11, color: color),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
color: color,
|
||||
fontSize: 10.5,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showDriverAvatarDialog(
|
||||
BuildContext context, RideLifecycleController controller) {
|
||||
final imageUrl =
|
||||
'${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg';
|
||||
Get.dialog(
|
||||
Dialog(
|
||||
insetPadding: const EdgeInsets.symmetric(horizontal: 38),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(18, 20, 18, 18),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 58,
|
||||
backgroundColor: Colors.grey[200],
|
||||
backgroundImage: NetworkImage(imageUrl),
|
||||
onBackgroundImageError: (_, __) {},
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
Text(
|
||||
controller.driverName,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppStyle.title.copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
'${controller.driverTier.tr} • ${controller.driverRate}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.grey[700],
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
barrierDismissible: true,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSlimLicensePlate(String plateNumber) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
|
||||
Reference in New Issue
Block a user