184 lines
6.2 KiB
Dart
184 lines
6.2 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
import 'package:Intaleq/constant/box_name.dart';
|
|
import 'package:Intaleq/onbording_page.dart';
|
|
import 'package:Intaleq/views/auth/login_page.dart';
|
|
import 'package:Intaleq/controller/auth/login_controller.dart';
|
|
import 'package:Intaleq/controller/functions/secure_storage.dart';
|
|
import 'package:Intaleq/views/widgets/my_scafold.dart';
|
|
import 'package:Intaleq/constant/style.dart';
|
|
|
|
import '../../main.dart';
|
|
|
|
// كنترولر مع منطق تحميل محسن ينتظر العمليات غير المتزامنة
|
|
class SplashScreenController extends GetxController
|
|
with GetTickerProviderStateMixin {
|
|
late AnimationController _animationController;
|
|
|
|
// الحركات الخاصة بكل عنصر من عناصر الواجهة
|
|
late Animation<double> titleFadeAnimation;
|
|
late Animation<double> titleScaleAnimation;
|
|
late Animation<double> taglineFadeAnimation;
|
|
late Animation<Offset> taglineSlideAnimation;
|
|
late Animation<double> footerFadeAnimation;
|
|
|
|
final progress = 0.0.obs;
|
|
Timer? _progressTimer;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
|
|
_animationController = AnimationController(
|
|
vsync: this,
|
|
duration: const Duration(milliseconds: 2000),
|
|
);
|
|
|
|
// --- تعريف الحركات المتتالية ---
|
|
titleFadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
CurvedAnimation(
|
|
parent: _animationController,
|
|
curve: const Interval(0.0, 0.5, curve: Curves.easeOut),
|
|
),
|
|
);
|
|
titleScaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
|
|
CurvedAnimation(
|
|
parent: _animationController,
|
|
curve: const Interval(0.0, 0.5, curve: Curves.easeOut),
|
|
),
|
|
);
|
|
taglineFadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
CurvedAnimation(
|
|
parent: _animationController,
|
|
curve: const Interval(0.3, 0.8, curve: Curves.easeOut),
|
|
),
|
|
);
|
|
taglineSlideAnimation =
|
|
Tween<Offset>(begin: const Offset(0, 0.5), end: Offset.zero).animate(
|
|
CurvedAnimation(
|
|
parent: _animationController,
|
|
curve: const Interval(0.3, 0.8, curve: Curves.easeOut),
|
|
),
|
|
);
|
|
footerFadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
CurvedAnimation(
|
|
parent: _animationController,
|
|
curve: const Interval(0.5, 1.0, curve: Curves.easeOut),
|
|
),
|
|
);
|
|
|
|
_animationController.forward();
|
|
|
|
// بدء عملية التهيئة والتحميل
|
|
_initializeApp();
|
|
}
|
|
|
|
/// تهيئة التطبيق وانتظار انتهاء التحميل قبل الانتقال
|
|
Future<void> _initializeApp() async {
|
|
// تشغيل مؤقت شريط التقدم ليعطي انطباعاً مرئياً فقط
|
|
_startProgressAnimation();
|
|
|
|
// تعريف مهمتين: منطق التحميل، والحد الأدنى لوقت عرض الشاشة
|
|
final logicFuture = _performNavigationLogic();
|
|
final minTimeFuture = Future.delayed(const Duration(seconds: 3));
|
|
|
|
// الانتظار حتى انتهاء المهمتين معاً
|
|
await Future.wait([logicFuture, minTimeFuture]);
|
|
|
|
// بعد انتهاء الانتظار، سيتم الانتقال تلقائياً من داخل a_performNavigationLogic
|
|
}
|
|
|
|
/// تشغيل حركة شريط التقدم بشكل مرئي ومنفصل عن منطق التحميل
|
|
void _startProgressAnimation() {
|
|
const totalTime = 2800; // مدة ملء الشريط
|
|
const interval = 50;
|
|
int elapsed = 0;
|
|
|
|
_progressTimer =
|
|
Timer.periodic(const Duration(milliseconds: interval), (timer) {
|
|
elapsed += interval;
|
|
progress.value = (elapsed / totalTime).clamp(0.0, 1.0);
|
|
if (elapsed >= totalTime) {
|
|
timer.cancel();
|
|
}
|
|
});
|
|
}
|
|
|
|
/// تنفيذ منطق التحميل الفعلي وتسجيل الدخول وتحديد وجهة الانتقال
|
|
Future<void> _performNavigationLogic() async {
|
|
// تنفيذ المهام الأولية
|
|
await _getPackageInfo();
|
|
SecureStorage().saveData('iss', 'mobile-app:');
|
|
|
|
// تحديد الشاشة التالية
|
|
if (box.read(BoxName.onBoarding) == null) {
|
|
Get.off(() => OnBoardingPage());
|
|
} else if (box.read(BoxName.email) != null &&
|
|
box.read(BoxName.phone) != null &&
|
|
box.read(BoxName.isVerified) == '1') {
|
|
// -- النقطة الأهم --
|
|
// هنا ننتظر انتهاء عملية تسجيل الدخول قبل الانتقال
|
|
await Get.put(LoginController()).loginUsingCredentials(
|
|
box.read(BoxName.passengerID).toString(),
|
|
box.read(BoxName.email).toString(),
|
|
);
|
|
// بعد هذه العملية، سيتولى LoginController بنفسه الانتقال للصفحة الرئيسية أو صفحة الدخول
|
|
} else {
|
|
Get.off(() => LoginPage());
|
|
}
|
|
}
|
|
|
|
/// جلب معلومات الحزمة لعرض إصدار التطبيق
|
|
Future<void> _getPackageInfo() async {
|
|
final info = await PackageInfo.fromPlatform();
|
|
box.write(BoxName.packagInfo, info.version);
|
|
update();
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
_progressTimer?.cancel();
|
|
_animationController.dispose();
|
|
super.onClose();
|
|
}
|
|
}
|
|
|
|
// يمكن الإبقاء على هذه الفئة لواجهة المستخدم المتعلقة بالأمان كما في الملف الأصلي
|
|
class SecurityPage extends StatelessWidget {
|
|
const SecurityPage({
|
|
super.key,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MyScafolld(
|
|
title: "security_warning".tr,
|
|
body: [
|
|
Center(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(20),
|
|
child: Column(
|
|
children: [
|
|
Text(
|
|
"security_message".tr,
|
|
style: AppStyle.headTitle2,
|
|
),
|
|
TextButton(
|
|
onPressed: () async {
|
|
// await SecurityHelper.clearAllData();
|
|
},
|
|
child: Text(
|
|
"security_warning".tr,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
)
|
|
],
|
|
isleading: false);
|
|
}
|
|
}
|