import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:permission_handler/permission_handler.dart'; import 'home_screen.dart'; import '../utils/secure_messaging_service.dart'; class SplashScreen extends StatefulWidget { const SplashScreen({super.key}); @override State createState() => _SplashScreenState(); } class _SplashScreenState extends State with TickerProviderStateMixin { static const _platform = MethodChannel('com.example.saba_secure_sms/sms_role'); String _statusText = "در حال بررسی مجوزها..."; String? _startupError; late AnimationController _animationController; late AnimationController _loaderController; late Animation _scaleAnimation; late Animation _fadeAnimation; @override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 1500), ); _scaleAnimation = Tween(begin: 0.6, end: 1.0).animate( CurvedAnimation(parent: _animationController, curve: Curves.elasticOut), ); _fadeAnimation = Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: _animationController, curve: const Interval(0.0, 0.5, curve: Curves.easeIn)), ); _loaderController = AnimationController( vsync: this, duration: const Duration(milliseconds: 1800), )..repeat(); _animationController.forward(); _checkPermissions(); } @override void dispose() { _animationController.dispose(); _loaderController.dispose(); super.dispose(); } Future _checkPermissions() async { // کمی تاخیر برای اینکه انیمیشن دیده شود await Future.delayed(const Duration(seconds: 2)); // ... rest of permission logic remains the same ... Map statuses = await [ Permission.sms, Permission.phone, Permission.contacts, Permission.notification, ].request(); if (statuses[Permission.sms]!.isGranted && statuses[Permission.phone]!.isGranted && statuses[Permission.contacts]!.isGranted) { await _checkAndRequestDefaultSms(); if (mounted) { setState(() { _statusText = "آماده‌سازی امن صبا..."; _startupError = null; }); } await _initializeSecureLayer(); } else { if (mounted) { showDialog( context: context, barrierDismissible: false, builder: (context) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), title: const Text("مجوزهای مورد نیاز"), content: const Text( "صبا برای پیام‌رسانی امن به دسترسی پیامک و مخاطبین نیاز دارد."), actions: [ TextButton( onPressed: () => openAppSettings(), child: const Text("تنظیمات"), ), TextButton( onPressed: () { Navigator.pop(context); _checkPermissions(); }, child: const Text("تلاش مجدد"), ), ], ), ); } } } Future _initializeSecureLayer() async { try { await SecureMessagingService.instance.init(); // تاخیر کوتاه برای نمایش حالت 'آماده' await Future.delayed(const Duration(milliseconds: 800)); _goToHome(); } catch (e) { if (!mounted) return; setState(() { _startupError = e.toString(); _statusText = "خطا در راه‌اندازی لایه امنیتی"; }); } } Future _checkAndRequestDefaultSms() async { try { final bool isDefault = await _platform.invokeMethod('isDefaultSmsApp'); if (!isDefault) { await _platform.invokeMethod('requestDefaultSmsApp'); await Future.delayed(const Duration(seconds: 1)); } } catch (_) {} } void _goToHome() { if (mounted) { Navigator.pushReplacement( context, PageRouteBuilder( transitionDuration: const Duration(milliseconds: 800), pageBuilder: (context, animation, secondaryAnimation) => const HomeScreen(), transitionsBuilder: (context, animation, secondaryAnimation, child) { return FadeTransition(opacity: animation, child: child); }, ), ); } } Widget _buildSecurityLoader() { return AnimatedBuilder( animation: _loaderController, builder: (context, child) { final t = _loaderController.value; final scanProgress = Curves.easeInOut.transform(t); final pulses = [ (t + 0.08) % 1.0, (t + 0.58) % 1.0, ]; return SizedBox( width: 180, child: Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: 120, height: 120, child: Stack( alignment: Alignment.center, children: [ for (final pulse in pulses) Transform.scale( scale: 0.78 + (pulse * 0.72), child: Opacity( opacity: (1 - pulse) * 0.22, child: Container( width: 88, height: 88, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: Colors.white, width: 1.2, ), ), ), ), ), Container( width: 92, height: 92, decoration: BoxDecoration( borderRadius: BorderRadius.circular(28), gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Colors.white.withValues(alpha: 0.18), Colors.white.withValues(alpha: 0.06), ], ), border: Border.all( color: Colors.white.withValues(alpha: 0.22), width: 1, ), boxShadow: [ BoxShadow( color: const Color(0xFF8EC5FF).withValues(alpha: 0.18), blurRadius: 20, spreadRadius: 1, ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(28), child: Stack( alignment: Alignment.center, children: [ Positioned( top: 10 + (scanProgress * 50), child: Container( width: 78, height: 18, decoration: BoxDecoration( borderRadius: BorderRadius.circular(18), gradient: LinearGradient( colors: [ Colors.transparent, Colors.white.withValues(alpha: 0.0), const Color(0xFF7FD8FF) .withValues(alpha: 0.34), Colors.white.withValues(alpha: 0.0), Colors.transparent, ], ), ), ), ), Container( width: 60, height: 60, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.white.withValues(alpha: 0.1), ), ), const Icon( Icons.verified_user_rounded, color: Colors.white, size: 34, ), ], ), ), ), Positioned( bottom: 2, child: Row( children: List.generate(4, (index) { final wave = 0.5 + 0.5 * math.sin( ((t + (index * 0.16)) * 2 * math.pi), ); final height = 10 + (wave * 18); return Container( width: 9, height: height, margin: const EdgeInsets.symmetric(horizontal: 3), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), gradient: const LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.white, Color(0xFF7FD8FF), ], ), ), ); }), ), ), ], ), ), const SizedBox(height: 16), Container( width: 150, height: 8, decoration: BoxDecoration( borderRadius: BorderRadius.circular(99), color: Colors.white.withValues(alpha: 0.12), ), child: Stack( children: [ AnimatedAlign( duration: const Duration(milliseconds: 120), alignment: Alignment(-1 + (scanProgress * 2), 0), child: Container( width: 52, height: 8, decoration: BoxDecoration( borderRadius: BorderRadius.circular(99), gradient: const LinearGradient( colors: [ Color(0xFF7FD8FF), Color(0xFFFFFFFF), ], ), ), ), ), ], ), ), ], ), ); }, ); } @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Theme.of(context).primaryColor, const Color(0xFF1A237E)], ), ), child: Stack( children: [ // Background subtle patterns could go here Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ AnimatedBuilder( animation: _animationController, builder: (context, child) { return Opacity( opacity: _fadeAnimation.value, child: Transform.scale( scale: _scaleAnimation.value, child: Hero( tag: 'app_logo', child: SizedBox( width: 200, height: 200, child: Image.asset('صبا بالا.png'), ), ), ), ); }, ), const SizedBox(height: 40), const Text( "صبا", style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: 1.2, ), ), const Text( "پیام‌رسان امن و پیشرفته", style: TextStyle( fontSize: 16, color: Colors.white70, fontWeight: FontWeight.w300, ), ), const SizedBox(height: 60), if (_startupError == null) _buildSecurityLoader(), if (_startupError != null) ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: Colors.blue.shade900, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15)), ), onPressed: () { setState(() { _startupError = null; _statusText = "در حال اتصال..."; }); _checkPermissions(); }, child: const Text("تلاش مجدد"), ), const SizedBox(height: 20), Text( _statusText, style: const TextStyle(color: Colors.white60, fontSize: 13), ), ], ), ), const Positioned( bottom: 40, left: 0, right: 0, child: Center( child: Text( "SABA SECURE MESSENGER", style: TextStyle( color: Colors.white24, fontSize: 12, letterSpacing: 2, fontWeight: FontWeight.bold, ), ), ), ), ], ), ), ); } }