@eohjsc/react-native-smart-city 0.7.22 → 0.7.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.
- package/package.json +1 -1
- package/src/commons/ActionGroup/TerminalBoxTemplate.js +3 -0
- package/src/commons/ActionTemplate/OnOffButtonAction.js +38 -4
- package/src/commons/ActionTemplate/OnOffSimpleAction.js +55 -15
- package/src/commons/ActionTemplate/OnOffSmartLockAction.js +46 -8
- package/src/commons/ActionTemplate/SwitchButtonAction.js +35 -4
- package/src/commons/ActionTemplate/ThreeButtonAction.js +13 -3
- package/src/commons/ActionTemplate/__test__/OnOffButtonAction.test.js +46 -7
- package/src/commons/ActionTemplate/__test__/OnOffSimpleAction.test.js +66 -6
- package/src/commons/ActionTemplate/__test__/OnOffSmartLockAction.test.js +53 -13
- package/src/commons/ActionTemplate/__test__/SwitchButtonAction.test.js +46 -7
- package/src/commons/ActionTemplate/__test__/index.test.js +6 -2
- package/src/commons/ActionTemplate/index.js +65 -10
- package/src/commons/MediaPlayerDetail/MediaPlayerFull.js +26 -32
- package/src/commons/OneTapTemplate/StatesGridActionTemplate.js +8 -6
- package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +6 -0
- package/src/commons/SubUnit/OneTap/index.js +5 -0
- package/src/commons/UnitSummary/ConfigHistoryChart/index.js +16 -12
- package/src/commons/Widgets/IFrameWithConfig/IFrameWithConfig.js +3 -1
- package/src/commons/Widgets/IFrameWithConfig/__tests__/IFrameWithConfig.test.js +1 -1
- package/src/configs/API.js +6 -0
- package/src/configs/AccessibilityLabel.js +2 -0
- package/src/screens/ActivityLog/__test__/index.test.js +10 -0
- package/src/screens/ActivityLog/hooks/index.js +1 -1
- package/src/screens/Automate/AddNewAction/ChooseAction.js +15 -51
- package/src/screens/Automate/AddNewAction/SelectControlDevices.js +13 -3
- package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +74 -54
- package/src/screens/Automate/AddNewAction/__test__/ChooseAction.test.js +114 -4
- package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +37 -8
- package/src/screens/Automate/AddNewAutoSmart/AddTypeSmart.js +5 -0
- package/src/screens/Automate/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +18 -2
- package/src/screens/Automate/Components/InputName.js +7 -6
- package/src/screens/Automate/Constants.js +12 -0
- package/src/screens/Automate/EditActionsList/UpdateActionScript.js +24 -55
- package/src/screens/Automate/EditActionsList/__tests__/UpdateActionScript.test.js +298 -41
- package/src/screens/Automate/EditActionsList/__tests__/index.test.js +2 -2
- package/src/screens/Automate/EditActionsList/index.js +26 -14
- package/src/screens/Automate/MultiUnits.js +9 -1
- package/src/screens/Automate/OneTap/__test__/AddNewOneTap.test.js +3 -3
- package/src/screens/Automate/ScriptDetail/Components/AddActionScript.js +4 -10
- package/src/screens/Automate/ScriptDetail/Components/DeleteScript.js +2 -4
- package/src/screens/Automate/ScriptDetail/__test__/index.test.js +78 -0
- package/src/screens/Automate/ScriptDetail/index.js +16 -10
- package/src/screens/Automate/ScriptDetail/utils.js +39 -15
- package/src/screens/Automate/SetSchedule/AddEditConditionSchedule.js +27 -160
- package/src/screens/Automate/SetSchedule/EditSchedule.js +269 -0
- package/src/screens/Automate/SetSchedule/__test__/AddEditConditionSchedule.test.js +327 -22
- package/src/screens/Automate/SetSchedule/__test__/index.test.js +35 -22
- package/src/screens/Automate/SetSchedule/components/RepeatOptionsPopup.js +2 -8
- package/src/screens/Automate/SetSchedule/index.js +15 -129
- package/src/screens/Automate/SetSchedule/styles/indexStyles.js +9 -0
- package/src/screens/Automate/__test__/MultiUnits.test.js +6 -1
- package/src/screens/Automate/hooks/useAction.js +222 -0
- package/src/screens/Device/__test__/detail.test.js +48 -1
- package/src/screens/Device/detail.js +46 -3
- package/src/screens/PlayBackCamera/__test__/index.test.js +48 -13
- package/src/screens/PlayBackCamera/index.js +1 -1
- package/src/utils/Apis/axios.js +6 -0
- package/src/utils/I18n/translations/en.js +8 -0
- package/src/utils/I18n/translations/vi.js +12 -4
- package/src/screens/Automate/constants.js +0 -0
|
@@ -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
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
text_on: '
|
|
23
|
-
text_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(
|
|
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(
|
|
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[
|
|
73
|
+
touchOpacity[2].props.onPress();
|
|
46
74
|
});
|
|
47
|
-
expect(mockFuntion).
|
|
75
|
+
expect(mockFuntion).not.toHaveBeenCalled();
|
|
76
|
+
expect(mockToggle).toHaveBeenCalledWith({
|
|
48
77
|
...configuration,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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(
|
|
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(
|
|
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).
|
|
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(
|
|
52
|
-
expect(textTitle[0].props.children).toEqual(
|
|
53
|
-
expect(textTitle[1].props.children).toEqual(
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
[
|
|
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
|
|
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
|
|
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
|
|
106
|
+
return (
|
|
107
|
+
<OnOffSmartLockAction
|
|
108
|
+
{...item}
|
|
109
|
+
onPress={onPressSelectAction}
|
|
110
|
+
onPressToggle={onPressSelectToggle}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
64
113
|
case 'switch_button_action_template':
|
|
65
|
-
return
|
|
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
|
<>
|
|
@@ -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
|
-
|
|
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 } =
|
|
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(
|
|
25
|
+
setActionName(option.text);
|
|
25
26
|
|
|
26
27
|
onSelectAction &&
|
|
27
28
|
onSelectAction({
|
|
28
29
|
index: item.index,
|
|
29
|
-
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
|
-
{
|
|
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={
|
|
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,
|
|
@@ -23,7 +23,13 @@ export const useFetchConfigHistory = (
|
|
|
23
23
|
) => {
|
|
24
24
|
const fetchDataDisplayHistory = useCallback(
|
|
25
25
|
async (startDate, endDate, setProcessing = () => {}) => {
|
|
26
|
-
if (
|
|
26
|
+
if (
|
|
27
|
+
!configs ||
|
|
28
|
+
!Array.isArray(configs) ||
|
|
29
|
+
!configs.length ||
|
|
30
|
+
!startDate ||
|
|
31
|
+
!endDate
|
|
32
|
+
) {
|
|
27
33
|
return;
|
|
28
34
|
}
|
|
29
35
|
|
|
@@ -86,13 +92,11 @@ export const updateConfigChart = async (
|
|
|
86
92
|
];
|
|
87
93
|
})
|
|
88
94
|
);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
})
|
|
95
|
-
);
|
|
95
|
+
const chartData = configuration.map((config) => {
|
|
96
|
+
config.data = data_by_id[config.id];
|
|
97
|
+
return config;
|
|
98
|
+
});
|
|
99
|
+
setChartData(chartData);
|
|
96
100
|
|
|
97
101
|
data.configs.map((config) => {
|
|
98
102
|
if (config.middle.not_ready.length > 0) {
|
|
@@ -113,10 +117,10 @@ export const updateConfigChart = async (
|
|
|
113
117
|
middleDataByDay.sort((a, b) => (a.date > b.date ? 1 : -1)); // small to large
|
|
114
118
|
const middleData = middleDataByDay.map((x) => x.data).flat();
|
|
115
119
|
data_by_id[config.id] = [...config.head, ...middleData, ...config.tail];
|
|
116
|
-
setChartData((
|
|
117
|
-
const index =
|
|
118
|
-
|
|
119
|
-
return [...
|
|
120
|
+
setChartData((prev) => {
|
|
121
|
+
const index = prev.map((c) => c.id).indexOf(config.id);
|
|
122
|
+
prev[index].data = data_by_id[config.id];
|
|
123
|
+
return [...prev];
|
|
120
124
|
});
|
|
121
125
|
});
|
|
122
126
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
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';
|
|
@@ -24,7 +25,8 @@ const IFrameWithConfig = memo(
|
|
|
24
25
|
const [chartData, setChartData] = useState(configuration?.history_configs);
|
|
25
26
|
const fetchDataDisplayHistory = useFetchConfigHistory(
|
|
26
27
|
configuration?.history_configs,
|
|
27
|
-
setChartData
|
|
28
|
+
setChartData,
|
|
29
|
+
API.CONFIG.DISPLAY_HISTORY_V5()
|
|
28
30
|
);
|
|
29
31
|
|
|
30
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.
|
|
255
|
+
mockAxios.onGet(API.CONFIG.DISPLAY_HISTORY_V5()).reply(200, {
|
|
256
256
|
configs: [
|
|
257
257
|
{
|
|
258
258
|
id: 1,
|
package/src/configs/API.js
CHANGED
|
@@ -90,6 +90,7 @@ const API = {
|
|
|
90
90
|
CONFIG: {
|
|
91
91
|
DISPLAY_HISTORY_V3: () => '/chip_manager/configs/value_history_v3/',
|
|
92
92
|
DISPLAY_HISTORY_V4: () => '/chip_manager/configs/value_history_v4/',
|
|
93
|
+
DISPLAY_HISTORY_V5: () => '/chip_manager/configs/value_history_v5/',
|
|
93
94
|
},
|
|
94
95
|
AUTOMATE: {
|
|
95
96
|
ACTION_ONE_TAP: (id) => `/property_manager/automate/${id}/action_one_tap/`,
|
|
@@ -109,12 +110,16 @@ const API = {
|
|
|
109
110
|
`/property_manager/automate/${automateId}/update_script_notify/`,
|
|
110
111
|
UPDATE_SCRIPT_ACTION: (automateId) =>
|
|
111
112
|
`/property_manager/automate/${automateId}/update_script_action/`,
|
|
113
|
+
UPDATE_SCRIPT_TOGGLE: (automateId) =>
|
|
114
|
+
`/property_manager/automate/${automateId}/update_script_toggle/`,
|
|
112
115
|
UPDATE_SCRIPT_EMAIL: (automateId) =>
|
|
113
116
|
`/property_manager/automate/${automateId}/update_script_email/`,
|
|
114
117
|
UPDATE_SCRIPT_SMS: (automateId) =>
|
|
115
118
|
`/property_manager/automate/${automateId}/update_script_sms/`,
|
|
116
119
|
ADD_SCRIPT_ACTION: (id) =>
|
|
117
120
|
`/property_manager/automate/${id}/add_script_action/`,
|
|
121
|
+
ADD_SCRIPT_TOGGLE: (id) =>
|
|
122
|
+
`/property_manager/automate/${id}/add_script_toggle/`,
|
|
118
123
|
ADD_SCRIPT_NOTIFY: (id) =>
|
|
119
124
|
`/property_manager/automate/${id}/add_script_notify/`,
|
|
120
125
|
ADD_SCRIPT_DELAY: (id) =>
|
|
@@ -125,6 +130,7 @@ const API = {
|
|
|
125
130
|
FETCH_AUTOMATE: (automateId) =>
|
|
126
131
|
`/property_manager/automate_v2/${automateId}/`,
|
|
127
132
|
CREATE_AUTOMATE: () => '/property_manager/automate/',
|
|
133
|
+
CREATE_AUTOMATE_V2: () => '/property_manager/automate_v2/',
|
|
128
134
|
UPDATE_AUTOMATE: (automateId) =>
|
|
129
135
|
`/property_manager/automate/${automateId}/`,
|
|
130
136
|
ENABLE_SCRIPT: (automateId) =>
|
|
@@ -306,6 +306,7 @@ export default {
|
|
|
306
306
|
ONE_BUTTON: 'ONE_BUTTON',
|
|
307
307
|
ON_BUTTON: 'ON_BUTTON',
|
|
308
308
|
OFF_BUTTON: 'OFF_BUTTON',
|
|
309
|
+
TOGGLE_BUTTON: 'TOGGLE_BUTTON',
|
|
309
310
|
|
|
310
311
|
// Device Detail
|
|
311
312
|
DEVICE_DETAIL_MEDIA_PLAYER: 'DEVICE_DETAIL_MEDIA_PLAYER',
|
|
@@ -610,6 +611,7 @@ export default {
|
|
|
610
611
|
// OnOffSimpleAction
|
|
611
612
|
ON_OFF_SIMPLE_ACTION_ON: 'ON_OFF_SIMPLE_ACTION_ON',
|
|
612
613
|
ON_OFF_SIMPLE_ACTION_OFF: 'ON_OFF_SIMPLE_ACTION_OFF',
|
|
614
|
+
ON_OFF_SIMPLE_ACTION_TOGGLE: 'ON_OFF_SIMPLE_ACTION_TOGGLE',
|
|
613
615
|
|
|
614
616
|
// Add New Device LG
|
|
615
617
|
ADD_NEW_DEVICE_LG_ADD: 'ADD_NEW_DEVICE_LG_ADD',
|
|
@@ -198,4 +198,14 @@ describe('Test Activity log', () => {
|
|
|
198
198
|
const items = instance.findAllByType(ItemLog);
|
|
199
199
|
expect(items).toHaveLength(0);
|
|
200
200
|
});
|
|
201
|
+
|
|
202
|
+
it('render type null', async () => {
|
|
203
|
+
route.params.type = undefined;
|
|
204
|
+
await act(async () => {
|
|
205
|
+
tree = await create(wrapComponent(route));
|
|
206
|
+
});
|
|
207
|
+
const instance = tree.root;
|
|
208
|
+
const items = instance.findAllByType(ItemLog);
|
|
209
|
+
expect(items).toHaveLength(0);
|
|
210
|
+
});
|
|
201
211
|
});
|
|
@@ -120,7 +120,7 @@ export default ({ id, type, share, filterEnabled }) => {
|
|
|
120
120
|
|
|
121
121
|
const fetchMembers = async () => {
|
|
122
122
|
const api = apiMaps[type];
|
|
123
|
-
if (!filterEnabled?.user) {
|
|
123
|
+
if (!api?.memberUrl || !filterEnabled?.user) {
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
126
|
const { success, data } = await axiosGet(api.memberUrl(share?.id));
|