import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:yumi/ui_kit/components/text/sc_text.dart'; class RegisterRewardDialogItem { const RegisterRewardDialogItem({required this.title}); final String title; } class RegisterRewardDialog extends StatelessWidget { const RegisterRewardDialog({ super.key, required this.items, this.title = 'Welcome to Yumi Party', this.subtitle = 'Here are some small gifts for you', }); static const String dialogTag = 'showRegisterRewardDialog'; static const double _dialogWidth = 340; static const double _dialogHeight = 250; static const double _titleWidth = 147; static const double _titleHeight = 22; final List items; final String title; final String subtitle; static List defaultItems() { return const [ RegisterRewardDialogItem(title: 'small gifts'), RegisterRewardDialogItem(title: 'small gifts'), ]; } static Future show( BuildContext context, { List? items, String title = 'Welcome to Yumi Party', String subtitle = 'Here are some small gifts for you', }) async { SmartDialog.dismiss(tag: dialogTag); await SmartDialog.show( tag: dialogTag, alignment: Alignment.center, maskColor: Colors.black.withValues(alpha: 0.56), animationType: SmartAnimationType.fade, clickMaskDismiss: true, builder: (_) => RegisterRewardDialog( items: items ?? defaultItems(), title: title, subtitle: subtitle, ), ); } @override Widget build(BuildContext context) { final screenWidth = MediaQuery.sizeOf(context).width; final dialogWidth = math.min(screenWidth - 36.w, _dialogWidth.w); return Material( color: Colors.transparent, child: SizedBox( width: dialogWidth, child: AspectRatio( aspectRatio: _dialogWidth / _dialogHeight, child: LayoutBuilder( builder: (context, constraints) { final scale = constraints.maxWidth / _dialogWidth; return Stack( children: [ Positioned.fill( child: Image.asset( _RegisterRewardAssets.dialogBackground, fit: BoxFit.fill, ), ), PositionedDirectional( end: 28 * scale, top: 52 * scale, child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => SmartDialog.dismiss( tag: RegisterRewardDialog.dialogTag, ), child: Padding( padding: EdgeInsets.all(6 * scale), child: Image.asset( _RegisterRewardAssets.closeIcon, width: 14 * scale, height: 14 * scale, fit: BoxFit.contain, ), ), ), ), Positioned( top: 34 * scale, left: 0, right: 0, child: Center( child: _RegisterRewardTitle( text: title, width: _titleWidth * scale, height: _titleHeight * scale, ), ), ), Positioned( top: 76 * scale, left: 24 * scale, right: 24 * scale, child: text( subtitle, fontSize: 12, fontWeight: FontWeight.w400, textAlign: TextAlign.center, maxLines: 2, textColor: Colors.white, ), ), Positioned( left: 0, right: 0, bottom: 38 * scale, child: _RegisterRewardItemsRow(items: items, scale: scale), ), ], ); }, ), ), ), ); } } class _RegisterRewardTitle extends StatelessWidget { const _RegisterRewardTitle({ required this.text, required this.width, required this.height, }); final String text; final double width; final double height; @override Widget build(BuildContext context) { const gradientColors = [ Color(0xFFFFF2BA), Color(0xFFFFFAE3), Color(0xFFFFF2BA), Color(0xFFFFFBE8), Color(0xFFFFF2BA), ]; final shadowTextStyle = TextStyle( fontSize: 15.sp, fontWeight: FontWeight.w500, height: 1.0, color: Colors.white, shadows: const [ Shadow(color: Color(0xFF17614D), blurRadius: 4, offset: Offset.zero), ], ); final gradientTextStyle = TextStyle( fontSize: 15.sp, fontWeight: FontWeight.w500, height: 1.0, color: Colors.white, ); return SizedBox( width: width, height: height, child: Stack( alignment: Alignment.center, children: [ FittedBox( fit: BoxFit.scaleDown, child: Text( text, maxLines: 1, textAlign: TextAlign.center, style: shadowTextStyle, ), ), ShaderMask( blendMode: BlendMode.srcIn, shaderCallback: (bounds) { return const LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: gradientColors, ).createShader(bounds); }, child: FittedBox( fit: BoxFit.scaleDown, child: Text( text, maxLines: 1, textAlign: TextAlign.center, style: gradientTextStyle, ), ), ), ], ), ); } } class _RegisterRewardItemsRow extends StatelessWidget { const _RegisterRewardItemsRow({required this.items, required this.scale}); final List items; final double scale; @override Widget build(BuildContext context) { final visibleItems = items.take(2).toList(); return Row( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ for (var index = 0; index < visibleItems.length; index++) ...[ _RegisterRewardItemCard(item: visibleItems[index], scale: scale), if (index != visibleItems.length - 1) SizedBox(width: 30 * scale), ], ], ); } } class _RegisterRewardItemCard extends StatelessWidget { const _RegisterRewardItemCard({required this.item, required this.scale}); final RegisterRewardDialogItem item; final double scale; @override Widget build(BuildContext context) { return SizedBox( width: 88 * scale, child: Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: 88 * scale, height: 88 * scale, child: Stack( alignment: Alignment.center, children: [ Image.asset( _RegisterRewardAssets.goldGlowBackground, width: 88 * scale, height: 88 * scale, fit: BoxFit.fill, ), Container( width: 44 * scale, height: 44 * scale, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.white.withValues(alpha: 0.10), border: Border.all( color: Colors.white.withValues(alpha: 0.62), width: 1.2 * scale, ), boxShadow: [ BoxShadow( color: Colors.white.withValues(alpha: 0.10), blurRadius: 8 * scale, offset: Offset.zero, ), ], ), child: Center( child: Container( width: 18 * scale, height: 18 * scale, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.white.withValues(alpha: 0.18), ), ), ), ), ], ), ), SizedBox(height: 8 * scale), text( item.title, fontSize: 12, fontWeight: FontWeight.w400, textAlign: TextAlign.center, maxLines: 2, lineHeight: 1.2, textColor: Colors.white, ), ], ), ); } } class _RegisterRewardAssets { static const String dialogBackground = 'sc_images/register_reward/dialog_background.png'; static const String goldGlowBackground = 'sc_images/register_reward/gold_glow_background.png'; static const String closeIcon = 'sc_images/register_reward/close_icon.png'; }