=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,18 +467,24 @@ Get.config( @@ -465,18 +467,24 @@ 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 |  
473 -| -------- | ---------- |  
474 -| StringX | `RxString` |  
475 -| IntX | `RxInt` |  
476 -| MapX | `RxMax` |  
477 -| ListX | `RxList` |  
478 -| NumX | `RxNum` |  
479 -| DoubleX | `RxDouble` | 480 +| Before | After |
  481 +| ------- | ---------- |
  482 +| StringX | `RxString` |
  483 +| IntX | `RxInt` |
  484 +| MapX | `RxMax` |
  485 +| ListX | `RxList` |
  486 +| NumX | `RxNum` |
  487 +| DoubleX | `RxDouble` |
480 488
481 RxController and GetBuilder now have merged, you no longer need to memorize which controller you want to use, just use GetxController, it will work for simple state management and for reactive as well. 489 RxController and GetBuilder now have merged, you no longer need to memorize which controller you want to use, just use GetxController, it will work for simple state management and for reactive as well.
482 490
@@ -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,56 +29,107 @@ class GetImpl implements GetService { @@ -29,56 +29,107 @@ 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,  
44 - Transition transition,  
45 - Duration duration,  
46 - int id,  
47 - bool fullscreenDialog = false,  
48 - Object arguments,  
49 - Bindings binding,  
50 - preventDuplicates = true,  
51 - bool popGesture}) { 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,
  57 + Transition transition,
  58 + Duration duration,
  59 + int id,
  60 + bool fullscreenDialog = false,
  61 + Object arguments,
  62 + Bindings binding,
  63 + preventDuplicates = true,
  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(  
57 - opaque: opaque ?? true,  
58 - page: () => page,  
59 - settings:  
60 - RouteSettings(name: '/${page.runtimeType}', arguments: arguments),  
61 - popGesture: popGesture ?? defaultPopGesture,  
62 - transition: transition ?? defaultTransition,  
63 - fullscreenDialog: fullscreenDialog,  
64 - binding: binding,  
65 - transitionDuration: duration ?? defaultDurationTransition));  
66 - }  
67 -  
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}) { 70 + return global(id).currentState.push(
  71 + GetPageRoute(
  72 + opaque: opaque ?? true,
  73 + page: () => page,
  74 + settings: RouteSettings(
  75 + name: '/${page.runtimeType}',
  76 + arguments: arguments,
  77 + ),
  78 + popGesture: popGesture ?? defaultPopGesture,
  79 + transition: transition ?? defaultTransition,
  80 + fullscreenDialog: fullscreenDialog,
  81 + binding: binding,
  82 + transitionDuration: duration ?? defaultDurationTransition,
  83 + ),
  84 + );
  85 + }
  86 +
  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,  
144 - bool closeOverlays = false,  
145 - bool canPop = true,  
146 - int id}) { 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,
  262 + bool closeOverlays = false,
  263 + bool canPop = true,
  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,19 +289,40 @@ class GetImpl implements GetService { @@ -170,19 +289,40 @@ 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,  
178 - Transition transition,  
179 - bool popGesture,  
180 - int id,  
181 - Object arguments,  
182 - Bindings binding,  
183 - bool fullscreenDialog = false,  
184 - preventDuplicates = true,  
185 - Duration duration}) { 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,
  317 + Transition transition,
  318 + bool popGesture,
  319 + int id,
  320 + Object arguments,
  321 + Bindings binding,
  322 + bool fullscreenDialog = false,
  323 + preventDuplicates = true,
  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,17 +338,45 @@ class GetImpl implements GetService { @@ -198,17 +338,45 @@ 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,  
204 - bool opaque = false,  
205 - bool popGesture,  
206 - int id,  
207 - Object arguments,  
208 - Bindings binding,  
209 - bool fullscreenDialog = false,  
210 - Duration duration,  
211 - Transition transition}) { 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,
  371 + bool opaque = false,
  372 + bool popGesture,
  373 + int id,
  374 + Object arguments,
  375 + Bindings binding,
  376 + bool fullscreenDialog = false,
  377 + Duration duration,
  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 }