@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.
Files changed (43) hide show
  1. package/package.json +3 -1
  2. package/src/commons/ActionGroup/ColorPickerTemplate.js +36 -23
  3. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +31 -12
  4. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +8 -2
  5. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +9 -7
  6. package/src/commons/ActionGroup/SliderRangeTemplate.js +5 -1
  7. package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +83 -3
  8. package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +57 -1
  9. package/src/commons/ActionGroup/__test__/index.test.js +4 -7
  10. package/src/commons/ConnectingProcess/index.js +4 -1
  11. package/src/commons/Device/ItemDevice.js +4 -1
  12. package/src/commons/Device/WaterQualitySensor/QualityIndicatorsItem.js +7 -2
  13. package/src/commons/Form/CurrencyInput.js +15 -1
  14. package/src/commons/Form/TextInputPassword.js +1 -1
  15. package/src/commons/HeaderAni/index.js +6 -1
  16. package/src/commons/MediaPlayerDetail/index.js +11 -2
  17. package/src/commons/Sharing/MemberList.js +10 -2
  18. package/src/commons/Sharing/WrapHeaderScrollable.js +2 -0
  19. package/src/commons/SubUnit/__test__/ShortDetail.test.js +1 -1
  20. package/src/configs/Constants.js +20 -0
  21. package/src/configs/SCConfig.js +2 -0
  22. package/src/navigations/UnitStack.js +3 -20
  23. package/src/navigations/UnitStackStyles.js +21 -0
  24. package/src/screens/AddNewDevice/__test__/AddNewDevice.test.js +8 -1
  25. package/src/screens/AddNewDevice/__test__/ConnectingDevices.test.js +1 -1
  26. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +39 -36
  27. package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +64 -10
  28. package/src/screens/Device/EditDevice/index.js +15 -13
  29. package/src/screens/SubUnit/AddSubUnit.js +23 -17
  30. package/src/screens/SubUnit/EditSubUnit.js +15 -13
  31. package/src/screens/SubUnit/__test__/AddSubUnit.test.js +9 -23
  32. package/src/screens/SyncLGDevice/__test__/AddLGDevice.test.js +8 -1
  33. package/src/screens/Unit/SelectAddress.js +7 -1
  34. package/src/screens/Unit/Station/index.js +3 -0
  35. package/src/screens/Unit/__test__/SelectAddress.test.js +80 -3
  36. package/src/screens/Unit/components/MyUnitDevice/index.js +4 -4
  37. package/src/screens/Unit/components/__test__/MyUnitDevice.test.js +2 -2
  38. package/src/utils/Apis/axios.js +9 -1
  39. package/src/utils/I18n/translations/en.json +3 -1
  40. package/src/utils/I18n/translations/vi.json +3 -1
  41. package/src/utils/Setting/Location.js +30 -0
  42. package/src/utils/__test__/Utils.test.js +12 -0
  43. 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.03",
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, useCallback, useState, useEffect, useMemo } from 'react';
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 = useCallback(
15
- (color) => {
16
- if (!isFirstColor) {
17
- setIsFirstColor(true);
18
- return;
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
- setValueColorComplete(configValue);
35
- }, [configuration.config, configValues, configuration]);
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
- <ColorPicker
46
- style={styles.colorPicker}
47
- sliderHidden={true}
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
- const data = { temperature: actionValue };
46
- if (allow_config_store_value && config) {
47
- data.config_id = config;
48
- data.value = actionValue;
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, JSON.stringify(data), actionName);
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 !== 'GOOGLE_HOME' &&
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
- {text_format.replace('{number}', value)}
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 style={styles.bigCircle} onPress={triggerAction}>
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
- doAction(
65
- action_data,
66
- JSON.stringify({ level: value, key_code: newOption?.value_int }),
67
- actionName
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 !== 'GOOGLE_HOME' &&
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
- setValueBrightness(configValue);
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={{ is_managed_by_backend: true }}
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 text = instance.findAllByType(Text);
366
- expect(text[0].props.children).toEqual('28 *C');
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({ name: gateway?.model });
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 onPress={goToSensorDisplay}>
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={16}
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
- top: 10,
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, { useState, useRef, useCallback, useMemo } from '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}>
@@ -90,7 +90,7 @@ const styles = StyleSheet.create({
90
90
  borderRadius: 2,
91
91
  paddingTop: 12,
92
92
  paddingBottom: 12,
93
- paddingHorizontal: 20,
93
+ paddingRight: 20,
94
94
  backgroundColor: Colors.White,
95
95
  // ...Theme.shadow,
96
96
  shadowColor: Colors.Gray13,
@@ -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 style={styles.btnBack} onPress={onPressLeft}>
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 { Image, View, StyleSheet, Text, TouchableOpacity } from 'react-native';
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 = Constants.width / 1.5;
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
- <Text style={styles.textCenter}>{t('no_member')}</Text>
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
  });