@eohjsc/react-native-smart-city 0.2.84 → 0.2.87

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 (128) hide show
  1. package/assets/images/Device/button-lock.svg +3 -0
  2. package/assets/images/Device/button-unlock.svg +3 -0
  3. package/assets/images/brightness.svg +12 -0
  4. package/assets/images/brightnessBlack.svg +12 -0
  5. package/index.js +4 -0
  6. package/package.json +3 -1
  7. package/src/Images/Common/SuccessfullyConnected.svg +4 -0
  8. package/src/Images/Common/eye-closed.png +0 -0
  9. package/src/Images/Common/eye-closed@2x.png +0 -0
  10. package/src/Images/Common/eye-closed@3x.png +0 -0
  11. package/src/Images/Common/eye.png +0 -0
  12. package/src/Images/Common/eye@2x.png +0 -0
  13. package/src/Images/Common/eye@3x.png +0 -0
  14. package/src/Images/SmartIr/AC.svg +14 -0
  15. package/src/Images/SmartIr/DIY.svg +3 -0
  16. package/src/Images/SmartIr/Fan.svg +10 -0
  17. package/src/Images/SmartIr/Fridge.svg +5 -0
  18. package/src/Images/SmartIr/TV.svg +10 -0
  19. package/src/Images/SmartIr/WM.svg +11 -0
  20. package/src/Images/SmartIr/index.js +7 -0
  21. package/src/commons/ActionGroup/LightActionTemplate.js +103 -0
  22. package/src/commons/ActionGroup/LightActionTemplateStyles.js +57 -0
  23. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/AutoLockStyles.js +40 -0
  24. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/ButtonWrapper.js +65 -0
  25. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/ButtonWrapperStyles.js +43 -0
  26. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/__test__/index.test.js +48 -0
  27. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/index.js +57 -0
  28. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +48 -0
  29. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLockStyle.js +51 -0
  30. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/ItemPasscode.js +48 -0
  31. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/ItemPasscodeStyles.js +42 -0
  32. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/PasscodeListStyles.js +49 -0
  33. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/index.js +66 -0
  34. package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/ButtonWrapper.js +96 -0
  35. package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/SetupGeneratePasscodeStyles.js +98 -0
  36. package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/__test__/index.test.js +62 -0
  37. package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/index.js +249 -0
  38. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +33 -31
  39. package/src/commons/ActionGroup/OnOffTemplate/index.js +4 -2
  40. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +2 -1
  41. package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +188 -186
  42. package/src/commons/ActionGroup/StatesGridActionTemplate.js +2 -1
  43. package/src/commons/ActionGroup/__test__/LightActionTemplate.test.js +59 -0
  44. package/src/commons/ActionGroup/index.js +6 -0
  45. package/src/commons/CardShadow/index.js +5 -2
  46. package/src/commons/CardShadow/styles.js +2 -3
  47. package/src/commons/ConnectingProcess/DeviceItem/DeviceItem.js +16 -0
  48. package/src/commons/ConnectingProcess/DeviceItem/DeviceItemStyles.js +42 -0
  49. package/src/commons/ConnectingProcess/__test__/Connecting.test.js +27 -0
  50. package/src/commons/ConnectingProcess/__test__/DeviceItem.test.js +18 -0
  51. package/src/commons/ConnectingProcess/index.js +205 -0
  52. package/src/commons/ConnectingProcess/styles.js +69 -0
  53. package/src/commons/Device/DisconnectedView.js +7 -1
  54. package/src/commons/Device/ItemDevice.js +8 -3
  55. package/src/commons/Device/LinearChart.js +3 -39
  56. package/src/commons/Device/__test__/DisconnectedView.test.js +13 -2
  57. package/src/commons/Form/TextInputPassword.js +1 -1
  58. package/src/commons/MediaPlayer/__test__/index.test.js +45 -0
  59. package/src/commons/RowItem/index.js +12 -7
  60. package/src/commons/SubUnit/ShortDetail.js +10 -22
  61. package/src/commons/SubUnit/__test__/ShortDetail.test.js +57 -48
  62. package/src/commons/WheelDateTimePicker/index.js +18 -4
  63. package/src/configs/API.js +4 -2
  64. package/src/configs/Colors.js +1 -0
  65. package/src/configs/Constants.js +39 -0
  66. package/src/configs/Images.js +2 -0
  67. package/src/context/actionType.ts +2 -0
  68. package/src/context/mockStore.ts +1 -0
  69. package/src/context/reducer.ts +10 -0
  70. package/src/hooks/Common/useBlockBackAndroid.js +3 -1
  71. package/src/iot/RemoteControl/Bluetooth.js +3 -3
  72. package/src/navigations/AddDeviceStack.js +10 -0
  73. package/src/navigations/SmartIrStack.js +31 -0
  74. package/src/navigations/SmartLockStack.js +51 -0
  75. package/src/navigations/UnitStack.js +12 -3
  76. package/src/screens/ActivityLog/hooks/index.js +18 -4
  77. package/src/screens/ActivityLog/index.js +3 -0
  78. package/src/screens/AddCommon/SelectSubUnit.js +30 -6
  79. package/src/screens/AddCommon/SelectUnit.js +24 -2
  80. package/src/screens/AddCommon/__test__/SelectSubUnit.test.js +120 -1
  81. package/src/screens/AddCommon/__test__/SelectUnit.test.js +16 -1
  82. package/src/screens/AddNewAction/SelectSensorDevices.js +4 -2
  83. package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +97 -37
  84. package/src/screens/AddNewGateway/PlugAndPlay/FirstWarning.js +4 -2
  85. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +178 -35
  86. package/src/screens/AddNewGateway/PlugAndPlay/__test__/ConnectWifiWarning.test.js +58 -0
  87. package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +26 -2
  88. package/src/screens/AddNewGateway/SelectGateway.js +132 -0
  89. package/src/screens/AddNewGateway/SelectGatewayStyles.js +55 -0
  90. package/src/screens/AddNewOneTap/index.js +32 -17
  91. package/src/screens/Automate/index.js +2 -2
  92. package/src/screens/Device/EditDevice/index.js +5 -3
  93. package/src/screens/Device/components/SensorConnectStatusViewHeader.js +13 -2
  94. package/src/screens/Device/components/SensorDisplayItem.js +3 -0
  95. package/src/screens/Device/detail.js +56 -16
  96. package/src/screens/Device/hooks/useDisconnectedDevice.js +21 -5
  97. package/src/screens/GuestInfo/components/AccessScheduleItem.js +9 -2
  98. package/src/screens/GuestInfo/components/RecurringDetail.js +3 -2
  99. package/src/screens/GuestInfo/components/TemporaryDetail.js +3 -2
  100. package/src/screens/GuestInfo/styles/AccessScheduleItemStyles.js +3 -0
  101. package/src/screens/Notification/__test__/NotificationItem.test.js +28 -5
  102. package/src/screens/Notification/components/NotificationItem.js +128 -20
  103. package/src/screens/ScanChipQR/__test__/ScanChipQR.test.js +11 -7
  104. package/src/screens/ScanChipQR/hooks/index.js +89 -19
  105. package/src/screens/ScriptDetail/index.js +1 -6
  106. package/src/screens/SelectUnit/index.js +1 -0
  107. package/src/screens/SharedUnit/index.js +1 -1
  108. package/src/screens/SmartIr/__test__/GroupButtonByType.test.js +54 -0
  109. package/src/screens/SmartIr/__test__/SelectBrand.test.js +74 -0
  110. package/src/screens/SmartIr/__test__/SelectDeviceType.test.js +64 -0
  111. package/src/screens/SmartIr/__test__/SmartIr.test.js +62 -0
  112. package/src/screens/SmartIr/components/GroupButtonByType/GroupButtonByType.js +86 -0
  113. package/src/screens/SmartIr/components/GroupButtonByType/GroupButtonByTypeStyles.js +76 -0
  114. package/src/screens/SmartIr/components/SelectBrand.js +61 -0
  115. package/src/screens/SmartIr/components/SelectBrandStyles.js +14 -0
  116. package/src/screens/SmartIr/components/SelectDeviceType.js +96 -0
  117. package/src/screens/SmartIr/components/SelectDeviceTypeStyles.js +30 -0
  118. package/src/screens/SmartIr/index.js +28 -0
  119. package/src/screens/SmartIr/styles.js +14 -0
  120. package/src/screens/Unit/AddMenu.js +4 -1
  121. package/src/screens/Unit/Detail.js +31 -5
  122. package/src/screens/Unit/components/MyUnitDevice/index.js +2 -4
  123. package/src/screens/Unit/components/__test__/MyUnitDevice.test.js +38 -9
  124. package/src/screens/UnitSummary/components/PowerConsumeHistoryChart/__test__/index.test.js +32 -1
  125. package/src/screens/UnitSummary/components/PowerConsumeHistoryChart/index.js +1 -1
  126. package/src/utils/I18n/translations/en.json +40 -2
  127. package/src/utils/I18n/translations/vi.json +40 -3
  128. package/src/utils/Route/index.js +11 -0
@@ -1,21 +1,27 @@
1
1
  import React from 'react';
2
- import { Image, View, TouchableWithoutFeedback } from 'react-native';
2
+ import { Image, View } from 'react-native';
3
3
  import { act, create } from 'react-test-renderer';
4
4
  import { TESTID } from '../../../configs/Constants';
5
5
  import { SCProvider } from '../../../context';
6
6
  import { mockSCStore } from '../../../context/mockStore';
7
+ import ShortDetailSubUnit from '../ShortDetail';
8
+ import ItemAddNew from '../../Device/ItemAddNew';
7
9
  import Routes from '../../../utils/Route';
8
10
 
9
- const wrapComponent = (unit, station) => (
11
+ const wrapComponent = (props) => (
10
12
  <SCProvider initState={mockSCStore({})}>
11
- <ShortDetailSubUnit unit={unit} station={station} />
13
+ <ShortDetailSubUnit {...props} />
12
14
  </SCProvider>
13
15
  );
14
16
 
15
- import ShortDetailSubUnit from '../ShortDetail';
17
+ jest.mock('react', () => {
18
+ return {
19
+ ...jest.requireActual('react'),
20
+ memo: (x) => x,
21
+ };
22
+ });
16
23
 
17
24
  const mockedNavigate = jest.fn();
18
-
19
25
  jest.mock('@react-navigation/native', () => {
20
26
  return {
21
27
  ...jest.requireActual('@react-navigation/native'),
@@ -27,43 +33,46 @@ jest.mock('@react-navigation/native', () => {
27
33
  });
28
34
 
29
35
  describe('test ShortDetail Subunit', () => {
30
- let tree, unit, station;
36
+ let tree, props;
31
37
  beforeEach(() => {
32
- unit = {
33
- address: null,
34
- background:
35
- 'https://cdn-staging.eoh.io/image-90a42c0a-96ad-42e5-b736-b2b8a2e7fb20.jpg',
36
- can_add: true,
37
- icon: 'https://cdn-staging.eoh.io/baelen.jpg',
38
- id: 21,
39
- main_config_count: 0,
40
- name: 'Gia Cat Unit',
41
- remote_control_options: { bluetooth: [], googlehome: [] },
42
- stations: [
43
- {
44
- background:
45
- 'https://cdn-staging.eoh.io/image-cc9ea441-e113-46b5-bff3-23d924723733.jpg',
46
- camera: null,
47
- id: 71,
48
- name: 'Station 1',
49
- sensors: [],
50
- },
51
- ],
52
- user_id: 64,
53
- };
54
-
55
- station = {
56
- background:
57
- 'https://cdn-staging.eoh.io/image-cc9ea441-e113-46b5-bff3-23d924723733.jpg',
58
- camera: null,
59
- id: 71,
60
- name: 'Station 1',
38
+ props = {
39
+ unit: {
40
+ address: null,
41
+ background:
42
+ 'https://cdn-staging.eoh.io/image-90a42c0a-96ad-42e5-b736-b2b8a2e7fb20.jpg',
43
+ can_add: true,
44
+ icon: 'https://cdn-staging.eoh.io/baelen.jpg',
45
+ id: 21,
46
+ main_config_count: 0,
47
+ name: 'Gia Cat Unit',
48
+ remote_control_options: { bluetooth: [], googlehome: [] },
49
+ stations: [
50
+ {
51
+ background:
52
+ 'https://cdn-staging.eoh.io/image-cc9ea441-e113-46b5-bff3-23d924723733.jpg',
53
+ camera: null,
54
+ id: 71,
55
+ name: 'Station 1',
56
+ sensors: [],
57
+ },
58
+ ],
59
+ user_id: 64,
60
+ },
61
+ station: {
62
+ background:
63
+ 'https://cdn-staging.eoh.io/image-cc9ea441-e113-46b5-bff3-23d924723733.jpg',
64
+ camera: null,
65
+ id: 71,
66
+ name: 'Station 1',
67
+ },
68
+ isNetworkConnected: true,
69
+ isGGHomeConnected: true,
61
70
  };
62
71
  });
63
72
 
64
73
  test('render ShortDetail', () => {
65
74
  act(() => {
66
- tree = create(wrapComponent(unit, station));
75
+ tree = create(wrapComponent(props));
67
76
  });
68
77
  const instance = tree.root;
69
78
  const image = instance.findAllByType(Image);
@@ -74,9 +83,9 @@ describe('test ShortDetail Subunit', () => {
74
83
  });
75
84
 
76
85
  test('render ShortDetail without background', () => {
77
- station.background = '';
86
+ props.station.background = '';
78
87
  act(() => {
79
- tree = create(wrapComponent(unit, station));
88
+ tree = create(wrapComponent(props));
80
89
  });
81
90
  const instance = tree.root;
82
91
  const image = instance.findAllByType(Image);
@@ -87,7 +96,7 @@ describe('test ShortDetail Subunit', () => {
87
96
  });
88
97
 
89
98
  test('render ShortDetail with camera', () => {
90
- station.camera = {
99
+ props.station.camera = {
91
100
  id: 2,
92
101
  name: 'EoH Gate',
93
102
  preview_uri: '',
@@ -95,7 +104,7 @@ describe('test ShortDetail Subunit', () => {
95
104
  };
96
105
 
97
106
  act(() => {
98
- tree = create(wrapComponent(unit, station));
107
+ tree = create(wrapComponent(props));
99
108
  });
100
109
  const instance = tree.root;
101
110
  const view = instance.findAllByType(View);
@@ -106,7 +115,7 @@ describe('test ShortDetail Subunit', () => {
106
115
  });
107
116
 
108
117
  test('render ShortDetail with device', () => {
109
- station.sensors = [
118
+ props.station.sensors = [
110
119
  {
111
120
  action: {
112
121
  color: '#00979D',
@@ -129,7 +138,7 @@ describe('test ShortDetail Subunit', () => {
129
138
  ];
130
139
 
131
140
  act(() => {
132
- tree = create(wrapComponent(unit, station));
141
+ tree = create(wrapComponent(props));
133
142
  });
134
143
  const instance = tree.root;
135
144
  const itemDevice = instance.findAll(
@@ -141,19 +150,19 @@ describe('test ShortDetail Subunit', () => {
141
150
 
142
151
  test('render ShortDetail add new device', () => {
143
152
  act(() => {
144
- tree = create(wrapComponent(unit, station));
153
+ tree = create(wrapComponent(props));
145
154
  });
146
155
  const instance = tree.root;
147
- const buttonAddNew = instance.findAllByType(TouchableWithoutFeedback);
156
+ const buttonAddNew = instance.findByType(ItemAddNew);
148
157
  act(() => {
149
- buttonAddNew[0].props.onPress();
158
+ buttonAddNew.props.onAddNew();
150
159
  });
151
160
  expect(mockedNavigate).toHaveBeenCalledWith(Routes.AddDeviceStack, {
152
161
  screen: Routes.ScanSensorQR,
153
162
  params: {
154
- station_id: station.id,
155
- unit_id: unit.id,
156
- unit_name: unit.name,
163
+ station_id: props.station.id,
164
+ unit_id: props.unit.id,
165
+ unit_name: props.unit.name,
157
166
  },
158
167
  });
159
168
  });
@@ -92,10 +92,14 @@ const WheelDateTimePicker = ({
92
92
  }, [dateSelected, hourSelected, minuteSelected, onCancel, onPicked]);
93
93
 
94
94
  const title = useMemo(() => {
95
- if (mode === 'time') {
96
- return t('set_time');
95
+ switch (mode) {
96
+ case 'time':
97
+ return t('set_time');
98
+ case 'datetime':
99
+ return t('set_date_time');
100
+ default:
101
+ return t('minutes');
97
102
  }
98
- return t('set_date_time');
99
103
  }, [t, mode]);
100
104
 
101
105
  return (
@@ -125,7 +129,7 @@ const WheelDateTimePicker = ({
125
129
  style={styles.picker}
126
130
  />
127
131
  </View>
128
- ) : (
132
+ ) : mode === 'datetime' ? (
129
133
  <View style={styles.container}>
130
134
  <Picker
131
135
  dataSource={dateData}
@@ -153,6 +157,16 @@ const WheelDateTimePicker = ({
153
157
  style={styles.picker}
154
158
  />
155
159
  </View>
160
+ ) : (
161
+ <View style={styles.container}>
162
+ <Picker
163
+ dataSource={minuteData}
164
+ selectedIndex={indexInitialMinute}
165
+ onValueChange={onValueMinuteChange}
166
+ keyPrefix="minute"
167
+ style={styles.picker}
168
+ />
169
+ </View>
156
170
  )}
157
171
  <ViewButtonBottom
158
172
  leftTitle={t('cancel')}
@@ -53,6 +53,8 @@ const API = {
53
53
  CHIP: {
54
54
  CHECK_FINALIZED: () =>
55
55
  SCConfig.apiRoot + '/property_manager/stations/check_chip_finalized/',
56
+ GET_CHIPS_FROM_UNIT: (id) =>
57
+ SCConfig.apiRoot + `/property_manager/get_chips/?unit_id=${id}`,
56
58
  },
57
59
  SENSOR: {
58
60
  SENSOR_DETAIL: (id) =>
@@ -180,9 +182,9 @@ const API = {
180
182
  `/connection_manager/lg_thinq/device_status/${sensorId}/`,
181
183
  },
182
184
  VCONNEX: {
183
- AUTHORIZE: (client_id, redirect_uri, user_id, station_id) =>
185
+ AUTHORIZE: (client_id, redirect_uri, user_id, unit_id, station_id) =>
184
186
  // eslint-disable-next-line max-len
185
- `https://partner-api-stg.vconnex.vn/oauth/authorize?client_id=${client_id}&redirect_uri=${redirect_uri}&response_type=code&scope=SYNCH&scope=CONTROL&scope=QUERY&state=${user_id}@${station_id}`,
187
+ `https://partner-api.vconnex.vn/oauth/authorize?client_id=${client_id}&redirect_uri=${redirect_uri}&response_type=code&scope=SYNCH&scope=CONTROL&scope=QUERY&state=${user_id}@${unit_id}@${station_id}`,
186
188
  },
187
189
  },
188
190
  NOTIFICATION: {
@@ -110,6 +110,7 @@ export const Colors = {
110
110
  Blue10: '#1890FF',
111
111
  Blue11: '#096DD9',
112
112
  Blue12: '#0050B3',
113
+ Blue13: '#E2F0F8',
113
114
 
114
115
  //Range Volcano:
115
116
  Volcano3: '#FFBB96',
@@ -487,6 +487,12 @@ export const TESTID = {
487
487
  TOUCH_SHARED_UNIT: 'TOUCH_SHARED_UNIT',
488
488
  SHARED_UNIT_OWN_BY: 'SHARED_UNIT_OWN_BY',
489
489
 
490
+ // Select subunit
491
+
492
+ SELECT_SUBUNIT_NAME: 'SELECT_SUBUNIT_NAME',
493
+ SELECT_SUBUNIT_RADIO_BUTTON: 'SELECT_SUBUNIT_RADIO_BUTTON',
494
+ SELECT_SUBUNIT_SELECT: 'SELECT_SUBUNIT_SELECT',
495
+
490
496
  // Select unit
491
497
  SELECT_UNIT_NAME: 'SELECT_UNIT_NAME',
492
498
  SELECT_UNIT_RADIO_BUTTON: 'SELECT_UNIT_RADIO_BUTTON',
@@ -561,6 +567,12 @@ export const TESTID = {
561
567
  ADD_NEW_GATEWAY_THEN_SELECT: 'ADD_NEW_GATEWAY_THEN_SELECT',
562
568
  ADD_NEW_GATEWAY_TEXT_IMEI: 'ADD_NEW_GATEWAY_TEXT_IMEI',
563
569
 
570
+ // Select Gateway
571
+
572
+ SELECT_GATEWAY_NAME: 'SELECT_GATEWAY_NAME',
573
+ SELECT_GATEWAY_RADIO_BUTTON: 'SELECT_GATEWAY_RADIO_BUTTON',
574
+ SELECT_GATEWAY_SELECT: 'SELECT_GATEWAY_SELECT',
575
+
564
576
  // Header
565
577
  HEADER_ANI_TITLE: 'HEADER_ANI_TITLE',
566
578
 
@@ -624,6 +636,16 @@ export const TESTID = {
624
636
 
625
637
  // MoveToAnotherSubUnit
626
638
  ROW_SUB_UNIT: 'ROW_SUB_UNIT',
639
+
640
+ //SetupGeneratePasscode
641
+ GENERATE_PASSCODE_CHOOSE_USER: 'GENERATE_PASSCODE_CHOOSE_USER',
642
+ GENERATE_PASSCODE_SET_TIME: 'GENERATE_PASSCODE_SET_TIME',
643
+ GENERATE_PASSCODE_SET_DURATION: 'GENERATE_PASSCODE_SET_DURATION',
644
+
645
+ //AutoLock
646
+ AUTO_LOCK_BUTTON_ENABLE: 'AUTO_LOCK_BUTTON_ENABLE',
647
+ AUTO_LOCK_BUTTON_INSTANT: 'AUTO_LOCK_BUTTON_INSTANT',
648
+ AUTO_LOCK_BUTTON_RELOCK_TIMING: 'AUTO_LOCK_BUTTON_RELOCK_TIMING',
627
649
  };
628
650
 
629
651
  export const NOTIFICATION_TYPES = {
@@ -648,6 +670,11 @@ export const NOTIFICATION_TYPES = {
648
670
  NOTIFY_REMOVE_MEMBER: 'NOTIFY_REMOVE_MEMBER',
649
671
  NOTIFY_MEMBER_LEAVE_UNIT: 'NOTIFY_MEMBER_LEAVE_UNIT',
650
672
  NOTIFY_RENAME_UNIT: 'NOTIFY_RENAME_UNIT',
673
+ NOTIFY_DEVICE_DISCONNECT: 'NOTIFY_DEVICE_DISCONNECT',
674
+ NOTIFY_RENAME_SUB_UNIT: 'NOTIFY_RENAME_SUB_UNIT',
675
+ NOTIFY_UPDATE_ADDRESS: 'NOTIFY_UPDATE_ADDRESS',
676
+ NOTIFY_REMOVE_SUB_UNIT: 'NOTIFY_REMOVE_SUB_UNIT',
677
+ NOTIFY_REMOVE_DEVICE: 'NOTIFY_REMOVE_DEVICE',
651
678
  };
652
679
 
653
680
  export const ACTIVITY_LOG_TYPES = {
@@ -655,3 +682,15 @@ export const ACTIVITY_LOG_TYPES = {
655
682
  ACTIVATED_BY: 'ACTIVATED_BY',
656
683
  SCRIPT_UPDATED_BY: 'SCRIPT_UPDATED_BY',
657
684
  };
685
+
686
+ export const SENSOR_TYPE = {
687
+ AIR_QUALITY: 'air_quality',
688
+ TURBIDITY: 'turbidity',
689
+ PH: 'ph',
690
+ CLO: 'clo',
691
+ UV: 'uv',
692
+ SMOKE: 'smoke',
693
+ FIRE: 'fire',
694
+ SOS: 'sos',
695
+ FILTER_WATER: 'filter_water',
696
+ };
@@ -11,4 +11,6 @@ export default {
11
11
  buttonLeftCurtain: require('../Images/Common/buttonLeftCurtain.png'),
12
12
  buttonRightCurtain: require('../Images/Common/buttonRightCurtain.png'),
13
13
  shadowButton: require('../Images/Common/shadowButton.png'),
14
+ eye: require('../Images/Common/eye.png'),
15
+ eyeClosed: require('../Images/Common/eye-closed.png'),
14
16
  };
@@ -6,6 +6,7 @@ export const Action = {
6
6
  LIST_ACTION: 'LIST_ACTION',
7
7
  IS_FIRST_OPEN_CAMERA: 'IS_FIRST_OPEN_CAMERA',
8
8
  IS_LAVIDA_SOURCE: 'IS_LAVIDA_SOURCE',
9
+ IS_CONNECT_WIFI_GATEWAY: 'IS_CONNECT_WIFI_GATEWAY',
9
10
  };
10
11
 
11
12
  export type AuthData = {
@@ -50,4 +51,5 @@ export type ActionDataMap = {
50
51
  export type AppType = {
51
52
  isFirstOpenCamera: boolean;
52
53
  isLavidaSource: boolean;
54
+ isConnectWifiGateway: boolean;
53
55
  };
@@ -49,6 +49,7 @@ export const mockSCStore = (data: ContextData): ContextData => {
49
49
  listAction: [...mockDataStore.listAction, ...(data?.listAction || [])],
50
50
  app: {
51
51
  isFirstOpenCamera: true,
52
+ isConnectWifiGateway: false,
52
53
  },
53
54
  };
54
55
  };
@@ -40,6 +40,7 @@ export const initialState = {
40
40
  app: {
41
41
  isFirstOpenCamera: true,
42
42
  isLavidaSource: false,
43
+ isConnectWifiGateway: false,
43
44
  },
44
45
  };
45
46
 
@@ -107,6 +108,15 @@ export const reducer = (currentState: ContextData, action: Action) => {
107
108
  },
108
109
  };
109
110
  }
111
+ case Action.IS_CONNECT_WIFI_GATEWAY: {
112
+ return {
113
+ ...currentState,
114
+ app: {
115
+ ...currentState.app,
116
+ isConnectWifiGateway: payload,
117
+ },
118
+ };
119
+ }
110
120
  default:
111
121
  return currentState;
112
122
  }
@@ -2,10 +2,12 @@ import { useIsFocused } from '@react-navigation/native';
2
2
  import { useCallback, useEffect } from 'react';
3
3
  import { BackHandler } from 'react-native';
4
4
 
5
- export const useBlockBackAndroid = () => {
5
+ export const useBlockBackAndroid = (actionBack) => {
6
6
  const focused = useIsFocused();
7
7
  const blockBack = useCallback(() => {
8
+ actionBack && actionBack();
8
9
  return true;
10
+ // eslint-disable-next-line react-hooks/exhaustive-deps
9
11
  }, []);
10
12
  useEffect(() => {
11
13
  if (focused) {
@@ -185,9 +185,9 @@ export const sendDataOverBluetooth = async (
185
185
  return result;
186
186
  }
187
187
 
188
- // eslint-disable-next-line no-shadow
189
- setTimeout(async (device) => {
190
- await device.cancelConnection();
188
+ const timeout = setTimeout(() => {
189
+ device.cancelConnection();
190
+ clearTimeout(timeout);
191
191
  }, responseTime);
192
192
  return result;
193
193
  };
@@ -3,9 +3,11 @@ import React, { memo } from 'react';
3
3
 
4
4
  import AddCommonSelectUnit from '../screens/AddCommon/SelectUnit';
5
5
  import AddCommonSelectSubUnit from '../screens/AddCommon/SelectSubUnit';
6
+ import AddGatewaySelectGateway from '../screens/AddNewGateway/SelectGateway';
6
7
  import AddNewDevice from '../screens/AddNewDevice';
7
8
  import ConnectDevices from '../screens/AddNewDevice/ConnectDevices';
8
9
  import ConnectingDevices from '../screens/AddNewDevice/ConnectingDevices';
10
+ import ConnectingProcess from '../commons/ConnectingProcess';
9
11
  import ScanSensorQR from '../screens/ScanSensorQR';
10
12
  import Route from '../utils/Route';
11
13
  import { screenOptions } from './utils';
@@ -28,6 +30,14 @@ export const AddDeviceStack = memo(() => {
28
30
  name={Route.AddCommonSelectSubUnit}
29
31
  component={AddCommonSelectSubUnit}
30
32
  />
33
+ <Stack.Screen
34
+ name={Route.AddGatewaySelectGateway}
35
+ component={AddGatewaySelectGateway}
36
+ />
37
+ <Stack.Screen
38
+ name={Route.ConnectingProcess}
39
+ component={ConnectingProcess}
40
+ />
31
41
  <Stack.Screen name={Route.AddNewDevice} component={AddNewDevice} />
32
42
  <Stack.Screen name={Route.ScanSensorQR} component={ScanSensorQR} />
33
43
  <Stack.Screen
@@ -0,0 +1,31 @@
1
+ import { createStackNavigator } from '@react-navigation/stack';
2
+ import React, { memo } from 'react';
3
+
4
+ import SelectDeviceType from '../screens/SmartIr/components/SelectDeviceType';
5
+ import SelectBrand from '../screens/SmartIr/components/SelectBrand';
6
+ import GroupButtonByType from '../screens/SmartIr/components/GroupButtonByType/GroupButtonByType';
7
+ import Route from '../utils/Route';
8
+ import { screenOptions } from './utils';
9
+
10
+ const Stack = createStackNavigator();
11
+
12
+ export const SmartIrStack = memo(() => {
13
+ return (
14
+ <Stack.Navigator
15
+ screenOptions={{
16
+ ...screenOptions,
17
+ headerShown: false,
18
+ }}
19
+ >
20
+ <Stack.Screen
21
+ name={Route.SelectDeviceType}
22
+ component={SelectDeviceType}
23
+ />
24
+ <Stack.Screen name={Route.SelectBrand} component={SelectBrand} />
25
+ <Stack.Screen
26
+ name={Route.GroupButtonByType}
27
+ component={GroupButtonByType}
28
+ />
29
+ </Stack.Navigator>
30
+ );
31
+ });
@@ -0,0 +1,51 @@
1
+ import { createStackNavigator } from '@react-navigation/stack';
2
+ import React, { memo } from 'react';
3
+
4
+ import Route from '../utils/Route';
5
+ import { screenOptions } from './utils';
6
+ import SetupGeneratePasscode from '../commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/index';
7
+ import AutoLock from '../commons/ActionGroup/OnOffSmartLock/AutoLock/index';
8
+ import PasscodeList from '../commons/ActionGroup/OnOffSmartLock/PasscodeList/index';
9
+ import ItemPasscode from '../commons/ActionGroup/OnOffSmartLock/PasscodeList/ItemPasscode';
10
+
11
+ const Stack = createStackNavigator();
12
+
13
+ export const SmartLockStack = memo(() => {
14
+ return (
15
+ <Stack.Navigator
16
+ screenOptions={{
17
+ ...screenOptions,
18
+ headerShown: false,
19
+ }}
20
+ >
21
+ <Stack.Screen
22
+ name={Route.SetupGeneratePasscode}
23
+ component={SetupGeneratePasscode}
24
+ options={{
25
+ headerShown: false,
26
+ }}
27
+ />
28
+ <Stack.Screen
29
+ name={Route.AutoLock}
30
+ component={AutoLock}
31
+ options={{
32
+ headerShown: false,
33
+ }}
34
+ />
35
+ <Stack.Screen
36
+ name={Route.PasscodeList}
37
+ component={PasscodeList}
38
+ options={{
39
+ headerShown: false,
40
+ }}
41
+ />
42
+ <Stack.Screen
43
+ name={Route.ItemPasscode}
44
+ component={ItemPasscode}
45
+ options={{
46
+ headerShown: false,
47
+ }}
48
+ />
49
+ </Stack.Navigator>
50
+ );
51
+ });
@@ -117,12 +117,16 @@ export const UnitStack = memo((props) => {
117
117
  component={ChooseLocation}
118
118
  options={{
119
119
  headerShown: true,
120
+ headerTitleStyle: {
121
+ ...styles.headerLocation,
122
+ },
120
123
  headerTitle: () => (
121
- <View style={styles.alignCenter}>
124
+ <View style={styles.headerLocation}>
122
125
  <Text type="H3" color={Colors.Gray9} bold>
123
126
  {t('choose_on_map')}
124
127
  </Text>
125
- <Text type="H4" color={Colors.Gray8}>
128
+
129
+ <Text type="H4" color={Colors.Gray8} style={styles.headerContent}>
126
130
  {t('plan_and_zoom_to_adjust')}
127
131
  </Text>
128
132
  </View>
@@ -323,7 +327,12 @@ const styles = StyleSheet.create({
323
327
  icLeft: {
324
328
  marginLeft: Device.isIOS ? 8 : 0,
325
329
  },
326
- alignCenter: {
330
+ headerLocation: {
327
331
  alignItems: 'center',
332
+ justifyContent: 'center',
333
+ },
334
+ headerContent: {
335
+ textAlign: 'center',
336
+ paddingBottom: 8,
328
337
  },
329
338
  });
@@ -37,6 +37,7 @@ String.prototype.capitalize = function () {
37
37
  return this.charAt(0).toUpperCase() + this.slice(1);
38
38
  };
39
39
 
40
+ let onEndReachedCalledDuringMomentum = false;
40
41
  let dataTemp = [];
41
42
 
42
43
  export default ({ id, type, share, filterEnabled }) => {
@@ -59,7 +60,7 @@ export default ({ id, type, share, filterEnabled }) => {
59
60
  if (page === 1) {
60
61
  setIsRefreshing(true);
61
62
  } else {
62
- if (!isCanLoadMore || isLoading) {
63
+ if (!isCanLoadMore) {
63
64
  return;
64
65
  }
65
66
  setIsLoading(true);
@@ -81,6 +82,7 @@ export default ({ id, type, share, filterEnabled }) => {
81
82
  params.append(key, value);
82
83
  }
83
84
  params.append('page', page);
85
+
84
86
  const { success, data } = await axiosGet(api.url(id), {
85
87
  params: params,
86
88
  });
@@ -91,9 +93,9 @@ export default ({ id, type, share, filterEnabled }) => {
91
93
  setData(api.standardizeData(results));
92
94
  } else {
93
95
  dataTemp = dataTemp.concat(results);
96
+ setIsCanLoadMore(page < Math.ceil(data.count / 20));
94
97
  setData(api.standardizeData(dataTemp));
95
98
  }
96
- setIsCanLoadMore(page < Math.ceil(data.count / 20));
97
99
  }
98
100
  page === 1 ? setIsRefreshing(false) : setIsLoading(false);
99
101
  };
@@ -110,9 +112,20 @@ export default ({ id, type, share, filterEnabled }) => {
110
112
  }
111
113
  };
112
114
 
113
- const onRefresh = () => fetchData({ ...filters, page: 1 });
115
+ const onRefresh = () => {
116
+ setIsCanLoadMore(true);
117
+ fetchData({ ...filters, page: 1 });
118
+ };
119
+
120
+ const onLoadMore = () => {
121
+ if (!onEndReachedCalledDuringMomentum) {
122
+ onEndReachedCalledDuringMomentum = true;
123
+ fetchData({ ...filters, page: page + 1 });
124
+ }
125
+ };
114
126
 
115
- const onLoadMore = () => fetchData({ ...filters, page: page + 1 });
127
+ const onMomentumScrollBegin = () =>
128
+ (onEndReachedCalledDuringMomentum = false);
116
129
 
117
130
  return {
118
131
  data,
@@ -124,5 +137,6 @@ export default ({ id, type, share, filterEnabled }) => {
124
137
  fetchMembers,
125
138
  filters,
126
139
  setFilters,
140
+ onMomentumScrollBegin,
127
141
  };
128
142
  };
@@ -34,7 +34,9 @@ const ActivityLogScreen = ({ route }) => {
34
34
  fetchMembers,
35
35
  filters,
36
36
  setFilters,
37
+ onMomentumScrollBegin,
37
38
  } = useActivityLog({ id, type, share, filterEnabled });
39
+
38
40
  const [showFilterPopup, setShowFilterPopup, setHideFilterPopup] =
39
41
  useBoolean();
40
42
 
@@ -113,6 +115,7 @@ const ActivityLogScreen = ({ route }) => {
113
115
  removeClippedSubviews={true}
114
116
  maxToRenderPerBatch={20}
115
117
  contentContainerStyle={styles.contentContainerStyle}
118
+ onMomentumScrollBegin={onMomentumScrollBegin}
116
119
  />
117
120
  </View>
118
121
  {(filterEnabled.user || filterEnabled.date) && (