Update: 2026-08-08 14:26:43

This commit is contained in:
Hamza-Ayed
2026-08-08 14:26:44 +03:00
parent b97a1fd587
commit ef37752ceb
7 changed files with 123 additions and 59 deletions
@@ -66,62 +66,53 @@ https://siromove.com/invite.php?code=$couponCode&app=rider
@override
void onInit() {
super.onInit();
// **MODIFIED**: Sync contacts automatically on controller initialization.
syncContactsToServerOnce();
// ‏لا نقرأ دفتر الهاتف هنا. القراءة تحدث فقط حين يطلب الكابتن
// ‏اختيار جهة اتصال — انظر loadDeviceContacts أدناه.
// fetchDriverStats();
}
// --- NEW LOGIC: ONE-TIME CONTACTS SYNC ---
// --- قراءة جهات الاتصال محلياً، بطلب المستخدم وحده ---
/// **NEW**: Syncs all phone contacts to the server, but only runs once per user.
Future<void> syncContactsToServerOnce() async {
final String syncFlagKey = 'contactsSynced_${box.read(BoxName.driverID)}';
// 1. Check if contacts have already been synced for this user.
if (box.read(syncFlagKey) == true) {
print("Contacts have already been synced for this user.");
return;
}
/// ‏كان هنا `syncContactsToServerOnce`: يقرأ دفتر هاتف الكابتن كاملاً
/// ‏تلقائياً عند فتح شاشة الدعوة، ويرفع **كل** اسم ورقم إلى
/// ‏`ride/egyptPhones/syrianAdd.php` — طلب لكل جهة اتصال.
///
/// ‏أُزيل الرفع بالكامل، ولثلاثة أسباب لا واحد:
///
/// ‏١) سياسة Google Play: رفع دفتر العناوين جملةً يتطلب إفصاحاً بارزاً
/// ‏وموافقة صريحة، وإذن النظام وحده لا يكفي. والتطبيق موقوف أصلاً.
///
/// ‏٢) البيانات ليست بيانات الكابتن ليتبرّع بها: هي أسماء وأرقام أطراف
/// ‏ثالثة لم تُستأذن ولا تعلم بوجود سيرو.
///
/// ‏٣) لا ميزة تعتمد عليها. الدعوة تعمل بالمشاركة أو باختيار جهة واحدة
/// ‏عمداً، وكلاهما لا يحتاج نسخة من الدفتر على السيرفر.
///
/// ‏ما بقي هنا قراءة محلية بحتة لعرض قائمة يختار منها الكابتن — لا
/// ‏شيء يغادر الجهاز.
Future<void> loadDeviceContacts() async {
if (contactMaps.isNotEmpty) return; // مُحمّلة سلفاً في هذه الجلسة
try {
// 2. Request permission and fetch all contacts.
if (await FlutterContacts.requestPermission(readonly: true)) {
// mySnackbarSuccess('Starting contacts sync in background...'.tr);
final List<Contact> allContacts =
await FlutterContacts.getContacts(withProperties: true);
// **FIX**: Assign fetched contacts to the class variable.
contacts = allContacts;
contactMaps.value = contacts.map((contact) {
return {
'name': contact.displayName,
'phones':
contact.phones.map((phone) => phone.normalizedNumber).toList(),
'emails': contact.emails.map((email) => email.address).toList(),
};
}).toList();
contactMaps.value = allContacts
.where((c) => c.phones.isNotEmpty)
.map((contact) => {
'name': contact.displayName,
'phones': contact.phones
.map((phone) => phone.normalizedNumber)
.toList(),
'emails':
contact.emails.map((email) => email.address).toList(),
})
.toList();
update();
// 3. Loop through contacts and save them to the server.
for (var contact in allContacts) {
if (contact.phones.isNotEmpty) {
// Use the normalized phone number for consistency.
var phone = contact.phones.first.normalizedNumber;
if (phone.isNotEmpty) {
CRUD().post(link: AppLink.savePhonesSyria, payload: {
"driverId": box.read(BoxName.driverID), // Associate with driver
"name": contact.displayName ?? 'No Name',
"phone": phone,
});
}
}
}
// 4. After a successful sync, set the flag to prevent future syncs.
await box.write(syncFlagKey, true);
// mySnackbarSuccess('Contacts sync completed successfully!'.tr);
}
} catch (e) {
// mySnackbarError('An error occurred during contact sync: $e'.tr);
// قراءة دفتر الهاتف ليست حرجة — الدعوة تعمل بالمشاركة أيضاً.
}
}