chore: استيراد أولي من سيرو (ecfe7568) — بلا أي تعديل

نسخة كاملة من مستودع سيرو عند ecfe7568 لتكون أساس تطبيق «انطلق».
نُسخ المتعقَّب في git فقط (12,509 ملفاً / 302 م.ب) بـ git archive، لا
`cp -r` — فاستُثنيت تلقائياً مخلفات البناء (build · node_modules ·
.dart_tool · .gradle · Pods ≈ 10.7 غ.ب) وكل ما يستثنيه .gitignore.

هذا الكوميت **بلا أي تعديل عمداً** حتى يكون كل ما يليه فرقاً مقروءاً
مقابل سيرو الأصلي. سيرو نفسه لم يُمسّ.

⚠️ لا يبني بعد: `.env` و`lib/env/env.g.dart` غير متعقَّبين في سيرو (وهذا
صحيح — أسرار لكل مستأجر). كل تطبيق فلاتر هنا يحتاج .env خاصاً بانطلق ثم
توليد env.g.dart عبر build_runner. لا تُنسخ أسرار سيرو.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hamza-Ayed
2026-07-27 05:10:29 +03:00
co-authored by Claude Opus 5
commit 92dc6b3641
3654 changed files with 896478 additions and 0 deletions
@@ -0,0 +1,791 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:secure_string_operations/secure_string_operations.dart';
import '../../constant/api_key.dart';
import '../../constant/box_name.dart';
import '../../constant/char_map.dart';
import '../../constant/info.dart';
import '../../constant/links.dart';
import '../../env/env.dart';
import '../../main.dart';
import '../../print.dart';
import '../../views/widgets/snackbar.dart';
import 'device_info.dart';
import 'encrypt_decrypt.dart';
import 'ssl_pinning.dart';
class CRUD {
var dev = '';
final _client = SslPinning.createPinnedClient();
getJWT() async {
// إذا كان الأدمن مسجل دخوله بالفعل، لا تقم بتوليد توكن "ضيف" قديم
if (box.read(BoxName.driverID) != null) {
Log.print('Admin session active. Skipping guest JWT.');
return;
}
// Note: We send 'android' instead of 'web' because the backend's loginAdmin.php
// explicitly validates the audience against 'allowedDriver1' (android) and 'allowedDriver2' (ios).
// Sending 'web' will cause a 400 Bad Request error.
dev = kIsWeb ? 'android' : (Platform.isAndroid ? 'android' : 'ios');
var payload = {
'id': 'admin',
'password': AK.passnpassenger,
'aud': '${AK.allowed}$dev',
};
Log.print('payload: $payload');
var response1 = await _client.post(
Uri.parse(AppLink.loginJwtDriver),
body: payload,
);
if (response1.statusCode == 200) {
final decodedResponse1 = jsonDecode(response1.body);
final jwt = decodedResponse1['jwt'];
Log.print('jwt: $jwt');
await box.write(BoxName.jwt, X.c(X.c(X.c(jwt, cn), cC), cs));
await storage.write(
key: BoxName.jwt, value: X.c(X.c(X.c(jwt, cn), cC), cs));
// await AppInitializer().getKey();
}
}
Future<dynamic> get({
required String link,
Map<String, dynamic>? payload,
}) async {
String token = '';
var rawJwt = box.read(BoxName.jwt);
if (rawJwt == null) {
await getJWT();
rawJwt = box.read(BoxName.jwt);
}
if (rawJwt != null) {
token = r(rawJwt.toString()).split(AppInformation.addd)[0];
try {
if (JwtDecoder.isExpired(token)) {
// If we have an admin ID, we should probably re-login or refresh,
// but for now let's just fall back to guest JWT if needed.
if (box.read(BoxName.driverID) == null) {
await getJWT();
token = r(box.read(BoxName.jwt).toString())
.split(AppInformation.addd)[0];
}
}
} catch (e) {
print('❌ JWT Decode Error: $e');
// If decryption failed, try using raw (maybe it was saved plain)
token = rawJwt.toString().split(AppInformation.addd)[0];
}
}
var url = Uri.parse(link);
Log.print('--- [CRUD GET] ---');
Log.print('URL: $link');
Log.print('Payload: $payload');
var response = await _client.post(
url,
body: payload,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization': 'Bearer $token',
'X-Device-FP': box.read(BoxName.fingerPrint) ?? '',
},
);
Log.print('Status Code: ${response.statusCode}');
String preview = response.body.length > 500
? '${response.body.substring(0, 500)}... (truncated)'
: response.body;
Log.print('Response Body: $preview');
Log.print('------------------');
if (response.statusCode == 200) {
try {
var jsonData = jsonDecode(response.body);
if (jsonData['status'] == 'success') {
return response.body;
}
return jsonData['status'] ?? 'failure';
} catch (e) {
return 'failure';
}
} else if (response.statusCode == 401) {
return 'token_expired';
} else {
return 'failure';
}
}
Future<dynamic> post(
{required String link, Map<String, dynamic>? payload}) async {
var url = Uri.parse(link);
try {
String token = '';
var rawJwt = box.read(BoxName.jwt);
if (rawJwt != null) {
token = r(rawJwt.toString()).split(AppInformation.addd)[0];
try {
if (JwtDecoder.isExpired(token)) {
if (box.read(BoxName.driverID) == null) {
await getJWT();
token = r(box.read(BoxName.jwt).toString())
.split(AppInformation.addd)[0];
}
}
} catch (e) {
token = rawJwt.toString().split(AppInformation.addd)[0];
}
}
Log.print('--- [CRUD POST] ---');
Log.print('URL: $link');
Log.print('Payload: $payload');
var response = await _client.post(
url,
body: payload,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization': 'Bearer $token',
'X-Device-FP': box.read(BoxName.fingerPrint) ?? '',
},
);
Log.print('Status Code: ${response.statusCode}');
String preview = response.body.length > 500
? '${response.body.substring(0, 500)}... (truncated)'
: response.body;
Log.print('Response Body: $preview');
Log.print('-------------------');
if (response.statusCode == 200) {
try {
var jsonData = jsonDecode(response.body);
if (jsonData['status'] == 'success') {
return jsonData;
} else {
return jsonData['status'];
}
} catch (e) {
return 'failure';
}
} else if (response.statusCode == 401) {
return 'token_expired';
} else {
return 'failure';
}
} catch (e) {
// addError('HTTP request error: $e', 'crud().post - HTTP');
return 'failure';
}
}
getJwtWallet() async {
// 1. فحص التوكن المخزن أولاً (Caching) لتقليل طلبات الـ SSO
var cachedWalletJwt = box.read('wallet_jwt');
var cachedWalletExpiry = box.read('wallet_jwt_expiry');
if (cachedWalletJwt != null && cachedWalletExpiry != null) {
int expiryMs = int.tryParse(cachedWalletExpiry.toString()) ?? 0;
// إذا لم ينته بعد (مع هامش أمان 60 ثانية)
if (DateTime.now().millisecondsSinceEpoch < expiryMs - 60000) {
Log.print(
'Using cached Wallet JWT. Expiry: ${DateTime.fromMillisecondsSinceEpoch(expiryMs)}');
return cachedWalletJwt.toString();
}
}
String fingerPrint = await DeviceHelper.getDeviceFingerprint();
final mainTokenEnc = box.read(BoxName.jwt);
if (mainTokenEnc == null) return null;
String mainToken = mainTokenEnc.toString();
// فك تشفير التوكن بنفس طريقة دالة get() التي تعمل بنجاح
try {
mainToken = r(mainTokenEnc.toString()).split(AppInformation.addd)[0];
} catch (e) {
// إذا فشل فك التشفير، نستخدم القيمة كما هي (ربما مخزنة بدون تشفير)
mainToken = mainTokenEnc.toString().split(AppInformation.addd)[0];
}
Log.print('Wallet SSO mainToken length: ${mainToken.length}');
Log.print(
'Wallet SSO token starts with: ${mainToken.substring(0, mainToken.length > 10 ? 10 : mainToken.length)}');
// استخدام الـ SSO للسيرفر الرئيسي إذا كان الأدمن مسجل دخوله
var response1 = await _client.post(
Uri.parse(AppLink.loginWalletAdminV3),
headers: {
'Authorization': 'Bearer $mainToken',
'X-Device-FP': fingerPrint,
},
);
Log.print('Wallet SSO login status: ${response1.statusCode}');
if (response1.statusCode == 200) {
final decoded = jsonDecode(response1.body);
final msg = decoded['message'];
String? jwt;
String? hmac;
if (msg is Map) {
jwt = msg['jwt'];
hmac = msg['hmac'];
} else {
jwt = decoded['jwt'];
hmac = decoded['hmac'];
}
if (hmac != null) await box.write(BoxName.hmac, hmac);
// تخزين التوكن الجديد في الكاش لمدة 10 دقائق (600 ثانية)
if (jwt != null) {
await box.write('wallet_jwt', jwt);
await box.write('wallet_jwt_expiry',
(DateTime.now().millisecondsSinceEpoch + (600 * 1000)).toString());
Log.print('Wallet JWT cached successfully.');
}
return jwt?.toString();
} else {
// Fallback: المحاولة بالطريقة القديمة إذا فشل الـ SSO
var payload = {
'id': box.read(BoxName.driverID) ?? '1',
'password': AK.passnpassenger,
'aud': '${Env.allowedWallet}${kIsWeb ? 'android' : (Platform.isAndroid ? 'android' : 'ios')}',
'fingerPrint': fingerPrint
};
var fallbackRes = await _client.post(
Uri.parse(AppLink.loginWalletAdmin),
body: payload,
);
if (fallbackRes.statusCode == 200) {
final decoded = jsonDecode(fallbackRes.body);
if (decoded['jwt'] != null) return decoded['jwt'].toString();
}
}
return null;
}
Future<dynamic> getWallet({
required String link,
Map<String, dynamic>? payload,
bool isRetry = false,
}) async {
var s = await getJwtWallet();
final hmac = box.read(BoxName.hmac);
var url = Uri.parse(link);
Log.print('--- getWallet Execution ---');
Log.print('URL: $url');
Log.print('JWT: $s');
Log.print('HMAC: $hmac');
Log.print('Is Retry: $isRetry');
Log.print('Payload: $payload');
if (payload != null && hmac != null) {
payload['hmac'] = hmac.toString();
}
try {
var response = await _client.post(
url,
body: payload,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization': 'Bearer $s',
'X-HMAC-Auth': hmac.toString(),
'X-Device-FP': box.read(BoxName.fingerPrint) ?? '',
},
);
Log.print('Status Code: ${response.statusCode}');
Log.print('Response Body: ${response.body}');
if (response.statusCode == 200) {
try {
var jsonData = jsonDecode(response.body);
if (jsonData['status'] == 'success') {
return jsonData;
}
Log.print('Logic Error: Status is not success. Data: $jsonData');
return jsonData['status'] ?? 'failure';
} catch (e) {
Log.print('JSON Decode Error in getWallet: $e');
return 'failure';
}
} else if (response.statusCode == 401 && !isRetry) {
Log.print('Token expired (401). Clearing cache and retrying...');
await box.remove('wallet_jwt');
await box.remove('wallet_jwt_expiry');
return await getWallet(link: link, payload: payload, isRetry: true);
} else {
Log.print('HTTP Error in getWallet. Status: ${response.statusCode}');
return 'failure';
}
} catch (e) {
Log.print('HTTP Request Exception in getWallet: $e');
return 'failure';
}
}
Future<dynamic> postWallet(
{required String link, Map<String, dynamic>? payload}) async {
var s = await getJwtWallet();
Log.print('jwt: $s');
final hmac = box.read(BoxName.hmac);
Log.print('hmac: $hmac');
var url = Uri.parse(link);
Log.print('url: $url');
// إضافة الـ HMAC للـ payload لزيادة التوافقية
if (payload != null && hmac != null) {
payload['hmac'] = hmac.toString();
}
try {
// await LoginDriverController().getJWT();
var response = await _client.post(
url,
body: payload,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization': 'Bearer $s',
'X-HMAC-Auth': hmac.toString(),
'X-Device-FP': box.read(BoxName.fingerPrint) ?? '',
},
);
// Log.print('response.request:${response.request}');
// Log.print('response.body: ${response.body}');
// Log.print('payload:$payload');
if (response.statusCode == 200) {
try {
var jsonData = jsonDecode(response.body);
if (jsonData['status'] == 'success') {
return jsonData;
}
return jsonData['status'] ?? 'failure';
} catch (e) {
return 'failure';
}
} else if (response.statusCode == 401) {
await getJwtWallet();
return 'token_expired';
} else {
return 'failure';
}
} catch (e) {
// addError('HTTP request error: $e', 'crud().post - HTTP');
return 'failure';
}
}
// }
Future sendWhatsAppAuth(String to, message) async {
var res = await CRUD().post(
link: AppLink.send_whatsapp_message,
payload: {'receiver': to, 'message': message});
if (res != 'failure') {
mySnackbarSuccess('Message sent successfully');
} else {
mySnackbarError('Failed to send message');
}
}
Future<dynamic> getAgoraToken({
required String channelName,
required String uid,
}) async {
var res = await _client.get(
Uri.parse(
'https://repulsive-pig-rugby-shirt.cyclic.app/token?channelName=$channelName'),
headers: {'Authorization': 'Bearer ${AK.agoraAppCertificate}'});
if (res.statusCode == 200) {
var response = jsonDecode(res.body);
return response['token'];
} else {}
}
Future<dynamic> getLlama({
required String link,
required String payload,
required String prompt,
}) async {
var url = Uri.parse(
link,
);
var headers = {
'Content-Type': 'application/json',
'Authorization':
'Bearer LL-X5lJ0Px9CzKK0HTuVZ3u2u4v3tGWkImLTG7okGRk4t25zrsLqJ0qNoUzZ2x4ciPy'
// 'Authorization': 'Bearer ${Env.llamaKey}'
};
var data = json.encode({
"model": "Llama-3-70b-Inst-FW",
// "model": "llama-13b-chat",
"messages": [
{
"role": "user",
"content":
"Extract the desired information from the following passage as json decoded like $prompt just in this:\n\n$payload"
}
],
"temperature": 0.9
});
var response = await _client.post(
url,
body: data,
headers: headers,
);
if (response.statusCode == 200) {
return response.body;
}
return response.statusCode;
}
Future allMethodForAI(String prompt, driverID, imagePath) async {}
Map<String, List<Map<String, String>>> getAllTextValuesWithLineNumbers(
Map json) {
Map<String, List<Map<String, String>>> output = {};
int lineNumber = 1;
if (json.containsKey('regions')) {
List<dynamic> regions = json['regions'];
for (Map<String, dynamic> region in regions) {
if (region.containsKey('lines')) {
List<dynamic> lines = region['lines'];
List<Map<String, String>> linesWithText = [];
for (Map<String, dynamic> line in lines) {
if (line.containsKey('words')) {
List<dynamic> words = line['words'];
String lineText = "";
for (Map<String, dynamic> word in words) {
if (word.containsKey('text')) {
lineText += word['text'] + " ";
}
}
lineText = lineText.trim();
linesWithText.add(
{"line_number": lineNumber.toString(), "text": lineText});
lineNumber++;
}
}
output["region_${region.hashCode}"] = linesWithText;
}
}
}
return output;
}
// List<String> getAllTextValues(Map json) {
// List<String> textValues = [];
// if (json.containsKey('regions')) {
// List<dynamic> regions = json['regions'];
// for (Map<String, dynamic> region in regions) {
// if (region.containsKey('lines')) {
// List<dynamic> lines = region['lines'];
// for (Map<String, dynamic> line in lines) {
// if (line.containsKey('words')) {
// List<dynamic> words = line['words'];
// for (Map<String, dynamic> word in words) {
// if (word.containsKey('text')) {
// textValues.add(word['text']);
// }
// }
// }
// }
// }
// }
// }
// return textValues;
// }
Future<dynamic> arabicTextExtractByVisionAndAI({
required String imagePath,
required String driverID,
}) async {
var headers = {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': AK.ocpApimSubscriptionKey
};
String imagePathFull =
'${AppLink.server}/card_image/$imagePath-$driverID.jpg';
var request = http.Request(
'POST',
Uri.parse(
'https://eastus.api.cognitive.microsoft.com/computervision/imageanalysis:analyze?features=caption,read&model-version=latest&language=en&api-version=2024-02-01'));
request.body = json.encode({"url": imagePathFull});
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
return await response.stream.bytesToString();
} else {}
}
Future<dynamic> getChatGPT({
required String link,
required String payload,
}) async {
var url = Uri.parse(
link,
);
var headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ${Env.chatGPTkeySeferNew}'
};
var data = json.encode({
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "user",
"content":
"Extract the desired information from the following passage as json decoded like vin,make,made,year,expiration_date,color,owner,registration_date just in this:\n\n$payload"
}
],
"temperature": 0.9
});
var response = await _client.post(
url,
body: data,
headers: headers,
);
if (response.statusCode == 200) {
return response.body;
}
return response.statusCode;
}
Future<dynamic> kazumiSMS({
required String link,
Map<String, dynamic>? payload,
}) async {
var url = Uri.parse(
link,
);
var headers = {'Content-Type': 'application/json'};
var request = http.Request('POST', url);
request.body = json.encode({
"username": "Sefer",
"password": AK.smsPasswordEgypt,
});
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
var responseBody = await response.stream.bytesToString();
var data = json.decode(responseBody);
return data;
} else {}
}
Future<dynamic> postPayMob({
required String link,
Map<String, dynamic>? payload,
}) async {
// String? basicAuthCredentials =
// await storage.read(key: BoxName.basicAuthCredentials);
var url = Uri.parse(
link,
);
var response = await _client.post(url,
body: payload, headers: {'Content-Type': 'application/json'});
var jsonData = jsonDecode(response.body);
if (response.statusCode == 200) {
if (jsonData['status'] == 'success') {
return response.body;
} else {
return (jsonData['status']);
}
} else {
return response.statusCode;
}
}
sendEmail(
String link,
Map<String, String>? payload,
) async {
var headers = {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
};
var request = http.Request('POST', Uri.parse(link));
request.bodyFields = payload!;
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
} else {}
}
Future<dynamic> postFromDialogue({
required String link,
Map<String, dynamic>? payload,
}) async {
// String? basicAuthCredentials =
// await storage.read(key: BoxName.basicAuthCredentials);
var url = Uri.parse(
link,
);
var response = await _client.post(
url,
body: payload,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
},
);
if (response.body.isNotEmpty) {
var jsonData = jsonDecode(response.body);
if (response.statusCode == 200) {
if (jsonData['status'] == 'success') {
Get.back();
// Get.snackbar(
// jsonData['status'],
// jsonData['message'],
// );
return response.body;
}
}
return (jsonData['status']);
}
}
Future<void> sendVerificationRequest(String phoneNumber) async {
final accountSid = AK.accountSIDTwillo;
final authToken = AK.authTokenTwillo;
final verifySid = AK.twilloRecoveryCode;
final Uri verificationUri = Uri.parse(
'https://verify.twilio.com/v2/Services/$verifySid/Verifications');
// Send the verification request
final response = await _client.post(
verificationUri,
headers: {
'Authorization':
'Basic ${base64Encode(utf8.encode('$accountSid:$authToken'))}',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: {
'To': phoneNumber,
'Channel': 'sms',
},
);
if (response.statusCode == 201) {
} else {}
// Prompt the user to enter the OTP
const otpCode = "123456"; // Replace with user input
// Check the verification code
final checkUri = Uri.parse(
'https://verify.twilio.com/v2/Services/$verifySid/VerificationCheck');
final checkResponse = await _client.post(
checkUri,
headers: {
'Authorization':
'Basic ${base64Encode(utf8.encode('$accountSid:$authToken'))}',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: {
'To': phoneNumber,
'Code': otpCode,
},
);
if (checkResponse.statusCode == 201) {
} else {}
}
Future<dynamic> getGoogleApi({
required String link,
Map<String, dynamic>? payload,
}) async {
var url = Uri.parse(
link,
);
var response = await _client.post(
url,
body: payload,
);
var jsonData = jsonDecode(response.body);
if (jsonData['status'] == 'OK') {
return jsonData;
}
return (jsonData['status']);
}
Future<dynamic> update({
required String endpoint,
required Map<String, dynamic> data,
required String id,
}) async {
// String? basicAuthCredentials =
// await storage.read(key: BoxName.basicAuthCredentials);
var url = Uri.parse('$endpoint/$id');
var response = await http.put(
url,
body: json.encode(data),
headers: {
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
},
);
return json.decode(response.body);
}
Future<dynamic> delete({
required String endpoint,
required String id,
}) async {
// String? basicAuthCredentials =
// await storage.read(key: BoxName.basicAuthCredentials);
var url = Uri.parse('$endpoint/$id');
var response = await http.delete(
url,
headers: {
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
},
);
return json.decode(response.body);
}
List phoneDriversTest = [
201023248456,
201023248456,
];
}
@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
class LineChartPainter extends CustomPainter {
final List<double> data;
LineChartPainter(this.data);
@override
void paint(Canvas canvas, Size size) {
// Calculate the scale factor.
final scaleFactor = size.height / 240;
// Draw the line chart.
for (var i = 0; i < data.length - 1; i++) {
final x1 = i * size.width / data.length;
final y1 = data[i] * scaleFactor;
final x2 = (i + 1) * size.width / data.length;
final y2 = data[i + 1] * scaleFactor;
canvas.drawLine(Offset(x1, y1), Offset(x2, y2), Paint());
}
}
@override
bool shouldRepaint(LineChartPainter oldDelegate) => false;
}
@@ -0,0 +1,148 @@
import 'dart:async';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jailbreak_root_detection/jailbreak_root_detection.dart';
import 'package:package_info_plus/package_info_plus.dart';
import '../../main.dart';
import '../../print.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
class DeviceHelper {
static Future<String> getDeviceFingerprint() async {
final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
Map<String, dynamic> deviceData;
try {
if (kIsWeb) {
WebBrowserInfo webInfo = await deviceInfoPlugin.webBrowserInfo;
return '${webInfo.vendor}_${webInfo.browserName.name}';
}
if (Platform.isAndroid) {
// Fetch Android-specific device information
AndroidDeviceInfo androidInfo = await deviceInfoPlugin.androidInfo;
deviceData = androidInfo.toMap(); // Convert to a map for easier access
} else if (Platform.isIOS) {
// Fetch iOS-specific device information
IosDeviceInfo iosInfo = await deviceInfoPlugin.iosInfo;
deviceData = iosInfo.toMap(); // Convert to a map for easier access
} else if (Platform.isMacOS) {
// Fetch macOS-specific device information
MacOsDeviceInfo macInfo = await deviceInfoPlugin.macOsInfo;
deviceData = macInfo.toMap();
} else {
return 'unknown_platform';
}
String deviceId = 'unknown';
if (Platform.isAndroid) {
deviceId = deviceData['fingerprint'] ?? 'unknown';
} else if (Platform.isIOS) {
deviceId = deviceData['identifierForVendor'] ?? 'unknown';
} else if (Platform.isMacOS) {
deviceId = deviceData['systemGUID'] ?? 'unknown';
}
final String deviceModel = deviceData['model'] ?? 'unknown';
final String fingerprint = '${deviceId}_$deviceModel';
print(fingerprint);
return (fingerprint);
} catch (e) {
throw Exception('Failed to generate device fingerprint');
}
}
}
class SecurityHelper {
/// Performs security checks and handles potential risks
static Future<void> performSecurityChecks() async {
bool isNotTrust = false;
bool isJailBroken = false;
bool isRealDevice = true;
bool isTampered = false;
String bundleId = "";
try {
isNotTrust = await JailbreakRootDetection.instance.isNotTrust;
isJailBroken = await JailbreakRootDetection.instance.isJailBroken;
isRealDevice = await JailbreakRootDetection.instance.isRealDevice;
PackageInfo packageInfo = await PackageInfo.fromPlatform();
bundleId = packageInfo.packageName;
if (bundleId.isNotEmpty) {
isTampered = await JailbreakRootDetection.instance.isTampered(bundleId);
}
} catch (e) {
Log.print("Error during security checks: $e");
}
await box.write('isNotTrust', isNotTrust);
await box.write('isTampered', isTampered);
await box.write('isJailBroken', isJailBroken);
if (isJailBroken || isRealDevice == false || isTampered) {
_showSecurityWarning();
}
}
static Future<void> clearAllData() async {
await box.erase();
exit(0);
}
static void _showSecurityWarning() {
final secondsRemaining = RxInt(10);
Get.dialog(
CupertinoAlertDialog(
title: Text("Security Warning".tr),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Text(
"Potential security risks detected. The application will close in @seconds seconds."
.trParams({
'seconds': secondsRemaining.value.toString(),
}),
)),
SizedBox(height: 24),
Obx(() => SizedBox(
width: double.infinity,
child: CupertinoActivityIndicator(
radius: 15,
animating: true,
))),
SizedBox(height: 8),
Obx(() => ClipRRect(
borderRadius: BorderRadius.circular(8),
child: LinearProgressIndicator(
value: secondsRemaining.value / 10,
backgroundColor: Colors.grey.shade300,
valueColor: AlwaysStoppedAnimation<Color>(
CupertinoColors.systemRed),
minHeight: 8,
),
)),
],
),
),
barrierDismissible: false,
);
Timer.periodic(Duration(seconds: 1), (timer) {
secondsRemaining.value--;
if (secondsRemaining.value <= 0) {
timer.cancel();
_clearDataAndExit();
}
});
}
static Future<void> _clearDataAndExit() async {
await box.erase();
exit(0);
}
}
@@ -0,0 +1,40 @@
import 'package:flutter/services.dart';
class DigitObscuringFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
final maskedText = maskDigits(newValue.text);
return newValue.copyWith(
text: maskedText,
selection: updateCursorPosition(maskedText, newValue.selection));
}
String maskDigits(String text) {
final totalDigits = text.length;
final visibleDigits = 4;
final hiddenDigits = totalDigits - visibleDigits * 2;
final firstVisibleDigits = text.substring(0, visibleDigits);
final lastVisibleDigits = text.substring(totalDigits - visibleDigits);
final maskedDigits = List.filled(hiddenDigits, '*').join();
return '$firstVisibleDigits$maskedDigits$lastVisibleDigits';
}
TextSelection updateCursorPosition(
String maskedText, TextSelection currentSelection) {
final cursorPosition = currentSelection.baseOffset;
final totalDigits = maskedText.length;
const visibleDigits = 4;
final hiddenDigits = totalDigits - visibleDigits * 2;
final updatedPosition = cursorPosition <= visibleDigits
? cursorPosition
: hiddenDigits + visibleDigits + (cursorPosition - visibleDigits);
return TextSelection.collapsed(
offset: updatedPosition, affinity: currentSelection.affinity);
}
}
@@ -0,0 +1,41 @@
// import 'dart:io';
//
// import 'package:get/get.dart';
// import 'package:image_picker/image_picker.dart';
// import 'package:google_ml_kit/google_ml_kit.dart';
//
// class ImagePickerController extends GetxController {
// RxBool textScanning = false.obs;
// RxString scannedText = ''.obs;
//
// Future<void> getImage(ImageSource source) async {
// try {
// final pickedImage = await ImagePicker().pickImage(source: source);
// if (pickedImage != null) {
// textScanning.value = true;
// final imageFile = File(pickedImage.path);
// getRecognisedText(imageFile);
// }
// } catch (e) {
// textScanning.value = false;
// scannedText.value = "Error occurred while scanning";
// }
// }
//
// Future<void> getRecognisedText(File image) async {
// final inputImage = InputImage.fromFilePath(image.path);
// final textDetector = GoogleMlKit.vision.textRecognizer();
// final RecognizedText recognisedText =
// await textDetector.processImage(inputImage);
// await textDetector.close();
//
// scannedText.value = '';
// for (TextBlock block in recognisedText.blocks) {
// for (TextLine line in block.lines) {
// scannedText.value += line.text + '\n';
// }
// }
//
// textScanning.value = false;
// }
// }
@@ -0,0 +1,77 @@
import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:flutter/foundation.dart';
import 'package:secure_string_operations/secure_string_operations.dart';
import '../../constant/char_map.dart';
import '../../env/env.dart';
class EncryptionHelper {
static EncryptionHelper? _instance;
late final encrypt.Key key;
late final encrypt.IV iv;
EncryptionHelper._(this.key, this.iv);
static EncryptionHelper get instance {
if (_instance == null) {
throw Exception(
"EncryptionHelper is not initialized. Call `await EncryptionHelper.initialize()` in main.");
}
return _instance!;
}
/// Initializes and stores the instance globally
static Future<void> initialize() async {
if (_instance != null) {
debugPrint("EncryptionHelper is already initialized.");
return; // Prevent re-initialization
}
debugPrint("Initializing EncryptionHelper...");
var keyOfApp = r(Env.keyOfApp).toString().split(Env.addd)[0];
// Log.print('keyOfApp: ${keyOfApp}');
var initializationVector =
r(Env.initializationVector).toString().split(Env.addd)[0];
// Log.print('initializationVector: ${initializationVector}');
// Set the global instance
_instance = EncryptionHelper._(
encrypt.Key.fromUtf8(keyOfApp),
encrypt.IV.fromUtf8(initializationVector),
);
debugPrint("EncryptionHelper initialized successfully.");
}
/// Encrypts a string
String encryptData(String plainText) {
try {
final encrypter =
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
final encrypted = encrypter.encrypt(plainText, iv: iv);
return encrypted.base64;
} catch (e) {
debugPrint('Encryption Error: $e');
return '';
}
}
/// Decrypts a string
String decryptData(String encryptedText) {
try {
final encrypter =
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
final encrypted = encrypt.Encrypted.fromBase64(encryptedText);
return encrypter.decrypt(encrypted, iv: iv);
} catch (e) {
debugPrint('Decryption Error: $e');
return '';
}
}
}
r(String string) {
return X.r(X.r(X.r(string, cn), cC), cs).toString();
}
c(String string) {
return X.c(X.c(X.c(string, cn), cC), cs).toString();
}
@@ -0,0 +1,829 @@
// import 'dart:convert';
// import 'dart:io';
// import 'package:get/get.dart';
// import 'package:image_cropper/image_cropper.dart';
// import 'package:image_picker/image_picker.dart';
// import 'package:http/http.dart' as http;
// import 'package:image/image.dart' as img;
// import 'package:path_provider/path_provider.dart';
// import '../../constant/api_key.dart';
// import '../../constant/colors.dart';
// class AI extends GetxController {
// final picker = ImagePicker();
// Map<String, dynamic> responseMap = {};
// Map<String, dynamic> responseCarLicenseMap = {};
// Map<String, dynamic> responseBackCarLicenseMap = {};
// Map<String, dynamic> responseIdCardeMap = {};
// bool isloading = false;
// var image;
// CroppedFile? croppedFile;
// DateTime now = DateTime.now();
// Future<void> pickImage() async {
// final pickedImage = await picker.pickImage(source: ImageSource.gallery);
// if (pickedImage != null) {
// image = File(pickedImage.path);
// // Crop the image
// croppedFile = await ImageCropper().cropImage(
// sourcePath: image!.path,
// aspectRatioPresets: [
// CropAspectRatioPreset.square,
// CropAspectRatioPreset.ratio3x2,
// CropAspectRatioPreset.original,
// CropAspectRatioPreset.ratio4x3,
// CropAspectRatioPreset.ratio16x9
// ],
// uiSettings: [
// AndroidUiSettings(
// toolbarTitle: 'Cropper'.tr,
// toolbarColor: AppColor.blueColor,
// toolbarWidgetColor: AppColor.yellowColor,
// initAspectRatio: CropAspectRatioPreset.original,
// lockAspectRatio: false),
// IOSUiSettings(
// title: 'Cropper'.tr,
// ),
// ],
// );
// // image = croppedFile;
// // Resize the image
// final rawImage =
// img.decodeImage(File(croppedFile!.path).readAsBytesSync());
// final resizedImage =
// img.copyResize(rawImage!, width: 800); // Adjust the width as needed
// final appDir = await getTemporaryDirectory();
// final resizedImagePath = '${appDir.path}/resized_image.jpg';
// final resizedImageFile = File(resizedImagePath);
// resizedImageFile.writeAsBytesSync(
// img.encodeJpg(resizedImage)); // Save the resized image as JPEG
// image = resizedImageFile;
// update();
// }
// }
// Future<void> generateContent() async {
// await pickImage();
// if (image != null) {
// final imageBytes = await image.readAsBytes();
// final imageData = base64Encode(imageBytes);
// var requestBody = jsonEncode({
// 'contents': [
// {
// 'parts': [
// {
// 'inlineData': {
// 'mimeType': 'image/jpeg',
// 'data': imageData,
// },
// },
// {
// 'text':
// 'write json for all data as first name ,last name,dob,licenseID,expiration date,issued date asdress class type ,output json type',
// },
// ],
// },
// ],
// 'generationConfig': {
// 'temperature': 0.4,
// 'topK': 32,
// 'topP': 1,
// 'maxOutputTokens': 4096,
// 'stopSequences': [],
// },
// 'safetySettings': [
// {
// 'category': 'HARM_CATEGORY_HARASSMENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_HATE_SPEECH',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// ],
// });
// final response = await http.post(
// Uri.parse(
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'),
// headers: {'Content-Type': 'application/json'},
// body: requestBody,
// );
// if (response.statusCode == 200) {
// var responseData = jsonDecode(response.body);
// // Process the responseData as needed
// var result =
// responseData['candidates'][0]['content']['parts'][0]['text'];
// RegExp regex = RegExp(r"```json([^`]*)```");
// String? jsonString =
// regex.firstMatch(responseData.toString())?.group(1)?.trim();
// if (jsonString != null) {
// // Convert the JSON object to a String
// jsonString = jsonEncode(json.decode(jsonString));
// } else {
// }
// // Rest of your code...
// } else {
// }
// } else {
// }
// }
// Future<void> geminiAiExtraction(String prompt, payload) async {
// var requestBody = jsonEncode({
// 'contents': [
// {
// 'parts': [
// // {
// // 'inlineData': {
// // 'mimeType': 'image/jpeg',
// // 'data': imageData,
// // },
// // },
// {
// 'text':
// "Extract the desired information from the following passage as json decoded like $prompt .and look for this instruction first name in line 3or 2 ,fullname in line 4 from it written left to right but you modify it rtl,address in line 5 it written left to right but you modify it rtl and 6,dob,nationalid in the last line as just in this:\n\n$payload"
// },
// ],
// },
// ],
// 'generationConfig': {
// 'temperature': 0.4,
// 'topK': 32,
// 'topP': 1,
// 'maxOutputTokens': 4096,
// 'stopSequences': [],
// },
// 'safety_settings': [
// {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
// {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
// {
// "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
// "threshold": "BLOCK_NONE"
// },
// {
// "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
// "threshold": "BLOCK_NONE"
// },
// ]
// });
// final response = await http.post(
// Uri.parse(
// // 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'),
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent?key=AIzaSyCyoLcSkDzK5_SMe00nhut56SSXWPR074w'),
// headers: {'Content-Type': 'application/json'},
// body: requestBody,
// );
// if (response.statusCode == 200) {
// var responseData = jsonDecode(response.body);
// // Process the responseData as needed
// var result = responseData['candidates'][0]['content']['parts'][0]['text'];
// RegExp regex = RegExp(r"```json([^`]*)```");
// String? jsonString =
// regex.firstMatch(responseData.toString())?.group(1)?.trim();
// if (jsonString != null) {
// // Convert the JSON object to a String
// jsonString = jsonEncode(json.decode(jsonString));
// } else {
// }
// // Rest of your code...
// } else {
// }
// }
// Future<void> getDriverLicenseJordanContent() async {
// await pickImage();
// isloading = true;
// update();
// if (image != null) {
// final imageBytes = await image.readAsBytes();
// final imageData = base64Encode(imageBytes);
// var requestBody = jsonEncode({
// 'contents': [
// {
// 'parts': [
// {
// 'inlineData': {
// 'mimeType': 'image/jpeg',
// 'data': imageData,
// },
// },
// {
// 'text':
// 'write json for all data as first name ,last name,dob,id ,expiration date,issued date asdress class type,age in years ,output json type in arabic value and stay engish key and make date format like YYYY-MM-DD , for name please extract name in arabic in Name in json plus first_name ',
// },
// ],
// },
// ],
// 'generationConfig': {
// 'temperature': 0.4,
// 'topK': 32,
// 'topP': 1,
// 'maxOutputTokens': 4096,
// 'stopSequences': [],
// },
// 'safetySettings': [
// {
// 'category': 'HARM_CATEGORY_HARASSMENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_HATE_SPEECH',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// ],
// });
// final response = await http.post(
// Uri.parse(
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'),
// headers: {'Content-Type': 'application/json'},
// body: requestBody,
// );
// isloading = false;
// update();
// if (response.statusCode == 200) {
// var responseData = jsonDecode(response.body);
// // Process the responseData as needed
// var result =
// responseData['candidates'][0]['content']['parts'][0]['text'];
// RegExp regex = RegExp(r"```json([^`]*)```");
// String? jsonString =
// regex.firstMatch(responseData.toString())?.group(1)?.trim();
// if (jsonString != null) {
// // Convert the JSON object to a String
// jsonString = jsonEncode(json.decode(jsonString));
// responseMap = jsonDecode(jsonString);
// } else {
// }
// // Rest of your code...
// } else {
// }
// } else {
// }
// }
// Future<void> getCarLicenseJordanContent() async {
// await pickImage();
// isloading = true;
// update();
// if (image != null) {
// final imageBytes = await image.readAsBytes();
// final imageData = base64Encode(imageBytes);
// var requestBody = jsonEncode({
// 'contents': [
// {
// 'parts': [
// {
// 'inlineData': {
// 'mimeType': 'image/jpeg',
// 'data': imageData,
// },
// },
// {
// 'text':
// '''Extract the following information from the front face of the Jordanian ID card:
// Name
// National ID number
// Gender
// Date of birth
// Output the extracted information in the following JSON format''',
// },
// ],
// },
// ],
// 'generationConfig': {
// 'temperature': 0.4,
// 'topK': 32,
// 'topP': 1,
// 'maxOutputTokens': 4096,
// 'stopSequences': [],
// },
// 'safetySettings': [
// {
// 'category': 'HARM_CATEGORY_HARASSMENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_HATE_SPEECH',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// ],
// });
// final response = await http.post(
// Uri.parse(
// // 'https://${API_ENDPOINT}/v1/projects/${PROJECT_ID}/locations/${LOCATION_ID}/publishers/google/models/${MODEL_ID}:streamGenerateContent'),
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'),
// headers: {'Content-Type': 'application/json'},
// body: requestBody,
// );
// isloading = false;
// update();
// if (response.statusCode == 200) {
// var responseData = jsonDecode(response.body);
// // Process the responseData as needed
// var result =
// responseData['candidates'][0]['content']['parts'][0]['text'];
// RegExp regex = RegExp(r"```json([^`]*)```");
// String? jsonString =
// regex.firstMatch(responseData.toString())?.group(1)?.trim();
// if (jsonString != null) {
// // Convert the JSON object to a String
// jsonString = jsonEncode(json.decode(jsonString));
// responseCarLicenseMap = jsonDecode(jsonString);
// } else {
// }
// // Rest of your code...
// } else {
// }
// } else {
// }
// }
// Future<void> jordanID() async {
// await pickImage();
// isloading = true;
// update();
// if (image != null) {
// final imageBytes = await image.readAsBytes();
// final imageData = base64Encode(imageBytes);
// var requestBody = jsonEncode({
// 'contents': [
// {
// 'parts': [
// {
// 'inlineData': {
// 'mimeType': 'image/jpeg',
// 'data': imageData,
// },
// },
// {
// 'text':
// '''Extract the following information from the front face of the Jordanian ID card:
// Name
// National ID number
// Gender
// Date of birth
// Output the extracted information in the following JSON format''',
// },
// ],
// },
// ],
// 'generationConfig': {
// 'temperature': 0.4,
// 'topK': 32,
// 'topP': 1,
// 'maxOutputTokens': 4096,
// 'stopSequences': [],
// },
// 'safetySettings': [
// {
// 'category': 'HARM_CATEGORY_HARASSMENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_HATE_SPEECH',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// ],
// });
// final response = await http.post(
// Uri.parse(
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'),
// headers: {'Content-Type': 'application/json'},
// body: requestBody,
// );
// isloading = false;
// update();
// if (response.statusCode == 200) {
// var responseData = jsonDecode(response.body);
// // Process the responseData as needed
// var result =
// responseData['candidates'][0]['content']['parts'][0]['text'];
// RegExp regex = RegExp(r"```json([^`]*)```");
// String? jsonString =
// regex.firstMatch(responseData.toString())?.group(1)?.trim();
// if (jsonString != null) {
// // Convert the JSON object to a String
// jsonString = jsonEncode(json.decode(jsonString));
// responseCarLicenseMap = jsonDecode(jsonString);
// } else {
// }
// // Rest of your code...
// } else {
// }
// } else {
// }
// }
// Future<void> carLicenseJordan() async {
// await pickImage();
// isloading = true;
// update();
// if (image != null) {
// final imageBytes = await image.readAsBytes();
// final imageData = base64Encode(imageBytes);
// var requestBody = jsonEncode({
// 'contents': [
// {
// 'parts': [
// {
// 'inlineData': {
// 'mimeType': 'image/jpeg',
// 'data': imageData,
// },
// },
// {
// 'text':
// '''Extract the following information from the front face of the car license card in Jordan:
// * name
// * Address
// * Vehicle type
// * car_kind
// * car_color
// * Vehicle category
// * car_year
// * car_plate
// * Registration type
// * Usage type
// * expire_date_of_license
// Output the extracted information in the following JSON formate and make date format like YYYY-MM-DD''',
// },
// ],
// },
// ],
// 'generationConfig': {
// 'temperature': 0.4,
// 'topK': 32,
// 'topP': 1,
// 'maxOutputTokens': 4096,
// 'stopSequences': [],
// },
// 'safetySettings': [
// {
// 'category': 'HARM_CATEGORY_HARASSMENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_HATE_SPEECH',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// ],
// });
// final response = await http.post(
// Uri.parse(
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro-vision-latest:generateContent?key=${AK.geminiApi}'),
// headers: {'Content-Type': 'application/json'},
// body: requestBody,
// );
// isloading = false;
// update();
// if (response.statusCode == 200) {
// var responseData = jsonDecode(response.body);
// // Process the responseData as needed
// var result =
// responseData['candidates'][0]['content']['parts'][0]['text'];
// RegExp regex = RegExp(r"```json([^`]*)```");
// String? jsonString =
// regex.firstMatch(responseData.toString())?.group(1)?.trim();
// if (jsonString != null) {
// // Convert the JSON object to a String
// jsonString = jsonEncode(json.decode(jsonString));
// responseCarLicenseMap = jsonDecode(jsonString);
// } else {
// }
// // Rest of your code...
// } else {
// }
// } else {
// }
// }
// Future getTextFromCard(String prompt) async {
// await pickImage();
// isloading = true;
// update();
// if (image != null) {
// final imageBytes = await image.readAsBytes();
// final imageData = base64Encode(imageBytes);
// var requestBody = jsonEncode({
// 'contents': [
// {
// 'parts': [
// {
// 'inlineData': {
// 'mimeType': 'image/jpeg',
// 'data': imageData,
// },
// },
// {
// 'text': prompt,
// },
// ],
// },
// ],
// 'generationConfig': {
// "temperature": 1,
// "topK": 32,
// "topP": 0.1,
// "maxOutputTokens": 4096,
// "stopSequences": []
// },
// 'safetySettings': [
// {
// 'category': 'HARM_CATEGORY_HARASSMENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_HATE_SPEECH',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// ],
// });
// final response = await http.post(
// Uri.parse(
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro-vision-latest:generateContent?key=${AK.geminiApi}'),
// headers: {'Content-Type': 'application/json'},
// body: requestBody,
// );
// isloading = false;
// update();
// if (response.statusCode == 200) {
// var responseData = jsonDecode(response.body);
// // Process the responseData as needed
// var result =
// responseData['candidates'][0]['content']['parts'][0]['text'];
// RegExp regex = RegExp(r"```json([^`]*)```");
// String? jsonString =
// regex.firstMatch(responseData.toString())?.group(1)?.trim();
// if (jsonString != null) {
// // Convert the JSON object to a String
// jsonString = jsonEncode(json.decode(jsonString));
// responseBackCarLicenseMap = jsonDecode(jsonString);
// } else {
// }
// // Rest of your code...
// } else {
// }
// } else {
// }
// }
// Future<void> generateBackCarLicenseJordanContent() async {
// await pickImage();
// isloading = true;
// update();
// if (image != null) {
// final imageBytes = await image.readAsBytes();
// final imageData = base64Encode(imageBytes);
// var requestBody = jsonEncode({
// 'contents': [
// {
// 'parts': [
// {
// 'inlineData': {
// 'mimeType': 'image/jpeg',
// 'data': imageData,
// },
// },
// {
// 'text':
// 'write json output from extracting car license back face for these key ,vin,fuelType,passengerType,curbWeight,insuranceCompany,policyNumber,notes,insuranceType and output it json .dont add data else this image',
// },
// ],
// },
// ],
// 'generationConfig': {
// 'temperature': 0.4,
// 'topK': 343,
// 'topP': 1,
// 'maxOutputTokens': 4096,
// 'stopSequences': [],
// },
// 'safetySettings': [
// {
// 'category': 'HARM_CATEGORY_HARASSMENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_HATE_SPEECH',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// ],
// });
// final response = await http.post(
// Uri.parse(
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'),
// headers: {'Content-Type': 'application/json'},
// body: requestBody,
// );
// isloading = false;
// update();
// if (response.statusCode == 200) {
// var responseData = jsonDecode(response.body);
// // Process the responseData as needed
// var result =
// responseData['candidates'][0]['content']['parts'][0]['text'];
// RegExp regex = RegExp(r"```json([^`]*)```");
// String? jsonString =
// regex.firstMatch(responseData.toString())?.group(1)?.trim();
// if (jsonString != null) {
// // Convert the JSON object to a String
// jsonString = jsonEncode(json.decode(jsonString));
// responseBackCarLicenseMap = jsonDecode(jsonString);
// } else {
// }
// // Rest of your code...
// } else {
// }
// } else {
// }
// }
// Future<void> getFromCarRegistration() async {
// await pickImage();
// if (image != null) {
// final imageBytes = await image.readAsBytes();
// final imageData = base64Encode(imageBytes);
// var requestBody = jsonEncode({
// 'contents': [
// {
// 'parts': [
// {
// 'inlineData': {
// 'mimeType': 'image/jpeg',
// 'data': imageData,
// },
// },
// {
// 'text':
// 'write output json from image for[ vin, make, model, year, expiration_date, color, owner, registration_date ],output json type ',
// },
// ],
// },
// ],
// 'generationConfig': {
// 'temperature': 0.4,
// 'topK': 32,
// 'topP': 1,
// 'maxOutputTokens': 4096,
// 'stopSequences': [],
// },
// 'safetySettings': [
// {
// 'category': 'HARM_CATEGORY_HARASSMENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_HATE_SPEECH',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// {
// 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
// 'threshold': 'BLOCK_MEDIUM_AND_ABOVE',
// },
// ],
// });
// final response = await http.post(
// Uri.parse(
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'),
// headers: {'Content-Type': 'application/json'},
// body: requestBody,
// );
// if (response.statusCode == 200) {
// var responseData = jsonDecode(response.body);
// // Process the responseData as needed
// var result =
// responseData['candidates'][0]['content']['parts'][0]['text'];
// RegExp regex = RegExp(r"```json([^`]*)```");
// String? jsonString =
// regex.firstMatch(responseData.toString())?.group(1)?.trim();
// if (jsonString != null) {
// // Convert the JSON object to a String
// jsonString = jsonEncode(json.decode(jsonString));
// } else {
// }
// // Rest of your code...
// } else {
// }
// } else {
// }
// }
// @override
// void onInit() {
// // generateContent();
// super.onInit();
// }
// }
@@ -0,0 +1,71 @@
import 'package:url_launcher/url_launcher.dart';
import 'dart:io';
void showInBrowser(String url) async {
if (await canLaunchUrl(Uri.parse(url))) {
launchUrl(Uri.parse(url));
} else {}
}
Future<void> makePhoneCall(String phoneNumber) async {
final Uri launchUri = Uri(
scheme: 'tel',
path: phoneNumber,
);
await launchUrl(launchUri);
}
void launchCommunication(
String method, String contactInfo, String message) async {
String url;
if (Platform.isIOS) {
switch (method) {
case 'phone':
url = 'tel:$contactInfo';
break;
case 'sms':
url = 'sms:$contactInfo?body=$message';
break;
case 'whatsapp':
url = 'https://api.whatsapp.com/send?phone=$contactInfo&text=$message';
break;
case 'email':
url = 'mailto:$contactInfo?subject=Subject&body=$message';
break;
default:
return;
}
} else if (Platform.isAndroid) {
switch (method) {
case 'phone':
url = 'tel:$contactInfo';
break;
case 'sms':
url = 'sms:$contactInfo?body=$message';
break;
case 'whatsapp':
url = 'whatsapp://send?phone=$contactInfo&text=$message';
break;
case 'email':
url = 'mailto:$contactInfo?subject=Subject&body=$message';
break;
default:
return;
}
} else {
return;
}
if (await canLaunchUrl(Uri.parse(url))) {
launchUrl(Uri.parse(url));
} else {}
}
@@ -0,0 +1,36 @@
import 'dart:convert';
import '../../constant/links.dart';
import 'crud.dart';
class LlamaAi {
Future<Map> getCarRegistrationData(String input, prompt) async {
Map exrtatDataFinal = {};
String oneLine = input.replaceAll('\n', ' ');
// var res = await CRUD().getLlama(link: AppLink.gemini, payload: oneLine);
var res = await CRUD()
.getLlama(link: AppLink.llama, payload: oneLine, prompt: prompt);
var decod = jsonDecode(res.toString());
// exrtatDataFinal = jsonDecode(extractDataFromJsonString(decod['choices']));
extractDataFromJsonString(decod['choices'][0]['message']['content']);
return exrtatDataFinal;
}
String extractDataFromJsonString(String jsonString) {
// Remove any leading or trailing whitespace from the string
jsonString = jsonString.trim();
// Extract the JSON substring from the given string
final startIndex = jsonString.indexOf('{');
final endIndex = jsonString.lastIndexOf('}');
final jsonSubstring = jsonString.substring(startIndex, endIndex + 1);
// Parse the JSON substring into a Map
final jsonData = jsonDecode(jsonSubstring);
// Return the extracted data
return jsonEncode(jsonData);
}
}
@@ -0,0 +1,133 @@
// import 'dart:async';
// import 'package:get/get.dart';
// import 'package:google_maps_flutter/google_maps_flutter.dart';
// import 'package:location/location.dart';
// import '../../constant/box_name.dart';
// import '../../constant/links.dart';
// import '../../main.dart';
// import 'crud.dart';
// // LocationController.dart
// class LocationController extends GetxController {
// LocationData? _currentLocation;
// late Location location;
// bool isLoading = false;
// late double heading = 0;
// late double accuracy = 0;
// late double previousTime = 0;
// late double latitude;
// late double totalDistance = 0;
// late double longitude;
// late DateTime time;
// late double speed = 0;
// late double speedAccuracy = 0;
// late double headingAccuracy = 0;
// bool isActive = false;
// late LatLng myLocation;
// String totalPoints = '0';
// LocationData? get currentLocation => _currentLocation;
// Timer? _locationTimer;
// @override
// void onInit() async {
// super.onInit();
// location = Location();
// getLocation();
// // startLocationUpdates();
// }
// Future<void> startLocationUpdates() async {
// if (box.read(BoxName.driverID) != null) {
// _locationTimer =
// Timer.periodic(const Duration(seconds: 5), (timer) async {
// try {
// // if (isActive) {
// if (double.parse(totalPoints) > -300) {
// await getLocation();
// // if (box.read(BoxName.driverID) != null) {
// await CRUD()
// .post(link: AppLink.addCarsLocationByPassenger, payload: {
// 'driver_id': box.read(BoxName.driverID).toString(),
// 'latitude': myLocation.latitude.toString(),
// 'longitude': myLocation.longitude.toString(),
// 'heading': heading.toString(),
// 'speed': (speed * 3.6).toStringAsFixed(1),
// 'distance': totalDistance == 0
// ? '0'
// : totalDistance < 1
// ? totalDistance.toStringAsFixed(3)
// : totalDistance.toStringAsFixed(1),
// 'status': box.read(BoxName.statusDriverLocation).toString()
// });
// }
// } catch (e) {
// // Handle the error gracefully
// }
// });
// }
// }
// void stopLocationUpdates() {
// _locationTimer?.cancel();
// }
// Future<void> getLocation() async {
// // isLoading = true;
// // update();
// bool serviceEnabled;
// PermissionStatus permissionGranted;
// // Check if location services are enabled
// serviceEnabled = await location.serviceEnabled();
// if (!serviceEnabled) {
// serviceEnabled = await location.requestService();
// if (!serviceEnabled) {
// // Location services are still not enabled, handle the error
// return;
// }
// }
// // Check if the app has permission to access location
// permissionGranted = await location.hasPermission();
// if (permissionGranted == PermissionStatus.denied) {
// permissionGranted = await location.requestPermission();
// if (permissionGranted != PermissionStatus.granted) {
// // Location permission is still not granted, handle the error
// return;
// }
// }
// // Configure location accuracy
// // LocationAccuracy desiredAccuracy = LocationAccuracy.high;
// // Get the current location
// LocationData _locationData = await location.getLocation();
// myLocation =
// (_locationData.latitude != null && _locationData.longitude != null
// ? LatLng(_locationData.latitude!, _locationData.longitude!)
// : null)!;
// speed = _locationData.speed!;
// heading = _locationData.heading!;
// // isLoading = false;
// update();
// }
// double calculateDistanceInKmPerHour(
// double? startTime, double? endTime, double speedInMetersPerSecond) {
// // Calculate the time difference in hours
// double timeDifferenceInHours = (endTime! - startTime!) / 1000 / 3600;
// // Convert speed to kilometers per hour
// double speedInKmPerHour = speedInMetersPerSecond * 3.6;
// // Calculate the distance in kilometers
// double distanceInKilometers = speedInKmPerHour * timeDifferenceInHours;
// return distanceInKilometers;
// }
// }
@@ -0,0 +1,16 @@
// import 'package:location/location.dart';
// import 'package:get/get.dart';
// class LocationPermissions {
// late Location location;
// Future locationPermissions() async {
// location = Location();
// var permissionStatus = await location.requestPermission();
// if (permissionStatus == PermissionStatus.denied) {
// // The user denied the location permission.
// Get.defaultDialog(title: 'GPS Required Allow !.'.tr, middleText: '');
// return null;
// }
// }
// }
@@ -0,0 +1,179 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../constant/box_name.dart';
import '../../constant/colors.dart';
import '../../constant/links.dart';
import '../../constant/style.dart';
import '../../main.dart';
import '../../views/widgets/elevated_btn.dart';
import '../../views/widgets/my_textField.dart';
import '../../views/widgets/snackbar.dart';
import 'crud.dart';
class LogOutController extends GetxController {
TextEditingController checkTxtController = TextEditingController();
final formKey = GlobalKey<FormState>();
final formKey1 = GlobalKey<FormState>();
final emailTextController = TextEditingController();
Future deleteMyAccountDriver(String id) async {
await CRUD().post(link: AppLink.removeUser, payload: {'id': id}).then(
(value) => mySnackbarWarning('Your Account is Deleted'.tr));
}
checkBeforeDelete() async {
await CRUD().post(
link: AppLink.deletecaptainAccounr,
payload: {'id': box.read(BoxName.driverID)}).then((value) => exit(0));
}
deletecaptainAccount() {
Get.defaultDialog(
backgroundColor: AppColor.yellowColor,
title: 'Are you sure to delete your account?'.tr,
middleText:
'Your data will be erased after 2 weeks\nAnd you will can\'t return to use app after 1 month ',
titleStyle: AppStyle.title,
content: Column(
children: [
Container(
width: Get.width,
decoration: AppStyle.boxDecoration,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Your data will be erased after 2 weeks\nAnd you will can\'t return to use app after 1 month'
.tr,
style: AppStyle.title.copyWith(color: AppColor.redColor),
),
),
),
const SizedBox(
height: 20,
),
Form(
key: formKey,
child: SizedBox(
width: Get.width,
child: MyTextForm(
controller: checkTxtController,
label: 'Enter Your First Name'.tr,
hint: 'Enter Your First Name'.tr,
type: TextInputType.name,
),
))
],
),
confirm: MyElevatedButton(
title: 'Delete'.tr,
onPressed: () {
if (checkTxtController.text == box.read(BoxName.nameDriver)) {
deletecaptainAccount();
}
}));
}
Future logOutPassenger() async {
Get.defaultDialog(
title: 'Are you Sure to LogOut?'.tr,
content: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
MyElevatedButton(
title: 'Cancel'.tr,
onPressed: () => Get.back(),
),
ElevatedButton(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(AppColor.redColor),
),
onPressed: () {
// box.remove(BoxName.agreeTerms);
box.remove(BoxName.driverID);
box.remove(BoxName.email);
box.remove(BoxName.lang);
box.remove(BoxName.name);
box.remove(BoxName.passengerID);
box.remove(BoxName.phone);
box.remove(BoxName.tokenFCM);
box.remove(BoxName.tokens);
box.remove(BoxName.addHome);
box.remove(BoxName.addWork);
box.remove(BoxName.agreeTerms);
box.remove(BoxName.apiKeyRun);
box.remove(BoxName.countryCode);
box.remove(BoxName.passengerWalletTotal);
Get.offAll(const MainApp());
},
child: Text(
'Sign Out'.tr,
style:
AppStyle.title.copyWith(color: AppColor.secondaryColor),
))
],
));
}
Future logOutCaptain() async {
Get.defaultDialog(
title: 'Are you Sure to LogOut?'.tr,
titleStyle: AppStyle.title,
content: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
MyElevatedButton(
title: 'Cancel'.tr,
onPressed: () => Get.back(),
),
ElevatedButton(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(AppColor.redColor),
),
onPressed: () {
// box.remove(BoxName.agreeTerms);
box.remove(BoxName.driverID);
box.remove(BoxName.sexDriver);
box.remove(BoxName.dobDriver);
box.remove(BoxName.nameDriver);
box.remove(BoxName.emailDriver);
box.remove(BoxName.phoneDriver);
box.remove(BoxName.statusDriverLocation);
box.remove(BoxName.cvvCodeDriver);
box.remove(BoxName.lastNameDriver);
box.remove(BoxName.passwordDriver);
box.remove(BoxName.cardNumberDriver);
box.remove(BoxName.expiryDateDriver);
box.remove(BoxName.cardHolderNameDriver);
box.remove(BoxName.vin);
box.remove(BoxName.make);
box.remove(BoxName.year);
box.remove(BoxName.owner);
box.remove(BoxName.onBoarding);
box.remove(BoxName.agreeTerms);
Get.offAll(const MainApp());
},
child: Text(
'Sign Out'.tr,
style:
AppStyle.title.copyWith(color: AppColor.secondaryColor),
))
],
));
}
deletePassengerAccount() async {
if (formKey1.currentState!.validate()) {
if (box.read(BoxName.email).toString() == emailTextController.text) {
await CRUD().post(link: AppLink.passengerRemovedAccountEmail, payload: {
'email': box.read(BoxName.email),
});
} else {
mySnackbarError('Email you inserted is Wrong.'.tr);
}
}
}
}
@@ -0,0 +1,25 @@
// import 'package:credit_card_scanner/credit_card_scanner.dart';
// import 'package:get/get.dart';
//
// class ScanIdCard extends GetxController {
// CardDetails? _cardDetails;
// CardScanOptions scanOptions = const CardScanOptions(
// scanCardHolderName: true,
// enableDebugLogs: true,
// validCardsToScanBeforeFinishingScan: 5,
// possibleCardHolderNamePositions: [
// CardHolderNameScanPosition.aboveCardNumber,
// ],
// );
//
// Future<void> scanCard() async {
// final CardDetails? cardDetails =
// await CardScanner.scanCard(scanOptions: scanOptions);
// if (cardDetails == null) {
// return;
// }
//
// _cardDetails = cardDetails;
// update();
// }
// }
@@ -0,0 +1,14 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class SecureStorage {
final FlutterSecureStorage _storage = const FlutterSecureStorage();
void saveData(String key, value) async {
await _storage.write(key: key, value: value);
}
Future<String?> readData(String boxName) async {
final String? value = await _storage.read(key: boxName);
return value;
}
}
+51
View File
@@ -0,0 +1,51 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
class SecurityChecks {
static const platform = MethodChannel(
'com.siro.siro_admin/security'); // Choose a unique channel name
static Future<bool> isDeviceCompromised() async {
try {
final bool result = await platform
.invokeMethod('isNativeRooted'); // Invoke the native method
return result;
} on PlatformException catch (e) {
print("Failed to check security status: ${e.message}");
return false; // Platform not supported → treat as secure
} catch (e) {
print("Security check error: $e");
return false;
}
}
static isDeviceRootedFromNative(BuildContext context) async {
bool compromised = await isDeviceCompromised();
if (compromised) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) => AlertDialog(
title: Text("Security Warning".tr),
content: Text(
"Your device appears to be compromised. The app will now close."
.tr),
actions: [
TextButton(
onPressed: () {
SystemNavigator.pop(); // Close the app
},
child: Text("OK"),
),
],
),
);
} else {
// Continue with normal app flow
print("Device is secure.");
}
}
}
@@ -0,0 +1,47 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:crypto/crypto.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart' as http_io;
class SslPinning {
SslPinning._();
static final Map<String, List<String>> _pins = {
'intaleq.xyz': [
'/tNRUeeLxUhQU5gbgdpVWC6QBGAqc/ujg8Kcf0wQiAM=',
'Hlx/0EWNDH5Xkt2KzvqxUzbw0vvEsyZSlibialSyGqI=',
],
'siromove.com': [
'C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHESsl=',
'diGVwiVYbubAI3RW4hB9xU8e/CH2GnkuvVFZE8zmgzI=',
],
};
static final List<String> _globalPins = [
'Ex/Od4QBaJmloAIDqe/IDxjrvXVYBxftwVU1gJMINuw=',
'lrzsBiZJdvN0YHeazyjFp8/oo8Cq4RqP/O4FwL3fCMY=',
'aXKbjhWobvwXelevtxcd/GSt0owvyozxUH40RTzLFHA=',
];
static http.Client createPinnedClient() {
if (kIsWeb) {
return http.Client();
}
final httpClient = HttpClient()
..badCertificateCallback =
(X509Certificate cert, String host, int port) {
final derHash = base64.encode(sha256.convert(cert.der).bytes);
for (final entry in _pins.entries) {
if (host == entry.key || host.endsWith('.${entry.key}')) {
if (entry.value.contains(derHash)) return true;
}
}
if (_globalPins.contains(derHash)) return true;
return false;
};
return http_io.IOClient(httpClient);
}
}
@@ -0,0 +1,439 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image/image.dart' as img;
import 'package:path_provider/path_provider.dart' as path_provider;
import '../../constant/api_key.dart';
import '../../constant/box_name.dart';
import '../../constant/colors.dart';
import '../../constant/info.dart';
import '../../main.dart';
import '../../print.dart';
import '../../views/widgets/snackbar.dart';
import 'encrypt_decrypt.dart';
class ImageController extends GetxController {
File? myImage;
bool isloading = false;
CroppedFile? croppedFile;
final picker = ImagePicker();
var image;
Future<img.Image> detectAndCropDocument(File imageFile) async {
img.Image? image = img.decodeImage(await imageFile.readAsBytes());
if (image == null) throw Exception('Unable to decode image');
int left = image.width, top = image.height, right = 0, bottom = 0;
// Threshold for considering a pixel as part of the document (adjust as needed)
const int threshold = 240;
for (int y = 0; y < image.height; y++) {
for (int x = 0; x < image.width; x++) {
final pixel = image.getPixel(x, y);
final luminance = img.getLuminance(pixel);
if (luminance < threshold) {
left = x < left ? x : left;
top = y < top ? y : top;
right = x > right ? x : right;
bottom = y > bottom ? y : bottom;
}
}
}
// Add a small padding
left = (left - 5).clamp(0, image.width);
top = (top - 5).clamp(0, image.height);
right = (right + 5).clamp(0, image.width);
bottom = (bottom + 5).clamp(0, image.height);
return img.copyCrop(image,
x: left, y: top, width: right - left, height: bottom - top);
}
Future<File> rotateImageIfNeeded(File imageFile) async {
img.Image croppedDoc = await detectAndCropDocument(imageFile);
// Check if the document is in portrait orientation
bool isPortrait = croppedDoc.height > croppedDoc.width;
img.Image processedImage;
if (isPortrait) {
// Rotate the image by 90 degrees clockwise
processedImage = img.copyRotate(croppedDoc, angle: 90);
} else {
processedImage = croppedDoc;
}
// Get temporary directory
final tempDir = await path_provider.getTemporaryDirectory();
final tempPath = tempDir.path;
// Create the processed image file
File processedFile = File('$tempPath/processed_image.jpg');
await processedFile.writeAsBytes(img.encodeJpg(processedImage));
return processedFile;
}
Future<File> rotateImage(File imageFile) async {
// Read the image file
img.Image? image = img.decodeImage(await imageFile.readAsBytes());
if (image == null) return imageFile;
// Rotate the image by 90 degrees clockwise
img.Image rotatedImage = img.copyRotate(image, angle: 90);
// Get temporary directory
final tempDir = await path_provider.getTemporaryDirectory();
final tempPath = tempDir.path;
// Create the rotated image file
File rotatedFile = File('$tempPath/rotated_image.jpg');
await rotatedFile.writeAsBytes(img.encodeJpg(rotatedImage));
return rotatedFile;
}
choosImage(String link, String imageType, String id) async {
try {
final pickedImage = await picker.pickImage(
source: ImageSource.camera,
preferredCameraDevice: CameraDevice.rear,
);
if (pickedImage == null) return;
image = File(pickedImage.path);
croppedFile = await ImageCropper().cropImage(
sourcePath: image!.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper'.tr,
toolbarColor: AppColor.blueColor,
toolbarWidgetColor: AppColor.yellowColor,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
IOSUiSettings(
title: 'Cropper'.tr,
),
],
);
if (croppedFile == null) return;
myImage = File(croppedFile!.path);
isloading = true;
update();
// Rotate the compressed image
File processedImage = await rotateImageIfNeeded(File(croppedFile!.path));
File compressedImage = await compressImage(processedImage);
print('link =$link');
Log.print('link: $link');
await uploadImage(
compressedImage,
{
'driverID': id,
'imageType': imageType,
},
link,
);
} catch (e) {
print('Error in choosImage: $e');
mySnackbarError('Image Upload Failed'.tr);
} finally {
isloading = false;
update();
}
}
// choosFaceFromDriverLicense(String link, String imageType) async {
// final pickedImage = await picker.pickImage(
// source: ImageSource.camera,
// preferredCameraDevice: CameraDevice.rear,
// );
// if (pickedImage == null) return;
// image = File(pickedImage.path);
// File? processedImage;
// // For face images, use face detection and cropping
// processedImage = await detectAndCropFace(image!);
// if (processedImage == null) {
// Get.snackbar('Face Detection Failed', 'No face detected in the image.');
// return;
// }
// isloading = true;
// update();
// File compressedImage = await compressImage(processedImage);
// try {
// await uploadImage(
// compressedImage,
// {
// 'driverID': box.read(BoxName.driverID).toString(),
// 'imageType': imageType
// },
// link,
// );
// } catch (e) {
// Get.snackbar('Image Upload Failed'.tr, e.toString(),
// backgroundColor: AppColor.redColor);
// } finally {
// isloading = false;
// update();
// }
// }
choosFace(String link, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.camera,
preferredCameraDevice: CameraDevice.front,
);
if (pickedImage != null) {
image = File(pickedImage.path);
isloading = true;
update();
// Compress the image
File compressedImage = await compressImage(File(pickedImage.path));
// Save the picked image directly
// File savedImage = File(pickedImage.path);
print('link =$link');
try {
await uploadImage(
compressedImage,
{
'driverID':
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
'imageType': imageType
},
link,
);
} catch (e) {
mySnackbarError('Image Upload Failed'.tr);
} finally {
isloading = false;
update();
}
}
}
uploadImage(File file, Map data, String link) async {
var request = http.MultipartRequest(
'POST',
Uri.parse(link),
);
Log.print('request: $request');
var length = await file.length();
var stream = http.ByteStream(file.openRead());
final headers = {
'Authorization':
'Bearer ${r(box.read(BoxName.jwt)).split(AppInformation.addd)[0]}',
// 'X-HMAC-Auth': '${box.read(BoxName.hmac)}',
};
Log.print('headers: $headers');
request.headers.addAll(headers);
// Set the file name to the driverID
request.files.add(
http.MultipartFile(
'image',
stream,
length,
filename: '${box.read(BoxName.driverID)}.jpg',
),
);
data.forEach((key, value) {
request.fields[key] = value;
});
var myrequest = await request.send();
var res = await http.Response.fromStream(myrequest);
if (res.statusCode == 200) {
Log.print('jsonDecode(res.body): ${jsonDecode(res.body)}');
if (jsonDecode(res.body)['status'] == 'Image uploaded successfully!') {
mySnackbarSuccess('Image uploaded successfully!'.tr);
}
return jsonDecode(res.body);
} else {
throw Exception(
'Failed to upload image: ${res.statusCode} - ${res.body}');
}
}
choosImagePicture(String link, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
// preferredCameraDevice: CameraDevice.rear,
// maxHeight: Get.height * .3,
// maxWidth: Get.width * .9,
// imageQuality: 100,
);
image = File(pickedImage!.path);
croppedFile = await ImageCropper().cropImage(
sourcePath: image!.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper'.tr,
toolbarColor: AppColor.blueColor,
toolbarWidgetColor: AppColor.yellowColor,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
IOSUiSettings(
title: 'Cropper'.tr,
),
],
);
myImage = File(pickedImage.path);
isloading = true;
update();
// Save the cropped image
// File savedCroppedImage = File(croppedFile!.path);
File compressedImage = await compressImage(File(croppedFile!.path));
print('link =$link');
try {
await uploadImage(
compressedImage,
{
'driverID':
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
'imageType': imageType
},
link,
);
} catch (e) {
mySnackbarError('Image Upload Failed'.tr);
} finally {
isloading = false;
update();
}
}
uploadImagePicture(File file, Map data, String link) async {
var request = http.MultipartRequest(
'POST',
Uri.parse(link), //'https://ride.mobile-app.store/uploadImage1.php'
);
var length = await file.length();
var stream = http.ByteStream(file.openRead());
request.headers.addAll({
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
});
// Set the file name to the driverID
request.files.add(
http.MultipartFile(
'image',
stream,
length,
filename: '${box.read(BoxName.driverID)}.jpg',
),
);
data.forEach((key, value) {
request.fields[key] = value;
});
var myrequest = await request.send();
var res = await http.Response.fromStream(myrequest);
if (res.statusCode == 200) {
return jsonDecode(res.body);
} else {
throw Exception(
'Failed to upload image: ${res.statusCode} - ${res.body}');
}
}
}
Future<File> compressImage(File file) async {
final dir = await path_provider.getTemporaryDirectory();
final targetPath = "${dir.absolute.path}/temp.jpg";
var result = await FlutterImageCompress.compressAndGetFile(
file.absolute.path,
targetPath,
quality: 70,
minWidth: 1024,
minHeight: 1024,
);
return File(result!.path);
}
// Future<File> detectAndCropFace(File imageFile) async {
// final inputImage = InputImage.fromFilePath(imageFile.path);
// final options = FaceDetectorOptions(
// enableClassification: false,
// enableLandmarks: false,
// enableTracking: false,
// minFaceSize: 0.15,
// performanceMode: FaceDetectorMode.accurate,
// );
// final faceDetector = FaceDetector(options: options);
// try {
// final List<Face> faces = await faceDetector.processImage(inputImage);
// final image = img.decodeImage(await imageFile.readAsBytes());
// if (image == null) throw Exception('Unable to decode image');
// int left, top, width, height;
// if (faces.isNotEmpty) {
// // Face detected, crop around the face
// final face = faces[0];
// double padding = 0.2; // 20% padding
// int paddingX = (face.boundingBox.width * padding).round();
// int paddingY = (face.boundingBox.height * padding).round();
// left = (face.boundingBox.left - paddingX).round();
// top = (face.boundingBox.top - paddingY).round();
// width = (face.boundingBox.width + 2 * paddingX).round();
// height = (face.boundingBox.height + 2 * paddingY).round();
// } else {
// // No face detected, crop the center of the image
// int size = min(image.width, image.height);
// left = (image.width - size) ~/ 2;
// top = (image.height - size) ~/ 2;
// width = size;
// height = size;
// }
// // Ensure dimensions are within image bounds
// left = left.clamp(0, image.width - 1);
// top = top.clamp(0, image.height - 1);
// width = width.clamp(1, image.width - left);
// height = height.clamp(1, image.height - top);
// final croppedImage =
// img.copyCrop(image, x: left, y: top, width: width, height: height);
// // Save the cropped image
// final tempDir = await path_provider.getTemporaryDirectory();
// final tempPath = tempDir.path;
// final croppedFile = File('$tempPath/cropped_image.jpg');
// await croppedFile.writeAsBytes(img.encodeJpg(croppedImage, quality: 100));
// return croppedFile;
// } finally {
// faceDetector.close();
// }
// }
@@ -0,0 +1,108 @@
// import 'dart:convert';
// import 'dart:io';
// import 'package:get/get.dart';
// import 'package:http/http.dart' as http;
// import 'package:image_cropper/image_cropper.dart';
// import 'package:image_picker/image_picker.dart';
// import 'package:path/path.dart';
// import '../../constant/api_key.dart';
// import '../../constant/box_name.dart';
// import '../../constant/colors.dart';
// import '../../main.dart';
// class ImageController extends GetxController {
// File? myImage;
// bool isloading = false;
// CroppedFile? croppedFile;
// final picker = ImagePicker();
// var image;
// choosImage(String link, String imageType) async {
// final pickedImage = await picker.pickImage(source: ImageSource.gallery);
// image = File(pickedImage!.path);
// croppedFile = await ImageCropper().cropImage(
// sourcePath: image!.path,
// aspectRatioPresets: [
// CropAspectRatioPreset.square,
// CropAspectRatioPreset.ratio3x2,
// CropAspectRatioPreset.original,
// CropAspectRatioPreset.ratio4x3,
// CropAspectRatioPreset.ratio16x9
// ],
// uiSettings: [
// AndroidUiSettings(
// toolbarTitle: 'Cropper'.tr,
// toolbarColor: AppColor.blueColor,
// toolbarWidgetColor: AppColor.yellowColor,
// initAspectRatio: CropAspectRatioPreset.original,
// lockAspectRatio: false),
// IOSUiSettings(
// title: 'Cropper'.tr,
// ),
// ],
// );
// myImage = File(pickedImage.path);
// isloading = true;
// update();
// // Save the cropped image
// File savedCroppedImage = File(croppedFile!.path);
// try {
// await uploadImage(
// savedCroppedImage,
// {
// 'driverID':
// box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
// 'imageType': imageType
// },
// link,
// );
// } catch (e) {
// Get.snackbar('Image Upload Failed'.tr, e.toString(),
// backgroundColor: AppColor.redColor);
// } finally {
// isloading = false;
// update();
// }
// }
// uploadImage(File file, Map data, String link) async {
// var request = http.MultipartRequest(
// 'POST',
// Uri.parse(link), //'https://ride.mobile-app.store/uploadImage1.php'
// );
// var length = await file.length();
// var stream = http.ByteStream(file.openRead());
// var multipartFile = http.MultipartFile(
// 'image',
// stream,
// length,
// filename: basename(file.path),
// );
// request.headers.addAll({
// 'Authorization':
// 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
// });
// // Set the file name to the driverID
// request.files.add(
// http.MultipartFile(
// 'image',
// stream,
// length,
// filename: '${box.read(BoxName.driverID)}.jpg',
// ),
// );
// data.forEach((key, value) {
// request.fields[key] = value;
// });
// var myrequest = await request.send();
// var res = await http.Response.fromStream(myrequest);
// if (res.statusCode == 200) {
// return jsonDecode(res.body);
// } else {
// throw Exception(
// 'Failed to upload image: ${res.statusCode} - ${res.body}');
// }
// }
// }
@@ -0,0 +1,90 @@
import 'dart:convert';
import 'package:get/get.dart';
import '../../constant/links.dart';
import '../../views/widgets/snackbar.dart';
import 'crud.dart';
class WalletController extends GetxController {
String paymentToken = '';
Future<String> generateTokenDriver(String amount, driverID) async {
var res = await CRUD().post(link: AppLink.addPaymentTokenDriver, payload: {
'driverID': driverID.toString(),
'amount': amount.toString(),
});
var d = jsonDecode(res);
return d['message'];
}
addPaymentToDriver(String amount, driverID, token) async {
paymentToken = await generateTokenDriver(amount.toString(), driverID);
var res = await CRUD().post(link: AppLink.addDrivePayment, payload: {
'rideId': 'gift_$driverID _${DateTime.now().toIso8601String()}',
'amount': amount,
'payment_method': 'visaRide',
'passengerID': 'gift',
'token': paymentToken,
'driverID': driverID.toString(),
});
if (res != 'failure') {
// FirebaseMessagesController().sendNotificationToAnyWithoutData(
// "لديك هدية من سفَر".tr,
// 'لقد حصلت على هدية من سفر بقيمة $amount ',
// token, // Access token correctly
// 'ding.wav',
// );
mySnackbarSuccess('addPaymentToDriver');
} else {
mySnackbarError('addPaymentToDriver');
}
}
Future addDriverWallet(String paymentMethod, driverID, point, phone) async {
// paymentToken = await generateToken(count);
// var paymentID = await getPaymentId(paymentMethod, point.toString());
await CRUD().postWallet(link: AppLink.addFromAdmin, payload: {
'driverID': driverID.toString(),
'paymentID': 'gift_connect_$driverID${DateTime.timestamp()}'.toString(),
'amount': point,
'token': 'gift_connect',
'paymentMethod': paymentMethod,
'phone': phone,
});
}
Future addDrivergift300(String paymentMethod, driverID, point, phone) async {
// paymentToken = await generateToken(count);
// var paymentID = await getPaymentId(paymentMethod, point.toString());
var res = await CRUD().postWallet(link: AppLink.add300ToDriver, payload: {
'driverID': driverID.toString(),
'paymentID': paymentMethod,
'amount': point,
'token': 'gift_connect_300',
'paymentMethod': paymentMethod,
'phone': phone,
});
if (res != 'failure') {
mySnackbarSuccess('addDrivergift300');
} else {
mySnackbarError(res);
}
}
Future addSeferWallet(String point, driverID) async {
var amount = (int.parse(point) * -1).toStringAsFixed(0);
var seferToken = await generateTokenDriver(amount, driverID);
var res = await CRUD().post(link: AppLink.addSeferWallet, payload: {
'amount': amount.toString(),
'paymentMethod': 'visaRide',
'passengerId': 'gift$driverID',
'token': seferToken,
'driverId': driverID.toString(),
});
if (res != 'failure') {
mySnackbarSuccess('addSeferWallet');
} else {
mySnackbarError('addSeferWallet');
}
}
}