mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-22 07:20:39 +00:00
added reset button (wip)
This commit is contained in:
parent
b008ef7c83
commit
985ecaa41e
4 changed files with 97 additions and 37 deletions
|
@ -68,7 +68,7 @@ class TimerBloc extends Bloc<TimerEvent, TimerState> {
|
|||
Future<void> _onResetTimer(ResetTimerEvent _, Emitter emit) async {
|
||||
_timer?.cancel();
|
||||
emit(
|
||||
TimerStoppedState(
|
||||
TimerResetState(
|
||||
duration: state.duration,
|
||||
timeLeft: state.duration,
|
||||
),
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/interactors/metering_interactor.dart';
|
||||
import 'package:lightmeter/providers/services_provider.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/timer/bloc_timer.dart';
|
||||
import 'package:lightmeter/screens/timer/screen_timer.dart';
|
||||
|
||||
|
@ -10,7 +11,19 @@ class TimerFlow extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MeteringInteractorProvider(
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
return IconButtonTheme(
|
||||
data: IconButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStatePropertyAll(scheme.surface),
|
||||
elevation: const MaterialStatePropertyAll(4),
|
||||
iconColor: MaterialStatePropertyAll(scheme.onSurface),
|
||||
shadowColor: const MaterialStatePropertyAll(Colors.transparent),
|
||||
surfaceTintColor: MaterialStatePropertyAll(scheme.surfaceTint),
|
||||
fixedSize: const MaterialStatePropertyAll(Size(Dimens.grid48, Dimens.grid48)),
|
||||
),
|
||||
),
|
||||
child: MeteringInteractorProvider(
|
||||
data: MeteringInteractor(
|
||||
ServicesProvider.of(context).userPreferencesService,
|
||||
ServicesProvider.of(context).caffeineService,
|
||||
|
@ -22,10 +35,11 @@ class TimerFlow extends StatelessWidget {
|
|||
child: BlocProvider(
|
||||
create: (context) => TimerBloc(
|
||||
MeteringInteractorProvider.of(context),
|
||||
124,
|
||||
60,
|
||||
),
|
||||
child: const TimerScreen(
|
||||
duration: const Duration(seconds: 124),
|
||||
duration: const Duration(seconds: 60),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -50,10 +50,9 @@ class _TimerScreenState extends State<TimerScreen> with TickerProviderStateMixin
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// TODO (@vodemn): split build in timer/components folder
|
||||
return BlocListener<TimerBloc, TimerState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous is TimerStoppedState && current is TimerResumedState ||
|
||||
previous is TimerResumedState && current is TimerStoppedState,
|
||||
listenWhen: (previous, current) => previous.runtimeType != current.runtimeType,
|
||||
listener: (context, state) => _updateAnimations(state),
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
|
@ -95,12 +94,29 @@ class _TimerScreenState extends State<TimerScreen> with TickerProviderStateMixin
|
|||
),
|
||||
),
|
||||
const Spacer(),
|
||||
BlocBuilder<TimerBloc, TimerState>(
|
||||
builder: (_, state) => FloatingActionButton(
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
context.read<TimerBloc>().add(
|
||||
state is TimerStoppedState ? const StartTimerEvent() : const StopTimerEvent(),
|
||||
);
|
||||
context.read<TimerBloc>().add(const ResetTimerEvent());
|
||||
},
|
||||
icon: const Icon(Icons.restore),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox.fromSize(
|
||||
size: const Size.square(Dimens.grid72),
|
||||
child: BlocBuilder<TimerBloc, TimerState>(
|
||||
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<TimerBloc>().add(event);
|
||||
},
|
||||
child: AnimatedIcon(
|
||||
icon: AnimatedIcons.play_pause,
|
||||
|
@ -108,6 +124,10 @@ class _TimerScreenState extends State<TimerScreen> with TickerProviderStateMixin
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -119,6 +139,10 @@ class _TimerScreenState extends State<TimerScreen> with TickerProviderStateMixin
|
|||
|
||||
void _updateAnimations(TimerState state) {
|
||||
switch (state) {
|
||||
case TimerResetState():
|
||||
startStopIconController.reverse();
|
||||
timelineController.stop();
|
||||
timelineController.animateTo(0, duration: Dimens.durationS);
|
||||
case TimerResumedState():
|
||||
startStopIconController.forward();
|
||||
timelineController.forward();
|
||||
|
@ -210,7 +234,6 @@ class _TimelinePainter extends CustomPainter {
|
|||
final double progress;
|
||||
|
||||
late final double timelineEdgeRadius = strokeWidth / 2;
|
||||
late final double radiansProgress = 2 * pi * progress;
|
||||
static const double radiansQuarterTurn = -pi / 2;
|
||||
static const double strokeWidth = Dimens.grid8;
|
||||
|
||||
|
@ -222,11 +245,22 @@ class _TimelinePainter extends CustomPainter {
|
|||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
print('PROGRESS: $progress');
|
||||
late final double radiansProgress = 2 * pi * progress;
|
||||
final radius = size.height / 2;
|
||||
final timerCenter = Offset(radius, radius);
|
||||
final timelineSegmentPath = Path.combine(
|
||||
PathOperation.difference,
|
||||
Path()
|
||||
|
||||
final timelineSegmentPath = Path();
|
||||
if (progress == 1) {
|
||||
timelineSegmentPath.addOval(
|
||||
Rect.fromCenter(
|
||||
center: timerCenter,
|
||||
height: size.height,
|
||||
width: size.width,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
timelineSegmentPath
|
||||
..arcTo(
|
||||
Rect.fromCenter(
|
||||
center: timerCenter,
|
||||
|
@ -238,7 +272,12 @@ class _TimelinePainter extends CustomPainter {
|
|||
false,
|
||||
)
|
||||
..lineTo(radius, radius)
|
||||
..lineTo(radius, 0),
|
||||
..lineTo(radius, 0);
|
||||
}
|
||||
|
||||
final timelinePath = Path.combine(
|
||||
PathOperation.difference,
|
||||
timelineSegmentPath,
|
||||
Path()
|
||||
..addOval(
|
||||
Rect.fromCircle(
|
||||
|
@ -293,7 +332,7 @@ class _TimelinePainter extends CustomPainter {
|
|||
canvas.drawPath(
|
||||
Path.combine(
|
||||
PathOperation.union,
|
||||
timelineSegmentPath,
|
||||
timelinePath,
|
||||
smoothEdgesPath,
|
||||
),
|
||||
Paint()..color = progressColor,
|
||||
|
@ -301,5 +340,5 @@ class _TimelinePainter extends CustomPainter {
|
|||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(_TimelinePainter oldDelegate) => oldDelegate.progress != progress;
|
||||
bool shouldRepaint(_TimelinePainter oldDelegate) => true;
|
||||
}
|
||||
|
|
|
@ -24,3 +24,10 @@ class TimerResumedState extends TimerState {
|
|||
required super.timeLeft,
|
||||
});
|
||||
}
|
||||
|
||||
class TimerResetState extends TimerStoppedState {
|
||||
const TimerResetState({
|
||||
required super.duration,
|
||||
required super.timeLeft,
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue