show timer for actionable snackbar

This commit is contained in:
Thibault Deckers 2021-07-16 17:13:05 +09:00
parent c4e44183b0
commit da1acfcb92

View file

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:math';
import 'package:aves/theme/durations.dart';
@ -14,10 +15,14 @@ mixin FeedbackMixin {
// provide the messenger if feedback happens as the widget is disposed
void showFeedbackWithMessenger(ScaffoldMessengerState messenger, String message, [SnackBarAction? action]) {
final duration = action != null ? Durations.opToastActionDisplay : Durations.opToastDisplay;
messenger.showSnackBar(SnackBar(
content: Text(message),
content: _FeedbackMessage(
message: message,
duration: action != null ? duration : null,
),
action: action,
duration: action != null ? Durations.opToastActionDisplay : Durations.opToastDisplay,
duration: duration,
));
}
@ -136,3 +141,66 @@ class _ReportOverlayState<T> extends State<ReportOverlay<T>> with SingleTickerPr
);
}
}
class _FeedbackMessage extends StatefulWidget {
final String message;
final Duration? duration;
const _FeedbackMessage({
Key? key,
required this.message,
this.duration,
}) : super(key: key);
@override
_FeedbackMessageState createState() => _FeedbackMessageState();
}
class _FeedbackMessageState extends State<_FeedbackMessage> {
late int _totalSecs, _elapsedSecs = 0;
Timer? _timer;
@override
void initState() {
super.initState();
final duration = widget.duration;
if (duration != null) {
_totalSecs = duration.inSeconds;
_timer = Timer.periodic(const Duration(seconds: 1), (_) {
setState(() => _elapsedSecs++);
});
}
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
final text = Text(widget.message);
final duration = widget.duration;
return duration == null
? text
: Row(
children: [
Expanded(child: text),
const SizedBox(width: 16),
CircularPercentIndicator(
percent: (_elapsedSecs.toDouble() / (_totalSecs - 1)).clamp(0.0, 1.0),
lineWidth: 2,
radius: 32,
backgroundColor: Theme.of(context).accentColor,
progressColor: Colors.grey,
animation: true,
animationDuration: 1000,
center: Text('${_totalSecs - _elapsedSecs}'),
animateFromLastPercent: true,
reverse: true,
),
],
);
}
}