@momo-kits/foundation 0.109.1-tracking.2 → 0.109.1-tracking.28

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.
@@ -135,13 +135,19 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
135
135
  borderBottomWidth: 1,
136
136
  },
137
137
  ]}>
138
- <View style={styles.iconButton} />
139
- <Text
140
- style={[Styles.flex, {textAlign: 'center'}]}
141
- numberOfLines={1}
142
- typography="header_default_bold">
143
- {options.title ?? ''}
144
- </Text>
138
+ {options.header ? (
139
+ <View style={Styles.flex}>{options.header}</View>
140
+ ) : (
141
+ <>
142
+ <View style={styles.iconButton} />
143
+ <Text
144
+ style={[Styles.flex, {textAlign: 'center'}]}
145
+ numberOfLines={1}
146
+ typography="header_default_bold">
147
+ {options.title ?? ''}
148
+ </Text>
149
+ </>
150
+ )}
145
151
  <TouchableOpacity
146
152
  style={styles.iconButton}
147
153
  onPress={() => onDismiss(true)}>
@@ -0,0 +1,147 @@
1
+ import React, {useContext} from 'react';
2
+ import {StyleSheet, TouchableOpacity, View} from 'react-native';
3
+ import {ApplicationContext, MiniAppContext} from '../index';
4
+ import {Colors, Radius, Spacing, Styles} from '../../Consts';
5
+ import {Text} from '../../Text';
6
+ import {Icon} from '../../Icon';
7
+
8
+ const ServiceItem: React.FC<any> = ({service}) => {
9
+ const {theme, translate} = useContext(ApplicationContext);
10
+ const {title, description, icon, onPress} = service;
11
+ const serviceTitle = translate?.(title);
12
+ const serviceDescription = translate?.(description);
13
+ return (
14
+ <TouchableOpacity onPress={onPress} style={Styles.row}>
15
+ <View style={styles.iconWrapper}>
16
+ <Icon color={theme.colors.text.hint} source={icon} size={28} />
17
+ </View>
18
+ <View>
19
+ <View style={Styles.row}>
20
+ <Text typography={'action_xs_bold'}>{serviceTitle}</Text>
21
+ <Icon source={'arrow_chevron_right_small'} size={16} />
22
+ </View>
23
+ <Text
24
+ typography={'description_xs_regular'}
25
+ color={theme.colors.text.hint}>
26
+ {serviceDescription}
27
+ </Text>
28
+ </View>
29
+ </TouchableOpacity>
30
+ );
31
+ };
32
+
33
+ const BottomSheetHelpCenter: React.FC<any> = ({onRequestClose}) => {
34
+ const {theme, navigator} = useContext(ApplicationContext);
35
+ const context = useContext<any>(MiniAppContext);
36
+
37
+ const onPressFaq = () => {
38
+ onRequestClose?.(() => {
39
+ navigator?.maxApi?.startFeatureCode?.(
40
+ 'helpcenter_problemlevel1',
41
+ context?.toolkitConfig?.faq
42
+ );
43
+ });
44
+ };
45
+
46
+ const onPressChatbot = () => {
47
+ onRequestClose?.(() => {
48
+ navigator?.maxApi?.getDataObserver('CURRENT_SCREEN', (data: any) => {
49
+ let screenName = data?.screenName;
50
+ navigator?.maxApi?.startFeatureCode?.('chatbot', {
51
+ botId: 'botGptCs',
52
+ forwardParams: {
53
+ forService: 'navigation',
54
+ mini_app_id: context?.appId,
55
+ feature_code: context?.code,
56
+ screen_name: screenName,
57
+ },
58
+ });
59
+ });
60
+ });
61
+ };
62
+
63
+ const onPressFeedback = () => {
64
+ onRequestClose?.(() => {
65
+ navigator?.maxApi?.startFeatureCode?.('feedback', {
66
+ forService: 'navigation',
67
+ loggedStatus: true,
68
+ application: {
69
+ appId: context?.appId,
70
+ appCode: context?.code,
71
+ appName: context?.name,
72
+ buildNumber: context?.buildNumber,
73
+ },
74
+ });
75
+ });
76
+ };
77
+
78
+ const services = [
79
+ {
80
+ title: {vi: 'Câu hỏi thường gặp', en: 'Câu hỏi thường gặp'},
81
+ description: {
82
+ vi: 'Giải đáp các thắc mắc mọi người thường gặp',
83
+ en: 'Giải đáp các thắc mắc mọi người thường gặp',
84
+ },
85
+ icon: 'notifications_circle_question',
86
+ onPress: onPressFaq,
87
+ },
88
+ {
89
+ title: {vi: 'Hỗ trợ trực tuyến', en: 'Hỗ trợ trực tuyến'},
90
+ description: {
91
+ vi: 'Trả lời mọi câu hỏi của bạn 24/7',
92
+ en: 'Trả lời mọi câu hỏi của bạn 24/7',
93
+ },
94
+ icon: 'ic_support',
95
+ onPress: onPressChatbot,
96
+ },
97
+ {
98
+ title: {vi: 'Chia sẻ góp ý', en: 'Chia sẻ góp ý'},
99
+ description: {
100
+ vi: 'Đề xuất cải thiện hoặc báo lỗi sản phẩm/dịch vụ',
101
+ en: 'Đề xuất cải thiện hoặc báo lỗi sản phẩm/dịch vụ',
102
+ },
103
+ icon: 'file_mail',
104
+ onPress: onPressFeedback,
105
+ },
106
+ ];
107
+
108
+ return (
109
+ <View
110
+ style={[
111
+ styles.container,
112
+ {
113
+ backgroundColor: theme.colors.background.surface,
114
+ },
115
+ ]}>
116
+ {services.map((item, index) => {
117
+ return (
118
+ <>
119
+ <ServiceItem service={item} />
120
+ {index !== services.length - 1 && <View style={styles.divider} />}
121
+ </>
122
+ );
123
+ })}
124
+ </View>
125
+ );
126
+ };
127
+
128
+ const styles = StyleSheet.create({
129
+ container: {height: 300, width: '100%', padding: Spacing.M},
130
+ divider: {
131
+ marginVertical: Spacing.M,
132
+ backgroundColor: Colors.black_02,
133
+ height: 1,
134
+ width: '100%',
135
+ },
136
+ iconWrapper: {
137
+ width: 36,
138
+ height: 36,
139
+ backgroundColor: Colors.black_02,
140
+ borderRadius: Radius.M,
141
+ marginRight: Spacing.S,
142
+ alignItems: 'center',
143
+ justifyContent: 'center',
144
+ },
145
+ });
146
+
147
+ export {BottomSheetHelpCenter};
@@ -12,14 +12,14 @@ import {PopupNotify} from '../../Popup';
12
12
  import {Tool, ToolGroup} from '../types';
13
13
  import {Icon} from '../../Icon';
14
14
  import {scaleSize, Text} from '../../Text';
15
+ import {BottomSheetHelpCenter} from './BottomSheetHelpCenter';
16
+ import {Image} from '../../Image';
15
17
 
16
18
  const WHITE_LIST = [
17
19
  'vn.momo.appx',
18
20
  'vn.momo.transactionhistory',
19
21
  'vn.momo.promotionhub',
20
22
  ];
21
- const HELP_CENTER_CODE = 'helpcenter';
22
- const HELP_CENTER_ICON = 'help_center';
23
23
 
24
24
  /**
25
25
  * main component for header right
@@ -29,6 +29,7 @@ const HeaderRight: React.FC<any> = props => {
29
29
  const {useOnBoarding = false, buttonOnBoarding, onPress} = headerRight;
30
30
  const context = useContext<any>(MiniAppContext);
31
31
  const {translate} = useContext(ApplicationContext);
32
+
32
33
  if (
33
34
  WHITE_LIST.includes(context?.appId) &&
34
35
  typeof props.headerRight === 'function'
@@ -36,10 +37,6 @@ const HeaderRight: React.FC<any> = props => {
36
37
  return props.headerRight(props);
37
38
  }
38
39
 
39
- if (context?.toolkitConfig?.hidden === true) {
40
- return <View />;
41
- }
42
-
43
40
  if (useOnBoarding && onPress) {
44
41
  return (
45
42
  <TouchableOpacity onPress={onPress} style={styles.onBoarding}>
@@ -68,7 +65,7 @@ const HeaderToolkitAction: React.FC<any> = ({
68
65
  useMore = false,
69
66
  tools = [],
70
67
  }) => {
71
- const {navigator} = useContext(ApplicationContext);
68
+ const {navigator, translate} = useContext(ApplicationContext);
72
69
  const context = useContext<any>(MiniAppContext);
73
70
 
74
71
  const [isFavorite, setIsFavorite] = useState<boolean>(false);
@@ -88,6 +85,9 @@ const HeaderToolkitAction: React.FC<any> = ({
88
85
  };
89
86
  }
90
87
 
88
+ /**
89
+ * check app is favorite
90
+ */
91
91
  const checkAppIsFavorite = () => {
92
92
  navigator?.maxApi?.dispatchFunction?.(
93
93
  'isFavoriteApp',
@@ -100,6 +100,9 @@ const HeaderToolkitAction: React.FC<any> = ({
100
100
  );
101
101
  };
102
102
 
103
+ /**
104
+ * close navigation container
105
+ */
103
106
  const onClose = () => {
104
107
  if (preventClose) {
105
108
  navigator?.showModal({
@@ -125,6 +128,9 @@ const HeaderToolkitAction: React.FC<any> = ({
125
128
  }
126
129
  };
127
130
 
131
+ /**
132
+ * on press shortcut
133
+ */
128
134
  const onPressShortcut = () => {
129
135
  setIsLoading(true);
130
136
  navigator?.maxApi?.dispatchFunction?.(
@@ -143,14 +149,39 @@ const HeaderToolkitAction: React.FC<any> = ({
143
149
  );
144
150
  };
145
151
 
152
+ /**
153
+ * on press help center
154
+ */
146
155
  const onPressHelpCenter = () => {
147
- navigator?.maxApi?.dispatchFunction?.(
148
- 'startFeatureCode',
149
- HELP_CENTER_CODE,
150
- () => {}
151
- );
156
+ const appName = translate?.(context?.name);
157
+ const appDescription = translate?.(context?.description);
158
+ navigator?.showBottomSheet({
159
+ options: {
160
+ header: (
161
+ <View style={[Styles.row, {paddingLeft: Spacing.M}]}>
162
+ <Image
163
+ source={{uri: context?.icon}}
164
+ style={{width: 40, height: 40, marginRight: Spacing.S}}
165
+ />
166
+ <View>
167
+ <Text typography={'label_default_medium'}>{appName}</Text>
168
+ <Text
169
+ typography={'description_default_regular'}
170
+ color={Colors.black_12}>
171
+ {appDescription}
172
+ </Text>
173
+ </View>
174
+ </View>
175
+ ),
176
+ },
177
+ surface: true,
178
+ screen: BottomSheetHelpCenter,
179
+ });
152
180
  };
153
181
 
182
+ /**
183
+ * on press icon more
184
+ */
154
185
  const onPressIconMore = () => {
155
186
  navigator?.maxApi?.dispatchFunction?.('showTools', tools, (key: string) => {
156
187
  for (const group of tools) {
@@ -201,14 +232,18 @@ const HeaderToolkitAction: React.FC<any> = ({
201
232
  />
202
233
  )}
203
234
  <View style={[styles.toolkitContainer, buttonStyle]}>
204
- <TouchableOpacity
205
- accessibilityLabel={'btn_navigation_help_center'}
206
- style={styles.toolkitButton}
207
- onPress={onPressHelpCenter}
208
- hitSlop={{top: 7, bottom: 7, left: 7, right: 0}}>
209
- <Icon color={tintColor} source={HELP_CENTER_ICON} size={20} />
210
- </TouchableOpacity>
211
- <View style={[styles.divider, {backgroundColor: tintColor}]} />
235
+ {context.appId !== 'vn.momo.helpcenter' && (
236
+ <>
237
+ <TouchableOpacity
238
+ accessibilityLabel={'btn_navigation_help_center'}
239
+ style={styles.toolkitButton}
240
+ onPress={onPressHelpCenter}
241
+ hitSlop={{top: 7, bottom: 7, left: 7, right: 0}}>
242
+ <Icon color={tintColor} source={'help_center'} size={20} />
243
+ </TouchableOpacity>
244
+ <View style={[styles.divider, {backgroundColor: tintColor}]} />
245
+ </>
246
+ )}
212
247
  <TouchableOpacity
213
248
  accessibilityLabel={'btn_navigation_close'}
214
249
  onPress={onClose}
@@ -27,7 +27,7 @@ const HeaderTitle: React.FC<any> = props => {
27
27
  );
28
28
 
29
29
  return (
30
- <View pointerEvents={'none'}>
30
+ <View pointerEvents={'none'} style={styles.headerTitleContainer}>
31
31
  <Animated.Text
32
32
  {...props}
33
33
  accessibilityLabel={'title_navigation_header'}
@@ -35,6 +35,7 @@ const HeaderTitle: React.FC<any> = props => {
35
35
  styles.title,
36
36
  {fontFamily: `${theme.font}-Bold`, opacity, color: props.tintColor},
37
37
  ]}
38
+ numberOfLines={1}
38
39
  />
39
40
  <Verified />
40
41
  </View>
@@ -258,9 +259,8 @@ const styles = StyleSheet.create({
258
259
  alignSelf: 'center',
259
260
  },
260
261
  headerTitleContainer: {
261
- alignItems: 'center',
262
262
  justifyContent: 'center',
263
- width: Dimensions.get('window').width - 182,
263
+ maxWidth: Dimensions.get('window').width - 178,
264
264
  },
265
265
  circle: {
266
266
  width: 32,
@@ -32,12 +32,12 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
32
32
  const isReady = useRef(false);
33
33
  const navigator = useRef(new Navigator(navigationRef, isReady));
34
34
  const [showGrid, setShowGrid] = useState(false);
35
- const config = useRef<any>();
36
35
 
37
36
  /**
38
37
  * inject data for navigator
39
38
  */
40
39
  navigator.current.maxApi = maxApi;
40
+
41
41
  /**
42
42
  * handle mini language & listen change
43
43
  * engine only shake to enable grid view
@@ -55,8 +55,11 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
55
55
  };
56
56
  }, []);
57
57
 
58
- const translate = (key: string) => {
59
- return localize?.translate(key);
58
+ const translate = (data?: string | {vi: string; en: string}) => {
59
+ if (data && typeof data !== 'string') {
60
+ return localize?.translateData(data);
61
+ }
62
+ return localize?.translate(data as string);
60
63
  };
61
64
 
62
65
  return (
@@ -64,7 +67,6 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
64
67
  <ApplicationContext.Provider
65
68
  value={{
66
69
  navigator: navigator.current,
67
- config: config.current,
68
70
  theme,
69
71
  showGrid,
70
72
  translate,
@@ -1,15 +1,9 @@
1
1
  import {CommonActions, StackActions} from '@react-navigation/native';
2
- import {
3
- BottomSheetParams,
4
- HeaderToolkitProps,
5
- ModalParams,
6
- ScreenParams,
7
- } from './types';
2
+ import {BottomSheetParams, ModalParams, ScreenParams} from './types';
8
3
 
9
4
  class Navigator {
10
5
  ref?: any;
11
6
  isReady?: any;
12
- toolkitConfig?: HeaderToolkitProps;
13
7
  maxApi?: any;
14
8
  dismissData?: any;
15
9
  toolkitCallback?: (key: string) => void;
@@ -111,16 +105,14 @@ class Navigator {
111
105
  };
112
106
 
113
107
  /**
114
- * navigate
108
+ * navigate route name bottom tab only
115
109
  * @param name
116
- * @param params
117
110
  */
118
- navigate = (name: string, params: any) => {
111
+ navigate = (name: string) => {
119
112
  if (this.isReady.current) {
120
113
  this.ref.current?.dispatch?.(
121
114
  CommonActions.navigate({
122
115
  name,
123
- params,
124
116
  })
125
117
  );
126
118
  }
@@ -137,9 +137,9 @@ const StackScreen: React.FC<ScreenParams> = props => {
137
137
  message: `${screenName} screen_load_time ${timeLoad}`,
138
138
  type: 'ERROR',
139
139
  });
140
- if (lastElement.current) {
140
+ if (lastElement.current?.children?.current?.length > 0) {
141
141
  Alert.alert(
142
- 'Last Element',
142
+ `${screenName}- load ${timeLoad}ms`,
143
143
  JSON.stringify(lastElement.current?.children?.current)
144
144
  );
145
145
  }
@@ -71,7 +71,7 @@ export type Context = {
71
71
  theme: Theme;
72
72
  navigator?: Navigator;
73
73
  showGrid?: boolean;
74
- translate?: (key: string) => string;
74
+ translate?: (data: string | {vi: string; en: string}) => string;
75
75
  };
76
76
 
77
77
  export type LocalizationObject = {
@@ -128,7 +128,8 @@ export type BottomSheetParams = {
128
128
  [key: string]: any;
129
129
  screen: React.ComponentType;
130
130
  options: {
131
- title: string;
131
+ header?: React.ReactNode;
132
+ title?: string;
132
133
  };
133
134
  useNativeModal?: boolean;
134
135
  surface?: boolean;
@@ -122,7 +122,11 @@ const getOptions = (
122
122
  if (params.headerRight) {
123
123
  options = {
124
124
  ...options,
125
- ...exportHeaderRight(params),
125
+ ...{
126
+ headerRight: (props: any) => {
127
+ return <HeaderRight {...props} headerRight={params.headerRight} />;
128
+ },
129
+ },
126
130
  };
127
131
  }
128
132
 
@@ -132,14 +136,6 @@ const getOptions = (
132
136
  };
133
137
  };
134
138
 
135
- const exportHeaderRight = (params: NavigationOptions) => {
136
- return {
137
- headerRight: (props: any) => {
138
- return <HeaderRight {...props} headerRight={params.headerRight} />;
139
- },
140
- };
141
- };
142
-
143
139
  const exportHeaderTitle = (
144
140
  params: NavigationOptions,
145
141
  animatedValue?: Animated.Value
@@ -177,6 +173,5 @@ export {
177
173
  getModalOptions,
178
174
  getOptions,
179
175
  exportHeaderTitle,
180
- exportHeaderRight,
181
176
  formatNameLength,
182
177
  };
package/Assets/icon.json CHANGED
@@ -4045,5 +4045,8 @@
4045
4045
  },
4046
4046
  "navigation_more_icon": {
4047
4047
  "uri": "data:image/png;base64,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"
4048
+ },
4049
+ "ic_support": {
4050
+ "uri": "https://static.momocdn.net/app/img/kits/ic_support.png"
4048
4051
  }
4049
4052
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.109.1-tracking.2",
3
+ "version": "0.109.1-tracking.28",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},