26-1-21/1
This commit is contained in:
@@ -105,6 +105,9 @@ class FirebaseMessagesController extends GetxController {
|
||||
// اقرأ "النوع" من حمولة البيانات، وليس من العنوان
|
||||
String category = message.data['category'] ?? '';
|
||||
|
||||
final mapCtrl = Get.isRegistered<MapPassengerController>()
|
||||
? Get.find<MapPassengerController>()
|
||||
: null;
|
||||
// اقرأ العنوان (للعرض)
|
||||
String title = message.notification?.title ?? '';
|
||||
String body = message.notification?.body ?? '';
|
||||
@@ -119,17 +122,25 @@ class FirebaseMessagesController extends GetxController {
|
||||
|
||||
// ... داخل معالج الإشعارات في تطبيق الراكب ...
|
||||
else if (category == 'Accepted Ride') {
|
||||
// <-- كان 'Accepted Ride'
|
||||
var driverListJson = message.data['driverList'];
|
||||
if (driverListJson != null) {
|
||||
var myList = jsonDecode(driverListJson) as List<dynamic>;
|
||||
final controller = Get.find<MapPassengerController>();
|
||||
// controller.currentRideState.value = RideState.driverApplied;
|
||||
await controller.processRideAcceptance(
|
||||
driverIdFromFCM: myList[0].toString(),
|
||||
rideIdFromFCM: myList[3].toString());
|
||||
} else {
|
||||
Log.print('❌ خطأ: RIDE_ACCEPTED وصل بدون driverList');
|
||||
if (mapCtrl != null) {
|
||||
Map<String, dynamic>? driverInfoMap;
|
||||
|
||||
// 2. معالجة driver_info (تأتي كـ String JSON من PHP)
|
||||
if (message.data['driver_info'] != null) {
|
||||
try {
|
||||
String rawJson = message.data['driver_info'];
|
||||
// 🔥 فك التشفير: تحويل الـ String إلى Map
|
||||
driverInfoMap = jsonDecode(rawJson);
|
||||
} catch (e) {
|
||||
print("❌ Error decoding FCM driver_info: $e");
|
||||
}
|
||||
}
|
||||
|
||||
// 3. تمرير البيانات الجاهزة للكنترولر
|
||||
await mapCtrl.processRideAcceptance(
|
||||
driverData: driverInfoMap,
|
||||
source: "FCM",
|
||||
);
|
||||
}
|
||||
} else if (category == 'Promo') {
|
||||
// <-- كان 'Promo'.tr
|
||||
@@ -142,7 +153,7 @@ class FirebaseMessagesController extends GetxController {
|
||||
if (Platform.isAndroid) {
|
||||
notificationController.showNotification(title, body, 'iphone_ringtone');
|
||||
}
|
||||
var myListString = message.data['DriverList'];
|
||||
var myListString = message.data['passengerList'];
|
||||
var myList = jsonDecode(myListString) as List<dynamic>;
|
||||
Get.to(() => TripMonitor(), arguments: {
|
||||
'rideId': myList[0].toString(),
|
||||
@@ -161,7 +172,7 @@ class FirebaseMessagesController extends GetxController {
|
||||
if (Platform.isAndroid) {
|
||||
notificationController.showNotification(title, body, 'tone1');
|
||||
}
|
||||
} else if (category == 'message From passenger') {
|
||||
} else if (category == 'MSG_FROM_PASSENGER') {
|
||||
// <-- كان 'message From passenger'
|
||||
if (Platform.isAndroid) {
|
||||
notificationController.showNotification(title, body, 'ding');
|
||||
@@ -178,78 +189,33 @@ class FirebaseMessagesController extends GetxController {
|
||||
} else if (category == 'Trip is Begin') {
|
||||
// <-- كان 'Trip is Begin'
|
||||
Log.print('[FCM] استقبل إشعار "TRIP_BEGUN".');
|
||||
final controller = Get.find<MapPassengerController>();
|
||||
controller.processRideBegin();
|
||||
// استدعاء الحارس
|
||||
mapCtrl!.processRideBegin(source: "FCM");
|
||||
} else if (category == 'Hi ,I will go now') {
|
||||
// <-- كان 'Hi ,I will go now'.tr
|
||||
if (Platform.isAndroid) {
|
||||
notificationController.showNotification(title, body, 'ding');
|
||||
}
|
||||
update();
|
||||
} else if (category == 'Hi ,I Arrive your site') {
|
||||
// <-- كان 'Hi ,I Arrive your site'.tr
|
||||
final controller = Get.find<MapPassengerController>();
|
||||
// if (controller.currentRideState.value == RideState.driverApplied) {
|
||||
Log.print('[FCM] السائق وصل. تغيير الحالة إلى driverArrived');
|
||||
controller.currentRideState.value = RideState.driverArrived;
|
||||
// }
|
||||
} else if (category == 'Cancel Trip from driver') {
|
||||
// <-- كان "Cancel Trip from driver"
|
||||
Get.back();
|
||||
if (Platform.isAndroid) {
|
||||
notificationController.showNotification(title, body, 'cancel');
|
||||
}
|
||||
Get.defaultDialog(
|
||||
title: "The driver canceled your ride.".tr, // العنوان المترجم للعرض
|
||||
middleText: "We will look for a new driver.\nPlease wait.".tr,
|
||||
confirm: MyElevatedButton(
|
||||
kolor: AppColor.greenColor,
|
||||
title: 'Ok'.tr,
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
await Get.find<MapPassengerController>()
|
||||
.reSearchAfterCanceledFromDriver();
|
||||
},
|
||||
),
|
||||
cancel: MyElevatedButton(
|
||||
title: 'Cancel'.tr,
|
||||
kolor: AppColor.redColor,
|
||||
onPressed: () {
|
||||
Get.offAll(() => const MapPagePassenger());
|
||||
},
|
||||
));
|
||||
} else if (category == "Arrive Ride") {
|
||||
// استدعاء الحارس
|
||||
mapCtrl!.processDriverArrival("FCM");
|
||||
} else if (category == 'Driver Finish Trip') {
|
||||
// <-- كان 'Driver Finish Trip'.tr
|
||||
final rawData = message.data['DriverList'];
|
||||
List<dynamic> driverList = [];
|
||||
if (rawData != null && rawData is String) {
|
||||
|
||||
// ✅ معالجة آمنة للبيانات
|
||||
var rawData = message.data['DriverList'];
|
||||
if (rawData != null && rawData.isNotEmpty) {
|
||||
try {
|
||||
driverList = jsonDecode(rawData);
|
||||
driverList = jsonDecode(rawData) as List<dynamic>;
|
||||
} catch (e) {
|
||||
Log.print('Error decoding DriverList JSON: $e');
|
||||
print("❌ Error decoding DriverList: $e");
|
||||
}
|
||||
} else {
|
||||
Log.print('Error: DriverList data is null or not a String.');
|
||||
}
|
||||
|
||||
if (driverList.length >= 3) {
|
||||
if (Platform.isAndroid) {
|
||||
notificationController.showNotification(
|
||||
title,
|
||||
'${'you will pay to Driver'.tr} ${driverList[3].toString()} \$',
|
||||
'tone1');
|
||||
}
|
||||
Get.find<AudioRecorderController>().stopRecording();
|
||||
// ... (باقي كود المحفظة) ...
|
||||
Get.find<MapPassengerController>().tripFinishedFromDriver();
|
||||
// ... (إشعار "لا تنسى متعلقاتك") ...
|
||||
Get.to(() => RateDriverFromPassenger(), arguments: {
|
||||
'driverId': driverList[0].toString(),
|
||||
'rideId': driverList[1].toString(),
|
||||
'price': driverList[3].toString()
|
||||
});
|
||||
} else {
|
||||
Log.print('Error: TRIP_FINISHED decoded list error.');
|
||||
if (driverList.isNotEmpty) {
|
||||
Get.find<MapPassengerController>()
|
||||
.processRideFinished(driverList, source: "FCM");
|
||||
}
|
||||
} else if (category == 'Finish Monitor') {
|
||||
// <-- كان "Finish Monitor".tr
|
||||
@@ -262,19 +228,21 @@ class FirebaseMessagesController extends GetxController {
|
||||
onPressed: () {
|
||||
Get.offAll(() => const MapPagePassenger());
|
||||
}));
|
||||
} else if (category == 'Driver Cancelled Your Trip') {
|
||||
} else if (category == 'Cancel Trip from driver') {
|
||||
Log.print("🔔 FCM: Ride Cancelled by Driver received.");
|
||||
|
||||
// لا داعي لكتابة منطق التنظيف هنا، الكنترولر يتكفل بكل شيء
|
||||
if (Get.isRegistered<MapPassengerController>()) {
|
||||
// استدعاء الحارس (سيتجاهل الأمر إذا كان السوكيت قد سبقه)
|
||||
Get.find<MapPassengerController>()
|
||||
.processRideCancelledByDriver(message.data, source: "FCM");
|
||||
}
|
||||
|
||||
// إشعار محلي (اختياري، لأن الديالوج سيظهر)
|
||||
if (Platform.isAndroid) {
|
||||
notificationController.showNotification(
|
||||
'Driver Cancelled Your Trip'.tr,
|
||||
'you will pay to Driver you will be pay the cost of driver time look to your Intaleq Wallet'
|
||||
.tr,
|
||||
'cancel');
|
||||
'Trip Cancelled'.tr, 'The driver cancelled the trip.'.tr, 'cancel');
|
||||
}
|
||||
box.write(BoxName.parentTripSelected, false);
|
||||
box.remove(BoxName.tokenParent);
|
||||
|
||||
Get.find<MapPassengerController>().restCounter();
|
||||
Get.offAll(() => const MapPagePassenger());
|
||||
}
|
||||
// ... (باقي الحالات مثل Call Income, Call End, إلخ) ...
|
||||
// ... بنفس الطريقة ...
|
||||
@@ -617,7 +585,7 @@ class FirebaseMessagesController extends GetxController {
|
||||
Future<dynamic> passengerDialog(String message) {
|
||||
return Get.defaultDialog(
|
||||
barrierDismissible: false,
|
||||
title: 'message From Driver'.tr,
|
||||
title: message.tr,
|
||||
titleStyle: AppStyle.title,
|
||||
middleTextStyle: AppStyle.title,
|
||||
middleText: message.tr,
|
||||
|
||||
@@ -1,41 +1,44 @@
|
||||
import 'package:Intaleq/print.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:get/get.dart'; // للترجمة .tr
|
||||
|
||||
class NotificationService {
|
||||
// استبدل هذا الرابط بالرابط الصحيح لملف PHP على السيرفر الخاص بك
|
||||
static const String _serverUrl =
|
||||
'https://syria.intaleq.xyz/intaleq/fcm/send_fcm.php';
|
||||
static const String _batchServerUrl =
|
||||
'https://syria.intaleq.xyz/intaleq/fcm/send_fcm_batch.php';
|
||||
'https://api.intaleq.xyz/intaleq/ride/firebase/send_fcm.php';
|
||||
|
||||
static Future<void> sendNotification({
|
||||
required String target,
|
||||
required String title,
|
||||
required String body,
|
||||
required String? category, // <-- [الإضافة الأولى]
|
||||
required String category, // إلزامي للتصنيف
|
||||
String? tone,
|
||||
List<String>? driverList, // <-- [تعديل 1] : إضافة المتغير الجديد
|
||||
List<String>? driverList,
|
||||
bool isTopic = false,
|
||||
}) async {
|
||||
try {
|
||||
final Map<String, dynamic> payload = {
|
||||
// 1. تجهيز البيانات المخصصة (Data Payload)
|
||||
Map<String, dynamic> customData = {};
|
||||
|
||||
customData['category'] = category;
|
||||
|
||||
// إذا كان هناك قائمة سائقين/ركاب، نضعها هنا
|
||||
if (driverList != null && driverList.isNotEmpty) {
|
||||
// نرسلها كـ JSON String لأن FCM v1 يدعم String Values فقط في الـ data
|
||||
customData['driverList'] = jsonEncode(driverList);
|
||||
}
|
||||
|
||||
// 2. تجهيز الطلب الرئيسي للسيرفر
|
||||
final Map<String, dynamic> requestPayload = {
|
||||
'target': target,
|
||||
'title': title,
|
||||
'body': body,
|
||||
'isTopic': isTopic,
|
||||
'data':
|
||||
customData, // 🔥🔥 التغيير الجوهري: وضعنا البيانات داخل "data" 🔥🔥
|
||||
};
|
||||
if (category != null) {
|
||||
payload['category'] =
|
||||
category; // <-- [الإضافة الثانية] (النص الثابت للتحكم)
|
||||
}
|
||||
// نضيف النغمة فقط إذا لم تكن فارغة
|
||||
if (tone != null) {
|
||||
payload['tone'] = tone;
|
||||
}
|
||||
|
||||
// <-- [تعديل 2] : نضيف قائمة البيانات بعد تشفيرها إلى JSON
|
||||
if (driverList != null) {
|
||||
payload['driverList'] = jsonEncode(driverList);
|
||||
if (tone != null) {
|
||||
requestPayload['tone'] = tone;
|
||||
}
|
||||
|
||||
final response = await http.post(
|
||||
@@ -43,71 +46,18 @@ class NotificationService {
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
body: jsonEncode(payload),
|
||||
body: jsonEncode(requestPayload),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print('✅ Notification sent successfully.');
|
||||
print('Server Response: ${response.body}');
|
||||
// print('Response: ${response.body}');
|
||||
} else {
|
||||
print(
|
||||
'❌ Failed to send notification. Status code: ${response.statusCode}');
|
||||
print('Server Error: ${response.body}');
|
||||
print('❌ Failed to send notification. Code: ${response.statusCode}');
|
||||
print('Error Body: ${response.body}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('❌ An error occurred while sending notification: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// [4] !! دالة جديدة مضافة !!
|
||||
/// ترسل إشعاراً "مجمعاً" إلى قائمة من السائقين
|
||||
static Future<void> sendBatchNotification({
|
||||
required List<String> targets, // <-- قائمة التوكينز
|
||||
required String title,
|
||||
required String body,
|
||||
String? tone,
|
||||
List<String>? driverList, // <-- بيانات الرحلة (نفسها للجميع)
|
||||
}) async {
|
||||
// لا ترسل شيئاً إذا كانت القائمة فارغة
|
||||
if (targets.isEmpty) {
|
||||
Log.print('⚠️ [Batch] No targets to send to. Skipped.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final Map<String, dynamic> payload = {
|
||||
// "targets" بدلاً من "target"
|
||||
'targets': jsonEncode(targets), // تشفير قائمة التوكينز
|
||||
'title': title,
|
||||
'body': body,
|
||||
};
|
||||
|
||||
if (tone != null) {
|
||||
payload['tone'] = tone;
|
||||
}
|
||||
|
||||
// بيانات الرحلة (DriverList)
|
||||
if (driverList != null) {
|
||||
payload['driverList'] = jsonEncode(driverList);
|
||||
}
|
||||
|
||||
final response = await http.post(
|
||||
Uri.parse(_batchServerUrl), // <-- !! تستخدم الرابط الجديد
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
body: jsonEncode(payload),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
Log.print('✅ [Batch] Notifications sent successfully.');
|
||||
Log.print('Server Response: ${response.body}');
|
||||
} else {
|
||||
Log.print('❌ [Batch] Failed to send. Status: ${response.statusCode}');
|
||||
Log.print('Server Error: ${response.body}');
|
||||
}
|
||||
} catch (e) {
|
||||
Log.print('❌ [Batch] An error occurred: $e');
|
||||
print('❌ Error sending notification: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class AudioRecorderController extends GetxController {
|
||||
|
||||
// Stop recording
|
||||
Future<void> stopRecording() async {
|
||||
await recorder.stop();
|
||||
recorder.stop();
|
||||
isRecording = false;
|
||||
isPaused = false;
|
||||
update();
|
||||
|
||||
@@ -100,9 +100,8 @@ class CRUD {
|
||||
}
|
||||
|
||||
final sc = response.statusCode;
|
||||
Log.print('sc: ${sc}');
|
||||
Log.print('request: ${response.request}');
|
||||
final body = response.body;
|
||||
Log.print('request: ${response.request}');
|
||||
Log.print('body: ${body}');
|
||||
|
||||
// 2xx
|
||||
@@ -188,9 +187,9 @@ class CRUD {
|
||||
'Bearer ${r(box.read(BoxName.jwt)).toString().split(Env.addd)[0]}'
|
||||
},
|
||||
);
|
||||
Log.print('response.body: ${response.body}');
|
||||
Log.print('response.request: ${response.request}');
|
||||
Log.print('response.payload: ${payload}');
|
||||
Log.print('request: ${response.request}');
|
||||
Log.print('body: ${response.body}');
|
||||
Log.print('payload: ${payload}');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
var jsonData = jsonDecode(response.body);
|
||||
|
||||
@@ -11,19 +11,17 @@ Future<void> makePhoneCall(String phoneNumber) async {
|
||||
// 1. تنظيف الرقم (إزالة المسافات والفواصل)
|
||||
String formattedNumber = phoneNumber.replaceAll(RegExp(r'\s+'), '');
|
||||
|
||||
// 2. التحقق من طول الرقم لتحديد طريقة التنسيق
|
||||
// 2. منطق التنسيق (مع الحفاظ على الأرقام القصيرة مثل 112 كما هي)
|
||||
if (formattedNumber.length > 6) {
|
||||
// --- التعديل المطلوب ---
|
||||
if (formattedNumber.startsWith('09')) {
|
||||
// إذا كان يبدأ بـ 09 (رقم موبايل سوري محلي)
|
||||
// نحذف أول خانة (الصفر) ونضيف +963
|
||||
// إذا كان يبدأ بـ 09 (رقم موبايل سوري محلي) -> +963
|
||||
formattedNumber = '+963${formattedNumber.substring(1)}';
|
||||
} else if (!formattedNumber.startsWith('+')) {
|
||||
// إذا لم يكن يبدأ بـ + (ولم يكن يبدأ بـ 09)، نضيف + في البداية
|
||||
// هذا للحفاظ على منطقك القديم للأرقام الدولية الأخرى
|
||||
// إذا لم يكن دولياً ولا محلياً معروفاً -> إضافة + فقط
|
||||
formattedNumber = '+$formattedNumber';
|
||||
}
|
||||
}
|
||||
// ملاحظة: الأرقام القصيرة (مثل 112) ستتجاوز الشرط أعلاه وتبقى "112" وهو الصحيح
|
||||
|
||||
// 3. التنفيذ (Launch)
|
||||
final Uri launchUri = Uri(
|
||||
@@ -31,8 +29,19 @@ Future<void> makePhoneCall(String phoneNumber) async {
|
||||
path: formattedNumber,
|
||||
);
|
||||
|
||||
if (await canLaunchUrl(launchUri)) {
|
||||
await launchUrl(launchUri);
|
||||
try {
|
||||
// استخدام LaunchMode.externalApplication هو الحل الجذري لمشاكل الـ Intent
|
||||
// لأنه يجبر النظام على تسليم الرابط لتطبيق الهاتف بدلاً من محاولة فتحه داخل تطبيقك
|
||||
if (await canLaunchUrl(launchUri)) {
|
||||
await launchUrl(launchUri, mode: LaunchMode.externalApplication);
|
||||
} else {
|
||||
// في بعض الأجهزة canLaunchUrl تعود بـ false مع الـ tel ومع ذلك يعمل launchUrl
|
||||
// لذا نجرب الإطلاق المباشر كاحتياط
|
||||
await launchUrl(launchUri, mode: LaunchMode.externalApplication);
|
||||
}
|
||||
} catch (e) {
|
||||
// طباعة الخطأ في حال الفشل التام
|
||||
print("Error launching call: $e");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
127
lib/controller/home/device_performance.dart
Normal file
127
lib/controller/home/device_performance.dart
Normal file
@@ -0,0 +1,127 @@
|
||||
import 'dart:io';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
|
||||
class DevicePerformanceManager {
|
||||
/// القائمة البيضاء لموديلات الهواتف القوية (Flagships Only)
|
||||
/// أي هاتف يبدأ موديله بأحد هذه الرموز سيعتبر قوياً
|
||||
static const List<String> _highEndSamsungModels = [
|
||||
'SM-S', // سلسلة Galaxy S21, S22, S23, S24 (S901, S908, S911...)
|
||||
'SM-F', // سلسلة Fold و Flip (Z Fold, Z Flip)
|
||||
'SM-N9', // سلسلة Note 9, Note 10, Note 20
|
||||
'SM-G9', // سلسلة S10, S20 (G970, G980...)
|
||||
];
|
||||
|
||||
static const List<String> _highEndGoogleModels = [
|
||||
'Pixel 6',
|
||||
'Pixel 7',
|
||||
'Pixel 8',
|
||||
'Pixel 9',
|
||||
'Pixel Fold'
|
||||
];
|
||||
|
||||
static const List<String> _highEndHuaweiModels = [
|
||||
'ELS-', // P40 Pro
|
||||
'ANA-', // P40
|
||||
'HMA-', // Mate 20
|
||||
'LYA-', // Mate 20 Pro
|
||||
'VOG-', // P30 Pro
|
||||
'ELE-', // P30
|
||||
'NOH-', // Mate 40 Pro
|
||||
'AL00', // Mate X series (some)
|
||||
];
|
||||
|
||||
static const List<String> _highEndXiaomiModels = [
|
||||
'2201122', // Xiaomi 12 series patterns often look like this
|
||||
'2210132', // Xiaomi 13
|
||||
'2304FPN', // Xiaomi 13 Ultra
|
||||
'M2007J1', // Mi 10 series
|
||||
'M2102K1', // Mi 11 Ultra
|
||||
];
|
||||
|
||||
static const List<String> _highEndOnePlusModels = [
|
||||
'GM19', // OnePlus 7
|
||||
'HD19', // OnePlus 7T
|
||||
'IN20', // OnePlus 8
|
||||
'KB20', // OnePlus 8T
|
||||
'LE21', // OnePlus 9
|
||||
'NE22', // OnePlus 10
|
||||
'PHB110', // OnePlus 11
|
||||
'CPH', // Newer OnePlus models
|
||||
];
|
||||
|
||||
/// دالة الفحص الرئيسية
|
||||
static Future<bool> isHighEndDevice() async {
|
||||
// 1. الآيفون دائماً قوي (نظام الرسوميات فيه متفوق حتى في الموديلات القديمة)
|
||||
if (Platform.isIOS) return true;
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
try {
|
||||
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||
|
||||
String manufacturer = androidInfo.manufacturer.toLowerCase();
|
||||
String model =
|
||||
androidInfo.model.toUpperCase(); // نحوله لحروف كبيرة للمقارنة
|
||||
String hardware = androidInfo.hardware.toLowerCase(); // المعالج
|
||||
|
||||
// --- الفحص العكسي (الحظر المباشر) ---
|
||||
// إذا كان المعالج من الفئات الضعيفة جداً المشهورة في الهواتف المقلدة
|
||||
// mt65xx, mt6735, sc77xx هي معالجات رخيصة جداً
|
||||
if (hardware.contains('mt65') ||
|
||||
hardware.contains('mt6735') ||
|
||||
hardware.contains('sc77')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- فحص القائمة البيضاء (Whitelist) ---
|
||||
|
||||
// 1. Samsung Flagships
|
||||
if (manufacturer.contains('samsung')) {
|
||||
for (var prefix in _highEndSamsungModels) {
|
||||
if (model.startsWith(prefix)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Google Pixel (6 and above)
|
||||
if (manufacturer.contains('google')) {
|
||||
for (var prefix in _highEndGoogleModels) {
|
||||
if (model.contains(prefix.toUpperCase())) return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Huawei Flagships
|
||||
if (manufacturer.contains('huawei')) {
|
||||
for (var prefix in _highEndHuaweiModels) {
|
||||
if (model.startsWith(prefix)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. OnePlus Flagships
|
||||
if (manufacturer.contains('oneplus')) {
|
||||
for (var prefix in _highEndOnePlusModels) {
|
||||
if (model.startsWith(prefix)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Xiaomi Flagships
|
||||
if (manufacturer.contains('xiaomi') ||
|
||||
manufacturer.contains('redmi') ||
|
||||
manufacturer.contains('poco')) {
|
||||
// شاومي تسميتها معقدة، لذا سنعتمد على فحص الرام كعامل مساعد هنا فقط
|
||||
// لأن هواتف شاومي القوية عادة لا تزور الرام
|
||||
// الرام يجب أن يكون أكبر من 6 جيجا (بايت)
|
||||
double ramGB = (androidInfo.availableRamSize) / (1024 * 1024 * 1024);
|
||||
if (ramGB > 7.5)
|
||||
return true; // 8GB RAM or more is usually safe for Xiaomi high-end
|
||||
}
|
||||
|
||||
// إذا لم يكن من ضمن القوائم أعلاه، نعتبره جهازاً متوسطاً/ضعيفاً ونعرض الرسم البسيط
|
||||
return false;
|
||||
} catch (e) {
|
||||
// في حال حدوث خطأ في الفحص، نعود للوضع الآمن (الرسم البسيط)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,7 @@ class RateController extends GetxController {
|
||||
update();
|
||||
}
|
||||
|
||||
void addRateToDriver() async {
|
||||
addRateToDriver() async {
|
||||
if (selectedRateItemId < 1) {
|
||||
Get.defaultDialog(
|
||||
title: 'You Should choose rate figure'.tr,
|
||||
|
||||
Reference in New Issue
Block a user