fix(apps): إسقاط التطبيق عند توليد الخريطة — النقاط صارت طبقة فلاتر

## العطل
Unhandled Exception: This Annotation Manager has not been initialized
  → didUpdateWidget → diffCircles → addCircle
  → libc++abi: std::domain_error → SIGABRT

## السبب البنيوي
MapLibre يُنشئ مديري التعليقات (circle/symbol/line) **عند تحميل الستايل
وحده**، ويهدمهم عند كل إعادة تحميل — وتبديل الوضع الليلي إعادةُ تحميل.
وحارسٌ زمنيّ لا يكفي: didUpdateWidget في الحزمة يستدعي diffCircles بمجرّد
وجود المتحكّم، وهو موجود قبل تحميل الستايل وأثناء إعادة تحميله. أي أن أي
نافذة زمنية نتركها ستُصاب عاجلاً أو آجلاً.

## العلاج — إزالة صنف العطل لا ترقيعه
كل ما يُرسم فوق الخريطة صار **طبقة فلاتر** في Stack: نقطة البداية والنهاية
(MapPin) والأسماء (MapLabel) وأيقونة السائق، بمواضع من getScreenCoordinate.
لا annotation manager، فلا عطل — ومعها نرث الخط العربي والاتجاه والثيم.

Polyline وحده بقي annotation (لا بديل لرسم المسار)، محروساً بعَلَم _styleReady
يُصفَّر عند كل تغيير styleUrl.

## أداء
onCameraMove يُطلق عشرات المرات في الثانية وكل مزامنة ثلاثة نداءات منصّة —
أُضيف حارس _syncing يمنع تكدّسها.

## توثيق
docs/23 §13 قاعدة جديدة: ممنوع markers/circles/polygons مع IntaleqMap.
كُتبت كي لا تتكرر في أي شاشة خريطة قادمة.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hamza-Ayed
2026-08-05 01:43:51 +03:00
co-authored by Claude Opus 5
parent ca766a2d4e
commit e2e663dd61
5 changed files with 425 additions and 240 deletions
+27
View File
@@ -222,3 +222,30 @@ if (Features.chat) routes.add(GoRoute(path: '/chat', builder: ...));
3. **صمام الأمان الثالث: المصالحة (reconciliation).** `GET /trips/:id` تُنادى عند: (أ) عودة التطبيق من الخلفية، (ب) إعادة اتصال السوكت بعد انقطاع، (ج) مؤقّت خفيف **أثناء رحلة نشطة فقط** (افتراضي كل 25 ثانية، قابل للضبط، يتوقف كلياً خارج الرحلة). سؤال المالك «هل يلزم كل فترة؟» — الجواب نعم لكن بهذا الشرط الضيّق: FCM قد يتأخر دقائق في Doze والسوكت قد يموت صامتاً؛ المؤقّت يغطي نافذة فشل القناتين معاً، وكلفته استعلام Redis واحد (A3).
4. **الفتح البارد**: `GET /trips/mine` (استئناف أي رحلة غير منتهية) + `GET /trips/rating/pending` (فرض شاشة التقييم قبل أي رحلة جديدة).
5. **العرض دائماً من حالة الـBloc الموحّدة** — لا شاشة تستمع للسوكت أو FCM مباشرة.
---
## 13. الخريطة — قاعدة مضافة 2026-08-05 (بعد سقوط التطبيق)
**ممنوع تمرير `markers`/`circles`/`polygons` إلى `IntaleqMap`.**
MapLibre يُنشئ «مديري التعليقات» عند تحميل الستايل وحده، ويهدمهم عند كل
إعادة تحميل — **وتبديل الوضع الليلي إعادةُ تحميل**. وأي إضافة تعليق في تلك
النافذة ترمي `This Annotation Manager has not been initialized`، وقد أسقطت
التطبيق فعلياً بـ`std::domain_error` من الطبقة الأصلية.
حارسٌ زمنيّ لا يكفي: `didUpdateWidget` في الحزمة يستدعي `diffCircles` بمجرّد
وجود المتحكّم — وهو موجود **قبل** تحميل الستايل و**أثناء** إعادة تحميله.
**القاعدة**: كل ما يُرسم فوق الخريطة (نقاط · أسماء · أيقونة السائق) يكون
**طبقة فلاتر** في `Stack` فوقها، بمواضع من `getScreenCoordinate`. هذا يزيل
صنف الأعطال كلياً، ويعطي الخط العربي والاتجاه والثيم مجاناً.
**الاستثناء الوحيد `Polyline`** — لا بديل عنه لرسم المسار. يُحرس بعَلَم
`_styleReady` يُصفَّر عند كل تغيير `styleUrl`.
**والأداء**: `onCameraMove` يُطلق عشرات المرات في الثانية، وكل مزامنة مواضع
ثلاثة نداءات منصّة. حارس `_syncing` إلزامي وإلا تتكدّس النداءات وتلتهم
الإطارات.
المرجع العملي: `apps/rider_new/lib/features/trip/view/widgets/ride_map.dart`.