318 lines
10 KiB
Dart
Executable File
318 lines
10 KiB
Dart
Executable File
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:sefer_driver/controller/home/captin/home_captain_controller.dart';
|
|
import 'package:sefer_driver/views/home/Captin/orderCaptin/order_speed_request.dart';
|
|
import 'package:sefer_driver/views/widgets/error_snakbar.dart';
|
|
import 'package:sefer_driver/views/widgets/mydialoug.dart';
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:sefer_driver/views/widgets/elevated_btn.dart';
|
|
|
|
import '../../constant/box_name.dart';
|
|
import '../../constant/colors.dart';
|
|
import '../../constant/style.dart';
|
|
import '../../main.dart';
|
|
import '../../print.dart';
|
|
import '../../views/auth/captin/criminal_documents_page.dart';
|
|
import '../../views/home/Captin/home_captain/home_captin.dart';
|
|
import '../../views/home/Captin/orderCaptin/order_request_page.dart';
|
|
import '../../views/home/Captin/orderCaptin/vip_order_page.dart';
|
|
import '../auth/google_sign.dart';
|
|
import '../functions/face_detect.dart';
|
|
import 'local_notification.dart';
|
|
|
|
class FirebaseMessagesController extends GetxController {
|
|
final fcmToken = FirebaseMessaging.instance;
|
|
|
|
List<String> tokens = [];
|
|
List dataTokens = [];
|
|
late String driverID;
|
|
late String driverToken;
|
|
NotificationSettings? notificationSettings;
|
|
NotificationController notificationController =
|
|
Get.put(NotificationController());
|
|
Future<void> getNotificationSettings() async {
|
|
// Get the current notification settings
|
|
NotificationSettings? notificationSettings =
|
|
await FirebaseMessaging.instance.getNotificationSettings();
|
|
'Notification authorization status: ${notificationSettings.authorizationStatus}';
|
|
|
|
// Call the update function if needed
|
|
update();
|
|
}
|
|
|
|
Future<void> requestFirebaseMessagingPermission() async {
|
|
FirebaseMessaging messaging = FirebaseMessaging.instance;
|
|
|
|
// Check if the platform is Android
|
|
if (Platform.isAndroid) {
|
|
// Request permission for Android
|
|
await messaging.requestPermission();
|
|
} else if (Platform.isIOS) {
|
|
// Request permission for iOS
|
|
NotificationSettings settings = await messaging.requestPermission(
|
|
alert: true,
|
|
announcement: true,
|
|
badge: true,
|
|
carPlay: true,
|
|
criticalAlert: true,
|
|
provisional: false,
|
|
sound: true,
|
|
);
|
|
messaging.setForegroundNotificationPresentationOptions(
|
|
alert: true, badge: true, sound: true);
|
|
}
|
|
}
|
|
|
|
Future getToken() async {
|
|
fcmToken.getToken().then((token) {
|
|
Log.print('token fcm driver: ${token}');
|
|
box.write(BoxName.tokenDriver, (token!));
|
|
});
|
|
// 🔹 الاشتراك في topic
|
|
await fcmToken.subscribeToTopic("drivers"); // أو "users" حسب نوع المستخدم
|
|
print("Subscribed to 'drivers' topic ✅");
|
|
|
|
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
|
// If the app is in the background or terminated, show a system tray message
|
|
RemoteNotification? notification = message.notification;
|
|
AndroidNotification? android = notification?.android;
|
|
// if (notification != null && android != null) {
|
|
|
|
if (message.data.isNotEmpty && message.notification != null) {
|
|
fireBaseTitles(message);
|
|
}
|
|
// if (message.data.isNotEmpty && message.notification != null) {
|
|
// fireBaseTitles(message);
|
|
// }
|
|
});
|
|
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) async {});
|
|
|
|
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
|
|
if (message.data.isNotEmpty && message.notification != null) {
|
|
fireBaseTitles(message);
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<void> fireBaseTitles(RemoteMessage message) async {
|
|
// [!! تعديل جوهري !!]
|
|
// اقرأ "النوع" من حمولة البيانات، وليس من العنوان
|
|
String category = message.data['category'] ?? '';
|
|
|
|
// اقرأ العنوان والنص (للعرض)
|
|
String title = message.notification?.title ?? '';
|
|
String body = message.notification?.body ?? '';
|
|
|
|
// استخدم switch لسهولة القراءة والصيانة
|
|
switch (category) {
|
|
case 'ORDER':
|
|
case 'Order': // Handle both cases for backward compatibility
|
|
if (Platform.isAndroid) {
|
|
notificationController.showNotification(title, body, 'tone1', '');
|
|
}
|
|
var myListString = message.data['DriverList'];
|
|
if (myListString != null) {
|
|
var myList = jsonDecode(myListString) as List<dynamic>;
|
|
driverToken = myList[14].toString();
|
|
Get.put(HomeCaptainController()).changeRideId();
|
|
update();
|
|
Get.to(() => OrderRequestPage(), arguments: {
|
|
'myListString': myListString,
|
|
'DriverList': myList,
|
|
'body': body
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'OrderVIP':
|
|
var myListString = message.data['DriverList'];
|
|
if (myListString != null) {
|
|
var myList = jsonDecode(myListString) as List<dynamic>;
|
|
if (Platform.isAndroid) {
|
|
notificationController.showNotification(title, body, 'order', '');
|
|
}
|
|
Get.to(VipOrderPage(), arguments: {
|
|
'myListString': myListString,
|
|
'DriverList': myList,
|
|
'body': body
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'Cancel Trip':
|
|
case 'TRIP_CANCELLED':
|
|
if (Platform.isAndroid) {
|
|
notificationController.showNotification(
|
|
title, 'Passenger Cancel Trip'.tr, 'cancel', '');
|
|
}
|
|
cancelTripDialog();
|
|
break;
|
|
|
|
case 'VIP Order Accepted':
|
|
// This seems to be a notification for the passenger, but if the driver needs to see it:
|
|
if (Platform.isAndroid) {
|
|
notificationController.showNotification(title, body, 'order', '');
|
|
}
|
|
// Maybe show a simple snackbar confirmation
|
|
mySnackbarSuccess('You accepted the VIP order.'.tr);
|
|
break;
|
|
|
|
case 'message From passenger':
|
|
case 'MSG_FROM_PASSENGER':
|
|
if (Platform.isAndroid) {
|
|
notificationController.showNotification(title, body, 'ding', '');
|
|
}
|
|
MyDialog().getDialog(title, body, () {
|
|
Get.back();
|
|
});
|
|
break;
|
|
|
|
case 'token change':
|
|
case 'TOKEN_CHANGE':
|
|
GoogleSignInHelper.signOut();
|
|
break;
|
|
|
|
case 'face detect':
|
|
case 'FACE_DETECT':
|
|
if (Platform.isAndroid) {
|
|
notificationController.showNotification(title, body, 'tone2', '');
|
|
}
|
|
String result0 = await faceDetector();
|
|
var result = jsonDecode(result0);
|
|
MyDialogContent().getDialog(
|
|
'Face Detection Result'.tr,
|
|
Text(
|
|
result['similar'].toString() == 'true'
|
|
? 'similar'.tr
|
|
: 'not similar'.tr,
|
|
style: AppStyle.title,
|
|
),
|
|
() {
|
|
Get.back();
|
|
},
|
|
);
|
|
update();
|
|
break;
|
|
|
|
case 'Hi ,I will go now':
|
|
case 'PASSENGER_COMING':
|
|
if (Platform.isAndroid) {
|
|
notificationController.showNotification(title, body, 'tone2', '');
|
|
}
|
|
update();
|
|
break;
|
|
|
|
case 'Criminal Document Required':
|
|
case 'DOC_REQUIRED':
|
|
if (Platform.isAndroid) {
|
|
notificationController.showNotification(title, body, 'tone2', '');
|
|
}
|
|
MyDialog().getDialog(title, 'You should have upload it .'.tr, () {
|
|
Get.to(() => const CriminalDocumemtPage());
|
|
});
|
|
break;
|
|
|
|
case 'Order Applied':
|
|
case 'ORDER_TAKEN':
|
|
mySnackbarSuccess("The order has been accepted by another driver.".tr);
|
|
break;
|
|
|
|
default:
|
|
Log.print('Received unhandled notification category: $category');
|
|
// Optionally show a generic notification
|
|
if (Platform.isAndroid) {
|
|
notificationController.showNotification(title, body, 'default', '');
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
SnackbarController driverAppliedTripSnakBar() {
|
|
return Get.snackbar(
|
|
'Driver Applied the Ride for You'.tr,
|
|
'',
|
|
colorText: AppColor.greenColor,
|
|
duration: const Duration(seconds: 3),
|
|
snackPosition: SnackPosition.TOP,
|
|
titleText: Text(
|
|
'Applied'.tr,
|
|
style: const TextStyle(color: AppColor.redColor),
|
|
),
|
|
messageText: Text(
|
|
'Driver Applied the Ride for You'.tr,
|
|
style: AppStyle.title,
|
|
),
|
|
icon: const Icon(Icons.approval),
|
|
shouldIconPulse: true,
|
|
margin: const EdgeInsets.all(16),
|
|
padding: const EdgeInsets.all(16),
|
|
);
|
|
}
|
|
|
|
Future<dynamic> cancelTripDialog() {
|
|
return Get.defaultDialog(
|
|
barrierDismissible: false,
|
|
title: 'Passenger Cancel Trip'.tr,
|
|
middleText: '',
|
|
confirm: MyElevatedButton(
|
|
title: 'Ok'.tr,
|
|
onPressed: () {
|
|
box.write(BoxName.rideStatus, 'Cancel');
|
|
box.write(BoxName.statusDriverLocation, 'off');
|
|
Log.print(
|
|
'rideStatus from 347 : ${box.read(BoxName.rideStatus)}');
|
|
Get.offAll(HomeCaptain());
|
|
}));
|
|
}
|
|
|
|
Future<dynamic> cancelTripDialog1() {
|
|
return Get.defaultDialog(
|
|
barrierDismissible: false,
|
|
title: 'Passenger Cancel Trip'.tr,
|
|
middleText:
|
|
'Trip Cancelled. The cost of the trip will be added to your wallet.'
|
|
.tr,
|
|
confirm: MyElevatedButton(
|
|
title: 'Ok'.tr,
|
|
onPressed: () {
|
|
box.write(BoxName.rideStatus, 'Cancel');
|
|
Log.print(
|
|
'rideStatus from 364 : ${box.read(BoxName.rideStatus)}');
|
|
Get.offAll(HomeCaptain());
|
|
}));
|
|
}
|
|
}
|
|
|
|
class OverlayContent extends StatelessWidget {
|
|
final String title;
|
|
final String body;
|
|
|
|
OverlayContent(this.title, this.body);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Material(
|
|
child: Container(
|
|
padding: const EdgeInsets.all(16.0),
|
|
color: Colors.white,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
|
),
|
|
const SizedBox(height: 8.0),
|
|
Text(
|
|
body,
|
|
style: const TextStyle(fontSize: 16),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|