fix: stabilize passenger mapping interactions and finalize localization
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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}',
|
||||
|
||||
Reference in New Issue
Block a user