25-6-13/1

This commit is contained in:
Hamza-Ayed
2025-06-13 01:56:06 +03:00
parent ce3ae01a75
commit 5eba032887
31 changed files with 945 additions and 862 deletions

View File

@@ -232,10 +232,7 @@ class LoginDriverController extends GetxController {
Log.print('(BoxName.emailDriver): ${box.read(BoxName.emailDriver)}');
var res = await CRUD().get(link: AppLink.loginFromGoogleCaptin, payload: {
'email': email.toString().contains('@')
// ? (box.read(BoxName.emailDriver))
? (email)
: email,
'email': email,
'id': driverID,
});

View File

@@ -408,7 +408,8 @@ class FirebaseMessagesController extends GetxController {
var encryptedKey = await storage.read(key: 'FCM_PRIVATE_KEY');
// Log.print('encryptedKey: ${encryptedKey}');
if (encryptedKey != null) {
serviceAccountKeyJson = (encryptedKey);
serviceAccountKeyJson =
EncryptionHelper.instance.decryptData(encryptedKey);
// Log.print('serviceAccountKeyJson: ${serviceAccountKeyJson}');
} else {
print('🔴 Error: FCM_PRIVATE_KEY not found in Secure Storage');

View File

@@ -4,7 +4,6 @@ import 'package:secure_string_operations/secure_string_operations.dart';
import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/constant/links.dart';
import 'package:sefer_driver/controller/auth/captin/login_captin_controller.dart';
import 'package:sefer_driver/controller/functions/add_error.dart';
import 'package:sefer_driver/main.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
@@ -44,9 +43,9 @@ class CRUD {
'Bearer ${X.r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs).toString().split(AppInformation.addd)[0]}'
},
);
// print(response.request);
// Log.print('response.body: ${response.body}');
// print(payload);
print(response.request);
Log.print('response.body: ${response.body}');
print(payload);
if (response.statusCode == 200) {
var jsonData = jsonDecode(response.body);
if (jsonData['status'] == 'success') {
@@ -82,7 +81,7 @@ class CRUD {
}) async {
var s = await LoginDriverController().getJwtWallet();
final hmac = box.read(BoxName.hmac);
Log.print('hmac: ${hmac}');
// Log.print('hmac: ${hmac}');
var url = Uri.parse(
link,
);
@@ -95,10 +94,9 @@ class CRUD {
'X-HMAC-Auth': hmac.toString(),
},
);
// print(response.request);
// // Log.print('response.request: ${response.request}');
// Log.print('response.body: ${response.body}');
// print(payload);
Log.print('response.request: ${response.request}');
Log.print('response.body: ${response.body}');
print(payload);
if (response.statusCode == 200) {
var jsonData = jsonDecode(response.body);
if (jsonData['status'] == 'success') {
@@ -145,9 +143,9 @@ class CRUD {
'X-HMAC-Auth': hmac.toString(),
},
);
// print(response.request);
// Log.print('response.body: ${response.body}');
// print(payload);
print(response.request);
Log.print('response.body: ${response.body}');
print(payload);
if (response.statusCode == 200) {
try {
var jsonData = jsonDecode(response.body);
@@ -203,9 +201,9 @@ class CRUD {
// 'Authorization': 'Bearer ${box.read(BoxName.jwt)}'
},
);
// print(response.request);
// Log.print('response.body: ${response.body}');
// print(payload);
print(response.request);
Log.print('response.body: ${response.body}');
print(payload);
if (response.statusCode == 200) {
try {
var jsonData = jsonDecode(response.body);

View File

@@ -4,10 +4,12 @@ import 'dart:math';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:sefer_driver/constant/table_names.dart';
import '../../constant/box_name.dart';
import '../../constant/links.dart';
import '../../main.dart';
import '../../print.dart';
import '../home/captin/home_captain_controller.dart';
import '../home/payment/captain_wallet_controller.dart';
import 'crud.dart';
@@ -72,6 +74,8 @@ class LocationController extends GetxController {
}
int _insertCounter = 0;
double? _lastSpeed;
DateTime? _lastSpeedTime;
Future<void> startLocationUpdates() async {
if (box.read(BoxName.driverID) != null) {
@@ -111,13 +115,17 @@ class LocationController extends GetxController {
if (_lastSavedPosition == null ||
_calculateDistanceInMeters(_lastSavedPosition!, myLocation) >=
10) {
double currentSpeed = speed; // m/s
double? acceleration = _calculateAcceleration(currentSpeed);
await sql.insertData({
'driver_id': box.read(BoxName.driverID).toString(),
'latitude': myLocation.latitude,
'longitude': myLocation.longitude,
'acceleration': acceleration ?? 0.0,
'created_at': DateTime.now().toIso8601String(),
'updated_at': DateTime.now().toIso8601String(),
}, 'car_locations');
}, TableName.behavior);
_lastSavedPosition = myLocation;
}
@@ -125,6 +133,7 @@ class LocationController extends GetxController {
// ✅ إدخال للسيرفر كل دقيقة
_insertCounter++;
Log.print('_insertCounter: ${_insertCounter}');
if (_insertCounter >= 12) {
_insertCounter = 0;
await CRUD().post(
@@ -199,4 +208,22 @@ class LocationController extends GetxController {
2;
return 12742 * 1000 * asin(sqrt(a)); // meters
}
double? _calculateAcceleration(double currentSpeed) {
final now = DateTime.now();
if (_lastSpeed != null && _lastSpeedTime != null) {
final deltaTime =
now.difference(_lastSpeedTime!).inMilliseconds / 1000.0; // seconds
if (deltaTime > 0) {
final acceleration = (currentSpeed - _lastSpeed!) / deltaTime;
_lastSpeed = currentSpeed;
_lastSpeedTime = now;
return double.parse(acceleration.toStringAsFixed(2));
}
}
_lastSpeed = currentSpeed;
_lastSpeedTime = now;
return null;
}
}

View File

@@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:sefer_driver/constant/box_name.dart';
@@ -90,7 +91,8 @@ class HomeCaptainController extends GetxController {
isActive = !isActive;
if (isActive) {
if (double.parse(totalPoints) > -300) {
// locationController.startLocationUpdates();
locationController.startLocationUpdates();
HapticFeedback.heavyImpact();
// locationBackController.startBackLocation();
activeStartTime = DateTime.now();
activeTimer = Timer.periodic(const Duration(seconds: 1), (timer) {

View File

@@ -173,6 +173,7 @@ class MapDriverController extends GetxController {
cancelTripFromDriverAfterApplied() async {
if (formKeyCancel.currentState!.validate()) {
box.write(BoxName.statusDriverLocation, 'off');
FirebaseMessagesController().sendNotificationToDriverMAP(
"Cancel Trip from driver",
"Trip Cancelled from driver. We are looking for a new driver. Please wait."

View File

@@ -65,7 +65,7 @@ class MyTranslation extends Translations {
"Order Applied": "تم تطبيق الطلب",
//firebase above
"cancel": "إلغاء",
"cancel": "إلغاء", "Syria": "‏سوريا",
"Security Warning": "تحذير أمني",
"Potential security risks detected. The application will close in @seconds seconds.":
"تم اكتشاف مخاطر أمنية محتملة. سيتم إغلاق التطبيق خلال @seconds ثانية.",

View File

@@ -44,11 +44,17 @@ final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@pragma('vm:entry-point')
Future<void> backgroundMessageHandler(RemoteMessage message) async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
if (!await FlutterOverlayWindow.isPermissionGranted()) {
// بإمكانك تجاهل الطلب في الخلفية والاكتفاء بالتنبيه
Log.print("Overlay permission not granted; showing only notification.");
}
if (Platform.isAndroid) {
if (message.notification != null && message.notification!.title != null) {
if (message.notification?.title == 'Order'.tr ||
Log.print('message.notification!.title: ${message.notification!.title}');
if (message.notification?.title == 'طلب' ||
message.notification?.title == 'OrderSpeed') {
var myListString = message.data['DriverList'] ?? '[]';
Log.print('myListString: $myListString');
@@ -57,6 +63,7 @@ Future<void> backgroundMessageHandler(RemoteMessage message) async {
List<dynamic> myList;
try {
myList = jsonDecode(myListString) as List<dynamic>;
Log.print('myList: ${myList}');
} catch (e) {
Log.print('Error decoding JSON: $e');
myList = [];
@@ -74,9 +81,9 @@ Future<void> backgroundMessageHandler(RemoteMessage message) async {
flag: OverlayFlag.focusPointer,
// visibility: NotificationVisibility.visibilityPublic,
positionGravity: PositionGravity.auto,
height: 700,
height: 1300,
width: WindowSize.matchParent,
startPosition: const OverlayPosition(0, -150),
startPosition: const OverlayPosition(0, -40),
);
NotificationController().showNotification(
message.notification!.title.toString(),
@@ -175,10 +182,10 @@ class _MyAppState extends State<MyApp> {
FirebaseMessagesController().getToken(),
]);
PermissionStatus status1 = await Permission.location.status;
if (status1.isGranted) {
await LocationController().startLocationUpdates();
}
// PermissionStatus status1 = await Permission.location.status;
// if (status1.isGranted) {
// await LocationController().startLocationUpdates();
// }
}
String? key = (await storage.read(key: BoxName.payMobApikey));

View File

@@ -19,9 +19,14 @@ class DbSql {
String path = join(await getDatabasesPath(), 'my_database.db');
return await openDatabase(
path,
version: 1,
onCreate: (db, version) async {
await db.execute('''
version: 3,
onCreate: (db, version) async => await _createTables(db),
onUpgrade: (db, oldVersion, newVersion) async => await _createTables(db),
);
}
Future<void> _createTables(Database db) async {
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.carLocations}(
id INTEGER PRIMARY KEY AUTOINCREMENT,
driver_id TEXT,
@@ -31,7 +36,7 @@ class DbSql {
updated_at TEXT
)
''');
await db.execute('''
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.placesFavorite}(
id INTEGER PRIMARY KEY AUTOINCREMENT,
latitude REAL,
@@ -40,7 +45,7 @@ class DbSql {
rate TEXT
)
''');
await db.execute('''
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.recentLocations}(
id INTEGER PRIMARY KEY AUTOINCREMENT,
latitude REAL,
@@ -49,7 +54,7 @@ class DbSql {
rate TEXT
)
''');
await db.execute('''
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.driverOrdersRefuse}(
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_id TEXT UNIQUE,
@@ -57,7 +62,7 @@ class DbSql {
driver_id TEXT
)
''');
await db.execute('''
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.rideLocation}(
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_id TEXT ,
@@ -66,29 +71,31 @@ class DbSql {
lng TEXT
)
''');
await db.execute('''
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.faceDetectTimes}(
id INTEGER PRIMARY KEY AUTOINCREMENT,
faceDetectTimes INTEGER
)
''');
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.behavior}(
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.behavior} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
speed REAL,
lat REAL,
lng REAL,
driver_id TEXT,
latitude REAL,
longitude REAL,
acceleration REAL,
timestamp TEXT
)
created_at TEXT,
updated_at TEXT
);
''');
await db.execute('''
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.captainNotification}(
id INTEGER PRIMARY KEY AUTOINCREMENT,
faceDetectTimes INTEGER
)
''');
await db.execute('''
await db.execute('''
CREATE TABLE IF NOT EXISTS ${TableName.applyRideFromOverLay}(
id INTEGER PRIMARY KEY AUTOINCREMENT,
start_location_lat TEXT,
@@ -129,8 +136,6 @@ class DbSql {
passenger_rate TEXT
)
''');
},
);
}
Future<List<Map<String, dynamic>>> getAllData(String table) async {

View File

@@ -1,52 +1,90 @@
// lib/models/order_data.dart
class OrderData {
final String customerName;
final double distance;
final double tripDistanceKm; // المسافة الكلية للرحلة بالكيلومتر
final String price;
final String startLocation;
final String endLocation;
final String passengerDistance;
final String duration;
final String startLocationAddress;
final String endLocationAddress;
final double distanceToPassengerKm; // المسافة إلى الراكب بالكيلومتر
final int tripDurationMinutes; // مدة الرحلة الكلية بالدقائق (مقربة لأعلى)
final int
durationToPassengerMinutes; // المدة إلى الراكب بالدقائق (مقربة لأعلى)
final String rideType;
final String orderId;
final String passengerId;
final String passengerRate;
final String? rawStartCoordinates;
final String? rawEndCoordinates;
OrderData({
required this.customerName,
required this.distance,
required this.tripDistanceKm,
required this.price,
required this.startLocation,
required this.endLocation,
required this.passengerDistance,
required this.duration,
required this.startLocationAddress,
required this.endLocationAddress,
required this.distanceToPassengerKm,
required this.tripDurationMinutes,
required this.durationToPassengerMinutes,
required this.rideType,
required this.orderId,
required this.passengerId,
required this.passengerRate,
this.rawStartCoordinates,
this.rawEndCoordinates,
});
// Factory constructor to create an OrderData instance from a List<dynamic>.
// This handles parsing and provides default values for safety.
// دالة مساعدة لتحويل الثواني إلى دقائق وتقريبها لأعلى
static int _secondsToRoundedUpMinutes(String secondsString) {
final seconds = double.tryParse(secondsString) ?? 0.0;
if (seconds <= 0) return 0;
return (seconds / 60)
.ceil(); // .ceil() لتقريب الكسر لأعلى (مثلاً 0.1 دقيقة تصبح 1 دقيقة)
}
factory OrderData.fromList(List<dynamic> list) {
// بناءً على testList والافتراضات الجديدة:
// list[4]: durationToRide (مدة الرحلة الكلية بالثواني)
// list[5]: distance (المسافة الكلية للرحلة بالكيلومتر)
// list[12]: distanceByPassenger (المسافة إلى الراكب بالمتر)
// list[15]: durationToPassenger (المدة إلى الراكب بالثواني)
double distanceToPassengerMeters =
list.length > 12 ? (double.tryParse(list[12].toString()) ?? 0.0) : 0.0;
return OrderData(
customerName: list.length > 8 ? list[8].toString() : 'Unknown Customer',
distance:
tripDistanceKm:
list.length > 5 ? (double.tryParse(list[5].toString()) ?? 0.0) : 0.0,
price: list.length > 2 ? list[2].toString().split('.')[0] : '0',
startLocation: list.length > 29 ? list[29].toString() : 'Unknown',
endLocation: list.length > 30 ? list[30].toString() : 'Unknown',
passengerDistance: list.length > 12 ? list[12].toString() : 'Unknown',
duration: list.length > 4
? (double.parse(list[4].toString()) / 60).toStringAsFixed(0)
: 'Unknown',
startLocationAddress:
list.length > 29 ? list[29].toString() : 'Unknown Address',
endLocationAddress:
list.length > 30 ? list[30].toString() : 'Unknown Address',
distanceToPassengerKm:
distanceToPassengerMeters / 1000.0, // تحويل من متر إلى كيلومتر
tripDurationMinutes:
list.length > 4 ? _secondsToRoundedUpMinutes(list[4].toString()) : 0,
durationToPassengerMinutes: list.length > 15
? _secondsToRoundedUpMinutes(list[15].toString())
: 0,
rideType:
list.length > 31 ? _getRideType(list[31].toString()) : 'Unknown',
orderId: list.length > 16 ? list[16].toString() : 'Unknown',
passengerId: list.length > 7 ? list[7].toString() : 'Unknown',
passengerRate: list.length > 33 ? list[33].toString() : 'Unknown',
orderId: list.length > 16 ? list[16].toString() : 'N/A',
passengerId: list.length > 7 ? list[7].toString() : 'N/A',
passengerRate: list.length > 33 ? list[33].toString() : 'N/A',
rawStartCoordinates: list.isNotEmpty ? list[0].toString() : null,
rawEndCoordinates: list.length > 1 ? list[1].toString() : null,
);
}
static String _getRideType(String type) {
switch (type) {
case 'Comfort':
@@ -60,7 +98,50 @@ class OrderData {
case 'Rayeh Gai':
return 'رايح جاي';
default:
return '';
return type;
}
}
Map<String, double?>? get startCoordinates {
if (rawStartCoordinates == null) return null;
final parts = rawStartCoordinates!.split(',');
if (parts.length == 2) {
return {
'lat': double.tryParse(parts[0].trim()),
'lng': double.tryParse(parts[1].trim())
};
}
return null;
}
Map<String, double?>? get endCoordinates {
if (rawEndCoordinates == null) return null;
final parts = rawEndCoordinates!.split(',');
if (parts.length == 2) {
return {
'lat': double.tryParse(parts[0].trim()),
'lng': double.tryParse(parts[1].trim())
};
}
return null;
}
Map<String, dynamic> toMap() {
return {
'customerName': customerName,
'tripDistanceKm': tripDistanceKm,
'price': price,
'startLocationAddress': startLocationAddress,
'endLocationAddress': endLocationAddress,
'distanceToPassengerKm': distanceToPassengerKm,
'tripDurationMinutes': tripDurationMinutes,
'durationToPassengerMinutes': durationToPassengerMinutes,
'rideType': rideType,
'orderId': orderId,
'passengerId': passengerId,
'passengerRate': passengerRate,
'rawStartCoordinates': rawStartCoordinates,
'rawEndCoordinates': rawEndCoordinates,
};
}
}

View File

@@ -16,6 +16,7 @@ class CountryPicker extends StatelessWidget {
final List<String> countryOptions = [
'Jordan',
"Syria",
'USA',
'Egypt',
'Turkey',

View File

@@ -1,10 +1,6 @@
import 'dart:io';
import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/controller/auth/captin/login_captin_controller.dart';
import 'package:sefer_driver/controller/firebase/local_notification.dart';
import 'package:sefer_driver/main.dart';
import 'package:sefer_driver/views/auth/captin/cards/sms_signup.dart';
import 'package:sefer_driver/views/home/Captin/orderCaptin/vip_order_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
@@ -12,7 +8,6 @@ import 'package:get/get.dart';
import 'package:sefer_driver/controller/home/captin/home_captain_controller.dart';
import '../../../../../constant/colors.dart';
import '../../../../../controller/packages/lingo/lingo_hunter.dart';
import '../../../../Rate/ride_calculate_driver.dart';
GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
@@ -95,26 +90,72 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
)
: const SizedBox(),
// : const SizedBox(),
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 {
print(box.read(BoxName.paymentLink));
},
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 {
// final List<dynamic> testList = const [
// "32.1117875,36.0669891",
// "32.1364001,36.0707479",
// "24.84",
// "7.56",
// "436",
// "4.38",
// "109270481246447459618",
// "113172279072358305645",
// "hamza",
// "e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k",
// "+201010101010",
// "6",
// "43",
// "true",
// "c2tXiuBJQCSg4CU4IfqYOL:APA91bFA0f8R3QMnPQnPEEdNyjY-jcoKt4nLBHxcLLsmDSuJn5yd4jSvwq7qDIZpkkPkjfjdwdKsGL0-G0aHpPyjfiBvbCwFmlRMCUKftNMNT7MJx2Bp16Y",
// "6",
// "1188",
// "false",
// "109270481246447459618",
// "436",
// "startEnd",
// "32.12404505187645,36.06566168367863",
// "",
// "",
// "",
// "",
// "5.42",
// "0",
// "hamzaayedflutter@gmail.com",
// "4368+PPP، السخنة، الأردن",
// "43PC+C4G، السخنة، الأردن",
// "Speed",
// "8",
// "5.00"
// ];
// await FlutterOverlayWindow.shareData(testList);
// await FlutterOverlayWindow.showOverlay(
// enableDrag: true,
// flag: OverlayFlag.focusPointer,
// // visibility: NotificationVisibility.visibilityPublic,
// positionGravity: PositionGravity.auto,
// height: 1300,
// width: WindowSize.matchParent,
// startPosition: const OverlayPosition(0, -90),
// );
// debugPrint('Overlay opened: ');
// },
// icon: const Icon(
// FontAwesome5.grin_tears,
// size: 29,
// color: AppColor.blueColor,
// ),
// );
// }),
// ),
const SizedBox(
height: 5,

File diff suppressed because it is too large Load Diff