new change to use intaleq_map sdk 04-16-4
This commit is contained in:
@@ -32,12 +32,14 @@ import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
// import 'package:google_polyline_algorithm/google_polyline_algorithm.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:location/location.dart';
|
||||
import 'package:Intaleq/constant/colors.dart';
|
||||
import 'package:Intaleq/constant/country_polygons.dart';
|
||||
import 'package:Intaleq/constant/links.dart';
|
||||
import 'package:Intaleq/constant/style.dart';
|
||||
import 'package:Intaleq/controller/home/points_for_rider_controller.dart';
|
||||
import 'package:Intaleq/views/home/map_widget.dart/form_serch_multiy_point.dart';
|
||||
import '../../constant/api_key.dart';
|
||||
import '../../constant/box_name.dart';
|
||||
import '../../constant/colors.dart';
|
||||
import '../../constant/country_polygons.dart';
|
||||
import '../../constant/info.dart';
|
||||
import '../../constant/links.dart';
|
||||
@@ -3276,7 +3278,9 @@ class MapPassengerController extends GetxController {
|
||||
"step3": placesCoordinate.length > 3 ? placesCoordinate[3] : "",
|
||||
"step4": placesCoordinate.length > 4 ? placesCoordinate[4] : "",
|
||||
};
|
||||
Log.print('payload add_ride: $payload');
|
||||
Log.print(
|
||||
'🏁 Ride Registration Detail: $startNameAddress -> $endNameAddress');
|
||||
Log.print(' 📦 Payload: $payload');
|
||||
|
||||
try {
|
||||
// الاتصال بـ add_ride.php
|
||||
@@ -4859,7 +4863,7 @@ Intaleq Team''';
|
||||
}
|
||||
|
||||
// 4. التخلص من متحكم الخريطة (ممارسة جيدة)
|
||||
mapController?.dispose();
|
||||
mapController = null;
|
||||
|
||||
Log.print("--- Cleanup complete. ---");
|
||||
super.onClose();
|
||||
@@ -5307,27 +5311,44 @@ Intaleq Team''';
|
||||
|
||||
final lat = passengerLocation.latitude;
|
||||
final lng = passengerLocation.longitude;
|
||||
final country = CountryPolygons.getCountryName(passengerLocation);
|
||||
|
||||
try {
|
||||
final url =
|
||||
'${AppLink.searchGeocoding}?q=${Uri.encodeComponent(q)}&lat=$lat&lng=$lng&radius=45000&country=syria';
|
||||
'${AppLink.searchGeocoding}?q=${Uri.encodeComponent(q)}&lat=$lat&lng=$lng&radius=15000&country=$country';
|
||||
final response = await CRUD().getMapSaas(link: url);
|
||||
|
||||
if (response != null && response['results'] is List) {
|
||||
List list = List.from(response['results']);
|
||||
List results = List.from(response['results']);
|
||||
final List filteredResults = [];
|
||||
final Set<String> seenPlaces = {};
|
||||
|
||||
for (final p in list) {
|
||||
// Normalize fields to match expected format in components
|
||||
p['distanceKm'] = (p['distance'] as num).toDouble() / 1000.0;
|
||||
// Ensure latitude/longitude are strings if UI expects them that way,
|
||||
// though modern code usually prefers doubles.
|
||||
// The old code used double.tryParse(p['latitude']?.toString() ?? '0.0')
|
||||
p['latitude'] = p['latitude'].toString();
|
||||
p['longitude'] = p['longitude'].toString();
|
||||
for (final p in results) {
|
||||
final name = p['name_ar'] ?? p['name'] ?? '';
|
||||
final district = p['district'] ?? '';
|
||||
final plat = p['latitude']?.toString() ?? '0';
|
||||
final plng = p['longitude']?.toString() ?? '0';
|
||||
|
||||
final dedupeKey =
|
||||
"${name.trim().toLowerCase()}_${district.trim().toLowerCase()}";
|
||||
|
||||
if (!seenPlaces.contains(dedupeKey)) {
|
||||
seenPlaces.add(dedupeKey);
|
||||
|
||||
p['distanceKm'] = (p['distance'] as num).toDouble() / 1000.0;
|
||||
p['latitude'] = plat;
|
||||
p['longitude'] = plng;
|
||||
p['name'] = name;
|
||||
p['address'] = p['full_address'] ??
|
||||
(district.isNotEmpty
|
||||
? "$district، ${p['governorate'] ?? ''}"
|
||||
: (p['governorate'] ?? ''));
|
||||
|
||||
filteredResults.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
placesDestination = list;
|
||||
Log.print('Updated places: $placesDestination');
|
||||
placesDestination = filteredResults;
|
||||
update();
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -5533,23 +5554,26 @@ Intaleq Team''';
|
||||
|
||||
final lat = passengerLocation.latitude;
|
||||
final lng = passengerLocation.longitude;
|
||||
final country = CountryPolygons.getCountryName(passengerLocation);
|
||||
|
||||
try {
|
||||
final url =
|
||||
'${AppLink.searchGeocoding}?q=${Uri.encodeComponent(q)}&lat=$lat&lng=$lng&radius=200000&country=syria';
|
||||
'${AppLink.searchGeocoding}?q=${Uri.encodeComponent(q)}&lat=$lat&lng=$lng&radius=15000&country=$country';
|
||||
final response = await CRUD().getMapSaas(link: url);
|
||||
|
||||
if (response != null && response['results'] is List) {
|
||||
List list = List.from(response['results']);
|
||||
|
||||
for (final p in list) {
|
||||
p['distanceKm'] = (p['distance'] as num).toDouble() / 1000.0;
|
||||
p['latitude'] = p['latitude'].toString();
|
||||
p['longitude'] = p['longitude'].toString();
|
||||
p['name'] = p['name_ar'] ?? p['name'] ?? '';
|
||||
p['address'] = p['full_address'] ??
|
||||
(p['district'] != null
|
||||
? "${p['district']}، ${p['governorate'] ?? ''}"
|
||||
: (p['governorate'] ?? ''));
|
||||
}
|
||||
|
||||
placesStart = list;
|
||||
Log.print('Updated places start: $placesStart');
|
||||
update();
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -5557,34 +5581,37 @@ Intaleq Team''';
|
||||
}
|
||||
}
|
||||
|
||||
Future getPlacesListsWayPoint(int index) async {
|
||||
var languageCode = wayPoint0Controller.text;
|
||||
Future<void> getPlacesListsWayPoint(int index) async {
|
||||
final q = wayPoint0Controller.text.trim();
|
||||
if (q.length < 3) return;
|
||||
|
||||
// Regular expression to check for English alphabet characters
|
||||
final englishRegex = RegExp(r'[a-zA-Z]');
|
||||
|
||||
// Check if text contains English characters
|
||||
if (englishRegex.hasMatch(languageCode)) {
|
||||
languageCode = 'en';
|
||||
} else {
|
||||
languageCode = 'ar';
|
||||
}
|
||||
|
||||
var url =
|
||||
'${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint0Controller.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=250000&language=$languageCode&key=${AK.mapAPIKEY.toString()}';
|
||||
final lat = passengerLocation.latitude;
|
||||
final lng = passengerLocation.longitude;
|
||||
final country = CountryPolygons.getCountryName(passengerLocation);
|
||||
|
||||
try {
|
||||
var response = await CRUD().getGoogleApi(link: url, payload: {});
|
||||
final url =
|
||||
'${AppLink.searchGeocoding}?q=${Uri.encodeComponent(q)}&lat=$lat&lng=$lng&radius=15000&country=$country';
|
||||
final response = await CRUD().getMapSaas(link: url);
|
||||
|
||||
if (response != null && response['results'] != null) {
|
||||
wayPoint0 = response['results'];
|
||||
placeListResponseAll[index] = response['results'];
|
||||
if (response != null && response['results'] is List) {
|
||||
List list = List.from(response['results']);
|
||||
for (final p in list) {
|
||||
p['distanceKm'] = (p['distance'] as num).toDouble() / 1000.0;
|
||||
p['latitude'] = p['latitude'].toString();
|
||||
p['longitude'] = p['longitude'].toString();
|
||||
p['name'] = p['name_ar'] ?? p['name'] ?? '';
|
||||
p['address'] = p['full_address'] ??
|
||||
(p['district'] != null
|
||||
? "${p['district']}، ${p['governorate'] ?? ''}"
|
||||
: (p['governorate'] ?? ''));
|
||||
}
|
||||
wayPoint0 = list;
|
||||
placeListResponseAll[index] = list;
|
||||
update();
|
||||
} else {
|
||||
Log.print('Error: Invalid response from Google Places API');
|
||||
}
|
||||
} catch (e) {
|
||||
Log.print('Error fetching places: $e');
|
||||
Log.print('Error fetching places in WayPoint: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6292,7 +6319,7 @@ Intaleq Team''';
|
||||
}
|
||||
|
||||
bool isDrawingRoute = false;
|
||||
showDrawingBottomSheet() {
|
||||
void showDrawingBottomSheet() {
|
||||
final bool isDark = Get.isDarkMode;
|
||||
final Color bgColor = isDark
|
||||
? Colors.black.withOpacity(0.65)
|
||||
@@ -6300,6 +6327,9 @@ Intaleq Team''';
|
||||
final Color textColor = isDark ? Colors.white : Colors.grey.shade800;
|
||||
final Color subtitleColor = isDark ? Colors.white70 : Colors.grey.shade600;
|
||||
|
||||
// Prevent showing multiple bottom sheets if one is already active
|
||||
if (Get.isBottomSheetOpen == true) return;
|
||||
|
||||
Get.bottomSheet(
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
@@ -6324,16 +6354,34 @@ Intaleq Team''';
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Minimal handle
|
||||
Container(
|
||||
width: 40,
|
||||
height: 4,
|
||||
margin: const EdgeInsets.only(bottom: 24),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark ? Colors.white24 : Colors.grey.shade300,
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
// Minimal handle and Close button Row
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const SizedBox(width: 48), // Balance for the close button
|
||||
Container(
|
||||
width: 40,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: isDark ? Colors.white24 : Colors.grey.shade300,
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: Icon(Icons.close,
|
||||
color: textColor.withOpacity(0.5), size: 22),
|
||||
onPressed: () {
|
||||
// Force back to close the overlay regardless of GetX state check
|
||||
Get.back();
|
||||
isDrawingRoute = false;
|
||||
isLoading = false;
|
||||
update();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
@@ -6538,26 +6586,10 @@ Intaleq Team''';
|
||||
String pointsString;
|
||||
dynamic routeData;
|
||||
|
||||
if (isSaaSRequest) {
|
||||
// SaaS parsing
|
||||
apiDistanceMeters = (responseData['distance'] as num).toDouble();
|
||||
pointsString = responseData['points'] ?? "";
|
||||
routeData = responseData; // For box storage
|
||||
} else {
|
||||
// OSRM parsing
|
||||
if (responseData['routes'] == null || responseData['routes'].isEmpty) {
|
||||
if (attemptCount < 2) {
|
||||
await _retryProcess(origin, destination, waypoints, attemptCount);
|
||||
return;
|
||||
}
|
||||
_handleFatalError("Route Not Found".tr,
|
||||
"No routes available for this destination.".tr);
|
||||
return;
|
||||
}
|
||||
routeData = responseData['routes'][0];
|
||||
apiDistanceMeters = (routeData['distance'] as num).toDouble();
|
||||
pointsString = routeData['geometry'] ?? "";
|
||||
}
|
||||
// SaaS parsing
|
||||
apiDistanceMeters = (responseData['distance'] as num).toDouble();
|
||||
pointsString = responseData['points'] ?? "";
|
||||
routeData = responseData; // For box storage
|
||||
|
||||
var originCoords = origin.split(',');
|
||||
double startLat = double.parse(originCoords[0]);
|
||||
@@ -6613,21 +6645,14 @@ Intaleq Team''';
|
||||
polylineCoordinates.clear();
|
||||
polylineCoordinates.addAll(decodedPoints);
|
||||
|
||||
// ── 4. العناوين والتحديثات ──────────────────────────────────
|
||||
final LatLng startLoc = polylineCoordinates.first;
|
||||
final LatLng endLoc = polylineCoordinates.last;
|
||||
|
||||
try {
|
||||
final results = await Future.wait([
|
||||
getReverseGeocoding(startLoc),
|
||||
getReverseGeocoding(endLoc),
|
||||
]);
|
||||
startNameAddress = results[0];
|
||||
endNameAddress = results[1];
|
||||
} catch (e) {
|
||||
startNameAddress = 'Start Point'.tr;
|
||||
endNameAddress = 'Destination'.tr;
|
||||
}
|
||||
// ── 4. العناوين والتحديثات ──────────────────────────────────
|
||||
startNameAddress = responseData['startName'] ?? 'Start Point'.tr;
|
||||
endNameAddress = responseData['endName'] ?? 'Destination'.tr;
|
||||
Log.print('📍 ROUTE START: $startNameAddress');
|
||||
Log.print('📍 ROUTE END: $endNameAddress');
|
||||
|
||||
// ── 5. Bounds Calculation (SaaS bbox vs OSRM manual) ──────────
|
||||
if (isSaaSRequest && responseData['bbox'] != null) {
|
||||
@@ -6863,7 +6888,7 @@ Intaleq Team''';
|
||||
// -----------------------------------------------------------------------------------------
|
||||
void _handleFatalError(String title, String message) {
|
||||
// 1. إغلاق شاشة التحميل (Drawing route...)
|
||||
if (isDrawingRoute || (Get.isBottomSheetOpen ?? false)) {
|
||||
if (Get.isBottomSheetOpen == true || Get.isDialogOpen == true) {
|
||||
Get.back();
|
||||
}
|
||||
|
||||
@@ -8041,6 +8066,7 @@ Intaleq Team''';
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
_checkAndRefreshMapStyle(); // Verify style version and clear cache if needed
|
||||
// // --- إضافة جديدة: تهيئة وحدة التحكم في الروابط العميقة ---
|
||||
Get.put(DeepLinkController(), permanent: true);
|
||||
// // ----------------------------------------------------
|
||||
@@ -8189,6 +8215,34 @@ Intaleq Team''';
|
||||
'The price may increase if the route changes.'.tr, 'ding');
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks the current version of assets/style.json and purges the map cache if it has changed.
|
||||
Future<void> _checkAndRefreshMapStyle() async {
|
||||
try {
|
||||
final String styleJson = await rootBundle.loadString('assets/style.json');
|
||||
final Map<String, dynamic> decoded = json.decode(styleJson);
|
||||
final String? currentVersion =
|
||||
decoded['metadata'] != null ? decoded['metadata']['version'] : null;
|
||||
|
||||
if (currentVersion == null) return;
|
||||
|
||||
final String lastVersion = box.read(BoxName.styleVersion) ?? "0.0.0";
|
||||
|
||||
if (currentVersion != lastVersion) {
|
||||
Log.print(
|
||||
"♻️ Map Style Version mismatch ($lastVersion -> $currentVersion). Purging offline cache...");
|
||||
await OfflineMapService.instance.clearCache();
|
||||
|
||||
// Final verification check: give native engine time to flush
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
box.write(BoxName.styleVersion, currentVersion);
|
||||
Log.print("✅ Style Version updated to $currentVersion");
|
||||
}
|
||||
} catch (e) {
|
||||
Log.print("⚠️ Style version check failed: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CarLocation {
|
||||
|
||||
Reference in New Issue
Block a user