@eohjsc/react-native-smart-city 0.3.3 → 0.3.6
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 +3 -1
- package/src/commons/ActionGroup/ColorPickerTemplate.js +36 -23
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +31 -12
- package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +8 -2
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +9 -7
- package/src/commons/ActionGroup/SliderRangeTemplate.js +5 -1
- package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +83 -3
- package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +57 -1
- package/src/commons/ActionGroup/__test__/index.test.js +4 -7
- package/src/commons/ConnectingProcess/index.js +4 -1
- package/src/commons/Device/ItemDevice.js +4 -1
- package/src/commons/Device/WaterQualitySensor/QualityIndicatorsItem.js +7 -2
- package/src/commons/Form/CurrencyInput.js +15 -1
- package/src/commons/Form/TextInputPassword.js +1 -1
- package/src/commons/HeaderAni/index.js +6 -1
- package/src/commons/MediaPlayerDetail/index.js +11 -2
- package/src/commons/Sharing/MemberList.js +10 -2
- package/src/commons/Sharing/WrapHeaderScrollable.js +2 -0
- package/src/commons/SubUnit/__test__/ShortDetail.test.js +1 -1
- package/src/configs/Constants.js +20 -0
- package/src/configs/SCConfig.js +2 -0
- package/src/navigations/UnitStack.js +3 -20
- package/src/navigations/UnitStackStyles.js +21 -0
- package/src/screens/AddNewDevice/__test__/AddNewDevice.test.js +8 -1
- package/src/screens/AddNewDevice/__test__/ConnectingDevices.test.js +1 -1
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +39 -36
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +64 -10
- package/src/screens/Device/EditDevice/index.js +15 -13
- package/src/screens/SubUnit/AddSubUnit.js +23 -17
- package/src/screens/SubUnit/EditSubUnit.js +15 -13
- package/src/screens/SubUnit/__test__/AddSubUnit.test.js +9 -23
- package/src/screens/SyncLGDevice/__test__/AddLGDevice.test.js +8 -1
- package/src/screens/Unit/SelectAddress.js +7 -1
- package/src/screens/Unit/Station/index.js +3 -0
- package/src/screens/Unit/__test__/SelectAddress.test.js +80 -3
- package/src/screens/Unit/components/MyUnitDevice/index.js +4 -4
- package/src/screens/Unit/components/__test__/MyUnitDevice.test.js +2 -2
- package/src/utils/Apis/axios.js +9 -1
- package/src/utils/I18n/translations/en.json +3 -1
- package/src/utils/I18n/translations/vi.json +3 -1
- package/src/utils/Setting/Location.js +30 -0
- package/src/utils/__test__/Utils.test.js +12 -0
- package/src/commons/ActionGroup/__test__/NumberUpDownTemplateWithNullConfigValue.test.js +0 -60
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eohjsc/react-native-smart-city",
|
|
3
3
|
"title": "React Native Smart Home",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.06",
|
|
5
5
|
"description": "TODO",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"files": [
|
|
@@ -146,6 +146,8 @@
|
|
|
146
146
|
"react-hooks-global-state": "^1.0.1",
|
|
147
147
|
"react-i18next": "^11.8.12",
|
|
148
148
|
"react-native-alert-async": "^1.0.5",
|
|
149
|
+
"react-native-android-keyboard-adjust": "^1.2.0",
|
|
150
|
+
"react-native-android-location-enabler": "^1.2.2",
|
|
149
151
|
"react-native-android-wifi": "^0.0.41",
|
|
150
152
|
"react-native-appearance": "^0.3.4",
|
|
151
153
|
"react-native-base64": "^0.1.0",
|
|
@@ -1,38 +1,51 @@
|
|
|
1
|
-
import React, { memo,
|
|
1
|
+
import React, { memo, useState, useEffect } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
import styles from './ColorPickerTemplateStyles';
|
|
4
4
|
import ColorPicker from 'react-native-wheel-color-picker';
|
|
5
5
|
import { watchMultiConfigs } from '../../iot/Monitor';
|
|
6
6
|
import { useConfigGlobalState } from '../../iot/states';
|
|
7
7
|
|
|
8
|
+
let isFirstTime = true;
|
|
9
|
+
|
|
10
|
+
const WheelColorPicker = ({ valueColor, onChangeColor }) => {
|
|
11
|
+
return (
|
|
12
|
+
<ColorPicker
|
|
13
|
+
style={styles.colorPicker}
|
|
14
|
+
sliderHidden={true}
|
|
15
|
+
swatches={false}
|
|
16
|
+
color={valueColor}
|
|
17
|
+
onColorChangeComplete={onChangeColor}
|
|
18
|
+
thumbSize={16}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
8
23
|
const ColorPickerTemplate = memo(({ actionGroup, doAction, sensor }) => {
|
|
9
24
|
const { configuration } = actionGroup;
|
|
10
25
|
const [valueColorComplete, setValueColorComplete] = useState('');
|
|
11
|
-
const [isFirstColor, setIsFirstColor] = useState(false);
|
|
12
26
|
const [configValues] = useConfigGlobalState('configValues');
|
|
13
27
|
|
|
14
|
-
const onChangeColor =
|
|
15
|
-
(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
const onChangeColor = (color) => {
|
|
29
|
+
const to = setTimeout(() => {
|
|
30
|
+
isFirstTime = false;
|
|
31
|
+
clearTimeout(to);
|
|
32
|
+
}, 1000);
|
|
33
|
+
|
|
34
|
+
!isFirstTime &&
|
|
20
35
|
doAction(
|
|
21
36
|
configuration?.action_color_data,
|
|
22
37
|
JSON.stringify({ value: color })
|
|
23
38
|
);
|
|
24
|
-
|
|
25
|
-
[configuration?.action_color_data, doAction, isFirstColor]
|
|
26
|
-
);
|
|
27
|
-
const valueColor = useMemo(() => {
|
|
28
|
-
return valueColorComplete || '';
|
|
29
|
-
}, [valueColorComplete]);
|
|
39
|
+
};
|
|
30
40
|
|
|
31
41
|
useEffect(() => {
|
|
32
42
|
const { config } = configuration;
|
|
33
43
|
const configValue = configValues[config];
|
|
34
|
-
|
|
35
|
-
|
|
44
|
+
if (configValue && isFirstTime) {
|
|
45
|
+
setValueColorComplete(`#${configValue?.toString(16)}`);
|
|
46
|
+
}
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
}, [configValues]);
|
|
36
49
|
|
|
37
50
|
useEffect(() => {
|
|
38
51
|
if (sensor?.is_managed_by_backend && sensor.device_type !== 'GOOGLE_HOME') {
|
|
@@ -40,15 +53,15 @@ const ColorPickerTemplate = memo(({ actionGroup, doAction, sensor }) => {
|
|
|
40
53
|
}
|
|
41
54
|
}, [sensor, configuration.config]);
|
|
42
55
|
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
return () => (isFirstTime = true);
|
|
58
|
+
}, []);
|
|
59
|
+
|
|
43
60
|
return (
|
|
44
61
|
<View style={styles.viewPickColor}>
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
swatches={false}
|
|
49
|
-
color={valueColor}
|
|
50
|
-
onColorChangeComplete={onChangeColor}
|
|
51
|
-
thumbSize={16}
|
|
62
|
+
<WheelColorPicker
|
|
63
|
+
valueColor={valueColorComplete}
|
|
64
|
+
onChangeColor={onChangeColor}
|
|
52
65
|
/>
|
|
53
66
|
</View>
|
|
54
67
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
import { View, TouchableOpacity } from 'react-native';
|
|
2
|
+
import { View, TouchableOpacity, ActivityIndicator } from 'react-native';
|
|
3
3
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
4
4
|
import { Colors } from '../../configs';
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@ import Text from '../Text';
|
|
|
7
7
|
import { useConfigGlobalState } from '../../iot/states';
|
|
8
8
|
import styles from './NumberUpDownActionTemplateStyle';
|
|
9
9
|
import { watchMultiConfigs } from '../../iot/Monitor';
|
|
10
|
-
import { TESTID } from '../../configs/Constants';
|
|
10
|
+
import { DEVICE_TYPE, TESTID } from '../../configs/Constants';
|
|
11
11
|
|
|
12
12
|
const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
13
13
|
const { configuration, title } = actionGroup;
|
|
@@ -25,6 +25,19 @@ const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
25
25
|
const [value, setValue] = useState();
|
|
26
26
|
const valueDefault = 28;
|
|
27
27
|
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (
|
|
33
|
+
!!config &&
|
|
34
|
+
sensor?.is_managed_by_backend &&
|
|
35
|
+
sensor.device_type !== DEVICE_TYPE.GOOGLE_HOME
|
|
36
|
+
) {
|
|
37
|
+
watchMultiConfigs([config]);
|
|
38
|
+
}
|
|
39
|
+
}, [sensor, config]);
|
|
40
|
+
|
|
28
41
|
useEffect(() => {
|
|
29
42
|
if (!config) {
|
|
30
43
|
setValue(valueDefault);
|
|
@@ -34,20 +47,22 @@ const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
34
47
|
const configValue = configValues[config];
|
|
35
48
|
if (configValue !== null && configValue !== undefined) {
|
|
36
49
|
setValue(configValue);
|
|
37
|
-
} else {
|
|
38
|
-
setValue(valueDefault);
|
|
39
50
|
}
|
|
40
51
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
-
}, []);
|
|
52
|
+
}, [JSON.stringify(configValues)]);
|
|
42
53
|
|
|
43
54
|
const doActionAndWatchConfig = useCallback(
|
|
44
55
|
async (actionData, actionValue, actionName) => {
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
data
|
|
48
|
-
|
|
56
|
+
let data = actionValue;
|
|
57
|
+
if (sensor.device_type !== DEVICE_TYPE.GOOGLE_HOME) {
|
|
58
|
+
data = { temperature: actionValue };
|
|
59
|
+
if (allow_config_store_value && config) {
|
|
60
|
+
data.config_id = config;
|
|
61
|
+
data.value = actionValue;
|
|
62
|
+
}
|
|
63
|
+
data = JSON.stringify(data);
|
|
49
64
|
}
|
|
50
|
-
await doAction(actionData,
|
|
65
|
+
await doAction(actionData, data, actionName);
|
|
51
66
|
if (!sensor?.is_managed_by_backend) {
|
|
52
67
|
return;
|
|
53
68
|
}
|
|
@@ -56,7 +71,7 @@ const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
56
71
|
}
|
|
57
72
|
|
|
58
73
|
config &&
|
|
59
|
-
sensor.device_type !==
|
|
74
|
+
sensor.device_type !== DEVICE_TYPE.GOOGLE_HOME &&
|
|
60
75
|
watchMultiConfigs([config]);
|
|
61
76
|
},
|
|
62
77
|
[
|
|
@@ -113,7 +128,11 @@ const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
113
128
|
</TouchableOpacity>
|
|
114
129
|
|
|
115
130
|
<Text testID={'abcd'} type="H2">
|
|
116
|
-
{
|
|
131
|
+
{value !== undefined ? (
|
|
132
|
+
text_format.replace('{number}', value)
|
|
133
|
+
) : (
|
|
134
|
+
<ActivityIndicator />
|
|
135
|
+
)}
|
|
117
136
|
</Text>
|
|
118
137
|
|
|
119
138
|
<TouchableOpacity
|
|
@@ -5,15 +5,20 @@ import React, { memo } from 'react';
|
|
|
5
5
|
import { TouchableOpacity, View } from 'react-native';
|
|
6
6
|
import { Colors } from '../../../configs';
|
|
7
7
|
import styles from './OnOffButtonTemplateStyle';
|
|
8
|
+
import { TESTID } from '../../../configs/Constants';
|
|
8
9
|
|
|
9
10
|
const OnOffButtonTemplate = memo(
|
|
10
11
|
({ isOn, triggerAction, actionGroup, isLight = false }) => {
|
|
11
|
-
const { configuration } = actionGroup;
|
|
12
|
+
const { configuration, id } = actionGroup;
|
|
12
13
|
|
|
13
14
|
return (
|
|
14
15
|
<>
|
|
15
16
|
<View style={styles.barrierControlContainer}>
|
|
16
|
-
<TouchableOpacity
|
|
17
|
+
<TouchableOpacity
|
|
18
|
+
style={styles.bigCircle}
|
|
19
|
+
onPress={triggerAction}
|
|
20
|
+
testID={`${TESTID.ON_OFF_BUTTON}-${id}`}
|
|
21
|
+
>
|
|
17
22
|
<View style={styles.smallCircle}>
|
|
18
23
|
<Icon
|
|
19
24
|
name={isOn ? configuration.icon_on : configuration.icon_off}
|
|
@@ -25,6 +30,7 @@ const OnOffButtonTemplate = memo(
|
|
|
25
30
|
styles.textBig,
|
|
26
31
|
{ color: isOn ? Colors.Gray8 : Colors.Gray6 },
|
|
27
32
|
]}
|
|
33
|
+
testID={`${TESTID.SENSOR_STATUS}-${id}`}
|
|
28
34
|
>
|
|
29
35
|
{isOn ? configuration.text_on : configuration.text_off}
|
|
30
36
|
</Text>
|
|
@@ -9,7 +9,7 @@ import { useDropdownAction } from './hooks/useDropdownAction';
|
|
|
9
9
|
import { useConfigGlobalState } from '../../iot/states';
|
|
10
10
|
import styles from './OptionsDropdownActionTemplateStyle';
|
|
11
11
|
import { watchMultiConfigs } from '../../iot/Monitor';
|
|
12
|
-
import { TESTID } from '../../configs/Constants';
|
|
12
|
+
import { DEVICE_TYPE, TESTID } from '../../configs/Constants';
|
|
13
13
|
import IconComponent from '../../commons/IconComponent';
|
|
14
14
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
15
15
|
import SvgDoorState from '../../../assets/images/Device/door-state.svg';
|
|
@@ -61,14 +61,16 @@ const OptionsDropdownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
61
61
|
const value = getOptionValue(newOption);
|
|
62
62
|
let actionName = `${sensor?.name} ${title?.toLowerCase()} ${value}`;
|
|
63
63
|
actionName = actionName.replace(/\s+/g, ' ').trim();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
|
|
65
|
+
let data = JSON.stringify({ level: value, key_code: newOption?.value_int });
|
|
66
|
+
if (sensor.device_type === DEVICE_TYPE.GOOGLE_HOME) {
|
|
67
|
+
data = value;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
doAction(action_data, data, actionName);
|
|
69
71
|
if (sensor?.is_managed_by_backend) {
|
|
70
72
|
configuration.config &&
|
|
71
|
-
sensor.device_type !==
|
|
73
|
+
sensor.device_type !== DEVICE_TYPE.GOOGLE_HOME &&
|
|
72
74
|
watchMultiConfigs([configuration.config]);
|
|
73
75
|
}
|
|
74
76
|
hideAlertAction();
|
|
@@ -33,7 +33,11 @@ const SliderRangeTemplate = memo(({ actionGroup, doAction, sensor }) => {
|
|
|
33
33
|
useEffect(() => {
|
|
34
34
|
const { config } = configuration;
|
|
35
35
|
const configValue = configValues[config];
|
|
36
|
-
|
|
36
|
+
let valueTemp = configValue;
|
|
37
|
+
if (configValue > 0) {
|
|
38
|
+
valueTemp = Math.round((configValue / 254) * 100);
|
|
39
|
+
}
|
|
40
|
+
setValueBrightness(valueTemp);
|
|
37
41
|
}, [configuration.config, configValues, configuration]);
|
|
38
42
|
|
|
39
43
|
useEffect(() => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { TouchableOpacity } from 'react-native';
|
|
2
|
+
import { ActivityIndicator, TouchableOpacity } from 'react-native';
|
|
3
3
|
import { act, create } from 'react-test-renderer';
|
|
4
4
|
import Text from '../../../commons/Text';
|
|
5
|
-
import { TESTID } from '../../../configs/Constants';
|
|
5
|
+
import { DEVICE_TYPE, TESTID } from '../../../configs/Constants';
|
|
6
6
|
import { watchMultiConfigs } from '../../../iot/Monitor';
|
|
7
7
|
import NumberUpDownActionTemplate from '../NumberUpDownActionTemplate';
|
|
8
8
|
|
|
@@ -48,7 +48,10 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
48
48
|
<NumberUpDownActionTemplate
|
|
49
49
|
actionGroup={actionGroup}
|
|
50
50
|
doAction={mockDoAction}
|
|
51
|
-
sensor={{
|
|
51
|
+
sensor={{
|
|
52
|
+
is_managed_by_backend: true,
|
|
53
|
+
device_type: DEVICE_TYPE.LG_THINQ,
|
|
54
|
+
}}
|
|
52
55
|
/>
|
|
53
56
|
);
|
|
54
57
|
});
|
|
@@ -288,4 +291,81 @@ describe('Test NumberUpDownActionTemplate', () => {
|
|
|
288
291
|
const text = instance.findByType(Text);
|
|
289
292
|
expect(text.props.children).toEqual('25 *C');
|
|
290
293
|
});
|
|
294
|
+
test('render template have title', async () => {
|
|
295
|
+
const mockDoAction = jest.fn();
|
|
296
|
+
actionGroup.title = 'title';
|
|
297
|
+
await act(async () => {
|
|
298
|
+
wrapper = await create(
|
|
299
|
+
<NumberUpDownActionTemplate
|
|
300
|
+
actionGroup={actionGroup}
|
|
301
|
+
doAction={mockDoAction}
|
|
302
|
+
sensor={{
|
|
303
|
+
is_managed_by_backend: true,
|
|
304
|
+
device_type: DEVICE_TYPE.LG_THINQ,
|
|
305
|
+
}}
|
|
306
|
+
/>
|
|
307
|
+
);
|
|
308
|
+
});
|
|
309
|
+
const instance = wrapper.root;
|
|
310
|
+
const text = instance.findAllByType(Text);
|
|
311
|
+
expect(text).toHaveLength(2);
|
|
312
|
+
});
|
|
313
|
+
test('render template watch config not exits', async () => {
|
|
314
|
+
const mockDoAction = jest.fn();
|
|
315
|
+
actionGroup.configuration.config = 100;
|
|
316
|
+
await act(async () => {
|
|
317
|
+
wrapper = await create(
|
|
318
|
+
<NumberUpDownActionTemplate
|
|
319
|
+
actionGroup={actionGroup}
|
|
320
|
+
doAction={mockDoAction}
|
|
321
|
+
sensor={{
|
|
322
|
+
is_managed_by_backend: true,
|
|
323
|
+
}}
|
|
324
|
+
/>
|
|
325
|
+
);
|
|
326
|
+
});
|
|
327
|
+
const instance = wrapper.root;
|
|
328
|
+
const text = instance.findAllByType(ActivityIndicator);
|
|
329
|
+
expect(text).toHaveLength(1);
|
|
330
|
+
});
|
|
331
|
+
test('action up sensor device type is GOOGLE_HOME', async () => {
|
|
332
|
+
const mockDoAction = jest.fn();
|
|
333
|
+
await act(async () => {
|
|
334
|
+
wrapper = await create(
|
|
335
|
+
<NumberUpDownActionTemplate
|
|
336
|
+
actionGroup={actionGroup}
|
|
337
|
+
doAction={mockDoAction}
|
|
338
|
+
sensor={{
|
|
339
|
+
is_managed_by_backend: true,
|
|
340
|
+
device_type: DEVICE_TYPE.GOOGLE_HOME,
|
|
341
|
+
name: 'Device',
|
|
342
|
+
}}
|
|
343
|
+
/>
|
|
344
|
+
);
|
|
345
|
+
});
|
|
346
|
+
const instance = wrapper.root;
|
|
347
|
+
const touchs = instance.find(
|
|
348
|
+
(el) =>
|
|
349
|
+
el.props.testID === TESTID.NUMBER_ACTION_UP &&
|
|
350
|
+
el.type === TouchableOpacity
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
await act(async () => {
|
|
354
|
+
await touchs.props.onPress();
|
|
355
|
+
});
|
|
356
|
+
expect(mockDoAction).toBeCalledWith(
|
|
357
|
+
{
|
|
358
|
+
color: '#00979D',
|
|
359
|
+
command_prefer_over_bluetooth: true,
|
|
360
|
+
command_prefer_over_googlehome: false,
|
|
361
|
+
command_prefer_over_internet: false,
|
|
362
|
+
googlehome_actions: [],
|
|
363
|
+
icon: 'caret-up',
|
|
364
|
+
id: 20,
|
|
365
|
+
key: '5ed1d4dc-a905-47cd-b0c9-f979644bd21a',
|
|
366
|
+
},
|
|
367
|
+
26,
|
|
368
|
+
'Device temp up'
|
|
369
|
+
);
|
|
370
|
+
});
|
|
291
371
|
});
|
|
@@ -5,7 +5,7 @@ import { act, create } from 'react-test-renderer';
|
|
|
5
5
|
import Text from '../../../commons/Text';
|
|
6
6
|
import { watchMultiConfigs } from '../../../iot/Monitor';
|
|
7
7
|
import { AlertAction, RadioCircle } from '../../../commons';
|
|
8
|
-
import { TESTID } from '../../../configs/Constants';
|
|
8
|
+
import { DEVICE_TYPE, TESTID } from '../../../configs/Constants';
|
|
9
9
|
import { getTranslate } from '../../../utils/I18n';
|
|
10
10
|
import { SCProvider } from '../../../context';
|
|
11
11
|
import { mockSCStore } from '../../../context/mockStore';
|
|
@@ -246,4 +246,60 @@ describe('Test OptionsDropdownActionTemplate', () => {
|
|
|
246
246
|
getTranslate('en', 'not_available')
|
|
247
247
|
);
|
|
248
248
|
});
|
|
249
|
+
test('doAction sensor device type is GOOGLE_HOME', async () => {
|
|
250
|
+
actionGroup.configuration.options[0].value_text = 'level-1';
|
|
251
|
+
sensor.device_type = DEVICE_TYPE.GOOGLE_HOME;
|
|
252
|
+
const mockDoAction = jest.fn();
|
|
253
|
+
await act(async () => {
|
|
254
|
+
wrapper = await create(wrapComponent(actionGroup, mockDoAction, sensor));
|
|
255
|
+
});
|
|
256
|
+
const instance = wrapper.root;
|
|
257
|
+
|
|
258
|
+
const touchs = instance.findAllByType(TouchableOpacity);
|
|
259
|
+
expect(touchs).toHaveLength(5);
|
|
260
|
+
const showListOption = touchs[0];
|
|
261
|
+
|
|
262
|
+
const texts = instance.findAllByType(Text);
|
|
263
|
+
expect(texts[1].props.children).toEqual('Level2');
|
|
264
|
+
|
|
265
|
+
const radioCircles = instance.findAllByType(RadioCircle);
|
|
266
|
+
expect(radioCircles[0].props.active).toBeFalsy();
|
|
267
|
+
expect(radioCircles[1].props.active).toBeTruthy();
|
|
268
|
+
|
|
269
|
+
const listChoosingOption = instance.findAll(
|
|
270
|
+
(el) =>
|
|
271
|
+
el.props.testID === TESTID.OPTIONS_DROPDOWN_ACTION_CHOOSING_ITEM &&
|
|
272
|
+
el.type === TouchableOpacity
|
|
273
|
+
);
|
|
274
|
+
expect(listChoosingOption).toHaveLength(2);
|
|
275
|
+
|
|
276
|
+
const alertAction = instance.findByType(AlertAction);
|
|
277
|
+
expect(alertAction.props.visible).toBeFalsy();
|
|
278
|
+
|
|
279
|
+
// show option
|
|
280
|
+
await act(async () => {
|
|
281
|
+
await showListOption.props.onPress();
|
|
282
|
+
});
|
|
283
|
+
expect(alertAction.props.visible).toBeTruthy();
|
|
284
|
+
|
|
285
|
+
// Choosed Level1 option
|
|
286
|
+
await act(async () => {
|
|
287
|
+
await listChoosingOption[0].props.onPress();
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
expect(radioCircles[0].props.active).toBeTruthy();
|
|
291
|
+
expect(radioCircles[1].props.active).toBeFalsy();
|
|
292
|
+
|
|
293
|
+
// doAction then update selectedOption
|
|
294
|
+
await act(async () => {
|
|
295
|
+
await alertAction.props.rightButtonClick();
|
|
296
|
+
});
|
|
297
|
+
expect(alertAction.props.visible).toBeFalsy();
|
|
298
|
+
|
|
299
|
+
expect(mockDoAction).toHaveBeenCalledWith(
|
|
300
|
+
action_data,
|
|
301
|
+
'level-1',
|
|
302
|
+
'Sensor name fan speed level-1'
|
|
303
|
+
); // doAction with text instead of int
|
|
304
|
+
});
|
|
249
305
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { TouchableOpacity, Switch } from 'react-native';
|
|
2
|
+
import { TouchableOpacity, Switch, ActivityIndicator } from 'react-native';
|
|
3
3
|
import renderer, { act } from 'react-test-renderer';
|
|
4
4
|
import DateTimePickerModal from 'react-native-modal-datetime-picker';
|
|
5
5
|
import moment from 'moment';
|
|
@@ -344,7 +344,7 @@ describe('Test ActionGroup', () => {
|
|
|
344
344
|
expect(mockDoAction).toHaveBeenCalledTimes(1);
|
|
345
345
|
});
|
|
346
346
|
|
|
347
|
-
test('render ActionGroup NumberUpDownActionTemplate', async () => {
|
|
347
|
+
test('render ActionGroup NumberUpDownActionTemplate watch config value null', async () => {
|
|
348
348
|
const mockDoAction = jest.fn();
|
|
349
349
|
const actionGroup = {
|
|
350
350
|
template: 'NumberUpDownActionTemplate',
|
|
@@ -362,11 +362,8 @@ describe('Test ActionGroup', () => {
|
|
|
362
362
|
);
|
|
363
363
|
});
|
|
364
364
|
const instance = wrapper.root;
|
|
365
|
-
const
|
|
366
|
-
expect(
|
|
367
|
-
|
|
368
|
-
const touchs = instance.findAllByType(TouchableOpacity);
|
|
369
|
-
expect(touchs).toHaveLength(2);
|
|
365
|
+
const activity = instance.findAllByType(ActivityIndicator);
|
|
366
|
+
expect(activity.length).toEqual(1);
|
|
370
367
|
});
|
|
371
368
|
|
|
372
369
|
test('render ActionGroup StatesGridActionTemplate', async () => {
|
|
@@ -45,6 +45,7 @@ const ConnectingProcess = ({ route }) => {
|
|
|
45
45
|
);
|
|
46
46
|
if (success) {
|
|
47
47
|
setSensor(data);
|
|
48
|
+
setNewName(data?.name);
|
|
48
49
|
} else {
|
|
49
50
|
ToastBottomHelper.error(JSON.stringify(data));
|
|
50
51
|
goBack();
|
|
@@ -64,6 +65,7 @@ const ConnectingProcess = ({ route }) => {
|
|
|
64
65
|
});
|
|
65
66
|
if (success) {
|
|
66
67
|
setSensor(data);
|
|
68
|
+
setNewName(data?.name);
|
|
67
69
|
} else {
|
|
68
70
|
ToastBottomHelper.error(JSON.stringify(data));
|
|
69
71
|
goBack();
|
|
@@ -79,7 +81,8 @@ const ConnectingProcess = ({ route }) => {
|
|
|
79
81
|
}
|
|
80
82
|
);
|
|
81
83
|
if (success) {
|
|
82
|
-
setSensor(
|
|
84
|
+
setSensor(data);
|
|
85
|
+
setNewName(data?.name || gateway?.model);
|
|
83
86
|
} else {
|
|
84
87
|
ToastBottomHelper.error(JSON.stringify(data));
|
|
85
88
|
goBack();
|
|
@@ -72,7 +72,10 @@ const ItemDevice = memo(
|
|
|
72
72
|
const textConnected = isConnected ? t('connected') : t('disconnected');
|
|
73
73
|
|
|
74
74
|
return (
|
|
75
|
-
<TouchableWithoutFeedback
|
|
75
|
+
<TouchableWithoutFeedback
|
|
76
|
+
onPress={goToSensorDisplay}
|
|
77
|
+
testID={`${TESTID.SENSOR_NAME}-${sensor?.id}`}
|
|
78
|
+
>
|
|
76
79
|
<View
|
|
77
80
|
style={[styles.container, wrapStyle, { borderColor }]}
|
|
78
81
|
testID={TESTID.SUB_UNIT_DEVICES}
|
|
@@ -37,7 +37,7 @@ const QualityIndicatorItem = memo(
|
|
|
37
37
|
>
|
|
38
38
|
<IconOutline
|
|
39
39
|
name={'info-circle'}
|
|
40
|
-
size={
|
|
40
|
+
size={18}
|
|
41
41
|
color={Colors.Gray8}
|
|
42
42
|
/>
|
|
43
43
|
</TouchableOpacity>
|
|
@@ -92,6 +92,11 @@ const styles = StyleSheet.create({
|
|
|
92
92
|
marginTop: 8,
|
|
93
93
|
},
|
|
94
94
|
iconInfo: {
|
|
95
|
-
|
|
95
|
+
width: 40,
|
|
96
|
+
height: 40,
|
|
97
|
+
justifyContent: 'center',
|
|
98
|
+
alignItems: 'center',
|
|
99
|
+
marginRight: -10,
|
|
100
|
+
marginTop: -2,
|
|
96
101
|
},
|
|
97
102
|
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
useState,
|
|
3
|
+
useRef,
|
|
4
|
+
useCallback,
|
|
5
|
+
useMemo,
|
|
6
|
+
useEffect,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
View,
|
|
4
10
|
TextInput,
|
|
@@ -6,6 +12,7 @@ import {
|
|
|
6
12
|
TouchableWithoutFeedback,
|
|
7
13
|
Platform,
|
|
8
14
|
} from 'react-native';
|
|
15
|
+
import AndroidKeyboardAdjust from 'react-native-android-keyboard-adjust';
|
|
9
16
|
import Text from '../Text';
|
|
10
17
|
import { Colors } from '../../configs';
|
|
11
18
|
|
|
@@ -125,6 +132,13 @@ const CurrencyInput = ({
|
|
|
125
132
|
return textInputValue.toString().length < 2 ? -12 : 0;
|
|
126
133
|
}, [textInputValue]);
|
|
127
134
|
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
const isAndroid = Platform.OS === 'android';
|
|
137
|
+
isAndroid && AndroidKeyboardAdjust.setAdjustResize();
|
|
138
|
+
|
|
139
|
+
return () => isAndroid && AndroidKeyboardAdjust.setAdjustPan();
|
|
140
|
+
}, []);
|
|
141
|
+
|
|
128
142
|
return (
|
|
129
143
|
<TouchableWithoutFeedback onPress={focusInput}>
|
|
130
144
|
<View style={styles.wrap}>
|
|
@@ -6,6 +6,7 @@ import { getStatusBarHeight } from 'react-native-iphone-x-helper';
|
|
|
6
6
|
|
|
7
7
|
import Text from '../../commons/Text';
|
|
8
8
|
import { Colors, Constants } from '../../configs';
|
|
9
|
+
import { TESTID } from '../../configs/Constants';
|
|
9
10
|
|
|
10
11
|
const screenHeight = Constants.height;
|
|
11
12
|
const default_height = 44;
|
|
@@ -89,7 +90,11 @@ const HeaderAni = memo(
|
|
|
89
90
|
},
|
|
90
91
|
]}
|
|
91
92
|
>
|
|
92
|
-
<TouchableOpacity
|
|
93
|
+
<TouchableOpacity
|
|
94
|
+
style={styles.btnBack}
|
|
95
|
+
onPress={onPressLeft}
|
|
96
|
+
testID={TESTID.ICON_BACK}
|
|
97
|
+
>
|
|
93
98
|
<Icon name={'left'} size={27} color={Colors.Gray9} />
|
|
94
99
|
</TouchableOpacity>
|
|
95
100
|
<View styles={styles.wrapRightComponent}>{rightComponent}</View>
|
|
@@ -6,7 +6,14 @@ import React, {
|
|
|
6
6
|
useContext,
|
|
7
7
|
useMemo,
|
|
8
8
|
} from 'react';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
Image,
|
|
11
|
+
View,
|
|
12
|
+
StyleSheet,
|
|
13
|
+
Text,
|
|
14
|
+
TouchableOpacity,
|
|
15
|
+
Platform,
|
|
16
|
+
} from 'react-native';
|
|
10
17
|
import { VLCPlayer } from 'react-native-vlc-media-player';
|
|
11
18
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
12
19
|
|
|
@@ -68,7 +75,9 @@ const MediaPlayerDetail = ({
|
|
|
68
75
|
newHeight = 224;
|
|
69
76
|
break;
|
|
70
77
|
case 4:
|
|
71
|
-
newWidth =
|
|
78
|
+
newWidth =
|
|
79
|
+
Constants.width /
|
|
80
|
+
(Platform.OS === 'ios' && Constants.width < 400 ? 1.5 : 2);
|
|
72
81
|
newHeight = 112;
|
|
73
82
|
break;
|
|
74
83
|
case 6:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
2
|
import { View, StyleSheet } from 'react-native';
|
|
3
3
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
4
|
-
import { Colors } from '../../configs';
|
|
4
|
+
import { Colors, Constants } from '../../configs';
|
|
5
5
|
import Text from '../../commons/Text';
|
|
6
6
|
import RowMember from './RowMember';
|
|
7
7
|
|
|
@@ -26,7 +26,9 @@ const MemberList = ({
|
|
|
26
26
|
/>
|
|
27
27
|
))}
|
|
28
28
|
{!dataMember.length && (
|
|
29
|
-
<
|
|
29
|
+
<View style={styles.viewEmpty}>
|
|
30
|
+
<Text style={styles.textCenter}>{t('no_member')}</Text>
|
|
31
|
+
</View>
|
|
30
32
|
)}
|
|
31
33
|
</View>
|
|
32
34
|
);
|
|
@@ -37,4 +39,10 @@ const styles = StyleSheet.create({
|
|
|
37
39
|
box: {
|
|
38
40
|
backgroundColor: Colors.White,
|
|
39
41
|
},
|
|
42
|
+
viewEmpty: {
|
|
43
|
+
justifyContent: 'center',
|
|
44
|
+
alignItems: 'center',
|
|
45
|
+
height: Constants.height - 200,
|
|
46
|
+
backgroundColor: Colors.White,
|
|
47
|
+
},
|
|
40
48
|
});
|