@eohjsc/react-native-smart-city 0.2.58 → 0.2.59

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.
Files changed (55) hide show
  1. package/package.json +1 -1
  2. package/src/Images/Common/buttonLeftCurtain.png +0 -0
  3. package/src/Images/Common/buttonPause-center-curtain.png +0 -0
  4. package/src/Images/Common/buttonRightCurtain.png +0 -0
  5. package/src/commons/ActionGroup/CurtainButtonTemplate.js +139 -0
  6. package/src/commons/ActionGroup/CurtainButtonTemplateStyle.js +58 -0
  7. package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +72 -0
  8. package/src/commons/ActionGroup/index.js +3 -0
  9. package/src/commons/Form/CurrencyInput.js +7 -1
  10. package/src/commons/MediaPlayerDetail/Styles/MediaPlayerDetailStyles.js +4 -0
  11. package/src/commons/MediaPlayerDetail/index.js +73 -39
  12. package/src/commons/SearchLocation/index.js +0 -1
  13. package/src/commons/SubUnit/ShortDetail.js +1 -1
  14. package/src/configs/API.js +5 -3
  15. package/src/configs/Constants.js +5 -1
  16. package/src/configs/Images.js +3 -0
  17. package/src/context/actionType.ts +5 -0
  18. package/src/context/mockStore.ts +3 -0
  19. package/src/context/reducer.ts +14 -0
  20. package/src/navigations/UnitStack.js +26 -4
  21. package/src/screens/ActivityLog/FilterPopup.js +1 -1
  22. package/src/screens/AddLocationMaps/index.js +137 -44
  23. package/src/screens/AddLocationMaps/indexStyle.js +14 -12
  24. package/src/screens/AddNewAction/SelectAction.js +1 -0
  25. package/src/screens/Automate/MultiUnits.js +8 -8
  26. package/src/screens/Automate/__test__/MultiUnits.test.js +2 -2
  27. package/src/screens/Automate/__test__/index.test.js +2 -0
  28. package/src/screens/Automate/index.js +4 -2
  29. package/src/screens/Device/detail.js +6 -3
  30. package/src/screens/Notification/__test__/Notification.test.js +3 -3
  31. package/src/screens/Notification/components/NotificationItem.js +3 -6
  32. package/src/screens/Notification/index.js +2 -2
  33. package/src/screens/ScriptDetail/__test__/index.test.js +13 -0
  34. package/src/screens/ScriptDetail/index.js +20 -17
  35. package/src/screens/SelectUnit/index.js +2 -0
  36. package/src/screens/SubUnit/AddSubUnit.js +4 -3
  37. package/src/screens/SubUnit/__test__/AddSubUnit.test.js +4 -3
  38. package/src/screens/Unit/ChooseLocation.js +100 -0
  39. package/src/screens/Unit/ChooseLocationStyles.js +29 -0
  40. package/src/screens/Unit/Detail.js +8 -2
  41. package/src/screens/Unit/ManageUnit.js +1 -1
  42. package/src/screens/Unit/SelectAddress.js +240 -0
  43. package/src/screens/Unit/SelectAddressStyles.js +48 -0
  44. package/src/screens/Unit/__test__/ChooseLocation.test.js +112 -0
  45. package/src/screens/Unit/__test__/SelectAddress.test.js +216 -0
  46. package/src/screens/Unit/components/MyUnitDevice/index.js +21 -5
  47. package/src/utils/I18n/translations/en.json +6 -2
  48. package/src/utils/I18n/translations/vi.json +8 -4
  49. package/src/utils/Route/index.js +2 -1
  50. package/assets/images/AddLocationMaps/PinLocation.svg +0 -3
  51. package/assets/images/AddLocationMaps/Point.svg +0 -3
  52. package/src/screens/Unit/ManageUnit/index.js +0 -286
  53. package/src/screens/Unit/ManageUnit/index.test.js +0 -34
  54. package/src/screens/Unit/SelectLocation.js +0 -161
  55. package/src/screens/Unit/SelectLocationStyles.js +0 -114
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.58",
4
+ "version": "0.2.59",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -0,0 +1,139 @@
1
+ import React, { memo, useCallback, useState } from 'react';
2
+ import { TouchableOpacity, View, Switch, Image } from 'react-native';
3
+ import { Icon } from '@ant-design/react-native';
4
+ import { useTranslations } from '../../hooks/Common/useTranslations';
5
+ import styles from './CurtainButtonTemplateStyle';
6
+ import Text from '../Text';
7
+ import { TESTID } from '../../configs/Constants';
8
+ import { Colors, Images } from '../../configs';
9
+ import { Section } from '../../commons/Section';
10
+ import { IconOutline } from '@ant-design/icons-react-native';
11
+
12
+ const CurtainButtonTemplate = memo(({ actionGroup, doAction }) => {
13
+ const t = useTranslations();
14
+ const { configuration } = actionGroup;
15
+ const [lock, setLock] = useState(false);
16
+
17
+ const onButtonOpenPress = useCallback(
18
+ () => doAction(configuration.open_action_data),
19
+ [configuration.open_action_data, doAction]
20
+ );
21
+ const onButtonStopPress = useCallback(
22
+ () => doAction(configuration.stop_action_data),
23
+ [configuration.stop_action_data, doAction]
24
+ );
25
+ const onButtonClosePress = useCallback(
26
+ () => doAction(configuration.close_action_data),
27
+ [configuration.close_action_data, doAction]
28
+ );
29
+ const onChangeSwitch = useCallback(() => {
30
+ if (lock) {
31
+ setLock(false);
32
+ doAction(configuration.action_off_data);
33
+ return;
34
+ }
35
+ doAction(configuration.action_on_data);
36
+ setLock(true);
37
+ }, [
38
+ configuration.action_off_data,
39
+ configuration.action_on_data,
40
+ doAction,
41
+ lock,
42
+ ]);
43
+
44
+ const RenderThreeButtonActions = () => {
45
+ const buttons = [
46
+ {
47
+ style: styles.buttonActionCurtain,
48
+ icon: Images.buttonLeftCurtain,
49
+ text: configuration.text1,
50
+ onPress: onButtonOpenPress,
51
+ testID: TESTID.BUTTON_TEMPLATE_1,
52
+ },
53
+ {
54
+ style: styles.buttonActionCurtainCenter,
55
+ icon: Images.buttonPauseCurtain,
56
+ text: configuration.text2,
57
+ onPress: onButtonStopPress,
58
+ testID: TESTID.BUTTON_TEMPLATE_2,
59
+ },
60
+ {
61
+ style: styles.buttonActionCurtain,
62
+ icon: Images.buttonRightCurtain,
63
+ text: configuration.text3,
64
+ onPress: onButtonClosePress,
65
+ testID: TESTID.BUTTON_TEMPLATE_3,
66
+ },
67
+ ];
68
+
69
+ return (
70
+ <>
71
+ {buttons.map((item, index) => (
72
+ <TouchableOpacity
73
+ testID={item.testID}
74
+ style={item.style}
75
+ onPress={item.onPress}
76
+ underlayColor={Colors.Gray2}
77
+ >
78
+ <Image source={item.icon} />
79
+ </TouchableOpacity>
80
+ ))}
81
+ </>
82
+ );
83
+ };
84
+ const itemLock = (icon, color) => {
85
+ return (
86
+ <>
87
+ <View style={styles.lockDoor}>
88
+ <Icon name={icon} size={15} color={color} style={styles.iconLock} />
89
+ <Text
90
+ style={styles.textLockDoor}
91
+ testID={TESTID.TEXT_DOOR_LOOK_ON_OFF}
92
+ >
93
+ {configuration.text_door_lock}{' '}
94
+ </Text>
95
+ </View>
96
+ <Switch
97
+ trackColor={{ false: Colors.Gray4, true: Colors.Primary }}
98
+ thumbColor={Colors.White}
99
+ ios_backgroundColor={Colors.Gray4}
100
+ onValueChange={onChangeSwitch}
101
+ value={lock}
102
+ />
103
+ </>
104
+ );
105
+ };
106
+ return (
107
+ <>
108
+ <View style={styles.wrap}>
109
+ <RenderThreeButtonActions />
110
+ </View>
111
+ <View style={styles.lockSwitch}>
112
+ {configuration.is_display_lock &&
113
+ itemLock(
114
+ lock ? 'lock' : 'unlock',
115
+ lock ? Colors.Primary : Colors.Gray6
116
+ )}
117
+ </View>
118
+ <Section style={styles.section}>
119
+ <View style={styles.reminderOption}>
120
+ <Text type="H4" color={Colors.Gray8}>
121
+ {t('schedule')}
122
+ </Text>
123
+ <TouchableOpacity>
124
+ <IconOutline name="plus" size={20} />
125
+ </TouchableOpacity>
126
+ </View>
127
+ <View>
128
+ <TouchableOpacity style={styles.tapToAddSchedule}>
129
+ <Text type="Body" color={Colors.Gray6} center>
130
+ {t('tap_to_add_new_schedule')}
131
+ </Text>
132
+ </TouchableOpacity>
133
+ </View>
134
+ </Section>
135
+ </>
136
+ );
137
+ });
138
+
139
+ export default CurtainButtonTemplate;
@@ -0,0 +1,58 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ export default StyleSheet.create({
4
+ wrap: {
5
+ flexDirection: 'row',
6
+ justifyContent: 'space-around',
7
+ paddingVertical: 30,
8
+ },
9
+ text: {
10
+ fontSize: 14,
11
+ lineHeight: 22,
12
+ },
13
+ lockSwitch: {
14
+ flexDirection: 'row',
15
+ justifyContent: 'space-between',
16
+ marginBottom: 7,
17
+ },
18
+ iconLock: {
19
+ paddingBottom: 7,
20
+ },
21
+ textLockDoor: {
22
+ paddingLeft: 12,
23
+ height: 24,
24
+ fontSize: 16,
25
+ lineHeight: 24,
26
+ },
27
+ lockDoor: {
28
+ flexDirection: 'row',
29
+ alignItems: 'flex-end',
30
+ paddingLeft: 5,
31
+ },
32
+ section: {
33
+ marginHorizontal: 20,
34
+ borderRadius: 10,
35
+ },
36
+ reminderOption: {
37
+ flex: 1,
38
+ flexDirection: 'row',
39
+ justifyContent: 'space-between',
40
+ },
41
+ tapToAddSchedule: {
42
+ paddingVertical: 50,
43
+ },
44
+ buttonActionCurtain: {
45
+ flex: 1,
46
+ aspectRatio: 1,
47
+ marginHorizontal: 4,
48
+ alignItems: 'center',
49
+ justifyContent: 'center',
50
+ },
51
+ buttonActionCurtainCenter: {
52
+ flex: 1,
53
+ aspectRatio: 1,
54
+ alignItems: 'center',
55
+ justifyContent: 'center',
56
+ marginTop: 15,
57
+ },
58
+ });
@@ -0,0 +1,72 @@
1
+ import React from 'react';
2
+ import renderer, { act } from 'react-test-renderer';
3
+ import { TouchableOpacity } from 'react-native';
4
+
5
+ import CurtainButtonTemplate from '../CurtainButtonTemplate';
6
+ import { SCProvider } from '../../../context';
7
+ import { mockSCStore } from '../../../context/mockStore';
8
+
9
+ const wrapComponent = (actionGroup) => (
10
+ <SCProvider initState={mockSCStore({})}>
11
+ <CurtainButtonTemplate actionGroup={actionGroup} doAction={jest.fn()} />
12
+ </SCProvider>
13
+ );
14
+
15
+ describe('Test CurtainButtonTemplate', () => {
16
+ const actionGroup = {
17
+ configuration: {
18
+ action1: '2b949045-8e03-4c07-a855-7794ade2e69c',
19
+ action1_data: {
20
+ color: '#00979D',
21
+ command_prefer_over_bluetooth: true,
22
+ command_prefer_over_googlehome: false,
23
+ command_prefer_over_internet: false,
24
+ googlehome_actions: [],
25
+ icon: 'caret-up',
26
+ id: 9,
27
+ key: '2b949045-8e03-4c07-a855-7794ade2e69c',
28
+ },
29
+ action2: '38347d5e-4418-4ab0-978c-c82f4c034897',
30
+ action2_data: {
31
+ color: '#00979D',
32
+ command_prefer_over_bluetooth: true,
33
+ command_prefer_over_googlehome: false,
34
+ command_prefer_over_internet: false,
35
+ googlehome_actions: [],
36
+ icon: 'stop',
37
+ id: 11,
38
+ key: '38347d5e-4418-4ab0-978c-c82f4c034897',
39
+ },
40
+ action3: 'a492e08c-8cb1-44ee-8ea0-46aaca4e5141',
41
+ action3_data: {
42
+ color: '#00979D',
43
+ command_prefer_over_bluetooth: true,
44
+ command_prefer_over_googlehome: false,
45
+ command_prefer_over_internet: false,
46
+ googlehome_actions: [],
47
+ icon: 'caret-down',
48
+ id: 10,
49
+ key: 'a492e08c-8cb1-44ee-8ea0-46aaca4e5141',
50
+ },
51
+ icon1: 'caret-up',
52
+ icon2: 'stop',
53
+ icon3: 'caret-down',
54
+ text1: 'UP',
55
+ text2: 'STOP/UNLOCK',
56
+ text3: 'DOWN',
57
+ id: 1,
58
+ template: 'curtain_button_action_template',
59
+ },
60
+ };
61
+
62
+ let wrapper;
63
+
64
+ test('render CurtainButtonTemplate', async () => {
65
+ await act(() => {
66
+ wrapper = renderer.create(wrapComponent(actionGroup));
67
+ });
68
+ const instance = wrapper.root;
69
+ const touchableOpacities = instance.findAllByType(TouchableOpacity);
70
+ expect(touchableOpacities.length).toEqual(5);
71
+ });
72
+ });
@@ -8,6 +8,7 @@ import NumberUpDownActionTemplate from './NumberUpDownActionTemplate';
8
8
  import OptionsDropdownActionTemplate from './OptionsDropdownActionTemplate';
9
9
  import OnOffTemplate from './OnOffTemplate';
10
10
  import TimerActionTemplate from './TimerActionTemplate';
11
+ import CurtainButtonTemplate from './CurtainButtonTemplate';
11
12
 
12
13
  export const getActionComponent = (template) => {
13
14
  switch (template) {
@@ -29,6 +30,8 @@ export const getActionComponent = (template) => {
29
30
  return OptionsDropdownActionTemplate;
30
31
  case 'TimerActionTemplate':
31
32
  return TimerActionTemplate;
33
+ case 'curtain_action_template':
34
+ return CurtainButtonTemplate;
32
35
  default:
33
36
  return null;
34
37
  }
@@ -4,6 +4,7 @@ import {
4
4
  TextInput,
5
5
  StyleSheet,
6
6
  TouchableWithoutFeedback,
7
+ Platform,
7
8
  } from 'react-native';
8
9
  import Text from '../Text';
9
10
  import { Colors } from '../../configs';
@@ -117,7 +118,12 @@ const CurrencyInput = ({
117
118
  : formattedValue;
118
119
  }, [formattedValue, startingWithSign]);
119
120
 
120
- const currencyMarginLeft = textInputValue.toString().length < 2 ? -12 : 0;
121
+ const currencyMarginLeft = useMemo(() => {
122
+ if (Platform.OS === 'ios') {
123
+ return 5;
124
+ }
125
+ return textInputValue.toString().length < 2 ? -12 : 0;
126
+ }, [textInputValue]);
121
127
 
122
128
  return (
123
129
  <TouchableWithoutFeedback onPress={focusInput}>
@@ -68,4 +68,8 @@ export default StyleSheet.create({
68
68
  right: 0,
69
69
  bottom: 0,
70
70
  },
71
+ firstOpenCamera: {
72
+ zIndex: -10,
73
+ position: 'absolute',
74
+ },
71
75
  });
@@ -1,5 +1,19 @@
1
- import React, { memo, useCallback, useState, useEffect } from 'react';
2
- import { Image, View, StyleSheet, Text, TouchableOpacity } from 'react-native';
1
+ import React, {
2
+ memo,
3
+ useCallback,
4
+ useState,
5
+ useEffect,
6
+ useContext,
7
+ useMemo,
8
+ } from 'react';
9
+ import {
10
+ Image,
11
+ View,
12
+ StyleSheet,
13
+ Text,
14
+ TouchableOpacity,
15
+ Platform,
16
+ } from 'react-native';
3
17
  import { VLCPlayer } from 'react-native-vlc-media-player';
4
18
  import { useTranslations } from '../../hooks/Common/useTranslations';
5
19
 
@@ -9,6 +23,8 @@ import { colorOpacity } from '../../utils/Converter/color';
9
23
  import styles from './Styles/MediaPlayerDetailStyles';
10
24
  import FImage from '../../commons/FImage';
11
25
  import { TESTID } from '../../configs/Constants';
26
+ import { SCContext, useSCContextSelector } from '../../context';
27
+ import { Action } from '../../context/actionType';
12
28
 
13
29
  const MediaPlayerDetail = ({
14
30
  uri,
@@ -16,7 +32,6 @@ const MediaPlayerDetail = ({
16
32
  thumbnail,
17
33
  style,
18
34
  wrapStyles,
19
- resizeMode = 'none',
20
35
  amount,
21
36
  handleFullScreen,
22
37
  isPaused = true,
@@ -25,6 +40,10 @@ const MediaPlayerDetail = ({
25
40
  width,
26
41
  height,
27
42
  }) => {
43
+ const { setAction } = useContext(SCContext);
44
+ const isFirstOpenCamera = useSCContextSelector(
45
+ (state) => state.app.isFirstOpenCamera
46
+ );
28
47
  const t = useTranslations();
29
48
  const [paused, setPaused] = useState(isPaused);
30
49
  const onTapPause = useCallback(() => {
@@ -72,13 +91,63 @@ const MediaPlayerDetail = ({
72
91
  };
73
92
  }, [amount]);
74
93
 
94
+ const renderCamera = useMemo(() => {
95
+ return (
96
+ <VLCPlayer
97
+ autoAspectRatio={true}
98
+ videoAspectRatio={
99
+ width && height
100
+ ? `${width}:${height}`
101
+ : `${getWidthHeight().width}:${getWidthHeight().height}`
102
+ }
103
+ source={{
104
+ initType: 2,
105
+ hwDecoderEnabled: 1,
106
+ hwDecoderForced: 1,
107
+ uri,
108
+ initOptions: [
109
+ '--no-audio',
110
+ '--rtsp-tcp',
111
+ '--network-caching=150',
112
+ '--rtsp-caching=150',
113
+ '--no-stats',
114
+ '--tcp-caching=150',
115
+ '--realrtsp-caching=150',
116
+ ],
117
+ }}
118
+ style={[
119
+ styles.player,
120
+ style,
121
+ {
122
+ width: width || getWidthHeight().width,
123
+ height: height || getWidthHeight().height,
124
+ },
125
+ isFirstOpenCamera && styles.firstOpenCamera,
126
+ ]}
127
+ isLive={true}
128
+ />
129
+ );
130
+ // eslint-disable-next-line react-hooks/exhaustive-deps
131
+ }, [uri, isFirstOpenCamera]);
132
+
75
133
  useEffect(() => {
76
134
  setPaused(isPaused);
77
135
  }, [isPaused]);
78
136
 
137
+ useEffect(() => {
138
+ if (isFirstOpenCamera) {
139
+ const to = setTimeout(() => {
140
+ setAction(Action.IS_FIRST_OPEN_CAMERA, false);
141
+ clearTimeout(to);
142
+ }, 500);
143
+ }
144
+ // eslint-disable-next-line react-hooks/exhaustive-deps
145
+ }, [isFirstOpenCamera]);
146
+
79
147
  const source = !thumbnail || !thumbnail.uri ? Images.BgDevice : thumbnail;
80
148
  return (
81
149
  <View style={[styles.wrap, wrapStyles]}>
150
+ {isFirstOpenCamera && Platform.OS === 'ios' && renderCamera}
82
151
  <View style={[styles.loadingWrap]}>
83
152
  <Text style={styles.loadingText}>{t('loading')}</Text>
84
153
  </View>
@@ -103,42 +172,7 @@ const MediaPlayerDetail = ({
103
172
  />
104
173
  </View>
105
174
  ) : (
106
- <VLCPlayer
107
- autoAspectRatio={true}
108
- videoAspectRatio={
109
- width && height
110
- ? `${width}:${height}`
111
- : `${getWidthHeight().width}:${getWidthHeight().height}`
112
- }
113
- source={{
114
- initType: 2,
115
- hwDecoderEnabled: 1,
116
- hwDecoderForced: 1,
117
- uri,
118
- initOptions: [
119
- '--no-audio',
120
- '--rtsp-tcp',
121
- '--network-caching=150',
122
- '--rtsp-caching=150',
123
- '--no-stats',
124
- '--tcp-caching=150',
125
- '--realrtsp-caching=150',
126
- // '--avcodec-threads=20',
127
- // '--live-cacheing=150',
128
- ],
129
- }}
130
- style={[
131
- styles.player,
132
- style,
133
- {
134
- width: width || getWidthHeight().width,
135
- height: height || getWidthHeight().height,
136
- },
137
- ]}
138
- // resizeMode={resizeMode}
139
- isLive={true}
140
- // playInBackground={true}
141
- />
175
+ renderCamera
142
176
  )}
143
177
 
144
178
  <View style={styles.buttonView}>
@@ -23,7 +23,6 @@ const SearchBarLocation = memo(({ input, onTextInput }) => {
23
23
  onChangeText={onTextInput}
24
24
  placeholder={t('choose_location')}
25
25
  placeholderTextColor={Colors.Gray6}
26
- underlineColorAndroid={null}
27
26
  />
28
27
  </View>
29
28
  );
@@ -84,7 +84,7 @@ const ShortDetailSubUnit = ({ unit, station, isGGHomeConnected }) => {
84
84
  const itemAddNewTitle = t(
85
85
  station?.isFavorites
86
86
  ? 'add_to_favorites'
87
- : station?.name === SubUnitName.scenario
87
+ : station?.name === SubUnitName.smart
88
88
  ? 'add_script'
89
89
  : 'add_new'
90
90
  );
@@ -179,9 +179,9 @@ const API = {
179
179
  },
180
180
  },
181
181
  NOTIFICATION: {
182
- LIST_ALL_NOTIFICATIONS: (page, type) =>
183
- SCConfig.apiRoot + `/notifications/root/?page=${page}&type=${type}`,
184
- SET_READ: (id) => SCConfig.apiRoot + `/notifications/root/${id}/set_read/`,
182
+ LIST_EOH_NOTIFICATIONS: (page, type) =>
183
+ SCConfig.apiRoot + `/notifications/eoh/?page=${page}&type=${type}`,
184
+ SET_READ: (id) => SCConfig.apiRoot + `/notifications/eoh/${id}/set_read/`,
185
185
  },
186
186
  EXTERNAL: {
187
187
  GOOGLE_MAP: {
@@ -189,6 +189,8 @@ const API = {
189
189
  'https://maps.googleapis.com/maps/api/place/autocomplete/json',
190
190
  GET_LAT_LNG_BY_PLACE_ID:
191
191
  'https://maps.googleapis.com/maps/api/place/details/json',
192
+ GET_LOCATION_FROM_LAT_LNG:
193
+ 'https://maps.googleapis.com/maps/api/geocode/json',
192
194
  },
193
195
  },
194
196
  SMART_ACCOUNT: {
@@ -84,7 +84,7 @@ export const SCANNING_STATUS = {
84
84
  };
85
85
 
86
86
  export const SubUnitName = {
87
- scenario: 'Kịch Bản',
87
+ smart: 'Kịch Bản',
88
88
  };
89
89
 
90
90
  export const AUTOMATE_TYPE = {
@@ -572,6 +572,10 @@ export const TESTID = {
572
572
  // ThreeButtonHistory
573
573
  HISTORY_BUTTON: 'HISTORY_BUTTON',
574
574
  HISTORY_CALENDAR: 'HISTORY_CALENDAR',
575
+
576
+ // SelectAddress
577
+ BUTTON_YOUR_LOCATION: 'BUTTON_YOUR_LOCATION',
578
+ BUTTON_CHOOSE_ON_MAP: 'BUTTON_CHOOSE_ON_MAP',
575
579
  };
576
580
 
577
581
  export const NOTIFICATION_TYPES = {
@@ -7,4 +7,7 @@ export default {
7
7
  file: require('../Images/Common/file.png'),
8
8
  activeButton: require('../Images/Common/ActiveButton.png'),
9
9
  logo: require('../Images/Common/logo.png'),
10
+ buttonPauseCurtain: require('../Images/Common/buttonPause-center-curtain.png'),
11
+ buttonLeftCurtain: require('../Images/Common/buttonLeftCurtain.png'),
12
+ buttonRightCurtain: require('../Images/Common/buttonRightCurtain.png'),
10
13
  };
@@ -4,6 +4,7 @@ export const Action = {
4
4
  STORE_STATUS_BAR: 'STORE_STATUS_BAR',
5
5
  LIST_DEVICE_TYPES: 'LIST_DEVICE_TYPES',
6
6
  LIST_ACTION: 'LIST_ACTION',
7
+ IS_FIRST_OPEN_CAMERA: 'IS_FIRST_OPEN_CAMERA',
7
8
  };
8
9
 
9
10
  export type AuthData = {
@@ -44,3 +45,7 @@ export type ActionDataMap = {
44
45
  LIST_DEVICE_TYPES: ListDevice;
45
46
  LIST_ACTION: ListAction;
46
47
  };
48
+
49
+ export type AppType = {
50
+ isFirstOpenCamera: boolean;
51
+ };
@@ -47,5 +47,8 @@ export const mockSCStore = (data: ContextData): ContextData => {
47
47
  barStyle: data?.statusBar?.barStyle || mockDataStore?.statusBar?.barStyle,
48
48
  },
49
49
  listAction: [...mockDataStore.listAction, ...(data?.listAction || [])],
50
+ app: {
51
+ isFirstOpenCamera: true,
52
+ },
50
53
  };
51
54
  };
@@ -7,6 +7,7 @@ import {
7
7
  Action,
8
8
  ListDevice,
9
9
  ListAction,
10
+ AppType,
10
11
  } from './actionType';
11
12
 
12
13
  export type ContextData = {
@@ -15,6 +16,7 @@ export type ContextData = {
15
16
  listDevice: ListDevice;
16
17
  listAction: ListAction;
17
18
  statusBar: StatusBar;
19
+ app: AppType;
18
20
  };
19
21
 
20
22
  export type Action = {
@@ -35,6 +37,9 @@ export const initialState = {
35
37
  statusBar: {} as StatusBar,
36
38
  listDevice: {} as ListDevice,
37
39
  listAction: [] as ListAction,
40
+ app: {
41
+ isFirstOpenCamera: true,
42
+ },
38
43
  };
39
44
 
40
45
  export const reducer = (currentState: ContextData, action: Action) => {
@@ -83,6 +88,15 @@ export const reducer = (currentState: ContextData, action: Action) => {
83
88
  }
84
89
 
85
90
  return { ...currentState, listAction: newListAction };
91
+
92
+ case Action.IS_FIRST_OPEN_CAMERA:
93
+ return {
94
+ ...currentState,
95
+ app: {
96
+ ...currentState.app,
97
+ isFirstOpenCamera: payload,
98
+ },
99
+ };
86
100
  default:
87
101
  return currentState;
88
102
  }