@eohjsc/react-native-smart-city 0.3.0 → 0.3.1
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/README.md +1 -1
- package/package.json +3 -3
- package/src/commons/Action/ItemQuickAction.js +11 -2
- package/src/commons/Action/__test__/ItemQuickAction.test.js +11 -6
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +31 -20
- package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +3 -2
- package/src/commons/ActionGroup/TwoButtonTemplate/index.js +0 -1
- package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +45 -48
- package/src/commons/ActionGroup/__test__/index.test.js +2 -2
- package/src/commons/ConnectingProcess/index.js +11 -7
- package/src/commons/Device/ConnectedViewHeader.js +1 -1
- package/src/commons/Device/HistoryChart.js +3 -3
- package/src/commons/Device/ItemDevice.js +15 -11
- package/src/commons/Device/SonosSpeaker/index.js +1 -1
- package/src/commons/FieldTemplate/ScheduleField/index.js +2 -2
- package/src/commons/Header/HeaderCustom.js +2 -1
- package/src/commons/HorizontalPicker/index.js +2 -2
- package/src/commons/MediaPlayerDetail/Styles/MediaPlayerDetailStyles.js +0 -6
- package/src/commons/MediaPlayerDetail/index.js +19 -50
- package/src/commons/SubUnit/Favorites/index.js +2 -3
- package/src/commons/SubUnit/ShortDetail.js +1 -2
- package/src/commons/SubUnit/__test__/Item.test.js +0 -1
- package/src/commons/UnitSummary/ConfigHistoryChart/index.js +2 -13
- package/src/commons/UnitSummary/ConfigHistoryChart.js +22 -13
- package/src/commons/WheelDateTimePicker/index.js +2 -2
- package/src/configs/API.js +4 -13
- package/src/configs/Constants.js +13 -0
- package/src/context/actionType.ts +8 -0
- package/src/context/mockStore.ts +10 -0
- package/src/context/reducer.ts +38 -2
- package/src/hooks/Common/index.js +2 -0
- package/src/hooks/Common/useGGHomeDeviceConnected.js +16 -0
- package/src/hooks/Common/useGetIdUser.js +1 -5
- package/src/hooks/Common/useSensorsStatus.js +5 -8
- package/src/hooks/IoT/__test__/useGGHomeConnection.test.js +198 -0
- package/src/hooks/IoT/__test__/useRemoteControl.test.js +198 -0
- package/src/hooks/IoT/index.js +4 -0
- package/src/hooks/IoT/useGGHomeConnection.js +91 -0
- package/src/hooks/IoT/useRemoteControl.js +79 -0
- package/src/hooks/index.js +4 -0
- package/src/hooks/useReceiveNotifications.js +8 -4
- package/src/iot/Monitor.js +3 -2
- package/src/iot/RemoteControl/Bluetooth.js +1 -1
- package/src/iot/RemoteControl/GoogleHome.js +75 -49
- package/src/iot/RemoteControl/Internet.js +1 -1
- package/src/iot/RemoteControl/__test__/GoogleHome.test.js +90 -21
- package/src/iot/RemoteControl/__test__/Internet.test.js +4 -4
- package/src/iot/RemoteControl/__test__/LgThinq.test.js +5 -5
- package/src/iot/RemoteControl/index.js +52 -52
- package/src/screens/ActivityLog/hooks/__test__/index.test.js +3 -3
- package/src/screens/ActivityLog/hooks/index.js +1 -1
- package/src/screens/AddLocationMaps/index.js +5 -4
- package/src/screens/AddNewAction/SelectAction.js +8 -8
- package/src/screens/AddNewAction/SetupSensor.js +7 -7
- package/src/screens/AddNewAction/__test__/SelectAction.test.js +2 -2
- package/src/screens/AddNewDevice/ConnectingDevices.js +1 -1
- package/src/screens/AddNewDevice/__test__/ConnectingDevices.test.js +2 -2
- package/src/screens/AddNewDevice/hooks/ConnectDevices.js +1 -1
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +23 -17
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +3 -3
- package/src/screens/AddNewGateway/SetupGatewayWifi.js +1 -0
- package/src/screens/AllCamera/index.js +4 -4
- package/src/screens/Automate/MultiUnits.js +8 -8
- package/src/screens/Automate/index.js +3 -3
- package/src/screens/Device/EditDevice/__test__/EditDevice.test.js +4 -4
- package/src/screens/Device/EditDevice/index.js +2 -2
- package/src/screens/Device/__test__/detail.test.js +13 -5
- package/src/screens/Device/components/DetailHistoryChart.js +1 -1
- package/src/screens/Device/components/SensorConnectStatusViewHeader.js +1 -0
- package/src/screens/Device/components/SensorDisplayItem.js +5 -2
- package/src/screens/Device/detail.js +49 -16
- package/src/screens/Device/hooks/useDisconnectedDevice.js +4 -4
- package/src/screens/EditActionsList/index.js +1 -1
- package/src/screens/EmergencySetting/components/DropDownItem.js +2 -2
- package/src/screens/HanetCamera/Detail.js +1 -1
- package/src/screens/HanetCamera/__test__/Detail.test.js +2 -2
- package/src/screens/HanetCamera/components/RequestFaceIDPopup.js +3 -2
- package/src/screens/HanetCamera/hooks/useHanetCheckinData.js +11 -11
- package/src/screens/HanetCamera/hooks/useHanetPlaceMembers.js +11 -11
- package/src/screens/ManageAccess/hooks/index.js +7 -4
- package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +2 -2
- package/src/screens/MoveToAnotherSubUnit/index.js +1 -1
- package/src/screens/Notification/__test__/NotificationItem.test.js +4 -4
- package/src/screens/Notification/components/NotificationItem.js +17 -20
- package/src/screens/Notification/index.js +9 -2
- package/src/screens/PlayBackCamera/Timer.js +2 -2
- package/src/screens/PlayBackCamera/index.js +3 -3
- package/src/screens/ScanChipQR/hooks/index.js +15 -16
- package/src/screens/ScriptDetail/index.js +14 -10
- package/src/screens/SelectUnit/index.js +4 -2
- package/src/screens/SetSchedule/index.js +9 -9
- package/src/screens/Sharing/Components/SensorItem.js +10 -12
- package/src/screens/Sharing/SelectPermission.js +14 -6
- package/src/screens/SideMenuDetail/__test__/index.test.js +4 -4
- package/src/screens/SideMenuDetail/index.js +2 -3
- package/src/screens/SmartIr/components/GroupButtonByType/GroupButtonByType.js +3 -2
- package/src/screens/SubUnit/Detail.js +1 -2
- package/src/screens/SubUnit/ManageSubUnit.js +12 -7
- package/src/screens/SubUnit/__test__/Detail.test.js +1 -1
- package/src/screens/SubUnit/__test__/ManageSubUnit.test.js +27 -1
- package/src/screens/SubUnit/hooks/__test__/useManageSubUnit.test.js +1 -1
- package/src/screens/SubUnit/hooks/useManageSubUnit.js +7 -7
- package/src/screens/Unit/ChooseLocation.js +6 -13
- package/src/screens/Unit/Detail.js +30 -75
- package/src/screens/Unit/SelectAddress.js +34 -21
- package/src/screens/Unit/SmartAccount.js +4 -4
- package/src/screens/Unit/Summaries.js +17 -1
- package/src/screens/Unit/__test__/CheckSendEmail.test.js +9 -1
- package/src/screens/Unit/__test__/Detail.test.js +16 -15
- package/src/screens/Unit/__test__/SelectAddress.test.js +72 -13
- package/src/screens/Unit/__test__/SmartAccount.test.js +1 -1
- package/src/screens/Unit/__test__/Summaries.test.js +100 -0
- package/src/screens/Unit/hook/useUnitConnectRemoteDevices.js +50 -0
- package/src/screens/Unit/styles.js +4 -0
- package/src/screens/UnitSummary/__test__/index.test.js +55 -1
- package/src/screens/UnitSummary/components/3PPowerConsumption/__test__/3PPowerConsumption.test.js +31 -2
- package/src/screens/UnitSummary/components/PowerConsumeHistoryChart/index.js +2 -13
- package/src/screens/UnitSummary/components/PowerConsumption/__test__/ItemPower.test.js +0 -1
- package/src/screens/UnitSummary/components/RunningDevices/__test__/index.test.js +11 -2
- package/src/screens/UnitSummary/components/RunningDevices/index.js +7 -10
- package/src/screens/UnitSummary/components/Temperature/index.js +4 -4
- package/src/screens/UnitSummary/index.js +15 -1
- package/src/utils/Apis/axios.js +16 -25
- package/src/utils/Converter/time.js +0 -18
- package/src/utils/I18n/translations/en.json +2 -1
- package/src/utils/I18n/translations/vi.json +3 -1
- package/src/utils/Permission/common.js +39 -0
- package/src/utils/Utils.js +5 -1
package/README.md
CHANGED
|
@@ -159,7 +159,7 @@ export const MyFunctionalComponent = () => {
|
|
|
159
159
|
- sendRemoteCommand user needs to `have permission to control the device`, you pass in the `sensor and action` to it and it will run after calling render.
|
|
160
160
|
- `sensor` is a device in your Unit and action is the `action` key of the device..
|
|
161
161
|
- You can take out the sensor and action from your Unit when calling the `API.UNIT.UNIT_DETAIL(unitId)` it will return all devices in 1 unit.
|
|
162
|
-
- Or get sensor from `API.
|
|
162
|
+
- Or get sensor from `API.DEVICE.DISPLAY(sensor.id)` returns all actions of 1 device.
|
|
163
163
|
- Refer YourProjectPath /node_modules/@eohjsc/react-native-smart-city/src/screens/Unit/Detail.js
|
|
164
164
|
|
|
165
165
|
## Sync file to EoH source
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eohjsc/react-native-smart-city",
|
|
3
3
|
"title": "React Native Smart Home",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.01",
|
|
5
5
|
"description": "TODO",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"files": [
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"ios": "react-native run-ios",
|
|
19
19
|
"start": "react-native start",
|
|
20
20
|
"test": "yarn run lint && yarn run jest",
|
|
21
|
-
"lint": "eslint . --ext js --ext ts --ext tsx",
|
|
21
|
+
"lint": "eslint . --ext js --ext ts --ext tsx --max-warnings 5",
|
|
22
22
|
"lint-fix": "eslint . --fix",
|
|
23
23
|
"type-check": "npx tsc",
|
|
24
24
|
"pod": "cd ios && pod install",
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
"react-native-pager-view": "^5.4.1",
|
|
177
177
|
"react-native-parallax-scroll-view": "^0.21.3",
|
|
178
178
|
"react-native-parsed-text": "^0.0.22",
|
|
179
|
-
"react-native-permissions": "
|
|
179
|
+
"react-native-permissions": "3.0.3",
|
|
180
180
|
"react-native-popover-view": "^4.0.3",
|
|
181
181
|
"react-native-progress": "^5.0.0",
|
|
182
182
|
"react-native-reanimated": "1.10.1",
|
|
@@ -3,7 +3,7 @@ import { TouchableOpacity, View } from 'react-native';
|
|
|
3
3
|
import { TESTID } from '../../configs/Constants';
|
|
4
4
|
import { useSCContextSelector } from '../../context';
|
|
5
5
|
import { watchMultiConfigs } from '../../iot/Monitor';
|
|
6
|
-
import {
|
|
6
|
+
import { useRemoteControl } from '../../hooks/IoT';
|
|
7
7
|
import { useConfigGlobalState } from '../../iot/states';
|
|
8
8
|
import IconComponent from '../IconComponent';
|
|
9
9
|
|
|
@@ -13,6 +13,8 @@ const ItemQuickAction = memo(({ sensor, wrapperStyle, setStatus, unit }) => {
|
|
|
13
13
|
// eslint-disable-next-line no-unused-vars
|
|
14
14
|
const [configValues, _] = useConfigGlobalState('configValues');
|
|
15
15
|
|
|
16
|
+
const sendRemoteCommand = useRemoteControl();
|
|
17
|
+
|
|
16
18
|
const revertActionUpdate = useCallback(
|
|
17
19
|
(value, on_action, on_status, off_action, off_status) => {
|
|
18
20
|
setIsSendingCommand(false);
|
|
@@ -81,7 +83,14 @@ const ItemQuickAction = memo(({ sensor, wrapperStyle, setStatus, unit }) => {
|
|
|
81
83
|
statusCallback(action.id === sensor.quick_action.on_action.id);
|
|
82
84
|
}, sensor.quick_action.interval);
|
|
83
85
|
}
|
|
84
|
-
}, [
|
|
86
|
+
}, [
|
|
87
|
+
sensor,
|
|
88
|
+
action,
|
|
89
|
+
userId,
|
|
90
|
+
revertActionUpdate,
|
|
91
|
+
statusCallback,
|
|
92
|
+
sendRemoteCommand,
|
|
93
|
+
]);
|
|
85
94
|
|
|
86
95
|
if (!action) {
|
|
87
96
|
return <View />;
|
|
@@ -5,7 +5,6 @@ import ItemQuickAction from '../ItemQuickAction';
|
|
|
5
5
|
import { Colors } from '../../../configs';
|
|
6
6
|
import { TESTID } from '../../../configs/Constants';
|
|
7
7
|
import { factory } from 'factory-girl';
|
|
8
|
-
import { sendRemoteCommand } from '../../../iot/RemoteControl';
|
|
9
8
|
|
|
10
9
|
class Sensor {}
|
|
11
10
|
|
|
@@ -21,7 +20,13 @@ jest.mock('react', () => {
|
|
|
21
20
|
|
|
22
21
|
useState.mockImplementation((init) => [init, mockSetState]);
|
|
23
22
|
|
|
24
|
-
jest.
|
|
23
|
+
const mockSendRemoteControl = jest.fn();
|
|
24
|
+
jest.mock('../../../hooks/IoT', () => {
|
|
25
|
+
return {
|
|
26
|
+
...jest.requireActual('../../../hooks/IoT'),
|
|
27
|
+
useRemoteControl: () => mockSendRemoteControl,
|
|
28
|
+
};
|
|
29
|
+
});
|
|
25
30
|
|
|
26
31
|
jest.mock('../../../iot/states', () => ({
|
|
27
32
|
useConfigGlobalState: () => [{}, null],
|
|
@@ -83,9 +88,9 @@ describe('Test ItemQuickAction', () => {
|
|
|
83
88
|
};
|
|
84
89
|
|
|
85
90
|
test('render with no action', async () => {
|
|
86
|
-
const
|
|
91
|
+
const newSensor = await factory.build('Sensor');
|
|
87
92
|
act(() => {
|
|
88
|
-
tree = create(<ItemQuickAction sensor={
|
|
93
|
+
tree = create(<ItemQuickAction sensor={newSensor} />);
|
|
89
94
|
});
|
|
90
95
|
const instance = tree.root;
|
|
91
96
|
const buttonOnActionPress = instance.findAll(
|
|
@@ -121,7 +126,7 @@ describe('Test ItemQuickAction', () => {
|
|
|
121
126
|
act(() => {
|
|
122
127
|
buttonOnActionPress.props.onPress();
|
|
123
128
|
});
|
|
124
|
-
expect(
|
|
129
|
+
expect(mockSendRemoteControl).toBeCalled();
|
|
125
130
|
expect(mockSetState).toBeCalledTimes(1);
|
|
126
131
|
|
|
127
132
|
jest.runAllTimers();
|
|
@@ -154,7 +159,7 @@ describe('Test ItemQuickAction', () => {
|
|
|
154
159
|
act(() => {
|
|
155
160
|
buttonOnActionPress.props.onPress();
|
|
156
161
|
});
|
|
157
|
-
expect(
|
|
162
|
+
expect(mockSendRemoteControl).toBeCalled();
|
|
158
163
|
expect(mockSetState).toBeCalledTimes(1);
|
|
159
164
|
|
|
160
165
|
jest.runAllTimers();
|
|
@@ -7,6 +7,7 @@ import Text from '../Text';
|
|
|
7
7
|
import { useConfigGlobalState } from '../../iot/states';
|
|
8
8
|
import styles from './NumberUpDownActionTemplateStyle';
|
|
9
9
|
import { watchMultiConfigs } from '../../iot/Monitor';
|
|
10
|
+
import { TESTID } from '../../configs/Constants';
|
|
10
11
|
|
|
11
12
|
const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
12
13
|
const { configuration, title } = actionGroup;
|
|
@@ -15,39 +16,39 @@ const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
15
16
|
max_value,
|
|
16
17
|
min_value,
|
|
17
18
|
text_format,
|
|
18
|
-
keep_track_config,
|
|
19
19
|
config,
|
|
20
|
+
allow_config_store_value,
|
|
20
21
|
} = configuration;
|
|
21
22
|
|
|
22
23
|
// eslint-disable-next-line no-unused-vars
|
|
23
24
|
const [configValues, setConfigValues] = useConfigGlobalState('configValues');
|
|
24
|
-
const [value, setValue] = useState(
|
|
25
|
+
const [value, setValue] = useState();
|
|
26
|
+
const valueDefault = 28;
|
|
25
27
|
|
|
26
28
|
useEffect(() => {
|
|
27
|
-
if (!keep_track_config) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
29
|
if (!config) {
|
|
30
|
+
setValue(valueDefault);
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const configValue = configValues[config];
|
|
35
35
|
if (configValue !== null && configValue !== undefined) {
|
|
36
36
|
setValue(configValue);
|
|
37
|
+
} else {
|
|
38
|
+
setValue(valueDefault);
|
|
37
39
|
}
|
|
38
|
-
|
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
+
}, []);
|
|
39
42
|
|
|
40
43
|
const doActionAndWatchConfig = useCallback(
|
|
41
44
|
async (actionData, actionValue, actionName) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
);
|
|
47
|
-
if (!sensor?.is_managed_by_backend) {
|
|
48
|
-
return;
|
|
45
|
+
const data = { temperature: actionValue };
|
|
46
|
+
if (allow_config_store_value && config) {
|
|
47
|
+
data.config_id = config;
|
|
48
|
+
data.value = actionValue;
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
await doAction(actionData, JSON.stringify(data), actionName);
|
|
51
|
+
if (!sensor?.is_managed_by_backend) {
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
if (!config) {
|
|
@@ -59,11 +60,11 @@ const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
59
60
|
watchMultiConfigs([config]);
|
|
60
61
|
},
|
|
61
62
|
[
|
|
62
|
-
config,
|
|
63
63
|
doAction,
|
|
64
|
-
|
|
65
|
-
sensor.is_managed_by_backend,
|
|
64
|
+
sensor?.is_managed_by_backend,
|
|
66
65
|
sensor.device_type,
|
|
66
|
+
allow_config_store_value,
|
|
67
|
+
config,
|
|
67
68
|
]
|
|
68
69
|
);
|
|
69
70
|
|
|
@@ -103,13 +104,23 @@ const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
103
104
|
)}
|
|
104
105
|
|
|
105
106
|
<View style={styles.controlPannel}>
|
|
106
|
-
<TouchableOpacity
|
|
107
|
+
<TouchableOpacity
|
|
108
|
+
style={styles.downButton}
|
|
109
|
+
onPress={doActionDown}
|
|
110
|
+
testID={TESTID.NUMBER_ACTION_DOWN}
|
|
111
|
+
>
|
|
107
112
|
<IconOutline name="down" size={32} color={Colors.Primary} />
|
|
108
113
|
</TouchableOpacity>
|
|
109
114
|
|
|
110
|
-
<Text type="H2">
|
|
115
|
+
<Text testID={'abcd'} type="H2">
|
|
116
|
+
{text_format.replace('{number}', value)}
|
|
117
|
+
</Text>
|
|
111
118
|
|
|
112
|
-
<TouchableOpacity
|
|
119
|
+
<TouchableOpacity
|
|
120
|
+
style={styles.upButton}
|
|
121
|
+
onPress={doActionUp}
|
|
122
|
+
testID={TESTID.NUMBER_ACTION_UP}
|
|
123
|
+
>
|
|
113
124
|
<IconOutline name="up" size={32} color={Colors.Primary} />
|
|
114
125
|
</TouchableOpacity>
|
|
115
126
|
</View>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { memo, useCallback } from 'react';
|
|
2
|
-
import { View, ScrollView
|
|
2
|
+
import { View, ScrollView } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import styles from './SmartTiviActionTemplateStyles';
|
|
5
5
|
import Text from '../../Text';
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
Youtube,
|
|
23
23
|
Netflix,
|
|
24
24
|
} from './component/Icon';
|
|
25
|
+
import { notImplemented } from '../../../utils/Utils';
|
|
25
26
|
|
|
26
27
|
const SmartTiviActionTemplate = memo(
|
|
27
28
|
({ actionGroup, doAction, scrollEnabled = true }) => {
|
|
@@ -68,7 +69,7 @@ const SmartTiviActionTemplate = memo(
|
|
|
68
69
|
case SMART_TIVI_BUTTON.HOME_BUTTON:
|
|
69
70
|
case SMART_TIVI_BUTTON.BACK_BUTTON:
|
|
70
71
|
case SMART_TIVI_BUTTON.CHANNEL_BUTTON:
|
|
71
|
-
return
|
|
72
|
+
return notImplemented(t);
|
|
72
73
|
default:
|
|
73
74
|
return <></>;
|
|
74
75
|
}
|
|
@@ -14,7 +14,6 @@ const TwoButtonTemplate = memo(({ actionGroup, doAction, sensor }) => {
|
|
|
14
14
|
const { button1, button2 } = configuration;
|
|
15
15
|
const [isOn, setIsOn] = useState(true);
|
|
16
16
|
const [isStart, setIsStart] = useState(true);
|
|
17
|
-
// eslint-disable-next-line no-unused-vars
|
|
18
17
|
const [configValues] = useConfigGlobalState('configValues');
|
|
19
18
|
const isLight = false;
|
|
20
19
|
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { TouchableOpacity } from 'react-native';
|
|
3
3
|
import { act, create } from 'react-test-renderer';
|
|
4
4
|
import Text from '../../../commons/Text';
|
|
5
|
+
import { TESTID } from '../../../configs/Constants';
|
|
5
6
|
import { watchMultiConfigs } from '../../../iot/Monitor';
|
|
6
7
|
import NumberUpDownActionTemplate from '../NumberUpDownActionTemplate';
|
|
7
8
|
|
|
@@ -30,7 +31,7 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
30
31
|
watchMultiConfigs.mockClear();
|
|
31
32
|
actionGroup = {
|
|
32
33
|
configuration: {
|
|
33
|
-
|
|
34
|
+
allow_config_store_value: false,
|
|
34
35
|
config: 5,
|
|
35
36
|
action_data,
|
|
36
37
|
min_value: 16,
|
|
@@ -57,28 +58,10 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
57
58
|
|
|
58
59
|
const touchs = instance.findAllByType(TouchableOpacity);
|
|
59
60
|
expect(touchs).toHaveLength(2);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test('do action call watchConfigs', async () => {
|
|
63
|
-
actionGroup.configuration.keep_track_config = true;
|
|
64
|
-
const mockDoAction = jest.fn();
|
|
65
|
-
await act(async () => {
|
|
66
|
-
wrapper = await create(
|
|
67
|
-
<NumberUpDownActionTemplate
|
|
68
|
-
actionGroup={actionGroup}
|
|
69
|
-
doAction={mockDoAction}
|
|
70
|
-
sensor={{ is_managed_by_backend: true }}
|
|
71
|
-
/>
|
|
72
|
-
);
|
|
73
|
-
});
|
|
74
|
-
const instance = wrapper.root;
|
|
75
|
-
const touchs = instance.findAllByType(TouchableOpacity);
|
|
76
|
-
expect(touchs).toHaveLength(2);
|
|
77
61
|
|
|
78
62
|
await act(async () => {
|
|
79
63
|
await touchs[0].props.onPress();
|
|
80
64
|
});
|
|
81
|
-
|
|
82
65
|
expect(watchMultiConfigs).toBeCalled();
|
|
83
66
|
});
|
|
84
67
|
|
|
@@ -104,8 +87,9 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
104
87
|
expect(watchMultiConfigs).not.toBeCalled();
|
|
105
88
|
});
|
|
106
89
|
|
|
107
|
-
test('do action
|
|
90
|
+
test('do action watchConfigs cause allow_config_store_value true', async () => {
|
|
108
91
|
const mockDoAction = jest.fn();
|
|
92
|
+
actionGroup.configuration.allow_config_store_value = true;
|
|
109
93
|
await act(async () => {
|
|
110
94
|
wrapper = await create(
|
|
111
95
|
<NumberUpDownActionTemplate
|
|
@@ -123,11 +107,11 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
123
107
|
await touchs[0].props.onPress();
|
|
124
108
|
});
|
|
125
109
|
|
|
126
|
-
expect(watchMultiConfigs).
|
|
110
|
+
expect(watchMultiConfigs).toBeCalled();
|
|
127
111
|
});
|
|
128
112
|
|
|
129
113
|
test('action down without config', async () => {
|
|
130
|
-
actionGroup.configuration.
|
|
114
|
+
actionGroup.configuration.allow_config_store_value = true;
|
|
131
115
|
actionGroup.configuration.config = undefined;
|
|
132
116
|
const mockDoAction = jest.fn();
|
|
133
117
|
await act(async () => {
|
|
@@ -150,8 +134,10 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
150
134
|
expect(watchMultiConfigs).not.toBeCalled();
|
|
151
135
|
});
|
|
152
136
|
|
|
153
|
-
test('action down
|
|
137
|
+
test('action down allow_config_store_value true', async () => {
|
|
154
138
|
const mockDoAction = jest.fn();
|
|
139
|
+
actionGroup.configuration.allow_config_store_value = true;
|
|
140
|
+
actionGroup.configuration.config = null;
|
|
155
141
|
await act(async () => {
|
|
156
142
|
wrapper = await create(
|
|
157
143
|
<NumberUpDownActionTemplate
|
|
@@ -162,19 +148,23 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
162
148
|
);
|
|
163
149
|
});
|
|
164
150
|
const instance = wrapper.root;
|
|
165
|
-
const touchs = instance.
|
|
166
|
-
|
|
167
|
-
|
|
151
|
+
const touchs = instance.find(
|
|
152
|
+
(el) =>
|
|
153
|
+
el.props.testID === TESTID.NUMBER_ACTION_DOWN &&
|
|
154
|
+
el.type === TouchableOpacity
|
|
155
|
+
);
|
|
168
156
|
await act(async () => {
|
|
169
|
-
await touchs
|
|
157
|
+
await touchs.props.onPress();
|
|
170
158
|
});
|
|
171
159
|
|
|
172
160
|
const text = instance.findByType(Text);
|
|
173
|
-
expect(text.props.children).toEqual('
|
|
161
|
+
expect(text.props.children).toEqual('27 *C');
|
|
174
162
|
});
|
|
175
163
|
|
|
176
|
-
test('action up
|
|
164
|
+
test('action up allow_config_store_value true', async () => {
|
|
177
165
|
const mockDoAction = jest.fn();
|
|
166
|
+
actionGroup.configuration.allow_config_store_value = true;
|
|
167
|
+
actionGroup.configuration.config = null;
|
|
178
168
|
await act(async () => {
|
|
179
169
|
wrapper = await create(
|
|
180
170
|
<NumberUpDownActionTemplate
|
|
@@ -185,19 +175,21 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
185
175
|
);
|
|
186
176
|
});
|
|
187
177
|
const instance = wrapper.root;
|
|
188
|
-
const touchs = instance.
|
|
189
|
-
|
|
190
|
-
|
|
178
|
+
const touchs = instance.find(
|
|
179
|
+
(el) =>
|
|
180
|
+
el.props.testID === TESTID.NUMBER_ACTION_UP &&
|
|
181
|
+
el.type === TouchableOpacity
|
|
182
|
+
);
|
|
191
183
|
await act(async () => {
|
|
192
|
-
await touchs
|
|
184
|
+
await touchs.props.onPress();
|
|
193
185
|
});
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
186
|
+
const text = instance.find(
|
|
187
|
+
(el) => el.props.testID === 'abcd' && el.type === Text
|
|
188
|
+
);
|
|
189
|
+
expect(text.props.children).toEqual('29 *C');
|
|
197
190
|
});
|
|
198
191
|
|
|
199
|
-
test('action down with
|
|
200
|
-
actionGroup.configuration.keep_track_config = true;
|
|
192
|
+
test('action down with allow_config_store_value false', async () => {
|
|
201
193
|
const mockDoAction = jest.fn();
|
|
202
194
|
await act(async () => {
|
|
203
195
|
wrapper = await create(
|
|
@@ -209,19 +201,21 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
209
201
|
);
|
|
210
202
|
});
|
|
211
203
|
const instance = wrapper.root;
|
|
212
|
-
const touchs = instance.
|
|
213
|
-
|
|
204
|
+
const touchs = instance.find(
|
|
205
|
+
(el) =>
|
|
206
|
+
el.props.testID === TESTID.NUMBER_ACTION_DOWN &&
|
|
207
|
+
el.type === TouchableOpacity
|
|
208
|
+
);
|
|
214
209
|
|
|
215
210
|
await act(async () => {
|
|
216
|
-
await touchs
|
|
211
|
+
await touchs.props.onPress();
|
|
217
212
|
});
|
|
218
213
|
|
|
219
214
|
const text = instance.findByType(Text);
|
|
220
|
-
expect(text.props.children).toEqual('
|
|
215
|
+
expect(text.props.children).toEqual('24 *C'); // TODO should 24, configValues make changes again
|
|
221
216
|
});
|
|
222
217
|
|
|
223
|
-
test('action up with
|
|
224
|
-
actionGroup.configuration.keep_track_config = true;
|
|
218
|
+
test('action up with allow_config_store_value false', async () => {
|
|
225
219
|
const mockDoAction = jest.fn();
|
|
226
220
|
await act(async () => {
|
|
227
221
|
wrapper = await create(
|
|
@@ -233,15 +227,18 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
233
227
|
);
|
|
234
228
|
});
|
|
235
229
|
const instance = wrapper.root;
|
|
236
|
-
const touchs = instance.
|
|
237
|
-
|
|
230
|
+
const touchs = instance.find(
|
|
231
|
+
(el) =>
|
|
232
|
+
el.props.testID === TESTID.NUMBER_ACTION_UP &&
|
|
233
|
+
el.type === TouchableOpacity
|
|
234
|
+
);
|
|
238
235
|
|
|
239
236
|
await act(async () => {
|
|
240
|
-
await touchs
|
|
237
|
+
await touchs.props.onPress();
|
|
241
238
|
});
|
|
242
239
|
|
|
243
240
|
const text = instance.findByType(Text);
|
|
244
|
-
expect(text.props.children).toEqual('
|
|
241
|
+
expect(text.props.children).toEqual('26 *C'); // TODO should 26, configValues make changes again
|
|
245
242
|
});
|
|
246
243
|
|
|
247
244
|
test('action down limit ', async () => {
|
|
@@ -356,8 +356,8 @@ describe('Test ActionGroup', () => {
|
|
|
356
356
|
text_format: '{number} *C',
|
|
357
357
|
},
|
|
358
358
|
};
|
|
359
|
-
await act(() => {
|
|
360
|
-
wrapper = renderer.create(
|
|
359
|
+
await act(async () => {
|
|
360
|
+
wrapper = await renderer.create(
|
|
361
361
|
wrapComponent(actionGroup, mockDoAction, sensor)
|
|
362
362
|
);
|
|
363
363
|
});
|
|
@@ -12,6 +12,7 @@ import styles from './styles';
|
|
|
12
12
|
import DeviceItem from './DeviceItem/DeviceItem';
|
|
13
13
|
import Connecting from '../Connecting';
|
|
14
14
|
import { useSCContextSelector } from '../../context';
|
|
15
|
+
import { ToastBottomHelper } from '../../utils/Utils';
|
|
15
16
|
|
|
16
17
|
const ConnectingProcess = ({ route }) => {
|
|
17
18
|
const { navigate, goBack } = useNavigation();
|
|
@@ -27,7 +28,6 @@ const ConnectingProcess = ({ route }) => {
|
|
|
27
28
|
devicePrefixName,
|
|
28
29
|
wifi_ssid,
|
|
29
30
|
wifi_pass,
|
|
30
|
-
chip_id,
|
|
31
31
|
} = route.params || {};
|
|
32
32
|
const [isLoading, setIsLoading] = useState(true);
|
|
33
33
|
const [sensor, setSensor] = useState(null);
|
|
@@ -46,6 +46,7 @@ const ConnectingProcess = ({ route }) => {
|
|
|
46
46
|
if (success) {
|
|
47
47
|
setSensor(data);
|
|
48
48
|
} else {
|
|
49
|
+
ToastBottomHelper.error(JSON.stringify(data));
|
|
49
50
|
goBack();
|
|
50
51
|
}
|
|
51
52
|
}
|
|
@@ -63,19 +64,23 @@ const ConnectingProcess = ({ route }) => {
|
|
|
63
64
|
if (success) {
|
|
64
65
|
setSensor(data);
|
|
65
66
|
} else {
|
|
67
|
+
ToastBottomHelper.error(JSON.stringify(data));
|
|
66
68
|
goBack();
|
|
67
69
|
}
|
|
68
70
|
break;
|
|
69
71
|
}
|
|
70
72
|
case 'LITE': {
|
|
71
|
-
const { success } = await axiosPost(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
const { success, data } = await axiosPost(
|
|
74
|
+
API.UNIT.ADD_GATEWAY(unit_id),
|
|
75
|
+
{
|
|
76
|
+
imei: gateway?.imei,
|
|
77
|
+
chip_name: gateway?.model,
|
|
78
|
+
}
|
|
79
|
+
);
|
|
76
80
|
if (success) {
|
|
77
81
|
setSensor({ name: gateway?.model });
|
|
78
82
|
} else {
|
|
83
|
+
ToastBottomHelper.error(JSON.stringify(data));
|
|
79
84
|
goBack();
|
|
80
85
|
}
|
|
81
86
|
break;
|
|
@@ -95,7 +100,6 @@ const ConnectingProcess = ({ route }) => {
|
|
|
95
100
|
wifi_pass,
|
|
96
101
|
user?.phone_number,
|
|
97
102
|
unit_id,
|
|
98
|
-
chip_id,
|
|
99
103
|
]);
|
|
100
104
|
|
|
101
105
|
const ConnectingSuccess = useCallback(() => {
|
|
@@ -29,7 +29,7 @@ const ConnectedViewHeader = memo(
|
|
|
29
29
|
const t = useTranslations();
|
|
30
30
|
const lastUpdatedStr = lastUpdated
|
|
31
31
|
? timeDifference(new Date(), lastUpdated)
|
|
32
|
-
:
|
|
32
|
+
: `5 ${t('seconds_ago')}`;
|
|
33
33
|
return (
|
|
34
34
|
<View style={styles.statusContainer}>
|
|
35
35
|
<View style={styles.connectStatus}>
|
|
@@ -151,12 +151,12 @@ const HistoryChart = memo(
|
|
|
151
151
|
if (configuration.config !== 'power_consumption') {
|
|
152
152
|
return null;
|
|
153
153
|
}
|
|
154
|
-
const { price } = chartConfig;
|
|
155
|
-
if (
|
|
154
|
+
const { price: chartPrice } = chartConfig;
|
|
155
|
+
if (chartPrice === '' || isNaN(chartPrice)) {
|
|
156
156
|
return null;
|
|
157
157
|
}
|
|
158
158
|
const sum = datas[0].data.reduce((a, b) => a + b.y, 0);
|
|
159
|
-
const roundedSum = sum *
|
|
159
|
+
const roundedSum = sum * chartPrice;
|
|
160
160
|
return roundedSum.toFixed();
|
|
161
161
|
}, [configuration, datas, chartConfig]);
|
|
162
162
|
|
|
@@ -11,8 +11,9 @@ import { useNavigation } from '@react-navigation/native';
|
|
|
11
11
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
12
12
|
import ItemQuickAction from '../../commons/Action/ItemQuickAction';
|
|
13
13
|
import Text from '../../commons/Text';
|
|
14
|
-
import { isDeviceConnected } from '../../iot/RemoteControl/Bluetooth';
|
|
14
|
+
import { isDeviceConnected as isBluetoothDeviceConnected } from '../../iot/RemoteControl/Bluetooth';
|
|
15
15
|
import { useSCContextSelector } from '../../context';
|
|
16
|
+
import { useGGHomeDeviceConnected } from '../../hooks/Common';
|
|
16
17
|
|
|
17
18
|
import { Colors } from '../../configs';
|
|
18
19
|
import { TESTID, DEVICE_TYPE, DEVICE_SIZE } from '../../configs/Constants';
|
|
@@ -26,7 +27,6 @@ const ItemDevice = memo(
|
|
|
26
27
|
sensor,
|
|
27
28
|
unit,
|
|
28
29
|
station,
|
|
29
|
-
isGGHomeConnected,
|
|
30
30
|
serverDown,
|
|
31
31
|
status,
|
|
32
32
|
wrapStyle,
|
|
@@ -39,6 +39,7 @@ const ItemDevice = memo(
|
|
|
39
39
|
const isNetworkConnected = useSCContextSelector(
|
|
40
40
|
(state) => state.app.isNetworkConnected
|
|
41
41
|
);
|
|
42
|
+
const { isConnected: isGGHomeConnected } = useGGHomeDeviceConnected(sensor);
|
|
42
43
|
|
|
43
44
|
const goToSensorDisplay = useCallback(() => {
|
|
44
45
|
navigation.navigate(Routes.DeviceDetail, {
|
|
@@ -46,24 +47,27 @@ const ItemDevice = memo(
|
|
|
46
47
|
station,
|
|
47
48
|
sensorData: sensor,
|
|
48
49
|
title,
|
|
49
|
-
isGGHomeConnected,
|
|
50
50
|
});
|
|
51
|
-
}, [navigation, sensor, station, title, unit
|
|
51
|
+
}, [navigation, sensor, station, title, unit]);
|
|
52
52
|
|
|
53
53
|
const isConnectedViaInternet =
|
|
54
54
|
status === undefined
|
|
55
55
|
? !serverDown && isNetworkConnected && sensor.is_connected
|
|
56
56
|
: !serverDown && isNetworkConnected && status.is_connected;
|
|
57
|
+
|
|
57
58
|
const isConnectedViaBLE =
|
|
58
59
|
isBluetoothEnabled &&
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
!sensor?.device_type !== DEVICE_TYPE.LG_THINQ &&
|
|
64
|
-
isGGHomeConnected;
|
|
60
|
+
isBluetoothDeviceConnected(
|
|
61
|
+
sensor?.remote_control_options?.bluetooth?.address
|
|
62
|
+
);
|
|
63
|
+
|
|
65
64
|
const isConnected =
|
|
66
|
-
|
|
65
|
+
!!sensor && sensor?.is_other_device
|
|
66
|
+
? sensor?.device_type === DEVICE_TYPE.LG_THINQ
|
|
67
|
+
? true
|
|
68
|
+
: isGGHomeConnected
|
|
69
|
+
: isConnectedViaInternet || isConnectedViaBLE;
|
|
70
|
+
|
|
67
71
|
const borderColor = isConnected ? Colors.Gray4 : Colors.Red6;
|
|
68
72
|
const textConnected = isConnected ? t('connected') : t('disconnected');
|
|
69
73
|
|
|
@@ -152,9 +152,9 @@ const ScheduleField = ({ dataItem, index, setDataForm, dataForm }) => {
|
|
|
152
152
|
<View style={styles.wrapper}>
|
|
153
153
|
<Text style={styles.textHeadLine}>{t('access_schedule')}</Text>
|
|
154
154
|
|
|
155
|
-
{listAccessSchedule.map((item,
|
|
155
|
+
{listAccessSchedule.map((item, i) => (
|
|
156
156
|
<AccessScheduleItem
|
|
157
|
-
key={
|
|
157
|
+
key={i}
|
|
158
158
|
item={item}
|
|
159
159
|
isSelected={item.value === accessSchedule}
|
|
160
160
|
onSelect={setAccessSchedule}
|
|
@@ -6,6 +6,7 @@ import { Icon } from '@ant-design/react-native';
|
|
|
6
6
|
import { useNavigation } from '@react-navigation/native';
|
|
7
7
|
import styles from './Styles/HeaderCustomStyles';
|
|
8
8
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
9
|
+
import { notImplemented } from '../../utils/Utils';
|
|
9
10
|
|
|
10
11
|
const HeaderCustom = ({
|
|
11
12
|
title = '',
|
|
@@ -33,7 +34,7 @@ const HeaderCustom = ({
|
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
const handleClose = useCallback(() => {
|
|
36
|
-
onClose ? onClose() :
|
|
37
|
+
onClose ? onClose() : notImplemented(t);
|
|
37
38
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
38
39
|
}, []);
|
|
39
40
|
|
|
@@ -76,8 +76,8 @@ const HorizontalPicker = ({
|
|
|
76
76
|
}, [maximum, minimum, time]);
|
|
77
77
|
|
|
78
78
|
useEffect(() => {
|
|
79
|
-
const scrollListener = scrollX.addListener(({ value }) => {
|
|
80
|
-
isCanChangeValue && onChangeValue && onChangeValue(
|
|
79
|
+
const scrollListener = scrollX.addListener(({ value: scrollValue }) => {
|
|
80
|
+
isCanChangeValue && onChangeValue && onChangeValue(scrollValue);
|
|
81
81
|
});
|
|
82
82
|
return () => scrollX.removeListener(scrollListener);
|
|
83
83
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|