@eohjsc/react-native-smart-city 0.2.90 → 0.2.93
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/Device/current-state.svg +3 -0
- package/assets/images/Device/door-state.svg +3 -0
- package/assets/images/Device/wind-strength.svg +12 -0
- package/package.json +1 -1
- package/src/commons/Action/ItemQuickAction.js +1 -0
- package/src/commons/Action/__test__/ItemQuickAction.test.js +49 -2
- package/src/commons/ActionGroup/ColorPickerTemplate.js +30 -24
- package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +60 -12
- package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/__test__/index.test.js +47 -0
- package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/index.js +2 -0
- package/src/commons/ActionGroup/OnOffTemplate/OnOffSimpleTemplateStyle.js +2 -1
- package/src/commons/ActionGroup/OnOffTemplate/index.js +48 -28
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +31 -11
- package/src/commons/ActionGroup/OptionsDropdownActionTemplateStyle.js +5 -2
- package/src/commons/ActionGroup/SliderRangeTemplate.js +19 -5
- package/src/commons/ActionGroup/TimerActionTemplate.js +14 -10
- package/src/commons/ActionGroup/TimerActionTemplateStyles.js +12 -0
- package/src/commons/ActionGroup/TwoButtonTemplate/TwoButtonTemplateStyles.js +55 -0
- package/src/commons/ActionGroup/TwoButtonTemplate/index.js +170 -0
- package/src/commons/ActionGroup/__test__/ColorPickerTemplate.test.js +74 -0
- package/src/commons/ActionGroup/__test__/OnOffSmartLock.test.js +107 -0
- package/src/commons/ActionGroup/__test__/SliderRangeTemplate.test.js +71 -0
- package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +1 -1
- package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +112 -0
- package/src/commons/ActionGroup/index.js +4 -1
- package/src/commons/Calendar/index.js +5 -1
- package/src/commons/CameraDevice/index.js +6 -1
- package/src/commons/ConnectingProcess/__test__/Connecting.test.js +4 -1
- package/src/commons/Device/HistoryChart.js +2 -2
- package/src/commons/Device/HorizontalBarChart.js +6 -2
- package/src/commons/Device/ItemDevice.js +3 -13
- package/src/commons/IconComponent/index.js +32 -26
- package/src/commons/MediaPlayerDetail/index.js +16 -4
- package/src/commons/SubUnit/Favorites/index.js +11 -41
- package/src/commons/SubUnit/ShortDetail.js +7 -41
- package/src/commons/SubUnit/__test__/Favorites.test.js +33 -35
- package/src/configs/API.js +4 -0
- package/src/configs/Constants.js +26 -0
- package/src/context/actionType.ts +17 -0
- package/src/context/mockStore.ts +18 -0
- package/src/context/reducer.ts +102 -0
- package/src/hooks/Common/index.js +2 -0
- package/src/hooks/Common/useSensorsStatus.js +52 -0
- package/src/iot/RemoteControl/Bluetooth.js +2 -0
- package/src/iot/RemoteControl/GoogleHome.js +1 -0
- package/src/navigations/AutomateStack.js +16 -1
- package/src/navigations/UnitStack.js +27 -0
- package/src/screens/AddNewAction/Device/__test__/index.test.js +1 -1
- package/src/screens/AddNewAction/SelectAction.js +13 -15
- package/src/screens/AddNewAction/__test__/SelectAction.test.js +0 -7
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +2 -0
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +2 -0
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/ConnectWifiWarning.test.js +10 -0
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +15 -0
- package/src/screens/AddNewGateway/SetupGatewayWifi.js +6 -1
- package/src/screens/AddNewGateway/__test__/SelectGateway.test.js +61 -0
- package/src/screens/AddNewGateway/__test__/SetupGateway.test.js +34 -0
- package/src/screens/AllCamera/index.js +1 -0
- package/src/screens/Automate/MultiUnits.js +9 -9
- package/src/screens/Automate/index.js +21 -20
- package/src/screens/Device/__test__/DetailHistoryChart.test.js +40 -0
- package/src/screens/Device/__test__/detail.test.js +119 -86
- package/src/screens/Device/detail.js +84 -80
- package/src/screens/Device/hooks/useFavoriteDevice.js +38 -0
- package/src/screens/EmergencyContacts/EmergencyContactsList.js +1 -1
- package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +41 -44
- package/src/screens/EmergencyContacts/__test__/EmergencyContactList.test.js +1 -0
- package/src/screens/EmergencyContacts/__test__/EmergencyContactsSelectContacts.test.js +18 -19
- package/src/screens/HanetCamera/Detail.js +20 -13
- package/src/screens/HanetCamera/ManageAccess.js +10 -52
- package/src/screens/HanetCamera/MemberInfo.js +59 -13
- package/src/screens/HanetCamera/__test__/ManageAccess.test.js +19 -0
- package/src/screens/HanetCamera/__test__/MemberInfo.test.js +57 -10
- package/src/screens/HanetCamera/components/RequestFaceIDPopup.js +90 -0
- package/src/screens/HanetCamera/hooks/__test__/useHanetCheckinData.test.js +9 -12
- package/src/screens/HanetCamera/hooks/useHanetCheckinData.js +10 -7
- package/src/screens/HanetCamera/styles/manageAccessStyles.js +0 -14
- package/src/screens/Notification/__test__/NotificationItem.test.js +64 -53
- package/src/screens/Notification/components/NotificationItem.js +13 -4
- package/src/screens/ScriptDetail/__test__/index.test.js +15 -4
- package/src/screens/ScriptDetail/hooks/useStarredScript.js +32 -0
- package/src/screens/ScriptDetail/index.js +11 -20
- package/src/screens/SharedUnit/__test__/TabHeader.test.js +5 -0
- package/src/screens/Sharing/SelectUser.js +3 -23
- package/src/screens/Sharing/__test__/SelectUser.test.js +12 -80
- package/src/screens/SmartIr/__test__/GroupButtonByType.test.js +33 -0
- package/src/screens/SmartIr/components/GroupButtonByType/GroupButtonByType.js +2 -0
- package/src/screens/Unit/ChooseLocation.js +5 -0
- package/src/screens/Unit/Detail.js +34 -44
- package/src/screens/Unit/ManageUnit.js +21 -20
- package/src/screens/Unit/ManageUnitStyles.js +1 -0
- package/src/screens/Unit/SelectAddress.js +8 -2
- package/src/screens/Unit/Summaries.js +12 -15
- package/src/screens/Unit/__test__/Detail.test.js +25 -0
- package/src/screens/Unit/components/MyUnitDevice/index.js +13 -10
- package/src/screens/Unit/components/__test__/Header.test.js +32 -0
- package/src/screens/Unit/components/__test__/MyUnitDevice.test.js +2 -2
- package/src/screens/Unit/hook/useFavorites.js +28 -0
- package/src/utils/Apis/axios.js +7 -2
- package/src/utils/I18n/translations/en.json +2 -4
- package/src/utils/I18n/translations/vi.json +2 -4
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8333 17.5003C10.8333 17.9612 11.2058 18.3337 11.6667 18.3337H14.1667C15.0508 18.3337 15.8983 17.9828 16.5233 17.3578C17.1483 16.7328 17.5 15.8845 17.5 15.0003V14.167C17.5 13.707 17.1267 13.3337 16.6667 13.3337H11.6667C11.2058 13.3337 10.8333 13.707 10.8333 14.167V17.5003ZM8.33333 18.3337C8.79333 18.3337 9.16667 17.9612 9.16667 17.5003V9.16699C9.16667 8.70699 8.79333 8.33366 8.33333 8.33366H3.33333C2.8725 8.33366 2.5 8.70699 2.5 9.16699V15.0003C2.5 15.8845 2.85083 16.7328 3.47583 17.3578C4.10083 17.9828 4.94917 18.3337 5.83333 18.3337H8.33333ZM11.6667 1.66699C11.2058 1.66699 10.8333 2.04033 10.8333 2.50033V10.8337C10.8333 11.2945 11.2058 11.667 11.6667 11.667H16.6667C17.1267 11.667 17.5 11.2945 17.5 10.8337V5.00033C17.5 4.11699 17.1483 3.26866 16.5233 2.64366C15.8983 2.01866 15.0508 1.66699 14.1667 1.66699H11.6667ZM9.16667 2.50033C9.16667 2.04033 8.79333 1.66699 8.33333 1.66699H5.83333C4.94917 1.66699 4.10083 2.01866 3.47583 2.64366C2.85083 3.26866 2.5 4.11699 2.5 5.00033V5.83366C2.5 6.29449 2.8725 6.66699 3.33333 6.66699H8.33333C8.79333 6.66699 9.16667 6.29449 9.16667 5.83366V2.50033Z" fill="#262626"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="14" height="20" viewBox="0 0 14 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M5.08207 0V1.4578H0.44812V18.5208L5.08207 18.5246V20L13.543 18.4803L13.5517 1.53027L5.08207 0ZM6.4854 9.33048C6.76956 9.33048 6.99993 9.63026 6.99993 10C6.99993 10.3698 6.7696 10.6695 6.4854 10.6695C6.20121 10.6695 5.97087 10.3698 5.97087 10C5.97083 9.63026 6.20125 9.33048 6.4854 9.33048ZM1.82397 17.1461V2.83366H5.08207V17.1487L1.82397 17.1461Z" fill="#262626"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M9.58338 8.90405C8.73524 8.90405 8.04529 9.59401 8.04529 10.4421C8.04529 11.2903 8.73524 11.9802 9.58338 11.9802C10.4315 11.9802 11.1215 11.2903 11.1215 10.4421C11.1215 9.59401 10.4315 8.90405 9.58338 8.90405Z" fill="#262626"/>
|
|
3
|
+
<path d="M10.0896 1.0983C10.05 0.849986 9.8352 0.666748 9.58337 0.666748C9.33153 0.666748 9.11722 0.849507 9.07716 1.09782C8.70402 4.72594 7.74586 6.7972 8.36633 8.20011C8.73014 8.00173 9.14063 7.87868 9.58337 7.87868C10.021 7.87868 10.4271 7.99913 10.788 8.19334C11.4004 6.7651 10.4525 4.62911 10.0896 1.0983Z" fill="#262626"/>
|
|
4
|
+
<path d="M18.1316 14.6488C15.1069 12.5509 13.6552 10.7323 12.1377 10.5322C12.1065 11.4101 11.6353 12.1731 10.9347 12.6112C11.8983 13.8846 14.3342 14.0934 17.6464 15.5385C17.8858 15.6247 18.1498 15.5233 18.2708 15.3017C18.392 15.0794 18.3329 14.802 18.1316 14.6488Z" fill="#262626"/>
|
|
5
|
+
<path d="M7.02812 10.5229C5.53447 10.7118 4.13354 12.5038 1.03566 14.6484C0.833895 14.8021 0.774798 15.0795 0.895965 15.3018C1.01399 15.5191 1.27536 15.6259 1.52033 15.5386C4.89766 14.0713 7.29305 13.8803 8.2387 12.6149C7.53207 12.1759 7.05629 11.4075 7.02812 10.5229Z" fill="#262626"/>
|
|
6
|
+
<path d="M4.08742 9.17253C4.02384 9.44843 4.19607 9.72381 4.47194 9.78739C4.51101 9.79641 4.54956 9.80041 4.5876 9.80041C4.82091 9.80041 5.03221 9.64018 5.08677 9.40287C5.36653 8.18688 6.13776 7.15968 7.1704 6.52144C7.2054 6.12909 7.26884 5.71527 7.34947 5.27661C5.72907 5.98082 4.49129 7.4176 4.08742 9.17253Z" fill="#262626"/>
|
|
7
|
+
<path d="M1.89294 10.4422C1.89294 10.7542 1.91147 11.0611 1.94753 11.3635C1.98157 11.649 2.24199 11.8456 2.51731 11.8121C2.7982 11.7786 2.99945 11.5237 2.96592 11.2423C2.93488 10.98 2.91834 10.7131 2.91834 10.4422C2.91834 7.49837 4.87318 4.95502 7.57711 4.0943C7.6469 3.73856 7.71731 3.3685 7.78564 2.9729C4.39986 3.79175 1.89294 6.86092 1.89294 10.4422Z" fill="#262626"/>
|
|
8
|
+
<path d="M11.5742 15.1955C11.4916 14.9246 11.2062 14.7694 10.9339 14.8556C9.76304 15.2133 8.46678 15.0536 7.38673 14.4771C7.02542 14.6444 6.62582 14.7981 6.20032 14.9462C7.17034 15.6732 8.35757 16.0817 9.58353 16.0817C10.1458 16.0817 10.7011 15.9991 11.2343 15.8359C11.5046 15.7533 11.6574 15.4663 11.5742 15.1955Z" fill="#262626"/>
|
|
9
|
+
<path d="M14.2983 15.8736C14.1291 15.6483 13.8076 15.6027 13.5803 15.7724C12.4192 16.6457 11.0374 17.1073 9.5834 17.1073C7.89129 17.1073 6.28662 16.4572 5.06627 15.3291C4.72242 15.4422 4.36162 15.5636 3.98523 15.6951C5.4295 17.2333 7.44556 18.1668 9.5834 18.1668C11.2612 18.1668 12.8568 17.5999 14.1972 16.5916C14.4235 16.4213 14.4685 16.0999 14.2983 15.8736Z" fill="#262626"/>
|
|
10
|
+
<path d="M12.603 3.36954C12.3451 3.2574 12.0417 3.37809 11.9301 3.63895C11.8184 3.89882 11.9391 4.20022 12.1994 4.31188C14.6593 5.36629 16.2484 7.77255 16.2484 10.4422C16.2484 10.9121 16.1958 11.3723 16.1007 11.8223C16.3763 12.0494 16.6665 12.2855 16.9745 12.5304C17.1657 11.8552 17.2739 11.1587 17.2739 10.4422C17.2739 7.36147 15.4404 4.58522 12.603 3.36954Z" fill="#262626"/>
|
|
11
|
+
<path d="M13.4302 6.31817C13.2224 6.12441 12.8979 6.13593 12.7057 6.34271C12.5124 6.54998 12.5234 6.87445 12.7302 7.0677C13.6476 7.92394 14.1551 9.07894 14.1859 10.3264C14.5032 10.5404 14.8303 10.7891 15.1759 11.0666C15.1989 10.8595 15.2231 10.6523 15.2231 10.4423C15.2231 8.88515 14.5697 7.38161 13.4302 6.31817Z" fill="#262626"/>
|
|
12
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -41,7 +41,6 @@ describe('Test ItemQuickAction', () => {
|
|
|
41
41
|
command_prefer_over_googlehome: false,
|
|
42
42
|
command_prefer_over_internet: false,
|
|
43
43
|
id: 9,
|
|
44
|
-
icon: 'caret-up',
|
|
45
44
|
},
|
|
46
45
|
quick_action: {
|
|
47
46
|
config_id: 51,
|
|
@@ -97,9 +96,42 @@ describe('Test ItemQuickAction', () => {
|
|
|
97
96
|
expect(buttonOnActionPress).toHaveLength(0);
|
|
98
97
|
});
|
|
99
98
|
|
|
100
|
-
test('render with full action data case on', () => {
|
|
99
|
+
test('render with full action data case on and icon up', () => {
|
|
101
100
|
const mockSetStatus = jest.fn();
|
|
101
|
+
sensor.action.icon = 'up';
|
|
102
|
+
act(() => {
|
|
103
|
+
tree = create(
|
|
104
|
+
<ItemQuickAction
|
|
105
|
+
sensor={sensor}
|
|
106
|
+
wrapperStyle={style}
|
|
107
|
+
setStatus={mockSetStatus}
|
|
108
|
+
/>
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const instance = tree.root;
|
|
113
|
+
const buttonOnActionPress = instance.find(
|
|
114
|
+
(el) =>
|
|
115
|
+
el.props.testID === TESTID.ITEM_QUICK_ACTION_PRESS &&
|
|
116
|
+
el.type === TouchableOpacity
|
|
117
|
+
);
|
|
118
|
+
expect(buttonOnActionPress).toBeDefined();
|
|
102
119
|
|
|
120
|
+
mockSetState.mockClear();
|
|
121
|
+
act(() => {
|
|
122
|
+
buttonOnActionPress.props.onPress();
|
|
123
|
+
});
|
|
124
|
+
expect(sendRemoteCommand).toBeCalled();
|
|
125
|
+
expect(mockSetState).toBeCalledTimes(1);
|
|
126
|
+
|
|
127
|
+
jest.runAllTimers();
|
|
128
|
+
expect(mockSetState).toBeCalledTimes(3);
|
|
129
|
+
expect(mockSetState).toBeCalledWith(sensor.quick_action.off_action);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test('render with icon_outlined poweroff', () => {
|
|
133
|
+
const mockSetStatus = jest.fn();
|
|
134
|
+
sensor.action.icon = null;
|
|
103
135
|
act(() => {
|
|
104
136
|
tree = create(
|
|
105
137
|
<ItemQuickAction
|
|
@@ -188,6 +220,21 @@ describe('Test ItemQuickAction', () => {
|
|
|
188
220
|
expect(buttonOnActionPress).toBeDefined();
|
|
189
221
|
});
|
|
190
222
|
|
|
223
|
+
test('click quick action icon down , isSendingCommand = true', () => {
|
|
224
|
+
sensor.action.icon = 'down';
|
|
225
|
+
useState.mockImplementationOnce((init) => [true, mockSetState]);
|
|
226
|
+
act(() => {
|
|
227
|
+
tree = create(<ItemQuickAction sensor={sensor} wrapperStyle={style} />);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const instance = tree.root;
|
|
231
|
+
const buttonOnActionPress = instance.find(
|
|
232
|
+
(el) =>
|
|
233
|
+
el.props.testID === TESTID.ITEM_QUICK_ACTION_PRESS &&
|
|
234
|
+
el.type === TouchableOpacity
|
|
235
|
+
);
|
|
236
|
+
expect(buttonOnActionPress).toBeDefined();
|
|
237
|
+
});
|
|
191
238
|
test('trigger action with quick action no auto update', () => {
|
|
192
239
|
const noAutoUpdateSensor = {
|
|
193
240
|
action: {
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import React, { memo, useCallback, useState } from 'react';
|
|
1
|
+
import React, { memo, useCallback, useState, useEffect, useMemo } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
import styles from './ColorPickerTemplateStyles';
|
|
4
4
|
import ColorPicker from 'react-native-wheel-color-picker';
|
|
5
|
+
import { watchMultiConfigs } from '../../iot/Monitor';
|
|
6
|
+
import { useConfigGlobalState } from '../../iot/states';
|
|
5
7
|
|
|
6
|
-
const ColorPickerTemplate = memo(({ actionGroup, doAction }) => {
|
|
8
|
+
const ColorPickerTemplate = memo(({ actionGroup, doAction, sensor }) => {
|
|
7
9
|
const { configuration } = actionGroup;
|
|
8
|
-
const [
|
|
10
|
+
const [valueColorComplete, setValueColorComplete] = useState('');
|
|
9
11
|
const [isFirstColor, setIsFirstColor] = useState(false);
|
|
12
|
+
const [configValues] = useConfigGlobalState('configValues');
|
|
10
13
|
|
|
11
14
|
const onChangeColor = useCallback(
|
|
12
15
|
(color) => {
|
|
@@ -14,35 +17,38 @@ const ColorPickerTemplate = memo(({ actionGroup, doAction }) => {
|
|
|
14
17
|
setIsFirstColor(true);
|
|
15
18
|
return;
|
|
16
19
|
}
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
doAction(
|
|
21
|
+
configuration?.action_color_data,
|
|
22
|
+
JSON.stringify({ value: color })
|
|
23
|
+
);
|
|
19
24
|
},
|
|
20
25
|
[configuration?.action_color_data, doAction, isFirstColor]
|
|
21
26
|
);
|
|
27
|
+
const valueColor = useMemo(() => {
|
|
28
|
+
return valueColorComplete || '';
|
|
29
|
+
}, [valueColorComplete]);
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
/>
|
|
35
|
-
);
|
|
36
|
-
},
|
|
37
|
-
[]
|
|
38
|
-
);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const { config } = configuration;
|
|
33
|
+
const configValue = configValues[config];
|
|
34
|
+
setValueColorComplete(configValue);
|
|
35
|
+
}, [configuration.config, configValues, configuration]);
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (sensor?.is_managed_by_backend) {
|
|
39
|
+
watchMultiConfigs([configuration.config]);
|
|
40
|
+
}
|
|
41
|
+
}, [sensor, configuration.config]);
|
|
39
42
|
|
|
40
43
|
return (
|
|
41
44
|
<View style={styles.viewPickColor}>
|
|
42
|
-
<
|
|
45
|
+
<ColorPicker
|
|
43
46
|
style={styles.colorPicker}
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
sliderHidden={true}
|
|
48
|
+
swatches={false}
|
|
49
|
+
color={valueColor}
|
|
50
|
+
onColorChangeComplete={onChangeColor}
|
|
51
|
+
thumbSize={16}
|
|
46
52
|
/>
|
|
47
53
|
</View>
|
|
48
54
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { memo, useCallback, useState } from 'react';
|
|
1
|
+
import React, { memo, useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { SafeAreaView, TouchableOpacity, View } from 'react-native';
|
|
3
3
|
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
4
4
|
import { Section } from '../../Section';
|
|
@@ -6,14 +6,58 @@ import Text from '../../Text';
|
|
|
6
6
|
import styles from './OnOffSmartLockStyle';
|
|
7
7
|
import ButtonLock from '../../../../assets/images/Device/button-lock.svg';
|
|
8
8
|
import ButtonUnLock from '../../../../assets/images/Device/button-unlock.svg';
|
|
9
|
+
import { useConfigGlobalState } from '../../../iot/states';
|
|
10
|
+
import { watchMultiConfigs } from '../../../iot/Monitor';
|
|
11
|
+
import { TESTID } from '../../../configs/Constants';
|
|
9
12
|
|
|
10
13
|
const OnOffSmartLock = memo(({ actionGroup, doAction, sensor }) => {
|
|
11
14
|
const t = useTranslations();
|
|
12
|
-
const
|
|
15
|
+
const { configuration } = actionGroup;
|
|
16
|
+
const { action_on_data, action_off_data } = configuration;
|
|
17
|
+
const [isUnlock, setisUnlock] = useState(true);
|
|
18
|
+
const [configValues] = useConfigGlobalState('configValues');
|
|
13
19
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
const handleActionSmartLock = useCallback(() => {
|
|
21
|
+
if (action_on_data && action_off_data) {
|
|
22
|
+
if (isUnlock) {
|
|
23
|
+
let actionName = `${
|
|
24
|
+
sensor?.name
|
|
25
|
+
} ${actionGroup?.title?.toLowerCase()} lock`;
|
|
26
|
+
actionName = actionName.replace(/\s+/g, ' ').trim();
|
|
27
|
+
const dataLock = { door_lock: 0 };
|
|
28
|
+
doAction(action_on_data, JSON.stringify(dataLock), actionName);
|
|
29
|
+
} else {
|
|
30
|
+
let actionName = `${
|
|
31
|
+
sensor?.name
|
|
32
|
+
} ${actionGroup?.title?.toLowerCase()} unlock`;
|
|
33
|
+
actionName = actionName.replace(/\s+/g, ' ').trim();
|
|
34
|
+
const dataUnlock = { door_lock: 1 };
|
|
35
|
+
doAction(action_off_data, JSON.stringify(dataUnlock), actionName);
|
|
36
|
+
}
|
|
37
|
+
if (sensor?.is_managed_by_backend) {
|
|
38
|
+
configuration.config && watchMultiConfigs([configuration.config]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}, [
|
|
42
|
+
actionGroup?.title,
|
|
43
|
+
action_off_data,
|
|
44
|
+
action_on_data,
|
|
45
|
+
doAction,
|
|
46
|
+
isUnlock,
|
|
47
|
+
sensor?.name,
|
|
48
|
+
configuration,
|
|
49
|
+
sensor?.is_managed_by_backend,
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
const { is_on_value, config } = configuration;
|
|
54
|
+
const configValue = configValues[config];
|
|
55
|
+
if (is_on_value && is_on_value.length) {
|
|
56
|
+
setisUnlock(is_on_value.includes(configValue));
|
|
57
|
+
} else {
|
|
58
|
+
setisUnlock(configValue);
|
|
59
|
+
}
|
|
60
|
+
}, [configValues, configuration]);
|
|
17
61
|
|
|
18
62
|
return (
|
|
19
63
|
<SafeAreaView style={styles.container}>
|
|
@@ -22,21 +66,25 @@ const OnOffSmartLock = memo(({ actionGroup, doAction, sensor }) => {
|
|
|
22
66
|
<View style={styles.wrapController}>
|
|
23
67
|
<Text style={styles.textController}>{t('controller')}</Text>
|
|
24
68
|
</View>
|
|
25
|
-
<View
|
|
26
|
-
<TouchableOpacity
|
|
27
|
-
{
|
|
69
|
+
<View>
|
|
70
|
+
<TouchableOpacity
|
|
71
|
+
onPress={handleActionSmartLock}
|
|
72
|
+
testID={TESTID.BUTTON_ON_OFF}
|
|
73
|
+
style={styles.wrapButtonSmartLock}
|
|
74
|
+
>
|
|
75
|
+
{isUnlock ? (
|
|
28
76
|
<ButtonLock style={styles.buttonSmartLock} />
|
|
29
77
|
) : (
|
|
30
78
|
<ButtonUnLock style={styles.buttonSmartLock} />
|
|
31
79
|
)}
|
|
80
|
+
<Text style={styles.textSmartLock}>
|
|
81
|
+
{t(isUnlock ? 'lock' : 'unlock')}
|
|
82
|
+
</Text>
|
|
32
83
|
</TouchableOpacity>
|
|
33
|
-
<Text style={styles.textSmartLock}>
|
|
34
|
-
{active ? t('lock') : t('unlock')}
|
|
35
|
-
</Text>
|
|
36
84
|
</View>
|
|
37
85
|
<View style={styles.wrapStatus}>
|
|
38
86
|
<Text style={styles.textStatus}>
|
|
39
|
-
{
|
|
87
|
+
{t(isUnlock ? 'door_is_open' : 'door_is_close')}
|
|
40
88
|
</Text>
|
|
41
89
|
</View>
|
|
42
90
|
</Section>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { act, create } from 'react-test-renderer';
|
|
3
|
+
|
|
4
|
+
import { mockSCStore } from '../../../../../context/mockStore';
|
|
5
|
+
import { TESTID } from '../../../../../configs/Constants';
|
|
6
|
+
import { SCProvider } from '../../../../../context';
|
|
7
|
+
import PasscodeList from '../index';
|
|
8
|
+
import { TouchableOpacity } from 'react-native';
|
|
9
|
+
|
|
10
|
+
const mockNavigate = jest.fn();
|
|
11
|
+
jest.mock('@react-navigation/native', () => {
|
|
12
|
+
return {
|
|
13
|
+
...jest.requireActual('@react-navigation/native'),
|
|
14
|
+
useNavigation: () => ({
|
|
15
|
+
navigate: mockNavigate,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const wrapComponent = () => (
|
|
21
|
+
<SCProvider initState={mockSCStore({})}>
|
|
22
|
+
<PasscodeList />
|
|
23
|
+
</SCProvider>
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
describe('Test SetupGeneratePasscode', () => {
|
|
27
|
+
let tree;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
mockNavigate.mockClear();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('render PasscodeList', async () => {
|
|
34
|
+
await act(async () => {
|
|
35
|
+
tree = await create(wrapComponent());
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const instance = tree.root;
|
|
39
|
+
const passcode_list = instance.findAll(
|
|
40
|
+
(item) =>
|
|
41
|
+
item.props.testID === TESTID.PASSCODE_LIST &&
|
|
42
|
+
item.type === TouchableOpacity
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
expect(passcode_list).toHaveLength(3);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -9,6 +9,7 @@ import t from '../../../../hooks/Common/useTranslations';
|
|
|
9
9
|
import { Colors } from '../../../../configs';
|
|
10
10
|
import Routes from '../../../../utils/Route';
|
|
11
11
|
import styles from './PasscodeListStyles';
|
|
12
|
+
import { TESTID } from '../../../../configs/Constants';
|
|
12
13
|
|
|
13
14
|
const PasscodeList = memo(() => {
|
|
14
15
|
const navigation = useNavigation();
|
|
@@ -50,6 +51,7 @@ const PasscodeList = memo(() => {
|
|
|
50
51
|
<TouchableOpacity
|
|
51
52
|
onPress={handleClickButton(item)}
|
|
52
53
|
style={styles.buttonWrapper}
|
|
54
|
+
testID={TESTID.PASSCODE_LIST}
|
|
53
55
|
>
|
|
54
56
|
<View>
|
|
55
57
|
<Text style={styles.textCode}>{item.code}</Text>
|
|
@@ -3,7 +3,7 @@ import { StyleSheet } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
export default StyleSheet.create({
|
|
5
5
|
wrap: {
|
|
6
|
-
paddingVertical:
|
|
6
|
+
paddingVertical: 16,
|
|
7
7
|
paddingHorizontal: 16,
|
|
8
8
|
marginHorizontal: 20,
|
|
9
9
|
marginTop: 20,
|
|
@@ -21,5 +21,6 @@ export default StyleSheet.create({
|
|
|
21
21
|
},
|
|
22
22
|
marginRight: {
|
|
23
23
|
marginRight: 10,
|
|
24
|
+
paddingBottom: 2,
|
|
24
25
|
},
|
|
25
26
|
});
|
|
@@ -24,48 +24,69 @@ const OnOffTemplate = memo(({ actionGroup, doAction, sensor }) => {
|
|
|
24
24
|
// eslint-disable-next-line no-unused-vars
|
|
25
25
|
const [configValues, _] = useConfigGlobalState('configValues');
|
|
26
26
|
|
|
27
|
+
const actionName = useCallback(
|
|
28
|
+
(text) => {
|
|
29
|
+
const actionNameType = `${
|
|
30
|
+
sensor?.name
|
|
31
|
+
} ${actionGroup?.title?.toLowerCase()} ${text}`;
|
|
32
|
+
return actionNameType.replace(/\s+/g, ' ').trim();
|
|
33
|
+
},
|
|
34
|
+
[actionGroup?.title, sensor?.name]
|
|
35
|
+
);
|
|
27
36
|
const triggerAction = useCallback(() => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
switch (sensor?.device_type) {
|
|
38
|
+
case DEVICE_TYPE.ZIGBEE:
|
|
39
|
+
if (action_on_data && action_off_data) {
|
|
40
|
+
if (isOn) {
|
|
41
|
+
doAction(
|
|
42
|
+
action_off_data,
|
|
43
|
+
JSON.stringify({ state: 0 }),
|
|
44
|
+
actionName('off')
|
|
45
|
+
);
|
|
46
|
+
} else {
|
|
47
|
+
doAction(
|
|
48
|
+
action_on_data,
|
|
49
|
+
JSON.stringify({ state: 1 }),
|
|
50
|
+
actionName('on')
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return;
|
|
55
|
+
default:
|
|
56
|
+
if (action_data) {
|
|
57
|
+
if (isOn) {
|
|
58
|
+
doAction(action_data, false);
|
|
59
|
+
} else {
|
|
60
|
+
doAction(action_data, true);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (action_on_data && action_off_data) {
|
|
64
|
+
if (isOn) {
|
|
65
|
+
doAction(action_off_data, null, actionName('off'));
|
|
66
|
+
} else {
|
|
67
|
+
doAction(action_on_data, null, actionName('on'));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (sensor?.is_managed_by_backend) {
|
|
71
|
+
configuration.config && watchMultiConfigs([configuration.config]);
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
52
74
|
}
|
|
53
75
|
}, [
|
|
54
|
-
|
|
76
|
+
actionName,
|
|
55
77
|
action_data,
|
|
56
78
|
action_off_data,
|
|
57
79
|
action_on_data,
|
|
58
80
|
configuration.config,
|
|
59
81
|
doAction,
|
|
60
82
|
isOn,
|
|
83
|
+
sensor?.device_type,
|
|
61
84
|
sensor?.is_managed_by_backend,
|
|
62
|
-
sensor?.name,
|
|
63
85
|
]);
|
|
64
86
|
|
|
65
87
|
useEffect(() => {
|
|
66
88
|
const { is_on_value, config } = configuration;
|
|
67
89
|
const configValue = configValues[config];
|
|
68
|
-
|
|
69
90
|
if (is_on_value && is_on_value.length > 0) {
|
|
70
91
|
setIsOn(is_on_value.includes(configValue));
|
|
71
92
|
return;
|
|
@@ -82,7 +103,6 @@ const OnOffTemplate = memo(({ actionGroup, doAction, sensor }) => {
|
|
|
82
103
|
if (sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
|
|
83
104
|
return;
|
|
84
105
|
}
|
|
85
|
-
|
|
86
106
|
if (sensor?.is_managed_by_backend) {
|
|
87
107
|
watchMultiConfigs([configuration.config]);
|
|
88
108
|
}
|
|
@@ -12,6 +12,9 @@ import { watchMultiConfigs } from '../../iot/Monitor';
|
|
|
12
12
|
import { TESTID } from '../../configs/Constants';
|
|
13
13
|
import IconComponent from '../../commons/IconComponent';
|
|
14
14
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
15
|
+
import SvgDoorState from '../../../assets/images/Device/door-state.svg';
|
|
16
|
+
import SvgCurrentState from '../../../assets/images/Device/current-state.svg';
|
|
17
|
+
import SvgWindStrength from '../../../assets/images/Device/wind-strength.svg';
|
|
15
18
|
|
|
16
19
|
function getOptionValue(option) {
|
|
17
20
|
if (option.value_text) {
|
|
@@ -27,7 +30,7 @@ const OptionsDropdownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
27
30
|
configuration;
|
|
28
31
|
// eslint-disable-next-line no-unused-vars
|
|
29
32
|
const [configValues, setConfigValues] = useConfigGlobalState('configValues');
|
|
30
|
-
|
|
33
|
+
const checkIcon = /\d/.test(icon); // to do check icon svg and icon antDesign
|
|
31
34
|
const selectedOption = useMemo(() => {
|
|
32
35
|
const currentValue = configValues[configuration.config];
|
|
33
36
|
if (currentValue === null || currentValue === undefined) {
|
|
@@ -84,23 +87,40 @@ const OptionsDropdownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
84
87
|
return selectedOption.text;
|
|
85
88
|
}, [configuration.config, selectedOption.text, t]);
|
|
86
89
|
|
|
90
|
+
const iconSvg = useMemo(() => {
|
|
91
|
+
switch (icon) {
|
|
92
|
+
case 'door-state-1':
|
|
93
|
+
return <SvgDoorState width={24} height={24} />;
|
|
94
|
+
case 'curent-state-1':
|
|
95
|
+
return <SvgCurrentState width={24} height={24} />;
|
|
96
|
+
case 'wind-strength-1':
|
|
97
|
+
return <SvgWindStrength width={24} height={24} />;
|
|
98
|
+
default:
|
|
99
|
+
return () => <></>;
|
|
100
|
+
}
|
|
101
|
+
}, [icon]);
|
|
102
|
+
|
|
87
103
|
return (
|
|
88
104
|
<View style={styles.wrap}>
|
|
89
105
|
<View style={styles.iconAndText}>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
{!checkIcon && (
|
|
107
|
+
<IconComponent
|
|
108
|
+
icon={icon}
|
|
109
|
+
iconKit={iconKit}
|
|
110
|
+
icon_outlined={icon_outlined}
|
|
111
|
+
isSendingCommand={false}
|
|
112
|
+
size={17}
|
|
113
|
+
style={styles.marginRight}
|
|
114
|
+
/>
|
|
115
|
+
)}
|
|
116
|
+
{checkIcon && <View style={styles.marginRight}>{iconSvg}</View>}
|
|
117
|
+
<Text style={styles.textTitle} type="H4">
|
|
118
|
+
{title}
|
|
119
|
+
</Text>
|
|
99
120
|
</View>
|
|
100
121
|
<TouchableOpacity style={styles.iconAndTextOption} onPress={onShowAlert}>
|
|
101
122
|
<Text
|
|
102
123
|
testID={TESTID.OPTIONS_DROPDOWN_ACTION_DISPLAY_SELECTED}
|
|
103
|
-
type="Body"
|
|
104
124
|
color={
|
|
105
125
|
displaySelected === t('not_available') ? Colors.Gray6 : Colors.Gray8
|
|
106
126
|
}
|
|
@@ -3,7 +3,7 @@ import { Colors } from '../../configs';
|
|
|
3
3
|
|
|
4
4
|
export default StyleSheet.create({
|
|
5
5
|
wrap: {
|
|
6
|
-
paddingVertical:
|
|
6
|
+
paddingVertical: 16,
|
|
7
7
|
paddingHorizontal: 16,
|
|
8
8
|
marginHorizontal: 20,
|
|
9
9
|
marginTop: 20,
|
|
@@ -43,7 +43,7 @@ export default StyleSheet.create({
|
|
|
43
43
|
},
|
|
44
44
|
text: {
|
|
45
45
|
fontSize: 16,
|
|
46
|
-
lineHeight:
|
|
46
|
+
lineHeight: 20,
|
|
47
47
|
color: Colors.Gray9,
|
|
48
48
|
},
|
|
49
49
|
writeNotAvailable: {
|
|
@@ -52,4 +52,7 @@ export default StyleSheet.create({
|
|
|
52
52
|
scrollView: {
|
|
53
53
|
height: 350,
|
|
54
54
|
},
|
|
55
|
+
textTitle: {
|
|
56
|
+
paddingTop: 2,
|
|
57
|
+
},
|
|
55
58
|
});
|
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import React, { memo, useCallback, useState, useMemo } from 'react';
|
|
1
|
+
import React, { memo, useCallback, useState, useMemo, useEffect } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
4
4
|
import styles from './SliderRangeTemplateStyles';
|
|
5
5
|
import Text from '../Text';
|
|
6
6
|
import { Colors } from '../../configs';
|
|
7
7
|
import SvgBrightness from '../../../assets/images/brightness.svg';
|
|
8
|
-
import
|
|
8
|
+
import SliderRange from 'react-native-slider';
|
|
9
|
+
import { watchMultiConfigs } from '../../iot/Monitor';
|
|
10
|
+
import { useConfigGlobalState } from '../../iot/states';
|
|
9
11
|
|
|
10
|
-
const SliderRangeTemplate = memo(({ actionGroup, doAction }) => {
|
|
12
|
+
const SliderRangeTemplate = memo(({ actionGroup, doAction, sensor }) => {
|
|
11
13
|
const t = useTranslations();
|
|
12
14
|
const { configuration } = actionGroup;
|
|
13
15
|
const [valueBrightness, setValueBrightness] = useState(0);
|
|
16
|
+
const [configValues] = useConfigGlobalState('configValues');
|
|
14
17
|
|
|
15
18
|
const onChangeBrightness = useCallback(
|
|
16
19
|
(value) => {
|
|
17
20
|
setValueBrightness(value);
|
|
18
21
|
doAction(
|
|
19
22
|
configuration?.action_brightness_data,
|
|
20
|
-
|
|
23
|
+
JSON.stringify({ value_brness: value })
|
|
21
24
|
);
|
|
22
25
|
},
|
|
23
26
|
[configuration?.action_brightness_data, doAction]
|
|
@@ -27,6 +30,17 @@ const SliderRangeTemplate = memo(({ actionGroup, doAction }) => {
|
|
|
27
30
|
return valueBrightness || 0;
|
|
28
31
|
}, [valueBrightness]);
|
|
29
32
|
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const { config } = configuration;
|
|
35
|
+
const configValue = configValues[config];
|
|
36
|
+
setValueBrightness(configValue);
|
|
37
|
+
}, [configuration.config, configValues, configuration]);
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (sensor?.is_managed_by_backend) {
|
|
41
|
+
watchMultiConfigs([configuration.config]);
|
|
42
|
+
}
|
|
43
|
+
}, [sensor, configuration.config]);
|
|
30
44
|
return (
|
|
31
45
|
<View style={styles.viewBrightness}>
|
|
32
46
|
<View style={styles.LeftBrightness}>
|
|
@@ -37,7 +51,7 @@ const SliderRangeTemplate = memo(({ actionGroup, doAction }) => {
|
|
|
37
51
|
</View>
|
|
38
52
|
<View style={styles.RightBrightness}>
|
|
39
53
|
<View style={styles.slider}>
|
|
40
|
-
<
|
|
54
|
+
<SliderRange
|
|
41
55
|
value={valueBrightness}
|
|
42
56
|
onSlidingComplete={onChangeBrightness}
|
|
43
57
|
onValueChange={setValueBrightness}
|