قرار المالك 2026-07-27: باك إند سيرو PHP هو المعتمد، وتطبيقاته المجرّبة ميدانياً تحل محل إعادة البناء المؤرشفة. سيرو نفسه لم يُمسّ. الخريطة: backend · payment_server · loction_server · ride_server · passenger_server · docker · dashboard · stress_test → الجذر siro_rider → apps/rider siro_driver → apps/driver siro_admin → dashboards/admin siro_service → dashboards/service android_bot → apps/android_bot socialBot → apps/socialBot نُسخ المتعقَّب في git سيرو فقط عبر `git archive` (3,198 ملفاً / ~169 م.ب) لا `cp -r` — فاستُثنيت مخلفات البناء تلقائياً. بلا أي تعديل محتوى عمداً: كل ما يلي يصير فرقاً مقروءاً مقابل المصدر. لم يُستورد وسببه: siromove.com (الموقع التسويقي يبقى marketing/ في تريبز، سيرو فيه 8 ملفات) · docs و planning (تريبز له docs/ الخاص) · deploy.sh (ليس نشراً على سيرفر بل `git add . && git push origin --all` — فخّ في مستودع آخر) · transit_dashboard (بانتظار قرار مصير backend-transit و dashboards/transit-web). ⚠️ لا يبني بعد — ثلاثة نواقص متوقعة ومقصودة: 1. `.env` و `lib/env/env.g.dart` غير متعقَّبين في سيرو (أسرار لكل مستأجر): كل تطبيق فلاتر يحتاج .env خاصاً ثم توليد env.g.dart بـ build_runner. 2. إعدادات Firebase (9 ملفات google-services.json و GoogleService-Info.plist) يستبعدها .gitignore تريبز — ولكل مستأجر مشروع Firebase خاص أصلاً. 3. apps/driver في سيرو يشير إلى `../../Intaleq/packages/get` خارج المستودع → يجب ضمّ الحزم داخله أسوة بـ apps/rider. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
102 lines
3.1 KiB
Dart
102 lines
3.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:intaleq_maps/intaleq_maps.dart';
|
|
import 'package:siro_driver/constant/api_key.dart';
|
|
import 'package:siro_driver/constant/box_name.dart';
|
|
import 'package:siro_driver/constant/links.dart';
|
|
import 'package:siro_driver/controller/functions/crud.dart';
|
|
import 'package:siro_driver/controller/functions/tts.dart';
|
|
|
|
import '../../../main.dart';
|
|
|
|
/// Handles map-related logic: fetching routes, drawing polylines, and managing markers.
|
|
class NavigationService extends GetxService {
|
|
final CRUD _crud = CRUD();
|
|
final TextToSpeechController _tts = Get.put(TextToSpeechController());
|
|
|
|
final RxSet<Marker> markers = <Marker>{}.obs;
|
|
final RxSet<Polyline> polylines = <Polyline>{}.obs;
|
|
final RxString currentInstruction = "".obs;
|
|
|
|
InlqBitmap carIcon = InlqBitmap.defaultMarker;
|
|
InlqBitmap passengerIcon = InlqBitmap.defaultMarker;
|
|
InlqBitmap startIcon = InlqBitmap.defaultMarker;
|
|
InlqBitmap endIcon = InlqBitmap.defaultMarker;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
_loadCustomIcons();
|
|
}
|
|
|
|
void _loadCustomIcons() {
|
|
carIcon = InlqBitmap.fromAsset('assets/images/car.png', size: 2.3);
|
|
passengerIcon = InlqBitmap.fromAsset('assets/images/picker.png');
|
|
startIcon = InlqBitmap.fromAsset('assets/images/A.png');
|
|
endIcon = InlqBitmap.fromAsset('assets/images/b.png');
|
|
}
|
|
|
|
Future<Map<String, dynamic>?> getRoute({
|
|
required LatLng origin,
|
|
required LatLng destination,
|
|
}) async {
|
|
final url =
|
|
'${AppLink.googleMapsLink}directions/json?language=${box.read(BoxName.lang)}&destination=${destination.latitude},${destination.longitude}&origin=${origin.latitude},${origin.longitude}&key=${AK.mapAPIKEY}';
|
|
|
|
final response = await _crud.getGoogleApi(link: url, payload: {});
|
|
|
|
if (response != null && response['routes'].isNotEmpty) {
|
|
return response['routes'][0];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
void drawRoute(Map<String, dynamic> routeData, {Color color = Colors.blue}) {
|
|
final pointsString = routeData["overview_polyline"]["points"];
|
|
final points = PolylineUtils.decode(pointsString);
|
|
|
|
final polyline = Polyline(
|
|
polylineId: PolylineId(routeData["summary"] ?? DateTime.now().toString()),
|
|
points: points,
|
|
width: 8,
|
|
color: color,
|
|
);
|
|
|
|
polylines.add(polyline);
|
|
}
|
|
|
|
void updateCarMarker(LatLng position, double heading) {
|
|
markers.removeWhere((m) => m.markerId.value == 'MyLocation');
|
|
markers.add(
|
|
Marker(
|
|
markerId: MarkerId('MyLocation'.tr),
|
|
position: position,
|
|
icon: carIcon,
|
|
rotation: heading,
|
|
anchor: const Offset(0.5, 0.5),
|
|
flat: true,
|
|
),
|
|
);
|
|
}
|
|
|
|
void setInitialMarkers(
|
|
LatLng passengerLocation, LatLng passengerDestination) {
|
|
markers.clear();
|
|
markers.add(Marker(
|
|
markerId: const MarkerId('passengerLocation'),
|
|
position: passengerLocation,
|
|
icon: passengerIcon,
|
|
));
|
|
markers.add(Marker(
|
|
markerId: const MarkerId('passengerDestination'),
|
|
position: passengerDestination,
|
|
icon: endIcon,
|
|
));
|
|
}
|
|
|
|
void clearRoutes() {
|
|
polylines.clear();
|
|
currentInstruction.value = "";
|
|
}
|
|
}
|