@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
package/src/context/reducer.ts
CHANGED
|
@@ -63,10 +63,11 @@ export const initialState = {
|
|
|
63
63
|
},
|
|
64
64
|
iot: {
|
|
65
65
|
googlehome: {
|
|
66
|
-
isFirstTimeConnect: true,
|
|
67
|
-
isConnecting: false,
|
|
68
66
|
connections: {},
|
|
69
67
|
},
|
|
68
|
+
internet: {
|
|
69
|
+
statuses: {},
|
|
70
|
+
},
|
|
70
71
|
},
|
|
71
72
|
valueEvaluations: {},
|
|
72
73
|
fetchedValueEvaluationUnits: [],
|
|
@@ -235,7 +236,7 @@ export const reducer = (currentState: ContextData, action: Action) => {
|
|
|
235
236
|
starredScriptIds: payload,
|
|
236
237
|
},
|
|
237
238
|
};
|
|
238
|
-
case Action.
|
|
239
|
+
case Action.STAR_SCRIPTS:
|
|
239
240
|
return {
|
|
240
241
|
...currentState,
|
|
241
242
|
automate: {
|
|
@@ -245,13 +246,13 @@ export const reducer = (currentState: ContextData, action: Action) => {
|
|
|
245
246
|
),
|
|
246
247
|
},
|
|
247
248
|
};
|
|
248
|
-
case Action.
|
|
249
|
+
case Action.UNSTAR_SCRIPTS:
|
|
249
250
|
return {
|
|
250
251
|
...currentState,
|
|
251
252
|
automate: {
|
|
252
253
|
...currentState.automate,
|
|
253
254
|
starredScriptIds: currentState.automate.starredScriptIds.filter(
|
|
254
|
-
(scriptId) => scriptId
|
|
255
|
+
(scriptId) => !payload.includes(scriptId)
|
|
255
256
|
),
|
|
256
257
|
},
|
|
257
258
|
};
|
|
@@ -263,8 +264,6 @@ export const reducer = (currentState: ContextData, action: Action) => {
|
|
|
263
264
|
...currentState.iot,
|
|
264
265
|
googlehome: {
|
|
265
266
|
...currentState.iot.googlehome,
|
|
266
|
-
isFirstTimeConnect: false,
|
|
267
|
-
isConnecting: false,
|
|
268
267
|
connections: payload,
|
|
269
268
|
},
|
|
270
269
|
},
|
|
@@ -276,8 +275,6 @@ export const reducer = (currentState: ContextData, action: Action) => {
|
|
|
276
275
|
...currentState.iot,
|
|
277
276
|
googlehome: {
|
|
278
277
|
...currentState.iot.googlehome,
|
|
279
|
-
isFirstTimeConnect: false,
|
|
280
|
-
isConnecting: false,
|
|
281
278
|
connections: {
|
|
282
279
|
...currentState.iot.googlehome.connections,
|
|
283
280
|
[payload.option.chip_id]: payload.data,
|
|
@@ -285,16 +282,24 @@ export const reducer = (currentState: ContextData, action: Action) => {
|
|
|
285
282
|
},
|
|
286
283
|
},
|
|
287
284
|
};
|
|
288
|
-
|
|
285
|
+
|
|
286
|
+
case Action.SET_DEVICES_STATUS:
|
|
287
|
+
// eslint-disable-next-line no-case-declarations
|
|
288
|
+
let newStatuses = currentState.iot.internet.statuses;
|
|
289
|
+
(payload || []).map(
|
|
290
|
+
(i) =>
|
|
291
|
+
(newStatuses[i.id] = {
|
|
292
|
+
...(newStatuses[i.id] || {}),
|
|
293
|
+
isConnected: i.is_connected,
|
|
294
|
+
})
|
|
295
|
+
);
|
|
289
296
|
return {
|
|
290
297
|
...currentState,
|
|
291
298
|
iot: {
|
|
292
299
|
...currentState.iot,
|
|
293
|
-
|
|
294
|
-
...currentState.iot.
|
|
295
|
-
|
|
296
|
-
? true
|
|
297
|
-
: false,
|
|
300
|
+
internet: {
|
|
301
|
+
...currentState.iot.internet,
|
|
302
|
+
statuses: newStatuses,
|
|
298
303
|
},
|
|
299
304
|
},
|
|
300
305
|
};
|
package/src/hoc/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useRemoteControl } from '../hooks/IoT';
|
|
2
|
+
|
|
3
|
+
function withRemoteControl(Component) {
|
|
4
|
+
return function WrappedComponent(props) {
|
|
5
|
+
const sendRemoteCommand = useRemoteControl();
|
|
6
|
+
return <Component {...props} sendRemoteCommand={sendRemoteCommand} />;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default withRemoteControl;
|
|
@@ -4,7 +4,7 @@ import useForceUpdate from './useForceUpdate';
|
|
|
4
4
|
import useKeyboardShow from './useKeyboardShow';
|
|
5
5
|
import usePopover from './usePopover';
|
|
6
6
|
import useTitleHeader from './useTitleHeader';
|
|
7
|
-
import
|
|
7
|
+
import useDevicesStatus from './useDevicesStatus';
|
|
8
8
|
import useGGHomeDeviceConnected from './useGGHomeDeviceConnected';
|
|
9
9
|
import { useBlockBackAndroid } from './useBlockBackAndroid';
|
|
10
10
|
import { useIsOwnerOfUnit } from './useIsOwnerOfUnit';
|
|
@@ -22,6 +22,6 @@ export {
|
|
|
22
22
|
useIsOwnerOfUnit,
|
|
23
23
|
useStatusBar,
|
|
24
24
|
useGetIdUser,
|
|
25
|
-
|
|
25
|
+
useDevicesStatus,
|
|
26
26
|
useGGHomeDeviceConnected,
|
|
27
27
|
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useCallback, useContext } from 'react';
|
|
2
|
+
import { useFocusEffect } from '@react-navigation/native';
|
|
3
|
+
import { SCContext, useSCContextSelector } from '../../context';
|
|
4
|
+
import { axiosGet } from '../../utils/Apis/axios';
|
|
5
|
+
import { API } from '../../configs';
|
|
6
|
+
import { Action } from '../../context/actionType';
|
|
7
|
+
|
|
8
|
+
let timeoutId;
|
|
9
|
+
|
|
10
|
+
const useDevicesStatus = (unit, devices) => {
|
|
11
|
+
const { setAction } = useContext(SCContext);
|
|
12
|
+
const isNetworkConnected = useSCContextSelector(
|
|
13
|
+
(state) => state.app.isNetworkConnected
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const getDevicesStatus = useCallback(async (_unit, _devices) => {
|
|
17
|
+
const params = new URLSearchParams();
|
|
18
|
+
_devices.forEach((device) => {
|
|
19
|
+
params.append('sensors', device.id);
|
|
20
|
+
});
|
|
21
|
+
const { success, data } = await axiosGet(
|
|
22
|
+
API.UNIT.SENSORS_STATUS(_unit.id),
|
|
23
|
+
{
|
|
24
|
+
params: params,
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
if (success) {
|
|
28
|
+
setAction(Action.SET_DEVICES_STATUS, data);
|
|
29
|
+
}
|
|
30
|
+
timeoutId = setTimeout(() => getDevicesStatus(_unit, _devices), 5000);
|
|
31
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
32
|
+
}, []);
|
|
33
|
+
|
|
34
|
+
useFocusEffect(
|
|
35
|
+
useCallback(() => {
|
|
36
|
+
if (!devices?.length || !isNetworkConnected) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const managedDevices = devices.filter(
|
|
41
|
+
(device) => device?.is_managed_by_backend
|
|
42
|
+
);
|
|
43
|
+
if (!managedDevices.length) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
timeoutId = setTimeout(() => getDevicesStatus(unit, managedDevices), 200);
|
|
48
|
+
|
|
49
|
+
return () => {
|
|
50
|
+
clearTimeout(timeoutId);
|
|
51
|
+
};
|
|
52
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
|
+
}, [unit, devices, isNetworkConnected])
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default useDevicesStatus;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useSCContextSelector } from '../../context';
|
|
2
2
|
|
|
3
3
|
const useGGHomeDeviceConnected = (device) => {
|
|
4
|
-
const { connections
|
|
5
|
-
|
|
6
|
-
);
|
|
4
|
+
const { connections } = useSCContextSelector((state) => state.iot.googlehome);
|
|
5
|
+
|
|
6
|
+
const isConnecting = !!device?.chip_id && !(device.chip_id in connections);
|
|
7
7
|
|
|
8
8
|
const isConnected =
|
|
9
9
|
!!device?.chip_id &&
|
|
@@ -167,8 +167,7 @@ describe('Test useGGHomeConnection', () => {
|
|
|
167
167
|
await act(async () => {
|
|
168
168
|
await result.current.connectGoogleHome(options);
|
|
169
169
|
});
|
|
170
|
-
expect(mockedSetAction).toBeCalledTimes(
|
|
171
|
-
expect(mockedSetAction).toBeCalledWith(Action.CONNECTING_GOOGLE_HOME);
|
|
170
|
+
expect(mockedSetAction).toBeCalledTimes(2);
|
|
172
171
|
expect(mockedSetAction).toBeCalledWith(
|
|
173
172
|
Action.SET_GOOGLE_HOME_CONNECTIONS,
|
|
174
173
|
conns
|
package/src/hooks/IoT/index.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import useGGHomeConnection from './useGGHomeConnection';
|
|
2
2
|
import useRemoteControl from './useRemoteControl';
|
|
3
3
|
import useValueEvaluations from './useValueEvaluation';
|
|
4
|
+
import useWatchConfigs from './useWatchConfigs';
|
|
5
|
+
import useUnwatchLGDeviceConfigControl from './useUnwatchLGDeviceConfigControl';
|
|
4
6
|
|
|
5
|
-
export {
|
|
7
|
+
export {
|
|
8
|
+
useGGHomeConnection,
|
|
9
|
+
useRemoteControl,
|
|
10
|
+
useValueEvaluations,
|
|
11
|
+
useWatchConfigs,
|
|
12
|
+
useUnwatchLGDeviceConfigControl,
|
|
13
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { useFocusEffect } from '@react-navigation/native';
|
|
3
|
+
import { unwatchMultiConfigs } from '../../iot/Monitor';
|
|
4
|
+
import { DEVICE_TYPE } from '../../configs/Constants';
|
|
5
|
+
|
|
6
|
+
const useUnwatchLGDeviceConfigControl = (device, configs) => {
|
|
7
|
+
const unwatch = useCallback(
|
|
8
|
+
(_configs) => {
|
|
9
|
+
if (
|
|
10
|
+
device?.is_managed_by_backend &&
|
|
11
|
+
device?.device_type === DEVICE_TYPE.LG_THINQ
|
|
12
|
+
) {
|
|
13
|
+
unwatchMultiConfigs(configs.map((config) => config));
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
[device, configs]
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
useFocusEffect(
|
|
20
|
+
useCallback(() => {
|
|
21
|
+
return () => {
|
|
22
|
+
unwatch();
|
|
23
|
+
};
|
|
24
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
25
|
+
}, [])
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default useUnwatchLGDeviceConfigControl;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useContext, useEffect } from 'react';
|
|
1
|
+
import { useCallback, useContext, useEffect, useState } from 'react';
|
|
2
2
|
import { API } from '../../configs';
|
|
3
3
|
import { SCContext, useSCContextSelector } from '../../context';
|
|
4
4
|
import { Action } from '../../context/actionType';
|
|
@@ -6,12 +6,14 @@ import { axiosGet } from '../../utils/Apis/axios';
|
|
|
6
6
|
|
|
7
7
|
const useValueEvaluations = (unitId) => {
|
|
8
8
|
const { setAction } = useContext(SCContext);
|
|
9
|
+
const [fetching, setFetching] = useState(false);
|
|
9
10
|
|
|
10
11
|
const fetchConfigValueEvaluations = useCallback(
|
|
11
12
|
async (page = 1) => {
|
|
12
13
|
if (!unitId) {
|
|
13
14
|
return;
|
|
14
15
|
}
|
|
16
|
+
setFetching(true);
|
|
15
17
|
const params = new URLSearchParams();
|
|
16
18
|
params.append('config__end_device__station__unit', unitId);
|
|
17
19
|
params.append('page', page);
|
|
@@ -24,9 +26,15 @@ const useValueEvaluations = (unitId) => {
|
|
|
24
26
|
data: data.results,
|
|
25
27
|
});
|
|
26
28
|
if (data.next) {
|
|
27
|
-
await fetchConfigValueEvaluations(page + 1);
|
|
29
|
+
return await fetchConfigValueEvaluations(page + 1);
|
|
28
30
|
}
|
|
31
|
+
} else {
|
|
32
|
+
setAction(Action.UPDATE_VALUE_EVALUATIONS, {
|
|
33
|
+
unitId,
|
|
34
|
+
data: [],
|
|
35
|
+
});
|
|
29
36
|
}
|
|
37
|
+
setFetching(false);
|
|
30
38
|
},
|
|
31
39
|
[unitId, setAction]
|
|
32
40
|
);
|
|
@@ -36,10 +44,15 @@ const useValueEvaluations = (unitId) => {
|
|
|
36
44
|
});
|
|
37
45
|
|
|
38
46
|
useEffect(() => {
|
|
39
|
-
if (!(fetchedValueEvaluationUnits.indexOf(unitId) !== -1)) {
|
|
47
|
+
if (!fetching && !(fetchedValueEvaluationUnits.indexOf(unitId) !== -1)) {
|
|
40
48
|
fetchConfigValueEvaluations();
|
|
41
49
|
}
|
|
42
|
-
}, [
|
|
50
|
+
}, [
|
|
51
|
+
unitId,
|
|
52
|
+
fetching,
|
|
53
|
+
fetchConfigValueEvaluations,
|
|
54
|
+
fetchedValueEvaluationUnits,
|
|
55
|
+
]);
|
|
43
56
|
};
|
|
44
57
|
|
|
45
58
|
export default useValueEvaluations;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { useFocusEffect } from '@react-navigation/native';
|
|
3
|
+
import { useSCContextSelector } from '../../context';
|
|
4
|
+
import { watchMultiConfigs, unwatchMultiConfigs } from '../../iot/Monitor';
|
|
5
|
+
import { SCConfig } from '../../configs';
|
|
6
|
+
|
|
7
|
+
let intervalId;
|
|
8
|
+
|
|
9
|
+
const useWatchConfigs = (configIds) => {
|
|
10
|
+
const isNetworkConnected = useSCContextSelector(
|
|
11
|
+
(state) => state.app.isNetworkConnected
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
useFocusEffect(
|
|
15
|
+
useCallback(() => {
|
|
16
|
+
if (!configIds.length || !isNetworkConnected) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
watchMultiConfigs(configIds);
|
|
21
|
+
clearInterval(intervalId);
|
|
22
|
+
intervalId = setInterval(() => {
|
|
23
|
+
watchMultiConfigs(configIds);
|
|
24
|
+
}, SCConfig.intervalWatchConfigTime);
|
|
25
|
+
|
|
26
|
+
return () => {
|
|
27
|
+
unwatchMultiConfigs(configIds);
|
|
28
|
+
clearInterval(intervalId);
|
|
29
|
+
};
|
|
30
|
+
}, [configIds, isNetworkConnected])
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default useWatchConfigs;
|
package/src/iot/Monitor.js
CHANGED
|
@@ -2,8 +2,10 @@ import { API } from '../configs';
|
|
|
2
2
|
import { getConfigGlobalState, setConfigGlobalState } from './states';
|
|
3
3
|
import _ from 'lodash';
|
|
4
4
|
import Pusher from 'pusher-js/react-native';
|
|
5
|
+
import PusherBatchAuthorizer from 'pusher-js-auth';
|
|
5
6
|
import { axiosPost } from '../utils/Apis/axios';
|
|
6
7
|
import { SCConfig } from '../configs';
|
|
8
|
+
import api from '../utils/Apis/axios';
|
|
7
9
|
|
|
8
10
|
Pusher.logToConsole = true;
|
|
9
11
|
let pusher = null;
|
|
@@ -12,23 +14,14 @@ const getPusher = () => {
|
|
|
12
14
|
if (!pusher) {
|
|
13
15
|
pusher = new Pusher(SCConfig.pusherAppKey, {
|
|
14
16
|
cluster: 'ap1',
|
|
15
|
-
authorizer:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
socket_id: socketId,
|
|
24
|
-
}
|
|
25
|
-
);
|
|
26
|
-
if (success) {
|
|
27
|
-
// eslint-disable-next-line promise/prefer-await-to-callbacks
|
|
28
|
-
callback(null, data);
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
};
|
|
17
|
+
authorizer: PusherBatchAuthorizer,
|
|
18
|
+
authEndpoint: SCConfig.apiRoot + API.IOT.CHIP_MANAGER.PUSHER_AUTH(),
|
|
19
|
+
authDelay: 300,
|
|
20
|
+
auth: {
|
|
21
|
+
headers: {
|
|
22
|
+
Accept: 'application/json',
|
|
23
|
+
Authorization: api.headers.Authorization,
|
|
24
|
+
},
|
|
32
25
|
},
|
|
33
26
|
});
|
|
34
27
|
}
|
|
@@ -55,7 +48,7 @@ const watchConfig = (configId) => {
|
|
|
55
48
|
return;
|
|
56
49
|
}
|
|
57
50
|
watchingConfigs[configId] = 1;
|
|
58
|
-
const channel = getPusher().subscribe(`private-
|
|
51
|
+
const channel = getPusher().subscribe(`private-config_v2-${configId}`);
|
|
59
52
|
channel.bind('new-value', updateGlobalValue.bind(channel, configId));
|
|
60
53
|
};
|
|
61
54
|
|
|
@@ -66,7 +59,7 @@ const unwatchConfig = (configId) => {
|
|
|
66
59
|
watchingConfigs[configId] -= 1;
|
|
67
60
|
if (!watchingConfigs[configId]) {
|
|
68
61
|
delete watchingConfigs[configId];
|
|
69
|
-
getPusher().unsubscribe(`private-
|
|
62
|
+
getPusher().unsubscribe(`private-config_v2-${configId}`);
|
|
70
63
|
if (_.isEmpty(watchingConfigs)) {
|
|
71
64
|
destroyPusher();
|
|
72
65
|
}
|
|
@@ -84,7 +77,7 @@ export const watchMultiConfigs = async (configIds) => {
|
|
|
84
77
|
waitWatchConfigIds = [];
|
|
85
78
|
clearTimeout(waitWatchConfigTimerId);
|
|
86
79
|
waitWatchConfigTimerId = 0;
|
|
87
|
-
},
|
|
80
|
+
}, 200);
|
|
88
81
|
}
|
|
89
82
|
};
|
|
90
83
|
|
|
@@ -48,10 +48,9 @@ async function stateChangeCallback(event) {
|
|
|
48
48
|
isChanged = true;
|
|
49
49
|
const [configId, type] = configMaps[entityId];
|
|
50
50
|
const typeConverter = valueTypes[type] || keepValue;
|
|
51
|
-
configValues[configId] =
|
|
52
|
-
event.data.new_state.state,
|
|
53
|
-
|
|
54
|
-
);
|
|
51
|
+
configValues[configId] = {
|
|
52
|
+
value: typeConverter(event.data.new_state.state, entityId),
|
|
53
|
+
};
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
if (entityId in attributeMaps) {
|
|
@@ -66,10 +65,9 @@ async function stateChangeCallback(event) {
|
|
|
66
65
|
|
|
67
66
|
const [configId, type] = attributeMap;
|
|
68
67
|
const typeConverter = valueTypes[type] || keepValue;
|
|
69
|
-
configValues[configId] =
|
|
70
|
-
entity.attributes[attributeName],
|
|
71
|
-
|
|
72
|
-
);
|
|
68
|
+
configValues[configId] = {
|
|
69
|
+
value: typeConverter(entity.attributes[attributeName], entityId),
|
|
70
|
+
};
|
|
73
71
|
}
|
|
74
72
|
}
|
|
75
73
|
|
|
@@ -91,7 +89,9 @@ async function fetchConnectionEntities(connection) {
|
|
|
91
89
|
const [configId, type] = configMaps[entityId];
|
|
92
90
|
const typeConverter = valueTypes[type] || keepValue;
|
|
93
91
|
|
|
94
|
-
configValues[configId] =
|
|
92
|
+
configValues[configId] = {
|
|
93
|
+
value: typeConverter(entity.state, entityId),
|
|
94
|
+
};
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
if (Object.prototype.hasOwnProperty.call(attributeMaps, entityId)) {
|
|
@@ -105,10 +105,9 @@ async function fetchConnectionEntities(connection) {
|
|
|
105
105
|
|
|
106
106
|
const [configId, type] = attributeMap;
|
|
107
107
|
const typeConverter = valueTypes[type] || keepValue;
|
|
108
|
-
configValues[configId] =
|
|
109
|
-
entity.attributes[attributeName],
|
|
110
|
-
|
|
111
|
-
);
|
|
108
|
+
configValues[configId] = {
|
|
109
|
+
value: typeConverter(entity.attributes[attributeName], entityId),
|
|
110
|
+
};
|
|
112
111
|
}
|
|
113
112
|
}
|
|
114
113
|
}
|
|
@@ -3,6 +3,7 @@ import { axiosGet } from '../../utils/Apis/axios';
|
|
|
3
3
|
import { getConfigGlobalState, setConfigGlobalState } from '../states';
|
|
4
4
|
import { sendCommandOverInternet } from './Internet';
|
|
5
5
|
|
|
6
|
+
// TODO update show config name of camelCase and snakeCase
|
|
6
7
|
let deviceMaps = {};
|
|
7
8
|
const propertyListMaps = {
|
|
8
9
|
temperature: 'targetTemperature',
|
|
@@ -122,7 +122,12 @@ describe('Remote Control Google Home', () => {
|
|
|
122
122
|
expect(getStates).toBeCalledTimes(1);
|
|
123
123
|
|
|
124
124
|
configValues = getConfigGlobalState('configValues');
|
|
125
|
-
expect(configValues).toEqual({
|
|
125
|
+
expect(configValues).toEqual({
|
|
126
|
+
1: { value: true },
|
|
127
|
+
2: { value: 50 },
|
|
128
|
+
3: { value: 10 },
|
|
129
|
+
4: { value: 123.4 },
|
|
130
|
+
});
|
|
126
131
|
});
|
|
127
132
|
|
|
128
133
|
it('When state change, global config value also change', async () => {
|
|
@@ -162,7 +167,7 @@ describe('Remote Control Google Home', () => {
|
|
|
162
167
|
);
|
|
163
168
|
|
|
164
169
|
configValues = getConfigGlobalState('configValues');
|
|
165
|
-
expect(configValues).toEqual({ 1: true });
|
|
170
|
+
expect(configValues).toEqual({ 1: { value: true } });
|
|
166
171
|
});
|
|
167
172
|
|
|
168
173
|
it('Connect to same google home will be skipped', async () => {
|
|
@@ -4,10 +4,12 @@ import { IconOutline } from '@ant-design/icons-react-native';
|
|
|
4
4
|
import { createStackNavigator } from '@react-navigation/stack';
|
|
5
5
|
import { BleManager } from 'react-native-ble-plx';
|
|
6
6
|
import NetInfo from '@react-native-community/netinfo';
|
|
7
|
+
import { AppState } from 'react-native';
|
|
7
8
|
import { get } from 'lodash';
|
|
8
9
|
|
|
9
10
|
import Text from '../commons/Text';
|
|
10
11
|
import { useTranslations } from '../hooks/Common/useTranslations';
|
|
12
|
+
import { unwatchAllConfigs } from '../iot/Monitor';
|
|
11
13
|
import { Colors, Device } from '../configs';
|
|
12
14
|
import Route from '../utils/Route';
|
|
13
15
|
import ActivityLogScreen from '../screens/ActivityLog';
|
|
@@ -51,7 +53,7 @@ import EmergencySetting from '../screens/EmergencySetting';
|
|
|
51
53
|
import ConfirmUnitDeletion from '../screens/ConfirmUnitDeletion';
|
|
52
54
|
import InfoMemberUnit from '../screens/Sharing/InfoMemberUnit';
|
|
53
55
|
import EnterPassword from '../screens/EnterPassword';
|
|
54
|
-
import
|
|
56
|
+
import SelectAddToFavorites from '../screens/Unit/SelectAddToFavorites';
|
|
55
57
|
import { HanetCameraStack } from './HanetCameraStack';
|
|
56
58
|
import { axiosGet } from '../utils/Apis/axios';
|
|
57
59
|
import { API } from '../configs';
|
|
@@ -107,6 +109,17 @@ export const UnitStack = memo((props) => {
|
|
|
107
109
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
108
110
|
}, []);
|
|
109
111
|
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
const subscription = AppState.addEventListener('change', (nextAppState) => {
|
|
114
|
+
if (nextAppState === 'background') {
|
|
115
|
+
unwatchAllConfigs();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return () => {
|
|
119
|
+
subscription?.remove();
|
|
120
|
+
};
|
|
121
|
+
}, []);
|
|
122
|
+
|
|
110
123
|
return (
|
|
111
124
|
<Stack.Navigator
|
|
112
125
|
screenOptions={{
|
|
@@ -402,8 +415,8 @@ export const UnitStack = memo((props) => {
|
|
|
402
415
|
}}
|
|
403
416
|
/>
|
|
404
417
|
<Stack.Screen
|
|
405
|
-
name={Route.
|
|
406
|
-
component={
|
|
418
|
+
name={Route.SelectAddToFavorites}
|
|
419
|
+
component={SelectAddToFavorites}
|
|
407
420
|
options={{
|
|
408
421
|
headerShown: false,
|
|
409
422
|
}}
|
|
@@ -349,7 +349,7 @@ const SelectAction = memo(({ route }) => {
|
|
|
349
349
|
<LoadingSelectAction style={styles.container} />
|
|
350
350
|
) : (
|
|
351
351
|
sensorData.map((item) => {
|
|
352
|
-
const isHasValue = !!item?.value
|
|
352
|
+
const isHasValue = !!item?.value;
|
|
353
353
|
return (
|
|
354
354
|
<View style={styles.wrapItem} key={item?.id}>
|
|
355
355
|
<TitleCheckBox
|
|
@@ -149,6 +149,10 @@ const SetUpSensor = () => {
|
|
|
149
149
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
150
150
|
}, [minimum, maximum, value]);
|
|
151
151
|
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
!isNumberValue && setValue(1);
|
|
154
|
+
}, [isNumberValue]);
|
|
155
|
+
|
|
152
156
|
useEffect(() => {
|
|
153
157
|
if (!isHasLimit && maximum - 150 <= value * 10) {
|
|
154
158
|
setMaximum(maximum + 200);
|