This commit is contained in:
Hamza-Ayed
2024-07-31 21:19:19 +03:00
parent dea83d970c
commit 2bc71355c3
106 changed files with 4600 additions and 727 deletions

View File

@@ -4,6 +4,9 @@ class BoxName {
static const String googlaMapApp = "googlaMapApp";
static const String lang = "lang";
static const String myListString = "myListString";
static const String myList = "myList";
static const String bodyOrder = "bodyOrder";
static const String gender = "gender";
static const String carType = "carType";
static const String isFirstTime = "isFirstTime";

View File

@@ -21,8 +21,9 @@ class AppColor {
// For dynamic elements like gradients
static List<Color> gradientStartEnd = [
const Color(0xFF1DA1F2), // Start with primary color
const Color(0xFF0C7ABF), // End with a slightly darker shade of Twitter blue
Color.fromARGB(255, 40, 158, 232), // Start with primary color
Color.fromARGB(
255, 44, 63, 75), // End with a slightly darker shade of Twitter blue
];
static List<Color> secondaryGradientStartEnd = [

View File

@@ -257,6 +257,9 @@ class AppLink {
static String sendmany = "https://sms.kazumi.me/api/sms/send-many";
static String checkCredit = "https://sms.kazumi.me/api/sms/check-credit";
static String checkStatus = "https://sms.kazumi.me/api/sms/check-status";
static String getSender = "$server/auth/sms/getSender.php";
static String updatePhoneInvalidSMS =
"$server/auth/sms/updatePhoneInvalidSMS.php";
//////////////service///////////

View File

@@ -10,29 +10,30 @@ class AppStyle {
fontSize: 40,
color: AppColor.accentColor,
fontFamily: box.read(BoxName.lang) == 'ar'
? 'mohanad'
: GoogleFonts.josefinSans().fontFamily);
// ?GoogleFonts.notoNaskhArabic().fontFamily
? GoogleFonts.notoNaskhArabic().fontFamily
: GoogleFonts.roboto().fontFamily);
static TextStyle headTitle2 = TextStyle(
fontWeight: FontWeight.bold,
fontSize: 26,
color: AppColor.writeColor,
fontFamily: box.read(BoxName.lang) == 'ar'
? 'mohanad'
: GoogleFonts.josefinSans().fontFamily);
? GoogleFonts.notoNaskhArabic().fontFamily
: GoogleFonts.roboto().fontFamily);
static TextStyle title = TextStyle(
fontWeight: FontWeight.normal,
fontSize: box.read(BoxName.lang) == 'ar' ? 14 : 16,
color: AppColor.writeColor,
fontFamily: box.read(BoxName.lang) == 'ar'
? 'mohanad'
: GoogleFonts.josefinSans().fontFamily);
? GoogleFonts.notoNaskhArabic().fontFamily
: GoogleFonts.roboto().fontFamily);
static TextStyle subtitle = TextStyle(
fontWeight: FontWeight.bold,
fontSize: 13,
color: AppColor.writeColor,
fontFamily: box.read(BoxName.lang) == 'ar'
? 'mohanad'
: GoogleFonts.josefinSans().fontFamily);
? GoogleFonts.notoNaskhArabic().fontFamily
: GoogleFonts.roboto().fontFamily);
static TextStyle number = const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
@@ -42,9 +43,9 @@ class AppStyle {
static BoxDecoration boxDecoration = const BoxDecoration(
boxShadow: [
BoxShadow(
color: AppColor.accentColor, blurRadius: 2, offset: Offset(1, 2)),
color: AppColor.accentColor, blurRadius: 5, offset: Offset(2, 4)),
BoxShadow(
color: AppColor.accentColor, blurRadius: 2, offset: Offset(-1, -1))
color: AppColor.accentColor, blurRadius: 5, offset: Offset(-2, -2))
],
color: AppColor.secondaryColor,
borderRadius: BorderRadius.all(
@@ -53,9 +54,13 @@ class AppStyle {
static BoxDecoration boxDecoration1 = const BoxDecoration(
boxShadow: [
BoxShadow(
color: AppColor.accentColor, blurRadius: 2, offset: Offset(1, 2)),
color: Color.fromARGB(255, 237, 230, 230),
blurRadius: 5,
offset: Offset(2, 4)),
BoxShadow(
color: AppColor.accentColor, blurRadius: 2, offset: Offset(-1, -1))
color: Color.fromARGB(255, 242, 237, 237),
blurRadius: 5,
offset: Offset(-2, -2))
],
color: AppColor.secondaryColor,
borderRadius: BorderRadius.all(

View File

@@ -6,4 +6,5 @@ class TableName {
static const String rideLocation = "rideLocation";
static const String faceDetectTimes = "faceDetectTimes";
static const String captainNotification = "captainNotification";
static const String applyRideFromOverLay = "applyRideFromOverLay";
}

View File

@@ -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');

View File

@@ -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());

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View 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");
}
}
}

View File

@@ -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),
),
],
),
),
);
}
}

View File

@@ -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)}');
}
}
}
}

View 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());
}
},
),
),
);
}
}

View File

@@ -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']);

View File

@@ -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

View File

@@ -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) {

View 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);
}

View File

@@ -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: '',

View File

@@ -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();

View File

@@ -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();

View File

@@ -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;

View File

@@ -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

View File

@@ -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']);

View File

@@ -10,7 +10,7 @@ class LocaleController extends GetxController {
String countryCode = '';
void restartApp() {
// Get.offAll(MyApp);
runApp(const MyApp());
runApp(MyApp());
}
ThemeData appTheme = themeEnglish;

View File

@@ -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":
"التقاط صورة للجهة الخلفية من وثيقة الهوية الخاصة بك",

View File

@@ -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(

View File

@@ -17,10 +17,7 @@ import 'package:flutter/foundation.dart'
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
@@ -28,15 +25,9 @@ class DefaultFirebaseOptions {
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
return macos;
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
return windows;
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
@@ -51,7 +42,7 @@ class DefaultFirebaseOptions {
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0',
appId: '1:594687661098:android:46557bd4f534b5bb595f53',
appId: '1:594687661098:android:b7ce96c17eb928ca595f53',
messagingSenderId: '594687661098',
projectId: 'ride-b1bd8',
storageBucket: 'ride-b1bd8.appspot.com',
@@ -63,8 +54,40 @@ class DefaultFirebaseOptions {
messagingSenderId: '594687661098',
projectId: 'ride-b1bd8',
storageBucket: 'ride-b1bd8.appspot.com',
iosClientId:
'594687661098-9fnj82nef9oagl98prigdf8qne3ddbto.apps.googleusercontent.com',
androidClientId: '594687661098-2dhoogl7be9phobfbu8bbg1sj567iv88.apps.googleusercontent.com',
iosClientId: '594687661098-9fnj82nef9oagl98prigdf8qne3ddbto.apps.googleusercontent.com',
iosBundleId: 'com.sefer.driver',
);
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyAVtyV7YVMeLbwA1UlNPxV9FhCzT0kjeAE',
appId: '1:594687661098:web:62d8388476ec91ec595f53',
messagingSenderId: '594687661098',
projectId: 'ride-b1bd8',
authDomain: 'ride-b1bd8.firebaseapp.com',
storageBucket: 'ride-b1bd8.appspot.com',
measurementId: 'G-Y3HFEC6F4N',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyCf2mW2h0HD8ZYjwh4VOa2ladw6MJkCDTM',
appId: '1:594687661098:ios:6f69eee1449be943595f53',
messagingSenderId: '594687661098',
projectId: 'ride-b1bd8',
storageBucket: 'ride-b1bd8.appspot.com',
androidClientId: '594687661098-2dhoogl7be9phobfbu8bbg1sj567iv88.apps.googleusercontent.com',
iosClientId: '594687661098-8e26699cris2k3nj5msj1osi59it9kpf.apps.googleusercontent.com',
iosBundleId: 'com.mobileapp.store.ride',
);
static const FirebaseOptions windows = FirebaseOptions(
apiKey: 'AIzaSyAVtyV7YVMeLbwA1UlNPxV9FhCzT0kjeAE',
appId: '1:594687661098:web:d9f43a2091395d87595f53',
messagingSenderId: '594687661098',
projectId: 'ride-b1bd8',
authDomain: 'ride-b1bd8.firebaseapp.com',
storageBucket: 'ride-b1bd8.appspot.com',
measurementId: 'G-C3DWQ8Z062',
);
}

View File

@@ -1,68 +1,125 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/payment/paymob/paymob_response.dart';
import 'package:SEFER/views/home/Captin/orderCaptin/order_request_page.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'constant/api_key.dart';
import 'constant/credential.dart';
import 'constant/info.dart';
import 'controller/firebase/firbase_messge.dart';
import 'controller/firebase/local_notification.dart';
import 'controller/functions/location_controller.dart';
import 'controller/functions/overlay_permisssion.dart';
import 'controller/local/local_controller.dart';
import 'controller/local/translations.dart';
import 'controller/payment/paymob/paymob_wallet.dart';
import 'firebase_options.dart';
import 'models/db_sql.dart';
import 'print.dart';
import 'splash_screen_page.dart';
import 'views/home/Captin/orderCaptin/order_request_page.dart';
import 'views/home/Captin/orderCaptin/order_over_lay.dart';
final box = GetStorage();
const storage = FlutterSecureStorage();
final PaymobPayment paymobPayment = PaymobPayment();
final PaymobPaymentWallet paymobPaymentWallet = PaymobPaymentWallet();
DbSql sql = DbSql.instance;
@pragma('vm:entry-point')
Future<void> backgroundMessageHandler(RemoteMessage message) async {
await Firebase.initializeApp();
if (message.data.isNotEmpty && message.notification != null) {
FirebaseMessagesController().fireBaseTitles(message);
if (Platform.isAndroid) {
if (message.notification != null && message.notification!.title != null) {
if (message.notification?.title == 'Order') {
var myListString = message.data['DriverList'] ?? '[]';
Log.print('myListString: $myListString');
// Decode the JSON string to a list
var myList;
try {
myList = jsonDecode(myListString) as List<dynamic>;
} catch (e) {
Log.print('Error decoding JSON: $e');
myList = [];
}
Future.delayed(const Duration(seconds: 1));
NotificationController().showNotification(
message.notification!.title.toString(),
message.notification!.body.toString(),
'order',
myListString,
);
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(myList);
// Bubble().startBubbleHead(sendAppToBackground: true);
}
} else {
FirebaseMessagesController().fireBaseTitles(message);
}
}
}
Future<void> handleBackgroundNotificationClick(RemoteMessage message) async {
await Firebase.initializeApp();
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
var myListString = message.data['DriverList'];
var myList = jsonDecode(myListString) as List<dynamic>;
@pragma('vm:entry-point')
void overlayMain() async {
WidgetsFlutterBinding.ensureInitialized();
Get.to(() => OrderRequestPage(), arguments: {
'myListString': myListString,
'DriverList': myList,
'body': message.notification?.body,
});
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: OrderOverlay(),
));
}
void closeOverLay() {
FlutterOverlayWindow.closeOverlay();
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
WakelockPlus.enable();
await LocationController().startLocationUpdates();
if (Platform.isAndroid) {
await NotificationController().initNotifications();
// Request location permission first
PermissionStatus status = await Permission.location.request();
if (status.isDenied) {
WidgetsBinding.instance.addPostFrameCallback((_) {
getPermissionLocation();
});
// Handle the case when permission is denied
// You might want to show a dialog explaining why the permission is needed
return;
}
// Set up the overlay entry point
// FlutterOverlayWindow.overlayMain = overlayMain;
await LocationController().startLocationUpdates();
await GetStorage.init();
Stripe.publishableKey = AK.publishableKeyStripe;
if (Platform.isAndroid || Platform.isIOS) {
@@ -72,7 +129,7 @@ void main() async {
await FirebaseMessagesController().requestFirebaseMessagingPermission();
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
NotificationController().initNotifications();
List<Future> initializationTasks = [
FirebaseMessagesController().getNotificationSettings(),
FirebaseMessagesController().getToken(),
@@ -98,24 +155,35 @@ void main() async {
iFrameID: 837992,
);
runApp(const MyApp());
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
MyApp({super.key});
@override
Widget build(BuildContext context) {
LocaleController localController = Get.put(LocaleController());
// checkForUpdate(context);
return GetMaterialApp(
title: AppInformation.appName,
translations: MyTranslation(),
debugShowCheckedModeBanner: false,
locale: localController.language,
theme: localController.appTheme,
key: UniqueKey(),
initialRoute: '/',
home: SplashScreen());
navigatorKey: navigatorKey,
title: AppInformation.appName,
translations: MyTranslation(),
debugShowCheckedModeBanner: false,
locale: localController.language,
theme: localController.appTheme,
key: UniqueKey(),
initialRoute: '/',
// home: SplashScreen(),
routes: {
'/order': (context) => OrderRequestPage(),
},
getPages: [
GetPage(name: '/', page: () => SplashScreen()),
GetPage(
name: '/order-page',
page: () => OrderRequestPage(),
arguments: box.read(BoxName.rideArguments)),
],
);
}
}

View File

@@ -78,6 +78,47 @@ class DbSql {
faceDetectTimes INTEGER
)
''');
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.applyRideFromOverLay}(
id INTEGER PRIMARY KEY AUTOINCREMENT,
start_location_lat TEXT,
start_location_lng TEXT,
end_location_lat TEXT,
end_location_lng TEXT,
total_passenger TEXT,
total_driver TEXT,
duration_to_ride TEXT,
distance TEXT,
driver_id TEXT,
passenger_id TEXT,
passenger_name TEXT,
passenger_token_fcm TEXT,
passenger_phone TEXT,
duration_by_passenger TEXT,
distance_by_passenger TEXT,
is_wallet_checked TEXT,
driver_token TEXT,
duration_to_passenger TEXT,
ride_id TEXT,
ride_timer_begin TEXT,
driver_id_duplicate TEXT,
duration_to_ride_duplicate TEXT,
way_points TEXT,
place_coordinate_0 TEXT,
place_coordinate_1 TEXT,
place_coordinate_2 TEXT,
place_coordinate_3 TEXT,
place_coordinate_4 TEXT,
cost_for_driver TEXT,
passenger_wallet_total TEXT,
passenger_email TEXT,
start_name_address TEXT,
end_name_address TEXT,
car_type TEXT,
kazan TEXT,
passenger_rate TEXT
)
''');
},
);
}

View File

@@ -25,11 +25,24 @@ class InviteDriverScreen extends StatelessWidget {
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 20),
MyTextForm(
controller: controller.invitePhoneController,
label: 'Enter driver\'s phone'.tr,
hint: 'Enter driver\'s phone'.tr,
type: TextInputType.phone),
Row(
children: [
Expanded(
child: MyTextForm(
controller: controller.invitePhoneController,
label: 'Enter driver\'s phone'.tr,
hint: 'Enter driver\'s phone'.tr,
type: TextInputType.phone,
),
),
IconButton(
icon: Icon(Icons.contacts),
onPressed: () async {
await controller.pickContact();
},
),
],
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
@@ -49,7 +62,6 @@ class InviteDriverScreen extends StatelessWidget {
const SizedBox(height: 20),
GetBuilder<InviteController>(builder: (controller) {
return SizedBox(
// decoration: AppStyle.boxDecoration,
height: Get.height * .4,
child: controller.driverInvitationData.isEmpty
? Center(
@@ -61,7 +73,6 @@ class InviteDriverScreen extends StatelessWidget {
: ListView.builder(
itemCount: controller.driverInvitationData.length,
itemBuilder: (context, index) {
// Ensure the 'countOfInvitDriver' key exists and is parseable as an int
int countOfInvitDriver = 0;
if (controller.driverInvitationData[index]
.containsKey('countOfInvitDriver')) {
@@ -72,25 +83,24 @@ class InviteDriverScreen extends StatelessWidget {
0;
}
// Calculate the progress value, ensuring it is between 0 and 1
double progressValue = countOfInvitDriver / 100.0;
if (progressValue > 1.0) progressValue = 1.0;
if (progressValue < 0.0) progressValue = 0.0;
return Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
child: Stack(
alignment: AlignmentDirectional.center,
children: [
InkWell(
onTap: () async {
controller.onSelectDriverInvitation(index);
},
child: Container(
return InkWell(
onTap: () async {
controller.onSelectDriverInvitation(index);
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
child: Stack(
alignment: AlignmentDirectional.center,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: AppColor.accentColor.withOpacity(
.5), // Background color of the container
color:
AppColor.accentColor.withOpacity(.5),
),
width: Get.width * .85,
child: ClipRRect(
@@ -104,10 +114,11 @@ class InviteDriverScreen extends StatelessWidget {
),
),
),
),
Text(
'${controller.driverInvitationData[index]['invitorName']} ${controller.driverInvitationData[index]['countOfInvitDriver']} / 100 ${'Trip'.tr}'),
],
Text(
'${controller.driverInvitationData[index]['invitorName']} ${controller.driverInvitationData[index]['countOfInvitDriver']} / 100 ${'Trip'.tr}',
),
],
),
),
);
},

View File

@@ -5,8 +5,10 @@ import 'package:get/get.dart';
import 'package:SEFER/controller/home/captin/map_driver_controller.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import '../../../constant/colors.dart';
import '../../../controller/functions/location_controller.dart';
import '../../Rate/rate_passenger.dart';
import '../../widgets/my_textField.dart';
import 'mapDriverWidgets/driver_end_ride_bar.dart';
import 'mapDriverWidgets/google_driver_map_page.dart';
import 'mapDriverWidgets/google_map_app.dart';
@@ -36,6 +38,7 @@ class PassengerLocationMapPage extends StatelessWidget {
body: [
GoogleDriverMap(locationController: locationController),
const PassengerInfoWindow(),
CancelWidget(mapDriverController: mapDriverController),
driverEndRideBar(),
const SosConnect(),
speedCircle(),
@@ -46,6 +49,70 @@ class PassengerLocationMapPage extends StatelessWidget {
}
}
class CancelWidget extends StatelessWidget {
const CancelWidget({
super.key,
required this.mapDriverController,
});
final MapDriverController mapDriverController;
@override
Widget build(BuildContext context) {
return Positioned(
top: 10,
left: 5,
child: GestureDetector(
onTap: () {
Get.defaultDialog(
title: "Are you sure you want to cancel this trip?".tr,
titleStyle: AppStyle.title,
content: Column(
children: [
Text("Why do you want to cancel this trip?".tr),
Form(
key: mapDriverController.formKeyCancel,
child: MyTextForm(
controller: mapDriverController.cancelTripCotroller,
label: "Write the reason for canceling the trip".tr,
hint: "Write the reason for canceling the trip".tr,
type: TextInputType.name,
))
],
),
confirm: MyElevatedButton(
title: 'OK'.tr,
onPressed: () async {
// todo add cancel and inform passenger to get new driver
await mapDriverController
.cancelTripFromDriverAfterApplied();
Get.back();
}),
cancel: MyElevatedButton(
title: 'NO'.tr,
kolor: AppColor.redColor,
onPressed: () {
Get.back();
}));
},
child: Container(
decoration: BoxDecoration(
color: AppColor.redColor,
borderRadius: BorderRadius.circular(15)),
child: const Padding(
padding: EdgeInsets.all(3),
child: Icon(
Icons.clear,
size: 40,
color: AppColor.secondaryColor,
),
),
),
),
);
}
}
class PricesWindow extends StatelessWidget {
const PricesWindow({
super.key,

View File

@@ -1,5 +1,6 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/home/captin/map_driver_controller.dart';
import 'package:SEFER/views/notification/available_rides_page.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
@@ -12,6 +13,7 @@ import '../../../../constant/info.dart';
import '../../../../constant/style.dart';
import '../../../../constant/table_names.dart';
import '../../../../controller/functions/location_controller.dart';
import '../../../../controller/functions/overlay_permisssion.dart';
import '../../../../controller/functions/package_info.dart';
import '../../../../controller/home/captin/home_captain_controller.dart';
import '../../../../controller/home/captin/order_request_controller.dart';
@@ -32,8 +34,10 @@ class HomeCaptain extends StatelessWidget {
Widget build(BuildContext context) {
Get.put(OrderRequestController());
Get.put(HomeCaptainController());
Get.put(CaptainWalletController());
WidgetsBinding.instance.addPostFrameCallback((_) {
checkForUpdate(context);
// checkForUpdate(context);
getPermissionOverlay();
_showFirstTimeOfferNotification(context);
});
return Scaffold(
@@ -240,6 +244,28 @@ class HomeCaptain extends StatelessWidget {
// ),
// ),
// ),
Positioned(
bottom: Get.height * .3,
right: 6,
child: AnimatedContainer(
duration: const Duration(microseconds: 200),
width: homeCaptainController.widthMapTypeAndTraffic,
decoration: BoxDecoration(
border: Border.all(color: AppColor.blueColor),
color: AppColor.secondaryColor,
borderRadius: BorderRadius.circular(15)),
child: IconButton(
onPressed: () {
Get.to(() => AvailableRidesPage());
},
icon: const Icon(
Icons.train_sharp,
size: 29,
color: AppColor.blueColor,
),
),
),
),
leftMainMenuCaptainIcons(),
box.read(BoxName.rideStatus) == 'Applied' ||
box.read(BoxName.rideStatus) == 'Begin'
@@ -401,8 +427,8 @@ void _showFirstTimeOfferNotification(BuildContext context) {
),
),
onPressed: () {
Navigator.of(context).pop();
_markAsNotFirstTime();
Navigator.of(context).pop();
},
),
],
@@ -416,7 +442,7 @@ void _showFirstTimeOfferNotification(BuildContext context) {
}
bool _checkIfFirstTime() {
if (box.read(BoxName.isFirstTime) == null) {
if (box.read(BoxName.isFirstTime).toString() == '') {
return true;
} else {
return false;
@@ -424,5 +450,5 @@ bool _checkIfFirstTime() {
}
void _markAsNotFirstTime() {
box.write(BoxName.isFirstTime, false);
box.write(BoxName.isFirstTime, 'false');
}

View File

@@ -2,14 +2,15 @@ import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:get/get.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../../../../../constant/colors.dart';
import '../../../../../print.dart';
import '../../../../Rate/ride_calculate_driver.dart';
import '../../../../../controller/functions/location_controller.dart';
import '../../../../auth/captin/cards/egypt_card_a_i.dart';
GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
return GetBuilder<HomeCaptainController>(
@@ -168,16 +169,125 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
// color: AppColor.secondaryColor,
// border: Border.all(color: AppColor.blueColor),
// borderRadius: BorderRadius.circular(15)),
// child: IconButton(
// onPressed: () async {
// Get.to(() => EgyptCardAI());
// },
// icon: const Icon(
// FontAwesome5.grin_tears,
// size: 29,
// color: AppColor.blueColor,
// ),
// ),
// child: Builder(builder: (context) {
// return IconButton(
// onPressed: () async {
// // Get.to(() => EgyptCardAI());
// // print(box.read(BoxName.myList));
//
// List<String> d = [
// "30.003028,31.2419628",
// "30.0955661,31.2665336",
// "160.00",
// "25.92",
// "1488",
// "16.93",
// "114243034311436865474",
// "113172279072358305645",
// "hamza ayed",
// "c9kqjnLqu08yogitln6B1Y:APA91bHyFJ7E7zv6-HIikwr6FrlMbi4Hc8L1STMPE99iPKqK4Gddwv8r9qZOCadsz9qTEJZ6KLEE9ruTJI6N8dKfK4CXez5pme5WIs14-1QGo29s07fQOniZgIlJV5XFL3yqzPRSUmn3",
// "+201023248456",
// "1 min",
// "1 m",
// "false",
// "em3j-v3PQlecGsTKFNU1wc:APA91bFjHq8xHpzeQwUMoyUtZ0J3oR6yXKUavrB_gBl9npUZe-qZtax-Raq4QBbdKv0AmtLKm0BfBd6N_592HBv4CVa41ii4122W3hr-BCUKKzJhzZcK8m0YjbWbtpvgJRD8uD_nuMk9",
// "0",
// "238",
// "false",
// "114243034311436865474",
// "1488",
// "startEnd",
// "30.049307749732176,31.274291574954987",
// "",
// "",
// "",
// "",
// "17.73",
// "0",
// "hamzaayedflutter@gmail.com",
// "الفسطاط، حي مصر القديمة، مصر",
// " الزاوية الحمراء، محافظة القاهرة، مصر",
// "Speed",
// "8",
// "5.00"
// ];
//
// try {
// print('Before showing overlay: ${box.read('some_key')}');
//
// // Ensure any existing overlay is closed before showing a new one
//
// bool isOverlayActive =
// await FlutterOverlayWindow.isActive();
// if (isOverlayActive) {
// await FlutterOverlayWindow.closeOverlay();
// }
// await FlutterOverlayWindow.showOverlay(
// enableDrag: true,
// overlayTitle: d[0],
// overlayContent: d[1],
// flag: OverlayFlag.focusPointer,
// visibility: NotificationVisibility.visibilityPublic,
// positionGravity: PositionGravity.auto,
// height: 700,
// width: WindowSize.matchParent,
// startPosition: const OverlayPosition(0, -170),
// );
//
// await FlutterOverlayWindow.shareData(d);
//
// print('After showing overlay: ${box.read('some_key')}');
// } catch (e) {
// print('Error showing overlay: $e');
// }
// // final Bubble _bubble = Bubble(showCloseButton: true);
// // try {
// // await _bubble.startBubbleHead(sendAppToBackground: false);
// // } on PlatformException {
// // print('Failed to call startBubbleHead');
// // }
//
// // Bubble().startBubbleHead(sendAppToBackground: true);
// // }
//
// // Future<void> stopBubbleHead() async {
// // try {
// // await _bubble.stopBubbleHead();
// // } on PlatformException {
// // print('Failed to call stopBubbleHead');
// // }
// // }
//
// // // send data to ovelay
// },
// icon: const Icon(
// FontAwesome5.grin_tears,
// size: 29,
// color: AppColor.blueColor,
// ),
// );
// }),
// ),
// AnimatedContainer(
// duration: const Duration(microseconds: 200),
// width: controller.widthMapTypeAndTraffic,
// decoration: BoxDecoration(
// color: AppColor.secondaryColor,
// border: Border.all(color: AppColor.blueColor),
// borderRadius: BorderRadius.circular(15)),
// child: Builder(builder: (context) {
// return IconButton(
// onPressed: () async {
// // Log.print('box: ${box.read(BoxName.rideStatus)}');
// Log.print('box: ${box.read(BoxName.tokenDriver)}');
// },
// icon: const Icon(
// FontAwesome5.closed_captioning,
// size: 29,
// color: AppColor.blueColor,
// ),
// );
// }),
// ),
],
)),

View File

@@ -9,10 +9,8 @@ import 'package:SEFER/controller/firebase/firbase_messge.dart';
import 'package:SEFER/controller/home/captin/map_driver_controller.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import '../../../../constant/box_name.dart';
import '../../../../constant/style.dart';
import '../../../../controller/functions/launch.dart';
import '../../../../main.dart';
class PassengerInfoWindow extends StatelessWidget {
const PassengerInfoWindow({
@@ -57,13 +55,6 @@ class PassengerInfoWindow extends StatelessWidget {
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
IconButton(
onPressed: () {
print(box
.read(BoxName.rideStatus));
},
icon: const Icon(Icons.add),
),
GestureDetector(
onTap: () async {
controller.isSocialPressed =

View File

@@ -0,0 +1,314 @@
import 'dart:async';
import 'package:SEFER/constant/colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart';
import '../../../../constant/box_name.dart';
import '../../../../constant/style.dart';
import '../../../../main.dart';
class OrderOverlay extends StatefulWidget {
const OrderOverlay({Key? key}) : super(key: key);
@override
State<OrderOverlay> createState() => _OrderOverlayState();
}
class _OrderOverlayState extends State<OrderOverlay>
with WidgetsBindingObserver {
List d = [];
Timer? _timer;
double _progress = 1.0;
bool _isOverlayActive = false;
final AudioPlayer _audioPlayer = AudioPlayer();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_setupOverlayListener();
}
void _setupOverlayListener() {
FlutterOverlayWindow.overlayListener.listen((event) {
if (mounted) {
setState(() {
d = event;
_resetAndStartTimer();
});
}
});
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
_checkOverlayStatus();
}
}
void _checkOverlayStatus() async {
bool isActive = await FlutterOverlayWindow.isActive();
if (isActive && mounted) {
_resetAndStartTimer();
}
}
void _resetAndStartTimer() {
_timer?.cancel();
setState(() {
_progress = 1.0;
_isOverlayActive = true;
});
_playAudio();
_startTimer();
}
void _startTimer() {
_timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
if (!_isOverlayActive) {
timer.cancel();
_stopAudio();
return;
}
if (mounted) {
setState(() {
_progress -=
1 / 100; // Decrease progress over 15 seconds (150 * 100ms)
if (_progress <= 0) {
timer.cancel();
_rejectOrder();
_stopAudio();
}
});
}
});
}
void _playAudio() async {
try {
await _audioPlayer.setAsset(
'assets/order.mp3',
preload: true,
initialPosition: Duration.zero,
);
await _audioPlayer.play();
} catch (e) {
print('An error occurred while playing the audio: $e');
}
}
void _stopAudio() {
_audioPlayer.stop();
}
@override
void dispose() {
_timer?.cancel();
_stopAudio();
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
String duration = (double.parse(d[4].toString()) / 60).toStringAsFixed(0);
String price = d[2].toString().split('.')[0];
return Material(
color: Colors.transparent,
child: Center(
child: Container(
padding: const EdgeInsets.all(12.0),
width: double.infinity,
height: 450, // Adjust height as needed
decoration: BoxDecoration(
gradient: const LinearGradient(colors: [
AppColor.blueColor,
AppColor.blueColor,
]),
borderRadius: BorderRadius.circular(12.0),
),
child: GestureDetector(
onTap: () async {
bool isOverlayActive = await FlutterOverlayWindow.isActive();
if (isOverlayActive) {
await FlutterOverlayWindow.closeOverlay();
}
},
child: ListView(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ListTile(
leading: _buildPriceAvatar(price),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
d.isNotEmpty ? d[8] : '', // Customer name
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: AppColor.secondaryColor,
),
),
Container(
decoration: BoxDecoration(
border: Border.all(
color: AppColor.redColor, width: 2)),
child: Padding(
padding: const EdgeInsets.all(3),
child: Text(
"${d[5]} KM",
style: AppStyle.number.copyWith(
color: AppColor.secondaryColor, fontSize: 18),
),
)),
const Text('🛣️')
],
),
// subtitle: Text(d.isNotEmpty ? d[10] : ''), // Phone number
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildDetailRow("🟢", d.isNotEmpty ? d[29] : ''),
_buildDetailRow("🔴".tr, d.isNotEmpty ? d[30] : ''),
_buildDetailRow(
"‏المسافة للراكب", d.isNotEmpty ? d[12] : ''),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildDetailRow("‏مدة الرحلة".tr, '$duration '),
_buildDetailRow("‏نوع الطلب".tr, _getRideType(d[31]))
],
),
const SizedBox(
height: 30,
),
const SizedBox(height: 8),
LinearProgressIndicator(
value: _progress,
minHeight: 15,
backgroundColor: Colors.white.withOpacity(0.3),
valueColor:
const AlwaysStoppedAnimation<Color>(Colors.white),
),
],
),
],
),
),
),
),
);
}
Widget _buildDetailRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 2.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
value,
style: AppStyle.title.copyWith(color: AppColor.secondaryColor),
),
Text(
label,
style: const TextStyle(
fontWeight: FontWeight.bold, color: AppColor.secondaryColor),
),
],
),
);
}
Widget _buildPriceAvatar(String price) {
return Container(
width: 80,
height: 80,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: const RadialGradient(
colors: [Color(0xFF4CAF50), Color(0xFF2E7D32)],
center: Alignment.center,
radius: 0.8,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 8,
offset: const Offset(0, 4),
),
],
),
child: Center(
child: Text(
'\$$price',
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
);
}
Widget _buildInfoRow(IconData icon, String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: [
Icon(icon, color: Colors.white.withOpacity(0.8), size: 24),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: TextStyle(
color: Colors.white.withOpacity(0.8), fontSize: 14),
),
Text(
value,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold),
),
],
),
),
],
),
);
}
String _getRideType(String type) {
switch (type) {
case 'Comfort':
return '‏كمفورت ❄️';
case 'Lady':
return '‏ليدي 👩';
case 'Speed':
return '‏‏‏سبيد 🔻';
case 'Mashwari':
return '‏مشواري';
case 'Rayeh Gai':
return 'رايح جاي';
default:
return '';
}
}
void _rejectOrder() async {
box.write(BoxName.rideStatus, 'reject');
bool isOverlayActive = await FlutterOverlayWindow.isActive();
if (isOverlayActive) {
await FlutterOverlayWindow.closeOverlay();
}
}
}

View File

@@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:SEFER/views/widgets/mydialoug.dart';
import 'package:flutter/material.dart';
@@ -23,23 +25,36 @@ class OrderRequestPage extends StatelessWidget {
Get.put(OrderRequestController());
@override
Widget build(BuildContext context) {
//TODO show order from start page from sql or api
final arguments = Get.arguments;
final myListString = arguments['myListString'];
final myList = arguments['DriverList'];
var myList;
// Check if 'DriverList' is null or empty
if (arguments['DriverList'] == null || arguments['DriverList'].isEmpty) {
myList = jsonDecode(myListString);
} else {
myList = arguments['DriverList'];
}
// final pointsList = arguments['PolylineJson'];
final body = arguments['body'];
// final body = arguments['body'];
Duration durationToAdd = Duration(seconds: int.parse(myList[4]));
int hours = durationToAdd.inHours;
int minutes = (durationToAdd.inMinutes % 60).round();
orderRequestController.startTimer(myList[6].toString(), body.toString());
var coords = myList[0].split(',');
var coordDestination = myList[1].split(',');
orderRequestController.startTimer(
myList[6].toString(),
myList[16].toString(),
);
var cords = myList[0].split(',');
var cordDestination = myList[1].split(',');
// Parse to double
double latPassengerLocation = double.parse(coords[0]);
double lngPassengerLocation = double.parse(coords[1]);
double latPassengerDestination = double.parse(coordDestination[0]);
double lngPassengerDestination = double.parse(coordDestination[1]);
double latPassengerLocation = double.parse(cords[0]);
double lngPassengerLocation = double.parse(cords[1]);
double latPassengerDestination = double.parse(cordDestination[0]);
double lngPassengerDestination = double.parse(cordDestination[1]);
List<LatLng> pointsDirection = [
LatLng(latPassengerLocation, lngPassengerLocation),
@@ -71,378 +86,422 @@ class OrderRequestPage extends StatelessWidget {
body: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: ListView(
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
// SizedBox(height: 200, child: Text(pointsList.toString())),
// Text(message.notification!.body.toString()),
SizedBox(
height: Get.height * .33,
child: GoogleMap(
initialCameraPosition: CameraPosition(
zoom: 12,
target: Get.find<HomeCaptainController>().myLocation),
cameraTargetBounds: CameraTargetBounds(bounds),
myLocationButtonEnabled: true,
trafficEnabled: true,
buildingsEnabled: true,
mapToolbarEnabled: true,
myLocationEnabled: true,
markers: {
Marker(
markerId: MarkerId('MyLocation'.tr),
position: LatLng(
latPassengerLocation, lngPassengerLocation),
draggable: true,
icon: orderRequestController.startIcon),
Marker(
markerId: MarkerId('Destination'.tr),
position: LatLng(
latPassengerDestination, lngPassengerDestination),
draggable: true,
icon: orderRequestController.endIcon),
},
polylines: {
Polyline(
zIndex: 1,
consumeTapEvents: true,
geodesic: true,
endCap: Cap.buttCap,
startCap: Cap.buttCap,
visible: true,
polylineId: const PolylineId('routeOrder'),
points: pointsDirection,
color: AppColor.primaryColor,
width: 2,
),
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 3,
color: myList[20].toString() == 'haveSteps'
? AppColor.greenColor
: AppColor.secondaryColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton.icon(
onPressed: () {
String mapUrl =
'https://www.google.com/maps/dir/${myList[0]}/${myList[1]}/';
showInBrowser(mapUrl);
},
icon: const Icon(Icons.map),
label: myList[20].toString() == 'haveSteps'
? Text(
'Trip has Steps'.tr,
style: AppStyle.title,
)
: Text('Routs of Trip'.tr,
style: AppStyle.title)),
Container(
color: myList[13].toString() == 'true'
? AppColor.deepPurpleAccent
: AppColor.greenColor,
child: myList[13].toString() ==
'true' //Visa or Cash Method from notify to driver
? Text(
'Visa',
style: AppStyle.title,
)
: Text('Cash', style: AppStyle.title),
)
],
child: Container(
color: const Color.fromARGB(255, 210, 201, 201),
child: ListView(
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
// SizedBox(height: 200, child: Text(pointsList.toString())),
// Text(message.notification!.body.toString()),
SizedBox(
height: Get.height * .33,
child: GoogleMap(
initialCameraPosition: CameraPosition(
zoom: 12,
target: Get.find<HomeCaptainController>().myLocation),
cameraTargetBounds: CameraTargetBounds(bounds),
myLocationButtonEnabled: true,
trafficEnabled: true,
buildingsEnabled: true,
mapToolbarEnabled: true,
myLocationEnabled: true,
markers: {
Marker(
markerId: MarkerId('MyLocation'.tr),
position: LatLng(
latPassengerLocation, lngPassengerLocation),
draggable: true,
icon: orderRequestController.startIcon),
Marker(
markerId: MarkerId('Destination'.tr),
position: LatLng(latPassengerDestination,
lngPassengerDestination),
draggable: true,
icon: orderRequestController.endIcon),
},
polylines: {
Polyline(
zIndex: 1,
consumeTapEvents: true,
geodesic: true,
endCap: Cap.buttCap,
startCap: Cap.buttCap,
visible: true,
polylineId: const PolylineId('routeOrder'),
points: pointsDirection,
color: AppColor.primaryColor,
width: 2,
),
},
),
),
),
Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 3,
color: myList[20].toString() == 'haveSteps'
? AppColor.greenColor
: AppColor.secondaryColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
double.parse(myList[2]).toStringAsFixed(2),
style: AppStyle.headTitle2,
),
AnimatedContainer(
duration: const Duration(seconds: 5),
curve: Curves.easeInOut,
child: AnimatedSize(
TextButton.icon(
onPressed: () {
String mapUrl =
'https://www.google.com/maps/dir/${myList[0]}/${myList[1]}/';
showInBrowser(mapUrl);
},
icon: const Icon(Icons.map),
label: myList[20].toString() == 'haveSteps'
? Text(
'Trip has Steps'.tr,
style: AppStyle.title,
)
: Text('Payment Method'.tr,
style: AppStyle.title)),
Container(
decoration: AppStyle.boxDecoration.copyWith(
color: myList[13].toString() == 'true'
? AppColor.deepPurpleAccent
: AppColor.greenColor,
),
child: myList[13].toString() ==
'true' //Visa or Cash Method from notify to driver
? Text(
'Visa',
style: AppStyle.title,
)
: Text('Cash', style: AppStyle.title),
)
],
),
),
),
Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
double.parse(myList[2]).toStringAsFixed(2),
style: AppStyle.headTitle2,
),
AnimatedContainer(
duration: const Duration(seconds: 5),
curve: Curves.easeInOut,
child: myList[31].toString() == 'Comfort'
? const Icon(
Icons.ac_unit,
color: AppColor.blueColor,
size: 50,
)
: const SizedBox(),
child: AnimatedSize(
duration: const Duration(seconds: 5),
curve: Curves.easeInOut,
child: myList[31].toString() == 'Comfort'
? Column(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
const Icon(
Icons.ac_unit,
color: AppColor.blueColor,
size: 50,
),
Text(
'Air condition Trip'.tr,
style: AppStyle.subtitle,
),
],
)
: const SizedBox(),
),
),
),
Text(
myList[31].toString(),
style: AppStyle.title
.copyWith(color: AppColor.greenColor),
),
],
)),
),
Container(
height: Get.height * .15,
width: Get.width * .9,
decoration: AppStyle.boxDecoration1,
child: ListView(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Icon(
Icons.arrow_circle_up,
color: AppColor.greenColor,
),
Text(
myList[12] + ' ' + ' (${myList[11]}) ',
style: AppStyle.title,
),
],
),
Text(
myList[29],
style: AppStyle.title,
),
],
),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Icon(
Icons.arrow_circle_up,
color: AppColor.greenColor,
),
Text(
myList[5] + ' ' + ' (${myList[4]}) ',
style: AppStyle.title,
),
],
),
Text(
myList[30],
style: AppStyle.title,
),
],
),
],
Text(
myList[31].toString().tr,
style: AppStyle.title
.copyWith(color: AppColor.greenColor),
),
],
)),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RichText(
text: TextSpan(
text: 'Passenger name : '
.tr, // Changed text to be more generic
style: AppStyle.subtitle,
children: [
TextSpan(
text: myList[8],
style: AppStyle
.title), // Assuming myList[8] holds passenger name
TextSpan(text: ' (', style: AppStyle.subtitle),
TextSpan(
text: myList[33].toString(),
style: AppStyle
.title), // Assuming 'rate' holds the passenger rate
TextSpan(text: ' ⭐)', style: AppStyle.subtitle),
],
const SizedBox(
height: 5,
),
Container(
height: Get.height * .15,
width: Get.width * .9,
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 5, vertical: 1),
child: ListView(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Icon(
Icons.arrow_circle_up,
color: AppColor.greenColor,
),
Text(
myList[12] + ' ' + ' (${myList[11]}) ',
style: AppStyle.title,
),
],
),
Text(
myList[29],
style: AppStyle.title,
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Icon(
Icons.arrow_circle_down,
color: AppColor.redColor,
),
Text(
myList[5] + ' ' + ' (${myList[4]}) ',
style: AppStyle.title,
),
],
),
Text(
myList[30],
style: AppStyle.title,
),
],
),
],
),
),
),
),
Padding(
padding: const EdgeInsets.all(4),
child: Container(
color: AppColor.greenColor.withOpacity(.5),
Padding(
padding: const EdgeInsets.all(8.0),
child: RichText(
text: TextSpan(
text: 'Cost Of Trip IS '.tr,
style: AppStyle.title,
text: "Passenger name: "
.tr, // Changed text to be more generic
style: AppStyle.subtitle,
children: [
TextSpan(
text: myList[26], style: AppStyle.headTitle2),
text: myList[8],
style: AppStyle
.title), // Assuming myList[8] holds passenger name
TextSpan(text: ' (', style: AppStyle.subtitle),
TextSpan(
text: myList[33].toString(),
style: AppStyle
.title), // Assuming 'rate' holds the passenger rate
TextSpan(text: ' ⭐)', style: AppStyle.subtitle),
],
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyElevatedButton(
kolor: AppColor.greenColor,
title: 'Accept Order'.tr,
onPressed: () async {
box.write(BoxName.statusDriverLocation, 'on');
orderRequestController.endTimer();
orderRequestController.changeApplied();
await CRUD().postFromDialogue(
link: AppLink.addDriverOrder,
payload: {
'driver_id': myList[6].toString(),
// box.read(BoxName.driverID).toString(),
'order_id': body.toString(),
'status': 'Apply'
Padding(
padding: const EdgeInsets.all(4),
child: Container(
color: AppColor.greenColor.withOpacity(.5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RichText(
text: TextSpan(
text: 'Cost Of Trip IS '.tr,
style: AppStyle.title,
children: [
TextSpan(
text: myList[26],
style: AppStyle.headTitle2),
],
),
),
RichText(
text: TextSpan(
text: 'Total net'.tr,
style: AppStyle.title,
children: [
TextSpan(
text: (double.parse(myList[2]) -
double.parse(myList[32]))
.toStringAsFixed(2),
style: AppStyle.headTitle2),
],
),
),
],
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyElevatedButton(
kolor: AppColor.greenColor,
title: 'Accept Order'.tr,
onPressed: () async {
Get.put(HomeCaptainController()).changeRideId();
box.write(BoxName.statusDriverLocation, 'on');
orderRequestController.endTimer();
orderRequestController.changeApplied();
await CRUD().postFromDialogue(
link: AppLink.addDriverOrder,
payload: {
'driver_id': myList[6].toString(),
// box.read(BoxName.driverID).toString(),
'order_id': myList[16].toString(),
'status': 'Apply'
});
var res = await CRUD().post(
link: AppLink.updateRideAndCheckIfApplied,
payload: {
'id': myList[16],
'rideTimeStart': DateTime.now().toString(),
'status': 'Apply',
'driver_id': myList[6].toString(),
});
if (res == 'failure') {
MyDialog().getDialog(
"This ride is already applied by another driver."
.tr,
'', () {
Get.back();
});
var res = await CRUD().post(
link: AppLink.updateRideAndCheckIfApplied,
payload: {
'id': myList[16],
'rideTimeStart': DateTime.now().toString(),
'status': 'Apply',
'driver_id': box.read(BoxName.driverID),
});
if (res == 'failure') {
MyDialog().getDialog(
"This ride is already applied by another driver."
.tr,
'', () {
} else {
List<String> bodyToPassenger = [
myList[6].toString(), //driver id
myList[8].toString(), // driver name
myList[9].toString(), //token driver
];
FirebaseMessagesController()
.sendNotificationToPassengerToken(
'Apply Ride'.tr,
'your ride is applied'.tr,
// arguments['DriverList'][9].toString(),
myList[9].toString(),
// box.read(BoxName.tokenDriver).toString(),
bodyToPassenger,
'start.wav');
Get.back();
});
} else {
box.write(BoxName.rideArguments, {
'passengerLocation': myList[0].toString(),
'passengerDestination': myList[1].toString(),
'Duration': myList[4].toString(),
'totalCost': myList[26].toString(),
'Distance': myList[5].toString(),
'name': myList[8].toString(),
'phone': myList[10].toString(),
'email': myList[28].toString(),
'WalletChecked': myList[13].toString(),
'tokenPassenger': myList[9].toString(),
'direction':
'https://www.google.com/maps/dir/${myList[0]}/${myList[1]}/',
'DurationToPassenger': myList[15].toString(),
'rideId': myList[16].toString(),
'passengerId': myList[7].toString(),
'driverId': myList[18].toString(),
'durationOfRideValue': myList[19].toString(),
'paymentAmount': myList[2].toString(),
'paymentMethod': myList[13].toString() == 'true'
? 'visa'
: 'cash',
'isHaveSteps': myList[20].toString(),
'step0': myList[21].toString(),
'step1': myList[22].toString(),
'step2': myList[23].toString(),
'step3': myList[24].toString(),
'step4': myList[25].toString(),
'passengerWalletBurc': myList[26].toString(),
'timeOfOrder': DateTime.now().toString(),
'totalPassenger': myList[2].toString(),
'carType': myList[31].toString(),
'kazan': myList[32].toString(),
'startNameLocation': myList[29].toString(),
'endNameLocation': myList[30].toString(),
});
'passengerID =${box.read(BoxName.rideArguments)}';
Get.to(() => PassengerLocationMapPage(),
arguments: box.read(BoxName.rideArguments));
}
// Get.back();
},
),
GetBuilder<OrderRequestController>(
builder: (timerController) {
final isNearEnd = timerController.remainingTime <=
5; // Define a threshold for "near end"
return Stack(
alignment: Alignment.center,
children: [
CircularProgressIndicator(
value: timerController.progress,
// Set the color based on the "isNearEnd" condition
color: isNearEnd ? Colors.red : Colors.blue,
),
Text(
'${timerController.remainingTime}',
style: AppStyle.number,
),
],
);
},
),
MyElevatedButton(
title: 'Refuse Order'.tr,
onPressed: () async {
orderRequestController.endTimer();
List<String> bodyToPassenger = [
box.read(BoxName.driverID).toString(),
box.read(BoxName.nameDriver).toString(),
box.read(BoxName.tokenDriver).toString(),
];
FirebaseMessagesController()
.sendNotificationToPassengerToken(
'Apply Ride',
'your ride is applied'.tr,
// arguments['DriverList'][9].toString(),
arguments['DriverList'][9].toString(),
// box.read(BoxName.tokenDriver).toString(),
'Order Under Review'.tr,
'${box.read(BoxName.nameDriver)} ${'is reviewing your order. They may need more information or a higher price.'.tr}',
myList[9].toString(),
bodyToPassenger,
'start.wav');
Get.back();
box.write(BoxName.rideArguments, {
'passengerLocation': myList[0].toString(),
'passengerDestination': myList[1].toString(),
'Duration': myList[4].toString(),
'totalCost': myList[26].toString(),
'Distance': myList[5].toString(),
'name': myList[8].toString(),
'phone': myList[10].toString(),
'email': myList[28].toString(),
'WalletChecked': myList[13].toString(),
'tokenPassenger': myList[9].toString(),
'direction':
'https://www.google.com/maps/dir/${myList[0]}/${myList[1]}/',
'DurationToPassenger': myList[15].toString(),
'rideId': myList[16].toString(),
'passengerId': myList[7].toString(),
'driverId': myList[18].toString(),
'durationOfRideValue': myList[19].toString(),
'paymentAmount': myList[2].toString(),
'paymentMethod': myList[13].toString() == 'true'
? 'visa'
: 'cash',
'isHaveSteps': myList[20].toString(),
'step0': myList[21].toString(),
'step1': myList[22].toString(),
'step2': myList[23].toString(),
'step3': myList[24].toString(),
'step4': myList[25].toString(),
'passengerWalletBurc': myList[26].toString(),
'timeOfOrder': DateTime.now().toString(),
'totalPassenger': myList[2].toString(),
'carType': myList[31].toString(),
'kazan': myList[32].toString(),
'startNameLocation': myList[29].toString(),
'endNameLocation': myList[30].toString(),
});
'passengerID =${box.read(BoxName.rideArguments)}';
Get.to(() => PassengerLocationMapPage(),
arguments: box.read(BoxName.rideArguments));
}
// Get.back();
},
),
GetBuilder<OrderRequestController>(
builder: (timerController) {
final isNearEnd = timerController.remainingTime <=
5; // Define a threshold for "near end"
'notification.wav');
return Stack(
alignment: Alignment.center,
children: [
CircularProgressIndicator(
value: timerController.progress,
// Set the color based on the "isNearEnd" condition
color: isNearEnd ? Colors.red : Colors.blue,
),
Text(
'${timerController.remainingTime}',
style: AppStyle.number,
),
],
);
},
),
MyElevatedButton(
title: 'Refuse Order'.tr,
onPressed: () async {
orderRequestController.endTimer();
List<String> bodyToPassenger = [
box.read(BoxName.driverID).toString(),
box.read(BoxName.nameDriver).toString(),
box.read(BoxName.tokenDriver).toString(),
];
FirebaseMessagesController()
.sendNotificationToPassengerToken(
'Refused Ride'.tr,
'${box.read(BoxName.nameDriver)} ${'reject your order.'.tr}',
arguments['DriverList'][9].toString(),
// box.read(BoxName.tokenDriver).toString(),
bodyToPassenger,
'cancel.wav');
orderRequestController.refuseOrder(
myList[16].toString(),
);
orderRequestController.addRideToNotificationDriverString(
orderRequestController.refuseOrder(
myList[16].toString(),
myList[29].toString(),
myList[30].toString(),
'${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day}',
'${DateTime.now().hour}:${DateTime.now().minute}',
myList[2].toString(),
myList[7].toString(),
'wait',
myList[31].toString(),
myList[33].toString(),
myList[2].toString(),
myList[5].toString(),
myList[4].toString()); //duration
},
kolor: AppColor.redColor,
),
],
),
)
],
);
orderRequestController.addRideToNotificationDriverString(
myList[16].toString(),
myList[29].toString(),
myList[30].toString(),
'${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day}',
'${DateTime.now().hour}:${DateTime.now().minute}',
myList[2].toString(),
myList[7].toString(),
'wait',
myList[31].toString(),
myList[33].toString(),
myList[2].toString(),
myList[5].toString(),
myList[4].toString()); //duration
},
kolor: AppColor.redColor,
),
],
),
)
],
),
),
)
],

View File

@@ -131,7 +131,7 @@ class OrderSpeedRequest extends StatelessWidget {
? AppColor.greenColor
: AppColor.secondaryColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton.icon(
onPressed: () {
@@ -145,12 +145,14 @@ class OrderSpeedRequest extends StatelessWidget {
'Trip has Steps'.tr,
style: AppStyle.title,
)
: Text('Routs of Trip'.tr,
: Text('Payment Method'.tr,
style: AppStyle.title)),
Container(
color: myList[13].toString() == 'true'
? AppColor.deepPurpleAccent
: AppColor.greenColor,
decoration: AppStyle.boxDecoration.copyWith(
color: myList[13].toString() == 'true'
? AppColor.deepPurpleAccent
: AppColor.greenColor,
),
child: myList[13].toString() ==
'true' //Visa or Cash Method from notify to driver
? Text(
@@ -182,90 +184,99 @@ class OrderSpeedRequest extends StatelessWidget {
duration: const Duration(seconds: 5),
curve: Curves.easeInOut,
child: myList[31].toString() == 'Comfort'
? const Icon(
Icons.ac_unit,
color: AppColor.blueColor,
size: 50,
? Column(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
const Icon(
Icons.ac_unit,
color: AppColor.blueColor,
size: 50,
),
Text(
'Air condition Trip'.tr,
style: AppStyle.subtitle,
),
],
)
: const SizedBox(),
),
),
Text(
myList[31].toString(),
myList[31].toString().tr,
style: AppStyle.title
.copyWith(color: AppColor.greenColor),
),
],
)),
),
const SizedBox(
height: 5,
),
Container(
height: Get.height * .15,
width: Get.width * .9,
decoration: AppStyle.boxDecoration1,
child: ListView(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Icon(
Icons.arrow_circle_up,
color: AppColor.greenColor,
),
Text(
myList[12] + ' ' + ' (${myList[11]}) ',
style: AppStyle.title,
),
],
),
Text(
myList[29],
style: AppStyle.title,
),
],
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Icon(
Icons.arrow_circle_up,
color: AppColor.greenColor,
),
Text(
myList[5] + ' ' + ' (${myList[4]}) ',
style: AppStyle.title,
),
],
),
Text(
myList[30],
style: AppStyle.title,
),
],
),
],
),
],
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 5, vertical: 1),
child: ListView(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Icon(
Icons.arrow_circle_up,
color: AppColor.greenColor,
),
Text(
myList[12] + ' ' + ' (${myList[11]}) ',
style: AppStyle.title,
),
],
),
Text(
myList[29],
style: AppStyle.title,
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Icon(
Icons.arrow_circle_down,
color: AppColor.redColor,
),
Text(
myList[5] + ' ' + ' (${myList[4]}) ',
style: AppStyle.title,
),
],
),
Text(
myList[30],
style: AppStyle.title,
),
],
),
],
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RichText(
text: TextSpan(
text: 'Passenger name : '
text: "Passenger name: "
.tr, // Changed text to be more generic
style: AppStyle.subtitle,
children: [
@@ -283,21 +294,42 @@ class OrderSpeedRequest extends StatelessWidget {
),
),
),
Padding(
padding: const EdgeInsets.all(4),
child: Container(
color: AppColor.deepPurpleAccent,
child: RichText(
text: TextSpan(
text: 'Cost Of Trip IS '.tr,
style: AppStyle.title,
children: [
TextSpan(text: myList[26], style: AppStyle.headTitle2),
],
),
color: AppColor.greenColor.withOpacity(.5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RichText(
text: TextSpan(
text: 'Cost Of Trip IS '.tr,
style: AppStyle.title,
children: [
TextSpan(
text: myList[26], style: AppStyle.headTitle2),
],
),
),
RichText(
text: TextSpan(
text: 'Total net'.tr,
style: AppStyle.title,
children: [
TextSpan(
text: (double.parse(myList[2]) -
double.parse(myList[32]))
.toStringAsFixed(2),
style: AppStyle.headTitle2),
],
),
),
],
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(

View File

@@ -48,15 +48,17 @@ class WalletCaptain extends StatelessWidget {
const SizedBox(),
Container(
// decoration: AppStyle.boxDecoration1.copyWith(
color: double.parse(
captainWalletController.totalPoints) <
color: double.parse(captainWalletController
.totalPoints
.toString()) <
0 &&
double.parse(
captainWalletController.totalPoints) >
double.parse(captainWalletController
.totalPoints
.toString()) >
-3000
? AppColor.yellowColor
: double.parse(
captainWalletController.totalPoints) <
: double.parse(captainWalletController.totalPoints
.toString()) <
-3000
? AppColor.redColor
: AppColor.greenColor,