Jonny Borges

added Get.closeAllSnackbars, Get.closeCurrentSnackbar, fix tests

@@ -2,51 +2,28 @@ import 'package:flutter/foundation.dart'; @@ -2,51 +2,28 @@ import 'package:flutter/foundation.dart';
2 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
3 import 'package:get/get.dart'; 3 import 'package:get/get.dart';
4 4
  5 +import 'lang/translation_service.dart';
  6 +import 'routes/app_pages.dart';
  7 +import 'shared/logger/logger_utils.dart';
  8 +
5 void main() { 9 void main() {
6 runApp(MyApp()); 10 runApp(MyApp());
7 } 11 }
8 12
9 -// class MyApp extends StatelessWidget {  
10 -// const MyApp({Key? key}) : super(key: key);  
11 -  
12 -// @override  
13 -// Widget build(BuildContext context) {  
14 -// return GetMaterialApp.router(  
15 -// debugShowCheckedModeBanner: false,  
16 -// enableLog: true,  
17 -// logWriterCallback: Logger.write,  
18 -// // initialRoute: AppPages.INITIAL,  
19 -// getPages: AppPages.routes,  
20 -// locale: TranslationService.locale,  
21 -// fallbackLocale: TranslationService.fallbackLocale,  
22 -// translations: TranslationService(),  
23 -// );  
24 -// }  
25 -// } 13 +class MyApp extends StatelessWidget {
  14 + const MyApp({Key? key}) : super(key: key);
26 15
27 -class First extends StatelessWidget {  
28 @override 16 @override
29 Widget build(BuildContext context) { 17 Widget build(BuildContext context) {
30 - return Scaffold(  
31 - appBar: AppBar(  
32 - title: Text('page one'),  
33 - leading: IconButton(  
34 - icon: Icon(Icons.more),  
35 - onPressed: () async {  
36 - var controller = Get.snackbar('dsdsds', 'sdsdsdsds');  
37 - },  
38 - ),  
39 - ),  
40 - body: Center(  
41 - child: Container(  
42 - height: 300,  
43 - width: 300,  
44 - child: ElevatedButton(  
45 - onPressed: () {},  
46 - child: Text('next screen'),  
47 - ),  
48 - ),  
49 - ), 18 + return GetMaterialApp.router(
  19 + debugShowCheckedModeBanner: false,
  20 + enableLog: true,
  21 + logWriterCallback: Logger.write,
  22 + // initialRoute: AppPages.INITIAL,
  23 + getPages: AppPages.routes,
  24 + locale: TranslationService.locale,
  25 + fallbackLocale: TranslationService.fallbackLocale,
  26 + translations: TranslationService(),
50 ); 27 );
51 } 28 }
52 } 29 }
@@ -56,68 +33,98 @@ class First extends StatelessWidget { @@ -56,68 +33,98 @@ class First extends StatelessWidget {
56 // runApp(MyApp()); 33 // runApp(MyApp());
57 // } 34 // }
58 35
59 -class MyApp extends StatelessWidget {  
60 - MyApp({Key? key}) : super(key: key); 36 +// class MyApp extends StatelessWidget {
  37 +// MyApp({Key? key}) : super(key: key);
61 38
62 - @override  
63 - Widget build(BuildContext context) {  
64 - return GetMaterialApp.router(  
65 - getPages: [  
66 - GetPage(  
67 - participatesInRootNavigator: true, name: '/', page: () => First()),  
68 - GetPage(  
69 - name: '/second',  
70 - page: () => Second(),  
71 - ),  
72 - GetPage(  
73 - name: '/third',  
74 - page: () => Third(),  
75 - ),  
76 - ],  
77 - debugShowCheckedModeBanner: false,  
78 - );  
79 - }  
80 -} 39 +// @override
  40 +// Widget build(BuildContext context) {
  41 +// return GetMaterialApp.router(
  42 +// getPages: [
  43 +// GetPage(
  44 +// participatesInRootNavigator: true,
  45 +// name: '/first',
  46 +// page: () => First()),
  47 +// GetPage(
  48 +// name: '/second',
  49 +// page: () => Second(),
  50 +// ),
  51 +// GetPage(
  52 +// name: '/third',
  53 +// page: () => Third(),
  54 +// ),
  55 +// ],
  56 +// debugShowCheckedModeBanner: false,
  57 +// );
  58 +// }
  59 +// }
81 60
82 -class Second extends StatelessWidget {  
83 - @override  
84 - Widget build(BuildContext context) {  
85 - return Scaffold(  
86 - appBar: AppBar(  
87 - title: Text('page two ${Get.parameters["id"]}'),  
88 - ),  
89 - body: Center(  
90 - child: Container(  
91 - height: 300,  
92 - width: 300,  
93 - child: ElevatedButton(  
94 - onPressed: () {},  
95 - child: Text('next screen'),  
96 - ),  
97 - ),  
98 - ),  
99 - );  
100 - }  
101 -} 61 +// class First extends StatelessWidget {
  62 +// @override
  63 +// Widget build(BuildContext context) {
  64 +// return Scaffold(
  65 +// appBar: AppBar(
  66 +// title: Text('page one'),
  67 +// leading: IconButton(
  68 +// icon: Icon(Icons.more),
  69 +// onPressed: () {
  70 +// Get.changeTheme(
  71 +// context.isDarkMode ? ThemeData.light() : ThemeData.dark());
  72 +// },
  73 +// ),
  74 +// ),
  75 +// body: Center(
  76 +// child: Container(
  77 +// height: 300,
  78 +// width: 300,
  79 +// child: ElevatedButton(
  80 +// onPressed: () {},
  81 +// child: Text('next screen'),
  82 +// ),
  83 +// ),
  84 +// ),
  85 +// );
  86 +// }
  87 +// }
102 88
103 -class Third extends StatelessWidget {  
104 - @override  
105 - Widget build(BuildContext context) {  
106 - return Scaffold(  
107 - backgroundColor: Colors.red,  
108 - appBar: AppBar(  
109 - title: Text('page three'),  
110 - ),  
111 - body: Center(  
112 - child: Container(  
113 - height: 300,  
114 - width: 300,  
115 - child: ElevatedButton(  
116 - onPressed: () {},  
117 - child: Text('go to first screen'),  
118 - ),  
119 - ),  
120 - ),  
121 - );  
122 - }  
123 -} 89 +// class Second extends StatelessWidget {
  90 +// @override
  91 +// Widget build(BuildContext context) {
  92 +// return Scaffold(
  93 +// appBar: AppBar(
  94 +// title: Text('page two ${Get.parameters["id"]}'),
  95 +// ),
  96 +// body: Center(
  97 +// child: Container(
  98 +// height: 300,
  99 +// width: 300,
  100 +// child: ElevatedButton(
  101 +// onPressed: () {},
  102 +// child: Text('next screen'),
  103 +// ),
  104 +// ),
  105 +// ),
  106 +// );
  107 +// }
  108 +// }
  109 +
  110 +// class Third extends StatelessWidget {
  111 +// @override
  112 +// Widget build(BuildContext context) {
  113 +// return Scaffold(
  114 +// backgroundColor: Colors.red,
  115 +// appBar: AppBar(
  116 +// title: Text('page three'),
  117 +// ),
  118 +// body: Center(
  119 +// child: Container(
  120 +// height: 300,
  121 +// width: 300,
  122 +// child: ElevatedButton(
  123 +// onPressed: () {},
  124 +// child: Text('go to first screen'),
  125 +// ),
  126 +// ),
  127 +// ),
  128 +// );
  129 +// }
  130 +// }
@@ -792,11 +792,11 @@ you can only use widgets and widget functions here'''; @@ -792,11 +792,11 @@ you can only use widgets and widget functions here''';
792 792
793 /// Returns true if a Snackbar, Dialog or BottomSheet is currently OPEN 793 /// Returns true if a Snackbar, Dialog or BottomSheet is currently OPEN
794 bool get isOverlaysOpen => 794 bool get isOverlaysOpen =>
795 - (isSnackbarOpen! || isDialogOpen! || isBottomSheetOpen!); 795 + (isSnackbarOpen || isDialogOpen! || isBottomSheetOpen!);
796 796
797 /// Returns true if there is no Snackbar, Dialog or BottomSheet open 797 /// Returns true if there is no Snackbar, Dialog or BottomSheet open
798 bool get isOverlaysClosed => 798 bool get isOverlaysClosed =>
799 - (!isSnackbarOpen! && !isDialogOpen! && !isBottomSheetOpen!); 799 + (!isSnackbarOpen && !isDialogOpen! && !isBottomSheetOpen!);
800 800
801 /// **Navigation.popUntil()** shortcut.<br><br> 801 /// **Navigation.popUntil()** shortcut.<br><br>
802 /// 802 ///
@@ -817,8 +817,11 @@ you can only use widgets and widget functions here'''; @@ -817,8 +817,11 @@ you can only use widgets and widget functions here''';
817 int? id, 817 int? id,
818 }) { 818 }) {
819 if (closeOverlays && isOverlaysOpen) { 819 if (closeOverlays && isOverlaysOpen) {
  820 + if (isSnackbarOpen) {
  821 + closeAllSnackbars();
  822 + }
820 navigator?.popUntil((route) { 823 navigator?.popUntil((route) {
821 - return (isOverlaysClosed); 824 + return (!isDialogOpen! && !isBottomSheetOpen!);
822 }); 825 });
823 } 826 }
824 if (canPop) { 827 if (canPop) {
@@ -1100,9 +1103,17 @@ you can only use widgets and widget functions here'''; @@ -1100,9 +1103,17 @@ you can only use widgets and widget functions here''';
1100 /// give name from previous route 1103 /// give name from previous route
1101 String get previousRoute => routing.previous; 1104 String get previousRoute => routing.previous;
1102 1105
1103 - ///TODO: made snackbar 2.0 trackeables  
1104 /// check if snackbar is open 1106 /// check if snackbar is open
1105 - bool? get isSnackbarOpen => true; //routing.isSnackbar; 1107 + bool get isSnackbarOpen =>
  1108 + SnackbarController.isSnackbarBeingShown; //routing.isSnackbar;
  1109 +
  1110 + void closeAllSnackbars() {
  1111 + SnackbarController.cancelAllSnackbars();
  1112 + }
  1113 +
  1114 + void closeCurrentSnackbar() {
  1115 + SnackbarController.closeCurrentSnackbar();
  1116 + }
1106 1117
1107 /// check if dialog is open 1118 /// check if dialog is open
1108 bool? get isDialogOpen => routing.isDialog; 1119 bool? get isDialogOpen => routing.isDialog;
@@ -6,7 +6,9 @@ import 'package:flutter/material.dart'; @@ -6,7 +6,9 @@ import 'package:flutter/material.dart';
6 import '../../../get.dart'; 6 import '../../../get.dart';
7 7
8 class SnackbarController { 8 class SnackbarController {
9 - static final _queue = GetQueue(); 9 + static final _snackBarQueue = _SnackBarQueue();
  10 + static bool get isSnackbarBeingShown => _snackBarQueue.isJobInProgress;
  11 +
10 late Animation<double> _filterBlurAnimation; 12 late Animation<double> _filterBlurAnimation;
11 late Animation<Color?> _filterColorAnimation; 13 late Animation<Color?> _filterColorAnimation;
12 14
@@ -15,9 +17,10 @@ class SnackbarController { @@ -15,9 +17,10 @@ class SnackbarController {
15 17
16 late SnackbarStatusCallback? _snackbarStatus; 18 late SnackbarStatusCallback? _snackbarStatus;
17 late final Alignment? _initialAlignment; 19 late final Alignment? _initialAlignment;
18 -  
19 late final Alignment? _endAlignment; 20 late final Alignment? _endAlignment;
  21 +
20 bool _wasDismissedBySwipe = false; 22 bool _wasDismissedBySwipe = false;
  23 +
21 bool _onTappedDismiss = false; 24 bool _onTappedDismiss = false;
22 25
23 Timer? _timer; 26 Timer? _timer;
@@ -41,24 +44,22 @@ class SnackbarController { @@ -41,24 +44,22 @@ class SnackbarController {
41 44
42 Future<SnackbarController> get future => _transitionCompleter.future; 45 Future<SnackbarController> get future => _transitionCompleter.future;
43 46
44 - bool get isSnackbarBeingShown => _currentStatus != SnackbarStatus.CLOSED;  
45 -  
46 Future<void> close() async { 47 Future<void> close() async {
47 _removeEntry(); 48 _removeEntry();
48 await future; 49 await future;
49 } 50 }
50 51
51 Future<void> show() { 52 Future<void> show() {
52 - return _queue.add(_show); 53 + return _snackBarQueue.addJob(this);
53 } 54 }
54 55
55 - // ignore: avoid_returning_this  
56 void _cancelTimer() { 56 void _cancelTimer() {
57 if (_timer != null && _timer!.isActive) { 57 if (_timer != null && _timer!.isActive) {
58 _timer!.cancel(); 58 _timer!.cancel();
59 } 59 }
60 } 60 }
61 61
  62 + // ignore: avoid_returning_this
62 void _configureAlignment(SnackPosition snackPosition) { 63 void _configureAlignment(SnackPosition snackPosition) {
63 switch (snack.snackPosition) { 64 switch (snack.snackPosition) {
64 case SnackPosition.TOP: 65 case SnackPosition.TOP:
@@ -289,8 +290,6 @@ class SnackbarController { @@ -289,8 +290,6 @@ class SnackbarController {
289 _removeEntry(); 290 _removeEntry();
290 } 291 }
291 292
292 - void _registerSnackbar() {}  
293 -  
294 void _removeEntry() { 293 void _removeEntry() {
295 assert( 294 assert(
296 !_transitionCompleter.isCompleted, 295 !_transitionCompleter.isCompleted,
@@ -324,5 +323,39 @@ class SnackbarController { @@ -324,5 +323,39 @@ class SnackbarController {
324 return future; 323 return future;
325 } 324 }
326 325
327 - void _unRegisterSnackbar() {} 326 + static void cancelAllSnackbars() {
  327 + _snackBarQueue.cancelAllJobs();
  328 + }
  329 +
  330 + static void closeCurrentSnackbar() {
  331 + _snackBarQueue.closeCurrentJob();
  332 + }
  333 +}
  334 +
  335 +class _SnackBarQueue {
  336 + final _queue = GetQueue();
  337 +
  338 + bool _isJobInProgress = false;
  339 +
  340 + SnackbarController? _currentSnackbar;
  341 +
  342 + bool get isJobInProgress => _isJobInProgress;
  343 +
  344 + Future<void> addJob(SnackbarController job) async {
  345 + _isJobInProgress = true;
  346 + _currentSnackbar = job;
  347 + final data = await _queue.add(job._show);
  348 + _isJobInProgress = false;
  349 + _currentSnackbar = null;
  350 + return data;
  351 + }
  352 +
  353 + void cancelAllJobs() {
  354 + _currentSnackbar?.close();
  355 + _queue.cancelAllJobs();
  356 + }
  357 +
  358 + void closeCurrentJob() {
  359 + _currentSnackbar?.close();
  360 + }
328 } 361 }
@@ -4,8 +4,8 @@ class GetMicrotask { @@ -4,8 +4,8 @@ class GetMicrotask {
4 int _version = 0; 4 int _version = 0;
5 int _microtask = 0; 5 int _microtask = 0;
6 6
7 - int get version => _version;  
8 int get microtask => _microtask; 7 int get microtask => _microtask;
  8 + int get version => _version;
9 9
10 void exec(Function callback) { 10 void exec(Function callback) {
11 if (_microtask == _version) { 11 if (_microtask == _version) {
@@ -23,6 +23,17 @@ class GetQueue { @@ -23,6 +23,17 @@ class GetQueue {
23 final List<_Item> _queue = []; 23 final List<_Item> _queue = [];
24 bool _active = false; 24 bool _active = false;
25 25
  26 + Future<T> add<T>(Function job) {
  27 + var completer = Completer<T>();
  28 + _queue.add(_Item(completer, job));
  29 + _check();
  30 + return completer.future;
  31 + }
  32 +
  33 + void cancelAllJobs() {
  34 + _queue.clear();
  35 + }
  36 +
26 void _check() async { 37 void _check() async {
27 if (!_active && _queue.isNotEmpty) { 38 if (!_active && _queue.isNotEmpty) {
28 _active = true; 39 _active = true;
@@ -36,13 +47,6 @@ class GetQueue { @@ -36,13 +47,6 @@ class GetQueue {
36 _check(); 47 _check();
37 } 48 }
38 } 49 }
39 -  
40 - Future<T> add<T>(Function job) {  
41 - var completer = Completer<T>();  
42 - _queue.add(_Item(completer, job));  
43 - _check();  
44 - return completer.future;  
45 - }  
46 } 50 }
47 51
48 class _Item { 52 class _Item {