@eohjsc/react-native-smart-city 0.4.76 → 0.4.78

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 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.4.76",
4
+ "version": "0.4.78",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -5,11 +5,13 @@ import MediaPlayerDetail from '../index';
5
5
  import PauseIcon from '../../../assets/images/Common/Pause.svg';
6
6
  import { SCProvider } from '../../../context';
7
7
  import { mockSCStore } from '../../../context/mockStore';
8
+ import { ToastBottomHelper } from '../../../utils/Utils';
9
+ import { getTranslate } from '../../../utils/I18n';
8
10
 
9
- const wrapComponent = () => (
11
+ const wrapComponent = (uri) => (
10
12
  <SCProvider initState={mockSCStore({})}>
11
13
  <MediaPlayerDetail
12
- uri={'rtsp://admin:hd111111:1111111/Streaming/Channels/101/'}
14
+ uri={uri}
13
15
  key={'camera-1'}
14
16
  thumbnail={{ uri: 'https://abc.com/image.png' }}
15
17
  cameraName={'cameraName'}
@@ -19,10 +21,12 @@ const wrapComponent = () => (
19
21
 
20
22
  describe('Test MediaPlayerDetail', () => {
21
23
  let wrapper;
24
+ const spyToastError = jest.spyOn(ToastBottomHelper, 'error');
22
25
 
23
26
  it('MediaPlayerDetail render when onTap setPause', async () => {
27
+ const uri = 'rtsp://admin:hd111111:1111111/Streaming/Channels/101/';
24
28
  await act(async () => {
25
- wrapper = await create(wrapComponent());
29
+ wrapper = await create(wrapComponent(uri));
26
30
  });
27
31
  const instance = wrapper.root;
28
32
  const buttons = instance.findAllByType(TouchableOpacity);
@@ -44,4 +48,11 @@ describe('Test MediaPlayerDetail', () => {
44
48
  expect(texts[1].child).toBeUndefined();
45
49
  expect(pauseIcon.child).toBeUndefined();
46
50
  });
51
+ it('MediaPlayerDetail uri wrong', async () => {
52
+ const uri = 'wrong://admin:hd111111:1111111/Streaming/Channels/101/';
53
+ await act(async () => {
54
+ wrapper = await create(wrapComponent(uri));
55
+ });
56
+ expect(spyToastError).toBeCalledWith(getTranslate('en', 'uri_invalid'));
57
+ });
47
58
  });
@@ -24,6 +24,8 @@ import { AccessibilityLabel } from '../../configs/Constants';
24
24
  import { SCContext, useSCContextSelector } from '../../context';
25
25
  import { Action } from '../../context/actionType';
26
26
  import VLCPlayer from 'react-native-vlc-media-player/VLCPlayer';
27
+ import { isValidURI } from '../../utils/Validation';
28
+ import { ToastBottomHelper } from '../../utils/Utils';
27
29
 
28
30
  const MediaPlayerDetail = ({
29
31
  id,
@@ -87,7 +89,8 @@ const MediaPlayerDetail = ({
87
89
  }, [amount]);
88
90
 
89
91
  const renderCamera = useMemo(() => {
90
- if (!uri) {
92
+ if (!uri || !isValidURI(uri)) {
93
+ ToastBottomHelper.error(t('uri_invalid'));
91
94
  return null;
92
95
  }
93
96
  return (
@@ -1,6 +1,6 @@
1
1
  import React, { memo } from 'react';
2
2
  import styles from '../styles/ConfigValueStyles';
3
- import { View } from 'react-native';
3
+ import { Platform, View } from 'react-native';
4
4
  import Text from '../../../Text';
5
5
  import LastUpdatedText from '../../../Device/LastUpdatedText';
6
6
  import { EvaluationConfigWrapper } from '../EvaluationOverConfig/EvaluationOverConfig';
@@ -17,7 +17,15 @@ const ConfigAndEvaluationDisplay = memo(
17
17
  <IconComponent icon={icon_kit || icon} />
18
18
  </View>
19
19
  <View style={styles.rowTop}>
20
- <Text bold>{stationItem?.configuration?.config_data?.name}</Text>
20
+ <Text
21
+ numberOfLines={1}
22
+ semibold
23
+ style={
24
+ Platform.OS === 'ios' ? styles.iosStyle : styles.androidStyle
25
+ }
26
+ >
27
+ {stationItem?.configuration?.config_data?.name}
28
+ </Text>
21
29
  </View>
22
30
  <View style={styles.rowBottom}>
23
31
  <Text style={styles.textValue} bold>
@@ -1,6 +1,6 @@
1
1
  import React, { memo, useMemo } from 'react';
2
2
  import styles from '../styles/ConfigValueStyles';
3
- import { View } from 'react-native';
3
+ import { Platform, View } from 'react-native';
4
4
  import Text from '../../../Text';
5
5
  import { useConfigGlobalState } from '../../../../iot/states';
6
6
  import { useWatchConfigs } from '../../../../hooks/IoT';
@@ -25,7 +25,15 @@ const ConfigValue = ({ device, stationItem }) => {
25
25
  <IconComponent icon={icon_kit || icon} />
26
26
  </View>
27
27
  <View style={styles.rowTop}>
28
- <Text bold>{stationItem?.configuration?.config_data?.name}</Text>
28
+ <Text
29
+ numberOfLines={1}
30
+ semibold
31
+ style={
32
+ Platform.OS === 'ios' ? styles.iosStyle : styles.androidStyle
33
+ }
34
+ >
35
+ {stationItem?.configuration?.config_data?.name}
36
+ </Text>
29
37
  </View>
30
38
  <View style={styles.rowBottom}>
31
39
  <Text style={styles.textValue} bold>
@@ -3,18 +3,14 @@ import { getTemplate } from './';
3
3
  import ItemDeviceWrapper from '../../Device/ItemDeviceWrapper';
4
4
 
5
5
  export const DeviceTemplate = memo(
6
- ({ device, stationItem, unit, station, index }) => {
6
+ ({ device, stationItem, unit, station, key }) => {
7
7
  const Template = getTemplate(stationItem);
8
8
  if (!Template) {
9
9
  return null;
10
10
  }
11
11
  return (
12
12
  <ItemDeviceWrapper device={device} unit={unit} station={station}>
13
- <Template.Display
14
- device={device}
15
- stationItem={stationItem}
16
- index={index}
17
- />
13
+ <Template.Display device={device} stationItem={stationItem} key={key} />
18
14
  </ItemDeviceWrapper>
19
15
  );
20
16
  }
@@ -1,6 +1,6 @@
1
1
  import React, { memo, useMemo } from 'react';
2
2
  import styles from '../styles/ConfigValueStyles';
3
- import { View } from 'react-native';
3
+ import { Platform, View } from 'react-native';
4
4
  import Text from '../../../Text';
5
5
  import { useConfigGlobalState } from '../../../../iot/states';
6
6
  import {
@@ -54,7 +54,15 @@ const EvaluationOverConfigDisplay = memo(
54
54
  <IconComponent icon={icon_kit || icon} />
55
55
  </View>
56
56
  <View style={styles.rowTop}>
57
- <Text bold>{stationItem?.configuration?.config_data?.name}</Text>
57
+ <Text
58
+ numberOfLines={1}
59
+ semibold
60
+ style={
61
+ Platform.OS === 'ios' ? styles.iosStyle : styles.androidStyle
62
+ }
63
+ >
64
+ {stationItem?.configuration?.config_data?.name}
65
+ </Text>
58
66
  </View>
59
67
 
60
68
  <View style={styles.rowBottom}>
@@ -16,6 +16,7 @@ export default StyleSheet.create({
16
16
  alignItems: 'center',
17
17
  },
18
18
  textValue: {
19
+ fontSize: 16,
19
20
  marginTop: 6,
20
21
  lineHeight: 16,
21
22
  },
@@ -31,4 +32,14 @@ export default StyleSheet.create({
31
32
  marginTop10: {
32
33
  marginTop: 10,
33
34
  },
35
+ iosStyle: {
36
+ fontSize: 14,
37
+ lineHeight: 22,
38
+ },
39
+ androidStyle: {
40
+ fontSize: 14,
41
+ lineHeight: 22,
42
+ includeFontPadding: false,
43
+ marginBottom: 8,
44
+ },
34
45
  });
@@ -106,13 +106,12 @@ const ShortDetailSubUnit = ({ unit, station, isOwner }) => {
106
106
  });
107
107
  };
108
108
 
109
- const renderSubUnitItem = (device, stationItem, index) => {
109
+ const renderSubUnitItem = (device, stationItem) => {
110
110
  return (
111
111
  <DeviceTemplate
112
112
  device={device}
113
113
  stationItem={stationItem}
114
- index={index}
115
- key={index}
114
+ key={`device-template-${stationItem.id}`}
116
115
  unit={unit}
117
116
  station={station}
118
117
  />
@@ -126,7 +125,7 @@ const ShortDetailSubUnit = ({ unit, station, isOwner }) => {
126
125
 
127
126
  return station.devices
128
127
  .map((device, index) => {
129
- const displays = [];
128
+ let displays = [];
130
129
  if (device.device_type === DEVICE_TYPE.HANET) {
131
130
  displays.push(
132
131
  <ItemHanetDevice
@@ -157,7 +156,7 @@ const ShortDetailSubUnit = ({ unit, station, isOwner }) => {
157
156
  />
158
157
  );
159
158
  }
160
- if (device.station_items) {
159
+ if (device.station_items?.length) {
161
160
  displays.push(
162
161
  ...device.station_items.map(renderSubUnitItem.bind(device, device))
163
162
  );
@@ -1446,5 +1446,6 @@ export default {
1446
1446
  bellow_widget_is_not_configured: 'Bellow widget is not configured',
1447
1447
  bellow_widget_is_wrongly_configured: 'Bellow widget is wrongly configured',
1448
1448
  'customize...': 'Customize...',
1449
+ uri_invalid: 'URI invalid',
1449
1450
  when_value_is: 'When value is',
1450
1451
  };
@@ -1456,5 +1456,6 @@ export default {
1456
1456
  bellow_widget_is_not_configured: 'Tiện ích bên dưới chưa được cấu hình',
1457
1457
  bellow_widget_is_wrongly_configured: 'Tiện ích bên dưới được cấu hình sai',
1458
1458
  'customize...': 'Tùy chỉnh...',
1459
+ uri_invalid: 'URI không hợp lệ',
1459
1460
  when_value_is: 'Khi giá trị là',
1460
1461
  };
@@ -14,3 +14,8 @@ export const isValidPhoneNumberOrEmailAddress = (data) => {
14
14
 
15
15
  export const isHTML = (string) =>
16
16
  /<[a-z]+\d?(\s+[\w-]+=("[^"]*"|'[^']*'))*\s*\/?>|&#?\w+;/i.test(string);
17
+
18
+ export const isValidURI = (uri) => {
19
+ const uriRegex = /^(rtsp|http|https):\/\/[^\s/$.?#].[^\s]*$/;
20
+ return uriRegex.test(uri);
21
+ };