@momo-kits/foundation 0.150.2-phuc.13 → 0.150.2-scaleSize.35
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 +39 -114
- package/Application/BottomTab/Badge.tsx +15 -2
- package/Application/BottomTab/BottomTabBar.tsx +1 -1
- package/Application/BottomTab/CustomBottomTabItem.tsx +5 -3
- package/Application/BottomTab/TabBarIcon.tsx +8 -6
- package/Application/BottomTab/index.tsx +82 -87
- package/Application/Components/BackgroundImageView.tsx +1 -1
- package/Application/Components/HeaderAnimated.tsx +12 -11
- package/Application/Components/HeaderBackground.tsx +1 -1
- package/Application/Components/HeaderExtendHeader.tsx +31 -26
- package/Application/Components/HeaderLeft.tsx +2 -2
- package/Application/Components/HeaderRight.tsx +24 -20
- package/Application/Components/HeaderTitle.tsx +19 -7
- package/Application/Components/NavigationButton.tsx +12 -11
- package/Application/Components/SearchHeader.tsx +20 -3
- package/Application/ModalScreen.tsx +14 -1
- package/Application/NavigationContainer.tsx +13 -7
- package/Application/StackScreen.tsx +100 -155
- package/Application/WidgetContainer.tsx +1 -1
- package/Application/index.ts +12 -31
- package/Application/types.ts +66 -18
- package/Application/utils.tsx +41 -17
- package/Assets/language.json +6 -2
- package/Assets/lottie_circle_loader.json +1 -0
- package/Badge/Badge.tsx +14 -11
- package/Badge/BadgeRibbon.tsx +1 -1
- package/Button/index.tsx +47 -32
- package/CheckBox/index.tsx +23 -19
- package/CheckBox/styles.ts +1 -0
- package/Context/index.ts +23 -0
- package/Divider/DashDivider.tsx +10 -9
- package/Divider/index.tsx +7 -7
- package/FoundationList/index.tsx +7 -4
- package/Icon/index.tsx +9 -9
- package/IconButton/index.tsx +12 -10
- package/Image/index.tsx +9 -2
- package/Input/Input.tsx +3 -5
- package/Input/InputDropDown.tsx +31 -23
- package/Input/InputMoney.tsx +3 -5
- package/Input/InputOTP.tsx +7 -7
- package/Input/InputPhoneNumber.tsx +271 -0
- package/Input/InputSearch.tsx +3 -5
- package/Input/InputTextArea.tsx +2 -1
- package/Input/TextTyping.tsx +8 -2
- package/Input/common.tsx +31 -24
- package/Input/index.tsx +21 -1
- package/Input/styles.ts +17 -12
- package/Input/utils.ts +42 -1
- package/Layout/Card.tsx +4 -3
- package/Layout/FloatingButton.tsx +1 -1
- package/Layout/GridSystem.tsx +15 -14
- package/Layout/Item.tsx +1 -1
- package/Layout/Screen.tsx +8 -5
- package/Layout/Section.tsx +1 -1
- package/Layout/TrackingScope.tsx +3 -3
- package/Loader/DotLoader.tsx +7 -7
- package/Loader/ProgressBar.tsx +10 -9
- package/Loader/Spinner.tsx +7 -7
- package/Pagination/Dot.tsx +10 -7
- package/Pagination/PaginationDot.tsx +8 -8
- package/Pagination/PaginationScroll.tsx +12 -10
- package/Popup/PopupNotify.tsx +2 -2
- package/Popup/PopupPromotion.tsx +1 -1
- package/Radio/index.tsx +18 -18
- package/Skeleton/index.tsx +1 -1
- package/Switch/index.tsx +17 -12
- package/Text/index.tsx +4 -4
- package/Text/styles.ts +37 -36
- package/Text/types.ts +1 -0
- package/Text/utils.ts +33 -4
- package/Title/index.tsx +48 -29
- package/index.ts +1 -0
- package/package.json +35 -34
- package/Application/Components/index.ts +0 -7
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
useCallback,
|
|
3
|
-
useContext,
|
|
4
|
-
useEffect,
|
|
5
|
-
useLayoutEffect,
|
|
6
|
-
useRef,
|
|
7
|
-
} from 'react';
|
|
1
|
+
import React, { useContext, useEffect, useLayoutEffect, useRef } from 'react';
|
|
8
2
|
import { Alert, InteractionManager } from 'react-native';
|
|
9
3
|
import { useHeaderHeight } from '@react-navigation/elements';
|
|
10
4
|
import { ScreenTrackingParams } from './types';
|
|
11
5
|
import Navigation from './Navigation';
|
|
12
|
-
import { ApplicationContext, MiniAppContext, ScreenContext } from '
|
|
6
|
+
import { ApplicationContext, MiniAppContext, ScreenContext } from '../Context';
|
|
13
7
|
import { GridSystem } from '../Layout';
|
|
14
8
|
import { version } from '../package.json';
|
|
9
|
+
import { useAppState } from './utils';
|
|
15
10
|
|
|
16
11
|
const runAfterInteractions = InteractionManager.runAfterInteractions;
|
|
17
12
|
|
|
@@ -54,6 +49,7 @@ const StackScreen: React.FC<any> = props => {
|
|
|
54
49
|
} = props.route.params;
|
|
55
50
|
const navigation = useRef(new Navigation(props.navigation, context)).current;
|
|
56
51
|
const heightHeader = useHeaderHeight();
|
|
52
|
+
const { isBackgroundToForeground } = useAppState();
|
|
57
53
|
|
|
58
54
|
const data = {
|
|
59
55
|
...initialParams,
|
|
@@ -75,11 +71,81 @@ const StackScreen: React.FC<any> = props => {
|
|
|
75
71
|
}
|
|
76
72
|
}, [navigation, options]);
|
|
77
73
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
/**
|
|
75
|
+
* tracking for screen
|
|
76
|
+
*/
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
let focusScreen: any;
|
|
79
|
+
let onFocusApp: any;
|
|
80
|
+
if (['Invalid', 'screen'].includes(screenName)) {
|
|
81
|
+
navigator?.maxApi?.showPopup?.('notice', {
|
|
82
|
+
title: 'Invalid screen name',
|
|
83
|
+
message:
|
|
84
|
+
'Your screen has not been rendered because Platform has not detected the screen name. Please migrate to support this feature.',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!bottomTab) {
|
|
89
|
+
focusScreen = props.navigation.addListener('focus', () => {
|
|
90
|
+
navigator?.maxApi?.getDataObserver?.('current_screen', (item: any) => {
|
|
91
|
+
onScreenNavigated(item?.screenName, screenName);
|
|
92
|
+
navigator?.maxApi?.setObserver?.('current_screen', { screenName });
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
onFocusApp = navigator?.maxApi?.listen?.('onFocusApp', () => {
|
|
96
|
+
if (props.navigation.isFocused()) {
|
|
97
|
+
navigator?.maxApi?.getDataObserver?.(
|
|
98
|
+
'current_screen',
|
|
99
|
+
(item: any) => {
|
|
100
|
+
onScreenNavigated(item?.screenName, screenName);
|
|
101
|
+
navigator?.maxApi?.setObserver?.('current_screen', {
|
|
102
|
+
screenName,
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
navigator?.maxApi?.startTraceScreenLoad?.(
|
|
111
|
+
screenName,
|
|
112
|
+
context,
|
|
113
|
+
(item: any) => {
|
|
114
|
+
tracking.current.traceIdLoad = item?.traceId;
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
navigator?.maxApi?.startTraceScreenInteraction?.(
|
|
118
|
+
screenName,
|
|
119
|
+
context,
|
|
120
|
+
(item: any) => {
|
|
121
|
+
tracking.current.traceIdInteraction = item?.traceId;
|
|
122
|
+
},
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
tracking.current.timeoutTracking = setTimeout(() => {
|
|
126
|
+
onScreenLoad();
|
|
127
|
+
onScreenInteraction();
|
|
128
|
+
}, 5000);
|
|
129
|
+
|
|
130
|
+
return () => {
|
|
131
|
+
onScreenLoad();
|
|
132
|
+
onScreenInteraction();
|
|
133
|
+
clearTimeout(tracking.current.timeoutLoad);
|
|
134
|
+
clearTimeout(tracking.current.timeoutInteraction);
|
|
135
|
+
clearTimeout(tracking.current.timeoutTracking);
|
|
136
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
137
|
+
clearTimeout(tracking.current.timeoutLoading);
|
|
138
|
+
focusScreen?.();
|
|
139
|
+
onFocusApp?.remove?.();
|
|
140
|
+
};
|
|
141
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
142
|
+
}, []);
|
|
143
|
+
|
|
144
|
+
const onScreenNavigated = (pre: string, current: string) => {
|
|
145
|
+
if (!isBackgroundToForeground) {
|
|
146
|
+
const item: any = {
|
|
147
|
+
preScreenName: pre,
|
|
148
|
+
screenName: current,
|
|
83
149
|
componentName: 'Screen',
|
|
84
150
|
state: 'navigated',
|
|
85
151
|
action: tracking.current?.mounted ? 'back' : 'push',
|
|
@@ -87,7 +153,7 @@ const StackScreen: React.FC<any> = props => {
|
|
|
87
153
|
|
|
88
154
|
context?.autoTracking?.({
|
|
89
155
|
...context,
|
|
90
|
-
...
|
|
156
|
+
...item,
|
|
91
157
|
});
|
|
92
158
|
|
|
93
159
|
tracking.current.mounted = true;
|
|
@@ -100,14 +166,13 @@ const StackScreen: React.FC<any> = props => {
|
|
|
100
166
|
message: `${screenName} screen_navigated`,
|
|
101
167
|
type: 'ERROR',
|
|
102
168
|
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
106
171
|
|
|
107
172
|
/**
|
|
108
173
|
* tracking for screen load
|
|
109
174
|
*/
|
|
110
|
-
const onScreenLoad =
|
|
175
|
+
const onScreenLoad = () => {
|
|
111
176
|
if (!tracking.current?.releaseLoad) {
|
|
112
177
|
let timeLoad = tracking.current.timeLoad;
|
|
113
178
|
if (timeLoad === 0) {
|
|
@@ -150,12 +215,12 @@ const StackScreen: React.FC<any> = props => {
|
|
|
150
215
|
);
|
|
151
216
|
}
|
|
152
217
|
}
|
|
153
|
-
}
|
|
218
|
+
};
|
|
154
219
|
|
|
155
220
|
/**
|
|
156
221
|
* tracking for screen load
|
|
157
222
|
*/
|
|
158
|
-
const onScreenInteraction =
|
|
223
|
+
const onScreenInteraction = () => {
|
|
159
224
|
if (!tracking.current?.releaseInteraction) {
|
|
160
225
|
let timeLoad = tracking.current.timeLoad;
|
|
161
226
|
if (timeLoad === 0) {
|
|
@@ -191,130 +256,7 @@ const StackScreen: React.FC<any> = props => {
|
|
|
191
256
|
type: 'ERROR',
|
|
192
257
|
});
|
|
193
258
|
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* tracking for screen
|
|
198
|
-
*/
|
|
199
|
-
useEffect(() => {
|
|
200
|
-
let focusScreen: any;
|
|
201
|
-
let onFocusApp: any;
|
|
202
|
-
if (['Invalid', 'screen'].includes(screenName)) {
|
|
203
|
-
navigator?.maxApi?.showPopup?.('notice', {
|
|
204
|
-
title: 'Invalid screen name',
|
|
205
|
-
message:
|
|
206
|
-
'Your screen has not been rendered because Platform has not detected the screen name. Please migrate to support this feature.',
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (!bottomTab) {
|
|
211
|
-
focusScreen = props.navigation.addListener('focus', () => {
|
|
212
|
-
navigator?.maxApi?.getDataObserver?.('current_screen', (data: any) => {
|
|
213
|
-
onScreenNavigated(data?.screenName, screenName);
|
|
214
|
-
navigator?.maxApi?.setObserver?.('current_screen', { screenName });
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
onFocusApp = navigator?.maxApi?.listen?.('onFocusApp', () => {
|
|
218
|
-
if (props.navigation.isFocused()) {
|
|
219
|
-
navigator?.maxApi?.getDataObserver?.(
|
|
220
|
-
'current_screen',
|
|
221
|
-
(data: any) => {
|
|
222
|
-
onScreenNavigated(data?.screenName, screenName);
|
|
223
|
-
navigator?.maxApi?.setObserver?.('current_screen', {
|
|
224
|
-
screenName,
|
|
225
|
-
});
|
|
226
|
-
},
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
navigator?.maxApi?.startTraceScreenLoad?.(
|
|
233
|
-
screenName,
|
|
234
|
-
context,
|
|
235
|
-
(data: any) => {
|
|
236
|
-
tracking.current.traceIdLoad = data?.traceId;
|
|
237
|
-
},
|
|
238
|
-
);
|
|
239
|
-
navigator?.maxApi?.startTraceScreenInteraction?.(
|
|
240
|
-
screenName,
|
|
241
|
-
context,
|
|
242
|
-
(data: any) => {
|
|
243
|
-
tracking.current.traceIdInteraction = data?.traceId;
|
|
244
|
-
},
|
|
245
|
-
);
|
|
246
|
-
|
|
247
|
-
tracking.current.timeoutTracking = setTimeout(() => {
|
|
248
|
-
onScreenLoad();
|
|
249
|
-
onScreenInteraction();
|
|
250
|
-
}, 5000);
|
|
251
|
-
|
|
252
|
-
return () => {
|
|
253
|
-
onScreenLoad();
|
|
254
|
-
onScreenInteraction();
|
|
255
|
-
clearTimeout(tracking.current.timeoutLoad);
|
|
256
|
-
clearTimeout(tracking.current.timeoutInteraction);
|
|
257
|
-
clearTimeout(tracking.current.timeoutTracking);
|
|
258
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
259
|
-
clearTimeout(tracking.current.timeoutLoading);
|
|
260
|
-
focusScreen?.();
|
|
261
|
-
onFocusApp?.remove?.();
|
|
262
|
-
};
|
|
263
|
-
}, [
|
|
264
|
-
bottomTab,
|
|
265
|
-
context,
|
|
266
|
-
navigator?.maxApi,
|
|
267
|
-
onScreenInteraction,
|
|
268
|
-
onScreenLoad,
|
|
269
|
-
onScreenNavigated,
|
|
270
|
-
props.navigation,
|
|
271
|
-
screenName,
|
|
272
|
-
]);
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* tracking for screen
|
|
276
|
-
*/
|
|
277
|
-
useEffect(() => {
|
|
278
|
-
if (['Invalid', 'screen'].includes(screenName)) {
|
|
279
|
-
navigator?.maxApi?.showPopup?.('notice', {
|
|
280
|
-
title: 'Invalid screen name',
|
|
281
|
-
message:
|
|
282
|
-
'Your screen has not been rendered because Platform has not detected the screen name. Please migrate to support this feature.',
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
navigator?.maxApi?.startTraceScreenLoad?.(
|
|
287
|
-
screenName,
|
|
288
|
-
context,
|
|
289
|
-
(item: any) => {
|
|
290
|
-
tracking.current.traceIdLoad = item?.traceId;
|
|
291
|
-
},
|
|
292
|
-
);
|
|
293
|
-
navigator?.maxApi?.startTraceScreenInteraction?.(
|
|
294
|
-
screenName,
|
|
295
|
-
context,
|
|
296
|
-
(item: any) => {
|
|
297
|
-
tracking.current.traceIdInteraction = item?.traceId;
|
|
298
|
-
},
|
|
299
|
-
);
|
|
300
|
-
|
|
301
|
-
tracking.current.timeoutTracking = setTimeout(() => {
|
|
302
|
-
onScreenLoad();
|
|
303
|
-
onScreenInteraction();
|
|
304
|
-
}, 5000);
|
|
305
|
-
|
|
306
|
-
return () => {
|
|
307
|
-
onScreenLoad();
|
|
308
|
-
onScreenInteraction();
|
|
309
|
-
};
|
|
310
|
-
}, [
|
|
311
|
-
context,
|
|
312
|
-
navigator?.maxApi,
|
|
313
|
-
onScreenInteraction,
|
|
314
|
-
onScreenLoad,
|
|
315
|
-
props.navigation,
|
|
316
|
-
screenName,
|
|
317
|
-
]);
|
|
259
|
+
};
|
|
318
260
|
|
|
319
261
|
/**
|
|
320
262
|
* tracking for first interaction by user
|
|
@@ -343,16 +285,19 @@ const StackScreen: React.FC<any> = props => {
|
|
|
343
285
|
}
|
|
344
286
|
};
|
|
345
287
|
|
|
288
|
+
/**
|
|
289
|
+
* tracking for loading screen
|
|
290
|
+
*/
|
|
346
291
|
const onScreenLoading = () => {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
292
|
+
const start = tracking.current.timeStartLoading;
|
|
293
|
+
const end = tracking.current.timeEndLoading;
|
|
294
|
+
if (!tracking.current?.releaseLoading && start && end && end > start) {
|
|
350
295
|
context?.autoTracking?.({
|
|
351
296
|
...context,
|
|
352
297
|
screenName,
|
|
353
298
|
componentName: 'Screen',
|
|
354
299
|
state: 'loading',
|
|
355
|
-
duration:
|
|
300
|
+
duration: end - start,
|
|
356
301
|
loadingType: 'skeleton',
|
|
357
302
|
});
|
|
358
303
|
tracking.current.releaseLoading = true;
|
|
@@ -369,7 +314,7 @@ const StackScreen: React.FC<any> = props => {
|
|
|
369
314
|
*/
|
|
370
315
|
if (item?.componentName === 'Widget') {
|
|
371
316
|
const index = widgets.current.findIndex(
|
|
372
|
-
(
|
|
317
|
+
(element: any) => element.componentId === item.componentId,
|
|
373
318
|
);
|
|
374
319
|
const time = Date.now() - tracking.current.startTime;
|
|
375
320
|
if (index === -1) {
|
|
@@ -404,8 +349,8 @@ const StackScreen: React.FC<any> = props => {
|
|
|
404
349
|
/**
|
|
405
350
|
* support for debug last element
|
|
406
351
|
*/
|
|
407
|
-
if (
|
|
408
|
-
tracking.current.lastElement =
|
|
352
|
+
if (item?.componentName) {
|
|
353
|
+
tracking.current.lastElement = item;
|
|
409
354
|
}
|
|
410
355
|
|
|
411
356
|
/**
|
|
@@ -414,7 +359,7 @@ const StackScreen: React.FC<any> = props => {
|
|
|
414
359
|
if (item?.interaction) {
|
|
415
360
|
onScreenLoad();
|
|
416
361
|
onScreenInteraction();
|
|
417
|
-
onFirstInteraction(
|
|
362
|
+
onFirstInteraction(item?.action);
|
|
418
363
|
}
|
|
419
364
|
/**
|
|
420
365
|
* timeout for handle tracking screen
|
|
@@ -439,7 +384,6 @@ const StackScreen: React.FC<any> = props => {
|
|
|
439
384
|
/**
|
|
440
385
|
* tracking for loading screen
|
|
441
386
|
*/
|
|
442
|
-
clearTimeout(tracking.current.timeoutLoading);
|
|
443
387
|
if (!loading) {
|
|
444
388
|
tracking.current.timeEndLoading = Date.now();
|
|
445
389
|
}
|
|
@@ -447,12 +391,13 @@ const StackScreen: React.FC<any> = props => {
|
|
|
447
391
|
/**
|
|
448
392
|
* timeout for handle tracking screen
|
|
449
393
|
*/
|
|
394
|
+
clearTimeout(tracking.current.timeoutLoading);
|
|
450
395
|
tracking.current.timeoutLoading = setTimeout(() => {
|
|
451
396
|
onScreenLoading();
|
|
452
397
|
}, 2000);
|
|
453
398
|
},
|
|
454
|
-
onSetParams: (
|
|
455
|
-
tracking.current.params =
|
|
399
|
+
onSetParams: (item: ScreenTrackingParams) => {
|
|
400
|
+
tracking.current.params = item;
|
|
456
401
|
},
|
|
457
402
|
}}
|
|
458
403
|
>
|
|
@@ -2,7 +2,7 @@ import React, { useContext, useRef, useState } from 'react';
|
|
|
2
2
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
3
3
|
import Navigator from './Navigator';
|
|
4
4
|
import { WidgetContainerProps } from './types';
|
|
5
|
-
import { ApplicationContext, MiniAppContext } from '
|
|
5
|
+
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
6
6
|
import Localize from './Localize';
|
|
7
7
|
import { defaultTheme } from '../Consts';
|
|
8
8
|
import {
|
package/Application/index.ts
CHANGED
|
@@ -1,48 +1,29 @@
|
|
|
1
|
-
import { Platform } from 'react-native';
|
|
2
|
-
import { createContext } from 'react';
|
|
3
1
|
import { NavigationContainer } from './NavigationContainer';
|
|
4
2
|
import { WidgetContainer } from './WidgetContainer';
|
|
5
3
|
import Localize from './Localize';
|
|
6
4
|
import BottomTab from './BottomTab';
|
|
7
|
-
import { defaultContext } from '../Consts';
|
|
8
|
-
import {
|
|
9
|
-
HeaderAnimated,
|
|
10
|
-
HeaderBackground,
|
|
11
|
-
HeaderTitle,
|
|
12
|
-
NavigationButton,
|
|
13
|
-
} from './Components';
|
|
14
|
-
import { setAutomationID, useComponentId, exportHeaderTitle } from './utils';
|
|
15
|
-
import Navigation from './Navigation';
|
|
16
|
-
import Navigator from './Navigator';
|
|
17
5
|
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
export * from './Components/BackgroundImageView';
|
|
7
|
+
export * from './Components/HeaderAnimated';
|
|
8
|
+
export * from './Components/HeaderBackground';
|
|
9
|
+
export * from './Components/HeaderExtendHeader';
|
|
10
|
+
export * from './Components/HeaderLeft';
|
|
11
|
+
export * from './Components/HeaderRight';
|
|
12
|
+
export * from './Components/HeaderTitle';
|
|
13
|
+
export * from './Components/NavigationButton';
|
|
14
|
+
export * from './Components/SearchHeader';
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const SkeletonContext = createContext({ loading: false });
|
|
25
|
-
const TrackingScopeContext = createContext<{ scopeName?: string }>({
|
|
26
|
-
scopeName: undefined,
|
|
27
|
-
});
|
|
16
|
+
import { exportHeaderTitle, setAutomationID, useComponentId } from './utils';
|
|
17
|
+
import Navigation from './Navigation';
|
|
18
|
+
import Navigator from './Navigator';
|
|
28
19
|
|
|
29
20
|
export {
|
|
30
|
-
ApplicationContext,
|
|
31
|
-
MiniAppContext,
|
|
32
|
-
ScreenContext,
|
|
33
|
-
ComponentContext,
|
|
34
|
-
SkeletonContext,
|
|
35
21
|
NavigationContainer,
|
|
36
22
|
WidgetContainer,
|
|
37
23
|
Localize,
|
|
38
|
-
HeaderTitle,
|
|
39
|
-
HeaderBackground,
|
|
40
|
-
NavigationButton,
|
|
41
24
|
BottomTab,
|
|
42
|
-
HeaderAnimated,
|
|
43
25
|
setAutomationID,
|
|
44
26
|
useComponentId,
|
|
45
|
-
TrackingScopeContext,
|
|
46
27
|
Navigation,
|
|
47
28
|
Navigator,
|
|
48
29
|
exportHeaderTitle,
|
package/Application/types.ts
CHANGED
|
@@ -1,17 +1,54 @@
|
|
|
1
|
-
import {EventArg} from '@react-navigation/core';
|
|
2
|
-
import {StackNavigationOptions} from '@react-navigation/stack';
|
|
3
|
-
import React, {ReactNode} from 'react';
|
|
1
|
+
import { EventArg } from '@react-navigation/core';
|
|
2
|
+
import { StackNavigationOptions } from '@react-navigation/stack';
|
|
3
|
+
import React, { ReactNode } from 'react';
|
|
4
4
|
import {
|
|
5
5
|
Animated,
|
|
6
6
|
TouchableOpacityProps,
|
|
7
7
|
ViewProps,
|
|
8
8
|
ViewStyle,
|
|
9
9
|
} from 'react-native';
|
|
10
|
-
import {PopupNotifyProps} from '../Popup/types';
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
import { PopupNotifyProps } from '../Popup/types';
|
|
11
|
+
import { InputRef, InputSearchProps } from '../Input';
|
|
12
|
+
|
|
13
|
+
export type NavigationProps = {
|
|
14
|
+
context: any;
|
|
15
|
+
setOptions: (params: NavigationOptions) => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type NavigatorProps = {
|
|
19
|
+
ref?: any;
|
|
20
|
+
isReady?: any;
|
|
21
|
+
isWidget?: any;
|
|
22
|
+
maxApi?: any;
|
|
23
|
+
dismissData?: any;
|
|
24
|
+
push: (params: ScreenParams) => void;
|
|
25
|
+
replace: (params: ScreenParams) => void;
|
|
26
|
+
pop: (count?: number) => void;
|
|
27
|
+
present: (params: ScreenParams) => void;
|
|
28
|
+
showModal: (params: ModalParams, onError?: (error: string) => void) => void;
|
|
29
|
+
showBottomSheet: (
|
|
30
|
+
params: BottomSheetParams,
|
|
31
|
+
onError?: (error: string) => void,
|
|
32
|
+
) => void;
|
|
33
|
+
popToTop: () => void;
|
|
34
|
+
navigate: (name: string) => void;
|
|
35
|
+
reset: (params: ScreenParams) => void;
|
|
36
|
+
setDismissData: (data: any) => void;
|
|
37
|
+
setCurrentContext: (context: {
|
|
38
|
+
code?: string;
|
|
39
|
+
name?: { vi: string; en: string };
|
|
40
|
+
description?: { vi: string; en: string };
|
|
41
|
+
icon?: string;
|
|
42
|
+
}) => void;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type LocalizeProps = {
|
|
46
|
+
getCurrentLanguage: 'en' | 'vi';
|
|
47
|
+
getAssets: LocalizationObject;
|
|
48
|
+
translate: (key: string) => string;
|
|
49
|
+
translateData: (data: { vi: string; en: string }) => string;
|
|
50
|
+
addTranslations: (translations: LocalizationObject) => void;
|
|
51
|
+
};
|
|
15
52
|
|
|
16
53
|
export type Theme = {
|
|
17
54
|
dark: boolean;
|
|
@@ -72,9 +109,9 @@ export type Theme = {
|
|
|
72
109
|
export type Context = {
|
|
73
110
|
[key: string]: any;
|
|
74
111
|
theme: Theme;
|
|
75
|
-
navigator?:
|
|
112
|
+
navigator?: NavigatorProps;
|
|
76
113
|
showGrid?: boolean;
|
|
77
|
-
translate?: (data: string | {vi: string; en: string}) => string;
|
|
114
|
+
translate?: (data: string | { vi: string; en: string }) => string;
|
|
78
115
|
};
|
|
79
116
|
|
|
80
117
|
export type LocalizationObject = {
|
|
@@ -87,39 +124,47 @@ export type LocalizationObject = {
|
|
|
87
124
|
};
|
|
88
125
|
|
|
89
126
|
export type ToolGroup = {
|
|
90
|
-
title: {vi: string; en: string};
|
|
127
|
+
title: { vi: string; en: string };
|
|
91
128
|
items: Tool[];
|
|
92
129
|
};
|
|
93
130
|
|
|
94
131
|
export type Tool = {
|
|
95
132
|
icon: string;
|
|
96
|
-
name: {vi: string; en: string};
|
|
133
|
+
name: { vi: string; en: string };
|
|
97
134
|
key: string;
|
|
98
135
|
showBadge?: boolean;
|
|
99
136
|
showRightIcon?: boolean;
|
|
100
137
|
onPress: () => void;
|
|
101
138
|
};
|
|
102
139
|
|
|
140
|
+
export type FeaturesFlag = {
|
|
141
|
+
enableForceFoundationList?: boolean;
|
|
142
|
+
enableBottomTabAnimation?: boolean;
|
|
143
|
+
enableHapticBottomTab?: boolean;
|
|
144
|
+
enableHapticDialog?: boolean;
|
|
145
|
+
};
|
|
146
|
+
|
|
103
147
|
export type NavigationContainerProps = {
|
|
104
148
|
screen: React.ComponentType<NavigationScreenProps>;
|
|
105
149
|
options?: NavigationOptions;
|
|
106
150
|
theme?: Theme;
|
|
107
151
|
maxApi: any;
|
|
108
152
|
initialParams?: any;
|
|
109
|
-
localize:
|
|
153
|
+
localize: LocalizeProps;
|
|
154
|
+
features: FeaturesFlag;
|
|
110
155
|
};
|
|
111
156
|
|
|
112
157
|
export type WidgetContainerProps = {
|
|
113
158
|
widget: React.ComponentType<any>;
|
|
114
159
|
theme?: Theme;
|
|
115
160
|
maxApi: any;
|
|
116
|
-
localize:
|
|
161
|
+
localize: LocalizeProps;
|
|
117
162
|
};
|
|
118
163
|
|
|
119
164
|
export type NavigationScreenProps = {
|
|
120
165
|
[key: string]: any;
|
|
121
166
|
options?: NavigationOptions;
|
|
122
|
-
navigation:
|
|
167
|
+
navigation: NavigationProps;
|
|
123
168
|
};
|
|
124
169
|
|
|
125
170
|
export type ScreenParams = {
|
|
@@ -157,9 +202,12 @@ export type BottomSheetParams = {
|
|
|
157
202
|
useBottomInset?: boolean;
|
|
158
203
|
useKeyboardAvoidingView?: boolean;
|
|
159
204
|
keyboardVerticalOffset?: number;
|
|
160
|
-
useScrollOverflow?: boolean;
|
|
161
205
|
useDivider?: boolean;
|
|
162
206
|
footerComponent?: React.ReactNode;
|
|
207
|
+
leftOptions?: {
|
|
208
|
+
iconLeft?: string;
|
|
209
|
+
onPressIconLeft?: () => void;
|
|
210
|
+
};
|
|
163
211
|
};
|
|
164
212
|
|
|
165
213
|
export interface NavigationButtonProps extends TouchableOpacityProps {
|
|
@@ -263,14 +311,13 @@ export type BottomTabProps = {
|
|
|
263
311
|
nested?: boolean;
|
|
264
312
|
tabs: BottomTabItemProps[];
|
|
265
313
|
initialRouteName?: string;
|
|
266
|
-
navigation:
|
|
314
|
+
navigation: NavigationProps;
|
|
267
315
|
listeners?: {
|
|
268
316
|
tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
|
|
269
317
|
focus?: (e: EventArg<'focus', false, unknown>) => void;
|
|
270
318
|
blur?: (e: EventArg<'blur', false, unknown>) => void;
|
|
271
319
|
};
|
|
272
320
|
floatingButton?: FloatingButtonProps;
|
|
273
|
-
useAnimation?: boolean;
|
|
274
321
|
};
|
|
275
322
|
|
|
276
323
|
export type FloatingButtonProps = {
|
|
@@ -292,4 +339,5 @@ export interface SearchHeaderProps extends InputSearchProps {
|
|
|
292
339
|
headerRightWidth?: 0 | 74 | 110 | number;
|
|
293
340
|
leftPosition?: 12 | 48 | number;
|
|
294
341
|
renderButtons?: () => ReactNode;
|
|
342
|
+
hiddenBack?: boolean;
|
|
295
343
|
}
|
package/Application/utils.tsx
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import React, { useContext, useMemo } from 'react';
|
|
1
|
+
import React, { useContext, useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
StackNavigationOptions,
|
|
4
4
|
TransitionPresets,
|
|
5
5
|
} from '@react-navigation/stack';
|
|
6
|
-
import {
|
|
7
|
-
HeaderBackground,
|
|
8
|
-
HeaderLeft,
|
|
9
|
-
HeaderRight,
|
|
10
|
-
HeaderTitle,
|
|
11
|
-
TitleCustom,
|
|
12
|
-
} from './Components';
|
|
13
|
-
import { HeaderTitleProps, NavigationOptions } from './types';
|
|
6
|
+
import type { HeaderTitleProps, NavigationOptions } from './types';
|
|
14
7
|
import { Colors, Spacing } from '../Consts';
|
|
15
|
-
import { Animated, Platform } from 'react-native';
|
|
16
|
-
import {
|
|
8
|
+
import { Animated, AppState, Platform } from 'react-native';
|
|
9
|
+
import {
|
|
10
|
+
MiniAppContext,
|
|
11
|
+
ScreenContext,
|
|
12
|
+
TrackingScopeContext,
|
|
13
|
+
} from '../Context';
|
|
14
|
+
import { HeaderTitle, TitleCustom } from './Components/HeaderTitle';
|
|
15
|
+
import { HeaderBackground } from './Components/HeaderBackground';
|
|
16
|
+
import { HeaderLeft } from './Components/HeaderLeft';
|
|
17
|
+
import { HeaderRight } from './Components/HeaderRight';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* default options for stack screen
|
|
@@ -197,12 +198,34 @@ const useComponentId = (componentName: string, accessibilityLabel?: string) => {
|
|
|
197
198
|
return { componentId };
|
|
198
199
|
};
|
|
199
200
|
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
201
|
+
const useAppState = () => {
|
|
202
|
+
const isBackgroundToForeground = useRef(false);
|
|
203
|
+
const appState = useRef(AppState.currentState);
|
|
204
|
+
|
|
205
|
+
useEffect(() => {
|
|
206
|
+
const subscription = AppState.addEventListener('change', nextAppState => {
|
|
207
|
+
isBackgroundToForeground.current = !!(
|
|
208
|
+
appState.current.match(/inactive|background/) &&
|
|
209
|
+
nextAppState === 'active'
|
|
210
|
+
);
|
|
211
|
+
appState.current = nextAppState;
|
|
212
|
+
|
|
213
|
+
if (isBackgroundToForeground.current) {
|
|
214
|
+
setTimeout(() => {
|
|
215
|
+
isBackgroundToForeground.current = false;
|
|
216
|
+
}, 100);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
return () => {
|
|
221
|
+
subscription.remove();
|
|
222
|
+
};
|
|
223
|
+
}, []);
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
isBackgroundToForeground: isBackgroundToForeground.current,
|
|
227
|
+
appState: appState.current,
|
|
228
|
+
};
|
|
206
229
|
};
|
|
207
230
|
|
|
208
231
|
export {
|
|
@@ -212,4 +235,5 @@ export {
|
|
|
212
235
|
exportHeaderTitle,
|
|
213
236
|
setAutomationID,
|
|
214
237
|
useComponentId,
|
|
238
|
+
useAppState,
|
|
215
239
|
};
|
package/Assets/language.json
CHANGED
|
@@ -98,7 +98,9 @@
|
|
|
98
98
|
"tutorial": "Hướng dẫn sử dụng",
|
|
99
99
|
"question": "Câu hỏi thường gặp",
|
|
100
100
|
"support": "Trung tâm hỗ trợ",
|
|
101
|
-
"skip": "Bỏ qua"
|
|
101
|
+
"skip": "Bỏ qua",
|
|
102
|
+
"enterPhoneNumber": "Vui lòng nhập số điện thoại",
|
|
103
|
+
"invalidPhoneNumber": "Số điện thoại không đúng"
|
|
102
104
|
},
|
|
103
105
|
"en": {
|
|
104
106
|
"seeMore": "See more",
|
|
@@ -199,6 +201,8 @@
|
|
|
199
201
|
"question": "FAQ",
|
|
200
202
|
"support": "Support center",
|
|
201
203
|
"errorCode": "Error code: ",
|
|
202
|
-
"skip": "Skip"
|
|
204
|
+
"skip": "Skip",
|
|
205
|
+
"enterPhoneNumber": "Please enter your phone number",
|
|
206
|
+
"invalidPhoneNumber": "Invalid phone number"
|
|
203
207
|
}
|
|
204
208
|
}
|