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.2 KiB

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<CountDownTimerWidget> createState() => _CountDownTimerWidgetState();
}
class _CountDownTimerWidgetState extends State<CountDownTimerWidget> {
Timer? _countdownTimer;
Duration? _duration;
late final CountDownTimerCubit _cubit;
@override
void initState() {
_cubit = BlocProvider.of<CountDownTimerCubit>(context);
_duration = Duration(minutes: widget.duration);
super.initState();
}
@override
Widget build(BuildContext context) {
String strDigits(int n) => n.toString().padLeft(2, '0');
final minutes = strDigits(_duration!.inMinutes.remainder(60));
final seconds = strDigits(_duration!.inSeconds.remainder(60));
return BlocBuilder<CountDownTimerCubit, BaseCubitType<CountDownTimerState>>(
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(
'$minutes:$seconds',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(width: 8),
SvgPicture.asset('timer'.svgPath),
],
);
},
);
}
void _startTimer() {
_duration = 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(() => _duration = Duration(minutes: widget.duration));
_startTimer();
}
void _setCountDown() {
const reduceSecondsBy = 1;
setState(() {
final seconds = _duration!.inSeconds - reduceSecondsBy;
if (seconds < 0) {
widget.finishCallback.call();
_countdownTimer!.cancel();
} else {
_duration = Duration(seconds: seconds);
_cubit.setDuration(_duration!);
}
});
}
}