route_observer.dart
6.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
import 'package:flutter/widgets.dart';
import '../../../../get_core/get_core.dart';
import '../../../../instance_manager.dart';
import '../../../get_navigation.dart';
import '../../dialog/dialog_route.dart';
import '../../router_report.dart';
import '../default_route.dart';
/// Extracts the name of a route based on it's instance type
/// or null if not possible.
String? _extractRouteName(Route? route) {
if (route?.settings.name != null) {
return route!.settings.name;
}
if (route is GetPageRoute) {
return route.routeName;
}
if (route is GetDialogRoute) {
return 'DIALOG ${route.hashCode}';
}
if (route is GetModalBottomSheetRoute) {
return 'BOTTOMSHEET ${route.hashCode}';
}
return null;
}
class GetObserver extends NavigatorObserver {
final Function(Routing?)? routing;
final Routing? _routeSend;
GetObserver([this.routing, this._routeSend]);
@override
void didPop(Route route, Route? previousRoute) {
super.didPop(route, previousRoute);
final currentRoute = _RouteData.ofRoute(route);
final newRoute = _RouteData.ofRoute(previousRoute);
// if (currentRoute.isSnackbar) {
// // Get.log("CLOSE SNACKBAR ${currentRoute.name}");
// Get.log("CLOSE SNACKBAR");
// } else
if (currentRoute.isBottomSheet || currentRoute.isDialog) {
Get.log("CLOSE ${currentRoute.name}");
} else if (currentRoute.isGetPageRoute) {
Get.log("CLOSE TO ROUTE ${currentRoute.name}");
}
if (previousRoute != null) {
RouterReportManager.reportCurrentRoute(previousRoute);
}
// Here we use a 'inverse didPush set', meaning that we use
// previous route instead of 'route' because this is
// a 'inverse push'
_routeSend?.update((value) {
// Only PageRoute is allowed to change current value
if (previousRoute is PageRoute) {
value.current = _extractRouteName(previousRoute) ?? '';
value.previous = newRoute.name ?? '';
} else if (value.previous.isNotEmpty) {
value.current = value.previous;
}
value.args = previousRoute?.settings.arguments;
value.route = previousRoute;
value.isBack = true;
value.removed = '';
// value.isSnackbar = newRoute.isSnackbar;
value.isBottomSheet = newRoute.isBottomSheet;
value.isDialog = newRoute.isDialog;
});
// print('currentRoute.isDialog ${currentRoute.isDialog}');
routing?.call(_routeSend);
}
@override
void didPush(Route route, Route? previousRoute) {
super.didPush(route, previousRoute);
final newRoute = _RouteData.ofRoute(route);
// if (newRoute.isSnackbar) {
// // Get.log("OPEN SNACKBAR ${newRoute.name}");
// Get.log("OPEN SNACKBAR");
// } else
if (newRoute.isBottomSheet || newRoute.isDialog) {
Get.log("OPEN ${newRoute.name}");
} else if (newRoute.isGetPageRoute) {
Get.log("GOING TO ROUTE ${newRoute.name}");
}
RouterReportManager.reportCurrentRoute(route);
_routeSend?.update((value) {
// Only PageRoute is allowed to change current value
if (route is PageRoute) {
value.current = newRoute.name ?? '';
}
final previousRouteName = _extractRouteName(previousRoute);
if (previousRouteName != null) {
value.previous = previousRouteName;
}
value.args = route.settings.arguments;
value.route = route;
value.isBack = false;
value.removed = '';
// value.isSnackbar = newRoute.isSnackbar ? true : value.isSnackbar ?? false;
value.isBottomSheet =
newRoute.isBottomSheet ? true : value.isBottomSheet ?? false;
value.isDialog = newRoute.isDialog ? true : value.isDialog ?? false;
});
if (routing != null) {
routing!(_routeSend);
}
}
@override
void didRemove(Route route, Route? previousRoute) {
super.didRemove(route, previousRoute);
final routeName = _extractRouteName(route);
final currentRoute = _RouteData.ofRoute(route);
Get.log("REMOVING ROUTE $routeName");
_routeSend?.update((value) {
value.route = previousRoute;
value.isBack = false;
value.removed = routeName ?? '';
value.previous = routeName ?? '';
// value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;
value.isBottomSheet =
currentRoute.isBottomSheet ? false : value.isBottomSheet;
value.isDialog = currentRoute.isDialog ? false : value.isDialog;
});
if (route is GetPageRoute) {
RouterReportManager.reportRouteWillDispose(route);
}
routing?.call(_routeSend);
}
@override
void didReplace({Route? newRoute, Route? oldRoute}) {
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
final newName = _extractRouteName(newRoute);
final oldName = _extractRouteName(oldRoute);
final currentRoute = _RouteData.ofRoute(oldRoute);
Get.log("REPLACE ROUTE $oldName");
Get.log("NEW ROUTE $newName");
if (newRoute != null) {
RouterReportManager.reportCurrentRoute(newRoute);
}
_routeSend?.update((value) {
// Only PageRoute is allowed to change current value
if (newRoute is PageRoute) {
value.current = newName ?? '';
}
value.args = newRoute?.settings.arguments;
value.route = newRoute;
value.isBack = false;
value.removed = '';
value.previous = '$oldName';
// value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;
value.isBottomSheet =
currentRoute.isBottomSheet ? false : value.isBottomSheet;
value.isDialog = currentRoute.isDialog ? false : value.isDialog;
});
if (oldRoute is GetPageRoute) {
RouterReportManager.reportRouteWillDispose(oldRoute);
}
routing?.call(_routeSend);
}
}
class Routing {
String current;
String previous;
dynamic args;
String removed;
Route<dynamic>? route;
bool? isBack;
// bool? isSnackbar;
bool? isBottomSheet;
bool? isDialog;
Routing({
this.current = '',
this.previous = '',
this.args,
this.removed = '',
this.route,
this.isBack,
// this.isSnackbar,
this.isBottomSheet,
this.isDialog,
});
void update(void fn(Routing value)) {
fn(this);
}
}
/// This is basically a util for rules about 'what a route is'
class _RouteData {
final bool isGetPageRoute;
//final bool isSnackbar;
final bool isBottomSheet;
final bool isDialog;
final String? name;
_RouteData({
required this.name,
required this.isGetPageRoute,
// required this.isSnackbar,
required this.isBottomSheet,
required this.isDialog,
});
factory _RouteData.ofRoute(Route? route) {
return _RouteData(
name: _extractRouteName(route),
isGetPageRoute: route is GetPageRoute,
// isSnackbar: route is SnackRoute,
isDialog: route is GetDialogRoute,
isBottomSheet: route is GetModalBottomSheetRoute,
);
}
}