|
@@ -0,0 +1,277 @@
|
|
|
+import 'package:flutter/cupertino.dart';
|
|
|
+import 'package:flutter/material.dart';
|
|
|
+import 'package:flutter/painting.dart';
|
|
|
+
|
|
|
+enum ProgressDialogType { Normal, Download }
|
|
|
+
|
|
|
+String _dialogMessage = "Loading...";
|
|
|
+double _progress = 0.0, _maxProgress = 100.0;
|
|
|
+
|
|
|
+Widget _customBody;
|
|
|
+
|
|
|
+TextAlign _textAlign = TextAlign.left;
|
|
|
+Alignment _progressWidgetAlignment = Alignment.centerLeft;
|
|
|
+
|
|
|
+TextDirection _direction = TextDirection.ltr;
|
|
|
+
|
|
|
+bool _isShowing = false;
|
|
|
+BuildContext _context, _dismissingContext;
|
|
|
+ProgressDialogType _progressDialogType;
|
|
|
+bool _barrierDismissible = true, _showLogs = false;
|
|
|
+Color _barrierColor;
|
|
|
+
|
|
|
+TextStyle _progressTextStyle = TextStyle(
|
|
|
+ color: Colors.black, fontSize: 12.0, fontWeight: FontWeight.w400),
|
|
|
+ _messageStyle = TextStyle(
|
|
|
+ color: Colors.black, fontSize: 18.0, fontWeight: FontWeight.w600);
|
|
|
+
|
|
|
+double _dialogElevation = 8.0, _borderRadius = 8.0;
|
|
|
+Color _backgroundColor = Colors.white;
|
|
|
+Curve _insetAnimCurve = Curves.easeInOut;
|
|
|
+EdgeInsets _dialogPadding = const EdgeInsets.all(8.0);
|
|
|
+
|
|
|
+Widget _progressWidget = Image.asset(
|
|
|
+ 'assets/double_ring_loading_io.gif',
|
|
|
+ package: 'progress_dialog',
|
|
|
+);
|
|
|
+
|
|
|
+class ProgressDialog {
|
|
|
+ _Body _dialog;
|
|
|
+
|
|
|
+ ProgressDialog(
|
|
|
+ BuildContext context, {
|
|
|
+ ProgressDialogType type,
|
|
|
+ bool isDismissible,
|
|
|
+ bool showLogs,
|
|
|
+ TextDirection textDirection,
|
|
|
+ Widget customBody,
|
|
|
+ Color barrierColor,
|
|
|
+ }) {
|
|
|
+ _context = context;
|
|
|
+ _progressDialogType = type ?? ProgressDialogType.Normal;
|
|
|
+ _barrierDismissible = isDismissible ?? true;
|
|
|
+ _showLogs = showLogs ?? false;
|
|
|
+ _customBody = customBody ?? null;
|
|
|
+ _direction = textDirection ?? TextDirection.ltr;
|
|
|
+ _barrierColor = barrierColor ?? barrierColor;
|
|
|
+ }
|
|
|
+
|
|
|
+ void style(
|
|
|
+ {Widget child,
|
|
|
+ double progress,
|
|
|
+ double maxProgress,
|
|
|
+ String message,
|
|
|
+ Widget progressWidget,
|
|
|
+ Color backgroundColor,
|
|
|
+ TextStyle progressTextStyle,
|
|
|
+ TextStyle messageTextStyle,
|
|
|
+ double elevation,
|
|
|
+ TextAlign textAlign,
|
|
|
+ double borderRadius,
|
|
|
+ Curve insetAnimCurve,
|
|
|
+ EdgeInsets padding,
|
|
|
+ Alignment progressWidgetAlignment}) {
|
|
|
+ if (_isShowing) return;
|
|
|
+ if (_progressDialogType == ProgressDialogType.Download) {
|
|
|
+ _progress = progress ?? _progress;
|
|
|
+ }
|
|
|
+
|
|
|
+ _dialogMessage = message ?? _dialogMessage;
|
|
|
+ _maxProgress = maxProgress ?? _maxProgress;
|
|
|
+ _progressWidget = progressWidget ?? _progressWidget;
|
|
|
+ _backgroundColor = backgroundColor ?? _backgroundColor;
|
|
|
+ _messageStyle = messageTextStyle ?? _messageStyle;
|
|
|
+ _progressTextStyle = progressTextStyle ?? _progressTextStyle;
|
|
|
+ _dialogElevation = elevation ?? _dialogElevation;
|
|
|
+ _borderRadius = borderRadius ?? _borderRadius;
|
|
|
+ _insetAnimCurve = insetAnimCurve ?? _insetAnimCurve;
|
|
|
+ _textAlign = textAlign ?? _textAlign;
|
|
|
+ _progressWidget = child ?? _progressWidget;
|
|
|
+ _dialogPadding = padding ?? _dialogPadding;
|
|
|
+ _progressWidgetAlignment =
|
|
|
+ progressWidgetAlignment ?? _progressWidgetAlignment;
|
|
|
+ }
|
|
|
+
|
|
|
+ void update(
|
|
|
+ {double progress,
|
|
|
+ double maxProgress,
|
|
|
+ String message,
|
|
|
+ Widget progressWidget,
|
|
|
+ TextStyle progressTextStyle,
|
|
|
+ TextStyle messageTextStyle}) {
|
|
|
+ if (_progressDialogType == ProgressDialogType.Download) {
|
|
|
+ _progress = progress ?? _progress;
|
|
|
+ }
|
|
|
+
|
|
|
+ _dialogMessage = message ?? _dialogMessage;
|
|
|
+ _maxProgress = maxProgress ?? _maxProgress;
|
|
|
+ _progressWidget = progressWidget ?? _progressWidget;
|
|
|
+ _messageStyle = messageTextStyle ?? _messageStyle;
|
|
|
+ _progressTextStyle = progressTextStyle ?? _progressTextStyle;
|
|
|
+
|
|
|
+ if (_isShowing) _dialog.update();
|
|
|
+ }
|
|
|
+
|
|
|
+ bool isShowing() {
|
|
|
+ return _isShowing;
|
|
|
+ }
|
|
|
+
|
|
|
+ Future<bool> hide() async {
|
|
|
+ try {
|
|
|
+ if (_isShowing) {
|
|
|
+ _isShowing = false;
|
|
|
+ Navigator.of(_dismissingContext).pop();
|
|
|
+ if (_showLogs) debugPrint('ProgressDialog dismissed');
|
|
|
+ return Future.value(true);
|
|
|
+ } else {
|
|
|
+ if (_showLogs) debugPrint('ProgressDialog already dismissed');
|
|
|
+ return Future.value(false);
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ debugPrint('Seems there is an issue hiding dialog');
|
|
|
+ debugPrint(err.toString());
|
|
|
+ return Future.value(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Future<bool> show() async {
|
|
|
+ try {
|
|
|
+ if (!_isShowing) {
|
|
|
+ _dialog = new _Body();
|
|
|
+ showDialog<dynamic>(
|
|
|
+ context: _context,
|
|
|
+ barrierDismissible: _barrierDismissible,
|
|
|
+ barrierColor: _barrierColor,
|
|
|
+ builder: (BuildContext context) {
|
|
|
+ _dismissingContext = context;
|
|
|
+ return WillPopScope(
|
|
|
+ onWillPop: () async => _barrierDismissible,
|
|
|
+ child: Dialog(
|
|
|
+ backgroundColor: _backgroundColor,
|
|
|
+ insetAnimationCurve: _insetAnimCurve,
|
|
|
+ insetAnimationDuration: Duration(milliseconds: 100),
|
|
|
+ elevation: _dialogElevation,
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius:
|
|
|
+ BorderRadius.all(Radius.circular(_borderRadius))),
|
|
|
+ child: _dialog,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ },
|
|
|
+ );
|
|
|
+ // Delaying the function for 200 milliseconds
|
|
|
+ // [Default transitionDuration of DialogRoute]
|
|
|
+ await Future.delayed(Duration(milliseconds: 200));
|
|
|
+ if (_showLogs) debugPrint('ProgressDialog shown');
|
|
|
+ _isShowing = true;
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ if (_showLogs) debugPrint("ProgressDialog already shown/showing");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ _isShowing = false;
|
|
|
+ debugPrint('Exception while showing the dialog');
|
|
|
+ debugPrint(err.toString());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// ignore: must_be_immutable
|
|
|
+class _Body extends StatefulWidget {
|
|
|
+ _BodyState _dialog = _BodyState();
|
|
|
+
|
|
|
+ update() {
|
|
|
+ _dialog.update();
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ State<StatefulWidget> createState() {
|
|
|
+ return _dialog;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class _BodyState extends State<_Body> {
|
|
|
+ update() {
|
|
|
+ setState(() {});
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void dispose() {
|
|
|
+ _isShowing = false;
|
|
|
+ if (_showLogs) debugPrint('ProgressDialog dismissed by back button');
|
|
|
+ super.dispose();
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ final loader = Align(
|
|
|
+ alignment: _progressWidgetAlignment,
|
|
|
+ child: SizedBox(
|
|
|
+ width: 60.0,
|
|
|
+ height: 60.0,
|
|
|
+ child: _progressWidget,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+
|
|
|
+ final text = Expanded(
|
|
|
+ child: _progressDialogType == ProgressDialogType.Normal
|
|
|
+ ? Text(
|
|
|
+ _dialogMessage,
|
|
|
+ textAlign: _textAlign,
|
|
|
+ style: _messageStyle,
|
|
|
+ textDirection: _direction,
|
|
|
+ )
|
|
|
+ : Padding(
|
|
|
+ padding: const EdgeInsets.all(8.0),
|
|
|
+ child: Column(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ children: <Widget>[
|
|
|
+ SizedBox(height: 8.0),
|
|
|
+ Row(
|
|
|
+ children: <Widget>[
|
|
|
+ Expanded(
|
|
|
+ child: Text(
|
|
|
+ _dialogMessage,
|
|
|
+ style: _messageStyle,
|
|
|
+ textDirection: _direction,
|
|
|
+ )),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ SizedBox(height: 4.0),
|
|
|
+ Align(
|
|
|
+ alignment: Alignment.bottomRight,
|
|
|
+ child: Text(
|
|
|
+ "$_progress/$_maxProgress",
|
|
|
+ style: _progressTextStyle,
|
|
|
+ textDirection: _direction,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+
|
|
|
+ return _customBody ??
|
|
|
+ Container(
|
|
|
+ padding: _dialogPadding,
|
|
|
+ child: Column(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ children: <Widget>[
|
|
|
+ // row body
|
|
|
+ Row(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ children: <Widget>[
|
|
|
+ const SizedBox(width: 8.0),
|
|
|
+ _direction == TextDirection.ltr ? loader : text,
|
|
|
+ const SizedBox(width: 8.0),
|
|
|
+ _direction == TextDirection.rtl ? loader : text,
|
|
|
+ const SizedBox(width: 8.0)
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|