@eohjsc/react-native-smart-city 0.2.84 → 0.2.85
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/assets/images/brightness.svg +12 -0
- package/package.json +3 -1
- package/src/Images/Common/SuccessfullyConnected.svg +4 -0
- package/src/Images/Common/eye-closed.png +0 -0
- package/src/Images/Common/eye-closed@2x.png +0 -0
- package/src/Images/Common/eye-closed@3x.png +0 -0
- package/src/Images/Common/eye.png +0 -0
- package/src/Images/Common/eye@2x.png +0 -0
- package/src/Images/Common/eye@3x.png +0 -0
- package/src/commons/ActionGroup/LightActionTemplate.js +103 -0
- package/src/commons/ActionGroup/LightActionTemplateStyles.js +57 -0
- package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +33 -31
- package/src/commons/ActionGroup/__test__/LightActionTemplate.test.js +59 -0
- package/src/commons/ActionGroup/index.js +3 -0
- package/src/commons/CardShadow/index.js +5 -2
- package/src/commons/CardShadow/styles.js +2 -3
- package/src/commons/ConnectingProcess/DeviceItem/DeviceItem.js +16 -0
- package/src/commons/ConnectingProcess/DeviceItem/DeviceItemStyles.js +42 -0
- package/src/commons/ConnectingProcess/__test__/Connecting.test.js +27 -0
- package/src/commons/ConnectingProcess/__test__/DeviceItem.test.js +18 -0
- package/src/commons/ConnectingProcess/index.js +202 -0
- package/src/commons/ConnectingProcess/styles.js +69 -0
- package/src/commons/Device/LinearChart.js +1 -0
- package/src/commons/Form/TextInputPassword.js +1 -1
- package/src/configs/API.js +2 -0
- package/src/configs/Constants.js +15 -0
- package/src/configs/Images.js +2 -0
- package/src/context/actionType.ts +2 -0
- package/src/context/reducer.ts +10 -0
- package/src/hooks/Common/useBlockBackAndroid.js +3 -1
- package/src/navigations/AddDeviceStack.js +10 -0
- package/src/screens/AddCommon/SelectSubUnit.js +29 -6
- package/src/screens/AddCommon/SelectUnit.js +24 -2
- package/src/screens/AddCommon/__test__/SelectSubUnit.test.js +120 -1
- package/src/screens/AddCommon/__test__/SelectUnit.test.js +16 -1
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +45 -15
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +52 -23
- package/src/screens/AddNewGateway/SelectGateway.js +132 -0
- package/src/screens/AddNewGateway/SelectGatewayStyles.js +55 -0
- package/src/screens/Device/detail.js +6 -6
- package/src/screens/Notification/__test__/NotificationItem.test.js +12 -2
- package/src/screens/Notification/components/NotificationItem.js +60 -12
- package/src/screens/ScanChipQR/__test__/ScanChipQR.test.js +10 -7
- package/src/screens/ScanChipQR/hooks/index.js +46 -22
- package/src/screens/Unit/Detail.js +23 -1
- package/src/utils/I18n/translations/en.json +8 -0
- package/src/utils/I18n/translations/vi.json +8 -1
- package/src/utils/Route/index.js +2 -0
|
@@ -35,13 +35,21 @@ describe('Test SelectUnit container', () => {
|
|
|
35
35
|
mockedGoBack.mockClear();
|
|
36
36
|
});
|
|
37
37
|
let tree;
|
|
38
|
-
const list_type = [
|
|
38
|
+
const list_type = [
|
|
39
|
+
'AddSubUnit',
|
|
40
|
+
'AddDevice',
|
|
41
|
+
'AddMember',
|
|
42
|
+
'AddLGDevice',
|
|
43
|
+
'',
|
|
44
|
+
'AddDeviceNewFlow',
|
|
45
|
+
];
|
|
39
46
|
const result = [
|
|
40
47
|
'Add new sub-unit',
|
|
41
48
|
'Add new device',
|
|
42
49
|
'Select a unit',
|
|
43
50
|
'Select a unit',
|
|
44
51
|
'Add new sub-unit',
|
|
52
|
+
'Select a unit',
|
|
45
53
|
];
|
|
46
54
|
list_type.forEach(function (type, i) {
|
|
47
55
|
test(`create SelectUnit ${type} container`, () => {
|
|
@@ -126,6 +134,13 @@ describe('Test SelectUnit container', () => {
|
|
|
126
134
|
unit_id: 1,
|
|
127
135
|
});
|
|
128
136
|
break;
|
|
137
|
+
case 'AddDeviceNewFlow':
|
|
138
|
+
expect(mockedNavigate).toBeCalledWith('AddGatewaySelectGateway', {
|
|
139
|
+
unit_id: 1,
|
|
140
|
+
addType: 'AddDeviceNewFlow',
|
|
141
|
+
scan_sensor_data: undefined,
|
|
142
|
+
});
|
|
143
|
+
break;
|
|
129
144
|
default:
|
|
130
145
|
break;
|
|
131
146
|
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
memo,
|
|
3
|
+
useEffect,
|
|
4
|
+
useState,
|
|
5
|
+
useCallback,
|
|
6
|
+
useContext,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
View,
|
|
4
10
|
StyleSheet,
|
|
@@ -16,15 +22,18 @@ import ScanQrGateway from '../../../../assets/images/scan-qr-gateway.svg';
|
|
|
16
22
|
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
17
23
|
import { getBottomSpace } from 'react-native-iphone-x-helper';
|
|
18
24
|
import BottomButtonView from '../../../commons/BottomButtonView';
|
|
19
|
-
import { Colors
|
|
20
|
-
import { axiosPost } from '../../../utils/Apis/axios';
|
|
25
|
+
import { Colors } from '../../../configs';
|
|
21
26
|
import Routes from '../../../utils/Route';
|
|
27
|
+
import { SCContext } from '../../../context';
|
|
28
|
+
import { Action } from '../../../context/actionType';
|
|
22
29
|
|
|
23
30
|
const ConnectWifiWarning = memo(({ route }) => {
|
|
24
|
-
const { wifi_ssid, wifi_pass, unit_id, chip_id } =
|
|
31
|
+
const { wifi_ssid, wifi_pass, unit_id, chip_id, devicePrefixName, body } =
|
|
32
|
+
route.params;
|
|
25
33
|
const t = useTranslations();
|
|
26
34
|
const { navigate, goBack } = useNavigation();
|
|
27
35
|
const [isLoading, setIsLoading] = useState(false);
|
|
36
|
+
const { setAction } = useContext(SCContext);
|
|
28
37
|
|
|
29
38
|
const getPermissionWifiAndroid = useCallback(async () => {
|
|
30
39
|
const granted = await PermissionsAndroid.request(
|
|
@@ -70,22 +79,42 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
70
79
|
socket: socket,
|
|
71
80
|
});
|
|
72
81
|
}
|
|
82
|
+
});
|
|
83
|
+
socket.on('message', (msg, rinfo) => {
|
|
84
|
+
const data = JSON.parse(msg.toString());
|
|
73
85
|
if (data.hasOwnProperty('gateway')) {
|
|
74
86
|
const checkWifiInterval = setInterval(() => {
|
|
75
87
|
// eslint-disable-next-line promise/prefer-await-to-then
|
|
76
88
|
WifiManager.getCurrentWifiSSID().then(async (ssid) => {
|
|
77
89
|
if (ssid !== wifi_ssid) {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
const IsRobot = devicePrefixName === 'ROBOT';
|
|
91
|
+
if (IsRobot) {
|
|
92
|
+
setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
|
|
93
|
+
navigate(Routes.AddDeviceStack, {
|
|
94
|
+
screen: Routes.AddCommonSelectSubUnit,
|
|
95
|
+
params: {
|
|
96
|
+
scan_sensor_data: { ...body },
|
|
97
|
+
addType: 'AddDeviceNewFlow',
|
|
98
|
+
gateway: data?.gateway,
|
|
99
|
+
unit_id: unit_id,
|
|
100
|
+
devicePrefixName: devicePrefixName,
|
|
101
|
+
wifi_ssid: wifi_ssid,
|
|
102
|
+
wifi_pass: wifi_pass,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
clearInterval(checkWifiInterval);
|
|
106
|
+
} else {
|
|
107
|
+
setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
|
|
108
|
+
navigate(Routes.AddDeviceStack, {
|
|
109
|
+
screen: Routes.ConnectingProcess,
|
|
110
|
+
params: {
|
|
111
|
+
unit_id: unit_id,
|
|
112
|
+
scan_sensor_data: { ...body },
|
|
113
|
+
gateway: data?.gateway,
|
|
114
|
+
devicePrefixName: devicePrefixName,
|
|
115
|
+
chip_id: chip_id,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
89
118
|
clearInterval(checkWifiInterval);
|
|
90
119
|
}
|
|
91
120
|
}
|
|
@@ -95,6 +124,7 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
95
124
|
});
|
|
96
125
|
socket.on('error', () => {
|
|
97
126
|
ToastBottomHelper.error(t('server_error'));
|
|
127
|
+
setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
|
|
98
128
|
goBack();
|
|
99
129
|
});
|
|
100
130
|
};
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
memo,
|
|
3
|
+
useState,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useEffect,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
View,
|
|
4
10
|
StyleSheet,
|
|
5
11
|
TouchableOpacity,
|
|
6
12
|
ScrollView,
|
|
7
|
-
|
|
13
|
+
ActivityIndicator,
|
|
8
14
|
} from 'react-native';
|
|
9
15
|
import { HeaderCustom } from '../../../commons/Header';
|
|
10
16
|
import { Colors } from '../../../configs';
|
|
@@ -12,6 +18,9 @@ import Text from '../../../commons/Text';
|
|
|
12
18
|
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
13
19
|
import WifiIcon from '../../../../assets/images/wifi.svg';
|
|
14
20
|
import ButtonPopup from '../../../commons/ButtonPopup';
|
|
21
|
+
import TextInputPassword from '../../../commons/Form/TextInputPassword';
|
|
22
|
+
import { SCContext, useSCContextSelector } from '../../../context';
|
|
23
|
+
import { Action } from '../../../context/actionType';
|
|
15
24
|
|
|
16
25
|
const GatewayWifiList = memo(({ route }) => {
|
|
17
26
|
const { list_wifi, socket } = route.params;
|
|
@@ -20,6 +29,11 @@ const GatewayWifiList = memo(({ route }) => {
|
|
|
20
29
|
const [isShowPopupPassword, setIsShowPopupPassword] = useState(false);
|
|
21
30
|
const [password, setPassword] = useState('');
|
|
22
31
|
const [selectedWifi, setSelectedWifi] = useState('');
|
|
32
|
+
const { setAction } = useContext(SCContext);
|
|
33
|
+
|
|
34
|
+
const isConnectWifiGateway = useSCContextSelector(
|
|
35
|
+
(state) => state.app.isConnectWifiGateway
|
|
36
|
+
);
|
|
23
37
|
|
|
24
38
|
const showPopupPassword = (ssid) => {
|
|
25
39
|
setIsShowPopupPassword(true);
|
|
@@ -32,21 +46,27 @@ const GatewayWifiList = memo(({ route }) => {
|
|
|
32
46
|
},
|
|
33
47
|
[setPassword]
|
|
34
48
|
);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
const connectWifi = useCallback(async () => {
|
|
50
|
+
if (!isConnectWifiGateway) {
|
|
51
|
+
await socket.send(
|
|
52
|
+
JSON.stringify({
|
|
53
|
+
type: 'connect',
|
|
54
|
+
data: { wifi: { ssid: selectedWifi, pass: password } },
|
|
55
|
+
}),
|
|
56
|
+
undefined,
|
|
57
|
+
undefined,
|
|
58
|
+
54321,
|
|
59
|
+
'192.168.27.1',
|
|
60
|
+
undefined
|
|
61
|
+
);
|
|
62
|
+
setAction(Action.IS_CONNECT_WIFI_GATEWAY, true);
|
|
63
|
+
}
|
|
64
|
+
}, [isConnectWifiGateway, password, selectedWifi, setAction, socket]);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!isConnectWifiGateway) {
|
|
67
|
+
setIsShowPopupPassword(false);
|
|
68
|
+
}
|
|
69
|
+
}, [isConnectWifiGateway]);
|
|
50
70
|
return (
|
|
51
71
|
<View style={styles.screen}>
|
|
52
72
|
<HeaderCustom title={t('connect_device')} isShowSeparator />
|
|
@@ -79,19 +99,28 @@ const GatewayWifiList = memo(({ route }) => {
|
|
|
79
99
|
|
|
80
100
|
<ButtonPopup
|
|
81
101
|
visible={isShowPopupPassword}
|
|
82
|
-
mainTitle={
|
|
83
|
-
|
|
102
|
+
mainTitle={
|
|
103
|
+
isConnectWifiGateway ? (
|
|
104
|
+
<ActivityIndicator color={Colors.White} size={'small'} />
|
|
105
|
+
) : (
|
|
106
|
+
t('connect')
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
onPressMain={connectWifi}
|
|
84
110
|
secondaryTitle={t('cancel')}
|
|
111
|
+
typeSecondary={isConnectWifiGateway ? 'disabled' : 'cancel'}
|
|
85
112
|
onPressSecondary={() => setIsShowPopupPassword(false)}
|
|
86
113
|
hideClose={true}
|
|
87
114
|
>
|
|
88
115
|
<>
|
|
89
116
|
<Text>{t('enter_wifi_password')}</Text>
|
|
90
|
-
<
|
|
91
|
-
secureTextEntry
|
|
92
|
-
|
|
93
|
-
|
|
117
|
+
<TextInputPassword
|
|
118
|
+
secureTextEntry
|
|
119
|
+
placeholder={t('password')}
|
|
120
|
+
onChange={onPasswordChange}
|
|
94
121
|
value={password}
|
|
122
|
+
textInputStyle={styles.input}
|
|
123
|
+
selectionColor={Colors.Primary}
|
|
95
124
|
/>
|
|
96
125
|
</>
|
|
97
126
|
</ButtonPopup>
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { useIsFocused, useNavigation } from '@react-navigation/native';
|
|
3
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
4
|
+
import { SafeAreaView, ScrollView, TouchableOpacity, View } from 'react-native';
|
|
5
|
+
|
|
6
|
+
import { API } from '../../configs';
|
|
7
|
+
import { Section, RadioCircle, ViewButtonBottom } from '../../commons';
|
|
8
|
+
import { axiosGet } from '../../utils/Apis/axios';
|
|
9
|
+
import Text from '../../commons/Text';
|
|
10
|
+
import Routes from '../../utils/Route';
|
|
11
|
+
import { TESTID } from '../../configs/Constants';
|
|
12
|
+
import styles from './SelectGatewayStyles';
|
|
13
|
+
|
|
14
|
+
const AddNewGatewaySelectGateway = ({ route }) => {
|
|
15
|
+
const t = useTranslations();
|
|
16
|
+
const navigation = useNavigation();
|
|
17
|
+
const isFocused = useIsFocused();
|
|
18
|
+
const { addType, unit_id, scan_sensor_data, devicePrefixName } = route.params;
|
|
19
|
+
const [selectedIndex, setSelectedIndex] = useState(-1);
|
|
20
|
+
|
|
21
|
+
const [gateways, setGateways] = useState([]);
|
|
22
|
+
const [title, setTitle] = useState('');
|
|
23
|
+
const [subTitle, setSubTitle] = useState('');
|
|
24
|
+
const [gateway, setGateway] = useState({});
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
switch (addType) {
|
|
28
|
+
case 'AddDeviceNewFlow':
|
|
29
|
+
setTitle(t('text_select_a_gateway'));
|
|
30
|
+
setSubTitle(t('text_select_a_gateway'));
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
setTitle(t('text_select_a_gateway'));
|
|
34
|
+
setSubTitle(t('text_select_a_gateway'));
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}, [title, subTitle, addType, t]);
|
|
38
|
+
|
|
39
|
+
const fetchDetails = useCallback(async () => {
|
|
40
|
+
const { success, data } = await axiosGet(
|
|
41
|
+
API.CHIP.GET_CHIPS_FROM_UNIT(unit_id)
|
|
42
|
+
);
|
|
43
|
+
if (success) {
|
|
44
|
+
setGateways(data);
|
|
45
|
+
}
|
|
46
|
+
}, [unit_id]);
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
isFocused && fetchDetails();
|
|
50
|
+
}, [fetchDetails, isFocused]);
|
|
51
|
+
|
|
52
|
+
const onPressNext = useCallback(() => {
|
|
53
|
+
switch (addType) {
|
|
54
|
+
case 'AddDeviceNewFlow':
|
|
55
|
+
navigation.navigate(Routes.AddCommonSelectSubUnit, {
|
|
56
|
+
unit_id: unit_id,
|
|
57
|
+
addType: 'AddDeviceNewFlow',
|
|
58
|
+
scan_sensor_data,
|
|
59
|
+
gateway,
|
|
60
|
+
devicePrefixName,
|
|
61
|
+
});
|
|
62
|
+
break;
|
|
63
|
+
default:
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
}, [
|
|
67
|
+
addType,
|
|
68
|
+
devicePrefixName,
|
|
69
|
+
gateway,
|
|
70
|
+
navigation,
|
|
71
|
+
scan_sensor_data,
|
|
72
|
+
unit_id,
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
const handleSelectIndex = (index) => {
|
|
76
|
+
setGateway(gateways[index]);
|
|
77
|
+
if (index !== selectedIndex) {
|
|
78
|
+
setSelectedIndex(index);
|
|
79
|
+
} else {
|
|
80
|
+
setSelectedIndex(-1);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<SafeAreaView style={styles.container}>
|
|
86
|
+
<Text semibold style={styles.title}>
|
|
87
|
+
{title}
|
|
88
|
+
</Text>
|
|
89
|
+
<Text style={styles.subtitle}>{subTitle}</Text>
|
|
90
|
+
<View style={styles.contentContainer}>
|
|
91
|
+
<ScrollView
|
|
92
|
+
style={styles.scrollContainer}
|
|
93
|
+
showsVerticalScrollIndicator={false}
|
|
94
|
+
>
|
|
95
|
+
<Section type={'border'}>
|
|
96
|
+
{gateways.map((item, index) => (
|
|
97
|
+
<TouchableOpacity
|
|
98
|
+
key={index}
|
|
99
|
+
style={styles.rowContainer}
|
|
100
|
+
onPress={() => handleSelectIndex(index)}
|
|
101
|
+
>
|
|
102
|
+
<RadioCircle
|
|
103
|
+
active={selectedIndex === index}
|
|
104
|
+
testID={TESTID.SELECT_GATEWAY_RADIO_BUTTON}
|
|
105
|
+
/>
|
|
106
|
+
<TouchableOpacity
|
|
107
|
+
style={styles.row}
|
|
108
|
+
onPress={() => handleSelectIndex(index)}
|
|
109
|
+
testID={TESTID.SELECT_GATEWAY_NAME}
|
|
110
|
+
>
|
|
111
|
+
<Text style={styles.text} testID={TESTID.SELECT_GATEWAY_NAME}>
|
|
112
|
+
{item.name}
|
|
113
|
+
</Text>
|
|
114
|
+
</TouchableOpacity>
|
|
115
|
+
</TouchableOpacity>
|
|
116
|
+
))}
|
|
117
|
+
</Section>
|
|
118
|
+
</ScrollView>
|
|
119
|
+
<ViewButtonBottom
|
|
120
|
+
leftTitle={t('cancel')}
|
|
121
|
+
onLeftClick={() => navigation.goBack()}
|
|
122
|
+
rightTitle={t('next')}
|
|
123
|
+
rightDisabled={selectedIndex === -1}
|
|
124
|
+
onRightClick={onPressNext}
|
|
125
|
+
testIDPrefix={TESTID.PREFIX.SELECT_UNIT}
|
|
126
|
+
/>
|
|
127
|
+
</View>
|
|
128
|
+
</SafeAreaView>
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export default AddNewGatewaySelectGateway;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Colors } from '../../configs';
|
|
2
|
+
|
|
3
|
+
import { StyleSheet, StatusBar, Platform } from 'react-native';
|
|
4
|
+
|
|
5
|
+
export default StyleSheet.create({
|
|
6
|
+
container: {
|
|
7
|
+
flex: 1,
|
|
8
|
+
backgroundColor: Colors.Gray2,
|
|
9
|
+
paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0,
|
|
10
|
+
},
|
|
11
|
+
contentContainer: {
|
|
12
|
+
flex: 1,
|
|
13
|
+
justifyContent: 'space-between',
|
|
14
|
+
},
|
|
15
|
+
scrollContainer: {
|
|
16
|
+
width: '100%',
|
|
17
|
+
flex: 1,
|
|
18
|
+
},
|
|
19
|
+
title: {
|
|
20
|
+
color: Colors.Gray9,
|
|
21
|
+
fontSize: 20,
|
|
22
|
+
lineHeight: 28,
|
|
23
|
+
marginTop: 8,
|
|
24
|
+
marginBottom: 4,
|
|
25
|
+
marginLeft: 16,
|
|
26
|
+
},
|
|
27
|
+
subtitle: {
|
|
28
|
+
color: Colors.Gray8,
|
|
29
|
+
fontSize: 14,
|
|
30
|
+
lineHeight: 22,
|
|
31
|
+
marginLeft: 16,
|
|
32
|
+
marginBottom: 16,
|
|
33
|
+
},
|
|
34
|
+
row: {
|
|
35
|
+
flex: 1,
|
|
36
|
+
paddingVertical: 16,
|
|
37
|
+
borderBottomColor: Colors.Gray4,
|
|
38
|
+
borderBottomWidth: 1,
|
|
39
|
+
marginRight: 24,
|
|
40
|
+
marginLeft: 16,
|
|
41
|
+
},
|
|
42
|
+
rowContainer: {
|
|
43
|
+
flexDirection: 'row',
|
|
44
|
+
alignItems: 'center',
|
|
45
|
+
paddingLeft: 16,
|
|
46
|
+
},
|
|
47
|
+
text: {
|
|
48
|
+
fontSize: 16,
|
|
49
|
+
lineHeight: 24,
|
|
50
|
+
color: Colors.Gray9,
|
|
51
|
+
},
|
|
52
|
+
buttonAdd: {
|
|
53
|
+
marginHorizontal: 16,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
@@ -58,11 +58,6 @@ const DeviceDetail = ({ route }) => {
|
|
|
58
58
|
const [controlOptions, setControlOptions] = useState({
|
|
59
59
|
internet: {},
|
|
60
60
|
});
|
|
61
|
-
// eslint-disable-next-line no-unused-vars
|
|
62
|
-
const [loading, setLoading] = useState({
|
|
63
|
-
isConnected: true,
|
|
64
|
-
displayTemplate: true,
|
|
65
|
-
});
|
|
66
61
|
const [isConnected, setConnected] = useState(false);
|
|
67
62
|
const [lastUpdated, setLastUpdated] = useState(null);
|
|
68
63
|
const [lastEvent, setLastEvent] = useState({ id: 0, reportedAt: 0 });
|
|
@@ -80,6 +75,10 @@ const DeviceDetail = ({ route }) => {
|
|
|
80
75
|
const [sensorName, setSensorName] = useState(sensor?.name);
|
|
81
76
|
const [lockShowing, acquireLockShowing, releaseLockShowing] = useBoolean();
|
|
82
77
|
const [showWindDirection, setShowWindDirection] = useState(false);
|
|
78
|
+
const [loading, setLoading] = useState({
|
|
79
|
+
isConnected: true,
|
|
80
|
+
displayTemplate: true,
|
|
81
|
+
});
|
|
83
82
|
|
|
84
83
|
const isDeviceConnectedViaBle = useMemo(
|
|
85
84
|
() => isDeviceConnected(sensor?.remote_control_options?.bluetooth?.address),
|
|
@@ -408,7 +407,8 @@ const DeviceDetail = ({ route }) => {
|
|
|
408
407
|
fetchValues();
|
|
409
408
|
return () => clearInterval(updateInterval);
|
|
410
409
|
} else {
|
|
411
|
-
|
|
410
|
+
Object.keys(sensor).length > 1 &&
|
|
411
|
+
setLoading((preState) => ({ ...preState, isConnected: false }));
|
|
412
412
|
}
|
|
413
413
|
}, [sensor, display]);
|
|
414
414
|
|
|
@@ -36,7 +36,7 @@ describe('test NotificationItem', () => {
|
|
|
36
36
|
id: 1,
|
|
37
37
|
content_code: '',
|
|
38
38
|
is_read: true,
|
|
39
|
-
params: JSON.stringify({ booking_id: 1 }),
|
|
39
|
+
params: JSON.stringify({ booking_id: 1, booking_id_new: 1 }),
|
|
40
40
|
created_at: '',
|
|
41
41
|
icon: '',
|
|
42
42
|
};
|
|
@@ -96,6 +96,16 @@ describe('test NotificationItem', () => {
|
|
|
96
96
|
screen: Routes.SmartParkingBookingDetails,
|
|
97
97
|
params: { id: 1 },
|
|
98
98
|
},
|
|
99
|
+
{
|
|
100
|
+
content_code: NOTIFICATION_TYPES.STOP_VIOLATION_FREE_PARKING_ZONE,
|
|
101
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
102
|
+
params: { id: 1 },
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
content_code: NOTIFICATION_TYPES.PAY_FINE_AND_EXTEND_SUCCESSFULLY,
|
|
106
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
107
|
+
params: { id: 1 },
|
|
108
|
+
},
|
|
99
109
|
];
|
|
100
110
|
|
|
101
111
|
for (const notify of listCase) {
|
|
@@ -110,7 +120,7 @@ describe('test NotificationItem', () => {
|
|
|
110
120
|
button.props.onPress();
|
|
111
121
|
});
|
|
112
122
|
expect(mockNavigate).toHaveBeenCalledWith(Routes.SmartParkingStack, {
|
|
113
|
-
|
|
123
|
+
screen: notify.screen,
|
|
114
124
|
params: notify.params,
|
|
115
125
|
});
|
|
116
126
|
});
|
|
@@ -80,7 +80,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
80
80
|
),
|
|
81
81
|
redirect: () =>
|
|
82
82
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
83
|
-
|
|
83
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
84
84
|
params: { id: booking_id },
|
|
85
85
|
}),
|
|
86
86
|
};
|
|
@@ -93,7 +93,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
93
93
|
),
|
|
94
94
|
redirect: () =>
|
|
95
95
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
96
|
-
|
|
96
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
97
97
|
params: { id: booking_id },
|
|
98
98
|
}),
|
|
99
99
|
};
|
|
@@ -105,7 +105,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
105
105
|
),
|
|
106
106
|
redirect: () =>
|
|
107
107
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
108
|
-
|
|
108
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
109
109
|
params: { id: booking_id },
|
|
110
110
|
}),
|
|
111
111
|
};
|
|
@@ -117,7 +117,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
117
117
|
),
|
|
118
118
|
redirect: () =>
|
|
119
119
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
120
|
-
|
|
120
|
+
screen: Routes.MyBookingList,
|
|
121
121
|
params: { tab: 1 },
|
|
122
122
|
}),
|
|
123
123
|
};
|
|
@@ -129,7 +129,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
129
129
|
),
|
|
130
130
|
redirect: () =>
|
|
131
131
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
132
|
-
|
|
132
|
+
screen: Routes.MyBookingList,
|
|
133
133
|
params: { tab: 1 },
|
|
134
134
|
}),
|
|
135
135
|
};
|
|
@@ -141,7 +141,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
141
141
|
),
|
|
142
142
|
redirect: () =>
|
|
143
143
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
144
|
-
|
|
144
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
145
145
|
params: { id: booking_id },
|
|
146
146
|
}),
|
|
147
147
|
};
|
|
@@ -153,7 +153,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
153
153
|
),
|
|
154
154
|
redirect: () =>
|
|
155
155
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
156
|
-
|
|
156
|
+
screen: Routes.MyBookingList,
|
|
157
157
|
params: { tab: 1 },
|
|
158
158
|
}),
|
|
159
159
|
};
|
|
@@ -168,7 +168,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
168
168
|
),
|
|
169
169
|
redirect: () =>
|
|
170
170
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
171
|
-
|
|
171
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
172
172
|
params: { id: violated_booking_id || booking_id },
|
|
173
173
|
}),
|
|
174
174
|
};
|
|
@@ -180,7 +180,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
180
180
|
),
|
|
181
181
|
redirect: () =>
|
|
182
182
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
183
|
-
|
|
183
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
184
184
|
params: { id: booking_id },
|
|
185
185
|
}),
|
|
186
186
|
};
|
|
@@ -192,7 +192,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
192
192
|
),
|
|
193
193
|
redirect: () =>
|
|
194
194
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
195
|
-
|
|
195
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
196
196
|
params: { id: booking_id },
|
|
197
197
|
}),
|
|
198
198
|
};
|
|
@@ -205,7 +205,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
205
205
|
),
|
|
206
206
|
redirect: () =>
|
|
207
207
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
208
|
-
|
|
208
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
209
209
|
params: { id: new_booking_id },
|
|
210
210
|
}),
|
|
211
211
|
};
|
|
@@ -217,7 +217,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
217
217
|
),
|
|
218
218
|
redirect: () =>
|
|
219
219
|
navigation.navigate(Routes.SmartParkingStack, {
|
|
220
|
-
|
|
220
|
+
screen: Routes.SmartParkingBookingDetails,
|
|
221
221
|
params: { id: booking_id },
|
|
222
222
|
}),
|
|
223
223
|
};
|
|
@@ -398,6 +398,54 @@ const NotificationItem = memo(({ item }) => {
|
|
|
398
398
|
<IconComponent icon={'home'} style={styles.backgroundSummer} />
|
|
399
399
|
),
|
|
400
400
|
};
|
|
401
|
+
case NOTIFICATION_TYPES.NOTIFY_DEVICE_DISCONNECT:
|
|
402
|
+
return {
|
|
403
|
+
content: customColorText(
|
|
404
|
+
t('text_notification_content_divice_disconnect'),
|
|
405
|
+
arrParams
|
|
406
|
+
),
|
|
407
|
+
redirect: () => {
|
|
408
|
+
navigation.navigate(Routes.UnitStack, {
|
|
409
|
+
screen: Routes.DeviceDetail,
|
|
410
|
+
params: {
|
|
411
|
+
unitId,
|
|
412
|
+
sensorId,
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
},
|
|
416
|
+
};
|
|
417
|
+
case NOTIFICATION_TYPES.NOTIFY_UPDATE_ADDRESS:
|
|
418
|
+
return {
|
|
419
|
+
content: customColorText(
|
|
420
|
+
t('text_notification_content_update_address'),
|
|
421
|
+
arrParams
|
|
422
|
+
),
|
|
423
|
+
redirect: () => {
|
|
424
|
+
navigation.navigate(Routes.UnitStack, {
|
|
425
|
+
screen: Routes.UnitDetail,
|
|
426
|
+
params: {
|
|
427
|
+
unitId,
|
|
428
|
+
},
|
|
429
|
+
});
|
|
430
|
+
},
|
|
431
|
+
};
|
|
432
|
+
case NOTIFICATION_TYPES.NOTIFY_RENAME_SUB_UNIT:
|
|
433
|
+
const stationId = paramsJSON?.sub_unit_id;
|
|
434
|
+
return {
|
|
435
|
+
content: customColorText(
|
|
436
|
+
t('text_notification_content_rename_sub_unit'),
|
|
437
|
+
arrParams
|
|
438
|
+
),
|
|
439
|
+
redirect: () => {
|
|
440
|
+
navigation.navigate(Routes.UnitStack, {
|
|
441
|
+
screen: Routes.UnitDetail,
|
|
442
|
+
params: {
|
|
443
|
+
unitId,
|
|
444
|
+
stationId,
|
|
445
|
+
},
|
|
446
|
+
});
|
|
447
|
+
},
|
|
448
|
+
};
|
|
401
449
|
default:
|
|
402
450
|
return {
|
|
403
451
|
content: customColorText(t('this_notification_will_be_updated_soon')),
|