add queue, improve logic, close the specific snackbar inside a queue
Showing
4 changed files
with
143 additions
and
232 deletions
| @@ -7,7 +7,7 @@ import 'routes/app_pages.dart'; | @@ -7,7 +7,7 @@ import 'routes/app_pages.dart'; | ||
| 7 | import 'shared/logger/logger_utils.dart'; | 7 | import 'shared/logger/logger_utils.dart'; | 
| 8 | 8 | ||
| 9 | void main() { | 9 | void main() { | 
| 10 | - runApp(const MyApp()); | 10 | + runApp(MyApp()); | 
| 11 | } | 11 | } | 
| 12 | 12 | ||
| 13 | class MyApp extends StatelessWidget { | 13 | class MyApp extends StatelessWidget { | 
| @@ -16,5 +16,5 @@ export 'src/routes/get_route.dart'; | @@ -16,5 +16,5 @@ export 'src/routes/get_route.dart'; | ||
| 16 | export 'src/routes/observers/route_observer.dart'; | 16 | export 'src/routes/observers/route_observer.dart'; | 
| 17 | export 'src/routes/route_middleware.dart'; | 17 | export 'src/routes/route_middleware.dart'; | 
| 18 | export 'src/routes/transitions_type.dart'; | 18 | export 'src/routes/transitions_type.dart'; | 
| 19 | -export 'src/snackbar/snack.dart'; | 19 | +export 'src/snackbar/snackbar.dart'; | 
| 20 | export 'src/snackbar/snackbar_controller.dart'; | 20 | export 'src/snackbar/snackbar_controller.dart'; | 
| @@ -8,6 +8,7 @@ import '../../../get_core/get_core.dart'; | @@ -8,6 +8,7 @@ import '../../../get_core/get_core.dart'; | ||
| 8 | import '../../get_navigation.dart'; | 8 | import '../../get_navigation.dart'; | 
| 9 | 9 | ||
| 10 | typedef OnTap = void Function(GetSnackBar snack); | 10 | typedef OnTap = void Function(GetSnackBar snack); | 
| 11 | + | ||
| 11 | typedef SnackbarStatusCallback = void Function(SnackbarStatus? status); | 12 | typedef SnackbarStatusCallback = void Function(SnackbarStatus? status); | 
| 12 | 13 | ||
| 13 | class GetSnackBar extends StatefulWidget { | 14 | class GetSnackBar extends StatefulWidget { | 
| @@ -17,6 +18,11 @@ class GetSnackBar extends StatefulWidget { | @@ -17,6 +18,11 @@ class GetSnackBar extends StatefulWidget { | ||
| 17 | /// The title displayed to the user | 18 | /// The title displayed to the user | 
| 18 | final String? title; | 19 | final String? title; | 
| 19 | 20 | ||
| 21 | + /// The direction in which the SnackBar can be dismissed. | ||
| 22 | + /// | ||
| 23 | + /// Cannot be null, defaults to [DismissDirection.down] when | ||
| 24 | + /// [snackPosition] == [SnackPosition.BOTTOM] and [DismissDirection.up] | ||
| 25 | + /// when [snackPosition] == [SnackPosition.TOP] | ||
| 20 | final DismissDirection? dismissDirection; | 26 | final DismissDirection? dismissDirection; | 
| 21 | 27 | ||
| 22 | /// The message displayed to the user. | 28 | /// The message displayed to the user. | 
| @@ -44,7 +50,8 @@ class GetSnackBar extends StatefulWidget { | @@ -44,7 +50,8 @@ class GetSnackBar extends StatefulWidget { | ||
| 44 | /// Check (this example)[https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/shadows.dart] | 50 | /// Check (this example)[https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/shadows.dart] | 
| 45 | final List<BoxShadow>? boxShadows; | 51 | final List<BoxShadow>? boxShadows; | 
| 46 | 52 | ||
| 47 | - /// Makes [backgroundColor] be ignored. | 53 | + /// Give to GetSnackbar a gradient background. | 
| 54 | + /// It Makes [backgroundColor] be ignored. | ||
| 48 | final Gradient? backgroundGradient; | 55 | final Gradient? backgroundGradient; | 
| 49 | 56 | ||
| 50 | /// You can use any widget here, but I recommend [Icon] or [Image] as | 57 | /// You can use any widget here, but I recommend [Icon] or [Image] as | 
| @@ -55,7 +62,10 @@ class GetSnackBar extends StatefulWidget { | @@ -55,7 +62,10 @@ class GetSnackBar extends StatefulWidget { | ||
| 55 | /// An option to animate the icon (if present). Defaults to true. | 62 | /// An option to animate the icon (if present). Defaults to true. | 
| 56 | final bool shouldIconPulse; | 63 | final bool shouldIconPulse; | 
| 57 | 64 | ||
| 58 | - /// A [TextButton] widget if you need an action from the user. | 65 | + /// (optional) An action that the user can take based on the snack bar. | 
| 66 | + /// | ||
| 67 | + /// For example, the snack bar might let the user undo the operation that | ||
| 68 | + /// prompted the snackbar. | ||
| 59 | final Widget? mainButton; | 69 | final Widget? mainButton; | 
| 60 | 70 | ||
| 61 | /// A callback that registers the user's click anywhere. | 71 | /// A callback that registers the user's click anywhere. | 
| @@ -200,6 +210,13 @@ class GetSnackBar extends StatefulWidget { | @@ -200,6 +210,13 @@ class GetSnackBar extends StatefulWidget { | ||
| 200 | } | 210 | } | 
| 201 | } | 211 | } | 
| 202 | 212 | ||
| 213 | +enum RowStyle { | ||
| 214 | + icon, | ||
| 215 | + action, | ||
| 216 | + all, | ||
| 217 | + none, | ||
| 218 | +} | ||
| 219 | + | ||
| 203 | /// Indicates Status of snackbar | 220 | /// Indicates Status of snackbar | 
| 204 | /// [SnackbarStatus.OPEN] Snack is fully open, [SnackbarStatus.CLOSED] Snackbar | 221 | /// [SnackbarStatus.OPEN] Snack is fully open, [SnackbarStatus.CLOSED] Snackbar | 
| 205 | /// has closed, | 222 | /// has closed, | 
| @@ -235,12 +252,30 @@ class _GetSnackBarState extends State<GetSnackBar> | @@ -235,12 +252,30 @@ class _GetSnackBarState extends State<GetSnackBar> | ||
| 235 | 252 | ||
| 236 | final Completer<Size> _boxHeightCompleter = Completer<Size>(); | 253 | final Completer<Size> _boxHeightCompleter = Completer<Size>(); | 
| 237 | 254 | ||
| 238 | - late VoidCallback _progressListener; | ||
| 239 | - | ||
| 240 | late CurvedAnimation _progressAnimation; | 255 | late CurvedAnimation _progressAnimation; | 
| 241 | 256 | ||
| 242 | final _backgroundBoxKey = GlobalKey(); | 257 | final _backgroundBoxKey = GlobalKey(); | 
| 243 | 258 | ||
| 259 | + double get buttonPadding { | ||
| 260 | + if (widget.padding.right - 12 < 0) { | ||
| 261 | + return 4; | ||
| 262 | + } else { | ||
| 263 | + return widget.padding.right - 12; | ||
| 264 | + } | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + RowStyle get _rowStyle { | ||
| 268 | + if (widget.mainButton != null && widget.icon == null) { | ||
| 269 | + return RowStyle.action; | ||
| 270 | + } else if (widget.mainButton == null && widget.icon != null) { | ||
| 271 | + return RowStyle.icon; | ||
| 272 | + } else if (widget.mainButton != null && widget.icon != null) { | ||
| 273 | + return RowStyle.all; | ||
| 274 | + } else { | ||
| 275 | + return RowStyle.none; | ||
| 276 | + } | ||
| 277 | + } | ||
| 278 | + | ||
| 244 | @override | 279 | @override | 
| 245 | Widget build(BuildContext context) { | 280 | Widget build(BuildContext context) { | 
| 246 | return Align( | 281 | return Align( | 
| @@ -258,7 +293,42 @@ class _GetSnackBarState extends State<GetSnackBar> | @@ -258,7 +293,42 @@ class _GetSnackBarState extends State<GetSnackBar> | ||
| 258 | top: widget.snackPosition == SnackPosition.TOP, | 293 | top: widget.snackPosition == SnackPosition.TOP, | 
| 259 | left: false, | 294 | left: false, | 
| 260 | right: false, | 295 | right: false, | 
| 261 | - child: _getSnack(), | 296 | + child: Stack( | 
| 297 | + children: [ | ||
| 298 | + FutureBuilder<Size>( | ||
| 299 | + future: _boxHeightCompleter.future, | ||
| 300 | + builder: (context, snapshot) { | ||
| 301 | + if (snapshot.hasData) { | ||
| 302 | + if (widget.barBlur == 0) { | ||
| 303 | + return _emptyWidget; | ||
| 304 | + } | ||
| 305 | + return ClipRRect( | ||
| 306 | + borderRadius: BorderRadius.circular(widget.borderRadius), | ||
| 307 | + child: BackdropFilter( | ||
| 308 | + filter: ImageFilter.blur( | ||
| 309 | + sigmaX: widget.barBlur!, sigmaY: widget.barBlur!), | ||
| 310 | + child: Container( | ||
| 311 | + height: snapshot.data!.height, | ||
| 312 | + width: snapshot.data!.width, | ||
| 313 | + decoration: BoxDecoration( | ||
| 314 | + color: Colors.transparent, | ||
| 315 | + borderRadius: | ||
| 316 | + BorderRadius.circular(widget.borderRadius), | ||
| 317 | + ), | ||
| 318 | + ), | ||
| 319 | + ), | ||
| 320 | + ); | ||
| 321 | + } else { | ||
| 322 | + return _emptyWidget; | ||
| 323 | + } | ||
| 324 | + }, | ||
| 325 | + ), | ||
| 326 | + if (widget.userInputForm != null) | ||
| 327 | + _containerWithForm() | ||
| 328 | + else | ||
| 329 | + _containerWithoutForm() | ||
| 330 | + ], | ||
| 331 | + ), | ||
| 262 | ), | 332 | ), | 
| 263 | ), | 333 | ), | 
| 264 | ); | 334 | ); | 
| @@ -267,8 +337,7 @@ class _GetSnackBarState extends State<GetSnackBar> | @@ -267,8 +337,7 @@ class _GetSnackBarState extends State<GetSnackBar> | ||
| 267 | @override | 337 | @override | 
| 268 | void dispose() { | 338 | void dispose() { | 
| 269 | _fadeController?.dispose(); | 339 | _fadeController?.dispose(); | 
| 270 | - | ||
| 271 | - widget.progressIndicatorController?.removeListener(_progressListener); | 340 | + widget.progressIndicatorController?.removeListener(_updateProgress); | 
| 272 | widget.progressIndicatorController?.dispose(); | 341 | widget.progressIndicatorController?.dispose(); | 
| 273 | 342 | ||
| 274 | _focusAttachment.detach(); | 343 | _focusAttachment.detach(); | 
| @@ -284,9 +353,8 @@ class _GetSnackBarState extends State<GetSnackBar> | @@ -284,9 +353,8 @@ class _GetSnackBarState extends State<GetSnackBar> | ||
| 284 | widget.userInputForm != null || | 353 | widget.userInputForm != null || | 
| 285 | ((widget.message != null && widget.message!.isNotEmpty) || | 354 | ((widget.message != null && widget.message!.isNotEmpty) || | 
| 286 | widget.messageText != null), | 355 | widget.messageText != null), | 
| 287 | - """ | ||
| 288 | -A message is mandatory if you are not using userInputForm. | ||
| 289 | -Set either a message or messageText"""); | 356 | + ''' | 
| 357 | +You need to either use message[String], or messageText[Widget] or define a userInputForm[Form] in GetSnackbar'''); | ||
| 290 | 358 | ||
| 291 | _isTitlePresent = (widget.title != null || widget.titleText != null); | 359 | _isTitlePresent = (widget.title != null || widget.titleText != null); | 
| 292 | _messageTopMargin = _isTitlePresent ? 6.0 : widget.padding.top; | 360 | _messageTopMargin = _isTitlePresent ? 6.0 : widget.padding.top; | 
| @@ -339,10 +407,7 @@ Set either a message or messageText"""); | @@ -339,10 +407,7 @@ Set either a message or messageText"""); | ||
| 339 | void _configureProgressIndicatorAnimation() { | 407 | void _configureProgressIndicatorAnimation() { | 
| 340 | if (widget.showProgressIndicator && | 408 | if (widget.showProgressIndicator && | 
| 341 | widget.progressIndicatorController != null) { | 409 | widget.progressIndicatorController != null) { | 
| 342 | - _progressListener = () { | ||
| 343 | - setState(() {}); | ||
| 344 | - }; | ||
| 345 | - widget.progressIndicatorController!.addListener(_progressListener); | 410 | + widget.progressIndicatorController!.addListener(_updateProgress); | 
| 346 | 411 | ||
| 347 | _progressAnimation = CurvedAnimation( | 412 | _progressAnimation = CurvedAnimation( | 
| 348 | curve: Curves.linear, parent: widget.progressIndicatorController!); | 413 | curve: Curves.linear, parent: widget.progressIndicatorController!); | 
| @@ -371,7 +436,7 @@ Set either a message or messageText"""); | @@ -371,7 +436,7 @@ Set either a message or messageText"""); | ||
| 371 | _fadeController!.forward(); | 436 | _fadeController!.forward(); | 
| 372 | } | 437 | } | 
| 373 | 438 | ||
| 374 | - Widget _generateInputSnack() { | 439 | + Widget _containerWithForm() { | 
| 375 | return Container( | 440 | return Container( | 
| 376 | key: _backgroundBoxKey, | 441 | key: _backgroundBoxKey, | 
| 377 | constraints: widget.maxWidth != null | 442 | constraints: widget.maxWidth != null | 
| @@ -383,7 +448,10 @@ Set either a message or messageText"""); | @@ -383,7 +448,10 @@ Set either a message or messageText"""); | ||
| 383 | boxShadow: widget.boxShadows, | 448 | boxShadow: widget.boxShadows, | 
| 384 | borderRadius: BorderRadius.circular(widget.borderRadius), | 449 | borderRadius: BorderRadius.circular(widget.borderRadius), | 
| 385 | border: widget.borderColor != null | 450 | border: widget.borderColor != null | 
| 386 | - ? Border.all(color: widget.borderColor!, width: widget.borderWidth!) | 451 | + ? Border.all( | 
| 452 | + color: widget.borderColor!, | ||
| 453 | + width: widget.borderWidth!, | ||
| 454 | + ) | ||
| 387 | : null, | 455 | : null, | 
| 388 | ), | 456 | ), | 
| 389 | child: Padding( | 457 | child: Padding( | 
| @@ -398,7 +466,14 @@ Set either a message or messageText"""); | @@ -398,7 +466,14 @@ Set either a message or messageText"""); | ||
| 398 | ); | 466 | ); | 
| 399 | } | 467 | } | 
| 400 | 468 | ||
| 401 | - Widget _generateSnack() { | 469 | + Widget _containerWithoutForm() { | 
| 470 | + final iconPadding = widget.padding.left > 16.0 ? widget.padding.left : 0.0; | ||
| 471 | + final left = _rowStyle == RowStyle.icon || _rowStyle == RowStyle.all | ||
| 472 | + ? 4.0 | ||
| 473 | + : widget.padding.left; | ||
| 474 | + final right = _rowStyle == RowStyle.action || _rowStyle == RowStyle.all | ||
| 475 | + ? 8.0 | ||
| 476 | + : widget.padding.right; | ||
| 402 | return Container( | 477 | return Container( | 
| 403 | key: _backgroundBoxKey, | 478 | key: _backgroundBoxKey, | 
| 404 | constraints: widget.maxWidth != null | 479 | constraints: widget.maxWidth != null | 
| @@ -427,63 +502,12 @@ Set either a message or messageText"""); | @@ -427,63 +502,12 @@ Set either a message or messageText"""); | ||
| 427 | : _emptyWidget, | 502 | : _emptyWidget, | 
| 428 | Row( | 503 | Row( | 
| 429 | mainAxisSize: MainAxisSize.max, | 504 | mainAxisSize: MainAxisSize.max, | 
| 430 | - children: _getAppropriateRowLayout(), | ||
| 431 | - ), | ||
| 432 | - ], | ||
| 433 | - ), | ||
| 434 | - ); | ||
| 435 | - } | ||
| 436 | - | ||
| 437 | - List<Widget> _getAppropriateRowLayout() { | ||
| 438 | - double buttonRightPadding; | ||
| 439 | - var iconPadding = 0.0; | ||
| 440 | - if (widget.padding.right - 12 < 0) { | ||
| 441 | - buttonRightPadding = 4; | ||
| 442 | - } else { | ||
| 443 | - buttonRightPadding = widget.padding.right - 12; | ||
| 444 | - } | ||
| 445 | - | ||
| 446 | - if (widget.padding.left > 16.0) { | ||
| 447 | - iconPadding = widget.padding.left; | ||
| 448 | - } | ||
| 449 | - | ||
| 450 | - if (widget.icon == null && widget.mainButton == null) { | ||
| 451 | - return [ | ||
| 452 | - _buildLeftBarIndicator(), | ||
| 453 | - Expanded( | ||
| 454 | - flex: 1, | ||
| 455 | - child: Column( | ||
| 456 | - crossAxisAlignment: CrossAxisAlignment.stretch, | ||
| 457 | - mainAxisSize: MainAxisSize.min, | ||
| 458 | - children: <Widget>[ | ||
| 459 | - (_isTitlePresent) | ||
| 460 | - ? Padding( | ||
| 461 | - padding: EdgeInsets.only( | ||
| 462 | - top: widget.padding.top, | ||
| 463 | - left: widget.padding.left, | ||
| 464 | - right: widget.padding.right, | ||
| 465 | - ), | ||
| 466 | - child: _getTitleText(), | ||
| 467 | - ) | ||
| 468 | - : _emptyWidget, | ||
| 469 | - Padding( | ||
| 470 | - padding: EdgeInsets.only( | ||
| 471 | - top: _messageTopMargin, | ||
| 472 | - left: widget.padding.left, | ||
| 473 | - right: widget.padding.right, | ||
| 474 | - bottom: widget.padding.bottom, | ||
| 475 | - ), | ||
| 476 | - child: widget.messageText ?? _getDefaultNotificationText(), | ||
| 477 | - ), | ||
| 478 | - ], | ||
| 479 | - ), | ||
| 480 | - ), | ||
| 481 | - ]; | ||
| 482 | - } else if (widget.icon != null && widget.mainButton == null) { | ||
| 483 | - return <Widget>[ | 505 | + children: [ | 
| 484 | _buildLeftBarIndicator(), | 506 | _buildLeftBarIndicator(), | 
| 507 | + if (_rowStyle == RowStyle.icon) | ||
| 485 | ConstrainedBox( | 508 | ConstrainedBox( | 
| 486 | - constraints: BoxConstraints.tightFor(width: 42.0 + iconPadding), | 509 | + constraints: | 
| 510 | + BoxConstraints.tightFor(width: 42.0 + iconPadding), | ||
| 487 | child: _getIcon(), | 511 | child: _getIcon(), | 
| 488 | ), | 512 | ), | 
| 489 | Expanded( | 513 | Expanded( | 
| @@ -492,112 +516,51 @@ Set either a message or messageText"""); | @@ -492,112 +516,51 @@ Set either a message or messageText"""); | ||
| 492 | crossAxisAlignment: CrossAxisAlignment.stretch, | 516 | crossAxisAlignment: CrossAxisAlignment.stretch, | 
| 493 | mainAxisSize: MainAxisSize.min, | 517 | mainAxisSize: MainAxisSize.min, | 
| 494 | children: <Widget>[ | 518 | children: <Widget>[ | 
| 495 | - (_isTitlePresent) | ||
| 496 | - ? Padding( | ||
| 497 | - padding: EdgeInsets.only( | ||
| 498 | - top: widget.padding.top, | ||
| 499 | - left: 4.0, | ||
| 500 | - right: widget.padding.left, | ||
| 501 | - ), | ||
| 502 | - child: _getTitleText(), | ||
| 503 | - ) | ||
| 504 | - : _emptyWidget, | 519 | + if (_isTitlePresent) | 
| 505 | Padding( | 520 | Padding( | 
| 506 | padding: EdgeInsets.only( | 521 | padding: EdgeInsets.only( | 
| 507 | - top: _messageTopMargin, | ||
| 508 | - left: 4.0, | ||
| 509 | - right: widget.padding.right, | ||
| 510 | - bottom: widget.padding.bottom, | ||
| 511 | - ), | ||
| 512 | - child: widget.messageText ?? _getDefaultNotificationText(), | ||
| 513 | - ), | ||
| 514 | - ], | 522 | + top: widget.padding.top, | 
| 523 | + left: left, | ||
| 524 | + right: right, | ||
| 515 | ), | 525 | ), | 
| 526 | + child: widget.titleText ?? | ||
| 527 | + Text( | ||
| 528 | + widget.title ?? "", | ||
| 529 | + style: TextStyle( | ||
| 530 | + fontSize: 16.0, | ||
| 531 | + color: Colors.white, | ||
| 532 | + fontWeight: FontWeight.bold, | ||
| 516 | ), | 533 | ), | 
| 517 | - ]; | ||
| 518 | - } else if (widget.icon == null && widget.mainButton != null) { | ||
| 519 | - return <Widget>[ | ||
| 520 | - _buildLeftBarIndicator(), | ||
| 521 | - Expanded( | ||
| 522 | - flex: 1, | ||
| 523 | - child: Column( | ||
| 524 | - crossAxisAlignment: CrossAxisAlignment.stretch, | ||
| 525 | - mainAxisSize: MainAxisSize.min, | ||
| 526 | - children: <Widget>[ | ||
| 527 | - (_isTitlePresent) | ||
| 528 | - ? Padding( | ||
| 529 | - padding: EdgeInsets.only( | ||
| 530 | - top: widget.padding.top, | ||
| 531 | - left: widget.padding.left, | ||
| 532 | - right: widget.padding.right, | ||
| 533 | ), | 534 | ), | 
| 534 | - child: _getTitleText(), | ||
| 535 | ) | 535 | ) | 
| 536 | - : _emptyWidget, | 536 | + else | 
| 537 | + _emptyWidget, | ||
| 537 | Padding( | 538 | Padding( | 
| 538 | padding: EdgeInsets.only( | 539 | padding: EdgeInsets.only( | 
| 539 | top: _messageTopMargin, | 540 | top: _messageTopMargin, | 
| 540 | - left: widget.padding.left, | ||
| 541 | - right: 8.0, | 541 | + left: left, | 
| 542 | + right: right, | ||
| 542 | bottom: widget.padding.bottom, | 543 | bottom: widget.padding.bottom, | 
| 543 | ), | 544 | ), | 
| 544 | - child: widget.messageText ?? _getDefaultNotificationText(), | ||
| 545 | - ), | ||
| 546 | - ], | ||
| 547 | - ), | 545 | + child: widget.messageText ?? | 
| 546 | + Text( | ||
| 547 | + widget.message ?? "", | ||
| 548 | + style: | ||
| 549 | + TextStyle(fontSize: 14.0, color: Colors.white), | ||
| 548 | ), | 550 | ), | 
| 549 | - Padding( | ||
| 550 | - padding: EdgeInsets.only(right: buttonRightPadding), | ||
| 551 | - child: _getMainActionButton(), | ||
| 552 | ), | 551 | ), | 
| 553 | - ]; | ||
| 554 | - } else { | ||
| 555 | - return <Widget>[ | ||
| 556 | - _buildLeftBarIndicator(), | ||
| 557 | - ConstrainedBox( | ||
| 558 | - constraints: BoxConstraints.tightFor(width: 42.0 + iconPadding), | ||
| 559 | - child: _getIcon(), | 552 | + ], | 
| 560 | ), | 553 | ), | 
| 561 | - Expanded( | ||
| 562 | - flex: 1, | ||
| 563 | - child: Column( | ||
| 564 | - crossAxisAlignment: CrossAxisAlignment.stretch, | ||
| 565 | - mainAxisSize: MainAxisSize.min, | ||
| 566 | - children: <Widget>[ | ||
| 567 | - (_isTitlePresent) | ||
| 568 | - ? Padding( | ||
| 569 | - padding: EdgeInsets.only( | ||
| 570 | - top: widget.padding.top, | ||
| 571 | - left: 4.0, | ||
| 572 | - right: 8.0, | ||
| 573 | ), | 554 | ), | 
| 574 | - child: _getTitleText(), | ||
| 575 | - ) | ||
| 576 | - : _emptyWidget, | 555 | + if (_rowStyle == RowStyle.action) | 
| 577 | Padding( | 556 | Padding( | 
| 578 | - padding: EdgeInsets.only( | ||
| 579 | - top: _messageTopMargin, | ||
| 580 | - left: 4.0, | ||
| 581 | - right: 8.0, | ||
| 582 | - bottom: widget.padding.bottom, | ||
| 583 | - ), | ||
| 584 | - child: widget.messageText ?? _getDefaultNotificationText(), | 557 | + padding: EdgeInsets.only(right: buttonPadding), | 
| 558 | + child: widget.mainButton, | ||
| 585 | ), | 559 | ), | 
| 586 | ], | 560 | ], | 
| 587 | ), | 561 | ), | 
| 562 | + ], | ||
| 588 | ), | 563 | ), | 
| 589 | - Padding( | ||
| 590 | - padding: EdgeInsets.only(right: buttonRightPadding), | ||
| 591 | - child: _getMainActionButton(), | ||
| 592 | - ), | ||
| 593 | - ]; | ||
| 594 | - } | ||
| 595 | - } | ||
| 596 | - | ||
| 597 | - Text _getDefaultNotificationText() { | ||
| 598 | - return Text( | ||
| 599 | - widget.message ?? "", | ||
| 600 | - style: TextStyle(fontSize: 14.0, color: Colors.white), | ||
| 601 | ); | 564 | ); | 
| 602 | } | 565 | } | 
| 603 | 566 | ||
| @@ -614,59 +577,5 @@ Set either a message or messageText"""); | @@ -614,59 +577,5 @@ Set either a message or messageText"""); | ||
| 614 | } | 577 | } | 
| 615 | } | 578 | } | 
| 616 | 579 | ||
| 617 | - Widget? _getMainActionButton() { | ||
| 618 | - return widget.mainButton; | ||
| 619 | - } | ||
| 620 | - | ||
| 621 | - Widget _getSnack() { | ||
| 622 | - Widget snack; | ||
| 623 | - | ||
| 624 | - if (widget.userInputForm != null) { | ||
| 625 | - snack = _generateInputSnack(); | ||
| 626 | - } else { | ||
| 627 | - snack = _generateSnack(); | ||
| 628 | - } | ||
| 629 | - | ||
| 630 | - return Stack( | ||
| 631 | - children: [ | ||
| 632 | - FutureBuilder<Size>( | ||
| 633 | - future: _boxHeightCompleter.future, | ||
| 634 | - builder: (context, snapshot) { | ||
| 635 | - if (snapshot.hasData) { | ||
| 636 | - if (widget.barBlur == 0) { | ||
| 637 | - return _emptyWidget; | ||
| 638 | - } | ||
| 639 | - return ClipRRect( | ||
| 640 | - borderRadius: BorderRadius.circular(widget.borderRadius), | ||
| 641 | - child: BackdropFilter( | ||
| 642 | - filter: ImageFilter.blur( | ||
| 643 | - sigmaX: widget.barBlur!, sigmaY: widget.barBlur!), | ||
| 644 | - child: Container( | ||
| 645 | - height: snapshot.data!.height, | ||
| 646 | - width: snapshot.data!.width, | ||
| 647 | - decoration: BoxDecoration( | ||
| 648 | - color: Colors.transparent, | ||
| 649 | - borderRadius: BorderRadius.circular(widget.borderRadius), | ||
| 650 | - ), | ||
| 651 | - ), | ||
| 652 | - ), | ||
| 653 | - ); | ||
| 654 | - } else { | ||
| 655 | - return _emptyWidget; | ||
| 656 | - } | ||
| 657 | - }, | ||
| 658 | - ), | ||
| 659 | - snack, | ||
| 660 | - ], | ||
| 661 | - ); | ||
| 662 | - } | ||
| 663 | - | ||
| 664 | - Widget _getTitleText() { | ||
| 665 | - return widget.titleText ?? | ||
| 666 | - Text( | ||
| 667 | - widget.title ?? "", | ||
| 668 | - style: TextStyle( | ||
| 669 | - fontSize: 16.0, color: Colors.white, fontWeight: FontWeight.bold), | ||
| 670 | - ); | ||
| 671 | - } | 580 | + void _updateProgress() => setState(() {}); | 
| 672 | } | 581 | } | 
| @@ -7,7 +7,7 @@ import '../../../get.dart'; | @@ -7,7 +7,7 @@ import '../../../get.dart'; | ||
| 7 | 7 | ||
| 8 | class SnackbarController { | 8 | class SnackbarController { | 
| 9 | static final _snackBarQueue = _SnackBarQueue(); | 9 | static final _snackBarQueue = _SnackBarQueue(); | 
| 10 | - static bool get isSnackbarBeingShown => _snackBarQueue.isJobInProgress; | 10 | + static bool get isSnackbarBeingShown => _snackBarQueue._isJobInProgress; | 
| 11 | 11 | ||
| 12 | late Animation<double> _filterBlurAnimation; | 12 | late Animation<double> _filterBlurAnimation; | 
| 13 | late Animation<Color?> _filterColorAnimation; | 13 | late Animation<Color?> _filterColorAnimation; | 
| @@ -54,7 +54,7 @@ class SnackbarController { | @@ -54,7 +54,7 @@ class SnackbarController { | ||
| 54 | /// Only one GetSnackbar will be displayed at a time, and this method returns | 54 | /// Only one GetSnackbar will be displayed at a time, and this method returns | 
| 55 | /// a future to when the snackbar disappears. | 55 | /// a future to when the snackbar disappears. | 
| 56 | Future<void> show() { | 56 | Future<void> show() { | 
| 57 | - return _snackBarQueue.addJob(this); | 57 | + return _snackBarQueue._addJob(this); | 
| 58 | } | 58 | } | 
| 59 | 59 | ||
| 60 | void _cancelTimer() { | 60 | void _cancelTimer() { | 
| @@ -319,7 +319,8 @@ class SnackbarController { | @@ -319,7 +319,8 @@ class SnackbarController { | ||
| 319 | element.remove(); | 319 | element.remove(); | 
| 320 | } | 320 | } | 
| 321 | 321 | ||
| 322 | - assert(!_transitionCompleter.isCompleted, 'Cannot remove overlay twice.'); | 322 | + assert(!_transitionCompleter.isCompleted, | 
| 323 | + 'Cannot remove overlay from a disposed snackbar'); | ||
| 323 | _controller.dispose(); | 324 | _controller.dispose(); | 
| 324 | _overlayEntries.clear(); | 325 | _overlayEntries.clear(); | 
| 325 | _transitionCompleter.complete(this); | 326 | _transitionCompleter.complete(this); | 
| @@ -331,38 +332,39 @@ class SnackbarController { | @@ -331,38 +332,39 @@ class SnackbarController { | ||
| 331 | } | 332 | } | 
| 332 | 333 | ||
| 333 | static void cancelAllSnackbars() { | 334 | static void cancelAllSnackbars() { | 
| 334 | - _snackBarQueue.cancelAllJobs(); | 335 | + _snackBarQueue._cancelAllJobs(); | 
| 335 | } | 336 | } | 
| 336 | 337 | ||
| 337 | static Future<void> closeCurrentSnackbar() async { | 338 | static Future<void> closeCurrentSnackbar() async { | 
| 338 | - await _snackBarQueue.closeCurrentJob(); | 339 | + await _snackBarQueue._closeCurrentJob(); | 
| 339 | } | 340 | } | 
| 340 | } | 341 | } | 
| 341 | 342 | ||
| 342 | class _SnackBarQueue { | 343 | class _SnackBarQueue { | 
| 343 | final _queue = GetQueue(); | 344 | final _queue = GetQueue(); | 
| 345 | + final _snackbarList = <SnackbarController>[]; | ||
| 344 | 346 | ||
| 345 | - bool _isJobInProgress = false; | ||
| 346 | - | ||
| 347 | - SnackbarController? _currentSnackbar; | 347 | + SnackbarController? get _currentSnackbar { | 
| 348 | + if (_snackbarList.isEmpty) return null; | ||
| 349 | + return _snackbarList.first; | ||
| 350 | + } | ||
| 348 | 351 | ||
| 349 | - bool get isJobInProgress => _isJobInProgress; | 352 | + bool get _isJobInProgress => _snackbarList.isNotEmpty; | 
| 350 | 353 | ||
| 351 | - Future<void> addJob(SnackbarController job) async { | ||
| 352 | - _isJobInProgress = true; | ||
| 353 | - _currentSnackbar = job; | 354 | + Future<void> _addJob(SnackbarController job) async { | 
| 355 | + _snackbarList.add(job); | ||
| 354 | final data = await _queue.add(job._show); | 356 | final data = await _queue.add(job._show); | 
| 355 | - _isJobInProgress = false; | ||
| 356 | - _currentSnackbar = null; | 357 | + _snackbarList.remove(job); | 
| 357 | return data; | 358 | return data; | 
| 358 | } | 359 | } | 
| 359 | 360 | ||
| 360 | - void cancelAllJobs() { | ||
| 361 | - _currentSnackbar?.close(); | 361 | + Future<void> _cancelAllJobs() async { | 
| 362 | + await _currentSnackbar?.close(); | ||
| 362 | _queue.cancelAllJobs(); | 363 | _queue.cancelAllJobs(); | 
| 364 | + _snackbarList.clear(); | ||
| 363 | } | 365 | } | 
| 364 | 366 | ||
| 365 | - Future<void> closeCurrentJob() async { | 367 | + Future<void> _closeCurrentJob() async { | 
| 366 | await _currentSnackbar?.close(); | 368 | await _currentSnackbar?.close(); | 
| 367 | } | 369 | } | 
| 368 | } | 370 | } | 
- 
Please register or login to post a comment