Showing
11 changed files
with
188 additions
and
156 deletions
| @@ -7,4 +7,4 @@ const Map<String, String> pt_BR = { | @@ -7,4 +7,4 @@ const Map<String, String> pt_BR = { | ||
| 7 | 'total_infecteds': 'Total de infectados', | 7 | 'total_infecteds': 'Total de infectados', | 
| 8 | 'details': 'Detalhes', | 8 | 'details': 'Detalhes', | 
| 9 | 'total_recovered': 'Total de recuperados' | 9 | 'total_recovered': 'Total de recuperados' | 
| 10 | -}; | ||
| 10 | +}; | 
| @@ -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