import 'package:flutter/material.dart'; import 'package:tugas_akhir_supabase/services/auth_services.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:tugas_akhir_supabase/di/service_locator.dart'; import 'package:audioplayers/audioplayers.dart'; import 'package:tugas_akhir_supabase/services/session_manager.dart'; import 'dart:async'; // Import HomeScreen class SplashScreen extends StatefulWidget { const SplashScreen({super.key}); @override _SplashScreenState createState() => _SplashScreenState(); } class _SplashScreenState extends State with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation _fadeAnimation; late Animation _scaleAnimation; late Animation _slideAnimation; late AuthServices _authServices; final AudioPlayer _audioPlayer = AudioPlayer(); bool _isAudioPlayed = false; @override void initState() { super.initState(); // Get auth service instance using the sl instance from service_locator.dart try { _authServices = sl(); } catch (e) { debugPrint('Error getting AuthServices from GetIt: $e'); // Create a local instance as fallback if GetIt fails _authServices = AuthServices(); } _animationController = AnimationController( duration: const Duration(milliseconds: 2000), // Increased duration vsync: this, ); _fadeAnimation = TweenSequence([ TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 20), TweenSequenceItem(tween: Tween(begin: 1.0, end: 1.0), weight: 60), TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 20), ]).animate( CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), ); _scaleAnimation = TweenSequence([ TweenSequenceItem( tween: Tween( begin: 0.5, end: 1.0, ).chain(CurveTween(curve: Curves.elasticOut)), weight: 40, ), TweenSequenceItem(tween: Tween(begin: 1.0, end: 1.0), weight: 40), TweenSequenceItem(tween: Tween(begin: 1.0, end: 1.2), weight: 20), ]).animate(_animationController); _slideAnimation = Tween(begin: 50.0, end: 0.0).animate( CurvedAnimation( parent: _animationController, curve: const Interval(0.0, 0.5, curve: Curves.easeOut), ), ); // Delay animation start for native splash to finish properly Future.delayed(const Duration(milliseconds: 900), () { if (mounted) { _animationController.forward(); } }); // Play sound after a short delay Timer(const Duration(milliseconds: 1000), () { _playDeepMaleVoice(); }); _animationController.addStatusListener((status) { if (status == AnimationStatus.completed) { // Langsung navigasi tanpa delay tambahan if (mounted) { _checkAuthAndNavigate(); } } }); } Future _playDeepMaleVoice() async { if (_isAudioPlayed) return; _isAudioPlayed = true; debugPrint('Playing intro voice...'); try { // Play the custom intro voice with delayed initialization Future.delayed(const Duration(milliseconds: 200), () async { try { await _audioPlayer.setReleaseMode(ReleaseMode.release); // Gunakan metode yang lebih sederhana untuk audio try { // Try to play custom intro voice debugPrint('Playing introVoice.mp3...'); await _audioPlayer.play( AssetSource('audio/introVoice.mp3'), volume: 0.8, ); debugPrint('Intro voice started playing'); } catch (assetError) { debugPrint('Could not play intro voice: $assetError'); // Fallback to regular welcome audio only try { debugPrint('Falling back to regular welcome audio...'); await _audioPlayer.play( AssetSource('audio/welcome.mp3'), volume: 0.8, ); debugPrint('Regular welcome audio started playing'); } catch (welcomeError) { debugPrint('Could not play welcome audio: $welcomeError'); // Don't try URL audio as it can cause connectivity issues } } } catch (e) { debugPrint('Audio initialization error: $e'); } }); } catch (e) { debugPrint('Error in audio playback: $e'); } } // Improved auth checking with timeout handling Future _checkAuthAndNavigate() async { try { // Check if user is logged in AND session is valid (not timed out) final isLoggedIn = _authServices.isUserLoggedIn(); final isSessionValid = SessionManager.isAuthenticated; if (!mounted) return; // Menghapus delay tambahan // Langsung navigasi if (isLoggedIn && isSessionValid) { // Valid session, navigate to home Navigator.pushReplacementNamed(context, '/home'); } else { // Session expired or no session, go to intro Navigator.pushReplacementNamed(context, '/intro'); } } catch (e) { // Handle any errors by directing to login if (mounted) { debugPrint('Auth error in splash screen: $e'); Navigator.pushReplacementNamed(context, '/intro'); } } } @override void dispose() { _animationController.dispose(); _audioPlayer.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, resizeToAvoidBottomInset: true, body: SafeArea( child: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.black, Colors.black87, const Color(0xFF056839).withOpacity(0.3), ], stops: const [0.0, 0.5, 1.0], ), ), child: AnimatedBuilder( animation: _animationController, builder: (context, child) { return Opacity( opacity: _fadeAnimation.value, child: Transform.scale( scale: _scaleAnimation.value, child: Center( child: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Transform.translate( offset: Offset(0, _slideAnimation.value), child: Container( width: 180, height: 180, decoration: BoxDecoration( color: Colors.transparent, shape: BoxShape.circle, ), child: Stack( alignment: Alignment.center, children: [ Container( width: 160, height: 160, decoration: BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ const Color( 0xFF056839, ).withOpacity(0.8), const Color(0xFF056839), ], ), boxShadow: [ BoxShadow( color: const Color( 0xFF056839, ).withOpacity(0.3), blurRadius: 20, spreadRadius: 5, ), ], ), ), Image.asset( 'assets/images/logo.png', width: 120, height: 120, color: Colors.white, ), ], ), ), ), const SizedBox(height: 40), Transform.translate( offset: Offset(0, _slideAnimation.value), child: Text( 'TaniSM4RT', style: GoogleFonts.poppins( fontSize: 48, fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: 2, shadows: [ Shadow( color: const Color( 0xFF056839, ).withOpacity(0.5), offset: const Offset(0, 4), blurRadius: 15, ), ], ), ), ), const SizedBox(height: 16), Transform.translate( offset: Offset(0, _slideAnimation.value), child: Container( padding: const EdgeInsets.symmetric( horizontal: 20, vertical: 8, ), decoration: BoxDecoration( color: const Color(0xFF056839).withOpacity(0.1), borderRadius: BorderRadius.circular(30), border: Border.all( color: const Color( 0xFF056839, ).withOpacity(0.3), width: 1, ), ), child: Text( 'Smart Farming Solution', style: GoogleFonts.poppins( fontSize: 16, color: Colors.white.withOpacity(0.9), letterSpacing: 1, fontWeight: FontWeight.w500, ), ), ), ), ], ), ), ), ), ); }, ), ), ), ); } }