Update: 2026-07-12 18:53:59
This commit is contained in:
@@ -74,11 +74,17 @@ class FirebaseMessagesController extends GetxController {
|
||||
// Log.print('fcmToken: ${token}');
|
||||
box.write(BoxName.tokenFCM, (token.toString()));
|
||||
});
|
||||
// 🔹 الاشتراك في topic
|
||||
await fcmToken
|
||||
.subscribeToTopic("passengers"); // أو "users" حسب نوع المستخدم
|
||||
// 🔹 الاشتراك في topic العام
|
||||
await fcmToken.subscribeToTopic("passengers");
|
||||
Log.print("Subscribed to 'passengers' topic ✅");
|
||||
|
||||
// اشتراك شخصي بـ passenger_{id} لاستقبال إشعارات العضوية في مواصلاتي
|
||||
final passengerId = box.read(BoxName.passengerID);
|
||||
if (passengerId != null && passengerId.toString().isNotEmpty) {
|
||||
await fcmToken.subscribeToTopic('passenger_${passengerId}');
|
||||
Log.print("Subscribed to 'passenger_${passengerId}' topic ✅");
|
||||
}
|
||||
|
||||
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
||||
// If the app is in the background or terminated, show a system tray message
|
||||
RemoteNotification? notification = message.notification;
|
||||
|
||||
@@ -297,30 +297,19 @@ class LocationSearchController extends GetxController {
|
||||
newMyLocation = passengerLocation;
|
||||
|
||||
if (!CountryPolygons.isServiceSupported(passengerLocation)) {
|
||||
Get.bottomSheet(
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.location_off, size: 60, color: Colors.redAccent),
|
||||
const SizedBox(height: 15),
|
||||
Text(
|
||||
'service_unavailable_area'.tr,
|
||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
isDismissible: false,
|
||||
enableDrag: false,
|
||||
);
|
||||
if (!Get.isSnackbarOpen) {
|
||||
Get.snackbar(
|
||||
'Alert'.tr,
|
||||
'service_unavailable_area'.tr,
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.redAccent,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(Icons.location_off, color: Colors.white),
|
||||
margin: const EdgeInsets.all(15),
|
||||
duration: const Duration(seconds: 5),
|
||||
isDismissible: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (Get.isRegistered<RideLifecycleController>()) {
|
||||
|
||||
@@ -24,6 +24,7 @@ class MapSocketController extends GetxController {
|
||||
// 🚌 مواصلاتي — الخط الحالي المشترَك فيه + مستمع تحديث موقع الباص
|
||||
int? _subscribedTransitRouteId;
|
||||
void Function(Map<String, dynamic> data)? onBusLocationUpdate;
|
||||
void Function(String errorCode)? onTransitError;
|
||||
|
||||
DateTime? get lastDriverLocationTime => _lastSocketLocationTime;
|
||||
int get socketLocationUpdatesCount => _socketLocationUpdatesCount;
|
||||
@@ -154,6 +155,18 @@ class MapSocketController extends GetxController {
|
||||
Log.print('Error parsing bus_location_update: $e');
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('transit_error', (data) {
|
||||
if (data == null) return;
|
||||
try {
|
||||
final map = Map<String, dynamic>.from(data as Map);
|
||||
final code = map['code']?.toString() ?? '';
|
||||
Log.print('⚠️ transit_error: $code');
|
||||
onTransitError?.call(code);
|
||||
} catch (e) {
|
||||
Log.print('Error parsing transit_error: $e');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ── مواصلاتي: اشتراك/إلغاء اشتراك ببثّ موقع خط ─────────────
|
||||
|
||||
@@ -21,6 +21,7 @@ final Map<String, String> ar_eg = {
|
||||
"Stops": "محطات",
|
||||
"No bus running on this route right now": "لا يوجد باص يعمل على هذا الخط الآن",
|
||||
"Bus is delayed": "الباص متأخر",
|
||||
"Missed the bus? Book a ride now": "فاتك الأتوبيس؟ احجز سيارة دلوقتي",
|
||||
" ')[0]).toString()}.\\n\${' I am using": " ')[0]).toString()}.\\n\${' I am using",
|
||||
" I am currently located at ": " أنا حالياً في ",
|
||||
" I am using": " أنا استخدم",
|
||||
|
||||
@@ -21,6 +21,7 @@ final Map<String, String> ar_jo = {
|
||||
"Stops": "محطات",
|
||||
"No bus running on this route right now": "لا يوجد باص يعمل على هذا الخط الآن",
|
||||
"Bus is delayed": "الباص متأخر",
|
||||
"Missed the bus? Book a ride now": "فاتك الباص؟ اطلب سيارة الآن",
|
||||
" ')[0]).toString()}.\\n\${' I am using": " ')[0]).toString()}.\\n\${' I am using",
|
||||
" I am currently located at ": " أنا حالياً في ",
|
||||
" I am using": " أنا استخدم",
|
||||
|
||||
@@ -21,6 +21,7 @@ final Map<String, String> ar_sy = {
|
||||
"Stops": "محطات",
|
||||
"No bus running on this route right now": "لا يوجد باص يعمل على هذا الخط الآن",
|
||||
"Bus is delayed": "الباص متأخر",
|
||||
"Missed the bus? Book a ride now": "فاتك الباص؟ اطلب سيارة هلق",
|
||||
" ')[0]).toString()}.\\n\${' I am using": " ')[0]).toString()}.\\n\${' I am using",
|
||||
" I am currently located at ": " أنا حالياً في ",
|
||||
" I am using": " أنا استخدم",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// transit_controller.dart — تحكم شاشات مواصلاتي (جهة الراكب)
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../home/map/map_socket_controller.dart';
|
||||
import '../../print.dart';
|
||||
@@ -55,12 +56,31 @@ class TransitController extends GetxController {
|
||||
);
|
||||
if (res.success) {
|
||||
await fetchMyEnrollments();
|
||||
// اشترك في topic المؤسسة لاستقبال إشعارات الانطلاق والتأخير
|
||||
try {
|
||||
await FirebaseMessaging.instance.subscribeToTopic('transit_org_$orgId');
|
||||
Log.print('Subscribed to transit_org_$orgId ✅');
|
||||
} catch (_) {}
|
||||
return true;
|
||||
}
|
||||
Get.snackbar('مواصلاتي', res.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
// اشتراك/إلغاء اشتراك في topic الخط المحدد
|
||||
Future<void> subscribeToRouteTopic(int routeId) async {
|
||||
try {
|
||||
await FirebaseMessaging.instance.subscribeToTopic('transit_route_$routeId');
|
||||
Log.print('Subscribed to transit_route_$routeId ✅');
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
Future<void> unsubscribeFromRouteTopic(int routeId) async {
|
||||
try {
|
||||
await FirebaseMessaging.instance.unsubscribeFromTopic('transit_route_$routeId');
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
Future<void> openOrgRoutes(int orgId) async {
|
||||
currentOrgId = orgId;
|
||||
isLoadingRoutes = true;
|
||||
@@ -101,6 +121,7 @@ class TransitController extends GetxController {
|
||||
if (Get.isRegistered<MapSocketController>()) {
|
||||
final ms = Get.find<MapSocketController>();
|
||||
ms.onBusLocationUpdate = _handleLiveBusUpdate;
|
||||
ms.onTransitError = _handleTransitError;
|
||||
ms.subscribeToTransitRoute(routeId);
|
||||
}
|
||||
}
|
||||
@@ -122,11 +143,23 @@ class TransitController extends GetxController {
|
||||
update();
|
||||
}
|
||||
|
||||
void _handleTransitError(String errorCode) {
|
||||
if (errorCode == 'NOT_ENROLLED') {
|
||||
liveError = 'غير مشترك في هذا الخط. فعّل عضويتك أولاً.';
|
||||
} else if (errorCode == 'ROUTE_NOT_FOUND') {
|
||||
liveError = 'الخط غير متاح حالياً.';
|
||||
} else {
|
||||
liveError = 'خطأ في الاتصال بالخط: $errorCode';
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void closeLiveRoute() {
|
||||
if (liveRouteId != null && Get.isRegistered<MapSocketController>()) {
|
||||
final ms = Get.find<MapSocketController>();
|
||||
ms.unsubscribeFromTransitRoute(liveRouteId!);
|
||||
ms.onBusLocationUpdate = null;
|
||||
ms.onTransitError = null;
|
||||
}
|
||||
liveRouteId = null;
|
||||
liveTripId = null;
|
||||
|
||||
Reference in New Issue
Block a user