Update: 2026-06-11 13:47:39
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ui' as ui;
|
||||
import 'dart:math' show cos, max, min, pi, pow, sqrt;
|
||||
import 'dart:typed_data';
|
||||
import 'package:siro_rider/controller/home/map/ride_lifecycle_controller.dart';
|
||||
@@ -84,7 +85,7 @@ class MapEngineController extends GetxController {
|
||||
}
|
||||
|
||||
void onStyleLoaded() async {
|
||||
Log.print('🗺️ Intaleq Map Style Loaded. Initializing...');
|
||||
Log.print('🗺️ Siro Map Style Loaded. Initializing...');
|
||||
isStyleLoaded = true;
|
||||
await _loadMapIcons();
|
||||
|
||||
@@ -161,6 +162,14 @@ class MapEngineController extends GetxController {
|
||||
await _addMapImage('orange_marker', 'assets/images/moto1.png');
|
||||
await _addMapImage('violet_marker', 'assets/images/lady1.png');
|
||||
|
||||
try {
|
||||
final walkBytes = await _createWalkMarkerBytes();
|
||||
await mapController?.addImage('walk_icon', walkBytes);
|
||||
Log.print('delimited: successfully added dynamic walk_icon');
|
||||
} catch (e) {
|
||||
Log.print('❌ Error loading dynamic walk icon: $e');
|
||||
}
|
||||
|
||||
isIconsLoaded = true;
|
||||
markers = markers.map((m) => m.copyWith()).toSet();
|
||||
update();
|
||||
@@ -799,6 +808,44 @@ class MapEngineController extends GetxController {
|
||||
update();
|
||||
}
|
||||
|
||||
Future<Uint8List> _createWalkMarkerBytes() async {
|
||||
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
|
||||
final Canvas canvas = Canvas(pictureRecorder);
|
||||
const double size = 60.0;
|
||||
|
||||
final Paint paint = Paint()..color = const Color(0xFF0288D1);
|
||||
final Paint borderPaint = Paint()
|
||||
..color = Colors.white
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 3.0;
|
||||
|
||||
canvas.drawCircle(const Offset(size / 2, size / 2), size / 2.5, paint);
|
||||
canvas.drawCircle(
|
||||
const Offset(size / 2, size / 2), size / 2.5, borderPaint);
|
||||
|
||||
TextPainter iconPainter = TextPainter(textDirection: TextDirection.ltr);
|
||||
iconPainter.text = TextSpan(
|
||||
text: String.fromCharCode(Icons.directions_walk.codePoint),
|
||||
style: TextStyle(
|
||||
fontSize: 30.0,
|
||||
fontFamily: Icons.directions_walk.fontFamily,
|
||||
color: Colors.white,
|
||||
),
|
||||
);
|
||||
iconPainter.layout();
|
||||
iconPainter.paint(
|
||||
canvas,
|
||||
Offset((size - iconPainter.width) / 2, (size - iconPainter.height) / 2),
|
||||
);
|
||||
|
||||
final ui.Image image = await pictureRecorder
|
||||
.endRecording()
|
||||
.toImage(size.toInt(), size.toInt());
|
||||
final ByteData? data =
|
||||
await image.toByteData(format: ui.ImageByteFormat.png);
|
||||
return data!.buffer.asUint8List();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
_animationTimers.forEach((key, timer) => timer.cancel());
|
||||
|
||||
@@ -846,6 +846,7 @@ class RideLifecycleController extends GetxController {
|
||||
|
||||
rideIsBeginPassengerTimer();
|
||||
runWhenRideIsBegin();
|
||||
_updatePassengerWalkLine();
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -1730,7 +1731,7 @@ class RideLifecycleController extends GetxController {
|
||||
String generateTrackingLink(String rideId, String driverId) {
|
||||
String cleanRideId = rideId.toString().trim();
|
||||
String cleanDriverId = driverId.toString().trim();
|
||||
const String secretSalt = "Intaleq_Secure_Track_2025";
|
||||
const String secretSalt = "Siro_Secure_Track_2025";
|
||||
|
||||
String rawString = "$cleanRideId$cleanDriverId$secretSalt";
|
||||
var bytes = utf8.encode(rawString);
|
||||
@@ -2260,6 +2261,7 @@ class RideLifecycleController extends GetxController {
|
||||
}
|
||||
|
||||
mapEngine.fitCameraToPoints(driverPos, passengerPos);
|
||||
_updatePassengerWalkLine();
|
||||
update();
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -2386,6 +2388,7 @@ class RideLifecycleController extends GetxController {
|
||||
),
|
||||
};
|
||||
}
|
||||
_updatePassengerWalkLine();
|
||||
update();
|
||||
}
|
||||
}
|
||||
@@ -3508,9 +3511,29 @@ class RideLifecycleController extends GetxController {
|
||||
|
||||
LatLngBounds boundsObj =
|
||||
LatLngBounds(northeast: northeastBound, southwest: southwestBound);
|
||||
var cameraUpdate = CameraUpdate.newLatLngBounds(boundsObj,
|
||||
left: 180, top: 180, right: 180, bottom: 180);
|
||||
mapController!.animateCamera(cameraUpdate);
|
||||
|
||||
final latDiff = (northeastBound.latitude - southwestBound.latitude).abs();
|
||||
final lngDiff = (northeastBound.longitude - southwestBound.longitude).abs();
|
||||
|
||||
if (latDiff < 0.0001 || lngDiff < 0.0001) {
|
||||
final center = LatLng(
|
||||
(northeastBound.latitude + southwestBound.latitude) / 2,
|
||||
(northeastBound.longitude + southwestBound.longitude) / 2,
|
||||
);
|
||||
mapController!.animateCamera(CameraUpdate.newLatLngZoom(center, 17));
|
||||
} else {
|
||||
try {
|
||||
var cameraUpdate = CameraUpdate.newLatLngBounds(boundsObj,
|
||||
left: 180, top: 180, right: 180, bottom: 180);
|
||||
mapController!.animateCamera(cameraUpdate);
|
||||
} catch (e) {
|
||||
final center = LatLng(
|
||||
(northeastBound.latitude + southwestBound.latitude) / 2,
|
||||
(northeastBound.longitude + southwestBound.longitude) / 2,
|
||||
);
|
||||
mapController!.animateCamera(CameraUpdate.newLatLngZoom(center, 17));
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -4562,4 +4585,82 @@ class RideLifecycleController extends GetxController {
|
||||
sinLng;
|
||||
return 2 * R * atan2(pow(h, 0.5).toDouble(), pow(1 - h, 0.5).toDouble());
|
||||
}
|
||||
|
||||
// دالة لبناء الخط المنقط
|
||||
List<Polyline> _buildDashedLine(LatLng start, LatLng end,
|
||||
{required Color color, required String prefixId}) {
|
||||
List<Polyline> segments = [];
|
||||
double dist = Geolocator.distanceBetween(
|
||||
start.latitude, start.longitude, end.latitude, end.longitude);
|
||||
|
||||
const double dashLengthMeters = 8.0;
|
||||
const double gapLengthMeters = 6.0;
|
||||
|
||||
double latDiff = end.latitude - start.latitude;
|
||||
double lngDiff = end.longitude - start.longitude;
|
||||
|
||||
double totalLength = 0;
|
||||
int segmentCount = 0;
|
||||
|
||||
while (totalLength < dist) {
|
||||
double startFraction = totalLength / dist;
|
||||
double endFraction = (totalLength + dashLengthMeters) / dist;
|
||||
|
||||
if (endFraction > 1.0) {
|
||||
endFraction = 1.0;
|
||||
}
|
||||
|
||||
double startLat = start.latitude + latDiff * startFraction;
|
||||
double startLng = start.longitude + lngDiff * startFraction;
|
||||
double endLat = start.latitude + latDiff * endFraction;
|
||||
double endLng = start.longitude + lngDiff * endFraction;
|
||||
|
||||
segments.add(
|
||||
Polyline(
|
||||
polylineId: PolylineId('${prefixId}_dash_$segmentCount'),
|
||||
points: [LatLng(startLat, startLng), LatLng(endLat, endLng)],
|
||||
color: color,
|
||||
width: 4,
|
||||
),
|
||||
);
|
||||
segmentCount++;
|
||||
totalLength += dashLengthMeters + gapLengthMeters;
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
|
||||
// تحديث الخط المنقط ومكان أيقونة المشي للراكب
|
||||
void _updatePassengerWalkLine() {
|
||||
polyLines.removeWhere(
|
||||
(p) => p.polylineId.value.startsWith('passenger_walk_line'));
|
||||
markers.removeWhere((m) => m.markerId.value == 'walk_end_marker');
|
||||
|
||||
bool shouldShowWalkPath =
|
||||
(statusRide == 'Apply' || statusRide == 'Arrived') &&
|
||||
_currentDriverRoutePoints.isNotEmpty &&
|
||||
passengerLocation.latitude != 0;
|
||||
|
||||
if (shouldShowWalkPath) {
|
||||
final LatLng lastRoadPt = _currentDriverRoutePoints.last;
|
||||
|
||||
final walkDashes = _buildDashedLine(
|
||||
lastRoadPt,
|
||||
passengerLocation,
|
||||
color: Colors.blueGrey,
|
||||
prefixId: 'passenger_walk_line',
|
||||
);
|
||||
polyLines.addAll(walkDashes);
|
||||
|
||||
markers.add(
|
||||
Marker(
|
||||
markerId: const MarkerId('walk_end_marker'),
|
||||
position: lastRoadPt,
|
||||
icon: InlqBitmap.fromStyleImage('walk_icon'),
|
||||
anchor: const Offset(0.5, 0.5),
|
||||
),
|
||||
);
|
||||
}
|
||||
mapEngine.update();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,25 +291,25 @@ class UiInteractionsController extends GetxController {
|
||||
rideLifecycle.rideId, rideLifecycle.driverId);
|
||||
|
||||
String message = """
|
||||
مرحباً، تابع رحلتي مباشرة على تطبيق انطلق 🚗
|
||||
مرحباً، تابع رحلتي مباشرة على تطبيق سيرو 🚗
|
||||
|
||||
يمكنك تتبع مسار الرحلة من هنا:
|
||||
$trackingLink
|
||||
|
||||
السائق: ${rideLifecycle.passengerName}
|
||||
السيارة: ${rideLifecycle.model} - ${rideLifecycle.licensePlate}
|
||||
شكراً لاستخدامك انطلق!
|
||||
شكراً لاستخدامك سيرو!
|
||||
"""
|
||||
.tr;
|
||||
|
||||
String messageEn = """Hello, follow my trip live on Intaleq 🚗
|
||||
String messageEn = """Hello, follow my trip live on Siro 🚗
|
||||
|
||||
Track my ride here:
|
||||
$trackingLink
|
||||
|
||||
Driver: ${rideLifecycle.passengerName}
|
||||
Car: ${rideLifecycle.model} - ${rideLifecycle.licensePlate}
|
||||
Thank you for using Intaleq!
|
||||
Thank you for using Siro!
|
||||
""";
|
||||
|
||||
String userLanguage = box.read(BoxName.lang) ?? 'ar';
|
||||
@@ -362,7 +362,7 @@ Thank you for using Intaleq!
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Send Intaleq app to him".tr,
|
||||
"Send Siro app to him".tr,
|
||||
style: AppStyle.title
|
||||
.copyWith(color: AppColor.greenColor, fontSize: 14),
|
||||
textAlign: TextAlign.center,
|
||||
@@ -379,14 +379,14 @@ Thank you for using Intaleq!
|
||||
|
||||
var message = '''Dear Friend,
|
||||
|
||||
🚀 I have just started an exciting trip on Intaleq!
|
||||
🚀 I have just started an exciting trip on Siro!
|
||||
Download the app to track my ride:
|
||||
|
||||
👉 Android: https://play.google.com/store/apps/details?id=com.Intaleq.intaleq&hl=en-US
|
||||
👉 iOS: https://apps.apple.com/st/app/intaleq-rider/id6748075179
|
||||
👉 Android: https://play.google.com/store/apps/details?id=com.Siro.siro&hl=en-US
|
||||
👉 iOS: https://apps.apple.com/st/app/siro-rider/id6748075179
|
||||
|
||||
See you there!
|
||||
Intaleq Team''';
|
||||
Siro Team''';
|
||||
|
||||
launchCommunication('whatsapp', phone, message);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user