@eohjsc/react-native-smart-city 0.2.72 → 0.2.76
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/index.js +2 -1
- package/package.json +2 -2
- 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 +24 -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/__test__/TimerActionTemplate.test.js +1 -1
- package/src/commons/ActionGroup/__test__/TimerActionTemplateWithutConfigValue.test.js +1 -1
- package/src/commons/ActionGroup/__test__/index.test.js +3 -3
- package/src/commons/ActionGroup/index.js +3 -0
- package/src/commons/ActionTemplate/__test__/index.test.js +2 -2
- package/src/commons/Automate/__test__/ItemAutomate.test.js +1 -1
- package/src/commons/Dashboard/MyPinnedSharedUnit/__test__/MyPinnedSharedUnit.test.js +1 -1
- package/src/commons/Device/HistoryChart.js +11 -7
- package/src/commons/Device/HorizontalBarChart.js +2 -1
- package/src/commons/Device/ItemDevice.js +17 -2
- package/src/commons/Device/WaterQualitySensor/QualityIndicatorsItem.js +1 -1
- package/src/commons/Device/WindDirection/Compass/Compass.test.js +2 -2
- package/src/commons/Device/__test__/ConnectedViewHeader.test.js +2 -2
- package/src/commons/Device/__test__/DisconnectedView.test.js +5 -5
- package/src/commons/Explore/__test__/HeaderExplore.test.js +1 -1
- package/src/commons/MediaPlayerDetail/__test__/MediaPlayerDetail.test.js +1 -1
- package/src/commons/Modal/__test__/ModalBottom.test.js +2 -2
- package/src/commons/Sharing/__test__/MemberList.test.js +3 -3
- package/src/commons/Sharing/__test__/RowMember.test.js +2 -2
- package/src/commons/SubUnit/Favorites/index.js +32 -1
- package/src/commons/SubUnit/ShortDetail.js +33 -3
- package/src/commons/SubUnit/__test__/Favorites.test.js +1 -0
- package/src/commons/SubUnit/__test__/ShortDetail.test.js +1 -0
- package/src/commons/Today/__test__/Today.test.js +1 -1
- package/src/configs/API.js +4 -0
- package/src/configs/Constants.js +23 -0
- package/src/configs/Images.js +1 -0
- package/src/context/SCContext.tsx +35 -2
- package/src/context/index.ts +6 -1
- package/src/navigations/UnitStack.js +1 -3
- package/src/screens/ActivityLog/__test__/index.test.js +10 -11
- package/src/screens/AddNewAction/Device/__test__/index.test.js +2 -2
- package/src/screens/AddNewDevice/__test__/ConnectingDevices.test.js +1 -1
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +37 -50
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/FirstWarning.test.js +1 -1
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +1 -1
- package/src/screens/AddNewGateway/__test__/ConnectingGateway.test.js +1 -1
- 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/PlayBackCamera/__test__/index.test.js +1 -1
- package/src/screens/Unit/Detail.js +2 -2
- package/src/screens/Unit/ManageUnit.js +9 -6
- package/src/screens/Unit/__test__/Detail.test.js +7 -1
- package/src/screens/Unit/components/MyUnitDevice/index.js +4 -1
- package/src/screens/Unit/components/__test__/Header.test.js +5 -5
- package/src/screens/Unit/components/__test__/MyUnitDevice.test.js +2 -2
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +4 -2
- 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/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
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import React, { useContext, useReducer } from 'react';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
|
+
import Toast from 'react-native-toast-message';
|
|
2
4
|
|
|
3
5
|
import {
|
|
4
6
|
ActionDataMap,
|
|
@@ -10,6 +12,18 @@ import {
|
|
|
10
12
|
import { initialState, Action, ContextData, reducer } from './reducer';
|
|
11
13
|
import { setConfigGlobalState } from '../iot/states.js';
|
|
12
14
|
import { setAxiosDefaultLanguage } from '../utils/Utils';
|
|
15
|
+
import { Alert } from '../commons';
|
|
16
|
+
import { Colors } from '../configs';
|
|
17
|
+
import Text from '../commons/Text';
|
|
18
|
+
|
|
19
|
+
const toastConfig = {
|
|
20
|
+
// only for error for now
|
|
21
|
+
error: (internalState) => (
|
|
22
|
+
<View style={styles.toastContainer}>
|
|
23
|
+
<Text style={styles.textWhite}>{internalState.text1}</Text>
|
|
24
|
+
</View>
|
|
25
|
+
),
|
|
26
|
+
};
|
|
13
27
|
|
|
14
28
|
type SCContextType = {
|
|
15
29
|
stateData: ContextData;
|
|
@@ -68,15 +82,34 @@ export const SCProvider = ({ children, initState = initialState }) => {
|
|
|
68
82
|
return (
|
|
69
83
|
<SCContext.Provider value={providerValue}>
|
|
70
84
|
{children}
|
|
71
|
-
|
|
72
|
-
<Toast config={toastConfig} ref={(ref) => Toast.setRef(ref)} /> */}
|
|
85
|
+
<Alert ref={(ref) => Alert.setRef(ref)} />
|
|
73
86
|
</SCContext.Provider>
|
|
74
87
|
);
|
|
75
88
|
};
|
|
76
89
|
|
|
90
|
+
export const SCWrapper = (props) => {
|
|
91
|
+
return (
|
|
92
|
+
<>
|
|
93
|
+
<SCProvider {...props} />
|
|
94
|
+
<Toast config={toastConfig} ref={(ref) => Toast.setRef(ref)} />
|
|
95
|
+
</>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
77
99
|
export const useSCContextSelector = (
|
|
78
100
|
selector: (contextData: ContextData) => unknown
|
|
79
101
|
) => {
|
|
80
102
|
const { stateData } = useContext(SCContext);
|
|
81
103
|
return selector(stateData);
|
|
82
104
|
};
|
|
105
|
+
|
|
106
|
+
const styles = StyleSheet.create({
|
|
107
|
+
toastContainer: {
|
|
108
|
+
borderRadius: 5,
|
|
109
|
+
padding: 10,
|
|
110
|
+
backgroundColor: Colors.Black,
|
|
111
|
+
},
|
|
112
|
+
textWhite: {
|
|
113
|
+
color: Colors.White,
|
|
114
|
+
},
|
|
115
|
+
});
|
package/src/context/index.ts
CHANGED
|
@@ -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
|
|
@@ -101,50 +101,49 @@ describe('Test Activity log', () => {
|
|
|
101
101
|
});
|
|
102
102
|
const instance = tree.root;
|
|
103
103
|
const dateTimeRangeChange = instance.findByType(DateTimeRangeChange);
|
|
104
|
-
const filterPopup = instance.
|
|
104
|
+
const filterPopup = instance.findAllByType(Modal);
|
|
105
105
|
const datePicker = instance.findByType(DateTimePickerModal);
|
|
106
106
|
const filterButton = instance.find(
|
|
107
107
|
(el) =>
|
|
108
108
|
el.props.testID === TESTID.FILTER_BUTTON && el.type === TouchableOpacity
|
|
109
109
|
);
|
|
110
110
|
// open popup
|
|
111
|
-
expect(filterPopup.props.isVisible).toBeFalsy();
|
|
111
|
+
expect(filterPopup[0].props.isVisible).toBeFalsy();
|
|
112
112
|
await act(async () => {
|
|
113
113
|
await filterButton.props.onPress();
|
|
114
114
|
});
|
|
115
|
-
expect(filterPopup.props.isVisible).toBeTruthy();
|
|
115
|
+
expect(filterPopup[0].props.isVisible).toBeTruthy();
|
|
116
116
|
// pick start date
|
|
117
117
|
await act(async () => {
|
|
118
118
|
await dateTimeRangeChange.props.onStart();
|
|
119
|
-
await filterPopup.props.onModalHide();
|
|
119
|
+
await filterPopup[0].props.onModalHide();
|
|
120
120
|
});
|
|
121
|
-
expect(filterPopup.props.isVisible).toBeFalsy();
|
|
122
|
-
expect(datePicker.props.isVisible).toBeTruthy();
|
|
121
|
+
expect(filterPopup[0].props.isVisible).toBeFalsy();
|
|
123
122
|
// cancel
|
|
124
123
|
await act(async () => {
|
|
125
124
|
await datePicker.props.onCancel();
|
|
126
125
|
await datePicker.props.onHide();
|
|
127
126
|
});
|
|
128
|
-
expect(filterPopup.props.isVisible).toBeTruthy();
|
|
127
|
+
expect(filterPopup[0].props.isVisible).toBeTruthy();
|
|
129
128
|
expect(datePicker.props.isVisible).toBeFalsy();
|
|
130
129
|
// open popup
|
|
131
130
|
await act(async () => {
|
|
132
131
|
await filterButton.props.onPress();
|
|
133
132
|
});
|
|
134
|
-
expect(filterPopup.props.isVisible).toBeTruthy();
|
|
133
|
+
expect(filterPopup[0].props.isVisible).toBeTruthy();
|
|
135
134
|
// pick end date
|
|
136
135
|
await act(async () => {
|
|
137
136
|
await dateTimeRangeChange.props.onEnd();
|
|
138
|
-
await filterPopup.props.onModalHide();
|
|
137
|
+
await filterPopup[0].props.onModalHide();
|
|
139
138
|
});
|
|
140
|
-
expect(filterPopup.props.isVisible).toBeFalsy();
|
|
139
|
+
expect(filterPopup[0].props.isVisible).toBeFalsy();
|
|
141
140
|
expect(datePicker.props.isVisible).toBeTruthy();
|
|
142
141
|
// confirm
|
|
143
142
|
await act(async () => {
|
|
144
143
|
await datePicker.props.onConfirm();
|
|
145
144
|
await datePicker.props.onHide();
|
|
146
145
|
});
|
|
147
|
-
expect(filterPopup.props.isVisible).toBeTruthy();
|
|
146
|
+
expect(filterPopup[0].props.isVisible).toBeTruthy();
|
|
148
147
|
expect(datePicker.props.isVisible).toBeFalsy();
|
|
149
148
|
});
|
|
150
149
|
});
|
|
@@ -31,11 +31,11 @@ describe('Test SelectDevice', () => {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
const instance = tree.root;
|
|
34
|
-
const touchableWithoutFeedback = instance.
|
|
34
|
+
const touchableWithoutFeedback = instance.findAllByType(
|
|
35
35
|
TouchableWithoutFeedback
|
|
36
36
|
);
|
|
37
37
|
act(() => {
|
|
38
|
-
touchableWithoutFeedback.props.onPress();
|
|
38
|
+
touchableWithoutFeedback[0].props.onPress();
|
|
39
39
|
});
|
|
40
40
|
expect(mockFuntion).toHaveBeenCalledWith(sensor);
|
|
41
41
|
});
|
|
@@ -53,7 +53,7 @@ describe('Test ConnectingDevices', () => {
|
|
|
53
53
|
});
|
|
54
54
|
const instance = tree.root;
|
|
55
55
|
const texts = instance.findAllByType(Text);
|
|
56
|
-
expect(texts).toHaveLength(
|
|
56
|
+
expect(texts).toHaveLength(4);
|
|
57
57
|
expect(texts[0].props.children).toEqual(
|
|
58
58
|
getTranslate('en', 'connecting_your_device')
|
|
59
59
|
);
|
|
@@ -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
|
};
|
|
@@ -37,7 +37,7 @@ describe('Test FirstWarning', () => {
|
|
|
37
37
|
});
|
|
38
38
|
const instance = tree.root;
|
|
39
39
|
const texts = instance.findAllByType(Text);
|
|
40
|
-
expect(texts).toHaveLength(
|
|
40
|
+
expect(texts).toHaveLength(10);
|
|
41
41
|
expect(texts[1].props.children).toEqual(
|
|
42
42
|
getTranslate('en', 'warning_beta_test_feature')
|
|
43
43
|
);
|
|
@@ -28,7 +28,7 @@ describe('Test GatewayWifiList', () => {
|
|
|
28
28
|
});
|
|
29
29
|
const instance = tree.root;
|
|
30
30
|
const texts = instance.findAllByType(Text);
|
|
31
|
-
expect(texts).toHaveLength(
|
|
31
|
+
expect(texts).toHaveLength(10);
|
|
32
32
|
expect(texts[1].props.children).toEqual(getTranslate('en', 'set_network'));
|
|
33
33
|
expect(texts[3].props.children).toEqual('eoh@io');
|
|
34
34
|
});
|
|
@@ -53,7 +53,7 @@ describe('Test ConnectingGateway', () => {
|
|
|
53
53
|
});
|
|
54
54
|
const instance = tree.root;
|
|
55
55
|
const texts = instance.findAllByType(Text);
|
|
56
|
-
expect(texts).toHaveLength(
|
|
56
|
+
expect(texts).toHaveLength(8);
|
|
57
57
|
expect(texts[0].props.children).toEqual(
|
|
58
58
|
getTranslate('en', 'connecting_your_gateway')
|
|
59
59
|
);
|
|
@@ -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
|
|
@@ -305,8 +305,8 @@ const UnitDetail = ({ route }) => {
|
|
|
305
305
|
};
|
|
306
306
|
|
|
307
307
|
const onBack = useCallback(() => {
|
|
308
|
-
navigate(routeName);
|
|
309
|
-
}, [navigate, routeName]);
|
|
308
|
+
navigate(isLavidaSource ? Routes.SmartHomeDashboard : routeName);
|
|
309
|
+
}, [navigate, routeName, isLavidaSource]);
|
|
310
310
|
|
|
311
311
|
const Dashboard = useCallback(() => {
|
|
312
312
|
navigate(isLavidaSource ? Routes.SmartHomeDashboard : Routes.Dashboard);
|
|
@@ -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
|
|
|
@@ -74,6 +74,7 @@ describe('Test UnitDetail', () => {
|
|
|
74
74
|
|
|
75
75
|
const detailUnitApiUrl = API.UNIT.UNIT_DETAIL(1);
|
|
76
76
|
const summaryUnitApiUrl = API.UNIT.UNIT_SUMMARY(1);
|
|
77
|
+
const sensorStatusApiUrl = API.SENSOR.STATUS();
|
|
77
78
|
|
|
78
79
|
let tree;
|
|
79
80
|
|
|
@@ -318,6 +319,11 @@ describe('Test UnitDetail', () => {
|
|
|
318
319
|
status: 200,
|
|
319
320
|
data: [],
|
|
320
321
|
};
|
|
322
|
+
} else if (url === sensorStatusApiUrl) {
|
|
323
|
+
return {
|
|
324
|
+
status: 200,
|
|
325
|
+
data: [],
|
|
326
|
+
};
|
|
321
327
|
}
|
|
322
328
|
|
|
323
329
|
return {
|
|
@@ -396,7 +402,7 @@ describe('Test UnitDetail', () => {
|
|
|
396
402
|
);
|
|
397
403
|
});
|
|
398
404
|
await act(async () => {
|
|
399
|
-
await jest.
|
|
405
|
+
await jest.runOnlyPendingTimers();
|
|
400
406
|
});
|
|
401
407
|
// TODO Called but can not expect
|
|
402
408
|
// expect(axios.get).toHaveBeenCalledWith(API.IOT.LG.DEVICE_STATUS(2));
|
|
@@ -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
|
});
|
|
@@ -22,11 +22,11 @@ describe('Test Header', () => {
|
|
|
22
22
|
tree = renderer.create(wrapComponent());
|
|
23
23
|
});
|
|
24
24
|
const instance = tree.root;
|
|
25
|
-
const modal = instance.
|
|
25
|
+
const modal = instance.findAllByType(Modal);
|
|
26
26
|
act(() => {
|
|
27
|
-
modal.props.onBackButtonPress();
|
|
27
|
+
modal[0].props.onBackButtonPress();
|
|
28
28
|
});
|
|
29
|
-
expect(modal.props.isVisible).toBe(false);
|
|
29
|
+
expect(modal[0].props.isVisible).toBe(false);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
test('test onItemClick', () => {
|
|
@@ -34,12 +34,12 @@ describe('Test Header', () => {
|
|
|
34
34
|
tree = renderer.create(wrapComponent());
|
|
35
35
|
});
|
|
36
36
|
const instance = tree.root;
|
|
37
|
-
const modal = instance.
|
|
37
|
+
const modal = instance.findAllByType(Modal);
|
|
38
38
|
const imageButton = instance.findByType(ImageButton);
|
|
39
39
|
act(() => {
|
|
40
40
|
imageButton.props.onPress(Routes.Sharing);
|
|
41
41
|
});
|
|
42
|
-
expect(modal.props.isVisible).toBe(false);
|
|
42
|
+
expect(modal[0].props.isVisible).toBe(false);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
test('test Popover Close Menu', () => {
|
|
@@ -22,7 +22,7 @@ describe('Test MyUnitDevice', () => {
|
|
|
22
22
|
});
|
|
23
23
|
const instance = tree.root;
|
|
24
24
|
const Views = instance.findAllByType(View);
|
|
25
|
-
expect(Views).toHaveLength(
|
|
25
|
+
expect(Views).toHaveLength(10);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
it('Test render without status', async () => {
|
|
@@ -31,6 +31,6 @@ describe('Test MyUnitDevice', () => {
|
|
|
31
31
|
});
|
|
32
32
|
const instance = tree.root;
|
|
33
33
|
const Views = instance.findAllByType(View);
|
|
34
|
-
expect(Views).toHaveLength(
|
|
34
|
+
expect(Views).toHaveLength(10);
|
|
35
35
|
});
|
|
36
36
|
});
|
|
@@ -91,8 +91,10 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
91
91
|
let params = new URLSearchParams();
|
|
92
92
|
params.append('config', listConfigs.total_power);
|
|
93
93
|
params.append('group_by', groupBy);
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
if (groupBy === 'date') {
|
|
95
|
+
params.append('date_from', moment(startDate).format('YYYY-MM-DD'));
|
|
96
|
+
params.append('date_to', moment(endDate).format('YYYY-MM-DD'));
|
|
97
|
+
}
|
|
96
98
|
const { success, data } = await axiosGet(
|
|
97
99
|
API.POWER_CONSUME.DISPLAY_HISTORY(),
|
|
98
100
|
{
|
|
@@ -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",
|