@eohjsc/react-native-smart-city 0.3.9 → 0.3.12

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.
Files changed (44) hide show
  1. package/index.js +2 -0
  2. package/package.json +1 -1
  3. package/src/commons/Device/HistoryChart.js +2 -2
  4. package/src/commons/MediaPlayerDetail/index.js +3 -0
  5. package/src/commons/SubUnit/Favorites/index.js +6 -2
  6. package/src/commons/UnitSummary/ConfigHistoryChart/__test__/ConfigHistoryChart.test.js +28 -1
  7. package/src/commons/UnitSummary/ConfigHistoryChart.js +57 -24
  8. package/src/configs/API.js +5 -1
  9. package/src/configs/Constants.js +23 -4
  10. package/src/configs/SCConfig.js +1 -1
  11. package/src/context/actionType.ts +6 -2
  12. package/src/context/mockStore.ts +17 -2
  13. package/src/context/reducer.ts +45 -5
  14. package/src/hooks/IoT/__test__/useValueEvaluation.test.js +58 -0
  15. package/src/hooks/IoT/index.js +2 -1
  16. package/src/hooks/IoT/useValueEvaluation.js +45 -0
  17. package/src/hooks/useReceiveNotifications.js +13 -18
  18. package/src/navigations/UnitStack.js +8 -0
  19. package/src/screens/AddLocationMaps/__test__/index.test.js +265 -0
  20. package/src/screens/AddLocationMaps/index.js +39 -16
  21. package/src/screens/AddNewAction/SelectAction.js +25 -5
  22. package/src/screens/AddNewAction/SetupSensor.js +62 -26
  23. package/src/screens/AddNewAction/__test__/SetupSensor.test.js +2 -0
  24. package/src/screens/Device/detail.js +18 -27
  25. package/src/screens/Device/hooks/useEvaluateValue.js +97 -0
  26. package/src/screens/Device/hooks/useFavoriteDevice.js +2 -2
  27. package/src/screens/Notification/__test__/Notification.test.js +17 -0
  28. package/src/screens/Notification/index.js +4 -0
  29. package/src/screens/ScriptDetail/index.js +13 -3
  30. package/src/screens/Sharing/SelectPermission.js +19 -11
  31. package/src/screens/Unit/Detail.js +13 -7
  32. package/src/screens/Unit/SelectAddress.js +1 -3
  33. package/src/screens/Unit/SelectDevices.js +158 -0
  34. package/src/screens/Unit/SelectDevicesStyles.js +40 -0
  35. package/src/screens/Unit/Summaries.js +1 -1
  36. package/src/screens/Unit/__test__/SelectAddress.test.js +90 -1
  37. package/src/screens/Unit/__test__/SelectDevices.test.js +110 -0
  38. package/src/screens/Unit/styles.js +4 -0
  39. package/src/utils/Apis/axios.js +6 -0
  40. package/src/utils/I18n/translations/en.json +7 -1
  41. package/src/utils/I18n/translations/vi.json +7 -1
  42. package/src/utils/Route/index.js +1 -0
  43. package/src/utils/Utils.js +1 -0
  44. package/src/utils/Validation.js +3 -0
package/index.js CHANGED
@@ -17,6 +17,7 @@ import NotificationStack from './src/navigations/NotificationStack';
17
17
  import MyPinnedSharedUnit from './src/commons/Dashboard/MyPinnedSharedUnit';
18
18
  import MyUnit from './src/commons/Dashboard/MyUnit';
19
19
  import SharedUnit from './src/commons/Unit/SharedUnit';
20
+ import { Action } from './src/context/actionType';
20
21
 
21
22
  export {
22
23
  AddSubUnitStack,
@@ -40,4 +41,5 @@ export {
40
41
  SharedUnit,
41
42
  MyUnit,
42
43
  SCWrapper,
44
+ Action,
43
45
  };
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.09",
4
+ "version": "0.3.12",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -234,7 +234,7 @@ const HistoryChart = memo(
234
234
  )}
235
235
  <DateTimePickerModal
236
236
  isVisible={eventPicker.showModalStart}
237
- date={eventPicker.startTime.valueOf()}
237
+ date={eventPicker.startTime?._d}
238
238
  mode={formatType || 'datetime'}
239
239
  onConfirm={onConfirmStart}
240
240
  onCancel={onCancel}
@@ -244,7 +244,7 @@ const HistoryChart = memo(
244
244
  />
245
245
  <DateTimePickerModal
246
246
  isVisible={eventPicker.showModalEnd}
247
- date={eventPicker.endTime.valueOf()}
247
+ date={eventPicker.endTime?._d}
248
248
  mode={formatType || 'datetime'}
249
249
  onConfirm={onConfirmEnd}
250
250
  onCancel={onCancel}
@@ -96,6 +96,9 @@ const MediaPlayerDetail = ({
96
96
  }, [amount]);
97
97
 
98
98
  const renderCamera = useMemo(() => {
99
+ if (!uri) {
100
+ return null;
101
+ }
99
102
  return (
100
103
  <VLCPlayer
101
104
  autoAspectRatio={true}
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
+ import { useNavigation } from '@react-navigation/native';
3
4
  import { useTranslations } from '../../../hooks/Common/useTranslations';
4
5
  import { useSensorsStatus } from '../../../hooks/Common';
5
6
 
@@ -8,7 +9,7 @@ import ItemDevice from '../../Device/ItemDevice';
8
9
  import ItemOneTap from '../OneTap/ItemOneTap';
9
10
  import ItemAddNew from '../../Device/ItemAddNew';
10
11
  import styles from './styles';
11
- import { notImplemented } from '../../../utils/Utils';
12
+ import Routes from '../../../utils/Route';
12
13
 
13
14
  const SubUnitFavorites = ({
14
15
  isOwner,
@@ -18,11 +19,14 @@ const SubUnitFavorites = ({
18
19
  wrapItemStyle,
19
20
  }) => {
20
21
  const t = useTranslations();
22
+ const { navigate } = useNavigation();
21
23
 
22
24
  const { getStatus, serverDown } = useSensorsStatus(unit, favoriteDevices);
23
25
 
24
26
  const handleOnAddNew = () => {
25
- notImplemented(t);
27
+ navigate(Routes.SelectDevices, {
28
+ unitId: unit.id,
29
+ });
26
30
  };
27
31
 
28
32
  return (
@@ -4,8 +4,13 @@ import ConfigHistoryChart from '../';
4
4
  import { SCProvider } from '../../../../context';
5
5
  import { mockSCStore } from '../../../../context/mockStore';
6
6
  import HistoryChart from '../../../../commons/Device/HistoryChart';
7
+ import MockAdapter from 'axios-mock-adapter';
8
+ import { API } from '../../../../configs';
9
+ import api from '../../../../utils/Apis/axios';
7
10
 
8
- const wrapComponent = (configs = []) => (
11
+ const mock = new MockAdapter(api.axiosInstance);
12
+
13
+ const wrapComponent = (configs = [1]) => (
9
14
  <SCProvider initState={mockSCStore({})}>
10
15
  <ConfigHistoryChart configs={configs} />
11
16
  </SCProvider>
@@ -16,6 +21,28 @@ describe('Test HistoryChart', () => {
16
21
 
17
22
  beforeAll(() => {
18
23
  jest.useFakeTimers();
24
+ mock.onGet(API.CONFIG.DISPLAY_HISTORY()).reply(200, [
25
+ {
26
+ config: 1,
27
+ data: [
28
+ {
29
+ url: 'https://valuelog-history/test',
30
+ },
31
+ {
32
+ x: '2022-06-16T00:00:00Z',
33
+ y: 5.0,
34
+ },
35
+ ],
36
+ },
37
+ ]);
38
+ mock.onGet('https://valuelog-history/test').reply(200, [
39
+ {
40
+ config_id: 1,
41
+ start_time: '2022-07-04T02:00:06.151765Z',
42
+ value_log: 0.0,
43
+ converted_value_log: 0.0,
44
+ },
45
+ ]);
19
46
  });
20
47
 
21
48
  it('Test render', async () => {
@@ -11,45 +11,78 @@ export const dateTimeType = {
11
11
  dateTime: 'datetime',
12
12
  };
13
13
 
14
- export const updateConfigChart = (
15
- success,
16
- data,
17
- configuration,
18
- setChartData
19
- ) => {
20
- if (success) {
21
- for (let i = 0; i < data.length; i++) {
22
- for (let j = 0; j < data[i].data.length; j++) {
23
- data[i].data[j].x = moment(data[i].data[j].x).toDate();
24
- }
25
- }
26
- setChartData(
27
- configuration.map((config) => {
28
- config.data = data.find((k) => k.config === config.id).data;
29
- return config;
30
- })
31
- );
32
- }
33
- };
34
-
35
14
  const ConfigHistoryChart = memo(({ configs }) => {
36
15
  const [chartData, setChartData] = useState(configs);
37
16
  const [startDate, setStartDate] = useState(moment().subtract(1, 'days'));
38
17
  const [endDate, setEndDate] = useState(moment());
39
18
 
40
19
  useEffect(() => {
20
+ const fetchDataS3 = (url) => {
21
+ return (
22
+ axiosGet(url, {
23
+ transformRequest: (rq, headers) => {
24
+ delete headers.Authorization;
25
+ return rq;
26
+ },
27
+ })
28
+ // eslint-disable-next-line promise/prefer-await-to-then
29
+ .then((response) => {
30
+ return response.data;
31
+ })
32
+ // eslint-disable-next-line promise/prefer-await-to-callbacks
33
+ .catch((error) => {})
34
+ );
35
+ };
36
+
41
37
  const fetchData = async () => {
42
38
  let params = new URLSearchParams();
43
39
  let configuration = configs.filter((item) => item.id);
44
40
  configuration.map((item) => {
45
41
  params.append('config', item.id);
46
42
  });
47
- params.append('date_from', startDate.valueOf() / 1000);
48
- params.append('date_to', endDate.valueOf() / 1000);
43
+ params.append('date_from', startDate.unix());
44
+ params.append('date_to', endDate.unix());
45
+
49
46
  const { success, data } = await axiosGet(API.CONFIG.DISPLAY_HISTORY(), {
50
47
  params,
51
48
  });
52
- updateConfigChart(success, data, configuration, setChartData);
49
+ if (success) {
50
+ let urls = [];
51
+ data.forEach((config) => {
52
+ config.data.forEach((value_log) => {
53
+ if (value_log.url) {
54
+ urls.push(value_log.url);
55
+ } else {
56
+ value_log.x = moment(value_log.x).toDate();
57
+ }
58
+ });
59
+ });
60
+
61
+ // eslint-disable-next-line promise/prefer-await-to-then
62
+ Promise.all(urls.map(fetchDataS3)).then((result) => {
63
+ let s3_data = [].concat.apply(
64
+ [],
65
+ result.filter((r) => r.length > 0)
66
+ );
67
+ s3_data.forEach((value_log) => {
68
+ value_log.x = moment(value_log.start_time).toDate();
69
+ value_log.y = value_log.converted_value_log;
70
+ });
71
+ setChartData(
72
+ configuration.map((config) => {
73
+ let s3_config_data = [].concat.apply(
74
+ [],
75
+ s3_data.filter((x) => x.config_id === config.id)
76
+ );
77
+ let config_data = data.find((k) => k.config === config.id).data;
78
+ config_data = config_data.filter((k) => !('url' in k));
79
+ config.data = [...s3_config_data, ...config_data];
80
+ config.data = config.data.sort((a, b) => a.x > b.x);
81
+ return config;
82
+ })
83
+ );
84
+ });
85
+ }
53
86
  };
54
87
  fetchData();
55
88
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -29,6 +29,9 @@ const API = {
29
29
  CHANGE_OWNER: (id) => `/property_manager/units/${id}/change_owner/`,
30
30
  FAVOURITE_DEVICES: (id) =>
31
31
  `/property_manager/units/${id}/favourite_devices/`,
32
+ DEVICES: (id) => `/property_manager/units/${id}/devices/`,
33
+ ADD_DEVICES_TO_FAVORITES: (id) =>
34
+ `/property_manager/units/${id}/add_devices_to_favourites/`,
32
35
  },
33
36
  SUB_UNIT: {
34
37
  REMOVE_SUB_UNIT: (unitId, id) =>
@@ -77,7 +80,7 @@ const API = {
77
80
  ACCESS: (id) => `/property_manager/shared_sensors/${id}/access/`,
78
81
  },
79
82
  CONFIG: {
80
- DISPLAY_HISTORY: () => '/property_manager/configs/display_history/',
83
+ DISPLAY_HISTORY: () => '/property_manager/configs/display_history_v2/',
81
84
  },
82
85
  AUTOMATE: {
83
86
  ACTION_ONE_TAP: (id) => `/property_manager/automate/${id}/action_one_tap/`,
@@ -173,6 +176,7 @@ const API = {
173
176
  `/notifications/eoh/?page=${page}&type=${type}`,
174
177
  SET_READ: (id) => `/notifications/eoh/${id}/set_read/`,
175
178
  },
179
+ VALUE_EVALUATIONS: () => '/property_manager/config_value_evaluations/',
176
180
  EXTERNAL: {
177
181
  GOOGLE_MAP: {
178
182
  AUTO_COMPLETE:
@@ -60,6 +60,9 @@ export const DEEP_LINK = {
60
60
  NOTIFICATION_SCREEN: 'app://eoh/notifications',
61
61
  };
62
62
 
63
+ const URL_STREAM_CAMERA_DEMO =
64
+ 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4';
65
+
63
66
  export const Constants = {
64
67
  paddingTop: getStatusBarHeight(),
65
68
  width: Dimensions.get('window').width,
@@ -69,7 +72,7 @@ export const Constants = {
69
72
  FONT_PREFIX,
70
73
  isIphoneX,
71
74
  DEEP_LINK,
72
- URL_STREAM_BALCONY_CAMERA,
75
+ URL_STREAM_CAMERA_DEMO,
73
76
  };
74
77
 
75
78
  export const DEVICE_TYPE = {
@@ -144,6 +147,25 @@ export const CONDITION_TYPES = {
144
147
  IS_ABOVE: 'IS_ABOVE',
145
148
  };
146
149
 
150
+ export const STATE_VALUE_SENSOR_TYPES = [
151
+ {
152
+ type: 'smoke',
153
+ stateValue: ['not_detected', 'detected'],
154
+ },
155
+ {
156
+ type: 'fire',
157
+ stateValue: ['not_detected', 'detected'],
158
+ },
159
+ {
160
+ type: 'sos',
161
+ stateValue: ['not_activated', 'activated'],
162
+ },
163
+ {
164
+ type: 'filter_water',
165
+ stateValue: ['not_detected', 'detected'],
166
+ },
167
+ ];
168
+
147
169
  export const AUTOMATES = {
148
170
  one_tap: {
149
171
  value: AUTOMATE_TYPE.ONE_TAP,
@@ -830,6 +852,3 @@ export const PROBLEM_CODE = {
830
852
  UNKNOWN_ERROR: 'UNKNOWN_ERROR',
831
853
  CANCEL_ERROR: 'CANCEL_ERROR',
832
854
  };
833
-
834
- const URL_STREAM_BALCONY_CAMERA =
835
- 'rtsp://admin:Eoh@2020@101.99.33.220:30554/main';
@@ -112,7 +112,7 @@ export class SCConfig {
112
112
 
113
113
  export const initSCConfig = (config) => {
114
114
  api.setBaseURL(config.apiRoot ?? SCDefaultConfig.apiRoot);
115
- LocaleConfig.defaultLocale = config.language;
115
+ LocaleConfig.defaultLocale = config.language ?? SCConfig.language;
116
116
  SCConfig.language = config.language ?? SCConfig.language;
117
117
  SCConfig.apiRoot = config.apiRoot ?? SCDefaultConfig.apiRoot;
118
118
  SCConfig.GOOGLE_MAP_API_KEY =
@@ -12,14 +12,16 @@ export const Action = {
12
12
  CAMERA_STATUS_CHANGE: 'CAMERA_STATUS_CHANGE',
13
13
  CLOSE_ALL_CAMERA: 'CLOSE_ALL_CAMERA',
14
14
  SET_FAVORITE_DEVICES: 'SET_FAVORITE_DEVICES',
15
- ADD_DEVICE_TO_FAVORITES: 'ADD_DEVICE_TO_FAVORITES',
16
- REMOVE_DEVICE_FROM_FAVORITES: 'REMOVE_DEVICE_FROM_FAVORITES',
15
+ ADD_DEVICES_TO_FAVORITES: 'ADD_DEVICE_TO_FAVORITES',
16
+ REMOVE_DEVICES_FROM_FAVORITES: 'REMOVE_DEVICE_FROM_FAVORITES',
17
17
  SET_STARRED_SCRIPTS: 'SET_STARRED_SCRIPTS',
18
18
  STAR_SCRIPT: 'STAR_SCRIPT',
19
19
  UNSTAR_SCRIPT: 'UNSTAR_SCRIPT',
20
20
  CONNECTING_GOOGLE_HOME: 'CONNECTING_GOOGLE_HOME',
21
21
  SET_GOOGLE_HOME_CONNECTIONS: 'SET_GOOGLE_HOME_CONNECTIONS',
22
22
  CHANGE_GOOGLE_HOME_CONN_STATE: 'CHANGE_GOOGLE_HOME_CONN_STATE',
23
+ UPDATE_VALUE_EVALUATIONS: 'UPDATE_VALUE_EVALUATIONS',
24
+ ON_RECEIVE_NOTIFICATION: 'ON_RECEIVE_NOTIFICATION',
23
25
  };
24
26
 
25
27
  export type AuthData = {
@@ -76,10 +78,12 @@ export type AppType = {
76
78
  isBluetoothEnabled: boolean;
77
79
  isNetworkConnected: boolean;
78
80
  camera_opened: any[];
81
+ notificationData: any;
79
82
  };
80
83
 
81
84
  export type IoTType = {
82
85
  googlehome: {
86
+ isFirstTimeConnect: boolean;
83
87
  isConnecting: boolean;
84
88
  connections: {};
85
89
  };
@@ -31,10 +31,23 @@ export const mockDataStore: ContextData = {
31
31
  automate: {
32
32
  starredScriptIds: [],
33
33
  },
34
+ app: {
35
+ isFirstOpenCamera: true,
36
+ isLavidaSource: false,
37
+ isConnectWifiGateway: false,
38
+ isBluetoothEnabled: true,
39
+ isNetworkConnected: true,
40
+ camera_opened: [],
41
+ },
34
42
  iot: {
35
- isConnecting: false,
36
- googlehome: {},
43
+ googlehome: {
44
+ isFirstTimeConnect: true,
45
+ isConnecting: false,
46
+ connections: {},
47
+ },
37
48
  },
49
+ valueEvaluations: {},
50
+ fetchedValueEvaluationUnits: [],
38
51
  };
39
52
 
40
53
  export const mockSCStore = (data: ContextData): ContextData => {
@@ -82,5 +95,7 @@ export const mockSCStore = (data: ContextData): ContextData => {
82
95
  connections: {},
83
96
  },
84
97
  },
98
+ valueEvaluations: {},
99
+ fetchedValueEvaluationUnits: [],
85
100
  };
86
101
  };
@@ -12,7 +12,7 @@ import {
12
12
  AppType,
13
13
  IoTType,
14
14
  } from './actionType';
15
- import { uniq } from 'lodash';
15
+ import { uniq, reduce } from 'lodash';
16
16
 
17
17
  export type ContextData = {
18
18
  auth: AuthData;
@@ -24,6 +24,8 @@ export type ContextData = {
24
24
  automate: AutomateType;
25
25
  app: AppType;
26
26
  iot: IoTType;
27
+ valueEvaluations: {};
28
+ fetchedValueEvaluationUnits: Array<number>;
27
29
  };
28
30
 
29
31
  export type Action = {
@@ -57,12 +59,17 @@ export const initialState = {
57
59
  isBluetoothEnabled: false,
58
60
  isNetworkConnected: false,
59
61
  camera_opened: [],
62
+ notificationData: null,
60
63
  },
61
64
  iot: {
62
65
  googlehome: {
66
+ isFirstTimeConnect: true,
67
+ isConnecting: false,
63
68
  connections: {},
64
69
  },
65
70
  },
71
+ valueEvaluations: {},
72
+ fetchedValueEvaluationUnits: [],
66
73
  };
67
74
 
68
75
  export const reducer = (currentState: ContextData, action: Action) => {
@@ -199,7 +206,7 @@ export const reducer = (currentState: ContextData, action: Action) => {
199
206
  favoriteDeviceIds: payload,
200
207
  },
201
208
  };
202
- case Action.ADD_DEVICE_TO_FAVORITES:
209
+ case Action.ADD_DEVICES_TO_FAVORITES:
203
210
  return {
204
211
  ...currentState,
205
212
  unit: {
@@ -209,13 +216,13 @@ export const reducer = (currentState: ContextData, action: Action) => {
209
216
  ),
210
217
  },
211
218
  };
212
- case Action.REMOVE_DEVICE_FROM_FAVORITES:
219
+ case Action.REMOVE_DEVICES_FROM_FAVORITES:
213
220
  return {
214
221
  ...currentState,
215
222
  unit: {
216
223
  ...currentState.unit,
217
224
  favoriteDeviceIds: currentState.unit.favoriteDeviceIds.filter(
218
- (deviceId) => deviceId !== payload
225
+ (deviceId) => !payload.includes(deviceId)
219
226
  ),
220
227
  },
221
228
  };
@@ -256,6 +263,7 @@ export const reducer = (currentState: ContextData, action: Action) => {
256
263
  ...currentState.iot,
257
264
  googlehome: {
258
265
  ...currentState.iot.googlehome,
266
+ isFirstTimeConnect: false,
259
267
  isConnecting: false,
260
268
  connections: payload,
261
269
  },
@@ -268,6 +276,7 @@ export const reducer = (currentState: ContextData, action: Action) => {
268
276
  ...currentState.iot,
269
277
  googlehome: {
270
278
  ...currentState.iot.googlehome,
279
+ isFirstTimeConnect: false,
271
280
  isConnecting: false,
272
281
  connections: {
273
282
  ...currentState.iot.googlehome.connections,
@@ -283,11 +292,42 @@ export const reducer = (currentState: ContextData, action: Action) => {
283
292
  ...currentState.iot,
284
293
  googlehome: {
285
294
  ...currentState.iot.googlehome,
286
- isConnecting: true,
295
+ isConnecting: currentState.iot.googlehome.isFirstTimeConnect
296
+ ? true
297
+ : false,
287
298
  },
288
299
  },
289
300
  };
290
301
 
302
+ case Action.UPDATE_VALUE_EVALUATIONS:
303
+ // eslint-disable-next-line no-case-declarations
304
+ const { data, unitId } = payload;
305
+ return {
306
+ ...currentState,
307
+ fetchedValueEvaluationUnits:
308
+ currentState.fetchedValueEvaluationUnits.indexOf(unitId) !== -1
309
+ ? currentState.fetchedValueEvaluationUnits
310
+ : [...currentState.fetchedValueEvaluationUnits, unitId],
311
+ valueEvaluations: reduce(
312
+ data,
313
+ (dict, item) => {
314
+ // eslint-disable-next-line no-param-reassign
315
+ dict[item.config] = item;
316
+ return dict;
317
+ },
318
+ currentState.valueEvaluations
319
+ ),
320
+ };
321
+
322
+ case Action.ON_RECEIVE_NOTIFICATION:
323
+ return {
324
+ ...currentState,
325
+ app: {
326
+ ...currentState.app,
327
+ notificationData: payload,
328
+ },
329
+ };
330
+
291
331
  default:
292
332
  return currentState;
293
333
  }
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import { renderHook } from '@testing-library/react-hooks';
3
+ import MockAdapter from 'axios-mock-adapter';
4
+ import { SCProvider } from '../../../context';
5
+ import { mockSCStore } from '../../../context/mockStore';
6
+ import { useValueEvaluations } from '../index';
7
+ import api from '../../../utils/Apis/axios';
8
+ import { API } from '../../../configs';
9
+
10
+ const mock = new MockAdapter(api.axiosInstance);
11
+
12
+ const mockedSetAction = jest.fn();
13
+
14
+ const wrapper = ({ children }) => <SCProvider>{children}</SCProvider>;
15
+
16
+ const mockUseContext = jest.fn().mockImplementation(() => ({
17
+ stateData: mockSCStore({}),
18
+ setAction: mockedSetAction,
19
+ }));
20
+
21
+ React.useContext = mockUseContext;
22
+
23
+ describe('Test useValueEvaluation', () => {
24
+ beforeEach(() => {
25
+ mock.resetHistory();
26
+ });
27
+
28
+ it('test unitId null', async () => {
29
+ renderHook(() => useValueEvaluations(null), {
30
+ wrapper,
31
+ });
32
+ expect(mock.history.get.length).toBe(0);
33
+ });
34
+
35
+ it('test unitId not null request success', async () => {
36
+ mock.onGet(API.VALUE_EVALUATIONS()).replyOnce(200, {
37
+ results: [],
38
+ next: 'link',
39
+ });
40
+ mock.onGet(API.VALUE_EVALUATIONS()).replyOnce(200, {
41
+ results: [],
42
+ });
43
+ renderHook(() => useValueEvaluations(1), {
44
+ wrapper,
45
+ });
46
+ expect(mock.history.get.length).toBe(1);
47
+ });
48
+
49
+ it('test request failed', async () => {
50
+ mock.onGet(API.VALUE_EVALUATIONS()).replyOnce(400, {
51
+ results: [],
52
+ });
53
+ renderHook(() => useValueEvaluations(1), {
54
+ wrapper,
55
+ });
56
+ expect(mock.history.get.length).toBe(1);
57
+ });
58
+ });
@@ -1,4 +1,5 @@
1
1
  import useGGHomeConnection from './useGGHomeConnection';
2
2
  import useRemoteControl from './useRemoteControl';
3
+ import useValueEvaluations from './useValueEvaluation';
3
4
 
4
- export { useGGHomeConnection, useRemoteControl };
5
+ export { useGGHomeConnection, useRemoteControl, useValueEvaluations };
@@ -0,0 +1,45 @@
1
+ import { useCallback, useContext, useEffect } from 'react';
2
+ import { API } from '../../configs';
3
+ import { SCContext, useSCContextSelector } from '../../context';
4
+ import { Action } from '../../context/actionType';
5
+ import { axiosGet } from '../../utils/Apis/axios';
6
+
7
+ const useValueEvaluations = (unitId) => {
8
+ const { setAction } = useContext(SCContext);
9
+
10
+ const fetchConfigValueEvaluations = useCallback(
11
+ async (page = 1) => {
12
+ if (!unitId) {
13
+ return;
14
+ }
15
+ const params = new URLSearchParams();
16
+ params.append('config__end_device__station__unit', unitId);
17
+ params.append('page', page);
18
+ const { success, data } = await axiosGet(API.VALUE_EVALUATIONS(), {
19
+ params,
20
+ });
21
+ if (success) {
22
+ setAction(Action.UPDATE_VALUE_EVALUATIONS, {
23
+ unitId,
24
+ data: data.results,
25
+ });
26
+ if (data.next) {
27
+ await fetchConfigValueEvaluations(page + 1);
28
+ }
29
+ }
30
+ },
31
+ [unitId, setAction]
32
+ );
33
+
34
+ const fetchedValueEvaluationUnits = useSCContextSelector((state) => {
35
+ return state.fetchedValueEvaluationUnits || [];
36
+ });
37
+
38
+ useEffect(() => {
39
+ if (!(fetchedValueEvaluationUnits.indexOf(unitId) !== -1)) {
40
+ fetchConfigValueEvaluations();
41
+ }
42
+ }, [unitId, fetchConfigValueEvaluations, fetchedValueEvaluationUnits]);
43
+ };
44
+
45
+ export default useValueEvaluations;
@@ -1,25 +1,20 @@
1
- import { useEffect, useState, useCallback } from 'react';
2
- import OneSignal from 'react-native-onesignal';
1
+ import { useEffect, useState } from 'react';
2
+ import { useSCContextSelector } from '../context';
3
3
 
4
- const useReceiveNotifications = () => {
5
- const [dataNofitication, setDataNofitication] = useState(null);
6
-
7
- const onReceived = useCallback((data) => {
8
- const { additionalData } = data;
9
- setDataNofitication(additionalData);
10
- }, []);
4
+ const useReceiveNotifications = (callBack) => {
5
+ const [dataNotification, setDataNotification] = useState(null);
6
+ const notificationData = useSCContextSelector(
7
+ (state) => state.app.notificationData
8
+ );
11
9
 
12
10
  useEffect(() => {
13
- OneSignal.setNotificationWillShowInForegroundHandler(
14
- (notifReceivedEvent) => {
15
- let notif = notifReceivedEvent.getNotification();
16
- setTimeout(() => notifReceivedEvent.complete(notif), 0);
17
- onReceived(notif);
18
- }
19
- );
20
- }, [onReceived]);
11
+ if (notificationData) {
12
+ setDataNotification(notificationData);
13
+ callBack && callBack();
14
+ }
15
+ }, [callBack, notificationData]);
21
16
 
22
- return { dataNofitication };
17
+ return { dataNotification };
23
18
  };
24
19
 
25
20
  export default useReceiveNotifications;
@@ -51,6 +51,7 @@ import EmergencySetting from '../screens/EmergencySetting';
51
51
  import ConfirmUnitDeletion from '../screens/ConfirmUnitDeletion';
52
52
  import InfoMemberUnit from '../screens/Sharing/InfoMemberUnit';
53
53
  import EnterPassword from '../screens/EnterPassword';
54
+ import SelectDevices from '../screens/Unit/SelectDevices';
54
55
  import { HanetCameraStack } from './HanetCameraStack';
55
56
  import { axiosGet } from '../utils/Apis/axios';
56
57
  import { API } from '../configs';
@@ -400,6 +401,13 @@ export const UnitStack = memo((props) => {
400
401
  headerShown: false,
401
402
  }}
402
403
  />
404
+ <Stack.Screen
405
+ name={Route.SelectDevices}
406
+ component={SelectDevices}
407
+ options={{
408
+ headerShown: false,
409
+ }}
410
+ />
403
411
  </Stack.Navigator>
404
412
  );
405
413
  });