@eohjsc/react-native-smart-city 0.7.21 → 0.7.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.
Files changed (101) hide show
  1. package/package.json +1 -1
  2. package/src/Images/Common/default_end_device.png +0 -0
  3. package/src/commons/ActionGroup/TerminalBoxTemplate.js +3 -0
  4. package/src/commons/ActionTemplate/OnOffButtonAction.js +38 -4
  5. package/src/commons/ActionTemplate/OnOffSimpleAction.js +55 -15
  6. package/src/commons/ActionTemplate/OnOffSmartLockAction.js +46 -8
  7. package/src/commons/ActionTemplate/SwitchButtonAction.js +35 -4
  8. package/src/commons/ActionTemplate/ThreeButtonAction.js +13 -3
  9. package/src/commons/ActionTemplate/__test__/OnOffButtonAction.test.js +46 -7
  10. package/src/commons/ActionTemplate/__test__/OnOffSimpleAction.test.js +66 -6
  11. package/src/commons/ActionTemplate/__test__/OnOffSmartLockAction.test.js +53 -13
  12. package/src/commons/ActionTemplate/__test__/SwitchButtonAction.test.js +46 -7
  13. package/src/commons/ActionTemplate/__test__/index.test.js +6 -2
  14. package/src/commons/ActionTemplate/index.js +65 -10
  15. package/src/commons/Dashboard/MyUnit/index.js +19 -20
  16. package/src/commons/DevMode/Search.js +1 -1
  17. package/src/commons/Device/RainningSensor/CurrentRainSensor.js +5 -5
  18. package/src/commons/MediaPlayerDetail/MediaPlayerFull.js +26 -32
  19. package/src/commons/OneTapTemplate/StatesGridActionTemplate.js +8 -6
  20. package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +6 -0
  21. package/src/commons/SubUnit/OneTap/index.js +5 -0
  22. package/src/commons/UnitSummary/ConfigHistoryChart/index.js +9 -11
  23. package/src/commons/Widgets/IFrameWithConfig/IFrameWithConfig.js +2 -2
  24. package/src/commons/Widgets/IFrameWithConfig/__tests__/IFrameWithConfig.test.js +1 -1
  25. package/src/configs/API.js +10 -0
  26. package/src/configs/AccessibilityLabel.js +5 -1
  27. package/src/configs/Images.js +1 -0
  28. package/src/navigations/AddMemberStack.js +3 -3
  29. package/src/screens/ActivityLog/__test__/index.test.js +10 -0
  30. package/src/screens/ActivityLog/hooks/index.js +1 -1
  31. package/src/screens/AddCommon/SelectUnit.js +3 -2
  32. package/src/screens/AddLocationMaps/__test__/index.test.js +13 -13
  33. package/src/screens/Automate/AddNewAction/ChooseAction.js +15 -51
  34. package/src/screens/Automate/AddNewAction/SelectControlDevices.js +13 -3
  35. package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +74 -54
  36. package/src/screens/Automate/AddNewAction/__test__/ChooseAction.test.js +114 -4
  37. package/src/screens/Automate/AddNewAction/__test__/ChooseConfig.test.js +9 -11
  38. package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +37 -8
  39. package/src/screens/Automate/AddNewAutoSmart/AddTypeSmart.js +5 -0
  40. package/src/screens/Automate/AddNewAutoSmart/__test__/AddAutomationTypeSmart.test.js +31 -0
  41. package/src/screens/Automate/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +18 -2
  42. package/src/screens/Automate/Components/InputName.js +7 -6
  43. package/src/screens/Automate/Constants.js +12 -0
  44. package/src/screens/Automate/EditActionsList/UpdateActionScript.js +24 -55
  45. package/src/screens/Automate/EditActionsList/__tests__/UpdateActionScript.test.js +298 -41
  46. package/src/screens/Automate/EditActionsList/__tests__/index.test.js +2 -2
  47. package/src/screens/Automate/EditActionsList/index.js +26 -14
  48. package/src/screens/Automate/MultiUnits.js +9 -1
  49. package/src/screens/Automate/OneTap/__test__/AddNewOneTap.test.js +3 -3
  50. package/src/screens/Automate/ScriptDetail/Components/AddActionScript.js +4 -10
  51. package/src/screens/Automate/ScriptDetail/Components/DeleteScript.js +2 -4
  52. package/src/screens/Automate/ScriptDetail/__test__/index.test.js +78 -0
  53. package/src/screens/Automate/ScriptDetail/index.js +16 -10
  54. package/src/screens/Automate/ScriptDetail/utils.js +39 -35
  55. package/src/screens/Automate/SetSchedule/AddEditConditionSchedule.js +27 -160
  56. package/src/screens/Automate/SetSchedule/EditSchedule.js +269 -0
  57. package/src/screens/Automate/SetSchedule/__test__/AddEditConditionSchedule.test.js +327 -22
  58. package/src/screens/Automate/SetSchedule/__test__/index.test.js +35 -22
  59. package/src/screens/Automate/SetSchedule/components/RepeatOptionsPopup.js +2 -8
  60. package/src/screens/Automate/SetSchedule/index.js +15 -129
  61. package/src/screens/Automate/SetSchedule/styles/indexStyles.js +9 -0
  62. package/src/screens/Automate/__test__/MultiUnits.test.js +6 -1
  63. package/src/screens/Automate/hooks/useAction.js +222 -0
  64. package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +69 -13
  65. package/src/screens/ConfirmUnitDeletion/index.js +14 -14
  66. package/src/screens/Device/__test__/detail.test.js +48 -1
  67. package/src/screens/Device/detail.js +46 -3
  68. package/src/screens/PlayBackCamera/__test__/index.test.js +48 -13
  69. package/src/screens/PlayBackCamera/index.js +1 -1
  70. package/src/screens/Sharing/Components/ConfigItem.js +34 -0
  71. package/src/screens/Sharing/Components/DeviceItem.js +77 -0
  72. package/src/screens/Sharing/Components/ItemChangeRole.js +3 -4
  73. package/src/screens/Sharing/Components/ShareDeviceSelector.js +255 -0
  74. package/src/screens/Sharing/Components/Styles/CheckBoxCustomStyles.js +1 -1
  75. package/src/screens/Sharing/Components/Styles/DeviceItemStyles.js +11 -27
  76. package/src/screens/Sharing/{Styles/SelectPermissionStyles.js → Components/Styles/ShareDeviceSelectorStyles.js} +3 -11
  77. package/src/screens/Sharing/Components/SubUnitItem.js +28 -0
  78. package/src/screens/Sharing/Components/SubUnitTreeView.js +68 -0
  79. package/src/screens/Sharing/Components/TitleCheckBox.js +23 -41
  80. package/src/screens/Sharing/Components/__test__/ItemChangeRole.test.js +7 -7
  81. package/src/screens/Sharing/Components/__test__/ShareDeviceSelector.test.js +298 -0
  82. package/src/screens/Sharing/Components/index.js +14 -1
  83. package/src/screens/Sharing/InfoMemberUnit.js +20 -20
  84. package/src/screens/Sharing/SelectShareDevice.js +11 -255
  85. package/src/screens/Sharing/SelectUser.js +12 -12
  86. package/src/screens/Sharing/UpdateShareDevice.js +45 -301
  87. package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +58 -11
  88. package/src/screens/Sharing/__test__/SelectShareDevice.test.js +51 -160
  89. package/src/screens/Sharing/__test__/SelectUser.test.js +72 -10
  90. package/src/screens/Sharing/__test__/UpdateShareDevice.test.js +49 -209
  91. package/src/utils/Apis/axios.js +6 -0
  92. package/src/utils/I18n/translations/en.js +9 -1
  93. package/src/utils/I18n/translations/vi.js +10 -2
  94. package/src/commons/Sharing/StationDevicePermissions.js +0 -204
  95. package/src/screens/Automate/constants.js +0 -0
  96. package/src/screens/Sharing/Components/CheckBoxConfig.js +0 -44
  97. package/src/screens/Sharing/Components/CheckBoxSubUnit.js +0 -35
  98. package/src/screens/Sharing/Components/EndDevice.js +0 -93
  99. package/src/screens/Sharing/Components/Styles/CheckBoxConfigStyles.js +0 -18
  100. package/src/screens/Sharing/Components/Styles/TitleCheckBoxStyles.js +0 -21
  101. package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +0 -31
@@ -2,13 +2,21 @@ import React from 'react';
2
2
  import renderer, { act } from 'react-test-renderer';
3
3
  import { TouchableOpacity } from 'react-native';
4
4
 
5
+ import Text from '../../Text';
6
+ import AccessibilityLabel from '../../../configs/AccessibilityLabel';
5
7
  import OnOffSmartLockAction from '../OnOffSmartLockAction';
6
8
  import { SCProvider } from '../../../context';
7
9
  import { mockSCStore } from '../../../context/mockStore';
8
10
 
9
- const wrapComponent = (configuration, onPress) => (
11
+ const wrapComponent = (configuration, onPress, onPressToggle) => (
10
12
  <SCProvider initState={mockSCStore({})}>
11
- <OnOffSmartLockAction configuration={configuration} onPress={onPress} />
13
+ <OnOffSmartLockAction
14
+ configuration={configuration}
15
+ onPress={onPress}
16
+ onPressToggle={onPressToggle}
17
+ title={'Lock'}
18
+ template={'OnOffSmartLockActionTemplate'}
19
+ />
12
20
  </SCProvider>
13
21
  );
14
22
 
@@ -17,38 +25,70 @@ describe('Test OnOffSmartLockAction', () => {
17
25
 
18
26
  it('test onPress smart lock action', async () => {
19
27
  const configuration = {
20
- action_on: 'a',
21
- action_off: 'b',
22
- text_on: 'on',
23
- text_off: 'off',
28
+ action_off: 'f49e1577-493d-4bae-a9ab-3b0f96a4ec52',
29
+ action_on: '94600cbe-2035-47d5-bd43-89ace5d59796',
30
+ text_on: 'Open',
31
+ text_off: 'Close',
24
32
  };
25
33
  const mockFuntion = jest.fn();
34
+ const mockToggle = jest.fn();
26
35
  await act(async () => {
27
- tree = await renderer.create(wrapComponent(configuration, mockFuntion));
36
+ tree = await renderer.create(
37
+ wrapComponent(configuration, mockFuntion, mockToggle)
38
+ );
28
39
  });
29
40
  const instance = tree.root;
30
41
  const touchOpacity = instance.findAllByType(TouchableOpacity);
31
42
 
32
- expect(touchOpacity).toHaveLength(2);
43
+ expect(touchOpacity).toHaveLength(3);
33
44
  await act(async () => {
34
45
  touchOpacity[0].props.onPress();
35
46
  });
47
+ expect(mockFuntion).toHaveBeenCalledWith({
48
+ ...configuration,
49
+ name: configuration.text_on,
50
+ action: configuration.action_on,
51
+ action_off: null,
52
+ template: 'OnOffSmartLockActionTemplate',
53
+ is_toggle: false,
54
+ });
55
+ expect(mockToggle).not.toHaveBeenCalled();
56
+
57
+ mockFuntion.mockClear();
58
+ await act(async () => {
59
+ touchOpacity[1].props.onPress();
60
+ });
36
61
  expect(mockFuntion).toHaveBeenCalledWith({
37
62
  ...configuration,
38
63
  name: configuration.text_off,
39
64
  action: configuration.action_off,
40
65
  action_on: null,
66
+ template: 'OnOffSmartLockActionTemplate',
67
+ is_toggle: false,
41
68
  });
69
+ expect(mockToggle).not.toHaveBeenCalled();
42
70
 
43
71
  mockFuntion.mockClear();
44
72
  await act(async () => {
45
- touchOpacity[1].props.onPress();
73
+ touchOpacity[2].props.onPress();
46
74
  });
47
- expect(mockFuntion).toHaveBeenCalledWith({
75
+ expect(mockFuntion).not.toHaveBeenCalled();
76
+ expect(mockToggle).toHaveBeenCalledWith({
48
77
  ...configuration,
49
- name: configuration.text_on,
50
- action: configuration.action_on,
51
- action_off: null,
78
+ action_on_data: null,
79
+ action_off_data: null,
80
+ template: 'OnOffSmartLockActionTemplate',
81
+ is_toggle: true,
52
82
  });
83
+
84
+ const textTitle = instance.findAll(
85
+ (el) =>
86
+ el.props.accessibilityLabel ===
87
+ AccessibilityLabel.ON_OFF_BUTTON_ACTION_TITLE && el.type === Text
88
+ );
89
+ expect(textTitle).toHaveLength(3);
90
+ expect(textTitle[0].props.children).toEqual('Lock - Open');
91
+ expect(textTitle[1].props.children).toEqual('Lock - Close');
92
+ expect(textTitle[2].props.children).toEqual('Lock - Toggle');
53
93
  });
54
94
  });
@@ -8,11 +8,12 @@ import Text from '../../Text';
8
8
  import AccessibilityLabel from '../../../configs/AccessibilityLabel';
9
9
  import SwitchButtonAction from '../SwitchButtonAction';
10
10
 
11
- const wrapComponent = (configuration, onPress) => (
11
+ const wrapComponent = (configuration, onPress, onPressToggle) => (
12
12
  <SCProvider initState={mockSCStore({})}>
13
13
  <SwitchButtonAction
14
14
  configuration={configuration}
15
15
  onPress={onPress}
16
+ onPressToggle={onPressToggle}
16
17
  title={'Cong tac 1'}
17
18
  template={'switch_button_action_template'}
18
19
  />
@@ -30,26 +31,64 @@ describe('Test SwitchButtonAction', () => {
30
31
  action_on: '94600cbe-2035-47d5-bd43-89ace5d59796',
31
32
  };
32
33
  const mockFuntion = jest.fn();
34
+ const mockToggle = jest.fn();
33
35
  await act(async () => {
34
- tree = await renderer.create(wrapComponent(configuration, mockFuntion));
36
+ tree = await renderer.create(
37
+ wrapComponent(configuration, mockFuntion, mockToggle)
38
+ );
35
39
  });
36
40
  const instance = tree.root;
37
41
  const touchOpacity = instance.findAllByType(TouchableOpacity);
38
42
 
39
- expect(touchOpacity).toHaveLength(2);
43
+ expect(touchOpacity).toHaveLength(3);
40
44
  await act(async () => {
41
45
  touchOpacity[0].props.onPress();
46
+ });
47
+ expect(mockFuntion).toHaveBeenCalledWith({
48
+ ...configuration,
49
+ name: configuration.text_on,
50
+ action: configuration.action_on,
51
+ action_off: null,
52
+ template: 'switch_button_action_template',
53
+ is_toggle: false,
54
+ });
55
+ expect(mockToggle).not.toHaveBeenCalled();
56
+
57
+ mockFuntion.mockClear();
58
+ await act(async () => {
42
59
  touchOpacity[1].props.onPress();
43
60
  });
44
- expect(mockFuntion).toHaveBeenCalled();
61
+ expect(mockFuntion).toHaveBeenCalledWith({
62
+ ...configuration,
63
+ name: configuration.text_off,
64
+ action: configuration.action_off,
65
+ action_on: null,
66
+ template: 'switch_button_action_template',
67
+ is_toggle: false,
68
+ });
69
+ expect(mockToggle).not.toHaveBeenCalled();
70
+
71
+ mockFuntion.mockClear();
72
+ await act(async () => {
73
+ touchOpacity[2].props.onPress();
74
+ });
75
+ expect(mockFuntion).not.toHaveBeenCalled();
76
+ expect(mockToggle).toHaveBeenCalledWith({
77
+ ...configuration,
78
+ action_on_data: null,
79
+ action_off_data: null,
80
+ template: 'switch_button_action_template',
81
+ is_toggle: true,
82
+ });
45
83
 
46
84
  const textTitle = instance.findAll(
47
85
  (el) =>
48
86
  el.props.accessibilityLabel ===
49
87
  AccessibilityLabel.ON_OFF_BUTTON_ACTION_TITLE && el.type === Text
50
88
  );
51
- expect(textTitle).toHaveLength(2);
52
- expect(textTitle[0].props.children).toEqual(['Cong tac 1', ' ', 'On']);
53
- expect(textTitle[1].props.children).toEqual(['Cong tac 1', ' ', 'Off']);
89
+ expect(textTitle).toHaveLength(3);
90
+ expect(textTitle[0].props.children).toEqual('Cong tac 1 - On');
91
+ expect(textTitle[1].props.children).toEqual('Cong tac 1 - Off');
92
+ expect(textTitle[2].props.children).toEqual('Cong tac 1 - Toggle');
54
93
  });
55
94
  });
@@ -39,7 +39,7 @@ describe('Test ActionTemplate', () => {
39
39
  },
40
40
  };
41
41
  let switchTemplate = {
42
- title: '',
42
+ title: 'LED',
43
43
  template: 'switch_button_action_template',
44
44
  configuration: {
45
45
  text_on: 'On',
@@ -88,6 +88,7 @@ describe('Test ActionTemplate', () => {
88
88
  template: 'three_button_action_template',
89
89
  });
90
90
  });
91
+
91
92
  it('test render SwitchButtonAction', async () => {
92
93
  await act(async () => {
93
94
  tree = await renderer.create(wrapComponent(switchTemplate));
@@ -99,6 +100,9 @@ describe('Test ActionTemplate', () => {
99
100
  el.props.accessibilityLabel ===
100
101
  AccessibilityLabel.ON_OFF_BUTTON_ACTION_TITLE && el.type === Text
101
102
  );
102
- expect(textTitle).toHaveLength(2);
103
+ expect(textTitle).toHaveLength(3);
104
+ expect(textTitle[0].props.children).toEqual('LED - On');
105
+ expect(textTitle[1].props.children).toEqual('LED - Off');
106
+ expect(textTitle[2].props.children).toEqual('LED - Toggle');
103
107
  });
104
108
  });
@@ -20,19 +20,27 @@ const ActionTemplate = memo(({ device, item, onSelectAction }) => {
20
20
  const onClose = () => setVisible(false);
21
21
  const [actionName, setActionName] = useState();
22
22
 
23
- const onPressSelectAction = useCallback(
24
- (action) => {
23
+ const getActionData = useCallback(
24
+ (action, value) => {
25
25
  let actionData = null;
26
26
  if (device?.device_type === DEVICE_TYPE.ZIGBEE) {
27
- const state = action?.action_on ? 1 : 0;
27
+ const state = value;
28
28
  actionData = { state: state };
29
29
  if (action?.allow_config_store_value && action?.config) {
30
30
  actionData.config_id = action.config;
31
31
  actionData.config_value = state;
32
32
  }
33
33
  } else if (device?.device_type === DEVICE_TYPE.LG_THINQ) {
34
- actionData = { value: action?.action_on ? 1 : 0 };
34
+ actionData = { value };
35
35
  }
36
+ return actionData;
37
+ },
38
+ [device?.device_type]
39
+ );
40
+
41
+ const onPressSelectAction = useCallback(
42
+ (action) => {
43
+ const actionData = getActionData(action, action?.action_on ? 1 : 0);
36
44
  setVisible(false);
37
45
  setActionName(action?.name);
38
46
  onSelectAction &&
@@ -42,31 +50,78 @@ const ActionTemplate = memo(({ device, item, onSelectAction }) => {
42
50
  action: action?.action,
43
51
  data: actionData,
44
52
  template: action?.template,
53
+ is_toggle: action?.is_toggle,
54
+ });
55
+ },
56
+ [item?.index, onSelectAction, getActionData]
57
+ );
58
+
59
+ const onPressSelectToggle = useCallback(
60
+ (toggle) => {
61
+ const actionOnData = getActionData(toggle, 1);
62
+ const actionOffData = getActionData(toggle, 0);
63
+ setVisible(false);
64
+ setActionName(t('toggle'));
65
+ onSelectAction &&
66
+ onSelectAction({
67
+ index: item?.index,
68
+ action_on: toggle?.action_on,
69
+ action_on_data: actionOnData,
70
+ action_off: toggle?.action_off,
71
+ action_off_data: actionOffData,
72
+ config: toggle?.config,
73
+ is_on_values: toggle?.is_on_value,
74
+ template: toggle?.template,
75
+ is_toggle: toggle?.is_toggle,
45
76
  });
46
77
  },
47
- [device?.device_type, item?.index, onSelectAction]
78
+ [item?.index, onSelectAction, getActionData, t]
48
79
  );
49
80
 
50
81
  const renderAction = useMemo(() => {
51
82
  switch (item.template) {
52
83
  case 'on_off_button_action_template':
53
- return <OnOffButtonAction {...item} onPress={onPressSelectAction} />;
84
+ return (
85
+ <OnOffButtonAction
86
+ {...item}
87
+ onPress={onPressSelectAction}
88
+ onPressToggle={onPressSelectToggle}
89
+ />
90
+ );
54
91
  case 'one_button_action_template':
55
92
  return <OneButtonAction {...item} onPress={onPressSelectAction} />;
56
93
  case 'three_button_action_template':
57
94
  return <ThreeButtonAction {...item} onPress={onPressSelectAction} />;
58
95
  case 'OnOffSimpleActionTemplate':
59
- return <OnOffSimpleAction {...item} onPress={onPressSelectAction} />;
96
+ return (
97
+ <OnOffSimpleAction
98
+ {...item}
99
+ onPress={onPressSelectAction}
100
+ onPressToggle={onPressSelectToggle}
101
+ />
102
+ );
60
103
  case 'curtain_action_template':
61
104
  return <CurtainAction {...item} onPress={onPressSelectAction} />;
62
105
  case 'OnOffSmartLockActionTemplate':
63
- return <OnOffSmartLockAction {...item} onPress={onPressSelectAction} />;
106
+ return (
107
+ <OnOffSmartLockAction
108
+ {...item}
109
+ onPress={onPressSelectAction}
110
+ onPressToggle={onPressSelectToggle}
111
+ />
112
+ );
64
113
  case 'switch_button_action_template':
65
- return <SwitchButtonAction {...item} onPress={onPressSelectAction} />;
114
+ return (
115
+ <SwitchButtonAction
116
+ {...item}
117
+ onPress={onPressSelectAction}
118
+ onPressToggle={onPressSelectToggle}
119
+ />
120
+ );
66
121
  default:
67
122
  return null;
68
123
  }
69
- }, [item, onPressSelectAction]);
124
+ }, [item, onPressSelectAction, onPressSelectToggle]);
70
125
 
71
126
  return (
72
127
  <>
@@ -1,40 +1,39 @@
1
+ import { API, Colors, Images, SCConfig } from '../../../configs';
2
+ import { AccessibilityLabel, DEVICE_TYPE } from '../../../configs/Constants';
3
+ import { Dimensions, TouchableOpacity, View } from 'react-native';
1
4
  import React, {
2
5
  memo,
3
6
  useCallback,
4
- useEffect,
5
- useState,
6
7
  useContext,
8
+ useEffect,
7
9
  useMemo,
8
10
  useRef,
11
+ useState,
9
12
  } from 'react';
10
- import { View, TouchableOpacity, Dimensions } from 'react-native';
13
+ import { SCContext, useSCContextSelector } from '../../../context';
14
+ import { axiosGet, fetchWithCache } from '../../../utils/Apis/axios';
15
+ import { useBluetoothConnection, useWatchConfigs } from '../../../hooks/IoT';
11
16
  import {
12
- useNavigation,
13
- useIsFocused,
14
17
  useFocusEffect,
18
+ useIsFocused,
19
+ useNavigation,
15
20
  } from '@react-navigation/native';
16
- import NetInfo from '@react-native-community/netinfo';
17
- import { BleManager } from 'react-native-ble-plx';
18
- import { API, Colors, Images, SCConfig } from '../../../configs';
19
- import Text from '../../Text';
20
- import { axiosGet, fetchWithCache } from '../../../utils/Apis/axios';
21
21
 
22
- import styles from './styles';
23
- import { Section } from '../../Section';
24
- import { useTranslations } from '../../../hooks/Common/useTranslations';
25
- import { useUnitConnectRemoteDevices } from '../../../screens/Unit/hook/useUnitConnectRemoteDevices';
26
- import { useWatchConfigs, useBluetoothConnection } from '../../../hooks/IoT';
27
- import { SCContext, useSCContextSelector } from '../../../context';
28
22
  import { Action } from '../../../context/actionType';
29
-
23
+ import { BleManager } from 'react-native-ble-plx';
30
24
  import Carousel from 'react-native-new-snap-carousel';
31
- import { AccessibilityLabel, DEVICE_TYPE } from '../../../configs/Constants';
32
- import Routes from '../../../utils/Route';
25
+ import FImage from '../../FImage';
33
26
  import MyUnitDevice from '../../../screens/Unit/components/MyUnitDevice';
27
+ import NetInfo from '@react-native-community/netinfo';
28
+ import Routes from '../../../utils/Route';
34
29
  import { STORAGE_KEY } from '../../../utils/Storage';
30
+ import { Section } from '../../Section';
31
+ import Text from '../../Text';
35
32
  import { preloadImagesFromUnits } from '../../../utils/Functions/preloadImages';
36
- import FImage from '../../FImage';
33
+ import styles from './styles';
37
34
  import { usePrevious } from '../../../hooks';
35
+ import { useTranslations } from '../../../hooks/Common/useTranslations';
36
+ import { useUnitConnectRemoteDevices } from '../../../screens/Unit/hook/useUnitConnectRemoteDevices';
38
37
 
39
38
  let screenWidth = Dimensions.get('window').width;
40
39
 
@@ -10,7 +10,7 @@ const Search = ({ onSearch }) => {
10
10
  <Image source={Images.search} style={styles.icon} />
11
11
  <TextInput
12
12
  style={styles.textInput}
13
- placeholder={t('what_are_you_looking_for')}
13
+ placeholder={t('search')}
14
14
  onChangeText={onSearch}
15
15
  />
16
16
  </View>
@@ -1,13 +1,13 @@
1
1
  import React, { useMemo } from 'react';
2
- import { View, StyleSheet } from 'react-native';
3
- import LinearGradient from 'react-native-linear-gradient';
2
+ import { StyleSheet, View } from 'react-native';
4
3
 
5
- import { Colors } from '../../../configs';
6
4
  import { CircleView } from '../../../commons';
7
- import Text from '../../../commons/Text';
5
+ import { Colors } from '../../../configs';
6
+ import FImage from '../../FImage';
8
7
  import IconComponent from '../../IconComponent';
8
+ import LinearGradient from 'react-native-linear-gradient';
9
+ import Text from '../../../commons/Text';
9
10
  import images from '../../../configs/Images';
10
- import FImage from '../../FImage';
11
11
  import { useTranslations } from '../../../hooks/Common/useTranslations';
12
12
 
13
13
  const CurrentRainSensor = ({
@@ -45,37 +45,6 @@ const MediaPlayerFull = ({
45
45
  setIsFullScreen(!isFullScreen);
46
46
  }, [isFullScreen]);
47
47
 
48
- const renderCamera = useMemo(() => {
49
- return (
50
- <VLCPlayer
51
- autoAspectRatio={true}
52
- videoAspectRatio={
53
- isFullScreen
54
- ? `${Constants.height}:${Constants.width}`
55
- : `${Constants.width}:224`
56
- }
57
- source={{
58
- initType: 2,
59
- hwDecoderEnabled: 1,
60
- hwDecoderForced: 1,
61
- uri,
62
- initOptions: [
63
- '--no-audio',
64
- '--rtsp-tcp',
65
- '--network-caching=150',
66
- '--rtsp-caching=150',
67
- '--no-stats',
68
- '--tcp-caching=150',
69
- '--realrtsp-caching=150',
70
- ],
71
- }}
72
- style={styles.video}
73
- resizeMode={'cover'}
74
- isLive={true}
75
- />
76
- );
77
- }, [isFullScreen, uri]);
78
-
79
48
  useEffect(() => {
80
49
  setPaused(isPaused);
81
50
  }, [isPaused]);
@@ -137,7 +106,32 @@ const MediaPlayerFull = ({
137
106
  />
138
107
  </View>
139
108
  ) : (
140
- renderCamera
109
+ <VLCPlayer
110
+ autoAspectRatio={true}
111
+ videoAspectRatio={
112
+ isFullScreen
113
+ ? `${Constants.height}:${Constants.width}`
114
+ : `${Constants.width}:224`
115
+ }
116
+ source={{
117
+ initType: 2,
118
+ hwDecoderEnabled: 1,
119
+ hwDecoderForced: 1,
120
+ uri,
121
+ initOptions: [
122
+ '--no-audio',
123
+ '--rtsp-tcp',
124
+ '--network-caching=150',
125
+ '--rtsp-caching=150',
126
+ '--no-stats',
127
+ '--tcp-caching=150',
128
+ '--realrtsp-caching=150',
129
+ ],
130
+ }}
131
+ style={styles.video}
132
+ resizeMode={'cover'}
133
+ isLive={true}
134
+ />
141
135
  )}
142
136
  <View style={styles.buttonView}>
143
137
  <View style={styles.buttonPause}>
@@ -14,24 +14,25 @@ const ActionItem = ({
14
14
  setVisible,
15
15
  template,
16
16
  item,
17
+ option,
17
18
  }) => {
18
19
  const handleSelectAction = useCallback(() => {
19
20
  let actionData = null;
20
- const { allow_config_store_value, config, is_on_value } = item;
21
+ const { allow_config_store_value, config, is_on_value } = option;
21
22
  if (allow_config_store_value && config) {
22
23
  actionData = { config_id: config, config_value: is_on_value };
23
24
  }
24
- setActionName(item.text);
25
+ setActionName(option.text);
25
26
 
26
27
  onSelectAction &&
27
28
  onSelectAction({
28
29
  index: item.index,
29
- action: item.action,
30
+ action: option.action,
30
31
  data: actionData,
31
32
  template,
32
33
  });
33
34
  setVisible(false);
34
- }, [item, setActionName, onSelectAction, template, setVisible]);
35
+ }, [item, option, setActionName, onSelectAction, template, setVisible]);
35
36
 
36
37
  return (
37
38
  <TouchableOpacity
@@ -39,7 +40,7 @@ const ActionItem = ({
39
40
  accessibilityLabel={AccessibilityLabel.STATES_GRID_ACTION_GRID_ITEM}
40
41
  >
41
42
  <Text type="H4" style={styles.textWithLine}>
42
- {item.text}
43
+ {option.text}
43
44
  </Text>
44
45
  </TouchableOpacity>
45
46
  );
@@ -71,7 +72,8 @@ const StatesGridActionTemplate = ({ device, item, onSelectAction }) => {
71
72
  <View style={styles.modalContent}>
72
73
  {options.map((option, index) => (
73
74
  <ActionItem
74
- item={option}
75
+ item={item}
76
+ option={option}
75
77
  key={index}
76
78
  setActionName={setActionName}
77
79
  onSelectAction={onSelectAction}
@@ -91,9 +91,15 @@ describe('test Item', () => {
91
91
  expect(global.mockedNavigate).toHaveBeenCalledWith(Routes.ScenarioName, {
92
92
  automate: {
93
93
  type: 'one_tap',
94
+ conditions: [
95
+ {
96
+ type: 'one_tap',
97
+ },
98
+ ],
94
99
  unit: undefined,
95
100
  },
96
101
  closeScreen: undefined,
102
+ unitId: undefined,
97
103
  });
98
104
  mockedNavigate.mockClear();
99
105
 
@@ -55,6 +55,11 @@ const SubUnitAutomate = ({ isOwner, listAutomate, unit, wrapItemStyle }) => {
55
55
  navigate(Routes.ScenarioName, {
56
56
  automate: {
57
57
  type: AUTOMATE_TYPE.ONE_TAP,
58
+ conditions: [
59
+ {
60
+ type: AUTOMATE_TYPE.ONE_TAP,
61
+ },
62
+ ],
58
63
  unit: unit?.id,
59
64
  },
60
65
  unitId: unit?.id,
@@ -86,13 +86,11 @@ export const updateConfigChart = async (
86
86
  ];
87
87
  })
88
88
  );
89
-
90
- setChartData(
91
- configuration.map((config) => {
92
- config.data = data_by_id[config.id];
93
- return config;
94
- })
95
- );
89
+ const chartData = configuration.map((config) => {
90
+ config.data = data_by_id[config.id];
91
+ return config;
92
+ });
93
+ setChartData(chartData);
96
94
 
97
95
  data.configs.map((config) => {
98
96
  if (config.middle.not_ready.length > 0) {
@@ -113,10 +111,10 @@ export const updateConfigChart = async (
113
111
  middleDataByDay.sort((a, b) => (a.date > b.date ? 1 : -1)); // small to large
114
112
  const middleData = middleDataByDay.map((x) => x.data).flat();
115
113
  data_by_id[config.id] = [...config.head, ...middleData, ...config.tail];
116
- setChartData((chartData) => {
117
- const index = chartData.map((c) => c.id).indexOf(config.id);
118
- chartData[index].data = data_by_id[config.id];
119
- return [...chartData];
114
+ setChartData((prev) => {
115
+ const index = prev.map((c) => c.id).indexOf(config.id);
116
+ prev[index].data = data_by_id[config.id];
117
+ return [...prev];
120
118
  });
121
119
  });
122
120
  }
@@ -1,12 +1,12 @@
1
1
  import moment from 'moment';
2
2
  import React, { memo, useCallback, useEffect, useRef, useState } from 'react';
3
3
 
4
+ import API from '../../../configs/API';
4
5
  import { styles as useIframeStyle } from '../IFrame/IFrameStyles';
5
6
  import { styles } from './IFrameWithConfigStyles';
6
7
  import IconComponent from '../../IconComponent';
7
8
  import { useConfigGlobalState } from '../../../iot/states';
8
9
  import { useFetchConfigHistory } from '../../UnitSummary/ConfigHistoryChart';
9
- import API from '../../../configs/API';
10
10
  import WebView from 'react-native-webview';
11
11
  import { TouchableOpacity, View } from 'react-native';
12
12
 
@@ -26,7 +26,7 @@ const IFrameWithConfig = memo(
26
26
  const fetchDataDisplayHistory = useFetchConfigHistory(
27
27
  configuration?.history_configs,
28
28
  setChartData,
29
- API.CONFIG.DISPLAY_HISTORY_V4()
29
+ API.CONFIG.DISPLAY_HISTORY_V5()
30
30
  );
31
31
 
32
32
  const postMessage = useCallback((message) => {
@@ -252,7 +252,7 @@ describe('Test IFrame With Config', () => {
252
252
  });
253
253
 
254
254
  const mockAxios = new MockAdapter(api.axiosInstance);
255
- mockAxios.onGet(API.CONFIG.DISPLAY_HISTORY_V4()).reply(200, {
255
+ mockAxios.onGet(API.CONFIG.DISPLAY_HISTORY_V5()).reply(200, {
256
256
  configs: [
257
257
  {
258
258
  id: 1,