@momo-kits/foundation 0.81.2-beta.1 → 0.81.2-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Application/Components.tsx +3 -3
- package/Application/ModalScreen.tsx +36 -30
- package/Application/Navigation.ts +8 -0
- package/Application/NavigationContainer.tsx +16 -3
- package/Application/Navigator.ts +39 -1
- package/Application/StackScreen.tsx +22 -17
- package/Application/types.ts +3 -4
- package/Application/utils.tsx +12 -0
- package/package.json +1 -1
|
@@ -151,7 +151,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
151
151
|
backgroundColor,
|
|
152
152
|
accessibilityLabel = '',
|
|
153
153
|
}) => {
|
|
154
|
-
const {navigator
|
|
154
|
+
const {navigator} = useContext(ApplicationContext);
|
|
155
155
|
const screen_name = navigator?.ref?.current?.getCurrentRoute().name;
|
|
156
156
|
|
|
157
157
|
useEffect(() => {
|
|
@@ -166,9 +166,9 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
166
166
|
const goBack = () => {
|
|
167
167
|
const canGoBack = navigator?.ref.current?.canGoBack();
|
|
168
168
|
|
|
169
|
-
if (
|
|
169
|
+
if (navigator?.trackingInfo) {
|
|
170
170
|
navigator?.maxApi?.trackEvent('service_icon_clicked', {
|
|
171
|
-
...
|
|
171
|
+
...navigator?.trackingInfo,
|
|
172
172
|
screen_name,
|
|
173
173
|
trigger_id: TRIGGER_ID,
|
|
174
174
|
icon_name: 'back',
|
|
@@ -26,6 +26,9 @@ import {
|
|
|
26
26
|
import {HeaderBackground, HeaderLeft, HeaderTitle} from './Components';
|
|
27
27
|
|
|
28
28
|
const ModalScreen: React.FC<any> = props => {
|
|
29
|
+
/**
|
|
30
|
+
* dismiss callback when modal | bottom sheet dismissed
|
|
31
|
+
*/
|
|
29
32
|
useEffect(() => {
|
|
30
33
|
return () => {
|
|
31
34
|
props.route.params?.onDismiss?.();
|
|
@@ -39,10 +42,8 @@ const ModalScreen: React.FC<any> = props => {
|
|
|
39
42
|
};
|
|
40
43
|
|
|
41
44
|
const Modal: React.FC<ModalParams> = props => {
|
|
42
|
-
const
|
|
43
|
-
const {
|
|
44
|
-
const {screen, barrierDismissible, modalName}: ModalParams =
|
|
45
|
-
props.route.params;
|
|
45
|
+
const {theme, navigator} = useContext(ApplicationContext);
|
|
46
|
+
const {screen, barrierDismissible, modalName} = props.route.params;
|
|
46
47
|
const Component = useRef(screen).current;
|
|
47
48
|
const navigation = new Navigation(props.navigation, theme);
|
|
48
49
|
const params = {
|
|
@@ -52,35 +53,40 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
52
53
|
|
|
53
54
|
delete params.screen;
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (routesLength > 1) {
|
|
59
|
-
screen_name = navigationRoutes[routesLength - 2]?.params?.screen?.name;
|
|
60
|
-
}
|
|
61
|
-
const error_code = (screen as Function)?.()?.props?.information;
|
|
62
|
-
|
|
56
|
+
/**
|
|
57
|
+
* tracking
|
|
58
|
+
*/
|
|
63
59
|
useEffect(() => {
|
|
64
|
-
navigator?.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
...appInfo,
|
|
60
|
+
if (navigator?.trackingInfo) {
|
|
61
|
+
const TRIGGER_ID = '111012100000000000';
|
|
62
|
+
const navigationRoutes = props.navigation.getState()?.routes || [];
|
|
63
|
+
const routesLength = navigationRoutes.length;
|
|
64
|
+
let screen_name = navigationRoutes?.[0]?.params?.screen?.name;
|
|
65
|
+
if (routesLength > 1) {
|
|
66
|
+
screen_name = navigationRoutes[routesLength - 2]?.params?.screen?.name;
|
|
67
|
+
}
|
|
68
|
+
const error_code = (screen as Function)?.()?.props?.information;
|
|
69
|
+
navigator?.maxApi?.trackEvent('service_component_displayed', {
|
|
70
|
+
...navigator?.trackingInfo,
|
|
76
71
|
screen_name,
|
|
77
|
-
trigger_id:
|
|
72
|
+
trigger_id: TRIGGER_ID,
|
|
78
73
|
component_type: 'popup',
|
|
79
74
|
component_name: modalName,
|
|
80
75
|
error_code,
|
|
81
|
-
icon_name: 'close',
|
|
82
76
|
});
|
|
83
|
-
|
|
77
|
+
|
|
78
|
+
return () => {
|
|
79
|
+
navigator?.maxApi?.trackEvent('service_icon_clicked', {
|
|
80
|
+
...navigator?.trackingInfo,
|
|
81
|
+
screen_name,
|
|
82
|
+
trigger_id: '111154100000000001',
|
|
83
|
+
component_type: 'popup',
|
|
84
|
+
component_name: modalName,
|
|
85
|
+
error_code,
|
|
86
|
+
icon_name: 'close',
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
}
|
|
84
90
|
}, []);
|
|
85
91
|
|
|
86
92
|
const onDismiss = () => {
|
|
@@ -123,7 +129,7 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
123
129
|
|
|
124
130
|
const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
125
131
|
const insets = useSafeAreaInsets();
|
|
126
|
-
const {theme, navigator
|
|
132
|
+
const {theme, navigator} = useContext(ApplicationContext);
|
|
127
133
|
const [keyboardSnap, setKeyboardSnap] = useState(0);
|
|
128
134
|
const {screen, options, snapPoint}: BottomSheetParams = props.route.params;
|
|
129
135
|
const Component = useRef(screen).current;
|
|
@@ -214,7 +220,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
214
220
|
/>
|
|
215
221
|
</View>
|
|
216
222
|
<NavigationContainer
|
|
217
|
-
|
|
223
|
+
trackingInfo={navigator?.trackingInfo}
|
|
218
224
|
maxApi={navigator?.maxApi}
|
|
219
225
|
theme={{
|
|
220
226
|
...theme,
|
|
@@ -258,7 +264,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
258
264
|
icon="24_navigation_close"
|
|
259
265
|
backgroundColor="transparent"
|
|
260
266
|
useBorder={false}
|
|
261
|
-
onPress={bottomSheetRef.current?.dismiss}
|
|
267
|
+
onPress={() => bottomSheetRef.current?.dismiss()}
|
|
262
268
|
accessibilityLabel={'BottomSheet/Close'}
|
|
263
269
|
/>
|
|
264
270
|
</HeaderRightAction>
|
|
@@ -14,6 +14,10 @@ class Navigation {
|
|
|
14
14
|
this.theme = theme;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* navigation options will be remove if used
|
|
19
|
+
* @param params
|
|
20
|
+
*/
|
|
17
21
|
private filterParams = (params: NavigationOptions) => {
|
|
18
22
|
if (params.headerRight) {
|
|
19
23
|
const headerRight = params.headerRight?.({}) as React.ReactElement;
|
|
@@ -27,6 +31,10 @@ class Navigation {
|
|
|
27
31
|
return params;
|
|
28
32
|
};
|
|
29
33
|
|
|
34
|
+
/**
|
|
35
|
+
* navigation setOptions support props NavigationOptions base on react-navigation options
|
|
36
|
+
* @param params
|
|
37
|
+
*/
|
|
30
38
|
setOptions = (params: NavigationOptions) => {
|
|
31
39
|
if (__DEV__) {
|
|
32
40
|
params = this.filterParams(params);
|
|
@@ -23,13 +23,16 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
23
23
|
options,
|
|
24
24
|
maxApi,
|
|
25
25
|
localization,
|
|
26
|
-
|
|
26
|
+
trackingInfo,
|
|
27
27
|
}) => {
|
|
28
28
|
const navigationRef = React.useRef<NavigationContainerRef>(null);
|
|
29
29
|
const navigator = useRef(new Navigator(navigationRef));
|
|
30
30
|
const [showGrid, setShowGrid] = useState(false);
|
|
31
31
|
const [language, setLanguage] = useState<'vi' | 'en'>('vi');
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* engine only shake to enable grid view
|
|
35
|
+
*/
|
|
33
36
|
useEffect(() => {
|
|
34
37
|
const subscription = DeviceEventEmitter.addListener(
|
|
35
38
|
'onChangeGrid',
|
|
@@ -38,10 +41,13 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
38
41
|
},
|
|
39
42
|
);
|
|
40
43
|
return () => {
|
|
41
|
-
subscription
|
|
44
|
+
subscription?.remove?.();
|
|
42
45
|
};
|
|
43
46
|
}, []);
|
|
44
47
|
|
|
48
|
+
/**
|
|
49
|
+
* handle mini language & listen change
|
|
50
|
+
*/
|
|
45
51
|
useEffect(() => {
|
|
46
52
|
maxApi?.getLanguage?.((lang: 'vi' | 'en') => {
|
|
47
53
|
setLanguage(lang);
|
|
@@ -54,8 +60,16 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
54
60
|
};
|
|
55
61
|
}, []);
|
|
56
62
|
|
|
63
|
+
/**
|
|
64
|
+
* inject data for navigator
|
|
65
|
+
*/
|
|
57
66
|
navigator.current.maxApi = maxApi;
|
|
67
|
+
navigator.current.trackingInfo = trackingInfo;
|
|
58
68
|
|
|
69
|
+
/**
|
|
70
|
+
* translate
|
|
71
|
+
* @param key
|
|
72
|
+
*/
|
|
59
73
|
const translate = (key: string) => {
|
|
60
74
|
const mergedLocalization: LocalizationObject = {
|
|
61
75
|
vi: {...localization?.vi, ...kitLocalization.vi},
|
|
@@ -74,7 +88,6 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
74
88
|
showGrid,
|
|
75
89
|
language,
|
|
76
90
|
translate,
|
|
77
|
-
appInfo,
|
|
78
91
|
}}>
|
|
79
92
|
<ReactNavigationContainer
|
|
80
93
|
theme={{
|
package/Application/Navigator.ts
CHANGED
|
@@ -4,37 +4,62 @@ import {
|
|
|
4
4
|
HeaderToolkitProps,
|
|
5
5
|
ModalParams,
|
|
6
6
|
ScreenParams,
|
|
7
|
+
TrackingInfo,
|
|
7
8
|
} from './types';
|
|
8
9
|
|
|
9
10
|
class Navigator {
|
|
10
11
|
ref?: any;
|
|
11
12
|
toolkitConfig?: HeaderToolkitProps;
|
|
12
13
|
maxApi?: any;
|
|
14
|
+
trackingInfo?: TrackingInfo;
|
|
13
15
|
|
|
14
16
|
constructor(navigation: any) {
|
|
15
17
|
this.ref = navigation;
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
/**
|
|
21
|
+
* push new stack screen
|
|
22
|
+
* @param params
|
|
23
|
+
*/
|
|
18
24
|
push = (params: ScreenParams) => {
|
|
19
25
|
this.ref.current.dispatch(StackActions.push('Stack', params));
|
|
20
26
|
};
|
|
21
27
|
|
|
28
|
+
/**
|
|
29
|
+
* replace current screen with new screen
|
|
30
|
+
* @param params
|
|
31
|
+
*/
|
|
22
32
|
replace = (params: ScreenParams) => {
|
|
23
33
|
this.ref.current.dispatch(StackActions.replace('Stack', params));
|
|
24
34
|
};
|
|
25
|
-
|
|
35
|
+
/**
|
|
36
|
+
* pop to dismiss a screen
|
|
37
|
+
* @param count
|
|
38
|
+
*/
|
|
26
39
|
pop = (count?: number) => {
|
|
27
40
|
this.ref.current.dispatch(StackActions.pop(count ?? 1));
|
|
28
41
|
};
|
|
29
42
|
|
|
43
|
+
/**
|
|
44
|
+
* present a new screen, show from bottom iOS
|
|
45
|
+
* @param params
|
|
46
|
+
*/
|
|
30
47
|
present = (params: ScreenParams) => {
|
|
31
48
|
this.ref.current.dispatch(StackActions.push('Dialog', params));
|
|
32
49
|
};
|
|
33
50
|
|
|
51
|
+
/**
|
|
52
|
+
* show a modal popup
|
|
53
|
+
* @param params
|
|
54
|
+
*/
|
|
34
55
|
showModal = (params: ModalParams) => {
|
|
35
56
|
this.ref.current.dispatch(StackActions.push('Modal', params));
|
|
36
57
|
};
|
|
37
58
|
|
|
59
|
+
/**
|
|
60
|
+
* show a bottom sheet
|
|
61
|
+
* @param params
|
|
62
|
+
*/
|
|
38
63
|
showBottomSheet = (params: BottomSheetParams) => {
|
|
39
64
|
this.ref.current.dispatch(
|
|
40
65
|
StackActions.push('Modal', {
|
|
@@ -44,10 +69,17 @@ class Navigator {
|
|
|
44
69
|
);
|
|
45
70
|
};
|
|
46
71
|
|
|
72
|
+
/**
|
|
73
|
+
* pop all screen route
|
|
74
|
+
*/
|
|
47
75
|
popToTop = () => {
|
|
48
76
|
this.ref.current.dispatch(StackActions.popToTop());
|
|
49
77
|
};
|
|
50
78
|
|
|
79
|
+
/**
|
|
80
|
+
* reset a navigation flow with new screen
|
|
81
|
+
* @param params
|
|
82
|
+
*/
|
|
51
83
|
reset = (params: ScreenParams) => {
|
|
52
84
|
this.ref.current.dispatch(
|
|
53
85
|
CommonActions.reset({
|
|
@@ -63,6 +95,12 @@ class Navigator {
|
|
|
63
95
|
);
|
|
64
96
|
};
|
|
65
97
|
|
|
98
|
+
/**
|
|
99
|
+
* request max api for mini app
|
|
100
|
+
* @param func
|
|
101
|
+
* @param args
|
|
102
|
+
* @param callback
|
|
103
|
+
*/
|
|
66
104
|
requestApi = (func: any, args: any = [], callback: any) => {
|
|
67
105
|
if (this.maxApi) {
|
|
68
106
|
this.maxApi[func]?.(...args, callback);
|
|
@@ -4,11 +4,9 @@ import Navigation from './Navigation';
|
|
|
4
4
|
import {ApplicationContext} from './index';
|
|
5
5
|
import {GridSystem} from '../Layout';
|
|
6
6
|
|
|
7
|
-
const TRIGGER_ID = '111378000000000000';
|
|
8
|
-
|
|
9
7
|
const StackScreen: React.FC<ScreenParams> = props => {
|
|
10
8
|
const {screen: Component, options}: ScreenParams = props.route.params;
|
|
11
|
-
const {theme, showGrid, navigator
|
|
9
|
+
const {theme, showGrid, navigator} = useContext(ApplicationContext);
|
|
12
10
|
const navigation = new Navigation(props.navigation, theme);
|
|
13
11
|
|
|
14
12
|
const params = {
|
|
@@ -18,17 +16,30 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
18
16
|
|
|
19
17
|
delete params.screen;
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
/**
|
|
20
|
+
* set options for screen
|
|
21
|
+
*/
|
|
22
|
+
useLayoutEffect(() => {
|
|
23
|
+
if (options) {
|
|
24
|
+
navigation.setOptions(options);
|
|
25
|
+
}
|
|
26
|
+
}, [options]);
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* tracking for screen
|
|
30
|
+
*/
|
|
28
31
|
useEffect(() => {
|
|
29
|
-
if (
|
|
32
|
+
if (navigator?.trackingInfo) {
|
|
33
|
+
const TRIGGER_ID = '111378000000000000';
|
|
34
|
+
const navigationRoutes = props.navigation.getState()?.routes || [];
|
|
35
|
+
const routesLength = navigationRoutes.length;
|
|
36
|
+
let pre_screen_name = navigationRoutes?.[0]?.params?.screen?.name;
|
|
37
|
+
if (routesLength > 1) {
|
|
38
|
+
pre_screen_name =
|
|
39
|
+
navigationRoutes[routesLength - 2]?.params?.screen?.name;
|
|
40
|
+
}
|
|
30
41
|
navigator?.maxApi?.trackEvent('service_frame_displayed', {
|
|
31
|
-
...
|
|
42
|
+
...navigator?.trackingInfo,
|
|
32
43
|
screen_name: Component.name,
|
|
33
44
|
pre_screen_name,
|
|
34
45
|
trigger_id: TRIGGER_ID,
|
|
@@ -36,12 +47,6 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
36
47
|
}
|
|
37
48
|
}, []);
|
|
38
49
|
|
|
39
|
-
useLayoutEffect(() => {
|
|
40
|
-
if (options) {
|
|
41
|
-
navigation.setOptions(options);
|
|
42
|
-
}
|
|
43
|
-
}, [options]);
|
|
44
|
-
|
|
45
50
|
return (
|
|
46
51
|
<>
|
|
47
52
|
<Component {...params} />
|
package/Application/types.ts
CHANGED
|
@@ -68,7 +68,6 @@ export type Context = {
|
|
|
68
68
|
showGrid?: boolean;
|
|
69
69
|
language?: 'vi' | 'en';
|
|
70
70
|
translate?: (key: string) => string;
|
|
71
|
-
appInfo: MiniAppInfo;
|
|
72
71
|
};
|
|
73
72
|
|
|
74
73
|
export type LocalizationObject = {
|
|
@@ -80,11 +79,11 @@ export type LocalizationObject = {
|
|
|
80
79
|
};
|
|
81
80
|
};
|
|
82
81
|
|
|
83
|
-
export type
|
|
82
|
+
export type TrackingInfo = {
|
|
83
|
+
[key: string]: any;
|
|
84
84
|
feature_code: string;
|
|
85
85
|
app_id: string;
|
|
86
86
|
build_number: number;
|
|
87
|
-
flow_partner_id?: string;
|
|
88
87
|
};
|
|
89
88
|
|
|
90
89
|
export type NavigationContainerProps = {
|
|
@@ -93,7 +92,7 @@ export type NavigationContainerProps = {
|
|
|
93
92
|
theme: Theme;
|
|
94
93
|
maxApi: any;
|
|
95
94
|
localization?: LocalizationObject;
|
|
96
|
-
|
|
95
|
+
trackingInfo?: TrackingInfo;
|
|
97
96
|
};
|
|
98
97
|
|
|
99
98
|
export type NavigationScreenProps = {
|
package/Application/utils.tsx
CHANGED
|
@@ -13,6 +13,9 @@ import {
|
|
|
13
13
|
import {NavigationOptions, Theme} from './types';
|
|
14
14
|
import {Colors} from '../Consts';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* default options for stack screen
|
|
18
|
+
*/
|
|
16
19
|
const getStackOptions = (): StackNavigationOptions => {
|
|
17
20
|
return {
|
|
18
21
|
headerTitleAlign: 'left',
|
|
@@ -24,6 +27,9 @@ const getStackOptions = (): StackNavigationOptions => {
|
|
|
24
27
|
};
|
|
25
28
|
};
|
|
26
29
|
|
|
30
|
+
/**
|
|
31
|
+
* default options for dialog screen
|
|
32
|
+
*/
|
|
27
33
|
const getDialogOptions = (): StackNavigationOptions => {
|
|
28
34
|
return {
|
|
29
35
|
headerTitleAlign: 'left',
|
|
@@ -35,6 +41,9 @@ const getDialogOptions = (): StackNavigationOptions => {
|
|
|
35
41
|
};
|
|
36
42
|
};
|
|
37
43
|
|
|
44
|
+
/**
|
|
45
|
+
* default options for modal screen
|
|
46
|
+
*/
|
|
38
47
|
const getModalOptions = (): StackNavigationOptions => {
|
|
39
48
|
return {
|
|
40
49
|
headerShown: false,
|
|
@@ -60,6 +69,9 @@ const getModalOptions = (): StackNavigationOptions => {
|
|
|
60
69
|
};
|
|
61
70
|
};
|
|
62
71
|
|
|
72
|
+
/**
|
|
73
|
+
* build react-navigation options
|
|
74
|
+
*/
|
|
63
75
|
const getOptions = (params: NavigationOptions, theme: Theme) => {
|
|
64
76
|
let options = {};
|
|
65
77
|
|