199 lines
6.2 KiB
Dart
199 lines
6.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import '../../core/themes/draw_slot_theme.dart';
|
|
import 'alternative_draw_animations.dart';
|
|
|
|
class DrawAnimationSelector extends StatefulWidget {
|
|
final List<Map<String, dynamic>> members;
|
|
final Function(String winnerId) onDrawComplete;
|
|
final String? serverSeed;
|
|
final String? clientSeed;
|
|
final int? nonce;
|
|
final Duration animationDuration;
|
|
/// When false, hides "Spin again" after a run (e.g. draw already finalized on parent).
|
|
final bool allowReplay;
|
|
|
|
const DrawAnimationSelector({
|
|
super.key,
|
|
required this.members,
|
|
required this.onDrawComplete,
|
|
this.serverSeed,
|
|
this.clientSeed,
|
|
this.nonce,
|
|
this.animationDuration = const Duration(seconds: 4),
|
|
this.allowReplay = true,
|
|
});
|
|
|
|
@override
|
|
State<DrawAnimationSelector> createState() => _DrawAnimationSelectorState();
|
|
}
|
|
|
|
class _DrawAnimationSelectorState extends State<DrawAnimationSelector> {
|
|
bool _isDrawStarted = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
}
|
|
|
|
void _startDraw() {
|
|
setState(() {
|
|
_isDrawStarted = true;
|
|
});
|
|
}
|
|
|
|
void _resetDraw() {
|
|
setState(() {
|
|
_isDrawStarted = false;
|
|
});
|
|
}
|
|
|
|
Widget _buildAnimationSelector(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
final scheme = theme.colorScheme;
|
|
final d = DrawSlotTheming(scheme, theme.brightness);
|
|
|
|
return Container(
|
|
padding: EdgeInsets.fromLTRB(22.w, 26.h, 22.w, 24.h),
|
|
decoration: d.introCardDecoration(),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Container(
|
|
width: 56.w,
|
|
height: 56.w,
|
|
decoration: BoxDecoration(
|
|
color: scheme.primaryContainer.withOpacity(
|
|
theme.brightness == Brightness.dark ? 0.35 : 0.65),
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
),
|
|
child: Icon(
|
|
Icons.auto_awesome_rounded,
|
|
color: scheme.primary,
|
|
size: 28.w,
|
|
),
|
|
),
|
|
SizedBox(width: 16.w),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'Monthly draw',
|
|
style: theme.textTheme.titleLarge?.copyWith(
|
|
fontWeight: FontWeight.w800,
|
|
letterSpacing: -0.2,
|
|
),
|
|
),
|
|
SizedBox(height: 4.h),
|
|
Text(
|
|
'Fair random pick with a clear on-screen reveal.',
|
|
style: theme.textTheme.bodyMedium?.copyWith(
|
|
height: 1.35,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 20.h),
|
|
Container(
|
|
padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 12.h),
|
|
decoration: BoxDecoration(
|
|
color: scheme.surfaceContainerHighest.withOpacity(
|
|
theme.brightness == Brightness.dark ? 0.5 : 1),
|
|
borderRadius: BorderRadius.circular(14.r),
|
|
border: Border.all(color: scheme.outlineVariant),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Icon(
|
|
Icons.people_alt_rounded,
|
|
size: 20.w,
|
|
color: scheme.primary,
|
|
),
|
|
SizedBox(width: 10.w),
|
|
Expanded(
|
|
child: Text(
|
|
'${widget.members.length} eligible members in this draw',
|
|
style: theme.textTheme.labelLarge?.copyWith(
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(height: 22.h),
|
|
FilledButton.icon(
|
|
onPressed: _startDraw,
|
|
icon: Icon(Icons.play_arrow_rounded, size: 22.w),
|
|
label: Text(
|
|
'Start draw',
|
|
style: theme.textTheme.labelLarge?.copyWith(
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
style: FilledButton.styleFrom(
|
|
padding: EdgeInsets.symmetric(vertical: 16.h),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final maxW = (MediaQuery.sizeOf(context).width - 32.w).clamp(280.w, 440.w);
|
|
return Align(
|
|
alignment: Alignment.topCenter,
|
|
child: SizedBox(
|
|
width: maxW,
|
|
child: Column(
|
|
children: [
|
|
if (!_isDrawStarted) _buildAnimationSelector(context),
|
|
if (_isDrawStarted) ...[
|
|
SlotMachineDrawAnimation(
|
|
members: widget.members,
|
|
onDrawComplete: widget.onDrawComplete,
|
|
serverSeed: widget.serverSeed,
|
|
clientSeed: widget.clientSeed,
|
|
nonce: widget.nonce,
|
|
animationDuration: widget.animationDuration,
|
|
),
|
|
SizedBox(height: 20.h),
|
|
if (widget.allowReplay)
|
|
SizedBox(
|
|
width: double.infinity,
|
|
child: OutlinedButton.icon(
|
|
onPressed: _resetDraw,
|
|
icon: Icon(Icons.replay_rounded, size: 20.w),
|
|
label: Text(
|
|
'Run again',
|
|
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
style: OutlinedButton.styleFrom(
|
|
padding: EdgeInsets.symmetric(vertical: 14.h),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|