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