import 'package:flutter/material.dart'; import '../../../l10n/app_localizations.dart'; import '../../theme/app_color_palette.dart'; import '../../theme/design_tokens.dart'; class DivinationGuideImage extends StatelessWidget { const DivinationGuideImage({super.key, required this.paths}); final List paths; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: AppSpacing.lg), child: paths.length == 1 ? Image.asset(paths.first, fit: BoxFit.contain) : Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Expanded(child: Image.asset(paths[0], fit: BoxFit.contain)), const SizedBox(width: AppSpacing.md), Expanded(child: Image.asset(paths[1], fit: BoxFit.contain)), ], ), ); } } class DivinationInstructionCard extends StatelessWidget { const DivinationInstructionCard({ super.key, required this.text, required this.onTap, }); final String text; final VoidCallback onTap; @override Widget build(BuildContext context) { final palette = Theme.of(context).extension()!; return InkWell( onTap: onTap, borderRadius: BorderRadius.circular(AppRadius.md), child: Container( width: double.infinity, padding: const EdgeInsets.all(AppSpacing.md), decoration: BoxDecoration( color: palette.warningContainer, borderRadius: BorderRadius.circular(AppRadius.md), ), child: Row( children: [ Expanded( child: Text( text, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: palette.warning, fontWeight: FontWeight.w600, ), ), ), const SizedBox(width: AppSpacing.sm), Text( '▶', style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: palette.warning, fontWeight: FontWeight.w700, ), ), ], ), ), ); } } class DivinationGuideDialog extends StatefulWidget { const DivinationGuideDialog({ super.key, required this.title, required this.guideImages, required this.instructions, }); final String title; final List> guideImages; final List instructions; @override State createState() => _DivinationGuideDialogState(); } class _DivinationGuideDialogState extends State { final PageController _pageController = PageController(); int _currentPage = 0; bool get _isLastPage => _currentPage == widget.guideImages.length - 1; @override void dispose() { _pageController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final colors = Theme.of(context).colorScheme; final swipeHint = _guideSwipeHint(Localizations.localeOf(context)); return Dialog( child: SizedBox( width: 360, height: 560, child: Column( children: [ const SizedBox(height: AppSpacing.lg), Text( widget.title, style: Theme.of(context).textTheme.titleLarge?.copyWith( color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.w700, ), ), const SizedBox(height: AppSpacing.md), Expanded( child: PageView.builder( controller: _pageController, onPageChanged: (index) { setState(() { _currentPage = index; }); }, itemCount: widget.guideImages.length, itemBuilder: (context, index) { return DivinationGuideImage(paths: widget.guideImages[index]); }, ), ), Padding( padding: const EdgeInsets.all(AppSpacing.lg), child: Text( widget.instructions[_currentPage], textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: colors.onSurfaceVariant, height: 1.45, ), ), ), Padding( padding: const EdgeInsets.fromLTRB( AppSpacing.lg, 0, AppSpacing.lg, AppSpacing.lg, ), child: SizedBox( width: double.infinity, child: FilledButton( onPressed: _isLastPage ? () => Navigator.of(context).pop() : null, child: Text( _isLastPage ? l10n.divinationIAcknowledge : '${_currentPage + 1} / ${widget.guideImages.length} · $swipeHint', ), ), ), ), ], ), ), ); } String _guideSwipeHint(Locale locale) { if (locale.languageCode == 'en') { return 'Swipe left for the next step'; } return '左滑查看下一步'; } }