navigation_observer.dart
3.49 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
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import '../config/config.dart';
import '../config/manager.dart';
import '../log/logger.dart';
import '../utils/element_util.dart';
import 'page_stack.dart';
class AutoTrackNavigationObserver extends NavigatorObserver {
static List<NavigatorObserver> wrap(List<NavigatorObserver>? navigatorObservers) {
if (navigatorObservers == null) {
return [AutoTrackNavigationObserver()];
}
bool found = false;
List<NavigatorObserver> removeList = [];
for (NavigatorObserver observer in navigatorObservers) {
if (observer is AutoTrackNavigationObserver) {
if (found) {
removeList.add(observer);
}
found = true;
}
}
for (NavigatorObserver observer in removeList) {
navigatorObservers.remove(observer);
}
if (!found) {
navigatorObservers.insert(0, AutoTrackNavigationObserver());
}
return navigatorObservers;
}
static List<NavigatorObserver> defaultNavigatorObservers() => [AutoTrackNavigationObserver()];
@override
void didPop(Route route, Route? previousRoute) {
super.didPop(route, previousRoute);
// print('didPop -> $route, previousRoute -> $previousRoute');
try {
PageStack.instance.pop(route, previousRoute);
} catch (e) {
AutoTrackLogger.getInstance().error(e);
}
}
@override
void didPush(Route route, Route? previousRoute) {
super.didPush(route, previousRoute);
// print('didPush -> $route, previousRoute -> $previousRoute');
try {
_findElement(route, (element) {
PageStack.instance.push(route, element, previousRoute);
});
} catch (e) {
AutoTrackLogger.getInstance().error(e);
}
}
@override
void didRemove(Route route, Route? previousRoute) {
super.didRemove(route, previousRoute);
// print('didRemove -> $route, previousRoute -> $previousRoute');
try {
PageStack.instance.remove(route, previousRoute);
} catch (e) {
AutoTrackLogger.getInstance().error(e);
}
}
@override
void didReplace({Route? newRoute, Route? oldRoute}) {
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
// print('didReplace -> $newRoute, oldRoute -> $oldRoute');
try {
if (newRoute != null) {
_findElement(newRoute, (element) {
PageStack.instance.replace(newRoute, element, oldRoute);
});
}
} catch (e) {
AutoTrackLogger.getInstance().error(e);
}
}
void _findElement(Route route, Function(Element) callback) {
SchedulerBinding.instance?.addPostFrameCallback((_) {
if (route is ModalRoute) {
ModalRoute pageRoute = route;
ElementUtil.walk(pageRoute.subtreeContext, (element, parent) {
if (parent != null && parent.widget is Semantics) {
callback(element);
return false;
}
return true;
});
} else if (AutoTrackConfigManager.instance.useCustomRoute) {
List<AutoTrackPageConfig> pageConfigs = AutoTrackConfigManager.instance.pageConfigs;
if (pageConfigs.isEmpty) {
return;
}
Element? lastPageElement;
ElementUtil.walk(route.navigator?.context, (element, parent) {
if (pageConfigs.last.isPageWidget!(element.widget)) {
lastPageElement = element;
return false;
}
return true;
});
if (lastPageElement != null) {
callback(lastPageElement!);
}
}
});
}
}