7/31/1
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:SEFER/constant/box_name.dart';
|
||||
import 'package:SEFER/constant/colors.dart';
|
||||
import 'package:SEFER/constant/links.dart';
|
||||
import 'package:SEFER/controller/functions/crud.dart';
|
||||
import 'package:SEFER/controller/home/payment/captain_wallet_controller.dart';
|
||||
import 'package:SEFER/views/widgets/mydialoug.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_contacts/contact.dart';
|
||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../main.dart';
|
||||
import '../../../print.dart';
|
||||
import '../../functions/launch.dart';
|
||||
import '../../notification/notification_captain_controller.dart';
|
||||
|
||||
@@ -38,6 +42,40 @@ class InviteController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> pickContact() async {
|
||||
try {
|
||||
print('Requesting contact permission...');
|
||||
if (await FlutterContacts.requestPermission(readonly: true)) {
|
||||
print('Permission granted. Opening external contact picker...');
|
||||
final Contact? contact = await FlutterContacts.openExternalPick();
|
||||
if (contact != null) {
|
||||
print('Contact picked: ${contact.displayName}');
|
||||
if (contact.phones.isNotEmpty) {
|
||||
print('Phone number found: ${contact.phones.first.number}');
|
||||
invitePhoneController.text = contact.phones.first.number;
|
||||
update();
|
||||
} else {
|
||||
print('Selected contact has no phone number.');
|
||||
Get.snackbar('No phone number'.tr,
|
||||
'The selected contact does not have a phone number.'.tr);
|
||||
}
|
||||
} else {
|
||||
print('No contact selected or picker was cancelled.');
|
||||
Get.snackbar('No contact selected'.tr, 'Please select a contact'.tr);
|
||||
}
|
||||
} else {
|
||||
print('Permission denied by user or system.');
|
||||
Get.snackbar('Permission denied'.tr,
|
||||
'Contact permission is required to pick a contact'.tr);
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error picking contact: $e');
|
||||
print('Stack trace: ${StackTrace.current}');
|
||||
Get.snackbar(
|
||||
'Error'.tr, 'An error occurred while picking a contact: $e'.tr);
|
||||
}
|
||||
}
|
||||
|
||||
void onSelectDriverInvitation(int index) async {
|
||||
MyDialog().getDialog(
|
||||
driverInvitationData[index]['countOfInvitDriver'] < 100
|
||||
@@ -89,7 +127,7 @@ class InviteController extends GetxController {
|
||||
"driverId": box.read(BoxName.driverID),
|
||||
"inviterDriverPhone": '+2${invitePhoneController.text}'
|
||||
});
|
||||
|
||||
Log.print('response: ${response}');
|
||||
if (response != 'failure') {
|
||||
var d = jsonDecode(response);
|
||||
Get.snackbar('Success', 'Invite sent successfully'.tr);
|
||||
@@ -109,7 +147,9 @@ class InviteController extends GetxController {
|
||||
|
||||
invitePhoneController.clear();
|
||||
} else {
|
||||
Get.snackbar('Error', 'Failed to send invite'.tr);
|
||||
Get.snackbar('Error'.tr, "Invite code already used".tr,
|
||||
backgroundColor: AppColor.redColor,
|
||||
duration: const Duration(seconds: 4));
|
||||
}
|
||||
// } catch (e) {
|
||||
// print('Error sending invite: $e');
|
||||
|
||||
@@ -55,7 +55,7 @@ class LoginDriverController extends GetxController {
|
||||
'id': driverID,
|
||||
});
|
||||
print(res);
|
||||
if (res == 'Failure') {
|
||||
if (res == 'failure') {
|
||||
//Failure
|
||||
if (box.read(BoxName.phoneVerified).toString() == '1') {
|
||||
Get.offAll(() => EgyptCardAI());
|
||||
|
||||
@@ -79,6 +79,21 @@ class RegisterCaptainController extends GetxController {
|
||||
update();
|
||||
}
|
||||
|
||||
bool isValidEgyptianPhoneNumber(String phoneNumber) {
|
||||
// Remove any whitespace from the phone number
|
||||
phoneNumber = phoneNumber.replaceAll(RegExp(r'\s+'), '');
|
||||
|
||||
// Check if the phone number has exactly 11 digits
|
||||
if (phoneNumber.length != 11) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the phone number starts with 010, 011, 012, or 015
|
||||
RegExp validPrefixes = RegExp(r'^01[0125]');
|
||||
|
||||
return validPrefixes.hasMatch(phoneNumber);
|
||||
}
|
||||
|
||||
sendOtpMessage() async {
|
||||
SmsEgyptController smsEgyptController = Get.put(SmsEgyptController());
|
||||
|
||||
@@ -87,21 +102,38 @@ class RegisterCaptainController extends GetxController {
|
||||
update();
|
||||
if (formKey3.currentState!.validate()) {
|
||||
if (box.read(BoxName.countryCode) == 'Egypt') {
|
||||
var responseCheker = await CRUD()
|
||||
.post(link: AppLink.checkPhoneNumberISVerfiedDriver, payload: {
|
||||
'phone_number': '+2${phoneController.text}',
|
||||
});
|
||||
if (responseCheker != 'failure') {
|
||||
var d = jsonDecode(responseCheker);
|
||||
if (d['message'][0]['is_verified'].toString() == '1') {
|
||||
Get.snackbar('Phone number is verified before'.tr, '',
|
||||
backgroundColor: AppColor.greenColor);
|
||||
box.write(BoxName.isVerified, '1');
|
||||
box.write(BoxName.phone, '+2${phoneController.text}');
|
||||
await Get.put(LoginDriverController()).loginUsingCredentials(
|
||||
box.read(BoxName.driverID).toString(),
|
||||
box.read(BoxName.emailDriver).toString(),
|
||||
);
|
||||
if (isValidEgyptianPhoneNumber(phoneController.text)) {
|
||||
var responseCheker = await CRUD()
|
||||
.post(link: AppLink.checkPhoneNumberISVerfiedDriver, payload: {
|
||||
'phone_number': '+2${phoneController.text}',
|
||||
});
|
||||
if (responseCheker != 'failure') {
|
||||
var d = jsonDecode(responseCheker);
|
||||
if (d['message'][0]['is_verified'].toString() == '1') {
|
||||
Get.snackbar('Phone number is verified before'.tr, '',
|
||||
backgroundColor: AppColor.greenColor);
|
||||
box.write(BoxName.phoneVerified, '1');
|
||||
box.write(BoxName.phone, '+2${phoneController.text}');
|
||||
await Get.put(LoginDriverController()).loginUsingCredentials(
|
||||
box.read(BoxName.driverID).toString(),
|
||||
box.read(BoxName.emailDriver).toString(),
|
||||
);
|
||||
} else {
|
||||
await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
|
||||
'phone_number': '+2${phoneController.text}',
|
||||
'token_code': randomNumber.toString(),
|
||||
"driverId": box.read(BoxName.driverID),
|
||||
"email": box.read(BoxName.emailDriver),
|
||||
});
|
||||
|
||||
await smsEgyptController.sendSmsEgypt(
|
||||
phoneController.text.toString(), randomNumber.toString());
|
||||
|
||||
isSent = true;
|
||||
|
||||
isLoading = false;
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
|
||||
'phone_number': '+2${phoneController.text}',
|
||||
@@ -112,25 +144,15 @@ class RegisterCaptainController extends GetxController {
|
||||
|
||||
await smsEgyptController.sendSmsEgypt(
|
||||
phoneController.text.toString(), randomNumber.toString());
|
||||
|
||||
isSent = true;
|
||||
|
||||
isLoading = false;
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
|
||||
'phone_number': '+2${phoneController.text}',
|
||||
'token_code': randomNumber.toString(),
|
||||
"driverId": box.read(BoxName.driverID),
|
||||
"email": box.read(BoxName.emailDriver),
|
||||
});
|
||||
|
||||
await smsEgyptController.sendSmsEgypt(
|
||||
phoneController.text.toString(), randomNumber.toString());
|
||||
isSent = true;
|
||||
|
||||
isLoading = false;
|
||||
update();
|
||||
Get.snackbar('Phone Number wrong'.tr, '',
|
||||
backgroundColor: AppColor.redColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:SEFER/constant/box_name.dart';
|
||||
import 'package:SEFER/constant/colors.dart';
|
||||
import 'package:SEFER/controller/auth/captin/login_captin_controller.dart';
|
||||
import 'package:SEFER/main.dart';
|
||||
import 'package:SEFER/views/auth/captin/cards/sms_signup.dart';
|
||||
@@ -35,22 +36,69 @@ class GoogleSignInHelper {
|
||||
}
|
||||
}
|
||||
|
||||
// static Future<GoogleSignInAccount?> signInFromLogin() async {
|
||||
// // try {
|
||||
// // final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
|
||||
// // if (googleUser != null) {
|
||||
// // await _handleSignUp(googleUser);
|
||||
// // // if (box.read(BoxName.countryCode) == 'Egypt') {
|
||||
// // await Get.find<LoginDriverController>().loginUsingCredentials(
|
||||
// // box.read(BoxName.driverID).toString(),
|
||||
// // box.read(BoxName.emailDriver).toString(),
|
||||
// // );
|
||||
// // // } else if (box.read(BoxName.countryCode) == 'Jordan') {
|
||||
// // // // Get.to(() => AiPage());
|
||||
// // // }
|
||||
// // }
|
||||
// // return googleUser;
|
||||
// // } catch (error) {
|
||||
// // return null;
|
||||
// // }
|
||||
// try {
|
||||
// final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
|
||||
// if (googleUser != null) {
|
||||
// // Handle sign-up logic
|
||||
// await _handleSignUp(googleUser);
|
||||
//
|
||||
// // Get country code
|
||||
// final String countryCode = box.read(BoxName.countryCode).toString();
|
||||
// final String driverID = box.read(BoxName.driverID).toString();
|
||||
// final String emailDriver = box.read(BoxName.emailDriver).toString();
|
||||
//
|
||||
// // Log-in using credentials based on country code
|
||||
// if (countryCode == 'Egypt') {
|
||||
// await Get.find<LoginDriverController>()
|
||||
// .loginUsingCredentials(driverID, emailDriver);
|
||||
// } else if (countryCode == 'Jordan') {
|
||||
// // Add logic for Jordan if needed, e.g., navigate to AiPage
|
||||
// // Get.to(() => AiPage());
|
||||
// }
|
||||
// }
|
||||
// return googleUser;
|
||||
// } catch (error) {
|
||||
// Get.snackbar('Google Sign-In error', '$error',
|
||||
// backgroundColor: AppColor.redColor);
|
||||
// // Log error details
|
||||
// print('Google Sign-In error: $error');
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
static Future<GoogleSignInAccount?> signInFromLogin() async {
|
||||
try {
|
||||
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
|
||||
if (googleUser != null) {
|
||||
await _handleSignUp(googleUser);
|
||||
// if (box.read(BoxName.countryCode) == 'Egypt') {
|
||||
await Get.find<LoginDriverController>().loginUsingCredentials(
|
||||
box.read(BoxName.driverID).toString(),
|
||||
box.read(BoxName.emailDriver).toString(),
|
||||
);
|
||||
// } else if (box.read(BoxName.countryCode) == 'Jordan') {
|
||||
// // Get.to(() => AiPage());
|
||||
// }
|
||||
}
|
||||
return googleUser;
|
||||
} catch (error) {
|
||||
Get.snackbar('Google Sign-In error', '$error',
|
||||
backgroundColor: AppColor.redColor);
|
||||
// Log error details
|
||||
print('Google Sign-In error: $error');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
18
lib/controller/firebase/bring_app_foreground.dart
Normal file
18
lib/controller/firebase/bring_app_foreground.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class AppLifecycleManager {
|
||||
static const platform = MethodChannel('com.sefer_driver/app_lifecycle');
|
||||
|
||||
static Future<void> bringAppToForeground() async {
|
||||
try {
|
||||
debugPrint('Attempting to bring app to foreground');
|
||||
await platform.invokeMethod('bringAppToForeground');
|
||||
debugPrint('Method invocation completed');
|
||||
} on PlatformException catch (e) {
|
||||
debugPrint("Failed to bring app to foreground: '${e.message}'.");
|
||||
} catch (e) {
|
||||
debugPrint("Unexpected error: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
|
||||
import 'package:SEFER/views/home/Captin/home_captain/widget/call_page.dart';
|
||||
import 'package:SEFER/views/widgets/mydialoug.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -79,9 +78,27 @@ class FirebaseMessagesController extends GetxController {
|
||||
}
|
||||
});
|
||||
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) async {
|
||||
// Handle background message
|
||||
if (message.data.isNotEmpty && message.notification != null) {
|
||||
fireBaseTitles(message);
|
||||
if (message.notification!.title! == 'Order'.tr) {
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController()
|
||||
.showNotification('Order'.tr, '', 'order', 'order_page_payload');
|
||||
}
|
||||
// await FirebaseMessagesController().showOverlayNotification(message);
|
||||
var myListString = message.data['DriverList'];
|
||||
// var points = message.data['PolylineJson'];
|
||||
|
||||
var myList = jsonDecode(myListString) as List<dynamic>;
|
||||
// var myPoints = jsonDecode(points) as List<dynamic>;
|
||||
driverToken = myList[14].toString();
|
||||
// This is for location using and uploading status
|
||||
Get.put(HomeCaptainController()).changeRideId();
|
||||
update();
|
||||
Get.to(() => OrderRequestPage(), arguments: {
|
||||
'myListString': myListString,
|
||||
'DriverList': myList,
|
||||
// 'PolylineJson': myPoints,
|
||||
'body': message.notification!.body
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -95,8 +112,9 @@ class FirebaseMessagesController extends GetxController {
|
||||
Future<void> fireBaseTitles(RemoteMessage message) async {
|
||||
if (message.notification!.title! == 'Order'.tr) {
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController().showNotification('Order'.tr, '', 'order');
|
||||
NotificationController().showNotification('Order'.tr, '', 'order', '');
|
||||
}
|
||||
// await FirebaseMessagesController().showOverlayNotification(message);
|
||||
var myListString = message.data['DriverList'];
|
||||
// var points = message.data['PolylineJson'];
|
||||
|
||||
@@ -113,8 +131,10 @@ class FirebaseMessagesController extends GetxController {
|
||||
'body': message.notification!.body
|
||||
});
|
||||
} else if (message.notification!.title == 'Cancel Trip') {
|
||||
NotificationController().showNotification(
|
||||
'Cancel Trip'.tr, 'Passenger Cancel Trip'.tr, 'cancel');
|
||||
// if (Platform.isAndroid) {
|
||||
// NotificationController().showNotification(
|
||||
// 'Cancel Trip'.tr, 'Passenger Cancel Trip'.tr, 'cancel', '');
|
||||
// }
|
||||
cancelTripDialog();
|
||||
} else if (message.notification!.title! == 'token change') {
|
||||
// NotificationController()
|
||||
@@ -122,14 +142,18 @@ class FirebaseMessagesController extends GetxController {
|
||||
// GoogleSignInHelper.signOut();
|
||||
GoogleSignInHelper.signOut();
|
||||
} else if (message.notification!.title! == 'message From passenger') {
|
||||
NotificationController()
|
||||
.showNotification('message From passenger', ''.tr, 'tone2');
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController()
|
||||
.showNotification('message From passenger', ''.tr, 'tone2', '');
|
||||
}
|
||||
passengerDialog(message.notification!.body!);
|
||||
|
||||
update();
|
||||
} else if (message.notification!.title! == 'face detect') {
|
||||
NotificationController()
|
||||
.showNotification('face detect'.tr, ''.tr, 'tone2');
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController()
|
||||
.showNotification('face detect'.tr, ''.tr, 'tone2', '');
|
||||
}
|
||||
String result0 = await faceDetector();
|
||||
// Handle the result here, e.g., show a dialog or update the UI
|
||||
var result = jsonDecode(result0);
|
||||
@@ -156,19 +180,20 @@ class FirebaseMessagesController extends GetxController {
|
||||
} else if (message.notification!.title! == 'Hi ,I will go now') {
|
||||
// Get.snackbar('Hi ,I will go now', '',
|
||||
// backgroundColor: AppColor.greenColor);
|
||||
NotificationController().showNotification(
|
||||
'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'tone2');
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController().showNotification(
|
||||
'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'tone2', '');
|
||||
}
|
||||
update();
|
||||
} else if (message.notification!.title! == 'Call Income'.tr) {
|
||||
try {
|
||||
var myListString = message.data['passengerList'];
|
||||
var driverList = jsonDecode(myListString) as List<dynamic>;
|
||||
// if (Platform.isAndroid) {
|
||||
NotificationController().showNotification(
|
||||
'Call Income'.tr,
|
||||
message.notification!.body!,
|
||||
'iphone_ringtone',
|
||||
);
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController().showNotification('Call Income'.tr,
|
||||
message.notification!.body!, 'iphone_ringtone', '');
|
||||
}
|
||||
// }
|
||||
// Assuming GetMaterialApp is initialized and context is valid for navigation
|
||||
// Get.to(() => PassengerCallPage(
|
||||
@@ -183,11 +208,10 @@ class FirebaseMessagesController extends GetxController {
|
||||
var myListString = message.data['passengerList'];
|
||||
var driverList = jsonDecode(myListString) as List<dynamic>;
|
||||
// if (Platform.isAndroid) {
|
||||
NotificationController().showNotification(
|
||||
'Call Income'.tr,
|
||||
message.notification!.body!,
|
||||
'iphone_ringtone',
|
||||
);
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController().showNotification('Call Income'.tr,
|
||||
message.notification!.body!, 'iphone_ringtone', '');
|
||||
}
|
||||
// }
|
||||
// Assuming GetMaterialApp is initialized and context is valid for navigation
|
||||
// Get.to(() => CallPage(
|
||||
@@ -198,11 +222,13 @@ class FirebaseMessagesController extends GetxController {
|
||||
} catch (e) {}
|
||||
} else if (message.notification!.title! ==
|
||||
"Criminal Document Required".tr) {
|
||||
NotificationController().showNotification(
|
||||
"Criminal Document Required".tr,
|
||||
message.notification!.body!,
|
||||
'tone2',
|
||||
);
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController().showNotification(
|
||||
"Criminal Document Required".tr,
|
||||
message.notification!.body!,
|
||||
'tone2',
|
||||
'');
|
||||
}
|
||||
MyDialog().getDialog(
|
||||
"Criminal Document Required".tr, 'You should have upload it .'.tr,
|
||||
() {
|
||||
@@ -215,10 +241,7 @@ class FirebaseMessagesController extends GetxController {
|
||||
var driverList = jsonDecode(myListString) as List<dynamic>;
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController().showNotification(
|
||||
'Call End'.tr,
|
||||
message.notification!.body!,
|
||||
'tone2',
|
||||
);
|
||||
'Call End'.tr, message.notification!.body!, 'tone2', '');
|
||||
}
|
||||
// Assuming GetMaterialApp is initialized and context is valid for navigation
|
||||
// Get.off(const CallPage());
|
||||
@@ -247,11 +270,14 @@ class FirebaseMessagesController extends GetxController {
|
||||
'body': message.notification!.body
|
||||
});
|
||||
} else if (message.notification!.title! == 'Order Applied'.tr) {
|
||||
NotificationController().showNotification(
|
||||
'The order Accepted by another Driver'.tr,
|
||||
'We regret to inform you that another driver has accepted this order.'
|
||||
.tr,
|
||||
'order');
|
||||
if (Platform.isAndroid) {
|
||||
NotificationController().showNotification(
|
||||
'The order Accepted by another Driver'.tr,
|
||||
'We regret to inform you that another driver has accepted this order.'
|
||||
.tr,
|
||||
'order',
|
||||
'');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,3 +649,34 @@ class FirebaseMessagesController extends GetxController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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: EdgeInsets.all(16.0),
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||
),
|
||||
SizedBox(height: 8.0),
|
||||
Text(
|
||||
body,
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:SEFER/constant/box_name.dart';
|
||||
import 'package:SEFER/constant/colors.dart';
|
||||
import 'package:SEFER/views/home/Captin/orderCaptin/order_request_page.dart';
|
||||
import 'package:SEFER/views/home/my_wallet/walet_captain.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../main.dart';
|
||||
import '../../print.dart';
|
||||
|
||||
class NotificationController extends GetxController {
|
||||
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
@@ -8,22 +17,108 @@ class NotificationController extends GetxController {
|
||||
// Initializes the local notifications plugin
|
||||
Future<void> initNotifications() async {
|
||||
const AndroidInitializationSettings android =
|
||||
AndroidInitializationSettings('@mipmap/launcher_icon');
|
||||
AndroidInitializationSettings('app_icon');
|
||||
|
||||
const InitializationSettings initializationSettings =
|
||||
InitializationSettings(android: android);
|
||||
await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
|
||||
|
||||
await _flutterLocalNotificationsPlugin.initialize(
|
||||
initializationSettings,
|
||||
onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,
|
||||
onDidReceiveBackgroundNotificationResponse:
|
||||
onDidReceiveBackgroundNotificationResponse,
|
||||
);
|
||||
|
||||
// Create a notification channel
|
||||
const AndroidNotificationChannel channel = AndroidNotificationChannel(
|
||||
'order_channel', // Channel ID
|
||||
'Order Notifications', // Channel name
|
||||
description:
|
||||
'This channel is used for order notifications.', // Channel description
|
||||
importance: Importance.max,
|
||||
);
|
||||
|
||||
// Register the channel with the system
|
||||
await _flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin>()
|
||||
?.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
// Displays a notification with the given title and message
|
||||
void showNotification(String title, String message, String tone) async {
|
||||
AndroidNotificationDetails android = AndroidNotificationDetails(
|
||||
'your channel id', 'your channel name',
|
||||
importance: Importance.max,
|
||||
priority: Priority.high,
|
||||
showWhen: false,
|
||||
sound: RawResourceAndroidNotificationSound(tone));
|
||||
void showNotification(
|
||||
String title, String message, String tone, String payLoad) async {
|
||||
BigTextStyleInformation bigTextStyleInformation = BigTextStyleInformation(
|
||||
message,
|
||||
contentTitle: title.tr,
|
||||
htmlFormatContent: true,
|
||||
htmlFormatContentTitle: true,
|
||||
);
|
||||
|
||||
AndroidNotificationDetails android =
|
||||
AndroidNotificationDetails('order_channel', 'Order Notifications',
|
||||
importance: Importance.max,
|
||||
priority: Priority.high,
|
||||
styleInformation: bigTextStyleInformation,
|
||||
playSound: true,
|
||||
sound: RawResourceAndroidNotificationSound(tone),
|
||||
audioAttributesUsage: AudioAttributesUsage.alarm,
|
||||
visibility: NotificationVisibility.public,
|
||||
autoCancel: false,
|
||||
color: AppColor.primaryColor,
|
||||
showProgress: true,
|
||||
showWhen: true,
|
||||
subText: message,
|
||||
actions: [
|
||||
AndroidNotificationAction(
|
||||
allowGeneratedReplies: true,
|
||||
'id',
|
||||
title.tr,
|
||||
titleColor: AppColor.bronze,
|
||||
showsUserInterface: true,
|
||||
)
|
||||
],
|
||||
category: AndroidNotificationCategory.call);
|
||||
|
||||
NotificationDetails details = NotificationDetails(android: android);
|
||||
await _flutterLocalNotificationsPlugin.show(0, title, message, details);
|
||||
|
||||
await _flutterLocalNotificationsPlugin.show(0, title, message, details,
|
||||
payload: payLoad);
|
||||
|
||||
// payload: 'order_page_payload');
|
||||
}
|
||||
|
||||
// Callback when the notification is tapped
|
||||
void onDidReceiveNotificationResponse(NotificationResponse response) {
|
||||
// jsonDecode(response.payload);
|
||||
print('Notification tapped!');
|
||||
if (response.payload != null) {
|
||||
print('Notification payload: ${response.payload}');
|
||||
// if (response.payload != 'order_page_payload') {
|
||||
// Log.print('arguments: ${box.read(BoxName.rideArguments)}');
|
||||
closeOverLay();
|
||||
Get.to(() => OrderRequestPage(),
|
||||
arguments: {'myListString': response.payload});
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
void onDidReceiveLocalNotification(
|
||||
int id, String? title, String? body, String? payload) async {
|
||||
// display a dialog with the notification details, tap ok to go to another page
|
||||
}
|
||||
// Callback when the notification is tapped while the app is in the background
|
||||
void onDidReceiveBackgroundNotificationResponse(
|
||||
NotificationResponse response) {
|
||||
print('Notification tapped while app is in background!');
|
||||
if (response.payload != null) {
|
||||
print('Notification payload: ${response.payload}');
|
||||
if (response.payload == 'order') {
|
||||
Get.to(() => OrderRequestPage(),
|
||||
arguments: box.read(BoxName.rideArguments));
|
||||
closeOverLay();
|
||||
Log.print('arguments: ${box.read(BoxName.rideArguments)}');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
37
lib/controller/firebase/order_lay.dart
Normal file
37
lib/controller/firebase/order_lay.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:SEFER/constant/links.dart';
|
||||
import 'package:SEFER/controller/functions/crud.dart';
|
||||
import 'package:SEFER/views/home/Captin/home_captain/home_captin.dart';
|
||||
import 'package:SEFER/views/home/Captin/orderCaptin/order_request_page.dart';
|
||||
import 'package:SEFER/views/widgets/elevated_btn.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class OverlayContent1 extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
color: Colors.white,
|
||||
child: MyElevatedButton(
|
||||
title: 'go to order',
|
||||
onPressed: () async {
|
||||
var res = await CRUD().post(
|
||||
link: AppLink.addFeedBack,
|
||||
payload: {
|
||||
"passengerId": 'dddddd',
|
||||
"feedBack": "eeeee",
|
||||
},
|
||||
);
|
||||
print(res);
|
||||
if (res != 'failure') {
|
||||
Navigator.push(
|
||||
context, MaterialPageRoute(builder: (cont) => HomeCaptain()));
|
||||
// Get.to(OrderRequestPage());
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,9 @@ class CRUD {
|
||||
},
|
||||
);
|
||||
// if (response.statusCode == 200) {
|
||||
// Log.print('response: ${response.request}');
|
||||
// Log.print('response: ${response.body}');
|
||||
// Log.print('response: ${payload}');
|
||||
var jsonData = jsonDecode(response.body);
|
||||
if (jsonData['status'] == 'success') {
|
||||
return response.body;
|
||||
@@ -230,7 +233,7 @@ class CRUD {
|
||||
if (jsonData['status'] == 'success') {
|
||||
return response.body;
|
||||
} else {
|
||||
String errorMessage = jsonData['message'];
|
||||
// String errorMessage = jsonData['message'];
|
||||
// Get.snackbar('Error'.tr, errorMessage.tr,
|
||||
// backgroundColor: AppColor.redColor);
|
||||
return (jsonData['status']);
|
||||
|
||||
@@ -28,7 +28,7 @@ class LocationBackgroundController extends GetxController {
|
||||
await BackgroundLocation.setAndroidNotification(
|
||||
title: "Background Location",
|
||||
message: "Tracking location...",
|
||||
icon: "@mipmap/ic_launcher",
|
||||
icon: "@mipmap/launcher_icon",
|
||||
);
|
||||
|
||||
// Set the location update interval to 5 seconds
|
||||
|
||||
@@ -38,7 +38,7 @@ class LocationController extends GetxController {
|
||||
getLocation();
|
||||
// startLocationUpdates();
|
||||
|
||||
totalPoints = Get.put(CaptainWalletController()).totalPoints;
|
||||
totalPoints = Get.put(CaptainWalletController()).totalPoints.toString();
|
||||
// isActive = Get.put(HomeCaptainController()).isActive;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,8 @@ class LocationController extends GetxController {
|
||||
_locationTimer =
|
||||
Timer.periodic(const Duration(seconds: 5), (timer) async {
|
||||
try {
|
||||
totalPoints = Get.find<CaptainWalletController>().totalPoints;
|
||||
totalPoints =
|
||||
Get.find<CaptainWalletController>().totalPoints.toString();
|
||||
isActive = Get.find<HomeCaptainController>().isActive;
|
||||
if (isActive) {
|
||||
if (double.parse(totalPoints) > -3000) {
|
||||
|
||||
56
lib/controller/functions/overlay_permisssion.dart
Normal file
56
lib/controller/functions/overlay_permisssion.dart
Normal file
@@ -0,0 +1,56 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:SEFER/views/widgets/mydialoug.dart';
|
||||
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
Future<void> getPermissionOverlay() async {
|
||||
if (Platform.isAndroid) {
|
||||
final bool status = await FlutterOverlayWindow.isPermissionGranted();
|
||||
if (status == false) {
|
||||
MyDialog().getDialog(
|
||||
'Allow overlay permission'.tr,
|
||||
'To display orders instantly, please grant permission to draw over other apps.'
|
||||
.tr,
|
||||
() async {
|
||||
Get.back();
|
||||
await FlutterOverlayWindow.requestPermission();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getPermissionLocation() async {
|
||||
final PermissionStatus status = await Permission.location.request();
|
||||
if (status.isDenied) {
|
||||
MyDialog().getDialog(
|
||||
'Enable Location Permission'.tr, // {en:ar}
|
||||
'Allowing location access will help us display orders near you. Please enable it now.'
|
||||
.tr, // {en:ar}
|
||||
() async {
|
||||
Get.back();
|
||||
await FlutterOverlayWindow.requestPermission();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getOverLay(String myListString) async {
|
||||
bool isOverlayActive = await FlutterOverlayWindow.isActive();
|
||||
if (isOverlayActive) {
|
||||
await FlutterOverlayWindow.closeOverlay();
|
||||
}
|
||||
await FlutterOverlayWindow.showOverlay(
|
||||
enableDrag: true,
|
||||
flag: OverlayFlag.focusPointer,
|
||||
visibility: NotificationVisibility.visibilityPublic,
|
||||
positionGravity: PositionGravity.auto,
|
||||
height: 700,
|
||||
width: WindowSize.matchParent,
|
||||
startPosition: const OverlayPosition(0, -150),
|
||||
);
|
||||
|
||||
await FlutterOverlayWindow.shareData(myListString);
|
||||
}
|
||||
@@ -4,21 +4,37 @@ import 'package:SEFER/constant/api_key.dart';
|
||||
import 'package:SEFER/constant/box_name.dart';
|
||||
import 'package:SEFER/constant/info.dart';
|
||||
import 'package:SEFER/constant/links.dart';
|
||||
import 'package:SEFER/controller/auth/captin/register_captin_controller.dart';
|
||||
import 'package:SEFER/controller/functions/crud.dart';
|
||||
import 'package:SEFER/main.dart';
|
||||
import 'package:SEFER/views/widgets/elevated_btn.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../print.dart';
|
||||
import '../auth/captin/login_captin_controller.dart';
|
||||
|
||||
class SmsEgyptController extends GetxController {
|
||||
var headers = {'Content-Type': 'application/json'};
|
||||
|
||||
Future<String> getSender() async {
|
||||
var res = await CRUD().get(link: AppLink.getSender, payload: {});
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res)['message'][0]['senderId'].toString();
|
||||
return d;
|
||||
} else {
|
||||
return "Sefer Egy";
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> sendSmsEgypt(String phone, otp) async {
|
||||
String sender = await getSender();
|
||||
var body = jsonEncode({
|
||||
"username": AppInformation.appName,
|
||||
"password": AK.smsPasswordEgypt, //'E)Pu=an/@Z',
|
||||
"message": "${AppInformation.appName} app code is $otp\ncopy it to app",
|
||||
"language": box.read(BoxName.lang) == 'en' ? "e" : 'r',
|
||||
"sender": "Sefer Egy", // todo add sefer sender name
|
||||
"sender": sender, //"Sefer Egy", // todo add sefer sender name
|
||||
"receiver": "2$phone"
|
||||
});
|
||||
|
||||
@@ -28,7 +44,20 @@ class SmsEgyptController extends GetxController {
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
if (res.statusCode == 200) {
|
||||
if (jsonDecode(res.body)['message'].toString() != "Success") {
|
||||
await CRUD().post(link: AppLink.updatePhoneInvalidSMS, payload: {
|
||||
"phone_number":
|
||||
'+2${Get.find<RegisterCaptainController>().phoneController.text}'
|
||||
});
|
||||
box.write(BoxName.phoneDriver,
|
||||
'+2${Get.find<RegisterCaptainController>().phoneController.text}');
|
||||
box.write(BoxName.phoneVerified, '1');
|
||||
|
||||
await Get.put(LoginDriverController()).loginUsingCredentials(
|
||||
box.read(BoxName.driverID).toString(),
|
||||
box.read(BoxName.emailDriver).toString(),
|
||||
);
|
||||
} else {
|
||||
Get.defaultDialog(
|
||||
title: 'You will receive code in sms message'.tr,
|
||||
middleText: '',
|
||||
|
||||
@@ -101,54 +101,57 @@ class ImageController extends GetxController {
|
||||
}
|
||||
|
||||
choosImage(String link, String imageType) async {
|
||||
final pickedImage = await picker.pickImage(
|
||||
source: ImageSource.camera,
|
||||
preferredCameraDevice: CameraDevice.rear,
|
||||
);
|
||||
try {
|
||||
final pickedImage = await picker.pickImage(
|
||||
source: ImageSource.camera,
|
||||
preferredCameraDevice: CameraDevice.rear,
|
||||
);
|
||||
|
||||
if (pickedImage == null) return;
|
||||
if (pickedImage == null) return;
|
||||
|
||||
image = File(pickedImage.path);
|
||||
image = File(pickedImage.path);
|
||||
|
||||
croppedFile = await ImageCropper().cropImage(
|
||||
sourcePath: image!.path,
|
||||
uiSettings: [
|
||||
AndroidUiSettings(
|
||||
croppedFile = await ImageCropper().cropImage(
|
||||
sourcePath: image!.path,
|
||||
uiSettings: [
|
||||
AndroidUiSettings(
|
||||
toolbarTitle: 'Cropper'.tr,
|
||||
toolbarColor: AppColor.blueColor,
|
||||
toolbarWidgetColor: AppColor.yellowColor,
|
||||
initAspectRatio: CropAspectRatioPreset.original,
|
||||
lockAspectRatio: false),
|
||||
IOSUiSettings(
|
||||
title: 'Cropper'.tr,
|
||||
),
|
||||
],
|
||||
);
|
||||
lockAspectRatio: false,
|
||||
),
|
||||
IOSUiSettings(
|
||||
title: 'Cropper'.tr,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
if (croppedFile == null) return;
|
||||
if (croppedFile == null) return;
|
||||
|
||||
myImage = File(croppedFile!.path);
|
||||
isloading = true;
|
||||
update();
|
||||
myImage = File(croppedFile!.path);
|
||||
isloading = true;
|
||||
update();
|
||||
|
||||
// Rotate the compressed image
|
||||
File processedImage = await rotateImageIfNeeded(File(croppedFile!.path));
|
||||
File compressedImage = await compressImage(processedImage);
|
||||
|
||||
print('link =$link');
|
||||
|
||||
// Rotate the compressed image
|
||||
// File rotatedImage = await rotateImage(compressedImage);
|
||||
File processedImage = await rotateImageIfNeeded(File(croppedFile!.path));
|
||||
File compressedImage = await compressImage(processedImage);
|
||||
print('link =$link');
|
||||
try {
|
||||
await uploadImage(
|
||||
compressedImage,
|
||||
{
|
||||
'driverID':
|
||||
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
|
||||
'imageType': imageType
|
||||
'imageType': imageType,
|
||||
},
|
||||
link,
|
||||
);
|
||||
} catch (e) {
|
||||
print('Error in choosImage: $e');
|
||||
Get.snackbar('Image Upload Failed'.tr, e.toString(),
|
||||
backgroundColor: AppColor.redColor);
|
||||
backgroundColor: AppColor.primaryColor);
|
||||
} finally {
|
||||
isloading = false;
|
||||
update();
|
||||
|
||||
@@ -229,7 +229,7 @@ class HomeCaptainController extends GetxController {
|
||||
getAllPayment();
|
||||
startPeriodicExecution();
|
||||
onMapCreated(mapHomeCaptainController!);
|
||||
totalPoints = Get.find<CaptainWalletController>().totalPoints;
|
||||
totalPoints = Get.find<CaptainWalletController>().totalPoints.toString();
|
||||
getRefusedOrderByCaptain();
|
||||
// LocationController().getLocation();
|
||||
super.onInit();
|
||||
|
||||
@@ -26,8 +26,10 @@ class MapDriverController extends GetxController {
|
||||
bool isLoading = true;
|
||||
final formKey1 = GlobalKey<FormState>();
|
||||
final formKey2 = GlobalKey<FormState>();
|
||||
final formKeyCancel = GlobalKey<FormState>();
|
||||
final messageToPassenger = TextEditingController();
|
||||
final sosEmergincyNumberCotroller = TextEditingController();
|
||||
final cancelTripCotroller = TextEditingController();
|
||||
List data = [];
|
||||
List dataDestination = [];
|
||||
LatLngBounds? boundsData;
|
||||
@@ -165,6 +167,30 @@ class MapDriverController extends GetxController {
|
||||
update();
|
||||
}
|
||||
|
||||
cancelTripFromDriverAfterApplied() async {
|
||||
if (formKeyCancel.currentState!.validate()) {
|
||||
await CRUD().post(link: AppLink.updateRides, payload: {
|
||||
"id": rideId.toString(), // Convert to String
|
||||
"status": 'CancelFromDriverAfterApply'
|
||||
});
|
||||
await CRUD().post(link: AppLink.addCancelRideFromPassenger, payload: {
|
||||
"rideID": rideId.toString(),
|
||||
"driverID": box.read(BoxName.driverID).toString(),
|
||||
"passengerID": passengerId.toString(),
|
||||
"note": cancelTripCotroller.text.toString()
|
||||
});
|
||||
FirebaseMessagesController().sendNotificationToDriverMAP(
|
||||
"Cancel Trip from driver".tr,
|
||||
"Trip Cancelled from driver. We are looking for a new driver. Please wait."
|
||||
.tr,
|
||||
tokenPassenger,
|
||||
[],
|
||||
'cancel.wav',
|
||||
);
|
||||
Get.offAll(HomeCaptain());
|
||||
}
|
||||
}
|
||||
|
||||
void startTimerToShowPassengerInfoWindowFromDriver() async {
|
||||
if (box.read(BoxName.rideStatus) == 'Begin') {
|
||||
isPassengerInfoWindow = false;
|
||||
|
||||
@@ -33,6 +33,12 @@ class OrderRequestController extends GetxController {
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
getRideDEtailsForBackgroundOrder() async {
|
||||
await CRUD().get(link: AppLink.getRidesDetails, payload: {
|
||||
'id': box.read(BoxName.myList)[2].toString(),
|
||||
});
|
||||
}
|
||||
|
||||
void addCustomStartIcon() async {
|
||||
// Create the marker with the resized image
|
||||
|
||||
|
||||
@@ -106,18 +106,18 @@ class CaptainWalletController extends GetxController {
|
||||
update();
|
||||
var res = await CRUD().get(
|
||||
link: AppLink.getAllPaymentFromRide,
|
||||
payload: {'driverID': box.read(BoxName.driverID)},
|
||||
payload: {'driverID': box.read(BoxName.driverID).toString()},
|
||||
);
|
||||
// isLoading = false;
|
||||
if (res != 'failure') {
|
||||
walletDate = jsonDecode(res);
|
||||
totalAmount = walletDate['message'][0]['total_amount'] ?? '0';
|
||||
totalAmount = walletDate['message'][0]['total_amount'].toString();
|
||||
update();
|
||||
var res1 = await CRUD().get(
|
||||
link: AppLink.getAllPaymentVisa,
|
||||
payload: {'driverID': box.read(BoxName.driverID)});
|
||||
payload: {'driverID': box.read(BoxName.driverID).toString()});
|
||||
walletDateVisa = jsonDecode(res1);
|
||||
totalAmountVisa = walletDateVisa['message'][0]['diff'] ?? '0';
|
||||
totalAmountVisa = walletDateVisa['message'][0]['diff'].toString();
|
||||
|
||||
update();
|
||||
} else {
|
||||
@@ -132,12 +132,13 @@ class CaptainWalletController extends GetxController {
|
||||
|
||||
var res = await CRUD().get(
|
||||
link: AppLink.getDriverPaymentPoints,
|
||||
payload: {'driverID': box.read(BoxName.driverID)},
|
||||
payload: {'driverID': box.read(BoxName.driverID).toString()},
|
||||
);
|
||||
isLoading = false;
|
||||
// update();
|
||||
walletDriverPointsDate = jsonDecode(res);
|
||||
|
||||
if (res != 'failure') {
|
||||
walletDriverPointsDate = jsonDecode(res);
|
||||
double totalPointsDouble = double.parse(
|
||||
walletDriverPointsDate['message'][0]['total_amount'].toString());
|
||||
totalPoints = totalPointsDouble.toStringAsFixed(0);
|
||||
@@ -283,7 +284,7 @@ class CaptainWalletController extends GetxController {
|
||||
);
|
||||
if (res != 'failure') {
|
||||
var json = jsonDecode(res);
|
||||
kazan = double.parse(json['message'][0]['kazan']);
|
||||
kazan = double.parse(json['message'][0]['kazan'].toString());
|
||||
// naturePrice = double.parse(json['message'][0]['naturePrice']);
|
||||
// heavyPrice = double.parse(json['message'][0]['heavyPrice']);
|
||||
// latePrice = double.parse(json['message'][0]['latePrice']);
|
||||
|
||||
@@ -10,7 +10,7 @@ class LocaleController extends GetxController {
|
||||
String countryCode = '';
|
||||
void restartApp() {
|
||||
// Get.offAll(MyApp);
|
||||
runApp(const MyApp());
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
ThemeData appTheme = themeEnglish;
|
||||
|
||||
@@ -150,7 +150,29 @@ class MyTranslation extends Translations {
|
||||
"This driver is not registered": "هذا السائق غير مسجل",
|
||||
'insert amount': "أدخل المبلغ",
|
||||
"phone number of driver": "رقم هاتف السائق",
|
||||
"Transfer budget": "نقل الميزانية",
|
||||
"Transfer budget": "نقل الميزانية", "Comfort": "كمفورت",
|
||||
"Speed": "سبيد",
|
||||
"Lady": "ليدي", "Permission denied": "تم رفض الإذن",
|
||||
"Contact permission is required to pick a contact":
|
||||
"مطلوب إذن الوصول إلى جهات الاتصال لاختيار جهة اتصال",
|
||||
"No contact selected": "لم يتم تحديد جهة اتصال",
|
||||
"Please select a contact": "يرجى تحديد جهة اتصال",
|
||||
"No phone number": "لا يوجد رقم هاتف",
|
||||
"The selected contact does not have a phone number":
|
||||
"جهة الاتصال المحددة لا تحتوي على رقم هاتف",
|
||||
"Error": "خطأ",
|
||||
"An error occurred while picking a contact":
|
||||
"حدث خطأ أثناء اختيار جهة الاتصال",
|
||||
"Are you sure you want to cancel this trip?":
|
||||
"هل أنت متأكد من أنك تريد إلغاء هذه الرحلة؟",
|
||||
"Cancel Trip from driver": "إلغاء الرحلة من السائق",
|
||||
"Why do you want to cancel this trip?":
|
||||
"لماذا تريد إلغاء هذه الرحلة؟",
|
||||
"Write the reason for canceling the trip": "اكتب سبب الإلغاء:",
|
||||
"Trip Cancelled from driver. We are looking for a new driver. Please wait.":
|
||||
"تم إلغاء الرحلة من قبل السائق. نحن نبحث عن سائق جديد. من فضلك انتظر.",
|
||||
"Delivery": "توصيل",
|
||||
"Mashwari": "مشواري", "Total Net": "صافي الإجمالي",
|
||||
"Special Order": "طلب خاص",
|
||||
"Speed Order": "طلب سريع",
|
||||
"No data yet!": "لا توجد بيانات حتى الآن!",
|
||||
@@ -200,6 +222,7 @@ class MyTranslation extends Translations {
|
||||
"History Page": "سجل الرحلات ",
|
||||
"Finished": "مكتملة",
|
||||
"Trip Detail": "تفاصيل الرحلة",
|
||||
"Invite code already used": "تم استخدام رمز الدعوة بالفعل",
|
||||
"Price is": "السعر",
|
||||
"Times of Trip": "أوقات الرحلة",
|
||||
"Time to Passenger is": "الوقت للوصول للراكب",
|
||||
@@ -258,8 +281,17 @@ class MyTranslation extends Translations {
|
||||
"التقط صورة لرخصة سيارتك من الأمام",
|
||||
"Capture an Image of Your ID Document front":
|
||||
"التقاط صورة لوثيقة هويتك من الأمام",
|
||||
"NationalID": "الرقم الوطني",
|
||||
"NationalID": "الرقم الوطني", "reject your order.": "رفض طلبك.",
|
||||
"Order Under Review": "الطلب قيد المراجعة",
|
||||
"is reviewing your order. They may need more information or a higher price.":
|
||||
"يتم مراجعة طلبك. قد يحتاجون إلى مزيد من المعلومات أو سعر أعلى.",
|
||||
"FullName": "الاسم الكامل",
|
||||
"Enable Location Permission": "تمكين إذن الموقع",
|
||||
'Allowing location access will help us display orders near you. Please enable it now.':
|
||||
"سيساعدنا السماح بالوصول إلى الموقع في عرض الطلبات القريبة منك. يرجى تمكينه الآن.",
|
||||
"Allow overlay permission": "السماح بإذنالظهور فوق التطبيقات",
|
||||
"To display orders instantly, please grant permission to draw over other apps.":
|
||||
"لعرض الطلبات على الفور، يرجى منح إذن لرسم فوق التطبيقات الأخرى.",
|
||||
"InspectionResult": "نتيجة الفحص",
|
||||
"Criminal Record": "صحيفة الحالة الجنائية",
|
||||
"The email or phone number is already registered.":
|
||||
@@ -331,10 +363,13 @@ class MyTranslation extends Translations {
|
||||
"Invite sent successfully": "تم إرسال الدعوة بنجاح",
|
||||
"Failed to send invite": "فشل إرسال الدعوة",
|
||||
"An error occurred": "حدث خطأ",
|
||||
"Air Condition Trip": "رحلة تكييف ",
|
||||
"Passenger name: ": "اسم الراكب: ",
|
||||
"Criminal Document Required": "الفيش الجنائي مطلوب",
|
||||
"Criminal Document": "الفيش الجنائي",
|
||||
"Marital Status": "الحالة الاجتماعية",
|
||||
"Full Name (Marital)": "الاسم الكامل (الزوجي)",
|
||||
"Payment Method": "طريقة الدفع",
|
||||
"Expiration Date": "تاريخ الانتهاء",
|
||||
"Capture an Image of Your ID Document Back":
|
||||
"التقاط صورة للجهة الخلفية من وثيقة الهوية الخاصة بك",
|
||||
|
||||
@@ -4,6 +4,8 @@ import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
import '../../../print.dart';
|
||||
|
||||
class PaymobResponseWallet {
|
||||
final bool success;
|
||||
final String? transactionID;
|
||||
@@ -142,7 +144,7 @@ class PaymobPaymentWallet {
|
||||
}) async {
|
||||
final Map<String, dynamic> data = {
|
||||
"source": {
|
||||
"identifier": "01010101010", // Replace with actual source identifier
|
||||
"identifier": box.read(BoxName.phoneDriver).toString(),
|
||||
"subtype": "WALLET",
|
||||
},
|
||||
"payment_token": paymentToken,
|
||||
@@ -217,6 +219,7 @@ class PaymobPaymentWallet {
|
||||
),
|
||||
);
|
||||
final urlWallet = await _getWalletUrl(paymentToken: purchaseToken);
|
||||
Log.print('urlWallet: ${urlWallet}');
|
||||
|
||||
if (context.mounted) {
|
||||
final response = await PaymobIFrameWallet.show(
|
||||
|
||||
Reference in New Issue
Block a user