added Get.closeAllSnackbars, Get.closeCurrentSnackbar, fix tests
Showing
4 changed files
with
177 additions
and
122 deletions
| @@ -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 { |
-
Please register or login to post a comment