Update codebase

This commit is contained in:
Hamza-Ayed
2026-08-11 00:11:23 +03:00
parent 6726fcd917
commit 0ff7d04f9a
345 changed files with 3756 additions and 3369 deletions
@@ -70,6 +70,42 @@ class TripAcceptedResult {
TripAcceptedResult({required this.tripId, required this.acceptedAt});
}
/// Model for a food-delivery offer passed to the overlay
class FoodOrderOverlayData {
final String orderId;
final String merchantName;
final String merchantAddress;
final String deliveryFeeText;
final String cashToCollectText;
final String distanceText;
final int itemsCount;
final bool isCash;
FoodOrderOverlayData({
required this.orderId,
required this.merchantName,
this.merchantAddress = '',
this.deliveryFeeText = '',
this.cashToCollectText = '',
this.distanceText = '',
this.itemsCount = 0,
this.isCash = false,
});
Map<String, dynamic> toMap() => {
'orderId': orderId,
'merchantName': merchantName,
'merchantAddress': merchantAddress,
'deliveryFeeText': deliveryFeeText,
'cashToCollectText': cashToCollectText,
'distanceText': distanceText,
'itemsCount': itemsCount,
'isCash': isCash,
};
String toJson() => jsonEncode(toMap());
}
/// Main plugin class — single entry point for Flutter side
class TripOverlayPlugin {
static const MethodChannel _channel = MethodChannel('trip_overlay_plugin');
@@ -82,6 +118,12 @@ class TripOverlayPlugin {
static final StreamController<String> _tripRejectedController =
StreamController<String>.broadcast();
// Stream controllers for food-delivery offer results FROM Android overlay
static final StreamController<String> _foodAcceptedController =
StreamController<String>.broadcast();
static final StreamController<String> _foodRejectedController =
StreamController<String>.broadcast();
static bool _isInitialized = false;
/// Stream that fires when the driver taps "Accept" in the overlay
@@ -91,6 +133,14 @@ class TripOverlayPlugin {
/// Stream that fires when the driver rejects or overlay times out
static Stream<String> get onTripRejected => _tripRejectedController.stream;
/// Stream that fires when the driver accepts a food-delivery offer
static Stream<String> get onFoodOrderAccepted =>
_foodAcceptedController.stream;
/// Stream that fires when the driver rejects a food offer or it times out
static Stream<String> get onFoodOrderRejected =>
_foodRejectedController.stream;
/// Initialize the plugin — call this once in main() or initState()
static Future<void> initialize() async {
if (_isInitialized) return;
@@ -113,6 +163,16 @@ class TripOverlayPlugin {
_tripRejectedController.add(tripId);
break;
case 'onFoodOrderAccepted':
final orderId = call.arguments['orderId'] as String;
_foodAcceptedController.add(orderId);
break;
case 'onFoodOrderRejected':
final orderId = call.arguments['orderId'] as String;
_foodRejectedController.add(orderId);
break;
default:
throw PlatformException(
code: 'UNKNOWN_METHOD',
@@ -199,6 +259,37 @@ class TripOverlayPlugin {
}
}
/// Show the food-delivery offer overlay with the given [data].
/// [autoCloseSeconds] — how long before auto-dismiss (default 20s).
///
/// يرجع false ولا يرمي أبداً: المُنادي يكمل مساره (إشعار محلي بديل) حتى لو
/// تعذّرت النافذة.
static Future<bool> showFoodOverlay(
FoodOrderOverlayData data, {
int autoCloseSeconds = 20,
}) async {
if (!isSupported) return false;
final granted = await isPermissionGranted();
if (!granted) {
await requestPermission();
return false;
}
try {
final result = await _channel.invokeMethod<bool>('showFoodOverlay', {
'foodData': data.toJson(),
'autoCloseSeconds': autoCloseSeconds,
});
return result ?? false;
} on PlatformException catch (e) {
debugPrint('[TripOverlay] showFoodOverlay failed: ${e.message}');
return false;
} on MissingPluginException {
return false;
}
}
/// Check if the overlay is currently visible
static Future<bool> isOverlayActive() async {
if (!isSupported) return false;
@@ -217,5 +308,7 @@ class TripOverlayPlugin {
static void dispose() {
_tripAcceptedController.close();
_tripRejectedController.close();
_foodAcceptedController.close();
_foodRejectedController.close();
}
}