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,6 +1,6 @@
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:Intaleq/constant/api_key.dart';
import 'package:Intaleq/controller/firebase/firbase_messge.dart';
import 'package:Intaleq/views/auth/otp_page.dart';
@@ -10,7 +10,7 @@ import 'package:http/http.dart' as http;
import 'package:Intaleq/constant/info.dart';
import 'package:Intaleq/controller/functions/add_error.dart';
import 'package:Intaleq/views/auth/login_page.dart';
import 'package:Intaleq/views/auth/sms_verfy_page.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:Intaleq/constant/box_name.dart';
@@ -18,17 +18,16 @@ import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/controller/functions/crud.dart';
import 'package:Intaleq/main.dart';
import 'package:Intaleq/views/home/map_page_passenger.dart';
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:location/location.dart';
import 'package:secure_string_operations/secure_string_operations.dart';
import '../../constant/char_map.dart';
import 'package:location/location.dart';
import '../../print.dart';
import '../../views/auth/otp_token_page.dart';
import '../functions/encrypt_decrypt.dart';
import '../functions/package_info.dart';
import '../functions/secure_storage.dart';
import '../functions/securty_check.dart';
class LoginController extends GetxController {
final formKey = GlobalKey<FormState>();
@@ -88,20 +87,7 @@ class LoginController extends GetxController {
update();
}
void _showJwtErrorDialog(String message) {
if (Get.context == null) return;
Get.defaultDialog(
title: "خطأ في الاتصال",
middleText: message,
textConfirm: "إعادة المحاولة",
confirmTextColor: Colors.white,
onConfirm: () {
Get.back();
getJwtWallet();
},
);
}
// ═══════════════════════════════════════════════════════════════
// LoginController — دوال إدارة الـ JWT
// ───────────────────────────────────────────────────────────────
@@ -141,8 +127,8 @@ class LoginController extends GetxController {
);
Log.print('AppLink.loginFirstTime: ${AppLink.loginFirstTime}');
Log.print('payload: ${payload}');
Log.print('response: ${response}');
Log.print('payload: $payload');
Log.print('response: $response');
if (response.statusCode == 200) {
final decoded = jsonDecode(response.body);
@@ -169,7 +155,7 @@ class LoginController extends GetxController {
);
Log.print('AppLink.loginJwtRider: ${AppLink.loginJwtRider}');
Log.print('payload: ${payload}');
Log.print('payload: $payload');
Log.print('response: ${response.body}');
if (response.statusCode == 200) {
final decoded = jsonDecode(response.body);
@@ -361,7 +347,7 @@ class LoginController extends GetxController {
}
Get.offAll(() => const MapPagePassenger());
} catch (e, st) {
} catch (e) {
addError('$e', 'loginUsingCredentials');
Get.snackbar('Error', e.toString(), backgroundColor: Colors.redAccent);
} finally {
@@ -433,7 +419,7 @@ class LoginController extends GetxController {
}
}
goToMapPage() {
void goToMapPage() {
if (box.read(BoxName.email) != null) {
Get.offAll(() => const MapPagePassenger());
}

View File

@@ -675,4 +675,32 @@ class CRUD {
return null;
}
}
Future<dynamic> postMapSaas({
required String link,
required Map<String, dynamic> payload,
}) async {
var url = Uri.parse(link);
try {
var response = await http.post(
url,
body: jsonEncode(payload),
headers: {
'Content-Type': 'application/json',
'x-api-key': Env.mapSaasKey,
},
);
Log.print('post -MapSaas link: $link');
Log.print('post -MapSaas payload: $payload');
Log.print('post -MapSaas response: ${response.body}');
if (response.statusCode == 200 || response.statusCode == 201) {
return jsonDecode(response.body);
}
Log.print('MapSaas Post Error: ${response.statusCode} - ${response.body}');
return null;
} catch (e) {
Log.print('MapSaas Post Exception: $e');
return null;
}
}
}

View File

@@ -1,4 +1,4 @@
import 'package:maplibre_gl/maplibre_gl.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
List<LatLng> decodePolylineIsolate(String encoded) {
List<LatLng> points = [];

File diff suppressed because it is too large Load Diff

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 'package:Intaleq/constant/style.dart';
import 'package:Intaleq/controller/home/map_passenger_controller.dart';

View File

@@ -6,14 +6,14 @@ import 'package:Intaleq/controller/functions/crud.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
class TripMonitorController extends GetxController {
bool isLoading = false;
Map tripData = {};
late String rideId;
late String driverId;
MapLibreMapController? mapController;
IntaleqMapController? mapController;
List myListString = [];
late Timer timer;
late LatLng parentLocation;
@@ -23,6 +23,8 @@ class TripMonitorController extends GetxController {
double rotation = 0;
double speed = 0;
bool isStyleLoaded = false;
Set<Marker> markers = {};
getLocationParent() async {
var res = await CRUD().get(
@@ -34,76 +36,56 @@ class TripMonitorController extends GetxController {
double.parse(tripData['message'][0]['longitude'].toString()));
rotation = double.parse(tripData['message'][0]['heading'].toString());
speed = double.parse(tripData['message'][0]['speed'].toString());
_updateMarker();
update();
}
}
void onMapCreated(MapLibreMapController controller) async {
void onMapCreated(IntaleqMapController controller) async {
mapController = controller;
update();
}
void onStyleLoaded() async {
isStyleLoaded = true;
await _loadMapIcons();
mapController?.animateCamera(
CameraUpdate.newLatLng(parentLocation),
);
refreshMapElements();
_updateMarker();
// Set up a timer or interval to trigger the marker update every 10 seconds.
timer = Timer.periodic(const Duration(seconds: 10), (_) async {
await getLocationParent();
mapController?.animateCamera(CameraUpdate.newLatLng(parentLocation));
refreshMapElements();
update();
});
}
Future<void> _loadMapIcons() async {
if (mapController == null) return;
final icons = {
'car': 'assets/images/car.png',
'moto': 'assets/images/moto1.png',
'lady': 'assets/images/lady1.png',
};
for (var entry in icons.entries) {
final bytes = await rootBundle.load(entry.value);
await mapController!.addImage(entry.key, bytes.buffer.asUint8List());
}
}
void refreshMapElements() async {
if (!isStyleLoaded || mapController == null) return;
await mapController!.clearSymbols();
String iconToUse = carIcon;
void _updateMarker() {
String iconPath = 'assets/images/car.png';
if (tripData['message'] != null && tripData['message'].isNotEmpty) {
final model = tripData['message'][0]['model'].toString();
final gender = tripData['message'][0]['gender'].toString();
if (model.contains('دراجة')) {
iconToUse = motoIcon;
iconPath = 'assets/images/moto1.png';
} else if (gender == 'Female') {
iconToUse = ladyIcon;
iconPath = 'assets/images/lady1.png';
}
}
await mapController!.addSymbol(SymbolOptions(
geometry: parentLocation,
iconImage: iconToUse,
iconRotate: rotation,
textField: 'driver',
textOpacity: 0,
));
markers = {
Marker(
markerId: const MarkerId('driver'),
position: parentLocation,
icon: InlqBitmap.fromAsset(iconPath),
rotation: rotation,
anchor: const Offset(0.5, 0.5),
),
};
update();
}
// init() async {
// final arguments = Get.arguments;
// driverId = arguments['driverId'];
// rideId = arguments['rideId'];
// await getLocationParent();
// }
Future<void> init({String? rideId, String? driverId}) async {
this.driverId = driverId!;
this.rideId = rideId!;
@@ -120,7 +102,6 @@ class TripMonitorController extends GetxController {
void onClose() {
timer.cancel();
mapController = null;
super.onClose();
}
}

View File

@@ -10,6 +10,8 @@ class MyTranslation extends Translations {
"Email Support": "الدعم عبر البريد الإلكتروني",
"For official inquiries": "للاستفسارات الرسمية",
"Intaleq Support": "دعم انطلق",
'Change Home location ?': 'تغيير موقع المنزل؟',
'Change Work location ?': 'تغيير موقع العمل؟',
"Reach out to us via": "تواصل معنا عبر",
"Support is Away": "الدعم غير متاح حالياً",
"Support is currently Online": "الدعم متاح حالياً",