fix: stabilize passenger mapping interactions and finalize localization

This commit is contained in:
Hamza-Ayed
2026-04-18 19:16:01 +03:00
parent a54a7a4189
commit 61343111a2
28 changed files with 14917 additions and 14716 deletions

View File

@@ -1,9 +1,10 @@
import 'package:Intaleq/print.dart';
import 'package:Intaleq/views/widgets/mydialoug.dart';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import 'package:Intaleq/constant/box_name.dart';
import 'package:Intaleq/constant/table_names.dart';
import 'package:Intaleq/views/widgets/elevated_btn.dart';
@@ -131,8 +132,7 @@ class _SearchFieldState extends State<_SearchField> {
decoration: InputDecoration(
hintText: widget.controller.hintTextDestinationPoint,
hintStyle: AppStyle.subtitle.copyWith(color: Colors.grey[600]),
prefixIcon:
Icon(Icons.search, color: AppColor.primaryColor),
prefixIcon: Icon(Icons.search, color: AppColor.primaryColor),
// --- [إصلاح] تم استبدال Obx بشرط بسيط لأن `setState` يعيد بناء الواجهة الآن ---
suffixIcon: widget
.controller.placeDestinationController.text.isNotEmpty
@@ -365,6 +365,11 @@ class _SearchResults extends StatelessWidget {
controller.changeMainBottomMenuMap();
controller.passengerStartLocationFromMap = true;
controller.isPickerShown = true;
// ✅ FIX: Draw the route after setting destination (matching the "Another Order" flow)
controller.getDirectionMap(
'${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}',
'${controller.myDestination.latitude},${controller.myDestination.longitude}');
}
}
@@ -407,22 +412,18 @@ Widget _buildQuickActionButton({
void _showChangeLocationDialog(
MapPassengerController controller, String locationType) {
Get.defaultDialog(
title: 'Change $locationType location?'.tr,
middleText: '',
confirm: MyElevatedButton(
title: 'Yes'.tr,
onPressed: () {
Get.back();
if (locationType == 'Work') {
controller.workLocationFromMap = true;
} else {
controller.homeLocationFromMap = true;
}
controller.changeMainBottomMenuMap();
controller.changePickerShown();
},
),
MyDialog().getDialog(
locationType == 'Work' ? 'Change Work location ?'.tr : 'Change Home location ?'.tr,
'',
() {
if (locationType == 'Work') {
controller.workLocationFromMap = true;
} else {
controller.homeLocationFromMap = true;
}
controller.changeMainBottomMenuMap();
controller.changePickerShown();
},
);
}
@@ -455,4 +456,4 @@ void _handleQuickAction(
Log.print("Error handling quick action: $e");
Toast.show(Get.context!, "Failed to get location".tr, AppColor.redColor);
}
}
}

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import '../../../constant/colors.dart';
import '../../../constant/style.dart';

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:Intaleq/constant/table_names.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import '../../../constant/colors.dart';
import '../../../constant/style.dart';
@@ -16,8 +17,7 @@ GetBuilder<MapPassengerController> formSearchPlaces(int index) {
Padding(
padding: const EdgeInsets.all(16),
child: Container(
decoration:
BoxDecoration(color: AppColor.secondaryColor),
decoration: BoxDecoration(color: AppColor.secondaryColor),
child: TextField(
decoration: InputDecoration(
border: const OutlineInputBorder(
@@ -82,7 +82,15 @@ GetBuilder<MapPassengerController> formSearchPlaces(int index) {
var res = controller.placeListResponseAll[index][i];
return InkWell(
onTap: () async {
// ── Extract selected location ──
final double lat = res['geometry']['location']['lat'];
final double lng = res['geometry']['location']['lng'];
final String placeName = res['name'].toString();
final selectedLatLng = LatLng(lat, lng);
controller.changeHeightPlaces();
// ── Update start/end based on context ──
if (controller.currentLocationToFormPlacesAll[index] ==
true) {
controller.newStartPointLocation =
@@ -92,7 +100,20 @@ GetBuilder<MapPassengerController> formSearchPlaces(int index) {
controller.newStartPointLocation;
}
// ✅ FIX: Set the waypoint to the selected location
controller.menuWaypoints[index] = selectedLatLng;
controller.menuWaypointNames[index] = placeName;
// ✅ FIX: Update hint text and coordinates
controller.convertHintTextPlaces(index, res);
// ✅ FIX: Draw the route with the updated waypoint
final String start =
'${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}';
final String dest =
'${controller.myDestination.latitude},${controller.myDestination.longitude}';
await controller.getDirectionMap(start, dest);
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),

View File

@@ -1,13 +1,11 @@
import 'package:Intaleq/print.dart';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:Intaleq/env/env.dart';
import 'package:get/get.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import 'package:Intaleq/controller/home/points_for_rider_controller.dart';
import 'package:Intaleq/services/offline_map_service.dart';
import '../../../constant/colors.dart';
import '../../../constant/style.dart';
import '../../../controller/home/map_passenger_controller.dart';
import '../../widgets/mycircular.dart';
import '../../widgets/mydialoug.dart';
@@ -27,82 +25,53 @@ class GoogleMapPassengerWidget extends StatelessWidget {
top: 0,
left: 0,
right: 0,
child: MapLibreMap(
attributionButtonPosition: AttributionButtonPosition.bottomLeft,
attributionButtonMargins: null,
child: IntaleqMap(
apiKey: Env.mapSaasKey,
styleUrl: Get.isDarkMode
? 'assets/style_dark.json'
: 'assets/style.json',
onMapCreated: controller.onMapCreated,
onStyleLoadedCallback: () => controller.onStyleLoaded(),
styleString: Get.isDarkMode ? "assets/style_dark.json" : "assets/style.json",
// ✅ Performance: Smoother zoom limits for low-end devices
minMaxZoomPreference: controller.lowPerf
? const MinMaxZoomPreference(6, 17)
: const MinMaxZoomPreference(6, 18),
initialCameraPosition: CameraPosition(
target: controller.passengerLocation,
zoom: controller.lowPerf ? 14.5 : 15,
),
// ✅ Map Settings
myLocationEnabled: true,
trackCameraPosition: true,
// ✅ Camera Movement Logic
onStyleLoaded: controller.onStyleLoaded,
onCameraMove: controller.onCameraMoveThrottled,
onCameraIdle: () {
if (controller.mapController != null) {
final position = controller.mapController!.cameraPosition;
if (position != null) {
Log.print('✅ onCameraIdle targeted: ${position.target}');
// 1. Always update current view target (for pickers)
controller
.updateCurrentLocationFromCamera(position.target);
// 2. Cache explicitly when panning around
// Optional: Limit this to only cache smaller regions (1km) so it doesn't overload on fast panning
OfflineMapService.instance.downloadRegion(position.target, radiusKm: 1.0);
OfflineMapService.instance
.downloadRegion(position.target, radiusKm: 1.0);
} else {
Log.print('⚠️ onCameraIdle: cameraPosition is NULL');
}
} else {
Log.print('⚠️ onCameraIdle: mapController is NULL');
}
},
onMapLongClick: (point, latlng) {
markers: controller.markers,
polylines: controller.polyLines,
polygons: controller.polygons,
circles: controller.circles,
initialCameraPosition: CameraPosition(
target: controller.passengerLocation,
zoom: controller.lowPerf ? 14.5 : 15,
),
myLocationEnabled: true,
onTap: (latlng) => controller.hidePlaces(),
onLongPress: (latlng) {
MyDialog().getDialog('Are you want to go to this site'.tr, '',
() async {
controller.clearPolyline();
if (controller.carsLocationByPassenger.isNotEmpty) {
await controller.getDirectionMap(
'${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}',
'${latlng.latitude},${latlng.longitude}',
);
Get.back(); // Close Dialog
await controller.bottomSheet();
controller.showBottomSheet1();
} else {
Get.back();
Get.snackbar(
'We Are Sorry That we dont have cars in your Location!'
.tr,
'',
colorText: AppColor.redColor,
duration: const Duration(seconds: 5),
backgroundColor: AppColor.secondaryColor,
icon: Icon(Icons.error, color: AppColor.redColor),
titleText: Text('Error'.tr,
style: TextStyle(color: AppColor.redColor)),
messageText: Text(
'We Are Sorry That we dont have cars in your Location!'
.tr,
style: AppStyle.title),
);
}
controller.getDirectionMap(
'${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}',
'${latlng.latitude},${latlng.longitude}',
);
controller.showBottomSheet1();
});
},
onMapClick: (point, latlng) {
controller.hidePlaces();
},
),
),
);
}
}
}

View File

@@ -6,7 +6,7 @@ import 'package:Intaleq/views/widgets/mycircular.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import 'dart:ui'; // مهم لإضافة تأثير الضبابية
import '../../../constant/colors.dart';

View File

@@ -9,7 +9,7 @@ import 'package:Intaleq/controller/home/map_passenger_controller.dart';
import 'package:Intaleq/main.dart';
import 'package:Intaleq/views/home/map_widget.dart/form_search_places_destenation.dart';
import 'package:Intaleq/views/widgets/elevated_btn.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import '../../../constant/colors.dart';
import '../../../constant/table_names.dart';
import '../../widgets/error_snakbar.dart';
@@ -607,26 +607,32 @@ class _MapPickerOverlay extends StatelessWidget {
const _MapPickerOverlay({required this.controller});
String _getModeTitle(BuildContext context) {
if (controller.isPickingWaypoint)
if (controller.isPickingWaypoint) {
return 'Move map to set stop'.tr +
' ${controller.pickingWaypointIndex + 1}'.tr;
if (controller.passengerStartLocationFromMap)
}
if (controller.passengerStartLocationFromMap) {
return controller.isAnotherOreder
? 'Now set the pickup point for the other person'.tr
: 'Move map to your pickup point'.tr;
if (controller.startLocationFromMap)
}
if (controller.startLocationFromMap) {
return 'Move map to set start location'.tr;
if (controller.workLocationFromMap)
}
if (controller.workLocationFromMap) {
return 'Move map to your work location'.tr;
if (controller.homeLocationFromMap)
}
if (controller.homeLocationFromMap) {
return 'Move map to your home location'.tr;
}
return 'Move map to select destination'.tr;
}
String _getConfirmLabel(BuildContext context) {
if (controller.isPickingWaypoint) return 'Set as Stop'.tr;
if (controller.passengerStartLocationFromMap)
if (controller.passengerStartLocationFromMap) {
return 'Confirm Pickup Location'.tr;
}
if (controller.workLocationFromMap) return 'Set as Work'.tr;
if (controller.homeLocationFromMap) return 'Set as Home'.tr;
return 'Set Destination'.tr;
@@ -634,8 +640,9 @@ class _MapPickerOverlay extends StatelessWidget {
IconData _getModeIcon() {
if (controller.isPickingWaypoint) return Icons.add_location_alt_rounded;
if (controller.passengerStartLocationFromMap)
if (controller.passengerStartLocationFromMap) {
return Icons.person_pin_circle_rounded;
}
if (controller.workLocationFromMap) return Icons.work_rounded;
if (controller.homeLocationFromMap) return Icons.home_rounded;
return Icons.location_on_rounded;
@@ -760,6 +767,8 @@ class _MapPickerOverlay extends StatelessWidget {
Future<void> _onConfirmTap(
MapPassengerController controller, BuildContext context) async {
Log.print(
'🔘 _onConfirmTap: isPickingWaypoint=${controller.isPickingWaypoint}, newMyLocation=${controller.newMyLocation}');
await Future.delayed(const Duration(milliseconds: 280));
final LatLng currentCameraPosition = LatLng(
controller.newMyLocation.latitude, controller.newMyLocation.longitude);
@@ -905,7 +914,6 @@ class _RecentPlaceChip extends StatelessWidget {
'Are you want to go this site'.tr,
' ',
() async {
Get.back();
await controller.getLocation();
await controller.getDirectionMap(
'${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}',