diff --git a/lib/screens/timer/bloc_timer.dart b/lib/screens/timer/bloc_timer.dart index 687e09a..79bc353 100644 --- a/lib/screens/timer/bloc_timer.dart +++ b/lib/screens/timer/bloc_timer.dart @@ -5,75 +5,30 @@ import 'package:lightmeter/interactors/metering_interactor.dart'; import 'package:lightmeter/screens/timer/event_timer.dart'; import 'package:lightmeter/screens/timer/state_timer.dart'; -const _kTimerStep = Duration(milliseconds: 1); - class TimerBloc extends Bloc { final MeteringInteractor _meteringInteractor; - late Timer? _timer; final Duration duration; - TimerBloc(this._meteringInteractor, this.duration) - : super( - TimerStoppedState( - duration: duration, - timeLeft: duration, - ), - ) { + TimerBloc(this._meteringInteractor, this.duration) : super(const TimerStoppedState()) { on(_onStartTimer); on(_onSetTimeLeft); on(_onStopTimer); on(_onResetTimer); } - @override - Future close() async { - _timer?.cancel(); - return super.close(); - } - Future _onStartTimer(StartTimerEvent _, Emitter emit) async { - emit( - TimerResumedState( - duration: state.duration, - timeLeft: state.timeLeft, - ), - ); - - _timer = Timer.periodic(_kTimerStep, (_) { - if (state.timeLeft.inMilliseconds == 0) { - add(const StopTimerEvent()); - } else { - add(SetTimeLeftEvent(state.timeLeft - _kTimerStep)); - } - }); + emit(const TimerResumedState()); } Future _onSetTimeLeft(SetTimeLeftEvent event, Emitter emit) async { - emit( - TimerResumedState( - duration: state.duration, - timeLeft: event.timeLeft, - ), - ); + emit(const TimerResumedState()); } Future _onStopTimer(StopTimerEvent _, Emitter emit) async { - _timer?.cancel(); - emit( - TimerStoppedState( - duration: state.duration, - timeLeft: state.timeLeft, - ), - ); + emit(const TimerStoppedState()); } Future _onResetTimer(ResetTimerEvent _, Emitter emit) async { - _timer?.cancel(); - emit( - TimerResetState( - duration: state.duration, - timeLeft: state.duration, - ), - ); + emit(const TimerResetState()); } } diff --git a/lib/screens/timer/flow_timer.dart b/lib/screens/timer/flow_timer.dart index 881bd61..68b219c 100644 --- a/lib/screens/timer/flow_timer.dart +++ b/lib/screens/timer/flow_timer.dart @@ -42,7 +42,10 @@ class TimerFlow extends StatelessWidget { MeteringInteractorProvider.of(context), _duration, ), - child: TimerScreen(exposurePair: exposurePair), + child: TimerScreen( + exposurePair: exposurePair, + duration: _duration, + ), ), ), ); diff --git a/lib/screens/timer/screen_timer.dart b/lib/screens/timer/screen_timer.dart index f28b63c..b98b6a6 100644 --- a/lib/screens/timer/screen_timer.dart +++ b/lib/screens/timer/screen_timer.dart @@ -1,21 +1,22 @@ -import 'dart:math'; - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lightmeter/data/models/exposure_pair.dart'; -import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/screens/timer/bloc_timer.dart'; import 'package:lightmeter/screens/timer/components/text/widget_text_timer.dart'; import 'package:lightmeter/screens/timer/components/timeline/widget_timeline_timer.dart'; import 'package:lightmeter/screens/timer/event_timer.dart'; import 'package:lightmeter/screens/timer/state_timer.dart'; -import 'package:material_color_utilities/material_color_utilities.dart'; class TimerScreen extends StatefulWidget { final ExposurePair exposurePair; + final Duration duration; - const TimerScreen({required this.exposurePair, super.key}); + const TimerScreen({ + required this.exposurePair, + required this.duration, + super.key, + }); @override State createState() => _TimerScreenState(); @@ -31,11 +32,13 @@ class _TimerScreenState extends State with TickerProviderStateMixin void initState() { super.initState(); - timelineController = AnimationController( - vsync: this, - duration: Duration(seconds: widget.exposurePair.shutterSpeed.value.toInt()), - ); + timelineController = AnimationController(vsync: this, duration: widget.duration); timelineAnimation = Tween(begin: 1, end: 0).animate(timelineController); + timelineController.addStatusListener((status) { + if (status == AnimationStatus.completed) { + context.read().add(const StopTimerEvent()); + } + }); startStopIconController = AnimationController(vsync: this, duration: Dimens.durationS); startStopIconAnimation = Tween(begin: 0, end: 1).animate(startStopIconController); @@ -56,7 +59,6 @@ class _TimerScreenState extends State with TickerProviderStateMixin @override Widget build(BuildContext context) { - // TODO (@vodemn): split build in timer/components folder return BlocListener( listenWhen: (previous, current) => previous.runtimeType != current.runtimeType, listener: (context, state) => _updateAnimations(state), @@ -88,13 +90,9 @@ class _TimerScreenState extends State with TickerProviderStateMixin valueListenable: timelineAnimation, builder: (_, value, child) => TimerTimeline( progress: value, - child: child!, - ), - child: BlocBuilder( - buildWhen: (previous, current) => previous.timeLeft != current.timeLeft, - builder: (_, state) => TimerText( - timeLeft: state.timeLeft, - duration: state.duration, + child: TimerText( + timeLeft: Duration(milliseconds: (widget.duration.inMilliseconds * value).toInt()), + duration: widget.duration, ), ), ), @@ -117,13 +115,14 @@ class _TimerScreenState extends State with TickerProviderStateMixin child: BlocBuilder( builder: (_, state) => FloatingActionButton( shape: state is TimerResumedState ? null : const CircleBorder(), - onPressed: state.timeLeft.inSeconds == 0 - ? null - : () { - final event = - state is TimerStoppedState ? const StartTimerEvent() : const StopTimerEvent(); - context.read().add(event); - }, + onPressed: () { + if (timelineAnimation.value == 0) { + return; + } + final event = + state is TimerStoppedState ? const StartTimerEvent() : const StopTimerEvent(); + context.read().add(event); + }, child: AnimatedIcon( icon: AnimatedIcons.play_pause, progress: startStopIconAnimation, diff --git a/lib/screens/timer/state_timer.dart b/lib/screens/timer/state_timer.dart index ec570b3..f088382 100644 --- a/lib/screens/timer/state_timer.dart +++ b/lib/screens/timer/state_timer.dart @@ -2,32 +2,17 @@ import 'package:flutter/material.dart'; @immutable sealed class TimerState { - final Duration duration; - final Duration timeLeft; - - const TimerState({ - required this.duration, - required this.timeLeft, - }); + const TimerState(); } class TimerStoppedState extends TimerState { - const TimerStoppedState({ - required super.duration, - required super.timeLeft, - }); + const TimerStoppedState(); } class TimerResumedState extends TimerState { - const TimerResumedState({ - required super.duration, - required super.timeLeft, - }); + const TimerResumedState(); } class TimerResetState extends TimerStoppedState { - const TimerResetState({ - required super.duration, - required super.timeLeft, - }); + const TimerResetState(); }