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
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!);
|
|
}
|
|
});
|
|
}
|
|
}
|