@eohjsc/react-native-smart-city 0.2.71 → 0.2.75
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/Images/Common/disney.svg +20 -0
- package/src/Images/Common/home.svg +3 -0
- package/src/Images/Common/input.svg +3 -0
- package/src/Images/Common/keyboard_arrow_down.svg +3 -0
- package/src/Images/Common/keyboard_arrow_up.svg +3 -0
- package/src/Images/Common/keyboard_return.svg +3 -0
- package/src/Images/Common/netflix.svg +9 -0
- package/src/Images/Common/pause.svg +3 -0
- package/src/Images/Common/shadowButton.png +0 -0
- package/src/Images/Common/spotify.svg +5 -0
- package/src/Images/Common/volume_up.svg +3 -0
- package/src/Images/Common/youtube.svg +13 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +214 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplateStyles.js +69 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/__test__/CircleButton.test.js +129 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/__test__/ControlPlay.test.js +138 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/__test__/RectangleButton.test.js +110 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/__test__/SmartTiviActionTemplate.test.js +144 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/component/CircleButton.js +91 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/component/CircleButtonStyles.js +79 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/component/ControlPlay.js +51 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/component/ControlPlayStyles.js +28 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/component/Icon.js +25 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/component/RectangleButton.js +49 -0
- package/src/commons/ActionGroup/SmartTiviActionTemplate/component/RectangleButtonStyles.js +47 -0
- package/src/commons/ActionGroup/index.js +3 -0
- package/src/commons/Device/HistoryChart.js +11 -7
- package/src/commons/Device/HorizontalBarChart.js +2 -1
- package/src/commons/Device/WaterQualitySensor/QualityIndicatorsItem.js +1 -1
- package/src/configs/API.js +3 -0
- package/src/configs/Constants.js +23 -0
- package/src/configs/Images.js +1 -0
- package/src/context/actionType.ts +2 -0
- package/src/context/reducer.ts +10 -0
- package/src/navigations/UnitStack.js +1 -3
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +37 -50
- package/src/screens/AddNewGateway/index.js +5 -1
- package/src/screens/ConfirmUnitDeletion/index.js +1 -1
- package/src/screens/Device/EditDevice/index.js +1 -1
- package/src/screens/Device/EditDevice/styles/EditDeviceStyles.js +2 -0
- package/src/screens/Notification/Monitor.js +12 -0
- package/src/screens/Notification/components/NotificationItem.js +11 -0
- package/src/screens/Notification/index.js +8 -0
- package/src/screens/Unit/Detail.js +8 -5
- package/src/screens/Unit/ManageUnit.js +9 -6
- package/src/screens/Unit/components/MyUnitDevice/index.js +4 -1
- package/src/utils/I18n/translations/en.json +3 -1
- package/src/utils/I18n/translations/vi.json +3 -1
- package/src/utils/Pusher/index.js +36 -0
- package/src/utils/Route/index.js +1 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import { TouchableOpacity, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import styles from './RectangleButtonStyles';
|
|
5
|
+
import { KeyboardArrowUp, KeyboardArrowDown } from './Icon';
|
|
6
|
+
import { TESTID } from '../../../../configs/Constants';
|
|
7
|
+
|
|
8
|
+
const RectangleButton = memo(
|
|
9
|
+
({ icon, onPressUp, onPressDown, wrapStyle, type, onPress }) => {
|
|
10
|
+
switch (type) {
|
|
11
|
+
case 'row':
|
|
12
|
+
return (
|
|
13
|
+
<View style={[styles.wrapRowRectangle, wrapStyle]}>
|
|
14
|
+
<TouchableOpacity style={[styles.rectangleRow]} onPress={onPress}>
|
|
15
|
+
{!!icon && icon}
|
|
16
|
+
</TouchableOpacity>
|
|
17
|
+
</View>
|
|
18
|
+
);
|
|
19
|
+
case 'column':
|
|
20
|
+
return (
|
|
21
|
+
<View style={[styles.wrapColumnRectangle, wrapStyle]}>
|
|
22
|
+
<TouchableOpacity
|
|
23
|
+
style={[styles.rectangleColumn]}
|
|
24
|
+
onPress={onPressUp}
|
|
25
|
+
testID={TESTID.SMART_TIVI_TEMPLATE.CH_VOLUME_UP_BUTTON}
|
|
26
|
+
>
|
|
27
|
+
<KeyboardArrowUp size={24} name={'up'} style={styles.padding8} />
|
|
28
|
+
</TouchableOpacity>
|
|
29
|
+
<View style={styles.iconKeyboardRetangle}>{!!icon && icon}</View>
|
|
30
|
+
<TouchableOpacity
|
|
31
|
+
style={[styles.rectangleColumn]}
|
|
32
|
+
onPress={onPressDown}
|
|
33
|
+
testID={TESTID.SMART_TIVI_TEMPLATE.CH_VOLUME_DOWN_BUTTON}
|
|
34
|
+
>
|
|
35
|
+
<KeyboardArrowDown
|
|
36
|
+
size={24}
|
|
37
|
+
name={'down'}
|
|
38
|
+
style={styles.padding8}
|
|
39
|
+
/>
|
|
40
|
+
</TouchableOpacity>
|
|
41
|
+
</View>
|
|
42
|
+
);
|
|
43
|
+
default:
|
|
44
|
+
return <></>;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export default RectangleButton;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors, Device } from '../../../../configs';
|
|
3
|
+
const widthMonitor = Device.screenWidth;
|
|
4
|
+
|
|
5
|
+
const centerRowItem = {
|
|
6
|
+
justifyContent: 'center',
|
|
7
|
+
alignItems: 'center',
|
|
8
|
+
};
|
|
9
|
+
const centerColumnItem = {
|
|
10
|
+
flexDirection: 'column',
|
|
11
|
+
justifyContent: 'space-between',
|
|
12
|
+
};
|
|
13
|
+
const borderItem = {
|
|
14
|
+
borderWidth: 1,
|
|
15
|
+
borderColor: Colors.Gray4,
|
|
16
|
+
borderRadius: 10,
|
|
17
|
+
};
|
|
18
|
+
export default StyleSheet.create({
|
|
19
|
+
rectangleColumn: {
|
|
20
|
+
padding: 16,
|
|
21
|
+
...centerRowItem,
|
|
22
|
+
},
|
|
23
|
+
rectangleRow: {
|
|
24
|
+
...centerRowItem,
|
|
25
|
+
},
|
|
26
|
+
wrapRowRectangle: {
|
|
27
|
+
flexWrap: 'nowrap',
|
|
28
|
+
...centerColumnItem,
|
|
29
|
+
width: widthMonitor / 2 - 37,
|
|
30
|
+
...borderItem,
|
|
31
|
+
margin: 12,
|
|
32
|
+
padding: 10,
|
|
33
|
+
},
|
|
34
|
+
wrapColumnRectangle: {
|
|
35
|
+
width: 63,
|
|
36
|
+
height: 186,
|
|
37
|
+
...centerColumnItem,
|
|
38
|
+
backgroundColor: Colors.White,
|
|
39
|
+
...borderItem,
|
|
40
|
+
},
|
|
41
|
+
iconKeyboardRetangle: {
|
|
42
|
+
...centerRowItem,
|
|
43
|
+
},
|
|
44
|
+
padding8: {
|
|
45
|
+
padding: 8,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -9,6 +9,7 @@ import OptionsDropdownActionTemplate from './OptionsDropdownActionTemplate';
|
|
|
9
9
|
import OnOffTemplate from './OnOffTemplate';
|
|
10
10
|
import TimerActionTemplate from './TimerActionTemplate';
|
|
11
11
|
import CurtainButtonTemplate from './CurtainButtonTemplate';
|
|
12
|
+
import SmartTiviActionTemplate from './SmartTiviActionTemplate/SmartTiviActionTemplate';
|
|
12
13
|
|
|
13
14
|
export const getActionComponent = (template) => {
|
|
14
15
|
switch (template) {
|
|
@@ -32,6 +33,8 @@ export const getActionComponent = (template) => {
|
|
|
32
33
|
return TimerActionTemplate;
|
|
33
34
|
case 'curtain_action_template':
|
|
34
35
|
return CurtainButtonTemplate;
|
|
36
|
+
case 'SmartTiviActionTemplate':
|
|
37
|
+
return SmartTiviActionTemplate;
|
|
35
38
|
default:
|
|
36
39
|
return null;
|
|
37
40
|
}
|
|
@@ -190,13 +190,17 @@ const HistoryChart = memo(
|
|
|
190
190
|
/>
|
|
191
191
|
)}
|
|
192
192
|
</View>
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
193
|
+
{!(
|
|
194
|
+
configuration.type === 'horizontal_bar_chart' && groupBy !== 'date'
|
|
195
|
+
) && (
|
|
196
|
+
<DateTimeRangeChange
|
|
197
|
+
startTime={eventPicker.startTime}
|
|
198
|
+
onStart={onStart}
|
|
199
|
+
onEnd={onEnd}
|
|
200
|
+
endTime={eventPicker.endTime}
|
|
201
|
+
formatType={formatType}
|
|
202
|
+
/>
|
|
203
|
+
)}
|
|
200
204
|
</View>
|
|
201
205
|
{configuration.config === 'power_consumption' && (
|
|
202
206
|
<View style={styles.wrapCalculateCost}>
|
|
@@ -65,8 +65,9 @@ const HorizontalBarChart = memo(({ datas, config }) => {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
const formatMoney = (number) => {
|
|
68
|
+
const formatNumber = number.toFixed();
|
|
68
69
|
return (
|
|
69
|
-
parseInt(
|
|
70
|
+
parseInt(formatNumber, 10)
|
|
70
71
|
.toFixed(0)
|
|
71
72
|
.toString()
|
|
72
73
|
.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1.') + 'đ'
|
package/src/configs/API.js
CHANGED
package/src/configs/Constants.js
CHANGED
|
@@ -178,6 +178,28 @@ export const TESTID = {
|
|
|
178
178
|
MY_UNIT_NO_UNIT: 'MY_UNIT_NO_UNIT',
|
|
179
179
|
ITEM_UNIT: 'ITEM_UNIT',
|
|
180
180
|
|
|
181
|
+
// SmartTiviTemplate
|
|
182
|
+
SMART_TIVI_TEMPLATE: {
|
|
183
|
+
BIG_BUTTON: 'BIG_BUTTON',
|
|
184
|
+
ONOFF_BUTTON: 'ONOFF_BUTTON',
|
|
185
|
+
EXIT_BUTTON: 'EXIT_BUTTON',
|
|
186
|
+
CH_VOLUME_UP_BUTTON: 'CH_VOLUME_UP_BUTTON',
|
|
187
|
+
CH_VOLUME_DOWN_BUTTON: 'CH_VOLUME_DOWN_BUTTON',
|
|
188
|
+
PREV_BUTTON: 'PREV_BUTTON',
|
|
189
|
+
STOP_BUTTON: 'STOP_BUTTON',
|
|
190
|
+
NEXT_BUTTON: 'NEXT_BUTTON',
|
|
191
|
+
UP_BUTTON: 'UP_BUTTON',
|
|
192
|
+
DOWN_BUTTON: 'DOWN_BUTTON',
|
|
193
|
+
LEFT_BUTTON: 'LEFT_BUTTON',
|
|
194
|
+
RIGHT_BUTTON: 'RIGHT_BUTTON',
|
|
195
|
+
OK_BUTTON: 'OK_BUTTON',
|
|
196
|
+
HOME_BUTTON: 'HOME_BUTTON',
|
|
197
|
+
BACK_BUTTON: 'BACK_BUTTON',
|
|
198
|
+
VOLUME_BUTTON: 'VOLUME_BUTTON',
|
|
199
|
+
CH_BUTTON: 'CH_BUTTON',
|
|
200
|
+
CONTROL_BUTTON: 'CONTROL_BUTTON',
|
|
201
|
+
},
|
|
202
|
+
|
|
181
203
|
// sub unit
|
|
182
204
|
SUB_UNIT_FULL_CAMERA: 'SUB_UNIT_FULL_CAMERA',
|
|
183
205
|
SUB_UNIT_CAMERA_VIEW: 'SUB_UNIT_CAMERA_VIEW',
|
|
@@ -612,6 +634,7 @@ export const NOTIFICATION_TYPES = {
|
|
|
612
634
|
REMINDER: 'REMINDER',
|
|
613
635
|
NOTIFY_REMOVE_UNIT: 'NOTIFY_REMOVE_UNIT',
|
|
614
636
|
NOTIFY_REMOVE_MEMBER: 'NOTIFY_REMOVE_MEMBER',
|
|
637
|
+
NOTIFY_MEMBER_LEAVE_UNIT: 'NOTIFY_MEMBER_LEAVE_UNIT',
|
|
615
638
|
};
|
|
616
639
|
|
|
617
640
|
export const ACTIVITY_LOG_TYPES = {
|
package/src/configs/Images.js
CHANGED
|
@@ -10,4 +10,5 @@ export default {
|
|
|
10
10
|
buttonPauseCurtain: require('../Images/Common/buttonPauseCurtain.png'),
|
|
11
11
|
buttonLeftCurtain: require('../Images/Common/buttonLeftCurtain.png'),
|
|
12
12
|
buttonRightCurtain: require('../Images/Common/buttonRightCurtain.png'),
|
|
13
|
+
shadowButton: require('../Images/Common/shadowButton.png'),
|
|
13
14
|
};
|
|
@@ -5,6 +5,7 @@ export const Action = {
|
|
|
5
5
|
LIST_DEVICE_TYPES: 'LIST_DEVICE_TYPES',
|
|
6
6
|
LIST_ACTION: 'LIST_ACTION',
|
|
7
7
|
IS_FIRST_OPEN_CAMERA: 'IS_FIRST_OPEN_CAMERA',
|
|
8
|
+
IS_LAVIDA_SOURCE: 'IS_LAVIDA_SOURCE',
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
export type AuthData = {
|
|
@@ -48,4 +49,5 @@ export type ActionDataMap = {
|
|
|
48
49
|
|
|
49
50
|
export type AppType = {
|
|
50
51
|
isFirstOpenCamera: boolean;
|
|
52
|
+
isLavidaSource: boolean;
|
|
51
53
|
};
|
package/src/context/reducer.ts
CHANGED
|
@@ -39,6 +39,7 @@ export const initialState = {
|
|
|
39
39
|
listAction: [] as ListAction,
|
|
40
40
|
app: {
|
|
41
41
|
isFirstOpenCamera: true,
|
|
42
|
+
isLavidaSource: false,
|
|
42
43
|
},
|
|
43
44
|
};
|
|
44
45
|
|
|
@@ -97,6 +98,15 @@ export const reducer = (currentState: ContextData, action: Action) => {
|
|
|
97
98
|
isFirstOpenCamera: payload,
|
|
98
99
|
},
|
|
99
100
|
};
|
|
101
|
+
case Action.IS_LAVIDA_SOURCE: {
|
|
102
|
+
return {
|
|
103
|
+
...currentState,
|
|
104
|
+
app: {
|
|
105
|
+
...currentState.app,
|
|
106
|
+
isLavidaSource: payload,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
100
110
|
default:
|
|
101
111
|
return currentState;
|
|
102
112
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
|
-
import { View, StyleSheet
|
|
2
|
+
import { View, StyleSheet } from 'react-native';
|
|
3
3
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
4
4
|
import { createStackNavigator } from '@react-navigation/stack';
|
|
5
5
|
import { get } from 'lodash';
|
|
@@ -134,7 +134,6 @@ export const UnitStack = memo((props) => {
|
|
|
134
134
|
component={UnitSummary}
|
|
135
135
|
options={{
|
|
136
136
|
headerShown: false,
|
|
137
|
-
animationEnabled: Platform.OS === 'ios',
|
|
138
137
|
}}
|
|
139
138
|
/>
|
|
140
139
|
<Stack.Screen
|
|
@@ -161,7 +160,6 @@ export const UnitStack = memo((props) => {
|
|
|
161
160
|
component={DeviceDetail}
|
|
162
161
|
options={{
|
|
163
162
|
headerShown: false,
|
|
164
|
-
animationEnabled: Platform.OS === 'ios',
|
|
165
163
|
}}
|
|
166
164
|
/>
|
|
167
165
|
<Stack.Screen
|
|
@@ -20,45 +20,12 @@ import { Colors, API } from '../../../configs';
|
|
|
20
20
|
import { axiosPost } from '../../../utils/Apis/axios';
|
|
21
21
|
import Routes from '../../../utils/Route';
|
|
22
22
|
|
|
23
|
-
const socket = dgram.createSocket({ type: 'udp4' });
|
|
24
|
-
|
|
25
|
-
socket.once('listening', function () {
|
|
26
|
-
socket.send(
|
|
27
|
-
JSON.stringify({ type: 'scan', data: { wifi: '' } }),
|
|
28
|
-
undefined,
|
|
29
|
-
undefined,
|
|
30
|
-
54321,
|
|
31
|
-
'192.168.27.1',
|
|
32
|
-
undefined
|
|
33
|
-
);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
23
|
const ConnectWifiWarning = memo(({ route }) => {
|
|
37
24
|
const { wifi_ssid, wifi_pass, unit_id, chip_id } = route.params;
|
|
38
25
|
const t = useTranslations();
|
|
39
|
-
const { navigate } = useNavigation();
|
|
26
|
+
const { navigate, goBack } = useNavigation();
|
|
40
27
|
const [isLoading, setIsLoading] = useState(false);
|
|
41
28
|
|
|
42
|
-
socket.on('message', function (msg, rinfo) {
|
|
43
|
-
const data = JSON.parse(msg.toString());
|
|
44
|
-
if (data.hasOwnProperty('wifi')) {
|
|
45
|
-
navigate(Routes.GatewayWifiList, {
|
|
46
|
-
list_wifi: data.wifi,
|
|
47
|
-
unit_id: unit_id,
|
|
48
|
-
chip_id: chip_id,
|
|
49
|
-
socket: socket,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
if (data.hasOwnProperty('gateway')) {
|
|
53
|
-
navigate(Routes.Dashboard);
|
|
54
|
-
ToastBottomHelper.success(t('completed'));
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
socket.on('error', () => {
|
|
59
|
-
ToastBottomHelper.error(t('server_error'));
|
|
60
|
-
});
|
|
61
|
-
|
|
62
29
|
const getPermissionWifiAndroid = useCallback(async () => {
|
|
63
30
|
const granted = await PermissionsAndroid.request(
|
|
64
31
|
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
|
@@ -78,26 +45,45 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
78
45
|
|
|
79
46
|
useEffect(() => {
|
|
80
47
|
Platform.OS === 'android' && getPermissionWifiAndroid();
|
|
81
|
-
socket.bind(54321);
|
|
82
48
|
}, [getPermissionWifiAndroid]);
|
|
83
49
|
|
|
84
|
-
const handleSend =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
50
|
+
const handleSend = () => {
|
|
51
|
+
const socket = dgram.createSocket({ type: 'udp4' });
|
|
52
|
+
socket.bind(54321);
|
|
53
|
+
socket.once('listening', function () {
|
|
54
|
+
socket.send(
|
|
55
|
+
JSON.stringify({ type: 'scan', data: { wifi: '' } }),
|
|
56
|
+
undefined,
|
|
57
|
+
undefined,
|
|
58
|
+
54321,
|
|
59
|
+
'192.168.27.1',
|
|
60
|
+
undefined
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
socket.on('message', function (msg, rinfo) {
|
|
64
|
+
const data = JSON.parse(msg.toString());
|
|
65
|
+
if (data.hasOwnProperty('wifi')) {
|
|
66
|
+
navigate(Routes.GatewayWifiList, {
|
|
67
|
+
list_wifi: data.wifi,
|
|
68
|
+
unit_id: unit_id,
|
|
69
|
+
chip_id: chip_id,
|
|
70
|
+
socket: socket,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (data.hasOwnProperty('gateway')) {
|
|
74
|
+
navigate(Routes.Dashboard);
|
|
75
|
+
ToastBottomHelper.success(t('completed'));
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
socket.on('error', () => {
|
|
79
|
+
ToastBottomHelper.error(t('server_error'));
|
|
80
|
+
goBack();
|
|
81
|
+
});
|
|
82
|
+
return () => {
|
|
83
|
+
socket.close();
|
|
84
|
+
};
|
|
93
85
|
};
|
|
94
86
|
|
|
95
|
-
useEffect(() => {
|
|
96
|
-
if (isLoading) {
|
|
97
|
-
handleSend();
|
|
98
|
-
}
|
|
99
|
-
}, [isLoading]);
|
|
100
|
-
|
|
101
87
|
const handleConnectWifiGateway = async () => {
|
|
102
88
|
setIsLoading(true);
|
|
103
89
|
const { success } = await axiosPost(API.UNIT.ADD_GATEWAY(unit_id), {
|
|
@@ -113,6 +99,7 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
113
99
|
},
|
|
114
100
|
(e) => {
|
|
115
101
|
ToastBottomHelper.error('Connection failed!');
|
|
102
|
+
goBack();
|
|
116
103
|
}
|
|
117
104
|
);
|
|
118
105
|
};
|
|
@@ -48,6 +48,10 @@ const AddNewGateway = memo(({ route }) => {
|
|
|
48
48
|
return true;
|
|
49
49
|
}, [chipName, imei]);
|
|
50
50
|
|
|
51
|
+
const textGateWay = !wifiName
|
|
52
|
+
? t('please_add_your_phone_number_and_chip_name')
|
|
53
|
+
: t('Please_add_gateway_name');
|
|
54
|
+
|
|
51
55
|
return (
|
|
52
56
|
<SafeAreaView style={styles.wrap}>
|
|
53
57
|
<Text
|
|
@@ -65,7 +69,7 @@ const AddNewGateway = memo(({ route }) => {
|
|
|
65
69
|
color={Colors.Gray8}
|
|
66
70
|
style={styles.textNote}
|
|
67
71
|
>
|
|
68
|
-
{
|
|
72
|
+
{textGateWay}
|
|
69
73
|
</Text>
|
|
70
74
|
|
|
71
75
|
<ScrollView
|
|
@@ -28,8 +28,8 @@ const ConfirmUnitDeletion = ({ route }) => {
|
|
|
28
28
|
if (confirm === 'YES') {
|
|
29
29
|
const { success } = await axiosDelete(API.UNIT.MANAGE_UNIT(unit.id));
|
|
30
30
|
if (success) {
|
|
31
|
-
navigation.navigate(Routes.Dashboard);
|
|
32
31
|
ToastBottomHelper.success(t('unit_deleted_successfully'));
|
|
32
|
+
navigation.navigate(Routes.Dashboard);
|
|
33
33
|
}
|
|
34
34
|
} else {
|
|
35
35
|
setErrorText(t('please_enter_correct'));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getPusher, destroyPusher } from '../../utils/Pusher';
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line promise/prefer-await-to-callbacks
|
|
4
|
+
export const watchNotificationData = (user, callback) => {
|
|
5
|
+
const channel = getPusher().subscribe(`private-user-${user.id}`);
|
|
6
|
+
channel.bind('new-notification', callback);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const unwatchNotificationData = (user) => {
|
|
10
|
+
getPusher().unsubscribe(`private-user-${user.id}`);
|
|
11
|
+
destroyPusher();
|
|
12
|
+
};
|
|
@@ -243,6 +243,17 @@ const NotificationItem = memo(({ item }) => {
|
|
|
243
243
|
<IconComponent icon={'home'} style={styles.backgroundSummer} />
|
|
244
244
|
),
|
|
245
245
|
};
|
|
246
|
+
case NOTIFICATION_TYPES.NOTIFY_MEMBER_LEAVE_UNIT:
|
|
247
|
+
return {
|
|
248
|
+
content: customColorText(
|
|
249
|
+
t('text_notification_content_member_leave_unit'),
|
|
250
|
+
arrParams
|
|
251
|
+
),
|
|
252
|
+
redirect: () => null,
|
|
253
|
+
iconContent: (
|
|
254
|
+
<IconComponent icon={'home'} style={styles.backgroundSummer} />
|
|
255
|
+
),
|
|
256
|
+
};
|
|
246
257
|
default:
|
|
247
258
|
return {
|
|
248
259
|
content: customColorText(t('this_notification_will_be_updated_soon')),
|
|
@@ -8,11 +8,14 @@ import { axiosGet } from '../../utils/Apis/axios';
|
|
|
8
8
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
9
9
|
import NotificationItem from './components/NotificationItem';
|
|
10
10
|
import WrapHeaderScrollable from '../../commons/Sharing/WrapHeaderScrollable';
|
|
11
|
+
import { watchNotificationData, unwatchNotificationData } from './Monitor';
|
|
12
|
+
import { useSCContextSelector } from '../../context';
|
|
11
13
|
|
|
12
14
|
let page = 1;
|
|
13
15
|
|
|
14
16
|
const Notification = memo(() => {
|
|
15
17
|
const t = useTranslations();
|
|
18
|
+
const user = useSCContextSelector((state) => state?.auth?.account?.user);
|
|
16
19
|
const [notifications, setNotifications] = useState([]);
|
|
17
20
|
const [maxPageNotification, setMaxPageNotification] = useState(1);
|
|
18
21
|
const rightComponent = useMemo(
|
|
@@ -66,6 +69,11 @@ const Notification = memo(() => {
|
|
|
66
69
|
}
|
|
67
70
|
}, []);
|
|
68
71
|
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
watchNotificationData(user, onRefresh);
|
|
74
|
+
return () => unwatchNotificationData(user);
|
|
75
|
+
}, [user, onRefresh]);
|
|
76
|
+
|
|
69
77
|
return (
|
|
70
78
|
<View style={styles.wrap}>
|
|
71
79
|
<WrapHeaderScrollable
|
|
@@ -18,7 +18,7 @@ import { lgThinqConnect } from '../../iot/RemoteControl/LG';
|
|
|
18
18
|
import ShortDetailSubUnit from '../../commons/SubUnit/ShortDetail';
|
|
19
19
|
import NavBar from '../../commons/NavBar';
|
|
20
20
|
import WrapParallaxScrollView from '../../commons/WrapParallaxScrollView';
|
|
21
|
-
import { SCContext } from '../../context';
|
|
21
|
+
import { SCContext, useSCContextSelector } from '../../context';
|
|
22
22
|
import { Action } from '../../context/actionType';
|
|
23
23
|
import CameraDevice from '../../commons/CameraDevice';
|
|
24
24
|
import { ModalFullVideo } from '../../commons/Modal';
|
|
@@ -43,6 +43,9 @@ const UnitDetail = ({ route }) => {
|
|
|
43
43
|
const isFocused = useIsFocused();
|
|
44
44
|
const { stateData, setAction } = useContext(SCContext);
|
|
45
45
|
const { navigate } = useNavigation();
|
|
46
|
+
const isLavidaSource = useSCContextSelector(
|
|
47
|
+
(state) => state.app.isLavidaSource
|
|
48
|
+
);
|
|
46
49
|
|
|
47
50
|
const [unit, setUnit] = useState(unitData || { id: unitId });
|
|
48
51
|
const [appState, setAppState] = useState(AppState.currentState);
|
|
@@ -302,12 +305,12 @@ const UnitDetail = ({ route }) => {
|
|
|
302
305
|
};
|
|
303
306
|
|
|
304
307
|
const onBack = useCallback(() => {
|
|
305
|
-
navigate(routeName);
|
|
306
|
-
}, [navigate, routeName]);
|
|
308
|
+
navigate(isLavidaSource ? Routes.SmartHomeDashboard : routeName);
|
|
309
|
+
}, [navigate, routeName, isLavidaSource]);
|
|
307
310
|
|
|
308
311
|
const Dashboard = useCallback(() => {
|
|
309
|
-
navigate(Routes.Dashboard);
|
|
310
|
-
}, [navigate]);
|
|
312
|
+
navigate(isLavidaSource ? Routes.SmartHomeDashboard : Routes.Dashboard);
|
|
313
|
+
}, [isLavidaSource, navigate]);
|
|
311
314
|
|
|
312
315
|
return (
|
|
313
316
|
<WrapParallaxScrollView
|
|
@@ -73,8 +73,8 @@ const ManageUnit = ({ route }) => {
|
|
|
73
73
|
const [showImagePicker, setShowImagePicker] = useState(false);
|
|
74
74
|
|
|
75
75
|
const updateUnit = useCallback(
|
|
76
|
-
async (headers) => {
|
|
77
|
-
const formData = createFormData(
|
|
76
|
+
async (bodyData, headers) => {
|
|
77
|
+
const formData = createFormData(bodyData, ['background']);
|
|
78
78
|
|
|
79
79
|
const { success, data } = await axiosPatch(
|
|
80
80
|
API.UNIT.MANAGE_UNIT(unit.id),
|
|
@@ -86,7 +86,7 @@ const ManageUnit = ({ route }) => {
|
|
|
86
86
|
ToastBottomHelper.success(t('unit_updated_successfully'));
|
|
87
87
|
}
|
|
88
88
|
},
|
|
89
|
-
[unit.id, t
|
|
89
|
+
[unit.id, t]
|
|
90
90
|
);
|
|
91
91
|
|
|
92
92
|
const updateLocation = useCallback(
|
|
@@ -116,9 +116,12 @@ const ManageUnit = ({ route }) => {
|
|
|
116
116
|
|
|
117
117
|
useEffect(() => {
|
|
118
118
|
if (imageUrl) {
|
|
119
|
-
updateUnit(
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
updateUnit(
|
|
120
|
+
{ background: imageUrl },
|
|
121
|
+
{
|
|
122
|
+
headers: { 'Content-Type': 'multipart/form-data' },
|
|
123
|
+
}
|
|
124
|
+
);
|
|
122
125
|
}
|
|
123
126
|
}, [imageUrl, updateUnit]);
|
|
124
127
|
|
|
@@ -51,12 +51,14 @@ const MyUnitDevice = ({ sensor, unit }) => {
|
|
|
51
51
|
|
|
52
52
|
const styles = StyleSheet.create({
|
|
53
53
|
item: {
|
|
54
|
-
height:
|
|
54
|
+
height: 'auto',
|
|
55
55
|
flexDirection: 'row',
|
|
56
56
|
justifyContent: 'space-between',
|
|
57
57
|
alignItems: 'center',
|
|
58
58
|
borderBottomColor: Colors.Gray4,
|
|
59
59
|
borderBottomWidth: 1,
|
|
60
|
+
paddingTop: 5,
|
|
61
|
+
paddingBottom: 5,
|
|
60
62
|
},
|
|
61
63
|
iconCircle: {
|
|
62
64
|
width: 32,
|
|
@@ -89,6 +91,7 @@ const styles = StyleSheet.create({
|
|
|
89
91
|
height: 32,
|
|
90
92
|
},
|
|
91
93
|
marginTop3: {
|
|
94
|
+
flex: 1,
|
|
92
95
|
marginTop: 3,
|
|
93
96
|
},
|
|
94
97
|
});
|
|
@@ -196,7 +196,7 @@
|
|
|
196
196
|
"text_poor_level": "Poor",
|
|
197
197
|
"text_very_poor_level": "Very poor",
|
|
198
198
|
"text_clo_low_range": "< 0.2 mg/l",
|
|
199
|
-
"text_clo_good_range": "
|
|
199
|
+
"text_clo_good_range": "0.2 - 0.5 mg/l",
|
|
200
200
|
"text_clo_high_range": "> 0.5 mg/l",
|
|
201
201
|
"turbidity_guide": "Water Turbidity Guide",
|
|
202
202
|
"what_is_turbidity": "What is Water Turbidity?",
|
|
@@ -671,6 +671,7 @@
|
|
|
671
671
|
"text_notification_content_remove_unit_to_owner": "Unit **%{unit_name}** has been removed successfully.",
|
|
672
672
|
"text_notification_content_remove_unit_to_member": "Unit **%{unit_name}** has been removed by **%{unit_owner_name}**. You cannot access to this unit anymore.",
|
|
673
673
|
"text_notification_content_remove_member": "You were remove from **%{unit_name}** by **%{unit_owner_name}**. You cannot access to this unit anymore.",
|
|
674
|
+
"text_notification_content_member_leave_unit": "**%{member_name}** has left **%{unit_name}**.",
|
|
674
675
|
"this_spot_does_not_exsit": "This spot does not exist",
|
|
675
676
|
"please_scan_again_or_contact_the_parking_manager": "Please scan again or contact the parking manager",
|
|
676
677
|
"this_spot_does_not_support_to_scan": "This spot does not support to scan",
|
|
@@ -750,6 +751,7 @@
|
|
|
750
751
|
"edit_actions_list": "Edit Actions List",
|
|
751
752
|
"des_edit_actions_list": "Hold and hover to rearrange actions order",
|
|
752
753
|
"please_add_your_phone_number_and_chip_name": "Please add your phone number and chip name",
|
|
754
|
+
"Please_add_gateway_name" : "Please add gateway name",
|
|
753
755
|
"phone_number_of_data_sim": "Phone number of data sim",
|
|
754
756
|
"select_a_sub_unit": "Select a sub-unit that you want to add this gateway",
|
|
755
757
|
"all_camera": "All Cameras",
|
|
@@ -232,7 +232,7 @@
|
|
|
232
232
|
"text_poor_level": "Kém",
|
|
233
233
|
"text_very_poor_level": "Rất kém",
|
|
234
234
|
"text_clo_low_range": "< 0.2 mg/l",
|
|
235
|
-
"text_clo_good_range": "
|
|
235
|
+
"text_clo_good_range": "0.2 - 0.5 mg/l",
|
|
236
236
|
"text_clo_high_range": "> 0.5 mg/l",
|
|
237
237
|
"turbidity_guide": "Độ đục",
|
|
238
238
|
"what_is_turbidity": "Độ đục của nước là gì?",
|
|
@@ -679,6 +679,7 @@
|
|
|
679
679
|
"text_notification_content_remove_unit_to_owner": "Địa điểm **%{unit_name}** vừa được xoá thành công.",
|
|
680
680
|
"text_notification_content_remove_unit_to_member": "Địa điểm **%{unit_name}** vừa được xoá bởi **%{unit_owner_name}**. Bạn không thể truy cập vào địa điểm này được nữa.",
|
|
681
681
|
"text_notification_content_remove_member": "Bạn vừa được xoá khỏi **%{unit_name}** bởi **%{unit_owner_name}**. Bạn không thể truy cập vào địa điểm này được nữa.",
|
|
682
|
+
"text_notification_content_member_leave_unit": "**%{member_name}** vừa rời khỏi **%{unit_name}**.",
|
|
682
683
|
"this_spot_does_not_exsit": "Vị trí đỗ này không tồn tại",
|
|
683
684
|
"please_scan_again_or_contact_the_parking_manager": "Vui lòng quét lại hoặc liên hệ với người quản lý bãi đậu xe",
|
|
684
685
|
"this_spot_does_not_support_to_scan": "Vị trí đỗ này không hỗ trợ quét",
|
|
@@ -754,6 +755,7 @@
|
|
|
754
755
|
"modbus_fail": "Modbus failrate",
|
|
755
756
|
"rssi_node": "RSSI Node",
|
|
756
757
|
"please_add_your_phone_number_and_chip_name": "Vui lòng thêm số điện thoại và tên chip của bạn",
|
|
758
|
+
"Please_add_gateway_name" : "Vui lòng thêm tên gateway",
|
|
757
759
|
"phone_number_of_data_sim": "Số điện thoại của dữ liệu sim",
|
|
758
760
|
"select_a_sub_unit": "Lựa chọn một khu vực mà bạn muốn thêm gateway",
|
|
759
761
|
"all_camera": "All Cameras",
|