@eohjsc/react-native-smart-city 0.2.94 → 0.2.97
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 +16 -4
- package/src/Images/Common/member.svg +4 -0
- package/src/Images/Common/owner.svg +3 -0
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +5 -1
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +5 -1
- package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +2 -2
- package/src/commons/Connecting/__test__/Connecting.test.js +23 -0
- package/src/commons/Connecting/index.js +67 -0
- package/src/commons/Connecting/styles.js +28 -0
- package/src/commons/ConnectingProcess/index.js +3 -54
- package/src/commons/Device/HistoryChart.js +2 -2
- package/src/commons/MenuActionMore/index.js +10 -16
- package/src/commons/PreventAccess/index.js +59 -0
- package/src/commons/PreventAccess/styles.js +33 -0
- package/src/commons/Sharing/MemberList.js +5 -10
- package/src/commons/Sharing/RowMember.js +128 -38
- package/src/commons/Sharing/__test__/MemberList.test.js +3 -3
- package/src/commons/Sharing/__test__/RowMember.test.js +4 -4
- package/src/configs/API.js +12 -2
- package/src/configs/Constants.js +10 -0
- package/src/hooks/Common/useSensorsStatus.js +33 -23
- package/src/iot/RemoteControl/GoogleHome.js +24 -11
- package/src/iot/RemoteControl/__test__/GoogleHome.test.js +32 -0
- package/src/navigations/UnitStack.js +16 -0
- package/src/screens/AddNewAction/SelectSensorDevices.js +6 -1
- package/src/screens/AddNewAction/__test__/SelectSensorDevices.test.js +34 -92
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +12 -3
- package/src/screens/AddNewGateway/PlugAndPlay/FirstWarning.js +5 -1
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +9 -1
- package/src/screens/Device/detail.js +16 -3
- package/src/screens/EditActionsList/Styles/indexStyles.js +1 -0
- package/src/screens/EmergencyContacts/EmergencyContactsList.js +1 -1
- package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +29 -11
- package/src/screens/EmergencyContacts/__test__/EmergencyContactList.test.js +1 -0
- package/src/screens/EmergencyContacts/__test__/EmergencyContactsSelectContacts.test.js +56 -0
- package/src/screens/EnterPassword/__test__/EnterPassword.test.js +124 -0
- package/src/screens/EnterPassword/index.js +84 -0
- package/src/screens/EnterPassword/styles.js +36 -0
- package/src/screens/Sharing/Components/ItemChangeRole.js +43 -0
- package/src/screens/Sharing/Components/SensorItem.js +7 -1
- package/src/screens/Sharing/Components/Styles/ItemChangeRoleStyles.js +35 -0
- package/src/screens/Sharing/Components/__test__/ItemChangeRole.test.js +37 -0
- package/src/screens/Sharing/Components/__test__/SensorItem.test.js +53 -0
- package/src/screens/Sharing/InfoMemberUnit.js +274 -0
- package/src/screens/Sharing/MemberList.js +50 -53
- package/src/screens/Sharing/SelectPermission.js +93 -12
- package/src/screens/Sharing/Styles/inforMemberUnitStyles.js +92 -0
- package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +121 -0
- package/src/screens/Sharing/__test__/MemberList.test.js +9 -24
- package/src/screens/Sharing/__test__/SelectPermission.test.js +53 -0
- package/src/screens/Sharing/hooks/index.js +76 -32
- package/src/screens/Unit/Detail.js +28 -13
- package/src/screens/Unit/ManageUnit.js +5 -5
- package/src/screens/Unit/ManageUnitStyles.js +1 -0
- package/src/screens/Unit/__test__/Detail.test.js +25 -5
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +1 -1
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +1 -1
- package/src/utils/I18n/translations/en.json +16 -1
- package/src/utils/I18n/translations/vi.json +14 -1
- package/src/utils/Route/index.js +2 -0
- package/src/utils/Utils.js +21 -0
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.2.
|
|
4
|
+
"version": "0.2.97",
|
|
5
5
|
"description": "TODO",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"files": [
|
|
@@ -81,10 +81,11 @@
|
|
|
81
81
|
"eslint-plugin-react": "^7.21.5",
|
|
82
82
|
"eslint-plugin-react-native": "^3.10.0",
|
|
83
83
|
"factory-girl": "^5.0.4",
|
|
84
|
+
"husky": "^8.0.1",
|
|
84
85
|
"jest": "^26.6.3",
|
|
85
86
|
"jest-circus": "^26.6.3",
|
|
86
87
|
"jetifier": "^1.6.6",
|
|
87
|
-
"lint-staged": "^
|
|
88
|
+
"lint-staged": "^12.4.1",
|
|
88
89
|
"metro-react-native-babel-preset": "^0.66.2",
|
|
89
90
|
"node-html-parser": "^2.0.2",
|
|
90
91
|
"react": "17.0.2",
|
|
@@ -97,7 +98,8 @@
|
|
|
97
98
|
"dependencies": {
|
|
98
99
|
"@ant-design/icons-react-native": "^2.2.1",
|
|
99
100
|
"@ant-design/react-native": "^4.0.5",
|
|
100
|
-
"@
|
|
101
|
+
"@babel/helper-environment-visitor": "^7.16.7",
|
|
102
|
+
"@eohjsc/highcharts": "^1.0.8",
|
|
101
103
|
"@eohjsc/react-native-keyboard-aware-scroll-view": "^0.9.5",
|
|
102
104
|
"@formatjs/intl-getcanonicallocales": "^1.4.5",
|
|
103
105
|
"@formatjs/intl-numberformat": "^5.6.2",
|
|
@@ -209,5 +211,15 @@
|
|
|
209
211
|
"bugs": {
|
|
210
212
|
"url": "https://github.com/github_account/react-native-smart-city/issues"
|
|
211
213
|
},
|
|
212
|
-
"homepage": "https://github.com/github_account/react-native-smart-city#readme"
|
|
214
|
+
"homepage": "https://github.com/github_account/react-native-smart-city#readme",
|
|
215
|
+
"husky": {
|
|
216
|
+
"hooks": {
|
|
217
|
+
"pre-commit": "lint-staged"
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"lint-staged": {
|
|
221
|
+
"*.{js, ts}": [
|
|
222
|
+
"yarn lint"
|
|
223
|
+
]
|
|
224
|
+
}
|
|
213
225
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M12 6C13.1046 6 14 5.10457 14 4C14 2.89543 13.1046 2 12 2C10.8954 2 10 2.89543 10 4C10 5.10457 10.8954 6 12 6Z" fill="#262626"/>
|
|
3
|
+
<path d="M15.89 8.11C15.5 7.72 14.83 7 13.53 7C13.32 7 12.11 7 10.99 7C8.24 6.99 6 4.75 6 2H4C4 5.16 6.11 7.84 9 8.71V22H11V16H13V22H15V10.05L18.95 14L20.36 12.59L15.89 8.11Z" fill="#262626"/>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.753 9.0184C21.753 9.66253 21.2308 10.1847 20.5867 10.1847C20.4682 10.1847 20.3559 10.1617 20.2483 10.1291L18.5961 15.808H5.15687L3.50472 10.1291C3.39711 10.1617 3.28483 10.1847 3.16633 10.1847C2.52221 10.1847 2 9.66253 2 9.0184C2 8.37428 2.52221 7.85207 3.16633 7.85207C3.81046 7.85207 4.33266 8.37428 4.33266 9.0184C4.33266 9.24732 4.26424 9.45912 4.15041 9.6392L7.88142 12.1939L8.36195 7.3196C7.78003 7.25367 7.32625 6.76567 7.32625 6.16633C7.32625 5.52221 7.84846 5 8.49258 5C9.13671 5 9.65892 5.52221 9.65892 6.16633C9.65892 6.59305 9.42752 6.96224 9.08539 7.16565L11.8765 11.7398L14.6863 7.13517C14.3743 6.92585 14.1687 6.57035 14.1687 6.16633C14.1687 5.52221 14.6909 5 15.3351 5C15.9792 5 16.5014 5.52221 16.5014 6.16633C16.5014 6.79118 16.0091 7.2969 15.392 7.32707L15.8716 12.1939L19.6026 9.6392C19.4888 9.45912 19.4203 9.24732 19.4203 9.0184C19.4203 8.37428 19.9425 7.85207 20.5867 7.85207C21.2308 7.85207 21.753 8.37428 21.753 9.0184ZM5.15782 16.6384H18.5962V18.712H5.15782V16.6384Z" fill="#262626"/>
|
|
3
|
+
</svg>
|
|
@@ -39,7 +39,11 @@ const NumberUpDownActionTemplate = ({ actionGroup, doAction, sensor }) => {
|
|
|
39
39
|
|
|
40
40
|
const doActionAndWatchConfig = useCallback(
|
|
41
41
|
(actionData, actionValue, actionName) => {
|
|
42
|
-
doAction(
|
|
42
|
+
doAction(
|
|
43
|
+
actionData,
|
|
44
|
+
JSON.stringify({ temperature: actionValue }),
|
|
45
|
+
actionName
|
|
46
|
+
);
|
|
43
47
|
if (!sensor?.is_managed_by_backend) {
|
|
44
48
|
return;
|
|
45
49
|
}
|
|
@@ -61,7 +61,11 @@ 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(
|
|
64
|
+
doAction(
|
|
65
|
+
action_data,
|
|
66
|
+
JSON.stringify({ level: value, key_code: newOption?.value_int }),
|
|
67
|
+
actionName
|
|
68
|
+
);
|
|
65
69
|
if (sensor?.is_managed_by_backend) {
|
|
66
70
|
configuration.config && watchMultiConfigs([configuration.config]);
|
|
67
71
|
}
|
|
@@ -152,7 +152,7 @@ describe('Test OptionsDropdownActionTemplate', () => {
|
|
|
152
152
|
|
|
153
153
|
expect(mockDoAction).toHaveBeenCalledWith(
|
|
154
154
|
action_data,
|
|
155
|
-
1,
|
|
155
|
+
JSON.stringify({ level: 1, key_code: 1 }),
|
|
156
156
|
'Sensor name fan speed 1'
|
|
157
157
|
);
|
|
158
158
|
is_managed_by_backend
|
|
@@ -221,7 +221,7 @@ describe('Test OptionsDropdownActionTemplate', () => {
|
|
|
221
221
|
|
|
222
222
|
expect(mockDoAction).toHaveBeenCalledWith(
|
|
223
223
|
action_data,
|
|
224
|
-
'level-1',
|
|
224
|
+
JSON.stringify({ level: 'level-1', key_code: 1 }),
|
|
225
225
|
'Sensor name fan speed level-1'
|
|
226
226
|
); // doAction with text instead of int
|
|
227
227
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer, { act } from 'react-test-renderer';
|
|
3
|
+
import Connecting from '../index';
|
|
4
|
+
import Text from '../../Text';
|
|
5
|
+
import { SCProvider } from '../../../context';
|
|
6
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
7
|
+
|
|
8
|
+
const wrapComponent = (route) => (
|
|
9
|
+
<SCProvider initState={mockSCStore({})}>
|
|
10
|
+
<Connecting route={route} />
|
|
11
|
+
</SCProvider>
|
|
12
|
+
);
|
|
13
|
+
describe('Test Connecting', () => {
|
|
14
|
+
let tree;
|
|
15
|
+
test('create Connecting', () => {
|
|
16
|
+
act(() => {
|
|
17
|
+
tree = renderer.create(wrapComponent());
|
|
18
|
+
});
|
|
19
|
+
const instance = tree.root;
|
|
20
|
+
const text = instance.findAllByType(Text);
|
|
21
|
+
expect(text).toHaveLength(4);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React, { useEffect, useCallback, useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import * as Progress from 'react-native-progress';
|
|
4
|
+
import Text from '../Text';
|
|
5
|
+
import { Colors, Constants } from '../../configs';
|
|
6
|
+
import styles from './styles';
|
|
7
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
8
|
+
import { HeaderCustom } from '../Header';
|
|
9
|
+
|
|
10
|
+
const Connecting = ({ isLoading, isConnect, isPercentConnect }) => {
|
|
11
|
+
const t = useTranslations();
|
|
12
|
+
const [percent, setPercent] = useState(0);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
processLoading();
|
|
16
|
+
}, [processLoading]);
|
|
17
|
+
|
|
18
|
+
const processLoading = useCallback(() => {
|
|
19
|
+
let interval;
|
|
20
|
+
if (isLoading) {
|
|
21
|
+
interval = setInterval(() => {
|
|
22
|
+
setPercent((prev) => {
|
|
23
|
+
if (prev === 1) {
|
|
24
|
+
clearInterval(interval);
|
|
25
|
+
return 1;
|
|
26
|
+
} else if (prev === 0.8 && isConnect) {
|
|
27
|
+
clearInterval(interval);
|
|
28
|
+
return 0.8;
|
|
29
|
+
} else {
|
|
30
|
+
return prev + 0.2;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}, 180);
|
|
34
|
+
} else {
|
|
35
|
+
clearInterval(interval);
|
|
36
|
+
}
|
|
37
|
+
}, [isConnect, isLoading]);
|
|
38
|
+
return (
|
|
39
|
+
<View style={styles.screen}>
|
|
40
|
+
<HeaderCustom title={t('connect_device')} isShowSeparator />
|
|
41
|
+
<View style={styles.body}>
|
|
42
|
+
<View style={styles.connecting}>
|
|
43
|
+
<Text type="H4" bold>
|
|
44
|
+
{t('connecting')}
|
|
45
|
+
</Text>
|
|
46
|
+
</View>
|
|
47
|
+
<View style={styles.percentLoad}>
|
|
48
|
+
<Progress.Bar
|
|
49
|
+
progress={isPercentConnect || percent}
|
|
50
|
+
animated={true}
|
|
51
|
+
color={Colors.Primary}
|
|
52
|
+
indeterminateAnimationDuration={1000}
|
|
53
|
+
height={7}
|
|
54
|
+
width={Constants.width - 80}
|
|
55
|
+
useNativeDriver={true}
|
|
56
|
+
/>
|
|
57
|
+
<Text style={styles.textPercentLoad}>{`${parseInt(
|
|
58
|
+
(isPercentConnect || percent) * 100,
|
|
59
|
+
10
|
|
60
|
+
)}%`}</Text>
|
|
61
|
+
</View>
|
|
62
|
+
</View>
|
|
63
|
+
</View>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default Connecting;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Constants } from '../../configs';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
screen: {
|
|
6
|
+
flex: 1,
|
|
7
|
+
width: '100%',
|
|
8
|
+
},
|
|
9
|
+
body: {
|
|
10
|
+
width: '100%',
|
|
11
|
+
height: Constants.height - 50,
|
|
12
|
+
justifyContent: 'center',
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
},
|
|
15
|
+
connecting: {
|
|
16
|
+
flexDirection: 'row',
|
|
17
|
+
justifyContent: 'center',
|
|
18
|
+
marginBottom: 10,
|
|
19
|
+
},
|
|
20
|
+
percentLoad: {
|
|
21
|
+
flexDirection: 'row',
|
|
22
|
+
justifyContent: 'center',
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
},
|
|
25
|
+
textPercentLoad: {
|
|
26
|
+
marginLeft: 10,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -3,14 +3,14 @@ import { SafeAreaView, View, TouchableOpacity } from 'react-native';
|
|
|
3
3
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
4
4
|
import Routes from '../../utils/Route';
|
|
5
5
|
import { useNavigation } from '@react-navigation/native';
|
|
6
|
-
import * as Progress from 'react-native-progress';
|
|
7
6
|
import ImageSuccessfully from '../../Images/Common/SuccessfullyConnected.svg';
|
|
8
7
|
|
|
9
8
|
import Text from '../Text';
|
|
10
9
|
import { axiosPost } from '../../utils/Apis/axios';
|
|
11
|
-
import { API, Colors
|
|
10
|
+
import { API, Colors } from '../../configs';
|
|
12
11
|
import styles from './styles';
|
|
13
12
|
import DeviceItem from './DeviceItem/DeviceItem';
|
|
13
|
+
import Connecting from '../Connecting';
|
|
14
14
|
import { useSCContextSelector } from '../../context';
|
|
15
15
|
|
|
16
16
|
const ConnectingProcess = ({ route }) => {
|
|
@@ -29,31 +29,9 @@ const ConnectingProcess = ({ route }) => {
|
|
|
29
29
|
wifi_pass,
|
|
30
30
|
chip_id,
|
|
31
31
|
} = route.params;
|
|
32
|
-
const [percent, setPercent] = useState(0);
|
|
33
32
|
const [isLoading, setIsLoading] = useState(true);
|
|
34
33
|
const [sensor, setSensor] = useState(null);
|
|
35
34
|
const user = useSCContextSelector((state) => state?.auth?.account?.user);
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
processLoading();
|
|
38
|
-
}, [processLoading]);
|
|
39
|
-
|
|
40
|
-
const processLoading = useCallback(() => {
|
|
41
|
-
let interval;
|
|
42
|
-
if (isLoading) {
|
|
43
|
-
interval = setInterval(() => {
|
|
44
|
-
setPercent((prev) => {
|
|
45
|
-
if (prev === 1) {
|
|
46
|
-
clearInterval(interval);
|
|
47
|
-
return 1;
|
|
48
|
-
} else {
|
|
49
|
-
return prev + 0.2;
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}, 180);
|
|
53
|
-
} else {
|
|
54
|
-
clearInterval(interval);
|
|
55
|
-
}
|
|
56
|
-
}, [isLoading]);
|
|
57
35
|
|
|
58
36
|
const ConnectingDevice = useCallback(async () => {
|
|
59
37
|
setIsLoading(true);
|
|
@@ -120,35 +98,6 @@ const ConnectingProcess = ({ route }) => {
|
|
|
120
98
|
chip_id,
|
|
121
99
|
]);
|
|
122
100
|
|
|
123
|
-
const Connecting = useCallback(() => {
|
|
124
|
-
return (
|
|
125
|
-
<>
|
|
126
|
-
<View style={styles.progressBar}>
|
|
127
|
-
<View style={styles.connecting}>
|
|
128
|
-
<Text type="H4" bold>
|
|
129
|
-
{t('connecting')}
|
|
130
|
-
</Text>
|
|
131
|
-
</View>
|
|
132
|
-
</View>
|
|
133
|
-
<View style={styles.percentLoad}>
|
|
134
|
-
<Progress.Bar
|
|
135
|
-
progress={percent}
|
|
136
|
-
animated={true}
|
|
137
|
-
color={Colors.Primary}
|
|
138
|
-
indeterminateAnimationDuration={1000}
|
|
139
|
-
height={7}
|
|
140
|
-
width={Constants.width - 80}
|
|
141
|
-
useNativeDriver={true}
|
|
142
|
-
/>
|
|
143
|
-
<Text style={styles.textPercentLoad}>{`${parseInt(
|
|
144
|
-
percent * 100,
|
|
145
|
-
10
|
|
146
|
-
)}%`}</Text>
|
|
147
|
-
</View>
|
|
148
|
-
</>
|
|
149
|
-
);
|
|
150
|
-
}, [percent, t]);
|
|
151
|
-
|
|
152
101
|
const ConnectingSuccess = useCallback(() => {
|
|
153
102
|
return (
|
|
154
103
|
<View style={styles.ConnectingSuccess}>
|
|
@@ -188,7 +137,7 @@ const ConnectingProcess = ({ route }) => {
|
|
|
188
137
|
<Text bold style={styles.connectingText}>
|
|
189
138
|
{t('connect_device')}
|
|
190
139
|
</Text>
|
|
191
|
-
{!!isLoading && <Connecting />}
|
|
140
|
+
{!!isLoading && <Connecting isLoading={isLoading} />}
|
|
192
141
|
{!isLoading && <ConnectingSuccess />}
|
|
193
142
|
</View>
|
|
194
143
|
{!isLoading && (
|
|
@@ -234,7 +234,7 @@ const HistoryChart = memo(
|
|
|
234
234
|
)}
|
|
235
235
|
<DateTimePickerModal
|
|
236
236
|
isVisible={eventPicker.showModalStart}
|
|
237
|
-
date={eventPicker.startTime.
|
|
237
|
+
date={eventPicker.startTime.valueOf()}
|
|
238
238
|
mode={formatType || 'datetime'}
|
|
239
239
|
onConfirm={onConfirmStart}
|
|
240
240
|
onCancel={onCancel}
|
|
@@ -242,7 +242,7 @@ const HistoryChart = memo(
|
|
|
242
242
|
/>
|
|
243
243
|
<DateTimePickerModal
|
|
244
244
|
isVisible={eventPicker.showModalEnd}
|
|
245
|
-
date={eventPicker.endTime.
|
|
245
|
+
date={eventPicker.endTime.valueOf()}
|
|
246
246
|
mode={formatType || 'datetime'}
|
|
247
247
|
onConfirm={onConfirmEnd}
|
|
248
248
|
onCancel={onCancel}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import React, { memo, useCallback, useEffect } from 'react';
|
|
1
|
+
import React, { memo, useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { TouchableOpacity, ScrollView } from 'react-native';
|
|
3
3
|
import Popover from 'react-native-popover-view';
|
|
4
|
-
import debounce from 'lodash.debounce';
|
|
5
4
|
|
|
6
5
|
import styles from './MenuActionMoreStyles';
|
|
7
6
|
import Text from '../Text';
|
|
@@ -20,26 +19,20 @@ const MenuActionMore = memo(
|
|
|
20
19
|
wrapStyle,
|
|
21
20
|
isTextCenter = true,
|
|
22
21
|
}) => {
|
|
22
|
+
const [isDisable, setIsDisable] = useState(false);
|
|
23
23
|
const onPress = useCallback(
|
|
24
|
-
(item, index) => {
|
|
24
|
+
(item, index) => () => {
|
|
25
|
+
setIsDisable(true);
|
|
25
26
|
hideMore && hideMore();
|
|
26
27
|
onItemClick && onItemClick(item, index);
|
|
28
|
+
const timeout = setTimeout(() => {
|
|
29
|
+
setIsDisable(false);
|
|
30
|
+
clearTimeout(timeout);
|
|
31
|
+
}, 500);
|
|
27
32
|
},
|
|
28
33
|
[hideMore, onItemClick]
|
|
29
34
|
);
|
|
30
35
|
|
|
31
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
32
|
-
const debouncedOnPress = useCallback(
|
|
33
|
-
debounce(
|
|
34
|
-
(item, index) => {
|
|
35
|
-
onPress(item, index);
|
|
36
|
-
},
|
|
37
|
-
500,
|
|
38
|
-
{ leading: true, trailing: false }
|
|
39
|
-
),
|
|
40
|
-
[]
|
|
41
|
-
);
|
|
42
|
-
|
|
43
36
|
useEffect(() => {
|
|
44
37
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
45
38
|
useStatusBarPreview(
|
|
@@ -65,9 +58,10 @@ const MenuActionMore = memo(
|
|
|
65
58
|
styles.menuWrapper,
|
|
66
59
|
isTextCenter ? styles.modalHeaderCenter : styles.modalHeader,
|
|
67
60
|
]}
|
|
68
|
-
onPress={(
|
|
61
|
+
onPress={onPress(item, index)}
|
|
69
62
|
key={index}
|
|
70
63
|
testID={TESTID.TOUCHABLE_ACTION_ADD_MORE}
|
|
64
|
+
disabled={isDisable}
|
|
71
65
|
>
|
|
72
66
|
<Text style={styles.modalHeaderText}>{item.text}</Text>
|
|
73
67
|
</TouchableOpacity>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { memo, useCallback, useMemo } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import Modal from 'react-native-modal';
|
|
4
|
+
import { useNavigation } from '@react-navigation/native';
|
|
5
|
+
|
|
6
|
+
import t from '../../hooks/Common/useTranslations';
|
|
7
|
+
import Text from '../Text';
|
|
8
|
+
import { Colors } from '../../configs';
|
|
9
|
+
import { styles } from './styles';
|
|
10
|
+
|
|
11
|
+
const PreventAccess = memo(({ headerBodyText, visible, hidePreventAccess }) => {
|
|
12
|
+
const { goBack } = useNavigation();
|
|
13
|
+
|
|
14
|
+
const dataText = useMemo(() => {
|
|
15
|
+
return {
|
|
16
|
+
headerText: t('note'),
|
|
17
|
+
bodyText: t('This {name} was removed!', {
|
|
18
|
+
name: headerBodyText ? headerBodyText : '',
|
|
19
|
+
}),
|
|
20
|
+
endOfText: t('back'),
|
|
21
|
+
};
|
|
22
|
+
}, [headerBodyText]);
|
|
23
|
+
|
|
24
|
+
const handleBackPress = useCallback(() => {
|
|
25
|
+
hidePreventAccess();
|
|
26
|
+
goBack();
|
|
27
|
+
}, [goBack, hidePreventAccess]);
|
|
28
|
+
|
|
29
|
+
const handleDonePopup = useCallback(() => {
|
|
30
|
+
goBack();
|
|
31
|
+
hidePreventAccess();
|
|
32
|
+
}, [goBack, hidePreventAccess]);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Modal
|
|
36
|
+
isVisible={visible}
|
|
37
|
+
transparent={true}
|
|
38
|
+
onBackButtonPress={handleBackPress}
|
|
39
|
+
style={styles.container}
|
|
40
|
+
>
|
|
41
|
+
<View style={styles.popoverStyle}>
|
|
42
|
+
<View style={styles.actionTextWrap}>
|
|
43
|
+
<Text size={17} bold color={Colors.Gray9} style={styles.textHeader}>
|
|
44
|
+
{dataText?.headerText}
|
|
45
|
+
</Text>
|
|
46
|
+
<Text type="H4" color={Colors.Gray8} style={styles.textNotification}>
|
|
47
|
+
{dataText?.bodyText}
|
|
48
|
+
</Text>
|
|
49
|
+
</View>
|
|
50
|
+
<View style={styles.endOfText}>
|
|
51
|
+
<Text size={16} bold color={Colors.Primary} onPress={handleDonePopup}>
|
|
52
|
+
{dataText?.endOfText}
|
|
53
|
+
</Text>
|
|
54
|
+
</View>
|
|
55
|
+
</View>
|
|
56
|
+
</Modal>
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
export default PreventAccess;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import { Colors } from '../../configs';
|
|
4
|
+
|
|
5
|
+
export const styles = StyleSheet.create({
|
|
6
|
+
container: {
|
|
7
|
+
flex: 1,
|
|
8
|
+
},
|
|
9
|
+
popoverStyle: {
|
|
10
|
+
flex: 1,
|
|
11
|
+
width: '100%',
|
|
12
|
+
backgroundColor: Colors.White,
|
|
13
|
+
position: 'absolute',
|
|
14
|
+
borderRadius: 10,
|
|
15
|
+
},
|
|
16
|
+
actionTextWrap: {
|
|
17
|
+
marginTop: 14,
|
|
18
|
+
marginHorizontal: 20,
|
|
19
|
+
},
|
|
20
|
+
textHeader: {
|
|
21
|
+
marginVertical: 10,
|
|
22
|
+
},
|
|
23
|
+
textNotification: {
|
|
24
|
+
lineHeight: 20,
|
|
25
|
+
},
|
|
26
|
+
endOfText: {
|
|
27
|
+
flexDirection: 'row',
|
|
28
|
+
justifyContent: 'flex-end',
|
|
29
|
+
marginTop: 5,
|
|
30
|
+
marginBottom: 20,
|
|
31
|
+
marginRight: 20,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
@@ -1,29 +1,27 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
2
|
import { View, StyleSheet } from 'react-native';
|
|
3
3
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
4
4
|
import { Colors } from '../../configs';
|
|
5
5
|
import Text from '../../commons/Text';
|
|
6
|
-
|
|
7
6
|
import RowMember from './RowMember';
|
|
8
7
|
|
|
9
8
|
const MemberList = ({
|
|
10
9
|
dataMember,
|
|
11
10
|
ownerId,
|
|
11
|
+
unit,
|
|
12
12
|
currentUserId, //user is using app
|
|
13
|
-
onPressRemove,
|
|
14
13
|
}) => {
|
|
15
14
|
const t = useTranslations();
|
|
16
|
-
|
|
17
15
|
return (
|
|
18
16
|
<View style={styles.box}>
|
|
19
17
|
{!!dataMember.length &&
|
|
20
18
|
dataMember.map((item, index) => (
|
|
21
19
|
<RowMember
|
|
22
20
|
member={item}
|
|
21
|
+
unit={unit}
|
|
23
22
|
index={index}
|
|
24
23
|
ownerId={ownerId}
|
|
25
24
|
currentUserId={currentUserId}
|
|
26
|
-
onPressRemove={onPressRemove}
|
|
27
25
|
key={index.toString()}
|
|
28
26
|
/>
|
|
29
27
|
))}
|
|
@@ -33,13 +31,10 @@ const MemberList = ({
|
|
|
33
31
|
</View>
|
|
34
32
|
);
|
|
35
33
|
};
|
|
36
|
-
export default MemberList;
|
|
34
|
+
export default memo(MemberList);
|
|
35
|
+
|
|
37
36
|
const styles = StyleSheet.create({
|
|
38
37
|
box: {
|
|
39
|
-
paddingBottom: 16,
|
|
40
|
-
borderRadius: 20,
|
|
41
38
|
backgroundColor: Colors.White,
|
|
42
|
-
borderWidth: 1,
|
|
43
|
-
borderColor: Colors.Gray4,
|
|
44
39
|
},
|
|
45
40
|
});
|