You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.3 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_bloc/flutter_bloc.dart';
  4. import 'package:flutter_svg/flutter_svg.dart';
  5. import 'package:my_flutter_puzzle/cubits/base_cubit_type.dart';
  6. import 'package:my_flutter_puzzle/cubits/count_down_timer_cubit.dart';
  7. import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart';
  8. class CountDownTimerWidget extends StatefulWidget {
  9. final int duration;
  10. final Function() finishCallback;
  11. const CountDownTimerWidget({Key? key, required this.duration, required this.finishCallback}) : super(key: key);
  12. @override
  13. State<CountDownTimerWidget> createState() => _CountDownTimerWidgetState();
  14. }
  15. class _CountDownTimerWidgetState extends State<CountDownTimerWidget> {
  16. Timer? _countdownTimer;
  17. Duration? myDuration;
  18. late final CountDownTimerCubit _cubit;
  19. @override
  20. void initState() {
  21. _cubit = BlocProvider.of<CountDownTimerCubit>(context);
  22. myDuration = Duration(minutes: widget.duration);
  23. super.initState();
  24. }
  25. void startTimer() {
  26. myDuration = Duration(minutes: widget.duration);
  27. _countdownTimer = Timer.periodic(const Duration(seconds: 1), (_) => setCountDown());
  28. }
  29. void stopTimer() {
  30. if (_countdownTimer == null) {
  31. return;
  32. }
  33. setState(() => _countdownTimer!.cancel());
  34. }
  35. void resetTimer() {
  36. stopTimer();
  37. setState(() => myDuration = Duration(minutes: widget.duration));
  38. startTimer();
  39. }
  40. void setCountDown() {
  41. const reduceSecondsBy = 1;
  42. setState(() {
  43. final seconds = myDuration!.inSeconds - reduceSecondsBy;
  44. if (seconds < 0) {
  45. widget.finishCallback.call();
  46. _countdownTimer!.cancel();
  47. } else {
  48. myDuration = Duration(seconds: seconds);
  49. }
  50. });
  51. }
  52. @override
  53. Widget build(BuildContext context) {
  54. String strDigits(int n) => n.toString().padLeft(2, '0');
  55. final hours = strDigits(myDuration!.inHours.remainder(24));
  56. final minutes = strDigits(myDuration!.inMinutes.remainder(60));
  57. final seconds = strDigits(myDuration!.inSeconds.remainder(60));
  58. return BlocBuilder<CountDownTimerCubit, BaseCubitType<CountDownTimerState>>(
  59. builder: (context, state) {
  60. switch (state.eventName!) {
  61. case CountDownTimerState.empty:
  62. break;
  63. case CountDownTimerState.start:
  64. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  65. startTimer();
  66. _cubit.empty();
  67. });
  68. break;
  69. case CountDownTimerState.stop:
  70. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  71. stopTimer();
  72. _cubit.empty();
  73. });
  74. break;
  75. case CountDownTimerState.reset:
  76. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  77. resetTimer();
  78. _cubit.empty();
  79. });
  80. break;
  81. }
  82. return Row(
  83. children: [
  84. Text(
  85. '$hours:$minutes:$seconds',
  86. style: const TextStyle(
  87. fontSize: 16,
  88. fontWeight: FontWeight.bold,
  89. color: Colors.white,
  90. ),
  91. ),
  92. const SizedBox(width: 8),
  93. SvgPicture.asset('timer'.svgPath),
  94. ],
  95. );
  96. },
  97. );
  98. }
  99. }