Showing
11 changed files
with
187 additions
and
155 deletions
@@ -3,7 +3,6 @@ import 'package:get/get.dart'; | @@ -3,7 +3,6 @@ import 'package:get/get.dart'; | ||
3 | 3 | ||
4 | import '../controllers/dashboard_controller.dart'; | 4 | import '../controllers/dashboard_controller.dart'; |
5 | 5 | ||
6 | - | ||
7 | class DashboardView extends GetView<DashboardController> { | 6 | class DashboardView extends GetView<DashboardController> { |
8 | @override | 7 | @override |
9 | Widget build(BuildContext context) { | 8 | Widget build(BuildContext context) { |
@@ -138,7 +138,11 @@ class HeaderValue { | @@ -138,7 +138,11 @@ class HeaderValue { | ||
138 | stringBuffer.write(_value); | 138 | stringBuffer.write(_value); |
139 | if (parameters != null && parameters!.isNotEmpty) { | 139 | if (parameters != null && parameters!.isNotEmpty) { |
140 | _parameters!.forEach((name, value) { | 140 | _parameters!.forEach((name, value) { |
141 | - stringBuffer..write('; ')..write(name)..write('=')..write(value); | 141 | + stringBuffer |
142 | + ..write('; ') | ||
143 | + ..write(name) | ||
144 | + ..write('=') | ||
145 | + ..write(value); | ||
142 | }); | 146 | }); |
143 | } | 147 | } |
144 | return stringBuffer.toString(); | 148 | return stringBuffer.toString(); |
1 | import 'dart:convert'; | 1 | import 'dart:convert'; |
2 | 2 | ||
3 | +/// Signature for [SocketNotifier.addCloses]. | ||
4 | +typedef CloseSocket = void Function(Close); | ||
5 | + | ||
6 | +/// Signature for [SocketNotifier.addMessages]. | ||
7 | +typedef MessageSocket = void Function(dynamic val); | ||
8 | + | ||
9 | +/// Signature for [SocketNotifier.open]. | ||
10 | +typedef OpenSocket = void Function(); | ||
11 | + | ||
12 | +/// Wrapper class to message and reason from SocketNotifier | ||
3 | class Close { | 13 | class Close { |
4 | final String? message; | 14 | final String? message; |
5 | final int? reason; | 15 | final int? reason; |
@@ -12,12 +22,8 @@ class Close { | @@ -12,12 +22,8 @@ class Close { | ||
12 | } | 22 | } |
13 | } | 23 | } |
14 | 24 | ||
15 | -typedef OpenSocket = void Function(); | ||
16 | - | ||
17 | -typedef CloseSocket = void Function(Close); | ||
18 | - | ||
19 | -typedef MessageSocket = void Function(dynamic val); | ||
20 | - | 25 | +/// This class manages the transmission of messages over websockets using |
26 | +/// GetConnect | ||
21 | class SocketNotifier { | 27 | class SocketNotifier { |
22 | List<void Function(dynamic)>? _onMessages = <MessageSocket>[]; | 28 | List<void Function(dynamic)>? _onMessages = <MessageSocket>[]; |
23 | Map<String, void Function(dynamic)>? _onEvents = <String, MessageSocket>{}; | 29 | Map<String, void Function(dynamic)>? _onEvents = <String, MessageSocket>{}; |
@@ -26,22 +32,42 @@ class SocketNotifier { | @@ -26,22 +32,42 @@ class SocketNotifier { | ||
26 | 32 | ||
27 | late OpenSocket open; | 33 | late OpenSocket open; |
28 | 34 | ||
29 | - void addMessages(MessageSocket socket) { | ||
30 | - _onMessages!.add((socket)); | 35 | + /// subscribe to close events |
36 | + void addCloses(CloseSocket socket) { | ||
37 | + _onCloses!.add(socket); | ||
38 | + } | ||
39 | + | ||
40 | + /// subscribe to error events | ||
41 | + void addErrors(CloseSocket socket) { | ||
42 | + _onErrors!.add((socket)); | ||
31 | } | 43 | } |
32 | 44 | ||
45 | + /// subscribe to named events | ||
33 | void addEvents(String event, MessageSocket socket) { | 46 | void addEvents(String event, MessageSocket socket) { |
34 | _onEvents![event] = socket; | 47 | _onEvents![event] = socket; |
35 | } | 48 | } |
36 | 49 | ||
37 | - void addCloses(CloseSocket socket) { | ||
38 | - _onCloses!.add(socket); | 50 | + /// subscribe to message events |
51 | + void addMessages(MessageSocket socket) { | ||
52 | + _onMessages!.add((socket)); | ||
39 | } | 53 | } |
40 | 54 | ||
41 | - void addErrors(CloseSocket socket) { | ||
42 | - _onErrors!.add((socket)); | 55 | + /// Dispose messages, events, closes and errors subscriptions |
56 | + void dispose() { | ||
57 | + _onMessages = null; | ||
58 | + _onEvents = null; | ||
59 | + _onCloses = null; | ||
60 | + _onErrors = null; | ||
43 | } | 61 | } |
44 | 62 | ||
63 | + /// Notify all subscriptions on [addCloses] | ||
64 | + void notifyClose(Close err) { | ||
65 | + for (var item in _onCloses!) { | ||
66 | + item(err); | ||
67 | + } | ||
68 | + } | ||
69 | + | ||
70 | + /// Notify all subscriptions on [addMessages] | ||
45 | void notifyData(dynamic data) { | 71 | void notifyData(dynamic data) { |
46 | for (var item in _onMessages!) { | 72 | for (var item in _onMessages!) { |
47 | item(data); | 73 | item(data); |
@@ -51,12 +77,7 @@ class SocketNotifier { | @@ -51,12 +77,7 @@ class SocketNotifier { | ||
51 | } | 77 | } |
52 | } | 78 | } |
53 | 79 | ||
54 | - void notifyClose(Close err) { | ||
55 | - for (var item in _onCloses!) { | ||
56 | - item(err); | ||
57 | - } | ||
58 | - } | ||
59 | - | 80 | + /// Notify all subscriptions on [addErrors] |
60 | void notifyError(Close err) { | 81 | void notifyError(Close err) { |
61 | // rooms.removeWhere((key, value) => value.contains(_ws)); | 82 | // rooms.removeWhere((key, value) => value.contains(_ws)); |
62 | for (var item in _onErrors!) { | 83 | for (var item in _onErrors!) { |
@@ -72,15 +93,9 @@ class SocketNotifier { | @@ -72,15 +93,9 @@ class SocketNotifier { | ||
72 | if (_onEvents!.containsKey(event)) { | 93 | if (_onEvents!.containsKey(event)) { |
73 | _onEvents![event]!(data); | 94 | _onEvents![event]!(data); |
74 | } | 95 | } |
96 | + // ignore: avoid_catches_without_on_clauses | ||
75 | } catch (_) { | 97 | } catch (_) { |
76 | return; | 98 | return; |
77 | } | 99 | } |
78 | } | 100 | } |
79 | - | ||
80 | - void dispose() { | ||
81 | - _onMessages = null; | ||
82 | - _onEvents = null; | ||
83 | - _onCloses = null; | ||
84 | - _onErrors = null; | ||
85 | - } | ||
86 | } | 101 | } |
@@ -4,15 +4,8 @@ import 'dart:convert'; | @@ -4,15 +4,8 @@ import 'dart:convert'; | ||
4 | import 'dart:html'; | 4 | import 'dart:html'; |
5 | 5 | ||
6 | import '../../../get_core/get_core.dart'; | 6 | import '../../../get_core/get_core.dart'; |
7 | - | ||
8 | import 'socket_notifier.dart'; | 7 | import 'socket_notifier.dart'; |
9 | 8 | ||
10 | -enum ConnectionStatus { | ||
11 | - connecting, | ||
12 | - connected, | ||
13 | - closed, | ||
14 | -} | ||
15 | - | ||
16 | class BaseWebSocket { | 9 | class BaseWebSocket { |
17 | String url; | 10 | String url; |
18 | WebSocket? socket; | 11 | WebSocket? socket; |
@@ -21,6 +14,8 @@ class BaseWebSocket { | @@ -21,6 +14,8 @@ class BaseWebSocket { | ||
21 | bool isDisposed = false; | 14 | bool isDisposed = false; |
22 | bool allowSelfSigned; | 15 | bool allowSelfSigned; |
23 | 16 | ||
17 | + ConnectionStatus? connectionStatus; | ||
18 | + Timer? _t; | ||
24 | BaseWebSocket( | 19 | BaseWebSocket( |
25 | this.url, { | 20 | this.url, { |
26 | this.ping = const Duration(seconds: 5), | 21 | this.ping = const Duration(seconds: 5), |
@@ -30,9 +25,12 @@ class BaseWebSocket { | @@ -30,9 +25,12 @@ class BaseWebSocket { | ||
30 | ? url.replaceAll('https:', 'wss:') | 25 | ? url.replaceAll('https:', 'wss:') |
31 | : url.replaceAll('http:', 'ws:'); | 26 | : url.replaceAll('http:', 'ws:'); |
32 | } | 27 | } |
33 | - ConnectionStatus? connectionStatus; | ||
34 | - Timer? _t; | ||
35 | 28 | ||
29 | + void close([int? status, String? reason]) { | ||
30 | + socket?.close(status, reason); | ||
31 | + } | ||
32 | + | ||
33 | + // ignore: use_setters_to_change_properties | ||
36 | void connect() { | 34 | void connect() { |
37 | try { | 35 | try { |
38 | connectionStatus = ConnectionStatus.connecting; | 36 | connectionStatus = ConnectionStatus.connecting; |
@@ -68,9 +66,18 @@ class BaseWebSocket { | @@ -68,9 +66,18 @@ class BaseWebSocket { | ||
68 | } | 66 | } |
69 | } | 67 | } |
70 | 68 | ||
71 | - // ignore: use_setters_to_change_properties | ||
72 | - void onOpen(OpenSocket fn) { | ||
73 | - socketNotifier!.open = fn; | 69 | + void dispose() { |
70 | + socketNotifier!.dispose(); | ||
71 | + socketNotifier = null; | ||
72 | + isDisposed = true; | ||
73 | + } | ||
74 | + | ||
75 | + void emit(String event, dynamic data) { | ||
76 | + send(jsonEncode({'type': event, 'data': data})); | ||
77 | + } | ||
78 | + | ||
79 | + void on(String event, MessageSocket message) { | ||
80 | + socketNotifier!.addEvents(event, message); | ||
74 | } | 81 | } |
75 | 82 | ||
76 | void onClose(CloseSocket fn) { | 83 | void onClose(CloseSocket fn) { |
@@ -85,12 +92,8 @@ class BaseWebSocket { | @@ -85,12 +92,8 @@ class BaseWebSocket { | ||
85 | socketNotifier!.addMessages(fn); | 92 | socketNotifier!.addMessages(fn); |
86 | } | 93 | } |
87 | 94 | ||
88 | - void on(String event, MessageSocket message) { | ||
89 | - socketNotifier!.addEvents(event, message); | ||
90 | - } | ||
91 | - | ||
92 | - void close([int? status, String? reason]) { | ||
93 | - socket?.close(status, reason); | 95 | + void onOpen(OpenSocket fn) { |
96 | + socketNotifier!.open = fn; | ||
94 | } | 97 | } |
95 | 98 | ||
96 | void send(dynamic data) { | 99 | void send(dynamic data) { |
@@ -103,14 +106,10 @@ class BaseWebSocket { | @@ -103,14 +106,10 @@ class BaseWebSocket { | ||
103 | Get.log('WebSocket not connected, message $data not sent'); | 106 | Get.log('WebSocket not connected, message $data not sent'); |
104 | } | 107 | } |
105 | } | 108 | } |
109 | +} | ||
106 | 110 | ||
107 | - void emit(String event, dynamic data) { | ||
108 | - send(jsonEncode({'type': event, 'data': data})); | ||
109 | - } | ||
110 | - | ||
111 | - void dispose() { | ||
112 | - socketNotifier!.dispose(); | ||
113 | - socketNotifier = null; | ||
114 | - isDisposed = true; | ||
115 | - } | 111 | +enum ConnectionStatus { |
112 | + connecting, | ||
113 | + connected, | ||
114 | + closed, | ||
116 | } | 115 | } |
@@ -4,30 +4,28 @@ import 'dart:io'; | @@ -4,30 +4,28 @@ import 'dart:io'; | ||
4 | import 'dart:math'; | 4 | import 'dart:math'; |
5 | 5 | ||
6 | import '../../../get_core/get_core.dart'; | 6 | import '../../../get_core/get_core.dart'; |
7 | - | ||
8 | import 'socket_notifier.dart'; | 7 | import 'socket_notifier.dart'; |
9 | 8 | ||
10 | -enum ConnectionStatus { | ||
11 | - connecting, | ||
12 | - connected, | ||
13 | - closed, | ||
14 | -} | ||
15 | - | ||
16 | class BaseWebSocket { | 9 | class BaseWebSocket { |
17 | String url; | 10 | String url; |
18 | WebSocket? socket; | 11 | WebSocket? socket; |
19 | SocketNotifier? socketNotifier = SocketNotifier(); | 12 | SocketNotifier? socketNotifier = SocketNotifier(); |
20 | bool isDisposed = false; | 13 | bool isDisposed = false; |
14 | + Duration ping; | ||
15 | + bool allowSelfSigned; | ||
16 | + ConnectionStatus? connectionStatus; | ||
17 | + | ||
21 | BaseWebSocket( | 18 | BaseWebSocket( |
22 | this.url, { | 19 | this.url, { |
23 | this.ping = const Duration(seconds: 5), | 20 | this.ping = const Duration(seconds: 5), |
24 | this.allowSelfSigned = true, | 21 | this.allowSelfSigned = true, |
25 | }); | 22 | }); |
26 | - Duration ping; | ||
27 | - bool allowSelfSigned; | ||
28 | 23 | ||
29 | - ConnectionStatus? connectionStatus; | 24 | + void close([int? status, String? reason]) { |
25 | + socket?.close(status, reason); | ||
26 | + } | ||
30 | 27 | ||
28 | + // ignore: use_setters_to_change_properties | ||
31 | Future connect() async { | 29 | Future connect() async { |
32 | if (isDisposed) { | 30 | if (isDisposed) { |
33 | socketNotifier = SocketNotifier(); | 31 | socketNotifier = SocketNotifier(); |
@@ -60,9 +58,18 @@ class BaseWebSocket { | @@ -60,9 +58,18 @@ class BaseWebSocket { | ||
60 | } | 58 | } |
61 | } | 59 | } |
62 | 60 | ||
63 | - // ignore: use_setters_to_change_properties | ||
64 | - void onOpen(OpenSocket fn) { | ||
65 | - socketNotifier!.open = fn; | 61 | + void dispose() { |
62 | + socketNotifier!.dispose(); | ||
63 | + socketNotifier = null; | ||
64 | + isDisposed = true; | ||
65 | + } | ||
66 | + | ||
67 | + void emit(String event, dynamic data) { | ||
68 | + send(jsonEncode({'type': event, 'data': data})); | ||
69 | + } | ||
70 | + | ||
71 | + void on(String event, MessageSocket message) { | ||
72 | + socketNotifier!.addEvents(event, message); | ||
66 | } | 73 | } |
67 | 74 | ||
68 | void onClose(CloseSocket fn) { | 75 | void onClose(CloseSocket fn) { |
@@ -77,12 +84,8 @@ class BaseWebSocket { | @@ -77,12 +84,8 @@ class BaseWebSocket { | ||
77 | socketNotifier!.addMessages(fn); | 84 | socketNotifier!.addMessages(fn); |
78 | } | 85 | } |
79 | 86 | ||
80 | - void on(String event, MessageSocket message) { | ||
81 | - socketNotifier!.addEvents(event, message); | ||
82 | - } | ||
83 | - | ||
84 | - void close([int? status, String? reason]) { | ||
85 | - socket?.close(status, reason); | 87 | + void onOpen(OpenSocket fn) { |
88 | + socketNotifier!.open = fn; | ||
86 | } | 89 | } |
87 | 90 | ||
88 | void send(dynamic data) async { | 91 | void send(dynamic data) async { |
@@ -95,16 +98,6 @@ class BaseWebSocket { | @@ -95,16 +98,6 @@ class BaseWebSocket { | ||
95 | } | 98 | } |
96 | } | 99 | } |
97 | 100 | ||
98 | - void dispose() { | ||
99 | - socketNotifier!.dispose(); | ||
100 | - socketNotifier = null; | ||
101 | - isDisposed = true; | ||
102 | - } | ||
103 | - | ||
104 | - void emit(String event, dynamic data) { | ||
105 | - send(jsonEncode({'type': event, 'data': data})); | ||
106 | - } | ||
107 | - | ||
108 | Future<WebSocket> _connectForSelfSignedCert(String url) async { | 101 | Future<WebSocket> _connectForSelfSignedCert(String url) async { |
109 | try { | 102 | try { |
110 | var r = Random(); | 103 | var r = Random(); |
@@ -136,3 +129,9 @@ class BaseWebSocket { | @@ -136,3 +129,9 @@ class BaseWebSocket { | ||
136 | } | 129 | } |
137 | } | 130 | } |
138 | } | 131 | } |
132 | + | ||
133 | +enum ConnectionStatus { | ||
134 | + connecting, | ||
135 | + connected, | ||
136 | + closed, | ||
137 | +} |
@@ -816,7 +816,16 @@ you can only use widgets and widget functions here'''; | @@ -816,7 +816,16 @@ you can only use widgets and widget functions here'''; | ||
816 | bool canPop = true, | 816 | bool canPop = true, |
817 | int? id, | 817 | int? id, |
818 | }) { | 818 | }) { |
819 | + //TODO: This code brings compatibility of the new snackbar with GetX 4, | ||
820 | + // remove this code in version 5 | ||
821 | + if (isSnackbarOpen && !closeOverlays) { | ||
822 | + closeCurrentSnackbar(); | ||
823 | + return; | ||
824 | + } | ||
825 | + | ||
819 | if (closeOverlays && isOverlaysOpen) { | 826 | if (closeOverlays && isOverlaysOpen) { |
827 | + //TODO: This code brings compatibility of the new snackbar with GetX 4, | ||
828 | + // remove this code in version 5 | ||
820 | if (isSnackbarOpen) { | 829 | if (isSnackbarOpen) { |
821 | closeAllSnackbars(); | 830 | closeAllSnackbars(); |
822 | } | 831 | } |
@@ -1111,8 +1120,8 @@ you can only use widgets and widget functions here'''; | @@ -1111,8 +1120,8 @@ you can only use widgets and widget functions here'''; | ||
1111 | SnackbarController.cancelAllSnackbars(); | 1120 | SnackbarController.cancelAllSnackbars(); |
1112 | } | 1121 | } |
1113 | 1122 | ||
1114 | - void closeCurrentSnackbar() { | ||
1115 | - SnackbarController.closeCurrentSnackbar(); | 1123 | + Future<void> closeCurrentSnackbar() async { |
1124 | + await SnackbarController.closeCurrentSnackbar(); | ||
1116 | } | 1125 | } |
1117 | 1126 | ||
1118 | /// check if dialog is open | 1127 | /// check if dialog is open |
@@ -9,24 +9,6 @@ import '../../get_navigation.dart'; | @@ -9,24 +9,6 @@ import '../../get_navigation.dart'; | ||
9 | import 'custom_transition.dart'; | 9 | import 'custom_transition.dart'; |
10 | import 'transitions_type.dart'; | 10 | import 'transitions_type.dart'; |
11 | 11 | ||
12 | -@immutable | ||
13 | -class PathDecoded { | ||
14 | - const PathDecoded(this.regex, this.keys); | ||
15 | - final RegExp regex; | ||
16 | - final List<String?> keys; | ||
17 | - | ||
18 | - @override | ||
19 | - bool operator ==(Object other) { | ||
20 | - if (identical(this, other)) return true; | ||
21 | - | ||
22 | - return other is PathDecoded && | ||
23 | - other.regex == regex; // && listEquals(other.keys, keys); | ||
24 | - } | ||
25 | - | ||
26 | - @override | ||
27 | - int get hashCode => regex.hashCode; | ||
28 | -} | ||
29 | - | ||
30 | class GetPage<T> extends Page<T> { | 12 | class GetPage<T> extends Page<T> { |
31 | final GetPageBuilder page; | 13 | final GetPageBuilder page; |
32 | final bool? popGesture; | 14 | final bool? popGesture; |
@@ -98,27 +80,6 @@ class GetPage<T> extends Page<T> { | @@ -98,27 +80,6 @@ class GetPage<T> extends Page<T> { | ||
98 | ); | 80 | ); |
99 | // settings = RouteSettings(name: name, arguments: Get.arguments); | 81 | // settings = RouteSettings(name: name, arguments: Get.arguments); |
100 | 82 | ||
101 | - static PathDecoded _nameToRegex(String path) { | ||
102 | - var keys = <String?>[]; | ||
103 | - | ||
104 | - String _replace(Match pattern) { | ||
105 | - var buffer = StringBuffer('(?:'); | ||
106 | - | ||
107 | - if (pattern[1] != null) buffer.write('\.'); | ||
108 | - buffer.write('([\\w%+-._~!\$&\'()*,;=:@]+))'); | ||
109 | - if (pattern[3] != null) buffer.write('?'); | ||
110 | - | ||
111 | - keys.add(pattern[2]); | ||
112 | - return "$buffer"; | ||
113 | - } | ||
114 | - | ||
115 | - var stringPath = '$path/?' | ||
116 | - .replaceAllMapped(RegExp(r'(\.)?:(\w+)(\?)?'), _replace) | ||
117 | - .replaceAll('//', '/'); | ||
118 | - | ||
119 | - return PathDecoded(RegExp('^$stringPath\$'), keys); | ||
120 | - } | ||
121 | - | ||
122 | GetPage<T> copy({ | 83 | GetPage<T> copy({ |
123 | String? name, | 84 | String? name, |
124 | GetPageBuilder? page, | 85 | GetPageBuilder? page, |
@@ -174,8 +135,6 @@ class GetPage<T> extends Page<T> { | @@ -174,8 +135,6 @@ class GetPage<T> extends Page<T> { | ||
174 | ); | 135 | ); |
175 | } | 136 | } |
176 | 137 | ||
177 | - late Future<T?> popped; | ||
178 | - | ||
179 | @override | 138 | @override |
180 | Route<T> createRoute(BuildContext context) { | 139 | Route<T> createRoute(BuildContext context) { |
181 | // return GetPageRoute<T>(settings: this, page: page); | 140 | // return GetPageRoute<T>(settings: this, page: page); |
@@ -185,7 +144,45 @@ class GetPage<T> extends Page<T> { | @@ -185,7 +144,45 @@ class GetPage<T> extends Page<T> { | ||
185 | unknownRoute: unknownRoute, | 144 | unknownRoute: unknownRoute, |
186 | ).getPageToRoute<T>(this, unknownRoute); | 145 | ).getPageToRoute<T>(this, unknownRoute); |
187 | 146 | ||
188 | - popped = _page.popped; | ||
189 | return _page; | 147 | return _page; |
190 | } | 148 | } |
149 | + | ||
150 | + static PathDecoded _nameToRegex(String path) { | ||
151 | + var keys = <String?>[]; | ||
152 | + | ||
153 | + String _replace(Match pattern) { | ||
154 | + var buffer = StringBuffer('(?:'); | ||
155 | + | ||
156 | + if (pattern[1] != null) buffer.write('\.'); | ||
157 | + buffer.write('([\\w%+-._~!\$&\'()*,;=:@]+))'); | ||
158 | + if (pattern[3] != null) buffer.write('?'); | ||
159 | + | ||
160 | + keys.add(pattern[2]); | ||
161 | + return "$buffer"; | ||
162 | + } | ||
163 | + | ||
164 | + var stringPath = '$path/?' | ||
165 | + .replaceAllMapped(RegExp(r'(\.)?:(\w+)(\?)?'), _replace) | ||
166 | + .replaceAll('//', '/'); | ||
167 | + | ||
168 | + return PathDecoded(RegExp('^$stringPath\$'), keys); | ||
169 | + } | ||
170 | +} | ||
171 | + | ||
172 | +@immutable | ||
173 | +class PathDecoded { | ||
174 | + final RegExp regex; | ||
175 | + final List<String?> keys; | ||
176 | + const PathDecoded(this.regex, this.keys); | ||
177 | + | ||
178 | + @override | ||
179 | + int get hashCode => regex.hashCode; | ||
180 | + | ||
181 | + @override | ||
182 | + bool operator ==(Object other) { | ||
183 | + if (identical(this, other)) return true; | ||
184 | + | ||
185 | + return other is PathDecoded && | ||
186 | + other.regex == regex; // && listEquals(other.keys, keys); | ||
187 | + } | ||
191 | } | 188 | } |
@@ -113,7 +113,6 @@ class GetObserver extends NavigatorObserver { | @@ -113,7 +113,6 @@ class GetObserver extends NavigatorObserver { | ||
113 | value.route = route; | 113 | value.route = route; |
114 | value.isBack = false; | 114 | value.isBack = false; |
115 | value.removed = ''; | 115 | value.removed = ''; |
116 | - // value.isSnackbar = newRoute.isSnackbar ? true : value.isSnackbar ?? false; | ||
117 | value.isBottomSheet = | 116 | value.isBottomSheet = |
118 | newRoute.isBottomSheet ? true : value.isBottomSheet ?? false; | 117 | newRoute.isBottomSheet ? true : value.isBottomSheet ?? false; |
119 | value.isDialog = newRoute.isDialog ? true : value.isDialog ?? false; | 118 | value.isDialog = newRoute.isDialog ? true : value.isDialog ?? false; |
@@ -12,7 +12,7 @@ class SnackbarController { | @@ -12,7 +12,7 @@ class SnackbarController { | ||
12 | late Animation<double> _filterBlurAnimation; | 12 | late Animation<double> _filterBlurAnimation; |
13 | late Animation<Color?> _filterColorAnimation; | 13 | late Animation<Color?> _filterColorAnimation; |
14 | 14 | ||
15 | - final GetSnackBar snack; | 15 | + final GetSnackBar snackbar; |
16 | final _transitionCompleter = Completer<SnackbarController>(); | 16 | final _transitionCompleter = Completer<SnackbarController>(); |
17 | 17 | ||
18 | late SnackbarStatusCallback? _snackbarStatus; | 18 | late SnackbarStatusCallback? _snackbarStatus; |
@@ -40,15 +40,19 @@ class SnackbarController { | @@ -40,15 +40,19 @@ class SnackbarController { | ||
40 | 40 | ||
41 | OverlayState? _overlayState; | 41 | OverlayState? _overlayState; |
42 | 42 | ||
43 | - SnackbarController(this.snack); | 43 | + SnackbarController(this.snackbar); |
44 | 44 | ||
45 | Future<SnackbarController> get future => _transitionCompleter.future; | 45 | Future<SnackbarController> get future => _transitionCompleter.future; |
46 | 46 | ||
47 | + /// Close the snackbar with animation | ||
47 | Future<void> close() async { | 48 | Future<void> close() async { |
48 | _removeEntry(); | 49 | _removeEntry(); |
49 | await future; | 50 | await future; |
50 | } | 51 | } |
51 | 52 | ||
53 | + /// Adds GetSnackbar to a view queue. | ||
54 | + /// Only one GetSnackbar will be displayed at a time, and this method returns | ||
55 | + /// a future to when the snackbar disappears. | ||
52 | Future<void> show() { | 56 | Future<void> show() { |
53 | return _snackBarQueue.addJob(this); | 57 | return _snackBarQueue.addJob(this); |
54 | } | 58 | } |
@@ -61,7 +65,7 @@ class SnackbarController { | @@ -61,7 +65,7 @@ class SnackbarController { | ||
61 | 65 | ||
62 | // ignore: avoid_returning_this | 66 | // ignore: avoid_returning_this |
63 | void _configureAlignment(SnackPosition snackPosition) { | 67 | void _configureAlignment(SnackPosition snackPosition) { |
64 | - switch (snack.snackPosition) { | 68 | + switch (snackbar.snackPosition) { |
65 | case SnackPosition.TOP: | 69 | case SnackPosition.TOP: |
66 | { | 70 | { |
67 | _initialAlignment = const Alignment(-1.0, -2.0); | 71 | _initialAlignment = const Alignment(-1.0, -2.0); |
@@ -89,8 +93,8 @@ class SnackbarController { | @@ -89,8 +93,8 @@ class SnackbarController { | ||
89 | assert(!_transitionCompleter.isCompleted, | 93 | assert(!_transitionCompleter.isCompleted, |
90 | 'Cannot configure a snackbar after disposing it.'); | 94 | 'Cannot configure a snackbar after disposing it.'); |
91 | _controller = _createAnimationController(); | 95 | _controller = _createAnimationController(); |
92 | - _configureAlignment(snack.snackPosition); | ||
93 | - _snackbarStatus = snack.snackbarStatus; | 96 | + _configureAlignment(snackbar.snackPosition); |
97 | + _snackbarStatus = snackbar.snackbarStatus; | ||
94 | _filterBlurAnimation = _createBlurFilterAnimation(); | 98 | _filterBlurAnimation = _createBlurFilterAnimation(); |
95 | _filterColorAnimation = _createColorOverlayColor(); | 99 | _filterColorAnimation = _createColorOverlayColor(); |
96 | _animation = _createAnimation(); | 100 | _animation = _createAnimation(); |
@@ -100,11 +104,11 @@ class SnackbarController { | @@ -100,11 +104,11 @@ class SnackbarController { | ||
100 | } | 104 | } |
101 | 105 | ||
102 | void _configureTimer() { | 106 | void _configureTimer() { |
103 | - if (snack.duration != null) { | 107 | + if (snackbar.duration != null) { |
104 | if (_timer != null && _timer!.isActive) { | 108 | if (_timer != null && _timer!.isActive) { |
105 | _timer!.cancel(); | 109 | _timer!.cancel(); |
106 | } | 110 | } |
107 | - _timer = Timer(snack.duration!, _removeEntry); | 111 | + _timer = Timer(snackbar.duration!, _removeEntry); |
108 | } else { | 112 | } else { |
109 | if (_timer != null) { | 113 | if (_timer != null) { |
110 | _timer!.cancel(); | 114 | _timer!.cancel(); |
@@ -121,8 +125,8 @@ class SnackbarController { | @@ -121,8 +125,8 @@ class SnackbarController { | ||
121 | return AlignmentTween(begin: _initialAlignment, end: _endAlignment).animate( | 125 | return AlignmentTween(begin: _initialAlignment, end: _endAlignment).animate( |
122 | CurvedAnimation( | 126 | CurvedAnimation( |
123 | parent: _controller, | 127 | parent: _controller, |
124 | - curve: snack.forwardAnimationCurve, | ||
125 | - reverseCurve: snack.reverseAnimationCurve, | 128 | + curve: snackbar.forwardAnimationCurve, |
129 | + reverseCurve: snackbar.reverseAnimationCurve, | ||
126 | ), | 130 | ), |
127 | ); | 131 | ); |
128 | } | 132 | } |
@@ -133,16 +137,16 @@ class SnackbarController { | @@ -133,16 +137,16 @@ class SnackbarController { | ||
133 | AnimationController _createAnimationController() { | 137 | AnimationController _createAnimationController() { |
134 | assert(!_transitionCompleter.isCompleted, | 138 | assert(!_transitionCompleter.isCompleted, |
135 | 'Cannot create a animationController from a disposed snackbar'); | 139 | 'Cannot create a animationController from a disposed snackbar'); |
136 | - assert(snack.animationDuration >= Duration.zero); | 140 | + assert(snackbar.animationDuration >= Duration.zero); |
137 | return AnimationController( | 141 | return AnimationController( |
138 | - duration: snack.animationDuration, | 142 | + duration: snackbar.animationDuration, |
139 | debugLabel: '$runtimeType', | 143 | debugLabel: '$runtimeType', |
140 | vsync: navigator!, | 144 | vsync: navigator!, |
141 | ); | 145 | ); |
142 | } | 146 | } |
143 | 147 | ||
144 | Animation<double> _createBlurFilterAnimation() { | 148 | Animation<double> _createBlurFilterAnimation() { |
145 | - return Tween(begin: 0.0, end: snack.overlayBlur).animate( | 149 | + return Tween(begin: 0.0, end: snackbar.overlayBlur).animate( |
146 | CurvedAnimation( | 150 | CurvedAnimation( |
147 | parent: _controller, | 151 | parent: _controller, |
148 | curve: const Interval( | 152 | curve: const Interval( |
@@ -155,7 +159,8 @@ class SnackbarController { | @@ -155,7 +159,8 @@ class SnackbarController { | ||
155 | } | 159 | } |
156 | 160 | ||
157 | Animation<Color?> _createColorOverlayColor() { | 161 | Animation<Color?> _createColorOverlayColor() { |
158 | - return ColorTween(begin: const Color(0x00000000), end: snack.overlayColor) | 162 | + return ColorTween( |
163 | + begin: const Color(0x00000000), end: snackbar.overlayColor) | ||
159 | .animate( | 164 | .animate( |
160 | CurvedAnimation( | 165 | CurvedAnimation( |
161 | parent: _controller, | 166 | parent: _controller, |
@@ -170,11 +175,11 @@ class SnackbarController { | @@ -170,11 +175,11 @@ class SnackbarController { | ||
170 | 175 | ||
171 | Iterable<OverlayEntry> _createOverlayEntries(Widget child) { | 176 | Iterable<OverlayEntry> _createOverlayEntries(Widget child) { |
172 | return <OverlayEntry>[ | 177 | return <OverlayEntry>[ |
173 | - if (snack.overlayBlur > 0.0) ...[ | 178 | + if (snackbar.overlayBlur > 0.0) ...[ |
174 | OverlayEntry( | 179 | OverlayEntry( |
175 | builder: (context) => GestureDetector( | 180 | builder: (context) => GestureDetector( |
176 | onTap: () { | 181 | onTap: () { |
177 | - if (snack.isDismissible && !_onTappedDismiss) { | 182 | + if (snackbar.isDismissible && !_onTappedDismiss) { |
178 | _onTappedDismiss = true; | 183 | _onTappedDismiss = true; |
179 | Get.back(); | 184 | Get.back(); |
180 | } | 185 | } |
@@ -202,7 +207,7 @@ class SnackbarController { | @@ -202,7 +207,7 @@ class SnackbarController { | ||
202 | builder: (context) => Semantics( | 207 | builder: (context) => Semantics( |
203 | child: AlignTransition( | 208 | child: AlignTransition( |
204 | alignment: _animation, | 209 | alignment: _animation, |
205 | - child: snack.isDismissible | 210 | + child: snackbar.isDismissible |
206 | ? _getDismissibleSnack(child) | 211 | ? _getDismissibleSnack(child) |
207 | : _getSnackbarContainer(child), | 212 | : _getSnackbarContainer(child), |
208 | ), | 213 | ), |
@@ -219,14 +224,16 @@ class SnackbarController { | @@ -219,14 +224,16 @@ class SnackbarController { | ||
219 | Widget _getBodyWidget() { | 224 | Widget _getBodyWidget() { |
220 | return Builder(builder: (_) { | 225 | return Builder(builder: (_) { |
221 | return GestureDetector( | 226 | return GestureDetector( |
222 | - child: snack, | ||
223 | - onTap: snack.onTap != null ? () => snack.onTap?.call(snack) : null, | 227 | + child: snackbar, |
228 | + onTap: snackbar.onTap != null | ||
229 | + ? () => snackbar.onTap?.call(snackbar) | ||
230 | + : null, | ||
224 | ); | 231 | ); |
225 | }); | 232 | }); |
226 | } | 233 | } |
227 | 234 | ||
228 | DismissDirection _getDefaultDismissDirection() { | 235 | DismissDirection _getDefaultDismissDirection() { |
229 | - if (snack.snackPosition == SnackPosition.TOP) { | 236 | + if (snackbar.snackPosition == SnackPosition.TOP) { |
230 | return DismissDirection.up; | 237 | return DismissDirection.up; |
231 | } | 238 | } |
232 | return DismissDirection.down; | 239 | return DismissDirection.down; |
@@ -234,7 +241,7 @@ class SnackbarController { | @@ -234,7 +241,7 @@ class SnackbarController { | ||
234 | 241 | ||
235 | Widget _getDismissibleSnack(Widget child) { | 242 | Widget _getDismissibleSnack(Widget child) { |
236 | return Dismissible( | 243 | return Dismissible( |
237 | - direction: snack.dismissDirection ?? _getDefaultDismissDirection(), | 244 | + direction: snackbar.dismissDirection ?? _getDefaultDismissDirection(), |
238 | resizeDuration: null, | 245 | resizeDuration: null, |
239 | confirmDismiss: (_) { | 246 | confirmDismiss: (_) { |
240 | if (_currentStatus == SnackbarStatus.OPENING || | 247 | if (_currentStatus == SnackbarStatus.OPENING || |
@@ -253,7 +260,7 @@ class SnackbarController { | @@ -253,7 +260,7 @@ class SnackbarController { | ||
253 | 260 | ||
254 | Widget _getSnackbarContainer(Widget child) { | 261 | Widget _getSnackbarContainer(Widget child) { |
255 | return Container( | 262 | return Container( |
256 | - margin: snack.margin, | 263 | + margin: snackbar.margin, |
257 | child: child, | 264 | child: child, |
258 | ); | 265 | ); |
259 | } | 266 | } |
@@ -327,8 +334,8 @@ class SnackbarController { | @@ -327,8 +334,8 @@ class SnackbarController { | ||
327 | _snackBarQueue.cancelAllJobs(); | 334 | _snackBarQueue.cancelAllJobs(); |
328 | } | 335 | } |
329 | 336 | ||
330 | - static void closeCurrentSnackbar() { | ||
331 | - _snackBarQueue.closeCurrentJob(); | 337 | + static Future<void> closeCurrentSnackbar() async { |
338 | + await _snackBarQueue.closeCurrentJob(); | ||
332 | } | 339 | } |
333 | } | 340 | } |
334 | 341 | ||
@@ -355,7 +362,7 @@ class _SnackBarQueue { | @@ -355,7 +362,7 @@ class _SnackBarQueue { | ||
355 | _queue.cancelAllJobs(); | 362 | _queue.cancelAllJobs(); |
356 | } | 363 | } |
357 | 364 | ||
358 | - void closeCurrentJob() { | ||
359 | - _currentSnackbar?.close(); | 365 | + Future<void> closeCurrentJob() async { |
366 | + await _currentSnackbar?.close(); | ||
360 | } | 367 | } |
361 | } | 368 | } |
@@ -40,12 +40,16 @@ void main() { | @@ -40,12 +40,16 @@ void main() { | ||
40 | }); | 40 | }); |
41 | 41 | ||
42 | test('Get start and delete called just one time', () async { | 42 | test('Get start and delete called just one time', () async { |
43 | - Get..put(Controller())..put(Controller()); | 43 | + Get |
44 | + ..put(Controller()) | ||
45 | + ..put(Controller()); | ||
44 | 46 | ||
45 | final controller = Get.find<Controller>(); | 47 | final controller = Get.find<Controller>(); |
46 | expect(controller.init, 1); | 48 | expect(controller.init, 1); |
47 | 49 | ||
48 | - Get..delete<Controller>()..delete<Controller>(); | 50 | + Get |
51 | + ..delete<Controller>() | ||
52 | + ..delete<Controller>(); | ||
49 | expect(controller.close, 1); | 53 | expect(controller.close, 1); |
50 | Get.reset(); | 54 | Get.reset(); |
51 | }); | 55 | }); |
-
Please register or login to post a comment