import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../../routes/route_paths.dart'; import '../../../../routes/app_router.dart'; import '../../../../bootstrap.dart'; import '../providers/auth_provider.dart'; /// 开屏页面 - 应用启动时显示的第一个页面 /// 播放帧动画,动画结束后检查用户认证状态并跳转 class SplashPage extends ConsumerStatefulWidget { const SplashPage({super.key}); @override ConsumerState createState() => _SplashPageState(); } class _SplashPageState extends ConsumerState { /// 帧动画总帧数 static const int _totalFrames = 36; /// 帧动画帧率 (fps) static const int _frameRate = 15; /// 当前显示的帧索引 (0-based) int _currentFrameIndex = 0; /// 是否显示跳过按钮 bool _showSkipButton = false; /// 是否已经开始跳转(防止重复跳转) bool _isNavigating = false; /// 帧动画是否正在播放 bool _isPlaying = true; /// 预加载的图片缓存 final List _frameProviders = []; @override void initState() { super.initState(); _initializeFrames(); } /// 初始化帧动画 void _initializeFrames() { // 创建所有帧的 ImageProvider(不会立即加载,只是创建引用) for (int i = 1; i <= _totalFrames; i++) { final frameNumber = i.toString().padLeft(3, '0'); final framePath = 'assets/images/splash_frames/frame_$frameNumber.png'; _frameProviders.add(AssetImage(framePath)); } // 启动帧动画播放 _playAnimation(); // 1秒后显示跳过按钮 Future.delayed(const Duration(seconds: 1), () { if (mounted) { setState(() { _showSkipButton = true; }); } }); } @override void didChangeDependencies() { super.didChangeDependencies(); // 预加载前几帧到内存,确保播放流畅 _precacheInitialFrames(); } /// 预加载前几帧 void _precacheInitialFrames() { // 预加载前5帧,确保启动时不卡顿 final framesToPrecache = _totalFrames < 5 ? _totalFrames : 5; for (int i = 0; i < framesToPrecache; i++) { precacheImage(_frameProviders[i], context); } } /// 播放帧动画 Future _playAnimation() async { final frameDuration = Duration(milliseconds: 1000 ~/ _frameRate); while (_isPlaying && _currentFrameIndex < _totalFrames - 1 && mounted) { await Future.delayed(frameDuration); if (!mounted || !_isPlaying) break; setState(() { _currentFrameIndex++; }); // 预加载后续帧(提前2帧预加载) final nextFrameIndex = _currentFrameIndex + 2; if (nextFrameIndex < _totalFrames) { precacheImage(_frameProviders[nextFrameIndex], context); } } // 动画播放完成 if (_currentFrameIndex >= _totalFrames - 1 && mounted && _isPlaying) { _navigateToNextPage(); } } /// 跳过动画 void _skipAnimation() { _isPlaying = false; _navigateToNextPage(); } /// 导航到下一个页面 Future _navigateToNextPage() async { // 防止重复跳转 if (_isNavigating) return; _isNavigating = true; // 初始化遥测服务(需要 BuildContext) await initializeTelemetry(context); // 检查认证状态 await ref.read(authProvider.notifier).checkAuthStatus(); if (!mounted) return; final authState = ref.read(authProvider); // 根据认证状态决定跳转目标 // 优先级: // 1. 钱包已创建且已备份 → 主页面 // 2. 账号已创建但钱包未完成 → 备份助记词页面 // 3. 首次打开或未看过向导 → 向导页 // 4. 其他情况 → 创建账户页面 if (authState.isWalletCreated) { // 已创建钱包且已备份,进入主页面(龙虎榜) debugPrint('[SplashPage] 钱包已创建且已备份 → 跳转到龙虎榜'); context.go(RoutePaths.ranking); } else if (authState.isAccountCreated && authState.userSerialNum != null) { // 账号已创建但钱包未完成(可能正在生成或未备份),直接进入备份助记词页面 debugPrint('[SplashPage] 账号已创建但钱包未完成 → 跳转到备份助记词页面'); debugPrint('[SplashPage] userSerialNum: ${authState.userSerialNum}, isWalletReady: ${authState.isWalletReady}'); context.go( RoutePaths.backupMnemonic, extra: BackupMnemonicParams( userSerialNum: authState.userSerialNum!, referralCode: authState.referralCode, ), ); } else if (authState.isFirstLaunch || !authState.hasSeenGuide) { // 首次打开或未看过向导,进入向导页 debugPrint('[SplashPage] 首次打开或未看过向导 → 跳转到向导页'); context.go(RoutePaths.guide); } else { // 已看过向导但未创建钱包,直接进入创建账户页面 debugPrint('[SplashPage] 已看过向导但未创建钱包 → 跳转到创建账户页面'); context.go(RoutePaths.onboarding); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Stack( fit: StackFit.expand, children: [ // 帧动画(全屏覆盖) _buildFrameAnimation(), // 跳过按钮 if (_showSkipButton) Positioned( top: MediaQuery.of(context).padding.top + 16, right: 16, child: _buildSkipButton(), ), ], ), ); } /// 构建帧动画视图 Widget _buildFrameAnimation() { return SizedBox.expand( child: Image( image: _frameProviders[_currentFrameIndex], fit: BoxFit.cover, gaplessPlayback: true, // 关键:防止帧切换时闪烁 ), ); } /// 构建跳过按钮 Widget _buildSkipButton() { return GestureDetector( onTap: _skipAnimation, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: Colors.black.withValues(alpha: 0.5), borderRadius: BorderRadius.circular(20), border: Border.all( color: Colors.white.withValues(alpha: 0.3), width: 1, ), ), child: const Row( mainAxisSize: MainAxisSize.min, children: [ Text( '跳过', style: TextStyle( fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w500, color: Colors.white, ), ), SizedBox(width: 4), Icon( Icons.skip_next, size: 18, color: Colors.white, ), ], ), ), ); } }