@eohjsc/react-native-smart-city 0.3.26 → 0.3.29
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 -0
- package/package.json +1 -1
- package/src/Images/Common/device_icon.png +0 -0
- package/src/Images/DevMode/gateway.png +0 -0
- package/src/Images/DevMode/gateway@2x.png +0 -0
- package/src/Images/DevMode/gateway@3x.png +0 -0
- package/src/Images/DevMode/menu.png +0 -0
- package/src/Images/DevMode/menu@2x.png +0 -0
- package/src/Images/DevMode/menu@3x.png +0 -0
- package/src/Images/DevMode/search.png +0 -0
- package/src/Images/DevMode/search@2x.png +0 -0
- package/src/Images/DevMode/search@3x.png +0 -0
- package/src/Images/DevMode/smart.png +0 -0
- package/src/Images/DevMode/smart@2x.png +0 -0
- package/src/Images/DevMode/smart@3x.png +0 -0
- package/src/Images/DevMode/template.png +0 -0
- package/src/Images/DevMode/template@2x.png +0 -0
- package/src/Images/DevMode/template@3x.png +0 -0
- package/src/commons/ActionGroup/CurtainButtonTemplate.js +1 -2
- package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +2 -0
- package/src/commons/ActionTemplate/CurtainAction.js +60 -0
- package/src/commons/ActionTemplate/CurtainActionStyles.js +11 -0
- package/src/commons/ActionTemplate/OnOffSmartLockAction.js +44 -0
- package/src/commons/ActionTemplate/OnOffSmartLockActionStyles.js +11 -0
- package/src/commons/ActionTemplate/index.js +18 -0
- package/src/commons/CameraDevice/index.js +1 -2
- package/src/commons/ConnectingProcess/DeviceItem/DeviceItem.js +20 -12
- package/src/commons/ConnectingProcess/DeviceItem/DeviceItemStyles.js +2 -0
- package/src/commons/ConnectingProcess/__test__/DeviceItem.test.js +1 -1
- package/src/commons/ConnectingProcess/index.js +11 -0
- package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +55 -5
- package/src/commons/Dashboard/MyUnit/index.js +59 -12
- package/src/commons/DevMode/Label.js +10 -0
- package/src/commons/DevMode/Search.js +20 -0
- package/src/commons/DevMode/Styles/LabelStyles.js +8 -0
- package/src/commons/DevMode/Styles/SearchStyles.js +21 -0
- package/src/commons/DevMode/index.js +3 -0
- package/src/commons/Device/ItemDevice.js +1 -0
- package/src/commons/Form/TextInput.js +4 -0
- package/src/commons/HeaderAni/index.js +1 -0
- package/src/commons/MediaPlayerDetail/index.js +0 -20
- package/src/commons/MenuActionMore/index.js +12 -4
- package/src/commons/Modal/index.js +1 -2
- package/src/commons/NavBar/index.js +12 -1
- package/src/commons/Popover/index.js +26 -0
- package/src/commons/SubUnit/ShortDetail.js +1 -0
- package/src/commons/SummaryItem/index.js +2 -1
- package/src/commons/Tabbar/Styles/indexStyles.js +51 -0
- package/src/commons/Tabbar/index.js +110 -0
- package/src/commons/Unit/HeaderUnit/index.js +2 -0
- package/src/commons/Unit/SharedUnit.js +1 -0
- package/src/commons/WrapParallaxScrollView/index.js +16 -2
- package/src/configs/Colors.js +4 -0
- package/src/configs/Constants.js +5 -0
- package/src/configs/Images.js +6 -0
- package/src/context/actionType.ts +2 -0
- package/src/context/reducer.ts +10 -0
- package/src/hooks/Common/useGGHomeDeviceConnected.js +9 -2
- package/src/hooks/Common/usePopover.js +0 -8
- package/src/hooks/IoT/useGGHomeConnection.js +0 -1
- package/src/navigations/GatewayStack.js +23 -0
- package/src/navigations/Main.js +144 -0
- package/src/navigations/SmartStack.js +23 -0
- package/src/navigations/TemplateStack.js +23 -0
- package/src/navigations/UnitStack.js +10 -2
- package/src/screens/AddNewAction/SelectAction.js +6 -1
- package/src/screens/AllCamera/__test__/index.test.js +1 -8
- package/src/screens/AllCamera/index.js +0 -13
- package/src/screens/Device/hooks/__test__/useEmergencyButton.test.js +37 -0
- package/src/screens/Drawer/Drawer.test.js +24 -0
- package/src/screens/Drawer/index.js +198 -0
- package/src/screens/Gateway/__test__/index.test.js +16 -0
- package/src/screens/Gateway/index.js +8 -0
- package/src/screens/Notification/__test__/NotificationItem.test.js +79 -85
- package/src/screens/Notification/components/NotificationItem.js +37 -220
- package/src/screens/ScriptDetail/__test__/index.test.js +39 -3
- package/src/screens/ScriptDetail/index.js +7 -10
- package/src/screens/Smart/__test__/index.test.js +16 -0
- package/src/screens/Smart/index.js +8 -0
- package/src/screens/SubUnit/AddSubUnit.js +1 -1
- package/src/screens/SubUnit/EditSubUnit.js +4 -1
- package/src/screens/Template/Styles/indexStyles.js +51 -0
- package/src/screens/Template/__test__/index.test.js +16 -0
- package/src/screens/Template/index.js +84 -0
- package/src/screens/Unit/Detail.js +10 -27
- package/src/screens/Unit/MoreMenu.js +16 -1
- package/src/screens/Unit/SmartAccount.js +7 -6
- package/src/screens/Unit/Station/__test__/index.test.js +41 -0
- package/src/screens/Unit/Station/index.js +0 -1
- package/src/screens/Unit/Summaries.js +14 -2
- package/src/screens/Unit/__test__/Detail.test.js +1 -5
- package/src/screens/Unit/components/Header/index.js +1 -1
- package/src/screens/Unit/components/MyUnitDevice/index.js +29 -12
- package/src/screens/Unit/components/__test__/Header.test.js +1 -1
- package/src/screens/Unit/components/__test__/MyUnitDevice.test.js +2 -2
- package/src/screens/Unit/hook/useUnitConnectRemoteDevices.js +6 -5
- package/src/utils/Converter/__test__/timer.test.js +99 -0
- package/src/utils/Functions/Search.js +17 -0
- package/src/utils/Functions/ShortEmail.js +4 -0
- package/src/utils/Functions/__test__/Search.test.js +6 -0
- package/src/utils/Functions/__test__/ShortEmail.test.js +6 -0
- package/src/utils/I18n/translations/en.json +32 -42
- package/src/utils/I18n/translations/vi.json +32 -44
- package/src/utils/Route/index.js +6 -0
- package/src/commons/Modal/ModalFullVideo.js +0 -48
- package/src/commons/Modal/Styles/ModalFullVideoStyles.js +0 -26
- package/src/screens/Unit/components/MyUnit/index.js +0 -136
- package/src/screens/Unit/components/__test__/MyUnit.test.js +0 -35
|
@@ -103,7 +103,6 @@ describe('Test ScriptDetail', () => {
|
|
|
103
103
|
|
|
104
104
|
await act(async () => {
|
|
105
105
|
await menu.props.onItemClick(rename);
|
|
106
|
-
await menu.props.hideComplete();
|
|
107
106
|
});
|
|
108
107
|
expect(menu.props.isVisible).toBeFalsy();
|
|
109
108
|
expect(alertAction.props.visible).toBeTruthy();
|
|
@@ -130,7 +129,6 @@ describe('Test ScriptDetail', () => {
|
|
|
130
129
|
|
|
131
130
|
await act(async () => {
|
|
132
131
|
await menu.props.onItemClick(rename);
|
|
133
|
-
await menu.props.hideComplete();
|
|
134
132
|
});
|
|
135
133
|
expect(menu.props.isVisible).toBeFalsy();
|
|
136
134
|
expect(alertAction.props.visible).toBeTruthy();
|
|
@@ -154,7 +152,6 @@ describe('Test ScriptDetail', () => {
|
|
|
154
152
|
|
|
155
153
|
await act(async () => {
|
|
156
154
|
await menu.props.onItemClick(deleteItem);
|
|
157
|
-
await menu.props.hideComplete();
|
|
158
155
|
});
|
|
159
156
|
expect(alertAction.props.visible).toBeTruthy();
|
|
160
157
|
mock.onDelete(API.AUTOMATE.SCRIPT(1)).reply(204);
|
|
@@ -358,4 +355,43 @@ describe('Test ScriptDetail', () => {
|
|
|
358
355
|
'Light Value lower than 3'
|
|
359
356
|
);
|
|
360
357
|
});
|
|
358
|
+
|
|
359
|
+
test('Test render textCondition schedule repeat everyday', async () => {
|
|
360
|
+
route.params = {
|
|
361
|
+
...route.params,
|
|
362
|
+
type: AUTOMATE_TYPE.SCHEDULE,
|
|
363
|
+
automate: {
|
|
364
|
+
repeat: 'every_day',
|
|
365
|
+
date_repeat: '2022-01-02',
|
|
366
|
+
time_repeat: '19:00:00',
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
await act(() => {
|
|
370
|
+
tree = create(wrapComponent(route));
|
|
371
|
+
});
|
|
372
|
+
const instance = tree.root;
|
|
373
|
+
const itemAutomate = instance.findByType(ItemAutomate);
|
|
374
|
+
expect(itemAutomate.props.textCondition).toEqual('Every day at 19:00');
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
test('Test render textCondition schedule repeat weekday', async () => {
|
|
378
|
+
route.params = {
|
|
379
|
+
...route.params,
|
|
380
|
+
type: AUTOMATE_TYPE.SCHEDULE,
|
|
381
|
+
automate: {
|
|
382
|
+
repeat: 'every_week',
|
|
383
|
+
date_repeat: '2022-01-02',
|
|
384
|
+
time_repeat: '19:00:00',
|
|
385
|
+
weekday_repeat: ['1', '2', '4', '6'],
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
await act(() => {
|
|
389
|
+
tree = create(wrapComponent(route));
|
|
390
|
+
});
|
|
391
|
+
const instance = tree.root;
|
|
392
|
+
const itemAutomate = instance.findByType(ItemAutomate);
|
|
393
|
+
expect(itemAutomate.props.textCondition).toEqual(
|
|
394
|
+
'Mon, Tue, Thu, Sat at 19:00'
|
|
395
|
+
);
|
|
396
|
+
});
|
|
361
397
|
});
|
|
@@ -43,6 +43,7 @@ import { popAction } from '../../navigations/utils';
|
|
|
43
43
|
import { TESTID } from '../../configs/Constants';
|
|
44
44
|
import useKeyboardAnimated from '../../hooks/Explore/useKeyboardAnimated';
|
|
45
45
|
import { REPEAT_OPTIONS } from '../SetSchedule/components/RepeatOptionsPopup';
|
|
46
|
+
import { useSCContextSelector } from '../../context';
|
|
46
47
|
|
|
47
48
|
const PreventDoubleTouch = withPreventDoubleClick(TouchableOpacity);
|
|
48
49
|
|
|
@@ -50,14 +51,8 @@ const ScriptDetail = ({ route }) => {
|
|
|
50
51
|
const { navigate, goBack, dispatch } = useNavigation();
|
|
51
52
|
const { params = {} } = route;
|
|
52
53
|
const refMenuAction = useRef();
|
|
53
|
-
const {
|
|
54
|
-
|
|
55
|
-
showingPopover,
|
|
56
|
-
showPopoverWithRef,
|
|
57
|
-
hidePopover,
|
|
58
|
-
hidingPopoverComplete,
|
|
59
|
-
hidePopoverComplete,
|
|
60
|
-
} = usePopover();
|
|
54
|
+
const { childRef, showingPopover, showPopoverWithRef, hidePopover } =
|
|
55
|
+
usePopover();
|
|
61
56
|
const t = useTranslations();
|
|
62
57
|
const {
|
|
63
58
|
id,
|
|
@@ -84,6 +79,9 @@ const ScriptDetail = ({ route }) => {
|
|
|
84
79
|
const [data, setData] = useState([]);
|
|
85
80
|
|
|
86
81
|
const { isStarred, starScript, unstarScript } = useStarredScript(automate);
|
|
82
|
+
const popoverAnimating = useSCContextSelector(
|
|
83
|
+
(state) => state.app.popoverAnimating
|
|
84
|
+
);
|
|
87
85
|
|
|
88
86
|
const [transY] = useKeyboardAnimated(-16);
|
|
89
87
|
const animatedStyle = Platform.select({
|
|
@@ -483,7 +481,6 @@ const ScriptDetail = ({ route }) => {
|
|
|
483
481
|
<MenuActionMore
|
|
484
482
|
isVisible={showingPopover}
|
|
485
483
|
hideMore={hidePopover}
|
|
486
|
-
hideComplete={hidePopoverComplete}
|
|
487
484
|
listMenuItem={listMenuItem}
|
|
488
485
|
childRef={childRef}
|
|
489
486
|
onItemClick={onItemClick}
|
|
@@ -491,7 +488,7 @@ const ScriptDetail = ({ route }) => {
|
|
|
491
488
|
wrapStyle={styles.wrapStyle}
|
|
492
489
|
/>
|
|
493
490
|
<AlertAction
|
|
494
|
-
visible={stateAlertAction.visible &&
|
|
491
|
+
visible={stateAlertAction.visible && !popoverAnimating}
|
|
495
492
|
hideModal={hideAlertAction}
|
|
496
493
|
title={stateAlertAction.title}
|
|
497
494
|
message={stateAlertAction.message}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { act, create } from 'react-test-renderer';
|
|
4
|
+
import Smart from '..';
|
|
5
|
+
|
|
6
|
+
describe('Test Template screen', () => {
|
|
7
|
+
let tree;
|
|
8
|
+
it('Test render', async () => {
|
|
9
|
+
await act(async () => {
|
|
10
|
+
tree = await create(<Smart />);
|
|
11
|
+
});
|
|
12
|
+
const instance = tree.root;
|
|
13
|
+
const Views = instance.findAllByType(View);
|
|
14
|
+
expect(Views).toHaveLength(1);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -42,7 +42,6 @@ const AddSubUnit = ({ route }) => {
|
|
|
42
42
|
setRoomName('');
|
|
43
43
|
setWallpaper('');
|
|
44
44
|
setImageUrl('');
|
|
45
|
-
awaitCreate.current = false;
|
|
46
45
|
};
|
|
47
46
|
|
|
48
47
|
const goDone = useCallback(async () => {
|
|
@@ -186,6 +185,7 @@ const AddSubUnit = ({ route }) => {
|
|
|
186
185
|
wrapStyle={styles.textInput}
|
|
187
186
|
selectionColor={Colors.Primary}
|
|
188
187
|
value={roomName}
|
|
188
|
+
maxLength={50}
|
|
189
189
|
/>
|
|
190
190
|
|
|
191
191
|
{isAddUnit && (
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors, Constants } from '../../../configs';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
wrap: {
|
|
6
|
+
flex: 1,
|
|
7
|
+
backgroundColor: Colors.White,
|
|
8
|
+
padding: 16,
|
|
9
|
+
},
|
|
10
|
+
wrapEmpty: {
|
|
11
|
+
flex: 1,
|
|
12
|
+
justifyContent: 'center',
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
marginTop: -100,
|
|
15
|
+
},
|
|
16
|
+
textEmpty1: {
|
|
17
|
+
fontSize: 20,
|
|
18
|
+
fontWeight: 'bold',
|
|
19
|
+
},
|
|
20
|
+
textEmpty2: {
|
|
21
|
+
fontSize: 14,
|
|
22
|
+
fontWeight: '400',
|
|
23
|
+
color: Colors.Neutral.Neutral5,
|
|
24
|
+
marginTop: 7,
|
|
25
|
+
},
|
|
26
|
+
contentContainerStyle: {
|
|
27
|
+
flex: 1,
|
|
28
|
+
},
|
|
29
|
+
item: {
|
|
30
|
+
width: (Constants.width - 42) / 2,
|
|
31
|
+
height: 128,
|
|
32
|
+
borderRadius: 8,
|
|
33
|
+
borderWidth: 1,
|
|
34
|
+
borderColor: Colors.Neutral.Neutral3,
|
|
35
|
+
marginBottom: 16,
|
|
36
|
+
justifyContent: 'space-around',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
},
|
|
39
|
+
oddItem: {
|
|
40
|
+
marginRight: 10,
|
|
41
|
+
},
|
|
42
|
+
nameItem: {
|
|
43
|
+
fontSize: 14,
|
|
44
|
+
fontWeight: 'bold',
|
|
45
|
+
},
|
|
46
|
+
countItem: {
|
|
47
|
+
fontSize: 12,
|
|
48
|
+
fontWeight: 400,
|
|
49
|
+
color: Colors.Neutral.Neutral5,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FlatList } from 'react-native';
|
|
3
|
+
import { act, create } from 'react-test-renderer';
|
|
4
|
+
import Template from '..';
|
|
5
|
+
|
|
6
|
+
describe('Test Template screen', () => {
|
|
7
|
+
let tree;
|
|
8
|
+
it('Test render', async () => {
|
|
9
|
+
await act(async () => {
|
|
10
|
+
tree = await create(<Template />);
|
|
11
|
+
});
|
|
12
|
+
const instance = tree.root;
|
|
13
|
+
const FlatLists = instance.findAllByType(FlatList);
|
|
14
|
+
expect(FlatLists).toHaveLength(1);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
TouchableWithoutFeedback,
|
|
5
|
+
Keyboard,
|
|
6
|
+
FlatList,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import { Label } from '../../commons/DevMode';
|
|
9
|
+
import Search from '../../commons/DevMode/Search';
|
|
10
|
+
import Text from '../../commons/Text';
|
|
11
|
+
import t from '../../hooks/Common/useTranslations';
|
|
12
|
+
import { convertToSlug } from '../../utils/Functions/Search';
|
|
13
|
+
import styles from './Styles/indexStyles';
|
|
14
|
+
|
|
15
|
+
const arrTemplates = [
|
|
16
|
+
{
|
|
17
|
+
id: 1,
|
|
18
|
+
name: 'Template name 1',
|
|
19
|
+
count: 2,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 2,
|
|
23
|
+
name: 'Template name 2',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 3,
|
|
27
|
+
name: 'Template name 3',
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const Template = () => {
|
|
32
|
+
const [data, setData] = useState(arrTemplates);
|
|
33
|
+
|
|
34
|
+
const onSearch = useCallback((value) => {
|
|
35
|
+
if (value === '') {
|
|
36
|
+
setData(arrTemplates);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const dataTemp = arrTemplates.filter((item) =>
|
|
40
|
+
convertToSlug(item?.name).includes(convertToSlug(value))
|
|
41
|
+
);
|
|
42
|
+
setData(dataTemp);
|
|
43
|
+
}, []);
|
|
44
|
+
|
|
45
|
+
const renderListEmptyComponent = useMemo(() => {
|
|
46
|
+
return (
|
|
47
|
+
<View style={styles.wrapEmpty}>
|
|
48
|
+
<Text style={styles.textEmpty1}>{t('no_template_yet')}</Text>
|
|
49
|
+
<Text style={styles.textEmpty2}>{t('add_your_template')}</Text>
|
|
50
|
+
</View>
|
|
51
|
+
);
|
|
52
|
+
}, []);
|
|
53
|
+
|
|
54
|
+
const renderItem = ({ item, index }) => {
|
|
55
|
+
return (
|
|
56
|
+
<View style={[styles.item, index % 2 === 0 && styles.oddItem]}>
|
|
57
|
+
<Text style={styles.nameItem}>{item?.name}</Text>
|
|
58
|
+
<Text style={styles.countItem}>{`${
|
|
59
|
+
item?.count > 0 ? item?.count : t('no')
|
|
60
|
+
} ${t('gateways').toLowerCase()}`}</Text>
|
|
61
|
+
</View>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
|
67
|
+
<View style={styles.wrap}>
|
|
68
|
+
<Label name={t('template')} />
|
|
69
|
+
<Search onSearch={onSearch} />
|
|
70
|
+
<FlatList
|
|
71
|
+
contentContainerStyle={styles.contentContainerStyle}
|
|
72
|
+
keyExtractor={(item) => item?.id}
|
|
73
|
+
data={data}
|
|
74
|
+
renderItem={renderItem}
|
|
75
|
+
extraData={data}
|
|
76
|
+
ListEmptyComponent={renderListEmptyComponent}
|
|
77
|
+
numColumns={2}
|
|
78
|
+
/>
|
|
79
|
+
</View>
|
|
80
|
+
</TouchableWithoutFeedback>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export default Template;
|
|
@@ -33,7 +33,6 @@ import WrapParallaxScrollView from '../../commons/WrapParallaxScrollView';
|
|
|
33
33
|
import { SCContext, useSCContextSelector } from '../../context';
|
|
34
34
|
import { Action } from '../../context/actionType';
|
|
35
35
|
import CameraDevice from '../../commons/CameraDevice';
|
|
36
|
-
import { ModalFullVideo } from '../../commons/Modal';
|
|
37
36
|
import { useNavigation } from '@react-navigation/native';
|
|
38
37
|
import Routes from '../../utils/Route';
|
|
39
38
|
import SubUnitAutomate from '../../commons/SubUnit/OneTap';
|
|
@@ -63,6 +62,7 @@ const UnitDetail = ({ route }) => {
|
|
|
63
62
|
routeName,
|
|
64
63
|
stationId,
|
|
65
64
|
isAddSubUnit,
|
|
65
|
+
isEditSubUnit,
|
|
66
66
|
isSuccessfullyConnected,
|
|
67
67
|
} = route.params;
|
|
68
68
|
|
|
@@ -92,8 +92,6 @@ const UnitDetail = ({ route }) => {
|
|
|
92
92
|
const [showAdd, setShowAdd, setHideAdd] = useBoolean();
|
|
93
93
|
const [showPreventAccess, setShowPreventAccess, setHidePreventAccess] =
|
|
94
94
|
useBoolean(false);
|
|
95
|
-
const [isFullScreen, setIsFullScreen] = useState(false);
|
|
96
|
-
const [dataFullScreen, setDataFullScreen] = useState();
|
|
97
95
|
const appState = useRef(AppState.currentState);
|
|
98
96
|
|
|
99
97
|
const { childRef, showingPopover, showPopoverWithRef, hidePopover } =
|
|
@@ -105,15 +103,6 @@ const UnitDetail = ({ route }) => {
|
|
|
105
103
|
listAutomate
|
|
106
104
|
);
|
|
107
105
|
|
|
108
|
-
const handleFullScreen = (data) => {
|
|
109
|
-
setIsFullScreen(!isFullScreen);
|
|
110
|
-
setDataFullScreen(data);
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const onClose = useCallback(() => {
|
|
114
|
-
setIsFullScreen(false);
|
|
115
|
-
}, []);
|
|
116
|
-
|
|
117
106
|
const prepareData = useCallback(
|
|
118
107
|
(rawUnitData) => {
|
|
119
108
|
rawUnitData.stations.unshift({
|
|
@@ -217,8 +206,9 @@ const UnitDetail = ({ route }) => {
|
|
|
217
206
|
}, [unit, indexStation]);
|
|
218
207
|
|
|
219
208
|
useEffect(() => {
|
|
209
|
+
isEditSubUnit && setIndexStation(0);
|
|
220
210
|
isOneTap && setIndexStation(1);
|
|
221
|
-
}, [isOneTap]);
|
|
211
|
+
}, [isEditSubUnit, isOneTap]);
|
|
222
212
|
|
|
223
213
|
useEffect(() => {
|
|
224
214
|
if (listMenuItem.length && isAddSubUnit) {
|
|
@@ -227,7 +217,7 @@ const UnitDetail = ({ route }) => {
|
|
|
227
217
|
}, [listMenuItem.length, isAddSubUnit]);
|
|
228
218
|
|
|
229
219
|
useEffect(() => {
|
|
230
|
-
if (listMenuItem.length && stationId) {
|
|
220
|
+
if (!isEditSubUnit && listMenuItem.length && stationId) {
|
|
231
221
|
const getStationCurrent = listMenuItem.filter(
|
|
232
222
|
(item) => item?.station.id === stationId
|
|
233
223
|
);
|
|
@@ -262,13 +252,7 @@ const UnitDetail = ({ route }) => {
|
|
|
262
252
|
);
|
|
263
253
|
}
|
|
264
254
|
if (station?.camera_devices) {
|
|
265
|
-
return
|
|
266
|
-
<CameraDevice
|
|
267
|
-
station={station}
|
|
268
|
-
handleFullScreen={handleFullScreen}
|
|
269
|
-
goToPlayBack={goToPlayBack}
|
|
270
|
-
/>
|
|
271
|
-
);
|
|
255
|
+
return <CameraDevice station={station} goToPlayBack={goToPlayBack} />;
|
|
272
256
|
} else if (station?.isOneTap) {
|
|
273
257
|
return (
|
|
274
258
|
<SubUnitAutomate
|
|
@@ -333,6 +317,8 @@ const UnitDetail = ({ route }) => {
|
|
|
333
317
|
onMore={showPopoverWithRef}
|
|
334
318
|
hideRightPlus={!isOwner}
|
|
335
319
|
onBack={(isSuccessfullyConnected && Dashboard) || (routeName && onBack)}
|
|
320
|
+
accessibilityLabel={TESTID.UNIT_DETAIL_PARALLAX_SCROLLVIEW}
|
|
321
|
+
idButtonMore={TESTID.UNIT_DETAIL_PARALLAX_BUTTON_MORE}
|
|
336
322
|
>
|
|
337
323
|
{renderCamera}
|
|
338
324
|
|
|
@@ -344,6 +330,7 @@ const UnitDetail = ({ route }) => {
|
|
|
344
330
|
listMenuItem={listMenuItem}
|
|
345
331
|
onSnapToItem={onSnapToItem}
|
|
346
332
|
indexStation={indexStation}
|
|
333
|
+
idLabelScrollView={TESTID.NAV_LIST}
|
|
347
334
|
/>
|
|
348
335
|
{renderDetailSubUnit()}
|
|
349
336
|
{!!unit.can_add && unit.stations.length === 0 && (
|
|
@@ -364,12 +351,8 @@ const UnitDetail = ({ route }) => {
|
|
|
364
351
|
isOwner={isOwner}
|
|
365
352
|
childRef={childRef}
|
|
366
353
|
showingPopover={showingPopover}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
isVisible={isFullScreen}
|
|
370
|
-
data={dataFullScreen}
|
|
371
|
-
modalStyles={styles.modal}
|
|
372
|
-
onClose={onClose}
|
|
354
|
+
idLabelPopover={TESTID.UNIT_DETAIL_POPUP_MORE}
|
|
355
|
+
idLabelItem={TESTID.UNIT_DETAIL_POPUP_MORE_ITEM}
|
|
373
356
|
/>
|
|
374
357
|
<PreventAccess
|
|
375
358
|
visible={showPreventAccess}
|
|
@@ -5,7 +5,16 @@ import { useNavigation } from '@react-navigation/native';
|
|
|
5
5
|
import { MenuActionMore } from '../../commons';
|
|
6
6
|
|
|
7
7
|
const MoreMenu = memo(
|
|
8
|
-
({
|
|
8
|
+
({
|
|
9
|
+
unit,
|
|
10
|
+
isOwner,
|
|
11
|
+
hidePopover,
|
|
12
|
+
childRef,
|
|
13
|
+
showingPopover,
|
|
14
|
+
idLabelPopover,
|
|
15
|
+
idLabelScrollView,
|
|
16
|
+
idLabelItem,
|
|
17
|
+
}) => {
|
|
9
18
|
const t = useTranslations();
|
|
10
19
|
const navigation = useNavigation();
|
|
11
20
|
|
|
@@ -19,16 +28,19 @@ const MoreMenu = memo(
|
|
|
19
28
|
|
|
20
29
|
const listMenuItem = useMemo(() => {
|
|
21
30
|
const RouteManageUnit = {
|
|
31
|
+
id: 1,
|
|
22
32
|
route: Routes.ManageUnit,
|
|
23
33
|
text: t('manage_unit'),
|
|
24
34
|
data: { unitId: unit.id, unit },
|
|
25
35
|
};
|
|
26
36
|
const RouteUnitMemberList = {
|
|
37
|
+
id: 2,
|
|
27
38
|
route: Routes.UnitMemberList,
|
|
28
39
|
text: t('members'),
|
|
29
40
|
data: { unitId: unit.id, unit },
|
|
30
41
|
};
|
|
31
42
|
const ListSmartAccount = {
|
|
43
|
+
id: 3,
|
|
32
44
|
route: Routes.ListSmartAccount,
|
|
33
45
|
text: t('smart_account'),
|
|
34
46
|
data: { unitId: unit.id, unit },
|
|
@@ -45,6 +57,9 @@ const MoreMenu = memo(
|
|
|
45
57
|
listMenuItem={listMenuItem}
|
|
46
58
|
childRef={childRef}
|
|
47
59
|
onItemClick={onItemClick}
|
|
60
|
+
idLabelPopover={idLabelPopover}
|
|
61
|
+
idLabelScrollView={idLabelScrollView}
|
|
62
|
+
idLabelItem={idLabelItem}
|
|
48
63
|
/>
|
|
49
64
|
);
|
|
50
65
|
}
|
|
@@ -14,11 +14,12 @@ import Routes from '../../utils/Route';
|
|
|
14
14
|
import { useNavigation } from '@react-navigation/native';
|
|
15
15
|
import { axiosDelete, axiosGet } from '../../utils/Apis/axios';
|
|
16
16
|
import { SmartAccountItem } from './SmartAccountItem';
|
|
17
|
-
import { usePopover
|
|
17
|
+
import { usePopover } from '../../hooks/Common';
|
|
18
18
|
import { MenuActionMore, AlertAction, FullLoading } from '../../commons';
|
|
19
19
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
20
20
|
import { useStateAlertRemove } from '../Unit/hook/useStateAlertRemove';
|
|
21
21
|
import { ToastBottomHelper } from '../../utils/Utils';
|
|
22
|
+
import { useSCContextSelector } from '../../context';
|
|
22
23
|
|
|
23
24
|
const ListSmartAccount = ({ route }) => {
|
|
24
25
|
const { unitId } = route?.params || {};
|
|
@@ -27,6 +28,9 @@ const ListSmartAccount = ({ route }) => {
|
|
|
27
28
|
const smartAccountRef = useRef(null);
|
|
28
29
|
const { navigate } = useNavigation();
|
|
29
30
|
const [loadingRemoveItem, setLoadingRemoveItem] = useState(false);
|
|
31
|
+
const popoverAnimating = useSCContextSelector(
|
|
32
|
+
(state) => state.app.popoverAnimating
|
|
33
|
+
);
|
|
30
34
|
|
|
31
35
|
const getAllSmartAccounts = useCallback(async () => {
|
|
32
36
|
const { success, data: accountData } = await axiosGet(
|
|
@@ -39,7 +43,6 @@ const ListSmartAccount = ({ route }) => {
|
|
|
39
43
|
|
|
40
44
|
const { childRef, showingPopover, showPopoverWithRef, hidePopover } =
|
|
41
45
|
usePopover();
|
|
42
|
-
const [lockShowing, acquireLockShowing, releaseLockShowing] = useBoolean();
|
|
43
46
|
const { stateAlertRemove, onShowRemoveAlert, hideAlertAction } =
|
|
44
47
|
useStateAlertRemove();
|
|
45
48
|
|
|
@@ -62,11 +65,10 @@ const ListSmartAccount = ({ route }) => {
|
|
|
62
65
|
return;
|
|
63
66
|
}
|
|
64
67
|
if (item.action === 'remove') {
|
|
65
|
-
acquireLockShowing();
|
|
66
68
|
onShowRemoveAlert(smartAccountRef.current.brand)();
|
|
67
69
|
}
|
|
68
70
|
},
|
|
69
|
-
[
|
|
71
|
+
[onShowRemoveAlert]
|
|
70
72
|
);
|
|
71
73
|
|
|
72
74
|
const deleteSmartAccount = useCallback(async () => {
|
|
@@ -124,7 +126,7 @@ const ListSmartAccount = ({ route }) => {
|
|
|
124
126
|
})}
|
|
125
127
|
</View>
|
|
126
128
|
<AlertAction
|
|
127
|
-
visible={stateAlertRemove.visible && !
|
|
129
|
+
visible={stateAlertRemove.visible && !popoverAnimating}
|
|
128
130
|
hideModal={hideAlertAction}
|
|
129
131
|
title={stateAlertRemove.title}
|
|
130
132
|
message={stateAlertRemove.message}
|
|
@@ -142,7 +144,6 @@ const ListSmartAccount = ({ route }) => {
|
|
|
142
144
|
listMenuItem={listMenuItem}
|
|
143
145
|
childRef={childRef}
|
|
144
146
|
onItemClick={onItemClick}
|
|
145
|
-
hideComplete={releaseLockShowing}
|
|
146
147
|
/>
|
|
147
148
|
</WrapHeaderScrollable>
|
|
148
149
|
{loadingRemoveItem && <FullLoading />}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FlatList } from 'react-native';
|
|
3
|
+
import { act, create } from 'react-test-renderer';
|
|
4
|
+
import Station from '..';
|
|
5
|
+
import { SCProvider } from '../../../../context';
|
|
6
|
+
import { mockSCStore } from '../../../../context/mockStore';
|
|
7
|
+
|
|
8
|
+
const mockOnSnapToItem = jest.fn();
|
|
9
|
+
|
|
10
|
+
const wrapComponent = (route) => (
|
|
11
|
+
<SCProvider initState={mockSCStore({})}>
|
|
12
|
+
<Station
|
|
13
|
+
listStation={[{ id: 1, station: { id: 1 }, text: 'station1' }]}
|
|
14
|
+
onSnapToItem={mockOnSnapToItem}
|
|
15
|
+
indexStation={1}
|
|
16
|
+
/>
|
|
17
|
+
</SCProvider>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
describe('Test Station', async () => {
|
|
21
|
+
let tree;
|
|
22
|
+
let route = {
|
|
23
|
+
unitId: 1,
|
|
24
|
+
unitData: {
|
|
25
|
+
id: 1,
|
|
26
|
+
},
|
|
27
|
+
isOneTap: false,
|
|
28
|
+
routeName: 'Test',
|
|
29
|
+
stationId: 1,
|
|
30
|
+
isAddSubUnit: false,
|
|
31
|
+
isSuccessfullyConnected: false,
|
|
32
|
+
};
|
|
33
|
+
it('Test render', async () => {
|
|
34
|
+
await act(async () => {
|
|
35
|
+
tree = create(wrapComponent(route));
|
|
36
|
+
});
|
|
37
|
+
const instance = tree.root;
|
|
38
|
+
const FlatLists = instance.findAllByType(FlatList);
|
|
39
|
+
expect(FlatLists).toHaveLength(1);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -6,6 +6,8 @@ import { useIsFocused, useNavigation } from '@react-navigation/native';
|
|
|
6
6
|
import { axiosGet } from '../../utils/Apis/axios';
|
|
7
7
|
import { API } from '../../configs';
|
|
8
8
|
import { useReceiveNotifications } from '../../hooks';
|
|
9
|
+
import { TESTID } from '../../configs/Constants';
|
|
10
|
+
import { useSCContextSelector } from '../../context';
|
|
9
11
|
|
|
10
12
|
const Summaries = memo(({ unit }) => {
|
|
11
13
|
const [unitSummaries, setUnitSummaries] = useState([]);
|
|
@@ -14,6 +16,9 @@ const Summaries = memo(({ unit }) => {
|
|
|
14
16
|
const isFocused = useIsFocused();
|
|
15
17
|
const navigation = useNavigation();
|
|
16
18
|
const appState = useRef(AppState.currentState);
|
|
19
|
+
const popoverAnimating = useSCContextSelector(
|
|
20
|
+
(state) => state.app.popoverAnimating
|
|
21
|
+
);
|
|
17
22
|
|
|
18
23
|
const fetchUnitSummary = useCallback(async () => {
|
|
19
24
|
if (!unit.id) {
|
|
@@ -33,6 +38,9 @@ const Summaries = memo(({ unit }) => {
|
|
|
33
38
|
|
|
34
39
|
const goToSummary = useCallback(
|
|
35
40
|
(summary) => {
|
|
41
|
+
if (popoverAnimating) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
36
44
|
navigation.navigate(Routes.UnitSummary, {
|
|
37
45
|
summaryId: summary.id,
|
|
38
46
|
unitId: unit.id,
|
|
@@ -40,7 +48,7 @@ const Summaries = memo(({ unit }) => {
|
|
|
40
48
|
unitData: unit,
|
|
41
49
|
});
|
|
42
50
|
},
|
|
43
|
-
[navigation, unit]
|
|
51
|
+
[navigation, popoverAnimating, unit]
|
|
44
52
|
);
|
|
45
53
|
|
|
46
54
|
const continuousFetchSummary = useCallback(async () => {
|
|
@@ -101,7 +109,11 @@ const Summaries = memo(({ unit }) => {
|
|
|
101
109
|
return (
|
|
102
110
|
<>
|
|
103
111
|
{!unitSummaries || !unitSummaries.length ? null : (
|
|
104
|
-
<ScrollView
|
|
112
|
+
<ScrollView
|
|
113
|
+
horizontal={true}
|
|
114
|
+
scrollIndicatorInsets={{ right: 1 }}
|
|
115
|
+
accessibilityLabel={TESTID.UNIT_DETAIL_UNIT_SUMMARY_VIEW}
|
|
116
|
+
>
|
|
105
117
|
{unitSummaries.map((item, index) => (
|
|
106
118
|
<SummaryItem key={index} item={item} goToSummary={goToSummary} />
|
|
107
119
|
))}
|
|
@@ -12,7 +12,6 @@ import { TESTID } from '../../../configs/Constants';
|
|
|
12
12
|
import { SCProvider } from '../../../context';
|
|
13
13
|
import { mockSCStore } from '../../../context/mockStore';
|
|
14
14
|
import CameraDevice from '../../../commons/CameraDevice';
|
|
15
|
-
import { ModalFullVideo } from '../../../commons/Modal';
|
|
16
15
|
import SubUnitFavorites from '../../../commons/SubUnit/Favorites';
|
|
17
16
|
import api from '../../../utils/Apis/axios';
|
|
18
17
|
import PreventAccess from '../../../commons/PreventAccess';
|
|
@@ -352,11 +351,7 @@ describe('Test UnitDetail', () => {
|
|
|
352
351
|
el.props.testID === TESTID.SUB_UNIT_FULL_CAMERA &&
|
|
353
352
|
el.type === TouchableOpacity
|
|
354
353
|
);
|
|
355
|
-
|
|
356
354
|
expect(fullCamera).toHaveLength(0);
|
|
357
|
-
const fullView = instance.findAllByType(ModalFullVideo);
|
|
358
|
-
expect(fullView).toHaveLength(1);
|
|
359
|
-
expect(fullView[0].props.isVisible).toEqual(false);
|
|
360
355
|
});
|
|
361
356
|
|
|
362
357
|
test('onPress subunit camera devices', async () => {
|
|
@@ -438,6 +433,7 @@ describe('Test UnitDetail', () => {
|
|
|
438
433
|
};
|
|
439
434
|
route.params.isAddSubUnit = true;
|
|
440
435
|
route.params.unitData = unitData;
|
|
436
|
+
route.params.isSuccessfullyConnected = false;
|
|
441
437
|
await act(async () => {
|
|
442
438
|
tree = await renderer.create(wrapComponent(route, account));
|
|
443
439
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useRef, useState } from 'react';
|
|
2
2
|
import { Dimensions, View, TouchableOpacity, StyleSheet } from 'react-native';
|
|
3
|
-
import Popover from '
|
|
3
|
+
import Popover from '../../../../commons/Popover';
|
|
4
4
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
5
5
|
import { useTranslations } from '../../../../hooks/Common/useTranslations';
|
|
6
6
|
|