show timer for actionable snackbar
This commit is contained in:
parent
c4e44183b0
commit
da1acfcb92
1 changed files with 70 additions and 2 deletions
|
@ -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,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue