@holper/react-native-holper-storybook 0.6.76 → 0.6.77
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/lib/components/CustomChatView/index.js +73 -0
- package/lib/components/CustomChatView/style.js +10 -0
- package/lib/components/TakePicture/index.js +21 -42
- package/lib/components/TakePicture/style.js +19 -11
- package/lib/components/UploadDocument/index.js +8 -6
- package/lib/components/index.js +28 -27
- package/package.json +5 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import MapView, { PROVIDER_GOOGLE } from "react-native-maps";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { Platform, TouchableOpacity, Alert, Linking } from "react-native";
|
|
5
|
+
import { MapStyle } from "../../configs/constants";
|
|
6
|
+
import styles from "./style";
|
|
7
|
+
|
|
8
|
+
const CustomChatView = ({ currentMessage, containerStyle, mapViewStyle }) => {
|
|
9
|
+
const openMapAsync = async () => {
|
|
10
|
+
const { location = {} } = currentMessage;
|
|
11
|
+
|
|
12
|
+
const mapScheme = Platform.select({
|
|
13
|
+
ios: "maps:0,0?q=",
|
|
14
|
+
android: "geo:0,0?q=",
|
|
15
|
+
});
|
|
16
|
+
const latLng = `${location.latitude},${location.longitude}`;
|
|
17
|
+
const label = `${currentMessage.user.name}`;
|
|
18
|
+
|
|
19
|
+
const url = Platform.select({
|
|
20
|
+
ios: `${mapScheme}${label}@${latLng}`,
|
|
21
|
+
android: `${mapScheme}${latLng}(${label})`,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const supported = await Linking.canOpenURL(url);
|
|
26
|
+
if (supported) {
|
|
27
|
+
return Linking.openURL(url);
|
|
28
|
+
}
|
|
29
|
+
Alert.alert("Opening the map is not supported.");
|
|
30
|
+
} catch ({ message }) {
|
|
31
|
+
Alert.alert(message);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
if (currentMessage.location) {
|
|
36
|
+
return (
|
|
37
|
+
<TouchableOpacity
|
|
38
|
+
style={[styles.container, containerStyle]}
|
|
39
|
+
onPress={openMapAsync}
|
|
40
|
+
>
|
|
41
|
+
<MapView
|
|
42
|
+
style={[styles.mapView, mapViewStyle]}
|
|
43
|
+
region={{
|
|
44
|
+
latitude: currentMessage.location.latitude,
|
|
45
|
+
longitude: currentMessage.location.longitude,
|
|
46
|
+
latitudeDelta: currentMessage.location.latitudeDelta || 0.0922,
|
|
47
|
+
longitudeDelta: currentMessage.location.longitudeDelta || 0.0421,
|
|
48
|
+
}}
|
|
49
|
+
customMapStyle={MapStyle}
|
|
50
|
+
provider={PROVIDER_GOOGLE}
|
|
51
|
+
scrollEnabled={false}
|
|
52
|
+
zoomEnabled={false}
|
|
53
|
+
/>
|
|
54
|
+
</TouchableOpacity>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return null;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
CustomChatView.propTypes = {
|
|
62
|
+
currentMessage: PropTypes.object,
|
|
63
|
+
containerStyle: PropTypes.object,
|
|
64
|
+
mapViewStyle: PropTypes.object,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
CustomChatView.defaultProps = {
|
|
68
|
+
currentMessage: {},
|
|
69
|
+
containerStyle: {},
|
|
70
|
+
mapViewStyle: {},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default CustomChatView;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useRef
|
|
1
|
+
import React, { useState, useRef } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import {
|
|
4
4
|
Modal,
|
|
@@ -8,11 +8,12 @@ import {
|
|
|
8
8
|
ActivityIndicator,
|
|
9
9
|
} from 'react-native';
|
|
10
10
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
|
11
|
-
import { CameraView,
|
|
11
|
+
import { CameraView, useCameraPermissions } from 'expo-camera';
|
|
12
12
|
import * as ImageManipulator from 'expo-image-manipulator';
|
|
13
13
|
import { Svg, Defs, Rect, Mask, Circle } from 'react-native-svg';
|
|
14
14
|
import Text from '../Text';
|
|
15
15
|
import Container from '../Container';
|
|
16
|
+
import Button from '../Button';
|
|
16
17
|
import { Colors } from '../../configs/constants';
|
|
17
18
|
import { ConfirmPictureModal } from './confirmPictureModal';
|
|
18
19
|
import style from './style';
|
|
@@ -46,44 +47,19 @@ const TakePicture = ({
|
|
|
46
47
|
onClose,
|
|
47
48
|
avatar,
|
|
48
49
|
cameraErrorMessage,
|
|
50
|
+
requestPermissionsMessage,
|
|
49
51
|
processingPictureMessage,
|
|
50
52
|
repeatPictureText,
|
|
51
53
|
usePictureText,
|
|
52
54
|
}) => {
|
|
53
|
-
const [
|
|
54
|
-
const [type, setType] = useState(
|
|
55
|
+
const [permission, requestPermission] = useCameraPermissions();
|
|
56
|
+
const [type, setType] = useState('back');
|
|
55
57
|
const [image, setImage] = useState(null);
|
|
56
58
|
const [takingPicture, setTakingPicture] = useState(false);
|
|
57
|
-
const [ratio, setRatio] = useState(DESIRED_RATIO);
|
|
58
59
|
const camera = useRef();
|
|
59
60
|
|
|
60
|
-
useEffect(() => {
|
|
61
|
-
(async () => {
|
|
62
|
-
const { status } = await CameraView.requestCameraPermissionsAsync();
|
|
63
|
-
setHasCameraPermission(status === 'granted');
|
|
64
|
-
})();
|
|
65
|
-
}, [visible]);
|
|
66
|
-
|
|
67
|
-
const prepareRatio = async () => {
|
|
68
|
-
if (isAndroid && camera) {
|
|
69
|
-
const ratios = await CameraView.getSupportedRatiosAsync();
|
|
70
|
-
|
|
71
|
-
// See if the current device has your desired ratio, otherwise get the maximum supported one
|
|
72
|
-
// Usually the last element of 'ratios' is the maximum supported ratio
|
|
73
|
-
const supportedRatio =
|
|
74
|
-
ratios.find((ratio) => ratio === DESIRED_RATIO) ||
|
|
75
|
-
ratios[ratios.length - 1];
|
|
76
|
-
|
|
77
|
-
setRatio(supportedRatio);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
61
|
const flipCamera = () => {
|
|
82
|
-
setType(
|
|
83
|
-
type === CameraView.Constants.Type.back
|
|
84
|
-
? CameraView.Constants.Type.front
|
|
85
|
-
: CameraView.Constants.Type.back
|
|
86
|
-
);
|
|
62
|
+
setType((current) => (current === 'back' ? 'front' : 'back'));
|
|
87
63
|
};
|
|
88
64
|
|
|
89
65
|
const takePicture = async () => {
|
|
@@ -130,12 +106,15 @@ const TakePicture = ({
|
|
|
130
106
|
onClose();
|
|
131
107
|
};
|
|
132
108
|
|
|
133
|
-
if (
|
|
134
|
-
return
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
109
|
+
if (!permission || permission.status !== 'granted') {
|
|
110
|
+
return (
|
|
111
|
+
<View style={style.cameraPermissionsContainer}>
|
|
112
|
+
<Text color='red'>{cameraErrorMessage}</Text>
|
|
113
|
+
<Button onPress={requestPermission} color='inverted'>
|
|
114
|
+
<Text color='white'>{requestPermissionsMessage}</Text>
|
|
115
|
+
</Button>
|
|
116
|
+
</View>
|
|
117
|
+
);
|
|
139
118
|
}
|
|
140
119
|
|
|
141
120
|
return (
|
|
@@ -143,16 +122,14 @@ const TakePicture = ({
|
|
|
143
122
|
animationType='slide'
|
|
144
123
|
transparent={false}
|
|
145
124
|
visible={visible}
|
|
146
|
-
onRequestClose={
|
|
125
|
+
onRequestClose={onClose}
|
|
147
126
|
>
|
|
148
127
|
<Container style={style.cameraContainer}>
|
|
149
128
|
<CameraView
|
|
150
129
|
ref={camera}
|
|
151
130
|
style={style.cameraContainer}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
onCameraReady={prepareRatio} // You can only get the supported ratios when the camera is mounted
|
|
155
|
-
ratio={ratio}
|
|
131
|
+
facing={type}
|
|
132
|
+
ratio={DESIRED_RATIO}
|
|
156
133
|
>
|
|
157
134
|
{avatar && isiOS && <SvgCircle />}
|
|
158
135
|
|
|
@@ -211,6 +188,7 @@ TakePicture.defaultProps = {
|
|
|
211
188
|
onClose: () => {},
|
|
212
189
|
avatar: false,
|
|
213
190
|
cameraErrorMessage: ' ',
|
|
191
|
+
requestPermissionsMessage: ' ',
|
|
214
192
|
processingPictureMessage: ' ',
|
|
215
193
|
repeatPictureText: ' ',
|
|
216
194
|
usePictureText: ' ',
|
|
@@ -221,6 +199,7 @@ TakePicture.propTypes = {
|
|
|
221
199
|
onClose: PropTypes.func.isRequired,
|
|
222
200
|
avatar: PropTypes.bool,
|
|
223
201
|
cameraErrorMessage: PropTypes.string.isRequired,
|
|
202
|
+
requestPermissionsMessage: PropTypes.string.isRequired,
|
|
224
203
|
processingPictureMessage: PropTypes.string.isRequired,
|
|
225
204
|
repeatPictureText: PropTypes.string.isRequired,
|
|
226
205
|
usePictureText: PropTypes.string.isRequired,
|
|
@@ -7,7 +7,7 @@ export default {
|
|
|
7
7
|
cameraContainer: {
|
|
8
8
|
flex: 1,
|
|
9
9
|
...StyleSheet.absoluteFillObject,
|
|
10
|
-
position: 'absolute'
|
|
10
|
+
position: 'absolute',
|
|
11
11
|
},
|
|
12
12
|
closeIcon: {
|
|
13
13
|
position: 'absolute',
|
|
@@ -19,7 +19,7 @@ export default {
|
|
|
19
19
|
borderRadius: 15,
|
|
20
20
|
backgroundColor: Colors.lightblue,
|
|
21
21
|
alignItems: 'center',
|
|
22
|
-
justifyContent: 'center'
|
|
22
|
+
justifyContent: 'center',
|
|
23
23
|
},
|
|
24
24
|
cameraFlipContainer: {
|
|
25
25
|
flex: 1,
|
|
@@ -27,7 +27,7 @@ export default {
|
|
|
27
27
|
flexDirection: 'row',
|
|
28
28
|
position: 'relative',
|
|
29
29
|
marginBottom: 20,
|
|
30
|
-
...StyleSheet.absoluteFillObject
|
|
30
|
+
...StyleSheet.absoluteFillObject,
|
|
31
31
|
},
|
|
32
32
|
cameraFlipBtn: {
|
|
33
33
|
flex: 0.2,
|
|
@@ -35,17 +35,17 @@ export default {
|
|
|
35
35
|
alignItems: 'center',
|
|
36
36
|
paddingLeft: 15,
|
|
37
37
|
paddingBottom: 10,
|
|
38
|
-
height: 60
|
|
38
|
+
height: 60,
|
|
39
39
|
},
|
|
40
40
|
cameraFlipIcon: {
|
|
41
41
|
position: 'absolute',
|
|
42
42
|
bottom: 10,
|
|
43
|
-
left: 25
|
|
43
|
+
left: 25,
|
|
44
44
|
},
|
|
45
45
|
cameraRecordBtn: {
|
|
46
46
|
position: 'absolute',
|
|
47
47
|
bottom: 0,
|
|
48
|
-
left:
|
|
48
|
+
left: width / 2 - 25,
|
|
49
49
|
},
|
|
50
50
|
cameraRetakePhoto: {
|
|
51
51
|
height: 40,
|
|
@@ -58,17 +58,17 @@ export default {
|
|
|
58
58
|
paddingHorizontal: 30,
|
|
59
59
|
position: 'absolute',
|
|
60
60
|
bottom: 0,
|
|
61
|
-
left: 0
|
|
61
|
+
left: 0,
|
|
62
62
|
},
|
|
63
63
|
cameraRetakePhotoText: {
|
|
64
|
-
color: Colors.white
|
|
64
|
+
color: Colors.white,
|
|
65
65
|
},
|
|
66
66
|
cameraTakingPictureOverlay: {
|
|
67
67
|
...StyleSheet.absoluteFillObject,
|
|
68
68
|
justifyContent: 'center',
|
|
69
69
|
alignItems: 'center',
|
|
70
70
|
zIndex: 999,
|
|
71
|
-
backgroundColor: 'rgba(0, 0, 0, 0.8)'
|
|
71
|
+
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
72
72
|
},
|
|
73
73
|
cameraTakenImageContainer: {
|
|
74
74
|
backgroundColor: 'rgba(0,0,0,0.9)',
|
|
@@ -76,12 +76,20 @@ export default {
|
|
|
76
76
|
...StyleSheet.absoluteFillObject,
|
|
77
77
|
position: 'absolute',
|
|
78
78
|
justifyContent: 'center',
|
|
79
|
-
alignItems: 'center'
|
|
79
|
+
alignItems: 'center',
|
|
80
80
|
},
|
|
81
81
|
cameraTakenImage: {
|
|
82
82
|
width: width - 30,
|
|
83
83
|
height: width - 30,
|
|
84
84
|
alignSelf: 'center',
|
|
85
|
-
position: 'relative'
|
|
85
|
+
position: 'relative',
|
|
86
|
+
},
|
|
87
|
+
cameraPermissionsContainer: {
|
|
88
|
+
flex: 1,
|
|
89
|
+
...StyleSheet.absoluteFillObject,
|
|
90
|
+
position: 'absolute',
|
|
91
|
+
backgroundColor: Colors.white,
|
|
92
|
+
justifyContent: 'center',
|
|
93
|
+
alignItems: 'center',
|
|
86
94
|
},
|
|
87
95
|
};
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
ActivityIndicator,
|
|
7
7
|
Platform,
|
|
8
8
|
} from 'react-native';
|
|
9
|
-
import {
|
|
9
|
+
import { CameraView, useCameraPermissions } from 'expo-camera';
|
|
10
10
|
import * as MediaLibrary from 'expo-media-library';
|
|
11
11
|
import * as ExpoImagePicker from 'expo-image-picker';
|
|
12
12
|
import Text from '../Text';
|
|
@@ -35,6 +35,7 @@ const UploadDocument = ({
|
|
|
35
35
|
file,
|
|
36
36
|
onPermissionDenied,
|
|
37
37
|
}) => {
|
|
38
|
+
const [permission, requestPermission] = useCameraPermissions();
|
|
38
39
|
const [showMediaModal, setShowMediaModal] = useState(false);
|
|
39
40
|
const [showCamera, setShowCamera] = useState(false);
|
|
40
41
|
const [image, setImage] = useState(null);
|
|
@@ -42,7 +43,7 @@ const UploadDocument = ({
|
|
|
42
43
|
|
|
43
44
|
useEffect(() => {
|
|
44
45
|
(async () => {
|
|
45
|
-
await
|
|
46
|
+
await requestPermission();
|
|
46
47
|
iOS
|
|
47
48
|
? await MediaLibrary.requestPermissionsAsync()
|
|
48
49
|
: await ExpoImagePicker.getMediaLibraryPermissionsAsync();
|
|
@@ -60,10 +61,7 @@ const UploadDocument = ({
|
|
|
60
61
|
|
|
61
62
|
switch (method) {
|
|
62
63
|
case 'camera':
|
|
63
|
-
|
|
64
|
-
await Camera.getCameraPermissionsAsync();
|
|
65
|
-
|
|
66
|
-
if (cameraStatus !== 'granted') {
|
|
64
|
+
if (permission && permission.status !== 'granted') {
|
|
67
65
|
onPermissionDenied();
|
|
68
66
|
return;
|
|
69
67
|
}
|
|
@@ -167,6 +165,8 @@ const UploadDocument = ({
|
|
|
167
165
|
|
|
168
166
|
<TakePicture
|
|
169
167
|
visible={showCamera}
|
|
168
|
+
cameraErrorMessage={takePicture.cameraErrorMessage}
|
|
169
|
+
requestPermissionsMessage={takePicture.requestPermissionsMessage}
|
|
170
170
|
processingPictureMessage={takePicture.processingPictureMessage}
|
|
171
171
|
repeatPictureText={takePicture.repeatPictureText}
|
|
172
172
|
usePictureText={takePicture.usePictureText}
|
|
@@ -204,6 +204,7 @@ UploadDocument.defaultProps = {
|
|
|
204
204
|
},
|
|
205
205
|
takePicture: {
|
|
206
206
|
cameraErrorMessage: ' ',
|
|
207
|
+
requestPermissionsMessage: ' ',
|
|
207
208
|
processingPictureMessage: ' ',
|
|
208
209
|
repeatPictureText: ' ',
|
|
209
210
|
usePictureText: ' ',
|
|
@@ -230,6 +231,7 @@ UploadDocument.propTypes = {
|
|
|
230
231
|
}),
|
|
231
232
|
takePicture: PropTypes.shape({
|
|
232
233
|
cameraErrorMessage: PropTypes.string,
|
|
234
|
+
requestPermissionsMessage: PropTypes.string,
|
|
233
235
|
processingPictureMessage: PropTypes.string,
|
|
234
236
|
repeatPictureText: PropTypes.string,
|
|
235
237
|
usePictureText: PropTypes.string,
|
package/lib/components/index.js
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
export { default as Button } from
|
|
2
|
-
export { default as Card } from
|
|
3
|
-
export { default as ConfirmationModal } from
|
|
4
|
-
export { default as Container } from
|
|
5
|
-
export { default as DeckSwiper } from
|
|
6
|
-
export { default as FlashMessage, sendMessage } from
|
|
7
|
-
export { default as FloatingContainer } from
|
|
8
|
-
export { default as Footer } from
|
|
9
|
-
export { default as Header } from
|
|
10
|
-
export { default as ImagePicker } from
|
|
11
|
-
export { default as ImageResponsive } from
|
|
12
|
-
export { default as ImageViewer } from
|
|
13
|
-
export { default as Input } from
|
|
14
|
-
export { default as InputPin } from
|
|
15
|
-
export { default as MenuItem } from
|
|
16
|
-
export { default as NavigationTitle } from
|
|
17
|
-
export { default as Notification } from
|
|
18
|
-
export { default as Select } from
|
|
19
|
-
export { default as SwipeablePanel } from
|
|
20
|
-
export { default as Switch } from
|
|
21
|
-
export { default as TakePicture } from
|
|
22
|
-
export { default as Text } from
|
|
23
|
-
export { default as Textarea } from
|
|
24
|
-
export { default as TimeOutButton } from
|
|
25
|
-
export { default as UploadDocument } from
|
|
26
|
-
export { default as VirtualKeyboard } from
|
|
27
|
-
export { default as withPreventDoubleClick } from
|
|
1
|
+
export { default as Button } from "./Button";
|
|
2
|
+
export { default as Card } from "./Card";
|
|
3
|
+
export { default as ConfirmationModal } from "./ConfirmationModal";
|
|
4
|
+
export { default as Container } from "./Container";
|
|
5
|
+
export { default as DeckSwiper } from "./DeckSwiper";
|
|
6
|
+
export { default as FlashMessage, sendMessage } from "./FlashMessage";
|
|
7
|
+
export { default as FloatingContainer } from "./FloatingContainer";
|
|
8
|
+
export { default as Footer } from "./Footer";
|
|
9
|
+
export { default as Header } from "./Header";
|
|
10
|
+
export { default as ImagePicker } from "./ImagePicker";
|
|
11
|
+
export { default as ImageResponsive } from "./ImageResponsive";
|
|
12
|
+
export { default as ImageViewer } from "./ImageViewer";
|
|
13
|
+
export { default as Input } from "./Input";
|
|
14
|
+
export { default as InputPin } from "./InputPin";
|
|
15
|
+
export { default as MenuItem } from "./MenuItem";
|
|
16
|
+
export { default as NavigationTitle } from "./NavigationTitle";
|
|
17
|
+
export { default as Notification } from "./Notification";
|
|
18
|
+
export { default as Select } from "./Select";
|
|
19
|
+
export { default as SwipeablePanel } from "./SwipeablePanel";
|
|
20
|
+
export { default as Switch } from "./Switch";
|
|
21
|
+
export { default as TakePicture } from "./TakePicture";
|
|
22
|
+
export { default as Text } from "./Text";
|
|
23
|
+
export { default as Textarea } from "./Textarea";
|
|
24
|
+
export { default as TimeOutButton } from "./TimeOutButton";
|
|
25
|
+
export { default as UploadDocument } from "./UploadDocument";
|
|
26
|
+
export { default as VirtualKeyboard } from "./VirtualKeyboard";
|
|
27
|
+
export { default as withPreventDoubleClick } from "./PreventDoubleClick";
|
|
28
|
+
export { default as CustomChatView } from "./CustomChatView";
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"main": "lib/index.js",
|
|
3
3
|
"name": "@holper/react-native-holper-storybook",
|
|
4
4
|
"description": "A component library for Holper projects",
|
|
5
|
-
"version": "0.6.
|
|
5
|
+
"version": "0.6.77",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"files": [
|
|
8
8
|
"lib",
|
|
@@ -49,6 +49,8 @@
|
|
|
49
49
|
"react-native-deck-swiper": "^2.0.16",
|
|
50
50
|
"react-native-dropdown-picker": "^5.4.6",
|
|
51
51
|
"react-native-flash-message": "^0.4.2",
|
|
52
|
+
"react-native-maps": "1.18.0",
|
|
53
|
+
"react-native-maps-directions": "1.9.0",
|
|
52
54
|
"react-native-safe-area-context": "4.12.0",
|
|
53
55
|
"react-native-status-bar-height": "^2.6.0",
|
|
54
56
|
"react-native-svg": "15.8.0",
|
|
@@ -79,6 +81,8 @@
|
|
|
79
81
|
"doctor": {
|
|
80
82
|
"reactNativeDirectoryCheck": {
|
|
81
83
|
"exclude": [
|
|
84
|
+
"react-native-maps",
|
|
85
|
+
"react-native-maps-directions",
|
|
82
86
|
"react-native-status-bar-height"
|
|
83
87
|
],
|
|
84
88
|
"listUnknownPackages": false
|