@eohjsc/react-native-smart-city 0.3.21 → 0.3.24

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 (104) hide show
  1. package/index.js +2 -0
  2. package/package.json +2 -1
  3. package/src/Images/Common/buttonLeftCurtain.png +0 -0
  4. package/src/Images/Common/buttonLeftCurtain@2x.png +0 -0
  5. package/src/Images/Common/buttonLeftCurtain@3x.png +0 -0
  6. package/src/commons/Action/ItemQuickAction.js +1 -12
  7. package/src/commons/Action/__test__/ItemQuickAction.test.js +1 -1
  8. package/src/commons/ActionGroup/ColorPickerTemplate.js +2 -9
  9. package/src/commons/ActionGroup/CurtainButtonTemplate.js +14 -21
  10. package/src/commons/ActionGroup/CurtainButtonTemplateStyle.js +5 -0
  11. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +12 -24
  12. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +10 -17
  13. package/src/commons/ActionGroup/OnOffTemplate/index.js +10 -35
  14. package/src/commons/ActionGroup/OneBigButtonTemplate.js +2 -3
  15. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +7 -8
  16. package/src/commons/ActionGroup/SliderRangeTemplate.js +3 -10
  17. package/src/commons/ActionGroup/StatesGridActionTemplate.js +9 -24
  18. package/src/commons/ActionGroup/ThreeButtonTemplate.js +6 -9
  19. package/src/commons/ActionGroup/TimerActionTemplate.js +11 -4
  20. package/src/commons/ActionGroup/TwoButtonTemplate/index.js +18 -33
  21. package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +3 -15
  22. package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +38 -4
  23. package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +7 -0
  24. package/src/commons/ActionGroup/__test__/OnOffSmartLock.test.js +17 -12
  25. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +11 -16
  26. package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +1 -1
  27. package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +11 -10
  28. package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +8 -7
  29. package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +8 -1
  30. package/src/commons/ActionGroup/__test__/TimerActionTemplateWithutConfigValue.test.js +7 -0
  31. package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +17 -2
  32. package/src/commons/ActionGroup/__test__/index.test.js +15 -18
  33. package/src/commons/ConnectingProcess/index.js +6 -25
  34. package/src/commons/Device/HistoryChart.js +8 -6
  35. package/src/commons/Device/ItemDevice.js +79 -35
  36. package/src/commons/MediaPlayerDetail/index.js +5 -0
  37. package/src/commons/RowItem/index.js +6 -2
  38. package/src/commons/SubUnit/Favorites/index.js +24 -6
  39. package/src/commons/SubUnit/ShortDetail.js +31 -5
  40. package/src/commons/SubUnit/__test__/Favorites.test.js +1 -0
  41. package/src/commons/SubUnit/__test__/ShortDetail.test.js +1 -0
  42. package/src/configs/API.js +9 -4
  43. package/src/configs/Constants.js +8 -2
  44. package/src/configs/SCConfig.js +4 -0
  45. package/src/context/actionType.ts +7 -5
  46. package/src/context/mockStore.ts +10 -3
  47. package/src/context/reducer.ts +29 -15
  48. package/src/hoc/index.js +3 -0
  49. package/src/hoc/withRemoteControl.js +10 -0
  50. package/src/hooks/Common/index.js +2 -2
  51. package/src/hooks/Common/useDevicesStatus.js +57 -0
  52. package/src/hooks/Common/useGGHomeDeviceConnected.js +3 -3
  53. package/src/hooks/IoT/__test__/useGGHomeConnection.test.js +1 -2
  54. package/src/hooks/IoT/__test__/useRemoteControl.test.js +9 -11
  55. package/src/hooks/IoT/index.js +9 -1
  56. package/src/hooks/IoT/useGGHomeConnection.js +0 -1
  57. package/src/hooks/IoT/useRemoteControl.js +2 -3
  58. package/src/hooks/IoT/useUnwatchLGDeviceConfigControl.js +29 -0
  59. package/src/hooks/IoT/useValueEvaluation.js +17 -4
  60. package/src/hooks/IoT/useWatchConfigs.js +34 -0
  61. package/src/iot/Monitor.js +13 -20
  62. package/src/iot/RemoteControl/GoogleHome.js +12 -13
  63. package/src/iot/RemoteControl/Internet.js +1 -8
  64. package/src/iot/RemoteControl/LG.js +1 -0
  65. package/src/iot/RemoteControl/__test__/GoogleHome.test.js +7 -2
  66. package/src/navigations/UnitStack.js +27 -3
  67. package/src/screens/AddNewAction/SelectAction.js +1 -1
  68. package/src/screens/AddNewAction/SetupSensor.js +4 -0
  69. package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +44 -78
  70. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +15 -35
  71. package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +2 -0
  72. package/src/screens/AllCamera/__test__/index.test.js +1 -1
  73. package/src/screens/Device/__test__/detail.test.js +1 -54
  74. package/src/screens/Device/components/SensorConnectStatusViewHeader.js +18 -8
  75. package/src/screens/Device/components/SensorDisplayItem.js +2 -2
  76. package/src/screens/Device/detail.js +36 -30
  77. package/src/screens/Device/hooks/__test__/useEvaluateValue.test.js +102 -0
  78. package/src/screens/Device/hooks/useDeviceWatchConfigControl.js +20 -0
  79. package/src/screens/Device/utils/index.js +45 -0
  80. package/src/screens/Device/utils/index.test.js +111 -0
  81. package/src/screens/EmergencyContacts/EmergencyContactsAddNew.js +35 -22
  82. package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +2 -1
  83. package/src/screens/EmergencyContacts/__test__/EmergencyContactAddNew.test.js +36 -2
  84. package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +0 -2
  85. package/src/screens/Notification/__test__/NotificationItem.test.js +84 -19
  86. package/src/screens/Notification/components/NotificationItem.js +64 -31
  87. package/src/screens/PlayBackCamera/index.js +22 -6
  88. package/src/screens/ScriptDetail/hooks/useStarredScript.js +2 -2
  89. package/src/screens/SubUnit/AddSubUnit.js +2 -1
  90. package/src/screens/Unit/AddMenu.js +4 -0
  91. package/src/screens/Unit/{SelectFavoritesDevices.js → SelectAddToFavorites.js} +81 -26
  92. package/src/screens/Unit/{SelectFavoritesDevicesStyles.js → SelectAddToFavoritesStyles.js} +0 -0
  93. package/src/screens/Unit/__test__/CheckSendEmail.test.js +12 -0
  94. package/src/screens/Unit/__test__/Detail.test.js +2 -3
  95. package/src/screens/Unit/__test__/SelectAddToFavorites.test.js +267 -0
  96. package/src/screens/Unit/components/AutomateScript/index.js +65 -0
  97. package/src/screens/Unit/components/AutomateScript/styles.js +48 -0
  98. package/src/screens/Unit/components/MyUnitDevice/index.js +4 -2
  99. package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +4 -2
  100. package/src/utils/I18n/translations/en.json +7 -2
  101. package/src/utils/I18n/translations/vi.json +6 -1
  102. package/src/utils/Route/index.js +1 -1
  103. package/src/hooks/Common/useSensorsStatus.js +0 -62
  104. package/src/screens/Unit/__test__/SelectFavoritesDevices.test.js +0 -110
@@ -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 SelectFavoritesDevices from '../screens/Unit/SelectFavoritesDevices';
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,28 @@ 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
+
123
+ useEffect(() => {
124
+ return () => {
125
+ const id = unitId || unitData?.id;
126
+ if (!id) {
127
+ return;
128
+ }
129
+ setAction(Action.NEED_UPDATE_VALUE_EVALUATIONS, id);
130
+ };
131
+ // eslint-disable-next-line react-hooks/exhaustive-deps
132
+ }, []);
133
+
110
134
  return (
111
135
  <Stack.Navigator
112
136
  screenOptions={{
@@ -402,8 +426,8 @@ export const UnitStack = memo((props) => {
402
426
  }}
403
427
  />
404
428
  <Stack.Screen
405
- name={Route.SelectFavoritesDevices}
406
- component={SelectFavoritesDevices}
429
+ name={Route.SelectAddToFavorites}
430
+ component={SelectAddToFavorites}
407
431
  options={{
408
432
  headerShown: false,
409
433
  }}
@@ -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 || item?.value === 0;
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);
@@ -28,14 +28,9 @@ import { Action } from '../../../context/actionType';
28
28
  import { TESTID } from '../../../configs/Constants';
29
29
  import Connecting from '../../../commons/Connecting';
30
30
 
31
- const isIos = Platform.OS === 'ios';
32
31
  const isAndroid = Platform.OS === 'android';
33
-
34
- let socket = null;
35
- if (isIos) {
36
- socket = dgram.createSocket({ type: 'udp4' });
37
- socket.bind(54321);
38
- }
32
+ let socket,
33
+ intervalSend = null;
39
34
 
40
35
  const ConnectWifiWarning = memo(({ route }) => {
41
36
  const {
@@ -83,77 +78,44 @@ const ConnectWifiWarning = memo(({ route }) => {
83
78
  }, [getPermissionWifiAndroid]);
84
79
 
85
80
  const handleSend = async () => {
86
- let intervalSend = null;
87
- if (isIos) {
88
- await setIsPercentConnect(1);
89
- await socket.on('message', (msg, rinfo) => {
90
- clearInterval(intervalSend);
91
- const data = JSON.parse(msg.toString());
92
- if (Object.prototype.hasOwnProperty.call(data, 'wifi')) {
93
- navigate(Routes.GatewayWifiList, {
94
- list_wifi: data.wifi,
95
- unit_id: unit_id,
96
- chip_id: chip_id,
97
- scan_sensor_data: { ...body },
98
- wifi_ssid: wifi_ssid,
99
- wifi_pass: wifi_pass,
100
- unit_name: unit_name,
101
- devicePrefixName: devicePrefixName,
102
- socket: socket,
103
- });
104
- }
105
- });
106
- intervalSend = setInterval(() => {
107
- socket.send(
108
- JSON.stringify({ type: 'scan', data: { wifi: '' } }),
109
- undefined,
110
- undefined,
111
- 54321,
112
- '192.168.27.1',
113
- undefined
114
- );
115
- }, 1000);
116
- socket.on('error', () => {
117
- ToastBottomHelper.error(t('server_error'));
118
- setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
119
- goBack();
120
- });
121
- } else {
122
- const dgSocket = dgram.createSocket({ type: 'udp4' });
123
- await setIsPercentConnect(1);
124
- await dgSocket.bind(54321);
125
- await dgSocket.on('message', (msg, rinfo) => {
126
- const data = JSON.parse(msg.toString());
127
- if (Object.prototype.hasOwnProperty.call(data, 'wifi')) {
128
- navigate(Routes.GatewayWifiList, {
129
- list_wifi: data.wifi,
130
- unit_id: unit_id,
131
- chip_id: chip_id,
132
- scan_sensor_data: { ...body },
133
- wifi_ssid: wifi_ssid,
134
- wifi_pass: wifi_pass,
135
- unit_name: unit_name,
136
- devicePrefixName: devicePrefixName,
137
- socket: dgSocket,
138
- });
139
- }
140
- });
141
- await dgSocket.once('listening', async () => {
142
- await dgSocket.send(
143
- JSON.stringify({ type: 'scan', data: { wifi: '' } }),
144
- undefined,
145
- undefined,
146
- 54321,
147
- '192.168.27.1',
148
- undefined
149
- );
150
- });
151
- dgSocket.on('error', () => {
152
- ToastBottomHelper.error(t('server_error'));
153
- setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
154
- goBack();
155
- });
156
- }
81
+ socket = dgram.createSocket({ type: 'udp4' });
82
+ socket.bind(54321);
83
+ setIsPercentConnect(1);
84
+
85
+ socket.on('message', (msg, rinfo) => {
86
+ clearInterval(intervalSend);
87
+ const data = JSON.parse(msg.toString());
88
+ if (Object.prototype.hasOwnProperty.call(data, 'wifi')) {
89
+ navigate(Routes.GatewayWifiList, {
90
+ list_wifi: data.wifi,
91
+ unit_id: unit_id,
92
+ chip_id: chip_id,
93
+ scan_sensor_data: { ...body },
94
+ wifi_ssid: wifi_ssid,
95
+ wifi_pass: wifi_pass,
96
+ unit_name: unit_name,
97
+ devicePrefixName: devicePrefixName,
98
+ socket: socket,
99
+ });
100
+ }
101
+ });
102
+
103
+ socket.on('error', () => {
104
+ ToastBottomHelper.error(t('server_error'));
105
+ setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
106
+ goBack();
107
+ });
108
+
109
+ intervalSend = setInterval(() => {
110
+ socket.send(
111
+ JSON.stringify({ type: 'scan', data: { wifi: '' } }),
112
+ undefined,
113
+ undefined,
114
+ 54321,
115
+ '192.168.27.1',
116
+ undefined
117
+ );
118
+ }, 5000); // workaround, todo Bang continue research
157
119
  };
158
120
 
159
121
  const handleConnectWifiGateway = async () => {
@@ -171,6 +133,10 @@ const ConnectWifiWarning = memo(({ route }) => {
171
133
  );
172
134
  };
173
135
 
136
+ useEffect(() => {
137
+ return () => intervalSend && clearInterval(intervalSend);
138
+ }, []);
139
+
174
140
  return (
175
141
  <View style={styles.screen}>
176
142
  {!isLoading ? (
@@ -11,7 +11,6 @@ import {
11
11
  TouchableOpacity,
12
12
  ScrollView,
13
13
  ActivityIndicator,
14
- Platform,
15
14
  } from 'react-native';
16
15
  import { HeaderCustom } from '../../../commons/Header';
17
16
  import { Colors } from '../../../configs';
@@ -128,11 +127,8 @@ const GatewayWifiList = memo(({ route }) => {
128
127
 
129
128
  const sendConnect = useCallback(
130
129
  (i) => {
131
- setTimeout(async () => {
130
+ const timeoutSendConnect = setTimeout(async () => {
132
131
  i++;
133
- await socket.on('message', (msg, rinfo) => {
134
- handleSocketOnMsg(msg);
135
- });
136
132
  socket.send(
137
133
  JSON.stringify({
138
134
  type: 'connect',
@@ -146,48 +142,32 @@ const GatewayWifiList = memo(({ route }) => {
146
142
  );
147
143
  if (i < 3) {
148
144
  sendConnect(i);
145
+ clearTimeout(timeoutSendConnect);
149
146
  }
150
147
  }, 1000);
151
148
  },
152
- [handleSocketOnMsg, password, selectedWifi, socket]
149
+ [password, selectedWifi, socket]
153
150
  );
154
151
 
155
152
  const connectWifi = useCallback(async () => {
156
153
  if (!isConnectWifiGateway) {
157
- if (Platform.OS === 'ios') {
158
- sendConnect(0);
159
- setAction(Action.IS_CONNECT_WIFI_GATEWAY, true);
160
- setIsSendWifi(true);
161
- } else {
162
- socket.on('message', (msg, rinfo) => {
163
- handleSocketOnMsg(msg);
164
- });
165
- socket.send(
166
- JSON.stringify({
167
- type: 'connect',
168
- data: { wifi: { ssid: selectedWifi, pass: password } },
169
- }),
170
- undefined,
171
- undefined,
172
- 54321,
173
- '192.168.27.1',
174
- undefined
175
- );
176
- socket.on('error', () => {
177
- ToastBottomHelper.error(t('server_error'));
178
- setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
179
- goBack();
180
- });
181
- setAction(Action.IS_CONNECT_WIFI_GATEWAY, true);
182
- setIsSendWifi(true);
183
- }
154
+ socket.on('message', (msg, rinfo) => {
155
+ handleSocketOnMsg(msg);
156
+ });
157
+ socket.on('error', () => {
158
+ ToastBottomHelper.error(t('server_error'));
159
+ setAction(Action.IS_CONNECT_WIFI_GATEWAY, false);
160
+ goBack();
161
+ });
162
+
163
+ sendConnect(0);
164
+ setAction(Action.IS_CONNECT_WIFI_GATEWAY, true);
165
+ setIsSendWifi(true);
184
166
  }
185
167
  }, [
186
168
  goBack,
187
169
  handleSocketOnMsg,
188
170
  isConnectWifiGateway,
189
- password,
190
- selectedWifi,
191
171
  sendConnect,
192
172
  setAction,
193
173
  socket,
@@ -97,6 +97,8 @@ describe('Test GatewayWifiList', () => {
97
97
  await ButtonPopup.props.onPressMain();
98
98
  });
99
99
  expect(socket.on).toBeCalled();
100
+ expect(socket.on.mock.calls[0][0]).toEqual('message');
101
+ jest.runOnlyPendingTimers();
100
102
  expect(socket.send).toBeCalled();
101
103
 
102
104
  const mockWifiThen = jest.fn();
@@ -90,7 +90,7 @@ describe('Test AllCamera screen', () => {
90
90
  });
91
91
  const instance = tree.root;
92
92
  const TouchableOpacities = instance.findAllByType(TouchableOpacity);
93
- expect(TouchableOpacities).toHaveLength(11);
93
+ expect(TouchableOpacities).toHaveLength(9);
94
94
  const ModalFullVideos = instance.findAllByType(ModalFullVideo);
95
95
  expect(ModalFullVideos).toHaveLength(1);
96
96
  act(() => {
@@ -12,7 +12,6 @@ import { TESTID } from '../../../configs/Constants';
12
12
  import Text from '../../../commons/Text';
13
13
  import { IconFill } from '@ant-design/icons-react-native';
14
14
  import CurrentRainSensor from '../../../commons/Device/RainningSensor/CurrentRainSensor';
15
- import { ConnectedViewHeader } from '../../../commons/Device';
16
15
  import { getTranslate } from '../../../utils/I18n';
17
16
  import { SCProvider } from '../../../context';
18
17
  import { mockSCStore } from '../../../context/mockStore';
@@ -30,6 +29,7 @@ jest.mock('@react-navigation/native', () => {
30
29
  useNavigation: () => ({
31
30
  navigate: mockedNavigate,
32
31
  }),
32
+ useFocusEffect: jest.fn(),
33
33
  };
34
34
  });
35
35
 
@@ -609,59 +609,6 @@ describe('test DeviceDetail', () => {
609
609
  expect(sensorDisplayItem).toHaveLength(0);
610
610
  });
611
611
 
612
- test('render CurrentRainSensor but is other device', async () => {
613
- route.params.sensorData.is_other_device = true;
614
- route.params.isGGHomeConnected = true;
615
-
616
- const responseDisplay = {
617
- status: 200,
618
- data: {
619
- items: [
620
- {
621
- id: 170,
622
- order: 1,
623
- template: 'value',
624
- type: 'value',
625
- configuration: {
626
- type: 'circle',
627
- configs: [
628
- {
629
- id: 428,
630
- color: 'red',
631
- standard: 'Temperature',
632
- measure: '°C',
633
- },
634
- ],
635
- },
636
- },
637
- ],
638
- },
639
- };
640
-
641
- const responseDisplayValueV2 = {
642
- status: 200,
643
- data: {
644
- configs: [{ id: 428 }],
645
- is_connected: true,
646
- last_updated: '2021-01-24T12:00:00.000Z',
647
- },
648
- };
649
-
650
- mockAxios(responseDisplay, responseDisplayValueV2);
651
-
652
- await act(async () => {
653
- tree = await create(wrapComponent(store, account, route));
654
- });
655
-
656
- const instance = tree.root;
657
- const sensorDisplayItem = instance.findAll(
658
- (el) => el.props.testID === TESTID.SENSOR_DISPLAY_ITEM
659
- );
660
- expect(sensorDisplayItem).toHaveLength(1);
661
- const connectedViewHeader = instance.findByType(ConnectedViewHeader);
662
- expect(connectedViewHeader.props.type).toEqual('GoogleHome');
663
- });
664
-
665
612
  test('HeaderDevice button more onClick', async () => {
666
613
  await act(async () => {
667
614
  tree = await create(wrapComponent(store, account, route));
@@ -14,18 +14,25 @@ export const SensorConnectStatusViewHeader = ({
14
14
  showWindDirection,
15
15
  children,
16
16
  }) => {
17
- const isConnecting =
18
- !!sensor &&
19
- sensor?.is_other_device &&
20
- sensor?.device_type !== DEVICE_TYPE.LG_THINQ
21
- ? isGGHomeConnecting
22
- : false;
17
+ const isConnecting = (() => {
18
+ if (!!sensor && sensor?.is_managed_by_backend) {
19
+ return false;
20
+ } else {
21
+ if (sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
22
+ return false;
23
+ } else if (sensor?.device_type === DEVICE_TYPE.GOOGLE_HOME) {
24
+ return isGGHomeConnecting;
25
+ } else {
26
+ return false;
27
+ }
28
+ }
29
+ })();
23
30
 
24
31
  if (isConnecting) {
25
32
  return <></>;
26
33
  }
27
34
 
28
- if (!!sensor && !sensor?.is_other_device) {
35
+ if (!!sensor && sensor?.is_managed_by_backend) {
29
36
  if (connectedViaNetwork) {
30
37
  return (
31
38
  <>
@@ -55,6 +62,7 @@ export const SensorConnectStatusViewHeader = ({
55
62
  );
56
63
  }
57
64
  } else {
65
+ // not managed by backend
58
66
  if (sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
59
67
  return (
60
68
  <>
@@ -62,7 +70,7 @@ export const SensorConnectStatusViewHeader = ({
62
70
  {children}
63
71
  </>
64
72
  );
65
- } else {
73
+ } else if (sensor?.device_type === DEVICE_TYPE.GOOGLE_HOME) {
66
74
  if (connectedViaGGHome) {
67
75
  return (
68
76
  <>
@@ -83,6 +91,8 @@ export const SensorConnectStatusViewHeader = ({
83
91
  />
84
92
  );
85
93
  }
94
+ } else {
95
+ return <DisconnectedView sensor={sensor} />;
86
96
  }
87
97
  }
88
98
  };
@@ -44,8 +44,8 @@ export const SensorDisplayItem = ({
44
44
  const sendRemoteCommand = useRemoteControl();
45
45
 
46
46
  const doAction = useCallback(
47
- (action, data, actionName) => {
48
- sendRemoteCommand(sensor, action, data, userId, actionName);
47
+ (action, data) => {
48
+ sendRemoteCommand(sensor, action, data, userId);
49
49
  },
50
50
  [sensor, userId, sendRemoteCommand]
51
51
  );
@@ -33,7 +33,7 @@ import { useFavoriteDevice } from './hooks/useFavoriteDevice';
33
33
  import BottomButtonView from '../../commons/BottomButtonView';
34
34
  import Text from '../../commons/Text';
35
35
  import { AlertAction, ButtonPopup, MenuActionMore } from '../../commons';
36
- import { TESTID } from '../../configs/Constants';
36
+ import { DEVICE_TYPE, TESTID } from '../../configs/Constants';
37
37
 
38
38
  import { usePopover } from '../../hooks/Common';
39
39
  import { useConfigGlobalState } from '../../iot/states';
@@ -51,6 +51,7 @@ import { EmergencyCountdown } from './components/EmergencyCountdown';
51
51
  import { SensorConnectStatusViewHeader } from './components/SensorConnectStatusViewHeader';
52
52
  import { useDisconnectedDevice } from './hooks/useDisconnectedDevice';
53
53
  import { useEvaluateValue } from './hooks/useEvaluateValue';
54
+ import { useDeviceWatchConfigControl } from './hooks/useDeviceWatchConfigControl';
54
55
  import { Card } from '../../commons/CardShadow';
55
56
  import PreventAccess from '../../commons/PreventAccess';
56
57
  import { notImplemented } from '../../utils/Utils';
@@ -122,6 +123,8 @@ const DeviceDetail = ({ route }) => {
122
123
 
123
124
  useDisconnectedDevice(sensorName, isDeviceHasBle, serverDown);
124
125
 
126
+ useDeviceWatchConfigControl(sensor, display);
127
+
125
128
  const isShowSetupEmergencyContact = useMemo(
126
129
  () =>
127
130
  display.items.filter(
@@ -148,7 +151,7 @@ const DeviceDetail = ({ route }) => {
148
151
  );
149
152
 
150
153
  const canManageSubUnit = useMemo(() => {
151
- return currentUserId === unit?.user_id;
154
+ return Number(currentUserId) === Number(unit?.user_id);
152
155
  }, [currentUserId, unit]);
153
156
 
154
157
  const fetchUnitDetail = useCallback(async () => {
@@ -360,13 +363,6 @@ const DeviceDetail = ({ route }) => {
360
363
  text: t('auto_lock'),
361
364
  });
362
365
  }
363
- menuItems.push({
364
- route: Routes.SmartLockStack,
365
- data: {
366
- screen: Routes.SetupGeneratePasscode,
367
- },
368
- text: t('setup_generate_passcode'),
369
- });
370
366
  if (isOwner && isShowSetUpSmartLock) {
371
367
  menuItems.push({
372
368
  route: Routes.SmartLockStack,
@@ -448,20 +444,24 @@ const DeviceDetail = ({ route }) => {
448
444
  if (!item.configuration) {
449
445
  return;
450
446
  }
447
+
451
448
  const data = item.configuration.configs.map((config) => {
452
- const configValue = configValues[config.id];
449
+ const configValue = configValues[config.id]?.value;
453
450
  const displayValue = displayValues.find((k) => k.id === config.id);
454
- if (!configValue && !displayValue) {
451
+ if (
452
+ (configValue === null || configValue === undefined) &&
453
+ !displayValue
454
+ ) {
455
455
  return;
456
456
  }
457
- const value = configValue
458
- ? {
459
- id: config.id,
460
- value: configValue,
461
- evaluate: evaluateValue(config.id, configValue),
462
- }
463
- : displayValue;
464
-
457
+ const value =
458
+ configValue !== null && configValue !== undefined
459
+ ? {
460
+ id: config.id,
461
+ value: configValue,
462
+ evaluate: evaluateValue(config.id, configValue),
463
+ }
464
+ : displayValue;
465
465
  return { ...config, ...value };
466
466
  });
467
467
  return data.filter((value) => value);
@@ -513,7 +513,10 @@ const DeviceDetail = ({ route }) => {
513
513
  }
514
514
  setLoading((preState) => ({ ...preState, isConnected: false }));
515
515
  };
516
- if (sensor?.is_managed_by_backend && !sensor?.is_other_device) {
516
+ if (
517
+ sensor?.is_managed_by_backend &&
518
+ sensor?.device_type !== DEVICE_TYPE.LG_THINQ
519
+ ) {
517
520
  const updateInterval = setInterval(() => fetchValues(), 5000);
518
521
  fetchValues();
519
522
  return () => clearInterval(updateInterval);
@@ -721,16 +724,19 @@ const DeviceDetail = ({ route }) => {
721
724
  isNetworkConnected !== null &&
722
725
  renderSensorConnected()}
723
726
  </View>
724
- {isShowSetupEmergencyContact && canManageSubUnit && (
725
- <BottomButtonView
726
- style={styles.bottomButtonEmergencyContact}
727
- mainIcon={<Icon name="plus" size={16} color={Colors.Primary} />}
728
- mainTitle={t('setup_my_emergency_contact')}
729
- onPressMain={onSetupContacts}
730
- typeMain="primaryBorder"
731
- semiboldMain={false}
732
- />
733
- )}
727
+ {isNetworkConnected &&
728
+ isConnected &&
729
+ isShowSetupEmergencyContact &&
730
+ canManageSubUnit && (
731
+ <BottomButtonView
732
+ style={styles.bottomButtonEmergencyContact}
733
+ mainIcon={<Icon name="plus" size={16} color={Colors.Primary} />}
734
+ mainTitle={t('setup_my_emergency_contact')}
735
+ onPressMain={onSetupContacts}
736
+ typeMain="primaryBorder"
737
+ semiboldMain={false}
738
+ />
739
+ )}
734
740
  <AlertSendConfirm
735
741
  showAlertConfirm={showAlertConfirm && !lockShowing}
736
742
  countDown={countDown}