@momo-kits/foundation 0.109.2-beta.1 → 0.110.1-beta.0
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/BottomSheet.tsx +20 -5
- package/Application/BottomTab/BottomTabBar.tsx +13 -2
- package/Application/BottomTab/index.tsx +2 -2
- package/Application/Components/BottomSheetHelpCenter.tsx +45 -0
- package/Application/Components/HeaderAnimated.tsx +2 -1
- package/Application/Components/HeaderBackground.tsx +16 -9
- package/Application/Components/HeaderExtendHeader.tsx +52 -23
- package/Application/Components/HeaderLeft.tsx +20 -21
- package/Application/Components/HeaderRight.tsx +72 -34
- package/Application/Components/HeaderTitle.tsx +297 -32
- package/Application/Components/SearchHeader.tsx +9 -15
- package/Application/Localize.ts +1 -1
- package/Application/Navigation.ts +3 -1
- package/Application/NavigationContainer.tsx +80 -4
- package/Application/Navigator.ts +5 -5
- package/Application/StackScreen.tsx +26 -40
- package/Application/types.ts +11 -3
- package/Application/utils.tsx +2 -0
- package/Button/index.tsx +0 -2
- package/Input/Input.tsx +19 -12
- package/Input/InputDropDown.tsx +0 -2
- package/Input/InputMoney.tsx +10 -9
- package/Input/InputOTP.tsx +0 -2
- package/Input/InputSearch.tsx +7 -3
- package/Input/index.tsx +18 -3
- package/Input/styles.ts +1 -0
- package/Layout/Screen.tsx +2 -7
- package/Radio/index.tsx +2 -2
- package/Radio/styles.ts +4 -1
- package/Text/index.tsx +106 -36
- package/Title/index.tsx +19 -5
- package/Title/types.ts +6 -0
- package/code-scanner.js +1 -1
- package/package.json +1 -1
- package/publish.sh +0 -1
- package/verify.js +1 -1
- package/tsconfig.json +0 -24
|
@@ -20,6 +20,7 @@ import {Icon} from '../Icon';
|
|
|
20
20
|
const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
21
21
|
const {theme, navigator} = useContext(ApplicationContext);
|
|
22
22
|
const heightDevice = Dimensions.get('screen').height;
|
|
23
|
+
const action = useRef<undefined | string>();
|
|
23
24
|
const insets = useSafeAreaInsets();
|
|
24
25
|
const {
|
|
25
26
|
screen: Screen,
|
|
@@ -29,6 +30,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
29
30
|
barrierDismissible = false,
|
|
30
31
|
draggable = true,
|
|
31
32
|
useBottomInset = true,
|
|
33
|
+
useKeyboardAvoidingView = true,
|
|
32
34
|
keyboardVerticalOffset,
|
|
33
35
|
}: BottomSheetParams = props.route.params;
|
|
34
36
|
const pan = useRef(
|
|
@@ -53,6 +55,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
53
55
|
},
|
|
54
56
|
onPanResponderRelease: (_, gestureState) => {
|
|
55
57
|
if (gestureState.dy > 100) {
|
|
58
|
+
action.current = 'gesture';
|
|
56
59
|
onDismiss();
|
|
57
60
|
} else {
|
|
58
61
|
Animated.spring(pan, {
|
|
@@ -82,7 +85,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
82
85
|
duration: 150,
|
|
83
86
|
}).start();
|
|
84
87
|
return () => {
|
|
85
|
-
props.route.params?.onDismiss?.();
|
|
88
|
+
props.route.params?.onDismiss?.(action.current);
|
|
86
89
|
};
|
|
87
90
|
}, []);
|
|
88
91
|
|
|
@@ -150,7 +153,10 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
150
153
|
)}
|
|
151
154
|
<TouchableOpacity
|
|
152
155
|
style={styles.iconButton}
|
|
153
|
-
onPress={() =>
|
|
156
|
+
onPress={() => {
|
|
157
|
+
action.current = 'icon_close';
|
|
158
|
+
onDismiss(true);
|
|
159
|
+
}}>
|
|
154
160
|
<Icon source="navigation_close" />
|
|
155
161
|
</TouchableOpacity>
|
|
156
162
|
</View>
|
|
@@ -162,16 +168,25 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
162
168
|
<Container
|
|
163
169
|
transparent
|
|
164
170
|
visible={true}
|
|
165
|
-
onRequestClose={() =>
|
|
171
|
+
onRequestClose={() => {
|
|
172
|
+
onDismiss();
|
|
173
|
+
}}
|
|
166
174
|
style={styles.overlay}>
|
|
167
175
|
<KeyboardAvoidingView
|
|
168
|
-
behavior={Platform.
|
|
176
|
+
behavior={Platform.select({
|
|
177
|
+
ios: 'padding',
|
|
178
|
+
android: undefined,
|
|
179
|
+
})}
|
|
169
180
|
keyboardVerticalOffset={keyboardVerticalOffset ?? -20}
|
|
181
|
+
enabled={useKeyboardAvoidingView}
|
|
170
182
|
style={[Styles.flex, {justifyContent: 'flex-end'}]}>
|
|
171
183
|
<TouchableOpacity
|
|
172
184
|
style={Styles.flex}
|
|
173
185
|
activeOpacity={1}
|
|
174
|
-
onPress={() =>
|
|
186
|
+
onPress={() => {
|
|
187
|
+
action.current = 'touch';
|
|
188
|
+
onDismiss();
|
|
189
|
+
}}
|
|
175
190
|
/>
|
|
176
191
|
<Animated.View style={{transform: pan.getTranslateTransform()}}>
|
|
177
192
|
{renderHeader()}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
View,
|
|
17
17
|
} from 'react-native';
|
|
18
18
|
import {EdgeInsets, useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
19
|
-
import {Radius} from '../../Consts';
|
|
19
|
+
import {Colors, Radius} from '../../Consts';
|
|
20
20
|
import {Icon} from '../../Icon';
|
|
21
21
|
import {Text} from '../../Text';
|
|
22
22
|
import {FloatingButtonProps} from '../types';
|
|
@@ -207,7 +207,7 @@ export default function BottomTabBar({
|
|
|
207
207
|
return (
|
|
208
208
|
<Animated.View
|
|
209
209
|
style={[
|
|
210
|
-
styles.tabBar,
|
|
210
|
+
floatingButton ? styles.tabBarFloatingButton : styles.tabBar,
|
|
211
211
|
{
|
|
212
212
|
backgroundColor: theme.colors.background.surface,
|
|
213
213
|
borderTopColor: theme.colors.border.default,
|
|
@@ -253,6 +253,17 @@ const styles = StyleSheet.create({
|
|
|
253
253
|
borderTopWidth: StyleSheet.hairlineWidth,
|
|
254
254
|
elevation: 8,
|
|
255
255
|
},
|
|
256
|
+
tabBarFloatingButton: {
|
|
257
|
+
left: 0,
|
|
258
|
+
right: 0,
|
|
259
|
+
bottom: 0,
|
|
260
|
+
zIndex: 1,
|
|
261
|
+
shadowColor: Colors.black_20,
|
|
262
|
+
shadowOffset: {width: 0, height: -2},
|
|
263
|
+
shadowOpacity: 0.05,
|
|
264
|
+
shadowRadius: 3,
|
|
265
|
+
elevation: 8,
|
|
266
|
+
},
|
|
256
267
|
floatingContainer: {
|
|
257
268
|
position: 'absolute',
|
|
258
269
|
alignItems: 'center',
|
|
@@ -7,7 +7,7 @@ import {EventArg} from '@react-navigation/core';
|
|
|
7
7
|
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
8
8
|
import {Colors} from '../../Consts';
|
|
9
9
|
import {Icon} from '../../Icon';
|
|
10
|
-
import {Text} from '../../Text';
|
|
10
|
+
import {exportFontFamily, Text} from '../../Text';
|
|
11
11
|
import {ApplicationContext} from '../index';
|
|
12
12
|
import StackScreen from '../StackScreen';
|
|
13
13
|
import {BottomTabProps, NavigationScreenProps} from '../types';
|
|
@@ -146,7 +146,7 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
146
146
|
lineHeight: Platform.OS === 'android' ? 17 : 14,
|
|
147
147
|
fontWeight: 'bold',
|
|
148
148
|
alignSelf: 'center',
|
|
149
|
-
fontFamily:
|
|
149
|
+
fontFamily: exportFontFamily('bold'),
|
|
150
150
|
left: isDot ? 8 : 4,
|
|
151
151
|
top: isDot ? -2 : -6,
|
|
152
152
|
backgroundColor: isNum ? Colors.red_03 : Colors.orange_03,
|
|
@@ -10,6 +10,7 @@ const ServiceItem: React.FC<any> = ({service}) => {
|
|
|
10
10
|
const {title, description, icon, onPress} = service;
|
|
11
11
|
const serviceTitle = translate?.(title);
|
|
12
12
|
const serviceDescription = translate?.(description);
|
|
13
|
+
|
|
13
14
|
return (
|
|
14
15
|
<TouchableOpacity onPress={onPress} style={Styles.row}>
|
|
15
16
|
<View style={styles.iconWrapper}>
|
|
@@ -35,6 +36,20 @@ const BottomSheetHelpCenter: React.FC<any> = ({onRequestClose}) => {
|
|
|
35
36
|
const context = useContext<any>(MiniAppContext);
|
|
36
37
|
|
|
37
38
|
const onPressFaq = () => {
|
|
39
|
+
const routes = navigator?.ref.current?.getRootState()?.routes || [];
|
|
40
|
+
const routesLength = routes.length;
|
|
41
|
+
let screenName = routes?.[0]?.params?.screen?.name;
|
|
42
|
+
if (routesLength > 1) {
|
|
43
|
+
screenName = routes[routesLength - 2]?.params?.screen?.name;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
context?.autoTracking?.({
|
|
47
|
+
...context,
|
|
48
|
+
componentName: 'TouchableOpacity',
|
|
49
|
+
componentId: 'bottomsheet_faq_item',
|
|
50
|
+
screenName: screenName,
|
|
51
|
+
});
|
|
52
|
+
|
|
38
53
|
onRequestClose?.(() => {
|
|
39
54
|
navigator?.maxApi?.startFeatureCode?.(
|
|
40
55
|
'helpcenter_problemlevel1',
|
|
@@ -44,6 +59,20 @@ const BottomSheetHelpCenter: React.FC<any> = ({onRequestClose}) => {
|
|
|
44
59
|
};
|
|
45
60
|
|
|
46
61
|
const onPressChatbot = () => {
|
|
62
|
+
const routes = navigator?.ref.current?.getRootState()?.routes || [];
|
|
63
|
+
const routesLength = routes.length;
|
|
64
|
+
let screenName = routes?.[0]?.params?.screen?.name;
|
|
65
|
+
if (routesLength > 1) {
|
|
66
|
+
screenName = routes[routesLength - 2]?.params?.screen?.name;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
context?.autoTracking?.({
|
|
70
|
+
...context,
|
|
71
|
+
componentName: 'TouchableOpacity',
|
|
72
|
+
componentId: 'bottomsheet_chatbot_item',
|
|
73
|
+
screenName: screenName,
|
|
74
|
+
});
|
|
75
|
+
|
|
47
76
|
onRequestClose?.(() => {
|
|
48
77
|
navigator?.maxApi?.getDataObserver('CURRENT_SCREEN', (data: any) => {
|
|
49
78
|
let screenName = data?.screenName;
|
|
@@ -61,6 +90,20 @@ const BottomSheetHelpCenter: React.FC<any> = ({onRequestClose}) => {
|
|
|
61
90
|
};
|
|
62
91
|
|
|
63
92
|
const onPressFeedback = () => {
|
|
93
|
+
const routes = navigator?.ref.current?.getRootState()?.routes || [];
|
|
94
|
+
const routesLength = routes.length;
|
|
95
|
+
let screenName = routes?.[0]?.params?.screen?.name;
|
|
96
|
+
if (routesLength > 1) {
|
|
97
|
+
screenName = routes[routesLength - 2]?.params?.screen?.name;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
context?.autoTracking?.({
|
|
101
|
+
...context,
|
|
102
|
+
componentName: 'TouchableOpacity',
|
|
103
|
+
componentId: 'bottomsheet_feedback_item',
|
|
104
|
+
screenName: screenName,
|
|
105
|
+
});
|
|
106
|
+
|
|
64
107
|
onRequestClose?.(() => {
|
|
65
108
|
navigator?.maxApi?.startFeatureCode?.('feedback', {
|
|
66
109
|
forService: 'navigation',
|
|
@@ -71,6 +114,8 @@ const BottomSheetHelpCenter: React.FC<any> = ({onRequestClose}) => {
|
|
|
71
114
|
appName: context?.name?.['en'],
|
|
72
115
|
buildNumber: context?.buildNumber,
|
|
73
116
|
},
|
|
117
|
+
newUi: true,
|
|
118
|
+
stepFeedback: 1,
|
|
74
119
|
});
|
|
75
120
|
});
|
|
76
121
|
};
|
|
@@ -13,15 +13,15 @@ const LinearGradientAnimated = Animated.createAnimatedComponent(LinearGradient);
|
|
|
13
13
|
*/
|
|
14
14
|
const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
15
15
|
image,
|
|
16
|
-
animatedValue,
|
|
16
|
+
animatedValue = new Animated.Value(0),
|
|
17
17
|
useGradient = true,
|
|
18
18
|
useShadowHeader = true,
|
|
19
|
-
gradientColor,
|
|
19
|
+
gradientColor: customGradientColor,
|
|
20
20
|
headerBackground,
|
|
21
21
|
}) => {
|
|
22
22
|
const {theme} = useContext(ApplicationContext);
|
|
23
23
|
|
|
24
|
-
const
|
|
24
|
+
const gradientColor = customGradientColor ?? theme.colors.gradient;
|
|
25
25
|
|
|
26
26
|
let headerImage = headerBackground ?? theme.assets?.headerBackground;
|
|
27
27
|
if (image === null) {
|
|
@@ -48,13 +48,21 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
48
48
|
{
|
|
49
49
|
backgroundColor: theme.colors.background.surface,
|
|
50
50
|
opacity: opacityBackground,
|
|
51
|
+
overflow: 'hidden',
|
|
51
52
|
},
|
|
52
|
-
]}
|
|
53
|
-
|
|
53
|
+
]}>
|
|
54
|
+
{theme?.assets?.headerBackground && (
|
|
55
|
+
<Image
|
|
56
|
+
style={styles.headerBackground}
|
|
57
|
+
source={{uri: theme?.assets?.headerBackground}}
|
|
58
|
+
loading={false}
|
|
59
|
+
/>
|
|
60
|
+
)}
|
|
61
|
+
</Animated.View>
|
|
54
62
|
<View style={styles.gradientContainer}>
|
|
55
|
-
{useGradient && (
|
|
63
|
+
{useGradient && !!gradientColor && (
|
|
56
64
|
<LinearGradientAnimated
|
|
57
|
-
colors={[
|
|
65
|
+
colors={[gradientColor, gradientColor + '00']}
|
|
58
66
|
style={[styles.extendedHeader, {opacity: opacityGradient}]}>
|
|
59
67
|
{!!headerImage && (
|
|
60
68
|
<Image
|
|
@@ -107,9 +115,8 @@ const styles = StyleSheet.create({
|
|
|
107
115
|
},
|
|
108
116
|
headerBackground: {
|
|
109
117
|
width: '100%',
|
|
110
|
-
height: undefined,
|
|
111
118
|
position: 'absolute',
|
|
112
|
-
aspectRatio: 375 /
|
|
119
|
+
aspectRatio: 375 / 152,
|
|
113
120
|
},
|
|
114
121
|
dividerHeader: {
|
|
115
122
|
borderBottomWidth: 1,
|
|
@@ -46,6 +46,7 @@ const HeaderExtendHeader: React.FC<{
|
|
|
46
46
|
const gradientColor = customGradientColor ?? theme.colors.gradient;
|
|
47
47
|
const headerBackground = customBackground ?? theme.assets?.headerBackground;
|
|
48
48
|
const leftPosition = inputSearchProps?.leftPosition || BACK_WIDTH + 20;
|
|
49
|
+
const isIos = Platform.OS === 'ios';
|
|
49
50
|
|
|
50
51
|
const opacityBackground = animatedValue?.interpolate({
|
|
51
52
|
inputRange: [0, 52],
|
|
@@ -94,7 +95,9 @@ const HeaderExtendHeader: React.FC<{
|
|
|
94
95
|
<Animated.View style={{height: height}} />
|
|
95
96
|
<Animated.View
|
|
96
97
|
style={[
|
|
97
|
-
|
|
98
|
+
isIos && useShadowHeader
|
|
99
|
+
? styles.shadowHeader
|
|
100
|
+
: styles.dividerHeader,
|
|
98
101
|
{
|
|
99
102
|
backgroundColor: theme.colors.background.surface,
|
|
100
103
|
opacity: opacityBackground,
|
|
@@ -102,26 +105,36 @@ const HeaderExtendHeader: React.FC<{
|
|
|
102
105
|
width: '100%',
|
|
103
106
|
height: heightHeader,
|
|
104
107
|
zIndex: 1,
|
|
108
|
+
overflow: 'hidden',
|
|
105
109
|
},
|
|
106
|
-
]}
|
|
107
|
-
|
|
110
|
+
]}>
|
|
111
|
+
{headerBackground && (
|
|
112
|
+
<Image
|
|
113
|
+
style={styles.headerBackground}
|
|
114
|
+
source={{uri: headerBackground}}
|
|
115
|
+
loading={false}
|
|
116
|
+
/>
|
|
117
|
+
)}
|
|
118
|
+
</Animated.View>
|
|
108
119
|
|
|
109
120
|
<Animated.View
|
|
110
121
|
style={[
|
|
111
122
|
styles.headerBox,
|
|
112
123
|
{height: headerType === 'extended' ? height : heightHeader},
|
|
113
124
|
]}>
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
{!!gradientColor && (
|
|
126
|
+
<LinearGradientAnimated
|
|
127
|
+
colors={[gradientColor, gradientColor + '00']}
|
|
128
|
+
style={[styles.extendedHeader, {opacity: opacityGradient}]}>
|
|
129
|
+
{!!theme.assets?.headerBackground && (
|
|
130
|
+
<Image
|
|
131
|
+
style={styles.headerBackground}
|
|
132
|
+
source={{uri: theme.assets?.headerBackground}}
|
|
133
|
+
loading={false}
|
|
134
|
+
/>
|
|
135
|
+
)}
|
|
136
|
+
</LinearGradientAnimated>
|
|
137
|
+
)}
|
|
125
138
|
</Animated.View>
|
|
126
139
|
|
|
127
140
|
<Animated.View
|
|
@@ -172,20 +185,30 @@ const HeaderExtendHeader: React.FC<{
|
|
|
172
185
|
height: heightHeader,
|
|
173
186
|
backgroundColor: theme.colors.background.surface,
|
|
174
187
|
opacity: opacityBackground,
|
|
188
|
+
overflow: 'hidden',
|
|
175
189
|
},
|
|
176
|
-
]}
|
|
177
|
-
|
|
178
|
-
<LinearGradientAnimated
|
|
179
|
-
colors={[gradientColor, gradientColor + '00']}
|
|
180
|
-
style={[styles.extendedHeader, {opacity: opacityGradient}]}>
|
|
181
|
-
{!!headerBackground && (
|
|
190
|
+
]}>
|
|
191
|
+
{headerBackground && (
|
|
182
192
|
<Image
|
|
183
193
|
style={styles.headerBackground}
|
|
184
194
|
source={{uri: headerBackground}}
|
|
185
195
|
loading={false}
|
|
186
196
|
/>
|
|
187
197
|
)}
|
|
188
|
-
</
|
|
198
|
+
</Animated.View>
|
|
199
|
+
{!!gradientColor && (
|
|
200
|
+
<LinearGradientAnimated
|
|
201
|
+
colors={[gradientColor, gradientColor + '00']}
|
|
202
|
+
style={[styles.extendedHeader, {opacity: opacityGradient}]}>
|
|
203
|
+
{!!headerBackground && (
|
|
204
|
+
<Image
|
|
205
|
+
style={styles.headerBackground}
|
|
206
|
+
source={{uri: headerBackground}}
|
|
207
|
+
loading={false}
|
|
208
|
+
/>
|
|
209
|
+
)}
|
|
210
|
+
</LinearGradientAnimated>
|
|
211
|
+
)}
|
|
189
212
|
<View style={{height: heightHeader}} />
|
|
190
213
|
<Verified />
|
|
191
214
|
</>
|
|
@@ -244,8 +267,14 @@ const styles = StyleSheet.create({
|
|
|
244
267
|
shadowRadius: 10,
|
|
245
268
|
},
|
|
246
269
|
android: {
|
|
247
|
-
|
|
248
|
-
|
|
270
|
+
shadowColor: Colors.black_17,
|
|
271
|
+
shadowOffset: {
|
|
272
|
+
width: 3,
|
|
273
|
+
height: 3,
|
|
274
|
+
},
|
|
275
|
+
shadowOpacity: 0.12,
|
|
276
|
+
shadowRadius: 10,
|
|
277
|
+
elevation: 10,
|
|
249
278
|
},
|
|
250
279
|
}),
|
|
251
280
|
},
|
|
@@ -12,35 +12,21 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
12
12
|
tintColor,
|
|
13
13
|
preventBack,
|
|
14
14
|
onPressLeftHeader,
|
|
15
|
+
onBackHandler,
|
|
15
16
|
}) => {
|
|
16
17
|
const context = useContext<any>(MiniAppContext);
|
|
17
18
|
const {navigator} = useContext(ApplicationContext);
|
|
18
19
|
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
const backHandler = BackHandler.addEventListener(
|
|
21
|
-
'hardwareBackPress',
|
|
22
|
-
goBackSafe
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
return () => backHandler.remove();
|
|
26
|
-
}, []);
|
|
27
|
-
|
|
28
20
|
const goBackSafe = () => {
|
|
29
21
|
const goBack = () => {
|
|
30
22
|
const canGoBack = navigator?.ref?.current?.canGoBack?.();
|
|
31
23
|
const currentRoute = navigator?.ref?.current?.getCurrentRoute?.();
|
|
32
|
-
|
|
24
|
+
context?.autoTracking?.({
|
|
33
25
|
...context,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
};
|
|
38
|
-
navigator?.maxApi?.showToastDebug?.({
|
|
39
|
-
appId: `auto - ${context.appId}`,
|
|
40
|
-
message: 'service_icon_clicked',
|
|
41
|
-
params,
|
|
26
|
+
componentName: 'IconButton',
|
|
27
|
+
componentId: 'navigation_back',
|
|
28
|
+
screenName: currentRoute?.params?.screen?.name ?? currentRoute?.name,
|
|
42
29
|
});
|
|
43
|
-
navigator?.maxApi?.trackEvent?.('service_icon_clicked', params);
|
|
44
30
|
|
|
45
31
|
if (canGoBack) {
|
|
46
32
|
navigator?.ref?.current?.goBack?.();
|
|
@@ -49,7 +35,6 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
49
35
|
} else {
|
|
50
36
|
(global as any)?.miniAppApi?.dispatch?.('dismiss', context);
|
|
51
37
|
}
|
|
52
|
-
onPressLeftHeader?.();
|
|
53
38
|
};
|
|
54
39
|
|
|
55
40
|
if (preventBack) {
|
|
@@ -68,11 +53,25 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
68
53
|
),
|
|
69
54
|
});
|
|
70
55
|
} else {
|
|
71
|
-
|
|
56
|
+
onPressLeftHeader?.();
|
|
57
|
+
if (typeof onBackHandler === 'function') {
|
|
58
|
+
onBackHandler(goBack);
|
|
59
|
+
} else {
|
|
60
|
+
goBack();
|
|
61
|
+
}
|
|
72
62
|
}
|
|
73
63
|
return true;
|
|
74
64
|
};
|
|
75
65
|
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
const backHandler = BackHandler.addEventListener(
|
|
68
|
+
'hardwareBackPress',
|
|
69
|
+
goBackSafe
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
return () => backHandler.remove();
|
|
73
|
+
}, [goBackSafe]);
|
|
74
|
+
|
|
76
75
|
return (
|
|
77
76
|
<View style={styles.headerLeft}>
|
|
78
77
|
<NavigationButton
|
|
@@ -15,25 +15,16 @@ import {scaleSize, Text} from '../../Text';
|
|
|
15
15
|
import {BottomSheetHelpCenter} from './BottomSheetHelpCenter';
|
|
16
16
|
import {Image} from '../../Image';
|
|
17
17
|
|
|
18
|
-
const
|
|
19
|
-
'vn.momo.appx',
|
|
20
|
-
'vn.momo.transactionhistory',
|
|
21
|
-
'vn.momo.promotionhub',
|
|
22
|
-
];
|
|
23
|
-
|
|
18
|
+
const DID_SYNC_NEW_HOME = 'did_sync_new_home';
|
|
24
19
|
/**
|
|
25
20
|
* main component for header right
|
|
26
21
|
*/
|
|
27
22
|
const HeaderRight: React.FC<any> = props => {
|
|
28
23
|
const {headerRight = {}} = props;
|
|
29
24
|
const {useOnBoarding = false, buttonOnBoarding, onPress} = headerRight;
|
|
30
|
-
const context = useContext<any>(MiniAppContext);
|
|
31
25
|
const {translate} = useContext(ApplicationContext);
|
|
32
26
|
|
|
33
|
-
if (
|
|
34
|
-
WHITE_LIST.includes(context?.appId) &&
|
|
35
|
-
typeof props.headerRight === 'function'
|
|
36
|
-
) {
|
|
27
|
+
if (typeof props.headerRight === 'function') {
|
|
37
28
|
return props.headerRight(props);
|
|
38
29
|
}
|
|
39
30
|
|
|
@@ -61,12 +52,13 @@ const HeaderRight: React.FC<any> = props => {
|
|
|
61
52
|
const HeaderToolkitAction: React.FC<any> = ({
|
|
62
53
|
tintColor,
|
|
63
54
|
preventClose,
|
|
64
|
-
useShortcut =
|
|
55
|
+
useShortcut = false,
|
|
65
56
|
useMore = false,
|
|
66
57
|
tools = [],
|
|
67
58
|
}) => {
|
|
68
59
|
const {navigator, translate} = useContext(ApplicationContext);
|
|
69
60
|
const context = useContext<any>(MiniAppContext);
|
|
61
|
+
const appCode = navigator?.appCode ? navigator?.appCode : context?.code;
|
|
70
62
|
|
|
71
63
|
const [isFavorite, setIsFavorite] = useState<boolean>(false);
|
|
72
64
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -74,11 +66,22 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
74
66
|
useEffect(() => {
|
|
75
67
|
if (useShortcut) {
|
|
76
68
|
checkAppIsFavorite();
|
|
69
|
+
|
|
70
|
+
const favoriteObserver = navigator?.maxApi?.observer?.(
|
|
71
|
+
DID_SYNC_NEW_HOME,
|
|
72
|
+
(updatedData: any) => {
|
|
73
|
+
const status = updatedData?.items?.includes(appCode);
|
|
74
|
+
setIsFavorite(status);
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
return () => {
|
|
78
|
+
favoriteObserver?.remove?.();
|
|
79
|
+
};
|
|
77
80
|
}
|
|
78
|
-
}, []);
|
|
81
|
+
}, [useShortcut, context, appCode]);
|
|
79
82
|
|
|
80
83
|
let buttonStyle: ViewStyle = {};
|
|
81
|
-
if (tintColor === Colors.black_01) {
|
|
84
|
+
if (tintColor === Colors.black_01 || tintColor === 'white') {
|
|
82
85
|
buttonStyle = {
|
|
83
86
|
backgroundColor: '#00000099',
|
|
84
87
|
borderColor: '#FFFFFF33',
|
|
@@ -88,22 +91,23 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
88
91
|
/**
|
|
89
92
|
* check app is favorite
|
|
90
93
|
*/
|
|
91
|
-
const checkAppIsFavorite = () =>
|
|
92
|
-
navigator?.maxApi?.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
(result: boolean) => {
|
|
96
|
-
if (result !== isFavorite) {
|
|
97
|
-
setIsFavorite(result);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
);
|
|
101
|
-
};
|
|
94
|
+
const checkAppIsFavorite = () =>
|
|
95
|
+
navigator?.maxApi?.isFavoriteApp(appCode, (result: boolean) => {
|
|
96
|
+
setIsFavorite(result);
|
|
97
|
+
});
|
|
102
98
|
|
|
103
99
|
/**
|
|
104
100
|
* close navigation container
|
|
105
101
|
*/
|
|
106
102
|
const onClose = () => {
|
|
103
|
+
const currentRoute = navigator?.ref?.current?.getCurrentRoute?.();
|
|
104
|
+
context?.autoTracking?.({
|
|
105
|
+
...context,
|
|
106
|
+
componentName: 'IconButton',
|
|
107
|
+
componentId: 'navigation_close',
|
|
108
|
+
screenName: currentRoute?.params?.screen?.name ?? currentRoute?.name,
|
|
109
|
+
});
|
|
110
|
+
|
|
107
111
|
if (preventClose) {
|
|
108
112
|
navigator?.showModal({
|
|
109
113
|
screen: () => (
|
|
@@ -132,13 +136,20 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
132
136
|
* on press shortcut
|
|
133
137
|
*/
|
|
134
138
|
const onPressShortcut = () => {
|
|
139
|
+
const currentRoute = navigator?.ref?.current?.getCurrentRoute?.();
|
|
140
|
+
context?.autoTracking?.({
|
|
141
|
+
...context,
|
|
142
|
+
componentName: 'IconButton',
|
|
143
|
+
componentId: 'navigation_shortcut',
|
|
144
|
+
screenName: currentRoute?.params?.screen?.name ?? currentRoute?.name,
|
|
145
|
+
});
|
|
135
146
|
setIsLoading(true);
|
|
136
|
-
navigator?.maxApi?.
|
|
137
|
-
'onToolAction',
|
|
147
|
+
navigator?.maxApi?.onToolAction(
|
|
138
148
|
{
|
|
139
149
|
item: {
|
|
140
150
|
key: 'onFavorite',
|
|
141
151
|
},
|
|
152
|
+
code: appCode,
|
|
142
153
|
},
|
|
143
154
|
({success}: {success: boolean}) => {
|
|
144
155
|
if (success) {
|
|
@@ -157,6 +168,14 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
157
168
|
const onPressHelpCenter = () => {
|
|
158
169
|
const appName = translate?.(context?.name);
|
|
159
170
|
const appDescription = translate?.(context?.description);
|
|
171
|
+
const currentRoute = navigator?.ref?.current?.getCurrentRoute?.();
|
|
172
|
+
context?.autoTracking?.({
|
|
173
|
+
...context,
|
|
174
|
+
componentName: 'IconButton',
|
|
175
|
+
componentId: 'navigation_helpcenter',
|
|
176
|
+
screenName: currentRoute?.params?.screen?.name ?? currentRoute?.name,
|
|
177
|
+
});
|
|
178
|
+
|
|
160
179
|
navigator?.showBottomSheet({
|
|
161
180
|
options: {
|
|
162
181
|
header: (
|
|
@@ -167,11 +186,13 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
167
186
|
/>
|
|
168
187
|
<View>
|
|
169
188
|
<Text typography={'label_default_medium'}>{appName}</Text>
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
189
|
+
{appDescription !== '{}' && (
|
|
190
|
+
<Text
|
|
191
|
+
typography={'description_default_regular'}
|
|
192
|
+
color={Colors.black_12}>
|
|
193
|
+
{appDescription}
|
|
194
|
+
</Text>
|
|
195
|
+
)}
|
|
175
196
|
</View>
|
|
176
197
|
</View>
|
|
177
198
|
),
|
|
@@ -185,7 +206,15 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
185
206
|
* on press icon more
|
|
186
207
|
*/
|
|
187
208
|
const onPressIconMore = () => {
|
|
188
|
-
navigator?.
|
|
209
|
+
const currentRoute = navigator?.ref?.current?.getCurrentRoute?.();
|
|
210
|
+
context?.autoTracking?.({
|
|
211
|
+
...context,
|
|
212
|
+
componentName: 'IconButton',
|
|
213
|
+
componentId: 'navigation_more',
|
|
214
|
+
screenName: currentRoute?.params?.screen?.name ?? currentRoute?.name,
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
navigator?.maxApi?.showTools(tools, appCode, (key: string) => {
|
|
189
218
|
for (const group of tools) {
|
|
190
219
|
const pressedTool = group?.items?.find?.(
|
|
191
220
|
(tool: Tool) => tool?.key === key
|
|
@@ -215,7 +244,16 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
215
244
|
(group: ToolGroup) => group?.items?.length === 1
|
|
216
245
|
)?.items[0];
|
|
217
246
|
iconShortcut = singleTool?.icon;
|
|
218
|
-
shortcutOnPress =
|
|
247
|
+
shortcutOnPress = () => {
|
|
248
|
+
singleTool?.onPress?.();
|
|
249
|
+
const currentRoute = navigator?.ref?.current?.getCurrentRoute?.();
|
|
250
|
+
context?.autoTracking?.({
|
|
251
|
+
...context,
|
|
252
|
+
componentName: 'IconButton',
|
|
253
|
+
componentId: 'navigation_shortcut',
|
|
254
|
+
screenName: currentRoute?.params?.screen?.name ?? currentRoute?.name,
|
|
255
|
+
});
|
|
256
|
+
};
|
|
219
257
|
}
|
|
220
258
|
|
|
221
259
|
const showBadge = tools.some((group: ToolGroup) =>
|