@eohjsc/react-native-smart-city 0.3.27 → 0.3.30
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/index.js +2 -0
- package/package.json +1 -1
- package/src/Images/Common/device_icon.png +0 -0
- package/src/Images/DevMode/gateway.png +0 -0
- package/src/Images/DevMode/gateway@2x.png +0 -0
- package/src/Images/DevMode/gateway@3x.png +0 -0
- package/src/Images/DevMode/menu.png +0 -0
- package/src/Images/DevMode/menu@2x.png +0 -0
- package/src/Images/DevMode/menu@3x.png +0 -0
- package/src/Images/DevMode/search.png +0 -0
- package/src/Images/DevMode/search@2x.png +0 -0
- package/src/Images/DevMode/search@3x.png +0 -0
- package/src/Images/DevMode/smart.png +0 -0
- package/src/Images/DevMode/smart@2x.png +0 -0
- package/src/Images/DevMode/smart@3x.png +0 -0
- package/src/Images/DevMode/template.png +0 -0
- package/src/Images/DevMode/template@2x.png +0 -0
- package/src/Images/DevMode/template@3x.png +0 -0
- package/src/commons/Action/ItemQuickAction.js +1 -0
- package/src/commons/ActionGroup/CurtainButtonTemplate.js +1 -2
- package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +2 -0
- package/src/commons/ActionGroup/SliderRangeTemplate.js +22 -14
- package/src/commons/ActionTemplate/CurtainAction.js +60 -0
- package/src/commons/ActionTemplate/CurtainActionStyles.js +11 -0
- package/src/commons/ActionTemplate/OnOffSmartLockAction.js +44 -0
- package/src/commons/ActionTemplate/OnOffSmartLockActionStyles.js +11 -0
- package/src/commons/ActionTemplate/index.js +18 -0
- package/src/commons/BottomButtonView/index.js +1 -0
- package/src/commons/Button/index.js +2 -0
- package/src/commons/CameraDevice/index.js +1 -2
- package/src/commons/ConnectingProcess/DeviceItem/DeviceItem.js +20 -12
- package/src/commons/ConnectingProcess/DeviceItem/DeviceItemStyles.js +2 -0
- package/src/commons/ConnectingProcess/__test__/DeviceItem.test.js +1 -1
- package/src/commons/ConnectingProcess/index.js +11 -0
- package/src/commons/Dashboard/MyUnit/index.js +1 -1
- package/src/commons/DevMode/Label.js +10 -0
- package/src/commons/DevMode/Search.js +20 -0
- package/src/commons/DevMode/Styles/LabelStyles.js +8 -0
- package/src/commons/DevMode/Styles/SearchStyles.js +21 -0
- package/src/commons/DevMode/index.js +3 -0
- package/src/commons/Device/ItemAddNew/index.js +5 -1
- package/src/commons/Device/ItemDevice.js +12 -9
- package/src/commons/Form/TextInput.js +4 -0
- package/src/commons/HeaderAni/index.js +1 -0
- package/src/commons/MediaPlayerDetail/index.js +0 -20
- package/src/commons/MenuActionMore/index.js +11 -1
- package/src/commons/Modal/index.js +1 -2
- package/src/commons/NavBar/index.js +13 -1
- package/src/commons/Popover/index.js +7 -6
- package/src/commons/SubUnit/OneTap/ItemOneTap.js +4 -1
- package/src/commons/SubUnit/ShortDetail.js +1 -0
- package/src/commons/SummaryItem/index.js +2 -1
- package/src/commons/Tabbar/Styles/indexStyles.js +51 -0
- package/src/commons/Tabbar/index.js +110 -0
- package/src/commons/Unit/HeaderUnit/index.js +2 -0
- package/src/commons/Unit/SharedUnit.js +1 -0
- package/src/commons/WrapParallaxScrollView/index.js +16 -2
- package/src/configs/Colors.js +4 -0
- package/src/configs/Constants.js +16 -0
- package/src/configs/Images.js +6 -0
- package/src/hooks/Common/useDevicesStatus.js +1 -1
- package/src/hooks/IoT/useValueEvaluation.js +10 -19
- package/src/iot/RemoteControl/GoogleHome.js +6 -6
- package/src/navigations/GatewayStack.js +23 -0
- package/src/navigations/Main.js +144 -0
- package/src/navigations/SmartStack.js +23 -0
- package/src/navigations/TemplateStack.js +23 -0
- package/src/navigations/UnitStack.js +5 -8
- package/src/screens/AddNewAction/Device/index.js +5 -1
- package/src/screens/AddNewAction/SelectAction.js +36 -15
- package/src/screens/AddNewAction/__test__/SelectAction.test.js +1 -0
- package/src/screens/AddNewAutoSmart/index.js +2 -0
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +13 -1
- package/src/screens/AllCamera/__test__/index.test.js +1 -8
- package/src/screens/AllCamera/index.js +0 -13
- package/src/screens/Device/components/SensorConnectStatusViewHeader.js +10 -11
- package/src/screens/Device/detail.js +35 -16
- package/src/screens/Device/hooks/__test__/useEmergencyButton.test.js +37 -0
- package/src/screens/Device/hooks/useFavoriteDevice.js +4 -2
- package/src/screens/Drawer/Drawer.test.js +24 -0
- package/src/screens/Drawer/index.js +198 -0
- package/src/screens/EmergencyContacts/EmergencyContactsAddNew.js +3 -3
- package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +4 -7
- package/src/screens/Gateway/__test__/index.test.js +16 -0
- package/src/screens/Gateway/index.js +8 -0
- package/src/screens/Notification/__test__/NotificationItem.test.js +74 -104
- package/src/screens/Notification/components/NotificationItem.js +40 -239
- package/src/screens/ScriptDetail/__test__/index.test.js +40 -1
- package/src/screens/ScriptDetail/index.js +2 -1
- package/src/screens/Sharing/Components/SensorItem.js +4 -1
- package/src/screens/Sharing/Components/Styles/SensorItemStyles.js +4 -0
- package/src/screens/Sharing/Components/Styles/TitleCheckBoxStyles.js +4 -0
- package/src/screens/Sharing/Components/TitleCheckBox.js +17 -8
- package/src/screens/Smart/__test__/index.test.js +16 -0
- package/src/screens/Smart/index.js +8 -0
- package/src/screens/SubUnit/AddSubUnit.js +1 -1
- package/src/screens/SubUnit/EditSubUnit.js +4 -1
- package/src/screens/Template/Styles/indexStyles.js +51 -0
- package/src/screens/Template/__test__/index.test.js +16 -0
- package/src/screens/Template/index.js +84 -0
- package/src/screens/Unit/Detail.js +16 -28
- package/src/screens/Unit/MoreMenu.js +16 -1
- package/src/screens/Unit/SelectAddToFavorites.js +11 -1
- package/src/screens/Unit/Station/__test__/index.test.js +41 -0
- package/src/screens/Unit/Station/index.js +0 -1
- package/src/screens/Unit/Summaries.js +6 -1
- package/src/screens/Unit/__test__/Detail.test.js +1 -5
- package/src/screens/Unit/components/AutomateScript/index.js +5 -2
- package/src/utils/Converter/__test__/timer.test.js +99 -0
- package/src/utils/Functions/Search.js +17 -0
- package/src/utils/Functions/ShortEmail.js +4 -0
- package/src/utils/Functions/__test__/Search.test.js +6 -0
- package/src/utils/Functions/__test__/ShortEmail.test.js +6 -0
- package/src/utils/I18n/translations/en.json +37 -42
- package/src/utils/I18n/translations/vi.json +37 -44
- package/src/utils/Route/index.js +6 -0
- package/src/commons/Modal/ModalFullVideo.js +0 -48
- package/src/commons/Modal/Styles/ModalFullVideoStyles.js +0 -26
|
@@ -27,6 +27,8 @@ const _TextInput = ({
|
|
|
27
27
|
selectionColor,
|
|
28
28
|
borderBottomOnly,
|
|
29
29
|
testID,
|
|
30
|
+
selection,
|
|
31
|
+
onSelectionChange,
|
|
30
32
|
}) => {
|
|
31
33
|
const errorStyle = !!errorText && styles.errorWrap;
|
|
32
34
|
return (
|
|
@@ -64,6 +66,8 @@ const _TextInput = ({
|
|
|
64
66
|
multiline={multiline}
|
|
65
67
|
selectionColor={selectionColor}
|
|
66
68
|
{...(value ? { value } : {})}
|
|
69
|
+
selection={selection}
|
|
70
|
+
onSelectionChange={onSelectionChange}
|
|
67
71
|
/>
|
|
68
72
|
{extraText && extraText}
|
|
69
73
|
{!!errorText && <Text style={styles.errorText}>{errorText}</Text>}
|
|
@@ -7,7 +7,6 @@ import React, {
|
|
|
7
7
|
useMemo,
|
|
8
8
|
} from 'react';
|
|
9
9
|
import {
|
|
10
|
-
Image,
|
|
11
10
|
View,
|
|
12
11
|
StyleSheet,
|
|
13
12
|
Text,
|
|
@@ -34,10 +33,8 @@ const MediaPlayerDetail = ({
|
|
|
34
33
|
style,
|
|
35
34
|
wrapStyles,
|
|
36
35
|
amount,
|
|
37
|
-
handleFullScreen,
|
|
38
36
|
isPaused = true,
|
|
39
37
|
goToPlayBack,
|
|
40
|
-
isShowFullScreenIcon = false,
|
|
41
38
|
width,
|
|
42
39
|
height,
|
|
43
40
|
}) => {
|
|
@@ -61,11 +58,6 @@ const MediaPlayerDetail = ({
|
|
|
61
58
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
62
59
|
}, [paused]);
|
|
63
60
|
|
|
64
|
-
const onFullScreen = useCallback(() => {
|
|
65
|
-
handleFullScreen && handleFullScreen({ uri, cameraName, thumbnail });
|
|
66
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
67
|
-
}, []);
|
|
68
|
-
|
|
69
61
|
const getWidthHeight = useCallback(() => {
|
|
70
62
|
let newWidth = 0,
|
|
71
63
|
newHeight = 0;
|
|
@@ -207,18 +199,6 @@ const MediaPlayerDetail = ({
|
|
|
207
199
|
{cameraName}
|
|
208
200
|
</Text>
|
|
209
201
|
)}
|
|
210
|
-
{isShowFullScreenIcon && (
|
|
211
|
-
<TouchableOpacity
|
|
212
|
-
onPress={onFullScreen}
|
|
213
|
-
style={[
|
|
214
|
-
styles.iconFullScreen,
|
|
215
|
-
(amount === 4 || amount === 6) && styles.iconFullScreen2,
|
|
216
|
-
]}
|
|
217
|
-
testID={TESTID.SUB_UNIT_FULL_CAMERA}
|
|
218
|
-
>
|
|
219
|
-
<Image source={Images.fullscreen} />
|
|
220
|
-
</TouchableOpacity>
|
|
221
|
-
)}
|
|
222
202
|
</View>
|
|
223
203
|
);
|
|
224
204
|
};
|
|
@@ -17,6 +17,9 @@ const MenuActionMore = memo(
|
|
|
17
17
|
onItemClick,
|
|
18
18
|
wrapStyle,
|
|
19
19
|
isTextCenter = true,
|
|
20
|
+
idLabelPopover,
|
|
21
|
+
idLabelScrollView,
|
|
22
|
+
idLabelItem = TESTID.SUB_UNIT_NAME,
|
|
20
23
|
}) => {
|
|
21
24
|
const [isDisable, setIsDisable] = useState(false);
|
|
22
25
|
const onPress = useCallback(
|
|
@@ -47,8 +50,12 @@ const MenuActionMore = memo(
|
|
|
47
50
|
onRequestClose={hideMore}
|
|
48
51
|
isVisible={isVisible}
|
|
49
52
|
arrowStyle={styles.wrap}
|
|
53
|
+
accessibilityLabel={idLabelPopover}
|
|
50
54
|
>
|
|
51
|
-
<ScrollView
|
|
55
|
+
<ScrollView
|
|
56
|
+
scrollIndicatorInsets={{ right: 1 }}
|
|
57
|
+
accessibilityLabel={idLabelScrollView}
|
|
58
|
+
>
|
|
52
59
|
{listMenuItem.map((item, index) => {
|
|
53
60
|
return (
|
|
54
61
|
<TouchableOpacity
|
|
@@ -59,6 +66,9 @@ const MenuActionMore = memo(
|
|
|
59
66
|
onPress={onPress(item, index)}
|
|
60
67
|
key={index}
|
|
61
68
|
testID={TESTID.TOUCHABLE_ACTION_ADD_MORE}
|
|
69
|
+
accessibilityLabel={`${idLabelItem}-${
|
|
70
|
+
(item?.route ? item?.id : item?.station?.id) || index
|
|
71
|
+
}`}
|
|
62
72
|
disabled={isDisable}
|
|
63
73
|
>
|
|
64
74
|
<Text style={styles.modalHeaderText}>{item.text}</Text>
|
|
@@ -10,7 +10,16 @@ import Station from '../../screens/Unit/Station';
|
|
|
10
10
|
import MenuActionMore from '../MenuActionMore';
|
|
11
11
|
|
|
12
12
|
const NavBar = memo(
|
|
13
|
-
({
|
|
13
|
+
({
|
|
14
|
+
listMenuItem,
|
|
15
|
+
listStation,
|
|
16
|
+
onSnapToItem,
|
|
17
|
+
indexStation,
|
|
18
|
+
style,
|
|
19
|
+
idLabelScrollView,
|
|
20
|
+
idLabelItem,
|
|
21
|
+
idLabelIconBars,
|
|
22
|
+
}) => {
|
|
14
23
|
const { childRef, showingPopover, showPopoverWithRef, hidePopover } =
|
|
15
24
|
usePopover();
|
|
16
25
|
const refMenuAction = useRef();
|
|
@@ -31,6 +40,7 @@ const NavBar = memo(
|
|
|
31
40
|
onPress={handleShowMenuAction}
|
|
32
41
|
ref={refMenuAction}
|
|
33
42
|
testID={TESTID.NAVBAR_ICON_BARS}
|
|
43
|
+
accessibilityLabel={idLabelIconBars}
|
|
34
44
|
>
|
|
35
45
|
<Icon name={'bars'} size={19} color={Colors.Black} />
|
|
36
46
|
</TouchableOpacity>
|
|
@@ -44,6 +54,8 @@ const NavBar = memo(
|
|
|
44
54
|
isTextCenter={false}
|
|
45
55
|
testID={TESTID.NAVBAR_MENU_ACTION_MORE}
|
|
46
56
|
wrapStyle={styles.wrapStyle}
|
|
57
|
+
idLabelScrollView={idLabelScrollView}
|
|
58
|
+
idLabelItem={idLabelItem}
|
|
47
59
|
/>
|
|
48
60
|
</>
|
|
49
61
|
);
|
|
@@ -3,22 +3,23 @@ import Popover from 'react-native-popover-view';
|
|
|
3
3
|
import { SCContext } from '../../context';
|
|
4
4
|
import { Action } from '../../context/actionType';
|
|
5
5
|
|
|
6
|
-
const PopoverComponent = (
|
|
6
|
+
const PopoverComponent = ({ onRequestClose, ...restProps }) => {
|
|
7
7
|
const { setAction } = useContext(SCContext);
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const _onRequestClose = () => {
|
|
10
10
|
setAction(Action.SET_POPOVER_ANIMATING, true);
|
|
11
|
+
onRequestClose && onRequestClose();
|
|
11
12
|
};
|
|
12
13
|
|
|
13
|
-
const
|
|
14
|
+
const _onCloseComplete = () => {
|
|
14
15
|
setAction(Action.SET_POPOVER_ANIMATING, false);
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
return (
|
|
18
19
|
<Popover
|
|
19
|
-
|
|
20
|
-
onCloseComplete={
|
|
21
|
-
{...
|
|
20
|
+
onRequestClose={_onRequestClose}
|
|
21
|
+
onCloseComplete={_onCloseComplete}
|
|
22
|
+
{...restProps}
|
|
22
23
|
/>
|
|
23
24
|
);
|
|
24
25
|
};
|
|
@@ -103,7 +103,10 @@ const ItemOneTap = memo(
|
|
|
103
103
|
? timeDifference(new Date(), moment(activate_at), true)
|
|
104
104
|
: null;
|
|
105
105
|
return (
|
|
106
|
-
<TouchableWithoutFeedback
|
|
106
|
+
<TouchableWithoutFeedback
|
|
107
|
+
onPress={onPressItem || goToDetail}
|
|
108
|
+
accessibilityLabel={`${TESTID.AUTOMATE_SCRIPT_NAME}-${id}`}
|
|
109
|
+
>
|
|
107
110
|
<View style={[styles.container, wrapSyles]}>
|
|
108
111
|
<View style={styles.boxIcon}>
|
|
109
112
|
{displayIcon()}
|
|
@@ -9,6 +9,7 @@ import Temperature from '../../../assets/images/Temperature.svg';
|
|
|
9
9
|
import UVIndex from '../../../assets/images/UVIndex.svg';
|
|
10
10
|
import WaterQuality from '../../../assets/images/WaterQuality.svg';
|
|
11
11
|
import Device from '../../../assets/images/Device.svg';
|
|
12
|
+
import { TESTID } from '../../configs/Constants';
|
|
12
13
|
|
|
13
14
|
const SummaryItem = memo(({ item, goToSummary }) => {
|
|
14
15
|
const Icon = (() => {
|
|
@@ -29,11 +30,11 @@ const SummaryItem = memo(({ item, goToSummary }) => {
|
|
|
29
30
|
return Device; /* istanbul ignore next */
|
|
30
31
|
}
|
|
31
32
|
})();
|
|
32
|
-
|
|
33
33
|
return (
|
|
34
34
|
<TouchableOpacity
|
|
35
35
|
onPress={() => goToSummary(item)}
|
|
36
36
|
style={styles.wrapSummaryItem}
|
|
37
|
+
accessibilityLabel={`${TESTID.UNIT_DETAIL_UNIT_SUMMARY_ITEM}-${item?.id}`}
|
|
37
38
|
>
|
|
38
39
|
<View style={styles.summaryItem}>
|
|
39
40
|
<Icon />
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { isIphoneX } from 'react-native-iphone-x-helper';
|
|
3
|
+
import { Colors } from '../../../configs';
|
|
4
|
+
|
|
5
|
+
const widthBadge = 20;
|
|
6
|
+
export default StyleSheet.create({
|
|
7
|
+
wrap: {
|
|
8
|
+
flexDirection: 'row',
|
|
9
|
+
height: 70,
|
|
10
|
+
backgroundColor: Colors.White,
|
|
11
|
+
paddingHorizontal: 10,
|
|
12
|
+
borderTopWidth: 1,
|
|
13
|
+
borderColor: Colors.Gray4,
|
|
14
|
+
},
|
|
15
|
+
label: {
|
|
16
|
+
textAlign: 'center',
|
|
17
|
+
fontSize: 12,
|
|
18
|
+
marginTop: 10,
|
|
19
|
+
marginBottom: isIphoneX() ? 10 : 0,
|
|
20
|
+
},
|
|
21
|
+
wrapTab: {
|
|
22
|
+
flex: 1,
|
|
23
|
+
justifyContent: 'center',
|
|
24
|
+
alignItems: 'center',
|
|
25
|
+
},
|
|
26
|
+
icon: {
|
|
27
|
+
marginBottom: -8,
|
|
28
|
+
},
|
|
29
|
+
wrapIcon: {
|
|
30
|
+
position: 'relative',
|
|
31
|
+
},
|
|
32
|
+
badgeCount: {
|
|
33
|
+
width: widthBadge,
|
|
34
|
+
height: 20,
|
|
35
|
+
flexDirection: 'row',
|
|
36
|
+
justifyContent: 'center',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
backgroundColor: Colors.Red,
|
|
39
|
+
borderRadius: widthBadge / 2,
|
|
40
|
+
position: 'absolute',
|
|
41
|
+
top: -8,
|
|
42
|
+
right: -8,
|
|
43
|
+
},
|
|
44
|
+
txtBadge: {
|
|
45
|
+
color: Colors.White,
|
|
46
|
+
fontSize: 12,
|
|
47
|
+
},
|
|
48
|
+
iconActive: {
|
|
49
|
+
tintColor: Colors.Primary,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import React, { memo, useEffect } from 'react';
|
|
2
|
+
import { Animated, View, Text, TouchableOpacity, Image } from 'react-native';
|
|
3
|
+
import Routes from '../../utils/Route';
|
|
4
|
+
import { Colors } from '../../configs/Colors';
|
|
5
|
+
import { Constants } from '../../configs/Constants';
|
|
6
|
+
import styles from './Styles/indexStyles';
|
|
7
|
+
import { Images } from '../../configs';
|
|
8
|
+
|
|
9
|
+
export const getTabBarIcon = (routeName) => {
|
|
10
|
+
switch (routeName) {
|
|
11
|
+
case Routes.TemplateStack:
|
|
12
|
+
return Images.template;
|
|
13
|
+
case Routes.GatewayStack:
|
|
14
|
+
return Images.gateway;
|
|
15
|
+
case Routes.SmartStack:
|
|
16
|
+
return Images.smart;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const getWidth = () => (Constants.width - 12) / 3;
|
|
21
|
+
|
|
22
|
+
const TabBarItem = ({
|
|
23
|
+
descriptor,
|
|
24
|
+
route,
|
|
25
|
+
index,
|
|
26
|
+
isFocused,
|
|
27
|
+
navigation,
|
|
28
|
+
notificationNumber,
|
|
29
|
+
updateLastSeen,
|
|
30
|
+
}) => {
|
|
31
|
+
const { options } = descriptor;
|
|
32
|
+
const label =
|
|
33
|
+
options.tabBarLabel !== undefined
|
|
34
|
+
? options.tabBarLabel
|
|
35
|
+
: options.title !== undefined
|
|
36
|
+
? options.title
|
|
37
|
+
: route.name;
|
|
38
|
+
const color = isFocused ? Colors.Primary : Colors.Black;
|
|
39
|
+
|
|
40
|
+
const onPress = () => {
|
|
41
|
+
const event = navigation.emit({
|
|
42
|
+
type: 'tabPress',
|
|
43
|
+
target: route.key,
|
|
44
|
+
canPreventDefault: true,
|
|
45
|
+
});
|
|
46
|
+
if (!isFocused && !event.defaultPrevented) {
|
|
47
|
+
navigation.navigate({
|
|
48
|
+
name: route.name,
|
|
49
|
+
merge: true,
|
|
50
|
+
params: { isMainSource: options.isMainSource },
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (isFocused) {
|
|
57
|
+
Animated.spring(options.tabOffSetValue, {
|
|
58
|
+
toValue: getWidth() * index,
|
|
59
|
+
useNativeDriver: true,
|
|
60
|
+
}).start();
|
|
61
|
+
}
|
|
62
|
+
}, [isFocused, index, options.tabOffSetValue]);
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (isFocused) {
|
|
66
|
+
if (route.name === Routes.NotificationStack) {
|
|
67
|
+
updateLastSeen && updateLastSeen();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}, [isFocused, route.name, updateLastSeen]);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<TouchableOpacity onPress={onPress} style={styles.wrapTab}>
|
|
74
|
+
<View style={styles.wrapIcon}>
|
|
75
|
+
<Image
|
|
76
|
+
style={[styles.icon, isFocused && styles.iconActive]}
|
|
77
|
+
source={getTabBarIcon(route.name)}
|
|
78
|
+
/>
|
|
79
|
+
{route.name === Routes.NotificationStack && notificationNumber > 0 && (
|
|
80
|
+
<View style={styles.badgeCount}>
|
|
81
|
+
<Text style={styles.txtBadge}>
|
|
82
|
+
{notificationNumber < 9 ? notificationNumber : '9+'}
|
|
83
|
+
</Text>
|
|
84
|
+
</View>
|
|
85
|
+
)}
|
|
86
|
+
</View>
|
|
87
|
+
|
|
88
|
+
<Text style={[styles.label, { color }]}>{label}</Text>
|
|
89
|
+
</TouchableOpacity>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const TabBar = ({ state, descriptors, navigation }) => {
|
|
94
|
+
return (
|
|
95
|
+
<View style={styles.wrap}>
|
|
96
|
+
{state.routes.map((route, index) => (
|
|
97
|
+
<TabBarItem
|
|
98
|
+
key={index}
|
|
99
|
+
descriptor={descriptors[route.key]}
|
|
100
|
+
route={route}
|
|
101
|
+
index={index}
|
|
102
|
+
isFocused={state.index === index}
|
|
103
|
+
navigation={navigation}
|
|
104
|
+
/>
|
|
105
|
+
))}
|
|
106
|
+
</View>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export default memo(TabBar);
|
|
@@ -19,6 +19,7 @@ const HeaderUnit = memo(
|
|
|
19
19
|
hideRightPlus,
|
|
20
20
|
styleBoxTitle,
|
|
21
21
|
bottomBorder,
|
|
22
|
+
idButtonMore,
|
|
22
23
|
}) => {
|
|
23
24
|
const { goBack } = useNavigation();
|
|
24
25
|
const buttonMoreRef = useRef(null);
|
|
@@ -80,6 +81,7 @@ const HeaderUnit = memo(
|
|
|
80
81
|
style={styles.btnMore}
|
|
81
82
|
onPress={onPressMore}
|
|
82
83
|
ref={buttonMoreRef}
|
|
84
|
+
accessibilityLabel={idButtonMore}
|
|
83
85
|
>
|
|
84
86
|
<Icon
|
|
85
87
|
name={'more'}
|
|
@@ -21,6 +21,8 @@ const WrapParallaxScrollView = ({
|
|
|
21
21
|
hideRight,
|
|
22
22
|
hideRightPlus,
|
|
23
23
|
contentBackground,
|
|
24
|
+
accessibilityLabel,
|
|
25
|
+
idButtonMore,
|
|
24
26
|
}) => {
|
|
25
27
|
const renderForeground = useCallback(
|
|
26
28
|
() => (
|
|
@@ -32,6 +34,7 @@ const WrapParallaxScrollView = ({
|
|
|
32
34
|
onMore={onMore}
|
|
33
35
|
hideRight={hideRight}
|
|
34
36
|
hideRightPlus={hideRightPlus}
|
|
37
|
+
idButtonMore={idButtonMore}
|
|
35
38
|
/>
|
|
36
39
|
<Text semibold style={styles.nameUnit}>
|
|
37
40
|
{title}
|
|
@@ -39,7 +42,16 @@ const WrapParallaxScrollView = ({
|
|
|
39
42
|
{contentBackground}
|
|
40
43
|
</View>
|
|
41
44
|
),
|
|
42
|
-
[
|
|
45
|
+
[
|
|
46
|
+
onBack,
|
|
47
|
+
onAdd,
|
|
48
|
+
onMore,
|
|
49
|
+
hideRight,
|
|
50
|
+
hideRightPlus,
|
|
51
|
+
idButtonMore,
|
|
52
|
+
title,
|
|
53
|
+
contentBackground,
|
|
54
|
+
]
|
|
43
55
|
);
|
|
44
56
|
const renderBackground = useCallback(
|
|
45
57
|
() => (
|
|
@@ -68,10 +80,11 @@ const WrapParallaxScrollView = ({
|
|
|
68
80
|
onMore={onMore}
|
|
69
81
|
hideRight={hideRight}
|
|
70
82
|
hideRightPlus={hideRightPlus}
|
|
83
|
+
idButtonMore={idButtonMore}
|
|
71
84
|
/>
|
|
72
85
|
</View>
|
|
73
86
|
),
|
|
74
|
-
[title, onBack, onAdd, onMore, hideRight, hideRightPlus]
|
|
87
|
+
[title, onBack, onAdd, onMore, hideRight, hideRightPlus, idButtonMore]
|
|
75
88
|
);
|
|
76
89
|
return (
|
|
77
90
|
<ParallaxScrollView
|
|
@@ -83,6 +96,7 @@ const WrapParallaxScrollView = ({
|
|
|
83
96
|
backgroundColor={Colors.White}
|
|
84
97
|
refreshControl={refreshControl}
|
|
85
98
|
showsVerticalScrollIndicator={false}
|
|
99
|
+
accessibilityLabel={accessibilityLabel}
|
|
86
100
|
>
|
|
87
101
|
{children}
|
|
88
102
|
</ParallaxScrollView>
|
package/src/configs/Colors.js
CHANGED
package/src/configs/Constants.js
CHANGED
|
@@ -313,11 +313,13 @@ export const TESTID = {
|
|
|
313
313
|
SUB_UNIT_GO_DETAIL: 'SUB_UNIT_GO_DETAIL',
|
|
314
314
|
VIEW_SUB_UNIT_AUTOMATE: 'VIEW_SUB_UNIT_AUTOMATE',
|
|
315
315
|
SUB_UNIT_NAME: 'SUB_UNIT_NAME',
|
|
316
|
+
SUB_UNIT_FAVORITES: 'SUB_UNIT_FAVORITES',
|
|
316
317
|
ANIMATED_SCROLL: 'ANIMATED_SCROLL',
|
|
317
318
|
ADD_SUB_UNIT: 'ADD_SUB_UNIT',
|
|
318
319
|
|
|
319
320
|
// NavBar
|
|
320
321
|
NAVBAR_ICON_BARS: 'NAVBAR_ICON_BARS',
|
|
322
|
+
NAVBAR_ICON_BARS_ADD_FAVORITES: 'NAVBAR_ICON_BARS_ADD_FAVORITES',
|
|
321
323
|
NAVBAR_MENU_ACTION_MORE: 'NAVBAR_MENU_ACTION_MORE',
|
|
322
324
|
NAVBAR_ON_SNAP_ITEM: 'NAVBAR_ON_SNAP_ITEM',
|
|
323
325
|
|
|
@@ -400,6 +402,11 @@ export const TESTID = {
|
|
|
400
402
|
//Unit Detail
|
|
401
403
|
UNIT_DETAIL_STATION_LIST: 'UNIT_DETAIL_STATION_LIST',
|
|
402
404
|
UNIT_DETAIL_UNIT_SUMMARY_VIEW: 'UNIT_DETAIL_UNIT_SUMMARY_VIEW',
|
|
405
|
+
UNIT_DETAIL_UNIT_SUMMARY_ITEM: 'UNIT_DETAIL_UNIT_SUMMARY_ITEM',
|
|
406
|
+
UNIT_DETAIL_PARALLAX_SCROLLVIEW: 'UNIT_DETAIL_PARALLAX_SCROLLVIEW',
|
|
407
|
+
UNIT_DETAIL_PARALLAX_BUTTON_MORE: 'UNIT_DETAIL_PARALLAX_BUTTON_MORE',
|
|
408
|
+
UNIT_DETAIL_POPUP_MORE: 'UNIT_DETAIL_POPUP_MORE',
|
|
409
|
+
UNIT_DETAIL_POPUP_MORE_ITEM: 'UNIT_DETAIL_POPUP_MORE_ITEM',
|
|
403
410
|
|
|
404
411
|
ON_CHECK_SPOT_NUMBER: 'ON_CHECK_SPOT_NUMBER',
|
|
405
412
|
ON_BOOK_NOW: 'ON_BOOK_NOW',
|
|
@@ -422,6 +429,7 @@ export const TESTID = {
|
|
|
422
429
|
|
|
423
430
|
// Automate
|
|
424
431
|
AUTOMATE_SCRIPT_ACTION: 'AUTOMATE_SCRIPT_ACTION',
|
|
432
|
+
AUTOMATE_SCRIPT_NAME: 'AUTOMATE_SCRIPT_NAME',
|
|
425
433
|
NAME_YOUR_BUTTON: 'NAME_YOUR_BUTTON',
|
|
426
434
|
BUTTON_ACTIVATE_ONE_TAP: 'BUTTON_ACTIVATE_ONE_TAP',
|
|
427
435
|
BUTTON_EDIT_SCRIPT_ACTION: 'BUTTON_EDIT_SCRIPT_ACTION',
|
|
@@ -439,6 +447,7 @@ export const TESTID = {
|
|
|
439
447
|
|
|
440
448
|
// Header Device
|
|
441
449
|
HEADER_DEVICE_BUTTON_STAR: 'HEADER_DEVICE_BUTTON_STAR',
|
|
450
|
+
HEADER_SCRIPT_DETAIL_BUTTON_STAR: 'HEADER_SCRIPT_DETAIL_BUTTON_STAR',
|
|
442
451
|
HEADER_DEVICE_BUTTON_MORE: 'HEADER_DEVICE_BUTTON_MORE',
|
|
443
452
|
|
|
444
453
|
// EMERGENCY BUTTON
|
|
@@ -661,6 +670,13 @@ export const TESTID = {
|
|
|
661
670
|
ADD_NEW_DEVICE_ADD: 'ADD_NEW_DEVICE_ADD',
|
|
662
671
|
ADD_NEW_DEVICE_THEN_SELECT: 'ADD_NEW_DEVICE_THEN_SELECT',
|
|
663
672
|
|
|
673
|
+
// Add Favorites
|
|
674
|
+
TOUCH_ADD_NEW_FAVORITES: 'TOUCH_ADD_NEW_FAVORITES',
|
|
675
|
+
LIST_FAVORITES: 'LIST_FAVORITES',
|
|
676
|
+
TOUCHABLE_ACTION_ADD_ITEM_FAVORITE: 'TOUCHABLE_ACTION_ADD_ITEM_FAVORITE',
|
|
677
|
+
TOUCHABLE_ACTION_ADD_ITEM_AUTOMATE_FAVORITE:
|
|
678
|
+
'TOUCHABLE_ACTION_ADD_ITEM_AUTOMATE_FAVORITE',
|
|
679
|
+
|
|
664
680
|
// Setup gateway wifi
|
|
665
681
|
SETUP_GATEWAY_WIFI_TITLE: 'SETUP_GATEWAY_WIFI_TITLE',
|
|
666
682
|
SETUP_GATEWAY_WIFI_PLEASE_SELECT_A_WIFI: 'SETUP_GATEWAY_PLEASE_SELECT_A_WIFI',
|
package/src/configs/Images.js
CHANGED
|
@@ -13,4 +13,10 @@ export default {
|
|
|
13
13
|
shadowButton: require('../Images/Common/shadowButton.png'),
|
|
14
14
|
eye: require('../Images/Common/eye.png'),
|
|
15
15
|
eyeClosed: require('../Images/Common/eye-closed.png'),
|
|
16
|
+
deviceIcon: require('../Images/Common/device_icon.png'),
|
|
17
|
+
template: require('../Images/DevMode/template.png'),
|
|
18
|
+
smart: require('../Images/DevMode/smart.png'),
|
|
19
|
+
gateway: require('../Images/DevMode/gateway.png'),
|
|
20
|
+
menu: require('../Images/DevMode/menu.png'),
|
|
21
|
+
search: require('../Images/DevMode/search.png'),
|
|
16
22
|
};
|
|
@@ -27,7 +27,7 @@ const useDevicesStatus = (unit, devices) => {
|
|
|
27
27
|
if (success) {
|
|
28
28
|
setAction(Action.SET_DEVICES_STATUS, data);
|
|
29
29
|
}
|
|
30
|
-
timeoutId = setTimeout(() => getDevicesStatus(_unit, _devices),
|
|
30
|
+
timeoutId = setTimeout(() => getDevicesStatus(_unit, _devices), 10000);
|
|
31
31
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
32
32
|
}, []);
|
|
33
33
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useContext, useEffect
|
|
1
|
+
import { useCallback, useContext, useEffect } from 'react';
|
|
2
2
|
import { API } from '../../configs';
|
|
3
3
|
import { SCContext, useSCContextSelector } from '../../context';
|
|
4
4
|
import { Action } from '../../context/actionType';
|
|
@@ -6,14 +6,15 @@ import { axiosGet } from '../../utils/Apis/axios';
|
|
|
6
6
|
|
|
7
7
|
const useValueEvaluations = (unitId) => {
|
|
8
8
|
const { setAction } = useContext(SCContext);
|
|
9
|
-
const
|
|
9
|
+
const fetchedValueEvaluationUnits = useSCContextSelector((state) => {
|
|
10
|
+
return state.fetchedValueEvaluationUnits || [];
|
|
11
|
+
});
|
|
10
12
|
|
|
11
13
|
const fetchConfigValueEvaluations = useCallback(
|
|
12
14
|
async (page = 1) => {
|
|
13
|
-
if (!unitId) {
|
|
15
|
+
if (!unitId || fetchedValueEvaluationUnits.indexOf(unitId) !== -1) {
|
|
14
16
|
return;
|
|
15
17
|
}
|
|
16
|
-
setFetching(true);
|
|
17
18
|
const params = new URLSearchParams();
|
|
18
19
|
params.append('config__end_device__station__unit', unitId);
|
|
19
20
|
params.append('page', page);
|
|
@@ -34,25 +35,15 @@ const useValueEvaluations = (unitId) => {
|
|
|
34
35
|
data: [],
|
|
35
36
|
});
|
|
36
37
|
}
|
|
37
|
-
setFetching(false);
|
|
38
38
|
},
|
|
39
|
-
|
|
39
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
|
+
[unitId, fetchedValueEvaluationUnits]
|
|
40
41
|
);
|
|
41
42
|
|
|
42
|
-
const fetchedValueEvaluationUnits = useSCContextSelector((state) => {
|
|
43
|
-
return state.fetchedValueEvaluationUnits || [];
|
|
44
|
-
});
|
|
45
|
-
|
|
46
43
|
useEffect(() => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}, [
|
|
51
|
-
unitId,
|
|
52
|
-
fetching,
|
|
53
|
-
fetchConfigValueEvaluations,
|
|
54
|
-
fetchedValueEvaluationUnits,
|
|
55
|
-
]);
|
|
44
|
+
fetchConfigValueEvaluations();
|
|
45
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
46
|
+
}, [unitId]);
|
|
56
47
|
};
|
|
57
48
|
|
|
58
49
|
export default useValueEvaluations;
|
|
@@ -127,12 +127,6 @@ export const googleHomeConnect = async (
|
|
|
127
127
|
for (let i = 0; i < options.length; i++) {
|
|
128
128
|
const option = options[i];
|
|
129
129
|
|
|
130
|
-
if (option.chip_id in oldConnections && !!oldConnections[option.chip_id]) {
|
|
131
|
-
connections[option.chip_id] = oldConnections[option.chip_id];
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
connections[option.chip_id] = 0; // connecting
|
|
135
|
-
|
|
136
130
|
option.config_maps.forEach((configMap) => {
|
|
137
131
|
if (option.text_maps) {
|
|
138
132
|
textMaps[configMap.entity_id] = option.text_maps;
|
|
@@ -156,6 +150,12 @@ export const googleHomeConnect = async (
|
|
|
156
150
|
}
|
|
157
151
|
});
|
|
158
152
|
|
|
153
|
+
if (option.chip_id in oldConnections && !!oldConnections[option.chip_id]) {
|
|
154
|
+
connections[option.chip_id] = oldConnections[option.chip_id];
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
connections[option.chip_id] = 0; // connecting
|
|
158
|
+
|
|
159
159
|
try {
|
|
160
160
|
let auth = new Auth(option.auth);
|
|
161
161
|
const connection = await createConnection({ auth });
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import { createStackNavigator } from '@react-navigation/stack';
|
|
3
|
+
|
|
4
|
+
import Routes from '../utils/Route';
|
|
5
|
+
import { screenOptions } from './utils';
|
|
6
|
+
import Gateway from '../screens/Gateway';
|
|
7
|
+
|
|
8
|
+
const Stack = createStackNavigator();
|
|
9
|
+
|
|
10
|
+
const GatewayStack = memo(() => {
|
|
11
|
+
return (
|
|
12
|
+
<Stack.Navigator
|
|
13
|
+
screenOptions={{
|
|
14
|
+
...screenOptions,
|
|
15
|
+
headerShown: false,
|
|
16
|
+
}}
|
|
17
|
+
>
|
|
18
|
+
<Stack.Screen name={Routes.Gateway} component={Gateway} />
|
|
19
|
+
</Stack.Navigator>
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export default GatewayStack;
|