المجلدات وأسماء حزم dart واستيراداتها: siro_rider → intaleq_rider siro_driver → intaleq_driver siro_admin → intaleq_admin siro_service → intaleq_service شمل ذلك `name:` في كل pubspec وكل `package:siro_*` في الاستيرادات (115 ملفاً في rider وحده)، وإشارات أسماء المجلدات في docs/ وتعليق في backend/Admin/notifications/broadcast.php. لم تبقَ إشارة واحدة (تحقّقت). + ضُمّت حزم get و get_storage داخل intaleq_driver/packages/ وحُوّلت مساراتها الثلاثة من `../../Intaleq/packages/*` إلى `./packages/*`. كانت تُحل عرضاً إلى مجلد App/Intaleq القديم المجاور — تبعية خارج المستودع تنكسر بأول نقل. لم يبقَ في أي تطبيق تبعية مسار خارج الشجرة. ⚠️ لم تُمسّ بعد: هويات المتاجر (applicationId · PRODUCT_BUNDLE_IDENTIFIER · shorebird app_id) ولا الألوان ولا النصوص المرئية ولا النطاقات — كل منها كوميت منفصل، والهويات تحتاج قرار المالك. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
129 lines
3.6 KiB
Dart
129 lines
3.6 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:intaleq_rider/constant/box_name.dart';
|
|
import 'package:intaleq_rider/constant/links.dart';
|
|
import 'package:intaleq_rider/controller/functions/crud.dart';
|
|
import 'package:intaleq_rider/main.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:intaleq_rider/views/widgets/error_snakbar.dart';
|
|
|
|
import '../../print.dart';
|
|
import '../../views/home/map_page_passenger.dart';
|
|
import '../firebase/firbase_messge.dart';
|
|
import '../firebase/notification_service.dart';
|
|
import '../functions/package_info.dart';
|
|
|
|
class OtpVerificationController extends GetxController {
|
|
final String phone;
|
|
final String deviceToken;
|
|
final String token;
|
|
final otpCode = ''.obs;
|
|
final isLoading = false.obs;
|
|
final isVerifying = false.obs;
|
|
var canResend = false.obs;
|
|
var countdown = 120.obs;
|
|
Timer? _timer;
|
|
|
|
OtpVerificationController({
|
|
required this.phone,
|
|
required this.deviceToken,
|
|
required this.token,
|
|
});
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
sendOtp(); // ترسل تلقائيًا عند فتح الصفحة
|
|
startCountdown();
|
|
}
|
|
|
|
void startCountdown() {
|
|
canResend.value = false;
|
|
countdown.value = 120;
|
|
_timer?.cancel();
|
|
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
if (countdown.value > 0) {
|
|
countdown.value--;
|
|
} else {
|
|
canResend.value = true;
|
|
timer.cancel();
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<void> sendOtp() async {
|
|
if (isLoading.value) return;
|
|
isLoading.value = true;
|
|
try {
|
|
final response = await CRUD().post(
|
|
link: '${AppLink.server}/auth/otp/request.php',
|
|
payload: {
|
|
'receiver': phone,
|
|
'context': 'token_change',
|
|
'user_type': 'passenger',
|
|
// 'device_token': deviceToken,
|
|
},
|
|
);
|
|
|
|
if (response != 'failure') {
|
|
isLoading.value = true;
|
|
// بإمكانك عرض رسالة نجاح هنا
|
|
} else {
|
|
mySnackbarError('Failed to send OTP'.tr);
|
|
}
|
|
} catch (e) {
|
|
mySnackbarError(e.toString());
|
|
} finally {
|
|
// isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
Future<void> verifyOtp(String ptoken) async {
|
|
isVerifying.value = true;
|
|
|
|
try {
|
|
String fingerPrint = await DeviceHelper.getDeviceFingerprint();
|
|
final response = await CRUD().post(
|
|
link: '${AppLink.server}/auth/otp/verify.php',
|
|
payload: {
|
|
'phone_number': phone,
|
|
'token_code': otpCode.value,
|
|
'context': 'token_change',
|
|
'user_type': 'passenger',
|
|
'token': box.read(BoxName.tokenFCM).toString(),
|
|
'fingerPrint': fingerPrint.toString(),
|
|
},
|
|
);
|
|
|
|
if (response != 'failure' && response['status'] == 'success') {
|
|
// تحديث التوكن والبصمة الجديدة في الباك إند
|
|
await CRUD().post(
|
|
link: "${AppLink.server}/ride/firebase/addToken.php",
|
|
payload: {
|
|
'token': box.read(BoxName.tokenFCM).toString(),
|
|
'fingerPrint': fingerPrint.toString(),
|
|
'passengerID': box.read(BoxName.passengerID).toString(),
|
|
});
|
|
|
|
await NotificationService.sendNotification(
|
|
category: 'token change',
|
|
target: ptoken.toString(),
|
|
title: 'token change'.tr,
|
|
body: 'change device'.tr,
|
|
isTopic: false, // Important: this is a token
|
|
tone: 'cancel',
|
|
driverList: [],
|
|
);
|
|
|
|
Get.offAll(() => const MapPagePassenger());
|
|
} else {
|
|
mySnackbarError('OTP is incorrect or expired');
|
|
}
|
|
} catch (e) {
|
|
mySnackbarError(e.toString());
|
|
} finally {
|
|
isVerifying.value = false;
|
|
}
|
|
}
|
|
}
|