@eohjsc/react-native-smart-city 0.3.20 → 0.3.23
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 +2 -1
- package/src/Images/Common/buttonLeftCurtain.png +0 -0
- package/src/Images/Common/buttonLeftCurtain@2x.png +0 -0
- package/src/Images/Common/buttonLeftCurtain@3x.png +0 -0
- package/src/commons/Action/ItemQuickAction.js +1 -12
- package/src/commons/Action/__test__/ItemQuickAction.test.js +1 -1
- package/src/commons/ActionGroup/ColorPickerTemplate.js +2 -9
- package/src/commons/ActionGroup/CurtainButtonTemplate.js +5 -4
- package/src/commons/ActionGroup/CurtainButtonTemplateStyle.js +5 -0
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +6 -16
- package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +7 -4
- package/src/commons/ActionGroup/OnOffTemplate/index.js +6 -12
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +5 -2
- package/src/commons/ActionGroup/SliderRangeTemplate.js +4 -9
- package/src/commons/ActionGroup/StatesGridActionTemplate.js +7 -10
- package/src/commons/ActionGroup/TimerActionTemplate.js +11 -4
- package/src/commons/ActionGroup/TwoButtonTemplate/index.js +12 -15
- package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +37 -2
- package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +7 -0
- package/src/commons/ActionGroup/__test__/OnOffSmartLock.test.js +15 -2
- package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +8 -1
- package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +8 -1
- package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +7 -0
- package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +8 -1
- package/src/commons/ActionGroup/__test__/TimerActionTemplateWithutConfigValue.test.js +7 -0
- package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +7 -0
- package/src/commons/ActionGroup/__test__/index.test.js +8 -1
- package/src/commons/Device/ItemDevice.js +79 -35
- package/src/commons/MediaPlayerDetail/index.js +5 -0
- package/src/commons/RowItem/index.js +6 -2
- package/src/commons/RowItem/styles.js +1 -0
- package/src/commons/SubUnit/Favorites/index.js +24 -6
- package/src/commons/SubUnit/ShortDetail.js +19 -5
- package/src/commons/SubUnit/__test__/Favorites.test.js +1 -0
- package/src/commons/SubUnit/__test__/ShortDetail.test.js +1 -0
- package/src/configs/API.js +8 -3
- package/src/configs/Constants.js +8 -2
- package/src/configs/SCConfig.js +4 -0
- package/src/context/actionType.ts +6 -5
- package/src/context/mockStore.ts +10 -3
- package/src/context/reducer.ts +20 -15
- package/src/hoc/index.js +3 -0
- package/src/hoc/withRemoteControl.js +10 -0
- package/src/hooks/Common/index.js +2 -2
- package/src/hooks/Common/useDevicesStatus.js +57 -0
- package/src/hooks/Common/useGGHomeDeviceConnected.js +3 -3
- package/src/hooks/IoT/__test__/useGGHomeConnection.test.js +1 -2
- package/src/hooks/IoT/index.js +9 -1
- package/src/hooks/IoT/useGGHomeConnection.js +0 -1
- package/src/hooks/IoT/useUnwatchLGDeviceConfigControl.js +29 -0
- package/src/hooks/IoT/useValueEvaluation.js +17 -4
- package/src/hooks/IoT/useWatchConfigs.js +34 -0
- package/src/iot/Monitor.js +13 -20
- package/src/iot/RemoteControl/GoogleHome.js +12 -13
- package/src/iot/RemoteControl/LG.js +1 -0
- package/src/iot/RemoteControl/__test__/GoogleHome.test.js +7 -2
- package/src/navigations/UnitStack.js +16 -3
- package/src/screens/AddNewAction/SelectAction.js +1 -1
- package/src/screens/AddNewAction/SetupSensor.js +4 -0
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +44 -78
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +15 -35
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +2 -0
- package/src/screens/AllCamera/__test__/index.test.js +1 -1
- package/src/screens/Device/__test__/detail.test.js +1 -54
- package/src/screens/Device/components/SensorConnectStatusViewHeader.js +18 -8
- package/src/screens/Device/detail.js +36 -23
- package/src/screens/Device/hooks/__test__/useEvaluateValue.test.js +102 -0
- package/src/screens/Device/hooks/useDeviceWatchConfigControl.js +20 -0
- package/src/screens/Device/utils/index.js +45 -0
- package/src/screens/Device/utils/index.test.js +111 -0
- package/src/screens/EmergencyContacts/EmergencyContactsAddNew.js +35 -22
- package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +2 -1
- package/src/screens/EmergencyContacts/__test__/EmergencyContactAddNew.test.js +36 -2
- package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +0 -2
- package/src/screens/Notification/__test__/NotificationItem.test.js +84 -19
- package/src/screens/Notification/components/NotificationItem.js +64 -31
- package/src/screens/ScriptDetail/hooks/useStarredScript.js +2 -2
- package/src/screens/SubUnit/AddSubUnit.js +2 -1
- package/src/screens/Unit/AddMenu.js +4 -0
- package/src/screens/Unit/{SelectFavoritesDevices.js → SelectAddToFavorites.js} +81 -26
- package/src/screens/Unit/{SelectFavoritesDevicesStyles.js → SelectAddToFavoritesStyles.js} +0 -0
- package/src/screens/Unit/__test__/CheckSendEmail.test.js +12 -0
- package/src/screens/Unit/__test__/Detail.test.js +2 -3
- package/src/screens/Unit/__test__/SelectAddToFavorites.test.js +267 -0
- package/src/screens/Unit/components/AutomateScript/index.js +65 -0
- package/src/screens/Unit/components/AutomateScript/styles.js +48 -0
- package/src/screens/Unit/components/MyUnitDevice/index.js +3 -2
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +4 -2
- package/src/utils/I18n/translations/en.json +7 -2
- package/src/utils/I18n/translations/vi.json +6 -1
- package/src/utils/Route/index.js +1 -1
- package/src/hooks/Common/useSensorsStatus.js +0 -62
- package/src/screens/Unit/__test__/SelectFavoritesDevices.test.js +0 -110
|
@@ -28,14 +28,9 @@ import { Action } from '../../../context/actionType';
|
|
|
28
28
|
import { TESTID } from '../../../configs/Constants';
|
|
29
29
|
import Connecting from '../../../commons/Connecting';
|
|
30
30
|
|
|
31
|
-
const isIos = Platform.OS === 'ios';
|
|
32
31
|
const isAndroid = Platform.OS === 'android';
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (isIos) {
|
|
36
|
-
socket = dgram.createSocket({ type: 'udp4' });
|
|
37
|
-
socket.bind(54321);
|
|
38
|
-
}
|
|
32
|
+
let socket,
|
|
33
|
+
intervalSend = null;
|
|
39
34
|
|
|
40
35
|
const ConnectWifiWarning = memo(({ route }) => {
|
|
41
36
|
const {
|
|
@@ -83,77 +78,44 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
83
78
|
}, [getPermissionWifiAndroid]);
|
|
84
79
|
|
|
85
80
|
const handleSend = async () => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
await dgSocket.bind(54321);
|
|
125
|
-
await dgSocket.on('message', (msg, rinfo) => {
|
|
126
|
-
const data = JSON.parse(msg.toString());
|
|
127
|
-
if (Object.prototype.hasOwnProperty.call(data, 'wifi')) {
|
|
128
|
-
navigate(Routes.GatewayWifiList, {
|
|
129
|
-
list_wifi: data.wifi,
|
|
130
|
-
unit_id: unit_id,
|
|
131
|
-
chip_id: chip_id,
|
|
132
|
-
scan_sensor_data: { ...body },
|
|
133
|
-
wifi_ssid: wifi_ssid,
|
|
134
|
-
wifi_pass: wifi_pass,
|
|
135
|
-
unit_name: unit_name,
|
|
136
|
-
devicePrefixName: devicePrefixName,
|
|
137
|
-
socket: dgSocket,
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
await dgSocket.once('listening', async () => {
|
|
142
|
-
await dgSocket.send(
|
|
143
|
-
JSON.stringify({ type: 'scan', data: { wifi: '' } }),
|
|
144
|
-
undefined,
|
|
145
|
-
undefined,
|
|
146
|
-
54321,
|
|
147
|
-
'192.168.27.1',
|
|
148
|
-
undefined
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
dgSocket.on('error', () => {
|
|
152
|
-
ToastBottomHelper.error(t('server_error'));
|
|
153
|
-
setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
|
|
154
|
-
goBack();
|
|
155
|
-
});
|
|
156
|
-
}
|
|
81
|
+
socket = dgram.createSocket({ type: 'udp4' });
|
|
82
|
+
socket.bind(54321);
|
|
83
|
+
setIsPercentConnect(1);
|
|
84
|
+
|
|
85
|
+
socket.on('message', (msg, rinfo) => {
|
|
86
|
+
clearInterval(intervalSend);
|
|
87
|
+
const data = JSON.parse(msg.toString());
|
|
88
|
+
if (Object.prototype.hasOwnProperty.call(data, 'wifi')) {
|
|
89
|
+
navigate(Routes.GatewayWifiList, {
|
|
90
|
+
list_wifi: data.wifi,
|
|
91
|
+
unit_id: unit_id,
|
|
92
|
+
chip_id: chip_id,
|
|
93
|
+
scan_sensor_data: { ...body },
|
|
94
|
+
wifi_ssid: wifi_ssid,
|
|
95
|
+
wifi_pass: wifi_pass,
|
|
96
|
+
unit_name: unit_name,
|
|
97
|
+
devicePrefixName: devicePrefixName,
|
|
98
|
+
socket: socket,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
socket.on('error', () => {
|
|
104
|
+
ToastBottomHelper.error(t('server_error'));
|
|
105
|
+
setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
|
|
106
|
+
goBack();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
intervalSend = setInterval(() => {
|
|
110
|
+
socket.send(
|
|
111
|
+
JSON.stringify({ type: 'scan', data: { wifi: '' } }),
|
|
112
|
+
undefined,
|
|
113
|
+
undefined,
|
|
114
|
+
54321,
|
|
115
|
+
'192.168.27.1',
|
|
116
|
+
undefined
|
|
117
|
+
);
|
|
118
|
+
}, 5000); // workaround, todo Bang continue research
|
|
157
119
|
};
|
|
158
120
|
|
|
159
121
|
const handleConnectWifiGateway = async () => {
|
|
@@ -171,6 +133,10 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
171
133
|
);
|
|
172
134
|
};
|
|
173
135
|
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
return () => intervalSend && clearInterval(intervalSend);
|
|
138
|
+
}, []);
|
|
139
|
+
|
|
174
140
|
return (
|
|
175
141
|
<View style={styles.screen}>
|
|
176
142
|
{!isLoading ? (
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
TouchableOpacity,
|
|
12
12
|
ScrollView,
|
|
13
13
|
ActivityIndicator,
|
|
14
|
-
Platform,
|
|
15
14
|
} from 'react-native';
|
|
16
15
|
import { HeaderCustom } from '../../../commons/Header';
|
|
17
16
|
import { Colors } from '../../../configs';
|
|
@@ -128,11 +127,8 @@ const GatewayWifiList = memo(({ route }) => {
|
|
|
128
127
|
|
|
129
128
|
const sendConnect = useCallback(
|
|
130
129
|
(i) => {
|
|
131
|
-
setTimeout(async () => {
|
|
130
|
+
const timeoutSendConnect = setTimeout(async () => {
|
|
132
131
|
i++;
|
|
133
|
-
await socket.on('message', (msg, rinfo) => {
|
|
134
|
-
handleSocketOnMsg(msg);
|
|
135
|
-
});
|
|
136
132
|
socket.send(
|
|
137
133
|
JSON.stringify({
|
|
138
134
|
type: 'connect',
|
|
@@ -146,48 +142,32 @@ const GatewayWifiList = memo(({ route }) => {
|
|
|
146
142
|
);
|
|
147
143
|
if (i < 3) {
|
|
148
144
|
sendConnect(i);
|
|
145
|
+
clearTimeout(timeoutSendConnect);
|
|
149
146
|
}
|
|
150
147
|
}, 1000);
|
|
151
148
|
},
|
|
152
|
-
[
|
|
149
|
+
[password, selectedWifi, socket]
|
|
153
150
|
);
|
|
154
151
|
|
|
155
152
|
const connectWifi = useCallback(async () => {
|
|
156
153
|
if (!isConnectWifiGateway) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}),
|
|
170
|
-
undefined,
|
|
171
|
-
undefined,
|
|
172
|
-
54321,
|
|
173
|
-
'192.168.27.1',
|
|
174
|
-
undefined
|
|
175
|
-
);
|
|
176
|
-
socket.on('error', () => {
|
|
177
|
-
ToastBottomHelper.error(t('server_error'));
|
|
178
|
-
setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
|
|
179
|
-
goBack();
|
|
180
|
-
});
|
|
181
|
-
setAction(Action.IS_CONNECT_WIFI_GATEWAY, true);
|
|
182
|
-
setIsSendWifi(true);
|
|
183
|
-
}
|
|
154
|
+
socket.on('message', (msg, rinfo) => {
|
|
155
|
+
handleSocketOnMsg(msg);
|
|
156
|
+
});
|
|
157
|
+
socket.on('error', () => {
|
|
158
|
+
ToastBottomHelper.error(t('server_error'));
|
|
159
|
+
setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
|
|
160
|
+
goBack();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
sendConnect(0);
|
|
164
|
+
setAction(Action.IS_CONNECT_WIFI_GATEWAY, true);
|
|
165
|
+
setIsSendWifi(true);
|
|
184
166
|
}
|
|
185
167
|
}, [
|
|
186
168
|
goBack,
|
|
187
169
|
handleSocketOnMsg,
|
|
188
170
|
isConnectWifiGateway,
|
|
189
|
-
password,
|
|
190
|
-
selectedWifi,
|
|
191
171
|
sendConnect,
|
|
192
172
|
setAction,
|
|
193
173
|
socket,
|
|
@@ -97,6 +97,8 @@ describe('Test GatewayWifiList', () => {
|
|
|
97
97
|
await ButtonPopup.props.onPressMain();
|
|
98
98
|
});
|
|
99
99
|
expect(socket.on).toBeCalled();
|
|
100
|
+
expect(socket.on.mock.calls[0][0]).toEqual('message');
|
|
101
|
+
jest.runOnlyPendingTimers();
|
|
100
102
|
expect(socket.send).toBeCalled();
|
|
101
103
|
|
|
102
104
|
const mockWifiThen = jest.fn();
|
|
@@ -90,7 +90,7 @@ describe('Test AllCamera screen', () => {
|
|
|
90
90
|
});
|
|
91
91
|
const instance = tree.root;
|
|
92
92
|
const TouchableOpacities = instance.findAllByType(TouchableOpacity);
|
|
93
|
-
expect(TouchableOpacities).toHaveLength(
|
|
93
|
+
expect(TouchableOpacities).toHaveLength(9);
|
|
94
94
|
const ModalFullVideos = instance.findAllByType(ModalFullVideo);
|
|
95
95
|
expect(ModalFullVideos).toHaveLength(1);
|
|
96
96
|
act(() => {
|
|
@@ -12,7 +12,6 @@ import { TESTID } from '../../../configs/Constants';
|
|
|
12
12
|
import Text from '../../../commons/Text';
|
|
13
13
|
import { IconFill } from '@ant-design/icons-react-native';
|
|
14
14
|
import CurrentRainSensor from '../../../commons/Device/RainningSensor/CurrentRainSensor';
|
|
15
|
-
import { ConnectedViewHeader } from '../../../commons/Device';
|
|
16
15
|
import { getTranslate } from '../../../utils/I18n';
|
|
17
16
|
import { SCProvider } from '../../../context';
|
|
18
17
|
import { mockSCStore } from '../../../context/mockStore';
|
|
@@ -30,6 +29,7 @@ jest.mock('@react-navigation/native', () => {
|
|
|
30
29
|
useNavigation: () => ({
|
|
31
30
|
navigate: mockedNavigate,
|
|
32
31
|
}),
|
|
32
|
+
useFocusEffect: jest.fn(),
|
|
33
33
|
};
|
|
34
34
|
});
|
|
35
35
|
|
|
@@ -609,59 +609,6 @@ describe('test DeviceDetail', () => {
|
|
|
609
609
|
expect(sensorDisplayItem).toHaveLength(0);
|
|
610
610
|
});
|
|
611
611
|
|
|
612
|
-
test('render CurrentRainSensor but is other device', async () => {
|
|
613
|
-
route.params.sensorData.is_other_device = true;
|
|
614
|
-
route.params.isGGHomeConnected = true;
|
|
615
|
-
|
|
616
|
-
const responseDisplay = {
|
|
617
|
-
status: 200,
|
|
618
|
-
data: {
|
|
619
|
-
items: [
|
|
620
|
-
{
|
|
621
|
-
id: 170,
|
|
622
|
-
order: 1,
|
|
623
|
-
template: 'value',
|
|
624
|
-
type: 'value',
|
|
625
|
-
configuration: {
|
|
626
|
-
type: 'circle',
|
|
627
|
-
configs: [
|
|
628
|
-
{
|
|
629
|
-
id: 428,
|
|
630
|
-
color: 'red',
|
|
631
|
-
standard: 'Temperature',
|
|
632
|
-
measure: '°C',
|
|
633
|
-
},
|
|
634
|
-
],
|
|
635
|
-
},
|
|
636
|
-
},
|
|
637
|
-
],
|
|
638
|
-
},
|
|
639
|
-
};
|
|
640
|
-
|
|
641
|
-
const responseDisplayValueV2 = {
|
|
642
|
-
status: 200,
|
|
643
|
-
data: {
|
|
644
|
-
configs: [{ id: 428 }],
|
|
645
|
-
is_connected: true,
|
|
646
|
-
last_updated: '2021-01-24T12:00:00.000Z',
|
|
647
|
-
},
|
|
648
|
-
};
|
|
649
|
-
|
|
650
|
-
mockAxios(responseDisplay, responseDisplayValueV2);
|
|
651
|
-
|
|
652
|
-
await act(async () => {
|
|
653
|
-
tree = await create(wrapComponent(store, account, route));
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
const instance = tree.root;
|
|
657
|
-
const sensorDisplayItem = instance.findAll(
|
|
658
|
-
(el) => el.props.testID === TESTID.SENSOR_DISPLAY_ITEM
|
|
659
|
-
);
|
|
660
|
-
expect(sensorDisplayItem).toHaveLength(1);
|
|
661
|
-
const connectedViewHeader = instance.findByType(ConnectedViewHeader);
|
|
662
|
-
expect(connectedViewHeader.props.type).toEqual('GoogleHome');
|
|
663
|
-
});
|
|
664
|
-
|
|
665
612
|
test('HeaderDevice button more onClick', async () => {
|
|
666
613
|
await act(async () => {
|
|
667
614
|
tree = await create(wrapComponent(store, account, route));
|
|
@@ -14,18 +14,25 @@ export const SensorConnectStatusViewHeader = ({
|
|
|
14
14
|
showWindDirection,
|
|
15
15
|
children,
|
|
16
16
|
}) => {
|
|
17
|
-
const isConnecting =
|
|
18
|
-
!!sensor &&
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
const isConnecting = (() => {
|
|
18
|
+
if (!!sensor && sensor?.is_managed_by_backend) {
|
|
19
|
+
return false;
|
|
20
|
+
} else {
|
|
21
|
+
if (sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
|
|
22
|
+
return false;
|
|
23
|
+
} else if (sensor?.device_type === DEVICE_TYPE.GOOGLE_HOME) {
|
|
24
|
+
return isGGHomeConnecting;
|
|
25
|
+
} else {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
})();
|
|
23
30
|
|
|
24
31
|
if (isConnecting) {
|
|
25
32
|
return <></>;
|
|
26
33
|
}
|
|
27
34
|
|
|
28
|
-
if (!!sensor &&
|
|
35
|
+
if (!!sensor && sensor?.is_managed_by_backend) {
|
|
29
36
|
if (connectedViaNetwork) {
|
|
30
37
|
return (
|
|
31
38
|
<>
|
|
@@ -55,6 +62,7 @@ export const SensorConnectStatusViewHeader = ({
|
|
|
55
62
|
);
|
|
56
63
|
}
|
|
57
64
|
} else {
|
|
65
|
+
// not managed by backend
|
|
58
66
|
if (sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
|
|
59
67
|
return (
|
|
60
68
|
<>
|
|
@@ -62,7 +70,7 @@ export const SensorConnectStatusViewHeader = ({
|
|
|
62
70
|
{children}
|
|
63
71
|
</>
|
|
64
72
|
);
|
|
65
|
-
} else {
|
|
73
|
+
} else if (sensor?.device_type === DEVICE_TYPE.GOOGLE_HOME) {
|
|
66
74
|
if (connectedViaGGHome) {
|
|
67
75
|
return (
|
|
68
76
|
<>
|
|
@@ -83,6 +91,8 @@ export const SensorConnectStatusViewHeader = ({
|
|
|
83
91
|
/>
|
|
84
92
|
);
|
|
85
93
|
}
|
|
94
|
+
} else {
|
|
95
|
+
return <DisconnectedView sensor={sensor} />;
|
|
86
96
|
}
|
|
87
97
|
}
|
|
88
98
|
};
|
|
@@ -33,7 +33,7 @@ import { useFavoriteDevice } from './hooks/useFavoriteDevice';
|
|
|
33
33
|
import BottomButtonView from '../../commons/BottomButtonView';
|
|
34
34
|
import Text from '../../commons/Text';
|
|
35
35
|
import { AlertAction, ButtonPopup, MenuActionMore } from '../../commons';
|
|
36
|
-
import { TESTID } from '../../configs/Constants';
|
|
36
|
+
import { DEVICE_TYPE, TESTID } from '../../configs/Constants';
|
|
37
37
|
|
|
38
38
|
import { usePopover } from '../../hooks/Common';
|
|
39
39
|
import { useConfigGlobalState } from '../../iot/states';
|
|
@@ -51,6 +51,7 @@ import { EmergencyCountdown } from './components/EmergencyCountdown';
|
|
|
51
51
|
import { SensorConnectStatusViewHeader } from './components/SensorConnectStatusViewHeader';
|
|
52
52
|
import { useDisconnectedDevice } from './hooks/useDisconnectedDevice';
|
|
53
53
|
import { useEvaluateValue } from './hooks/useEvaluateValue';
|
|
54
|
+
import { useDeviceWatchConfigControl } from './hooks/useDeviceWatchConfigControl';
|
|
54
55
|
import { Card } from '../../commons/CardShadow';
|
|
55
56
|
import PreventAccess from '../../commons/PreventAccess';
|
|
56
57
|
import { notImplemented } from '../../utils/Utils';
|
|
@@ -122,6 +123,8 @@ const DeviceDetail = ({ route }) => {
|
|
|
122
123
|
|
|
123
124
|
useDisconnectedDevice(sensorName, isDeviceHasBle, serverDown);
|
|
124
125
|
|
|
126
|
+
useDeviceWatchConfigControl(sensor, display);
|
|
127
|
+
|
|
125
128
|
const isShowSetupEmergencyContact = useMemo(
|
|
126
129
|
() =>
|
|
127
130
|
display.items.filter(
|
|
@@ -148,7 +151,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
148
151
|
);
|
|
149
152
|
|
|
150
153
|
const canManageSubUnit = useMemo(() => {
|
|
151
|
-
return currentUserId === unit?.user_id;
|
|
154
|
+
return Number(currentUserId) === Number(unit?.user_id);
|
|
152
155
|
}, [currentUserId, unit]);
|
|
153
156
|
|
|
154
157
|
const fetchUnitDetail = useCallback(async () => {
|
|
@@ -448,20 +451,24 @@ const DeviceDetail = ({ route }) => {
|
|
|
448
451
|
if (!item.configuration) {
|
|
449
452
|
return;
|
|
450
453
|
}
|
|
454
|
+
|
|
451
455
|
const data = item.configuration.configs.map((config) => {
|
|
452
|
-
const configValue = configValues[config.id];
|
|
456
|
+
const configValue = configValues[config.id]?.value;
|
|
453
457
|
const displayValue = displayValues.find((k) => k.id === config.id);
|
|
454
|
-
if (
|
|
458
|
+
if (
|
|
459
|
+
(configValue === null || configValue === undefined) &&
|
|
460
|
+
!displayValue
|
|
461
|
+
) {
|
|
455
462
|
return;
|
|
456
463
|
}
|
|
457
|
-
const value =
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
464
|
+
const value =
|
|
465
|
+
configValue !== null && configValue !== undefined
|
|
466
|
+
? {
|
|
467
|
+
id: config.id,
|
|
468
|
+
value: configValue,
|
|
469
|
+
evaluate: evaluateValue(config.id, configValue),
|
|
470
|
+
}
|
|
471
|
+
: displayValue;
|
|
465
472
|
return { ...config, ...value };
|
|
466
473
|
});
|
|
467
474
|
return data.filter((value) => value);
|
|
@@ -513,7 +520,10 @@ const DeviceDetail = ({ route }) => {
|
|
|
513
520
|
}
|
|
514
521
|
setLoading((preState) => ({ ...preState, isConnected: false }));
|
|
515
522
|
};
|
|
516
|
-
if (
|
|
523
|
+
if (
|
|
524
|
+
sensor?.is_managed_by_backend &&
|
|
525
|
+
sensor?.device_type !== DEVICE_TYPE.LG_THINQ
|
|
526
|
+
) {
|
|
517
527
|
const updateInterval = setInterval(() => fetchValues(), 5000);
|
|
518
528
|
fetchValues();
|
|
519
529
|
return () => clearInterval(updateInterval);
|
|
@@ -721,16 +731,19 @@ const DeviceDetail = ({ route }) => {
|
|
|
721
731
|
isNetworkConnected !== null &&
|
|
722
732
|
renderSensorConnected()}
|
|
723
733
|
</View>
|
|
724
|
-
{
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
+
{isNetworkConnected &&
|
|
735
|
+
isConnected &&
|
|
736
|
+
isShowSetupEmergencyContact &&
|
|
737
|
+
canManageSubUnit && (
|
|
738
|
+
<BottomButtonView
|
|
739
|
+
style={styles.bottomButtonEmergencyContact}
|
|
740
|
+
mainIcon={<Icon name="plus" size={16} color={Colors.Primary} />}
|
|
741
|
+
mainTitle={t('setup_my_emergency_contact')}
|
|
742
|
+
onPressMain={onSetupContacts}
|
|
743
|
+
typeMain="primaryBorder"
|
|
744
|
+
semiboldMain={false}
|
|
745
|
+
/>
|
|
746
|
+
)}
|
|
734
747
|
<AlertSendConfirm
|
|
735
748
|
showAlertConfirm={showAlertConfirm && !lockShowing}
|
|
736
749
|
countDown={countDown}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { renderHook } from '@testing-library/react-hooks';
|
|
3
|
+
import { useEvaluateValue } from '../useEvaluateValue';
|
|
4
|
+
import { SCProvider } from '../../../../context';
|
|
5
|
+
import { mockSCStore } from '../../../../context/mockStore';
|
|
6
|
+
|
|
7
|
+
const wrapper =
|
|
8
|
+
(valueEvaluations) =>
|
|
9
|
+
({ children }) =>
|
|
10
|
+
(
|
|
11
|
+
<SCProvider initState={mockSCStore({ valueEvaluations })}>
|
|
12
|
+
{children}
|
|
13
|
+
</SCProvider>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const mockUseContext = jest.fn().mockImplementation(() => ({
|
|
17
|
+
stateData: mockSCStore({}),
|
|
18
|
+
setAction: jest.fn(),
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
React.useContext = mockUseContext;
|
|
22
|
+
|
|
23
|
+
describe('Test useEvaluateValue', () => {
|
|
24
|
+
let valueEvaluations = {};
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
valueEvaluations = {
|
|
28
|
+
[1]: {
|
|
29
|
+
template: 'range',
|
|
30
|
+
configuration: {
|
|
31
|
+
ranges: [
|
|
32
|
+
{ start: 0.5, end: 1.5, evaluate: { text: 'On' } },
|
|
33
|
+
{ start: -0.5, end: 0.49, evaluate: { text: 'Off' } },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
[2]: {
|
|
38
|
+
template: 'boolean',
|
|
39
|
+
configuration: {
|
|
40
|
+
on: {
|
|
41
|
+
value: 1,
|
|
42
|
+
evaluate: {
|
|
43
|
+
text: 'On',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
off: {
|
|
47
|
+
value: 0,
|
|
48
|
+
evaluate: {
|
|
49
|
+
text: 'Off',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('test value null or undefined', async () => {
|
|
58
|
+
const { result: evaluateValue } = renderHook(() => useEvaluateValue(), {
|
|
59
|
+
wrapper: wrapper(valueEvaluations),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
expect(evaluateValue.current(1, null).text).toBe('--');
|
|
63
|
+
expect(evaluateValue.current(1, undefined).text).toBe('--');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('test not found ValueEvaluation', async () => {
|
|
67
|
+
const { result: evaluateValue } = renderHook(() => useEvaluateValue(), {
|
|
68
|
+
wrapper: wrapper(valueEvaluations),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(evaluateValue.current(3, 1)).toBe(null);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('test template not handle', async () => {
|
|
75
|
+
valueEvaluations[1].template = 'other_template';
|
|
76
|
+
const { result: evaluateValue } = renderHook(() => useEvaluateValue(), {
|
|
77
|
+
wrapper: wrapper(valueEvaluations),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
expect(evaluateValue.current(1, 1)).toBe(null);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('test evaluate range', async () => {
|
|
84
|
+
const { result: evaluateValue } = renderHook(() => useEvaluateValue(), {
|
|
85
|
+
wrapper: wrapper(valueEvaluations),
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
expect(evaluateValue.current(1, 1).text).toBe('On');
|
|
89
|
+
expect(evaluateValue.current(1, 0).text).toBe('Off');
|
|
90
|
+
expect(evaluateValue.current(1, 100).text).toBe(100);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('test evaluate boolean', async () => {
|
|
94
|
+
const { result: evaluateValue } = renderHook(() => useEvaluateValue(), {
|
|
95
|
+
wrapper: wrapper(valueEvaluations),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
expect(evaluateValue.current(2, 0).text).toBe('Off');
|
|
99
|
+
expect(evaluateValue.current(2, 1).text).toBe('On');
|
|
100
|
+
expect(evaluateValue.current(2, 2).text).toBe(2);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { DEVICE_TYPE } from '../../../configs/Constants';
|
|
3
|
+
import { getConfigControlFromDeviceDisplay } from '../utils';
|
|
4
|
+
import { useWatchConfigs } from '../../../hooks/IoT';
|
|
5
|
+
|
|
6
|
+
export const useDeviceWatchConfigControl = (device, display) => {
|
|
7
|
+
const configsNeedWatching = useMemo(() => {
|
|
8
|
+
if (
|
|
9
|
+
!device?.is_managed_by_backend ||
|
|
10
|
+
[DEVICE_TYPE.GOOGLE_HOME, DEVICE_TYPE.LG_THINQ].includes(
|
|
11
|
+
device?.device_type
|
|
12
|
+
)
|
|
13
|
+
) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
return getConfigControlFromDeviceDisplay(display);
|
|
17
|
+
}, [device, display]);
|
|
18
|
+
|
|
19
|
+
useWatchConfigs(configsNeedWatching);
|
|
20
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const getConfigControlFromDeviceDisplay = (deviceDisplay) => {
|
|
2
|
+
const configIds = [];
|
|
3
|
+
deviceDisplay?.items.map((item) => {
|
|
4
|
+
if (item.type !== 'action') {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const actionGroup = item.configuration;
|
|
8
|
+
const { configuration } = actionGroup;
|
|
9
|
+
|
|
10
|
+
switch (actionGroup.template) {
|
|
11
|
+
case 'on_off_button_action_template':
|
|
12
|
+
case 'OnOffButtonActionTemplate':
|
|
13
|
+
case 'OnOffSimpleActionTemplate':
|
|
14
|
+
case 'OnOffSmartLockActionTemplate':
|
|
15
|
+
case 'NumberUpDownActionTemplate':
|
|
16
|
+
case 'OptionsDropdownActionTemplate':
|
|
17
|
+
case 'color_picker_template':
|
|
18
|
+
case 'slider_range_template':
|
|
19
|
+
if (configuration.config) {
|
|
20
|
+
configIds.push(configuration.config);
|
|
21
|
+
}
|
|
22
|
+
break;
|
|
23
|
+
case 'StatesGridActionTemplate':
|
|
24
|
+
configuration.options.forEach((option) => {
|
|
25
|
+
configIds.push(option.config);
|
|
26
|
+
});
|
|
27
|
+
break;
|
|
28
|
+
case 'TimerActionTemplate':
|
|
29
|
+
if (configuration.config_hour) {
|
|
30
|
+
configIds.push(configuration.config_hour);
|
|
31
|
+
}
|
|
32
|
+
if (configuration.config_minute) {
|
|
33
|
+
configIds.push(configuration.config_minute);
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
case 'two_button_action_template':
|
|
37
|
+
configIds.push(configuration.button1.config);
|
|
38
|
+
configIds.push(configuration.button2.config);
|
|
39
|
+
break;
|
|
40
|
+
default:
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return configIds;
|
|
45
|
+
};
|