import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:my_flutter_puzzle/cubits/base_cubit_type.dart'; import 'package:my_flutter_puzzle/cubits/count_down_timer_cubit.dart'; import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart'; class CountDownTimerWidget extends StatefulWidget { final int duration; final Function() finishCallback; const CountDownTimerWidget({Key? key, required this.duration, required this.finishCallback}) : super(key: key); @override State createState() => _CountDownTimerWidgetState(); } class _CountDownTimerWidgetState extends State { Timer? _countdownTimer; Duration? myDuration; late final CountDownTimerCubit _cubit; @override void initState() { _cubit = BlocProvider.of(context); myDuration = Duration(minutes: widget.duration); super.initState(); } void startTimer() { myDuration = Duration(minutes: widget.duration); _countdownTimer = Timer.periodic(const Duration(seconds: 1), (_) => setCountDown()); } void stopTimer() { if (_countdownTimer == null) { return; } setState(() => _countdownTimer!.cancel()); } void resetTimer() { stopTimer(); setState(() => myDuration = Duration(minutes: widget.duration)); startTimer(); } void setCountDown() { const reduceSecondsBy = 1; setState(() { final seconds = myDuration!.inSeconds - reduceSecondsBy; if (seconds < 0) { widget.finishCallback.call(); _countdownTimer!.cancel(); } else { myDuration = Duration(seconds: seconds); } }); } @override Widget build(BuildContext context) { String strDigits(int n) => n.toString().padLeft(2, '0'); final hours = strDigits(myDuration!.inHours.remainder(24)); final minutes = strDigits(myDuration!.inMinutes.remainder(60)); final seconds = strDigits(myDuration!.inSeconds.remainder(60)); return BlocBuilder>( builder: (context, state) { switch (state.eventName!) { case CountDownTimerState.empty: break; case CountDownTimerState.start: WidgetsBinding.instance.addPostFrameCallback((timeStamp) { startTimer(); _cubit.empty(); }); break; case CountDownTimerState.stop: WidgetsBinding.instance.addPostFrameCallback((timeStamp) { stopTimer(); _cubit.empty(); }); break; case CountDownTimerState.reset: WidgetsBinding.instance.addPostFrameCallback((timeStamp) { resetTimer(); _cubit.empty(); }); break; } return Row( children: [ Text( '$hours:$minutes:$seconds', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(width: 8), SvgPicture.asset('timer'.svgPath), ], ); }, ); } }