Update codebase

This commit is contained in:
Hamza-Ayed
2026-08-09 16:56:13 +03:00
parent 95e2e4f35d
commit b64debaa88
1058 changed files with 164327 additions and 113928 deletions
@@ -0,0 +1 @@
// This file is no longer used. Gemini is now handled in the PHP backend.
@@ -111,8 +111,7 @@ class OfflineMapService {
for (var region in regions) {
await deleteOfflineRegion(region.id);
}
Log.print(
"✅ Map cache cleared successfully. ${regions.length} regions removed.");
Log.print("✅ Map cache cleared successfully. ${regions.length} regions removed.");
} catch (e) {
Log.print("⚠️ Failed to clear map cache: $e");
}
@@ -1,11 +1,11 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:tripz_driver/print.dart';
import 'package:siro_driver/print.dart';
class SignalingService {
WebSocket? _socket;
final String _url = "wss://calls.tripzapp.com/ws";
final String _url = "wss://calls.intaleqapp.com/ws";
// Callbacks
Function(List<dynamic> iceServers)? onConnected;
@@ -0,0 +1,79 @@
// turn_credentials_service.dart — جلب بيانات اعتماد TURN المؤقتة وتخزينها
//
// خادم الإشارات (Node) يُعيد STUN فقط، وSTUN وحده لا يكفي حين يكون الطرفان
// خلف CGNAT — وهي الحالة الغالبة لسائق وزبون على بيانات الجوال. نجلب TURN
// من الباك إند ونضمّه إلى قائمة ICE قبل إنشاء الاتصال.
//
// البيانات مؤقتة (HMAC بمهلة) لا كلمة مرور ثابتة داخل التطبيق، ونُخزّنها
// محلياً حتى قرب انتهائها فلا نُثقل بنداء شبكة قبل كل مكالمة.
import 'dart:convert';
import '../constant/box_name.dart';
import '../constant/links.dart';
import '../controller/functions/crud.dart';
import '../main.dart';
import '../print.dart';
class TurnCredentialsService {
static const String _cacheKey = BoxName.turnIceCache;
/// خوادم ICE جاهزة لتمريرها إلى createPeerConnection.
/// تعيد قائمة فارغة عند أي فشل — والمُنادي يكمل بـ STUN كما كان سابقاً.
static Future<List<Map<String, dynamic>>> getIceServers() async {
final cached = _readCache();
if (cached != null) return cached;
try {
final res = await CRUD().post(
link: '${AppLink.server}/ride/call/turn_credentials.php',
);
if (res is! Map || res['status'] != 'success') return [];
// غلاف jsonSuccess يضع الحمولة في message
final payload = res['message'];
if (payload is! Map || payload['ice_servers'] is! List) return [];
final servers = (payload['ice_servers'] as List)
.whereType<Map>()
.map((s) => Map<String, dynamic>.from(s))
.toList();
final ttl = int.tryParse(payload['ttl']?.toString() ?? '0') ?? 0;
if (ttl > 0 && servers.isNotEmpty) {
// ننتهي قبل الخادم بخمس دقائق تفادياً لسباق انتهاء الصلاحية أثناء مكالمة
final expiresAt = DateTime.now().add(Duration(seconds: ttl - 300));
box.write(_cacheKey, jsonEncode({
'expires_at': expiresAt.toIso8601String(),
'servers': servers,
}));
}
return servers;
} catch (e) {
Log.print('⚠️ [TURN] تعذّر جلب بيانات الاعتماد: $e');
return [];
}
}
static List<Map<String, dynamic>>? _readCache() {
try {
final raw = box.read(_cacheKey);
if (raw == null) return null;
final data = jsonDecode(raw.toString());
final expiresAt = DateTime.tryParse(data['expires_at']?.toString() ?? '');
if (expiresAt == null || DateTime.now().isAfter(expiresAt)) return null;
final servers = (data['servers'] as List)
.whereType<Map>()
.map((s) => Map<String, dynamic>.from(s))
.toList();
return servers.isEmpty ? null : servers;
} catch (_) {
return null;
}
}
static void clearCache() => box.remove(_cacheKey);
}