=William Cunha Cardoso

Merge branch 'issue-389' of https://github.com/WilliamCunhaCardoso/getx into issue-389

@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
22 - [Gestión del Estado](#gestión-del-estado) 22 - [Gestión del Estado](#gestión-del-estado)
23 - [Reactivo STATE_MANAGER](#reactivo-state_manager) 23 - [Reactivo STATE_MANAGER](#reactivo-state_manager)
24 - [Más detalles sobre la gestión del estado.](#más-detalles-sobre-la-gestión-del-estado) 24 - [Más detalles sobre la gestión del estado.](#más-detalles-sobre-la-gestión-del-estado)
  25 + - [Video explanation about state management](#video-explanation-about-state-management)
25 - [Gestión de Rutas](#gestión-de-rutas) 26 - [Gestión de Rutas](#gestión-de-rutas)
26 - [Más detalles sobre la gestión de rutas.](#más-detalles-sobre-la-gestión-de-rutas) 27 - [Más detalles sobre la gestión de rutas.](#más-detalles-sobre-la-gestión-de-rutas)
27 - [Video Explanation](#video-explanation) 28 - [Video Explanation](#video-explanation)
@@ -31,6 +32,7 @@ @@ -31,6 +32,7 @@
31 - [Cambiar de tema](#cambiar-de-tema) 32 - [Cambiar de tema](#cambiar-de-tema)
32 - [Otras API avanzadas y configuraciones manuales](#otras-api-avanzadas-y-configuraciones-manuales) 33 - [Otras API avanzadas y configuraciones manuales](#otras-api-avanzadas-y-configuraciones-manuales)
33 - [Configuraciones globales opcionales](#configuraciones-globales-opcionales) 34 - [Configuraciones globales opcionales](#configuraciones-globales-opcionales)
  35 + - [Video explanation of Other GetX Features](#video-explanation-of-other-getx-features)
34 - [Rompiendo cambios desde 2.0](#rompiendo-cambios-desde-20) 36 - [Rompiendo cambios desde 2.0](#rompiendo-cambios-desde-20)
35 - [¿Por qué Getx?](#por-qué-getx) 37 - [¿Por qué Getx?](#por-qué-getx)
36 38
@@ -187,6 +189,13 @@ Obx(() => Text (controller.name)); @@ -187,6 +189,13 @@ Obx(() => Text (controller.name));
187 189
188 **Vea una explicación más detallada de la administración del estado [aquí](./docs/es_ES/state_management.md). Allí verá más ejemplos y también la diferencia entre el Gestión del Estado simple y el Gestión del Estado reactivo** 190 **Vea una explicación más detallada de la administración del estado [aquí](./docs/es_ES/state_management.md). Allí verá más ejemplos y también la diferencia entre el Gestión del Estado simple y el Gestión del Estado reactivo**
189 191
  192 +### Video explanation about state management
  193 +
  194 +
  195 +Amateur Coder did an awesome video about state management! Link: [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw)
  196 +
  197 +You will get a good idea of GetX power.
  198 +
190 ## Gestión de Rutas 199 ## Gestión de Rutas
191 200
192 Para navegar a una nueva pantalla: 201 Para navegar a una nueva pantalla:
@@ -446,6 +455,11 @@ Get.config( @@ -446,6 +455,11 @@ Get.config(
446 ) 455 )
447 ``` 456 ```
448 457
  458 +## Video explanation of Other GetX Features
  459 +
  460 +
  461 +Amateur Coder did an awesome video about utils, storage, bindings and other features! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU)
  462 +
449 # Rompiendo cambios desde 2.0 463 # Rompiendo cambios desde 2.0
450 464
451 1- Rx types: 465 1- Rx types:
@@ -12,26 +12,28 @@ @@ -12,26 +12,28 @@
12 12
13 ![](getx.png) 13 ![](getx.png)
14 14
15 -- [**Communication and support channels:**](#communication-and-support-channels-)  
16 -- [**About Get**](#about-get)  
17 -- [**Installing**](#installing)  
18 -- [**Counter App in Get**](#counter-app-in-get)  
19 -- [**The Three pillars**](#the-three-pillars)  
20 - * [State management](#state-management)  
21 - + [Reactive State Manager](#reactive-state-manager)  
22 - + [More details about state management](#more-details-about-state-management)  
23 - * [Route management](#route-management)  
24 - + [More details about route management](#more-details-about-route-management)  
25 - + [Video Explanation](#video-explanation)  
26 - * [Dependency management](#dependency-management)  
27 - + [More details about dependency management](#more-details-about-dependency-management)  
28 -- [**How to contribute**](#how-to-contribute)  
29 -- [**Utils**](#utils)  
30 - * [Change Theme](#change-theme)  
31 - * [Other Advanced APIs](#other-advanced-apis)  
32 - + [Optional Global Settings and Manual configurations](#optional-global-settings-and-manual-configurations)  
33 -- [**Breaking changes from 2.0**](#breaking-changes-from-20)  
34 -- [**Why Getx?**](#why-getx-) 15 +- [Communication and support channels:](#communication-and-support-channels)
  16 +- [About Get](#about-get)
  17 +- [Installing](#installing)
  18 +- [Counter App with GetX](#counter-app-with-getx)
  19 +- [The Three pillars](#the-three-pillars)
  20 + - [State management](#state-management)
  21 + - [Reactive State Manager](#reactive-state-manager)
  22 + - [More details about state management](#more-details-about-state-management)
  23 + - [Video explanation about state management](#video-explanation-about-state-management)
  24 + - [Route management](#route-management)
  25 + - [More details about route management](#more-details-about-route-management)
  26 + - [Video Explanation](#video-explanation)
  27 + - [Dependency management](#dependency-management)
  28 + - [More details about dependency management](#more-details-about-dependency-management)
  29 +- [How to contribute](#how-to-contribute)
  30 +- [Utils](#utils)
  31 + - [Change Theme](#change-theme)
  32 + - [Other Advanced APIs](#other-advanced-apis)
  33 + - [Optional Global Settings and Manual configurations](#optional-global-settings-and-manual-configurations)
  34 + - [Video explanation of Other GetX Features](#video-explanation-of-other-getx-features)
  35 +- [Breaking changes from 2.0](#breaking-changes-from-20)
  36 +- [Why Getx?](#why-getx)
35 37
36 38
37 # Communication and support channels: 39 # Communication and support channels:
@@ -187,7 +189,7 @@ That's all. It's *that* simple. @@ -187,7 +189,7 @@ That's all. It's *that* simple.
187 ### Video explanation about state management 189 ### Video explanation about state management
188 190
189 191
190 -Amateur coder did an awesome video about state management! Link: [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw) 192 +Amateur Coder did an awesome video about state management! Link: [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw)
191 193
192 You will get a good idea of GetX power. 194 You will get a good idea of GetX power.
193 195
@@ -465,12 +467,18 @@ Get.config( @@ -465,12 +467,18 @@ Get.config(
465 ) 467 )
466 ``` 468 ```
467 469
  470 +## Video explanation of Other GetX Features
  471 +
  472 +
  473 +Amateur Coder did an awesome video about utils, storage, bindings and other features! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU)
  474 +
  475 +
468 # Breaking changes from 2.0 476 # Breaking changes from 2.0
469 477
470 1- Rx types: 478 1- Rx types:
471 479
472 | Before | After | 480 | Before | After |
473 -| -------- | ---------- | 481 +| ------- | ---------- |
474 | StringX | `RxString` | 482 | StringX | `RxString` |
475 | IntX | `RxInt` | 483 | IntX | `RxInt` |
476 | MapX | `RxMax` | 484 | MapX | `RxMax` |
@@ -33,6 +33,7 @@ @@ -33,6 +33,7 @@
33 - [Mudar tema (changeTheme)](#mudar-tema-changetheme) 33 - [Mudar tema (changeTheme)](#mudar-tema-changetheme)
34 - [Outras APIs avançadas](#outras-apis-avançadas) 34 - [Outras APIs avançadas](#outras-apis-avançadas)
35 - [Configurações Globais opcionais e configurações manuais](#configurações-globais-opcionais-e-configurações-manuais) 35 - [Configurações Globais opcionais e configurações manuais](#configurações-globais-opcionais-e-configurações-manuais)
  36 + - [Video explanation of Other GetX Features](#video-explanation-of-other-getx-features)
36 - [Breaking Changes da versão 2 para 3](#breaking-changes-da-versão-2-para-3) 37 - [Breaking Changes da versão 2 para 3](#breaking-changes-da-versão-2-para-3)
37 - [Tipagem Rx](#tipagem-rx) 38 - [Tipagem Rx](#tipagem-rx)
38 - [RxController e GetBuilder se uniram](#rxcontroller-e-getbuilder-se-uniram) 39 - [RxController e GetBuilder se uniram](#rxcontroller-e-getbuilder-se-uniram)
@@ -472,6 +473,11 @@ Get.config( @@ -472,6 +473,11 @@ Get.config(
472 ) 473 )
473 ``` 474 ```
474 475
  476 +## Video explanation of Other GetX Features
  477 +
  478 +
  479 +Amateur Coder did an awesome video about utils, storage, bindings and other features! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU)
  480 +
475 # Breaking Changes da versão 2 para 3 481 # Breaking Changes da versão 2 para 3
476 482
477 ## Tipagem Rx 483 ## Tipagem Rx
@@ -29,18 +29,31 @@ class GetImpl implements GetService { @@ -29,18 +29,31 @@ class GetImpl implements GetService {
29 RouteSettings settings; 29 RouteSettings settings;
30 String defaultSeparator = "_"; 30 String defaultSeparator = "_";
31 31
32 - ///Use to instead of Navigator.push, off instead of Navigator.pushReplacement,  
33 - ///offAll instead of Navigator.pushAndRemoveUntil. For named routes just add "named"  
34 - ///after them. Example: toNamed, offNamed, and AllNamed.  
35 - ///To return to the previous screen, use back().  
36 - ///No need to pass any context to Get, just put the name of the route inside  
37 - ///the parentheses and the magic will occur.  
38 -  
39 - /// It replaces Navigator.push, but needs no context, and it doesn't have the Navigator.push  
40 - /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior  
41 - /// of rebuilding every app after a route, use opaque = true as the parameter.  
42 - Future<T> to<T>(Widget page,  
43 - {bool opaque, 32 + /// Pushes a new [page] to the stack
  33 + ///
  34 + /// It has the advantage of not needing context,
  35 + /// so you can call from your business logic
  36 + ///
  37 + /// You can set a custom [transition], and a transition [duration].
  38 + ///
  39 + /// You can send any type of value to the other route in the [arguments].
  40 + ///
  41 + /// Just like native routing in Flutter, you can push a route
  42 + /// as a [fullscreenDialog],
  43 + ///
  44 + /// [id] is for when you are using nested navigation,
  45 + /// as explained in documentation
  46 + ///
  47 + /// If you want the same behavior of ios that pops a route when the user drag,
  48 + /// you can set [popGesture] to true
  49 + ///
  50 + /// If you're using the [Bindings] api, you must define it here
  51 + ///
  52 + /// By default, GetX will prevent you from push a route that you already in,
  53 + /// if you want to push anyway, set [preventDuplicates] to false
  54 + Future<T> to<T>(
  55 + Widget page, {
  56 + bool opaque,
44 Transition transition, 57 Transition transition,
45 Duration duration, 58 Duration duration,
46 int id, 59 int id,
@@ -48,37 +61,75 @@ class GetImpl implements GetService { @@ -48,37 +61,75 @@ class GetImpl implements GetService {
48 Object arguments, 61 Object arguments,
49 Bindings binding, 62 Bindings binding,
50 preventDuplicates = true, 63 preventDuplicates = true,
51 - bool popGesture}) { 64 + bool popGesture,
  65 + }) {
52 if (preventDuplicates && '/${page.runtimeType}' == currentRoute) { 66 if (preventDuplicates && '/${page.runtimeType}' == currentRoute) {
53 return null; 67 return null;
54 } 68 }
55 69
56 - return global(id).currentState.push(GetPageRoute( 70 + return global(id).currentState.push(
  71 + GetPageRoute(
57 opaque: opaque ?? true, 72 opaque: opaque ?? true,
58 page: () => page, 73 page: () => page,
59 - settings:  
60 - RouteSettings(name: '/${page.runtimeType}', arguments: arguments), 74 + settings: RouteSettings(
  75 + name: '/${page.runtimeType}',
  76 + arguments: arguments,
  77 + ),
61 popGesture: popGesture ?? defaultPopGesture, 78 popGesture: popGesture ?? defaultPopGesture,
62 transition: transition ?? defaultTransition, 79 transition: transition ?? defaultTransition,
63 fullscreenDialog: fullscreenDialog, 80 fullscreenDialog: fullscreenDialog,
64 binding: binding, 81 binding: binding,
65 - transitionDuration: duration ?? defaultDurationTransition)); 82 + transitionDuration: duration ?? defaultDurationTransition,
  83 + ),
  84 + );
66 } 85 }
67 86
68 - /// It replaces Navigator.pushNamed, but needs no context, and it doesn't have the Navigator.pushNamed  
69 - /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior  
70 - /// of rebuilding every app after a route, use opaque = true as the parameter.  
71 - Future<T> toNamed<T>(String page,  
72 - {Object arguments, int id, preventDuplicates = true}) { 87 + /// Pushes a new named [page] to the stack
  88 + ///
  89 + /// It has the advantage of not needing context, so you can call
  90 + /// from your business logic.
  91 + ///
  92 + /// You can send any type of value to the other route in the [arguments].
  93 + ///
  94 + /// [id] is for when you are using nested navigation,
  95 + /// as explained in documentation
  96 + ///
  97 + /// By default, GetX will prevent you from push a route that you already in,
  98 + /// if you want to push anyway, set [preventDuplicates] to false
  99 + ///
  100 + /// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
  101 + Future<T> toNamed<T>(
  102 + String page, {
  103 + Object arguments,
  104 + int id,
  105 + preventDuplicates = true,
  106 + }) {
73 if (preventDuplicates && page == currentRoute) { 107 if (preventDuplicates && page == currentRoute) {
74 return null; 108 return null;
75 } 109 }
76 return global(id).currentState.pushNamed(page, arguments: arguments); 110 return global(id).currentState.pushNamed(page, arguments: arguments);
77 } 111 }
78 112
79 - /// It replaces Navigator.pushReplacementNamed, but needs no context.  
80 - Future<T> offNamed<T>(String page,  
81 - {Object arguments, int id, preventDuplicates = true}) { 113 + /// Pop the current named [page] in the stack and push a new one in its place
  114 + ///
  115 + /// It has the advantage of not needing context, so you can call
  116 + /// from your business logic.
  117 + ///
  118 + /// You can send any type of value to the other route in the [arguments].
  119 + ///
  120 + /// [id] is for when you are using nested navigation,
  121 + /// as explained in documentation
  122 + ///
  123 + /// By default, GetX will prevent you from push a route that you already in,
  124 + /// if you want to push anyway, set [preventDuplicates] to false
  125 + ///
  126 + /// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
  127 + Future<T> offNamed<T>(
  128 + String page, {
  129 + Object arguments,
  130 + int id,
  131 + preventDuplicates = true,
  132 + }) {
82 if (preventDuplicates && page == currentRoute) { 133 if (preventDuplicates && page == currentRoute) {
83 return null; 134 return null;
84 } 135 }
@@ -87,29 +138,72 @@ class GetImpl implements GetService { @@ -87,29 +138,72 @@ class GetImpl implements GetService {
87 .pushReplacementNamed(page, arguments: arguments); 138 .pushReplacementNamed(page, arguments: arguments);
88 } 139 }
89 140
90 - /// It replaces Navigator.popUntil, but needs no context. 141 + /// Calls pop several times in the stack until [predicate] returns true
  142 + ///
  143 + /// [id] is for when you are using nested navigation,
  144 + /// as explained in documentation
  145 + ///
  146 + /// [predicate] can be used like this:
  147 + /// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
  148 + ///
  149 + /// or also like this:
  150 + /// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
91 void until(RoutePredicate predicate, {int id}) { 151 void until(RoutePredicate predicate, {int id}) {
92 // if (key.currentState.mounted) // add this if appear problems on future with route navigate 152 // if (key.currentState.mounted) // add this if appear problems on future with route navigate
93 // when widget don't mounted 153 // when widget don't mounted
94 return global(id).currentState.popUntil(predicate); 154 return global(id).currentState.popUntil(predicate);
95 } 155 }
96 156
97 - /// It replaces Navigator.pushAndRemoveUntil, but needs no context. 157 + /// Push the given [page], and then pop several [pages] in the stack until
  158 + /// [predicate] returns true
  159 + ///
  160 + /// [id] is for when you are using nested navigation,
  161 + /// as explained in documentation
  162 + ///
  163 + /// [predicate] can be used like this:
  164 + /// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
  165 + ///
  166 + /// or also like this:
  167 + /// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
98 Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate, {int id}) { 168 Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate, {int id}) {
99 // if (key.currentState.mounted) // add this if appear problems on future with route navigate 169 // if (key.currentState.mounted) // add this if appear problems on future with route navigate
100 // when widget don't mounted 170 // when widget don't mounted
101 return global(id).currentState.pushAndRemoveUntil(page, predicate); 171 return global(id).currentState.pushAndRemoveUntil(page, predicate);
102 } 172 }
103 173
104 - /// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context.  
105 - Future<T> offNamedUntil<T>(String page, RoutePredicate predicate,  
106 - {int id, Object arguments}) { 174 + /// Push the given named [page], and then pop several pages in the stack
  175 + /// until [predicate] returns true
  176 + ///
  177 + /// You can send any type of value to the other route in the [arguments].
  178 + ///
  179 + /// [id] is for when you are using nested navigation,
  180 + /// as explained in documentation
  181 + ///
  182 + /// [predicate] can be used like this:
  183 + /// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
  184 + /// or also like
  185 + /// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
  186 + ///
  187 + /// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
  188 + Future<T> offNamedUntil<T>(
  189 + String page,
  190 + RoutePredicate predicate, {
  191 + int id,
  192 + Object arguments,
  193 + }) {
107 return global(id) 194 return global(id)
108 .currentState 195 .currentState
109 .pushNamedAndRemoveUntil(page, predicate, arguments: arguments); 196 .pushNamedAndRemoveUntil(page, predicate, arguments: arguments);
110 } 197 }
111 198
112 - /// It replaces Navigator.popAndPushNamed, but needs no context. 199 + /// Pop the current named page and pushes a new [page] to the stack in its place
  200 + ///
  201 + /// You can send any type of value to the other route in the [arguments].
  202 + /// It is very similar to `offNamed()` but use a different approach
  203 + ///
  204 + /// The `offNamed()` pop a page, and goes to the next. The `offAndToNamed()` goes
  205 + /// to the next page, and removes the previous one. The route transition
  206 + /// animation is different.
113 Future<T> offAndToNamed<T>(String page, 207 Future<T> offAndToNamed<T>(String page,
114 {Object arguments, int id, dynamic result}) { 208 {Object arguments, int id, dynamic result}) {
115 return global(id) 209 return global(id)
@@ -117,12 +211,25 @@ class GetImpl implements GetService { @@ -117,12 +211,25 @@ class GetImpl implements GetService {
117 .popAndPushNamed(page, arguments: arguments, result: result); 211 .popAndPushNamed(page, arguments: arguments, result: result);
118 } 212 }
119 213
120 - /// It replaces Navigator.removeRoute, but needs no context. 214 + /// Remove a specific [route] from the stack
  215 + ///
  216 + /// [id] is for when you are using nested navigation,
  217 + /// as explained in documentation
121 void removeRoute(Route<dynamic> route, {int id}) { 218 void removeRoute(Route<dynamic> route, {int id}) {
122 return global(id).currentState.removeRoute(route); 219 return global(id).currentState.removeRoute(route);
123 } 220 }
124 221
125 - /// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context. 222 + /// Push a named [page] and remove all other pages from stack
  223 + ///
  224 + /// It has the advantage of not needing context, so you can
  225 + /// call from your business logic.
  226 + ///
  227 + /// You can send any type of value to the other route in the [arguments].
  228 + ///
  229 + /// [id] is for when you are using nested navigation,
  230 + /// as explained in documentation
  231 + ///
  232 + /// Note: Always put a slash on the route ('/page1'), to avoid unexpected errors
126 Future<T> offAllNamed<T>(String newRouteName, 233 Future<T> offAllNamed<T>(String newRouteName,
127 {RoutePredicate predicate, Object arguments, int id}) { 234 {RoutePredicate predicate, Object arguments, int id}) {
128 var route = (Route<dynamic> rota) => false; 235 var route = (Route<dynamic> rota) => false;
@@ -132,18 +239,30 @@ class GetImpl implements GetService { @@ -132,18 +239,30 @@ class GetImpl implements GetService {
132 arguments: arguments); 239 arguments: arguments);
133 } 240 }
134 241
  242 + /// Returns true if a snackbar, dialog or bottomsheet is currently showing in the screen
135 bool get isOverlaysOpen => 243 bool get isOverlaysOpen =>
136 (isSnackbarOpen || isDialogOpen || isBottomSheetOpen); 244 (isSnackbarOpen || isDialogOpen || isBottomSheetOpen);
137 245
  246 + /// returns true if there is no snackbar, dialog or bottomsheet open
138 bool get isOverlaysClosed => 247 bool get isOverlaysClosed =>
139 (!isSnackbarOpen && !isDialogOpen && !isBottomSheetOpen); 248 (!isSnackbarOpen && !isDialogOpen && !isBottomSheetOpen);
140 249
141 - /// It replaces Navigator.pop, but needs no context.  
142 - void back(  
143 - {dynamic result, 250 + /// Pop the current page, snackbar, dialog or bottomsheet in the stack
  251 + ///
  252 + /// if your set [closeOverlays] to true, Get.back() will close the currently open
  253 + /// snackbar/dialog/bottomsheet AND the current page
  254 + ///
  255 + /// [id] is for when you are using nested navigation,
  256 + /// as explained in documentation
  257 + ///
  258 + /// It has the advantage of not needing context, so you can call
  259 + /// from your business logic.
  260 + void back({
  261 + dynamic result,
144 bool closeOverlays = false, 262 bool closeOverlays = false,
145 bool canPop = true, 263 bool canPop = true,
146 - int id}) { 264 + int id,
  265 + }) {
147 if (closeOverlays && isOverlaysOpen) { 266 if (closeOverlays && isOverlaysOpen) {
148 navigator.popUntil((route) { 267 navigator.popUntil((route) {
149 return (isOverlaysClosed); 268 return (isOverlaysClosed);
@@ -158,7 +277,7 @@ class GetImpl implements GetService { @@ -158,7 +277,7 @@ class GetImpl implements GetService {
158 } 277 }
159 } 278 }
160 279
161 - /// It will close as many screens as you define. Times must be> 0; 280 + /// Close as many routes as defined by [times]
162 void close(int times, [int id]) { 281 void close(int times, [int id]) {
163 if ((times == null) || (times < 1)) { 282 if ((times == null) || (times < 1)) {
164 times = 1; 283 times = 1;
@@ -170,11 +289,31 @@ class GetImpl implements GetService { @@ -170,11 +289,31 @@ class GetImpl implements GetService {
170 return back; 289 return back;
171 } 290 }
172 291
173 - /// It replaces Navigator.pushReplacement, but needs no context, and it doesn't have the Navigator.pushReplacement  
174 - /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior  
175 - /// of rebuilding every app after a route, use opaque = true as the parameter.  
176 - Future<T> off<T>(Widget page,  
177 - {bool opaque = false, 292 + /// Pop the current page and pushes a new [page] to the stack
  293 + ///
  294 + /// It has the advantage of not needing context,
  295 + /// so you can call from your business logic
  296 + ///
  297 + /// You can set a custom [transition], and a transition [duration].
  298 + ///
  299 + /// You can send any type of value to the other route in the [arguments].
  300 + ///
  301 + /// Just like native routing in Flutter, you can push a route
  302 + /// as a [fullscreenDialog],
  303 + ///
  304 + /// [id] is for when you are using nested navigation,
  305 + /// as explained in documentation
  306 + ///
  307 + /// If you want the same behavior of ios that pops a route when the user drag,
  308 + /// you can set [popGesture] to true
  309 + ///
  310 + /// If you're using the [Bindings] api, you must define it here
  311 + ///
  312 + /// By default, GetX will prevent you from push a route that you already in,
  313 + /// if you want to push anyway, set [preventDuplicates] to false
  314 + Future<T> off<T>(
  315 + Widget page, {
  316 + bool opaque = false,
178 Transition transition, 317 Transition transition,
179 bool popGesture, 318 bool popGesture,
180 int id, 319 int id,
@@ -182,7 +321,8 @@ class GetImpl implements GetService { @@ -182,7 +321,8 @@ class GetImpl implements GetService {
182 Bindings binding, 321 Bindings binding,
183 bool fullscreenDialog = false, 322 bool fullscreenDialog = false,
184 preventDuplicates = true, 323 preventDuplicates = true,
185 - Duration duration}) { 324 + Duration duration,
  325 + }) {
186 if (preventDuplicates && '/${page.runtimeType}' == currentRoute) { 326 if (preventDuplicates && '/${page.runtimeType}' == currentRoute) {
187 return null; 327 return null;
188 } 328 }
@@ -198,9 +338,36 @@ class GetImpl implements GetService { @@ -198,9 +338,36 @@ class GetImpl implements GetService {
198 transitionDuration: duration ?? defaultDurationTransition)); 338 transitionDuration: duration ?? defaultDurationTransition));
199 } 339 }
200 340
201 - /// It replaces Navigator.pushAndRemoveUntil, but needs no context  
202 - Future<T> offAll<T>(Widget page,  
203 - {RoutePredicate predicate, 341 + /// Pop all pages in the stack and pushes a new [page] to it
  342 + ///
  343 + /// It has the advantage of not needing context,
  344 + /// so you can call from your business logic
  345 + ///
  346 + /// You can set a custom [transition], and a transition [duration].
  347 + ///
  348 + /// You can send any type of value to the other route in the [arguments].
  349 + ///
  350 + /// Just like native routing in Flutter, you can push a route
  351 + /// as a [fullscreenDialog],
  352 + ///
  353 + /// [predicate] can be used like this:
  354 + /// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
  355 + /// or also like
  356 + /// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
  357 + ///
  358 + /// [id] is for when you are using nested navigation,
  359 + /// as explained in documentation
  360 + ///
  361 + /// If you want the same behavior of ios that pops a route when the user drag,
  362 + /// you can set [popGesture] to true
  363 + ///
  364 + /// If you're using the [Bindings] api, you must define it here
  365 + ///
  366 + /// By default, GetX will prevent you from push a route that you already in,
  367 + /// if you want to push anyway, set [preventDuplicates] to false
  368 + Future<T> offAll<T>(
  369 + Widget page, {
  370 + RoutePredicate predicate,
204 bool opaque = false, 371 bool opaque = false,
205 bool popGesture, 372 bool popGesture,
206 int id, 373 int id,
@@ -208,7 +375,8 @@ class GetImpl implements GetService { @@ -208,7 +375,8 @@ class GetImpl implements GetService {
208 Bindings binding, 375 Bindings binding,
209 bool fullscreenDialog = false, 376 bool fullscreenDialog = false,
210 Duration duration, 377 Duration duration,
211 - Transition transition}) { 378 + Transition transition,
  379 + }) {
212 var route = (Route<dynamic> rota) => false; 380 var route = (Route<dynamic> rota) => false;
213 381
214 return global(id).currentState.pushAndRemoveUntil( 382 return global(id).currentState.pushAndRemoveUntil(
@@ -655,6 +823,16 @@ class GetImpl implements GetService { @@ -655,6 +823,16 @@ class GetImpl implements GetService {
655 translations.addAll(tr); 823 translations.addAll(tr);
656 } 824 }
657 825
  826 + void appendTranslations(Map<String, Map<String, String>> tr) {
  827 + tr.forEach((key, map) {
  828 + if (Get.translations.containsKey(key)) {
  829 + Get.translations[key].addAll(map);
  830 + } else {
  831 + Get.translations[key] = map;
  832 + }
  833 + });
  834 + }
  835 +
658 void changeTheme(ThemeData theme) { 836 void changeTheme(ThemeData theme) {
659 getxController.setTheme(theme); 837 getxController.setTheme(theme);
660 } 838 }
@@ -257,15 +257,22 @@ abstract class Translations { @@ -257,15 +257,22 @@ abstract class Translations {
257 257
258 extension Trans on String { 258 extension Trans on String {
259 String get tr { 259 String get tr {
  260 + // Returns the key if locale is null.
260 if (Get.locale?.languageCode == null) return this; 261 if (Get.locale?.languageCode == null) return this;
261 - if (Get.translations  
262 - .containsKey("${Get.locale.languageCode}_${Get.locale.countryCode}")) { 262 +
  263 + // Checks whether the language code and country code are present, and whether the key is also present.
  264 + if (Get.translations.containsKey(
  265 + "${Get.locale.languageCode}_${Get.locale.countryCode}") &&
  266 + Get.translations["${Get.locale.languageCode}_${Get.locale.countryCode}"]
  267 + .containsKey(this)) {
263 return Get.translations[ 268 return Get.translations[
264 "${Get.locale.languageCode}_${Get.locale.countryCode}"][this]; 269 "${Get.locale.languageCode}_${Get.locale.countryCode}"][this];
265 - } else if (Get.translations.containsKey(Get.locale.languageCode)) { 270 +
  271 + // Checks if there is a callback language in the absence of the specific country, and if it contains that key.
  272 + } else if (Get.translations.containsKey(Get.locale.languageCode) &&
  273 + Get.translations[Get.locale.languageCode].containsKey(this)) {
266 return Get.translations[Get.locale.languageCode][this]; 274 return Get.translations[Get.locale.languageCode][this];
267 - } else if (Get.translations.isNotEmpty) {  
268 - return Get.translations.values.first[this]; 275 + // If there is no corresponding language or corresponding key, return the key.
269 } else { 276 } else {
270 return this; 277 return this;
271 } 278 }