@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.
@@ -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;
@@ -0,0 +1,10 @@
1
+ export default {
2
+ container: {},
3
+ mapView: {
4
+ flexDirection: "column-reverse",
5
+ width: 250,
6
+ height: 150,
7
+ borderRadius: 13,
8
+ margin: 3,
9
+ },
10
+ };
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef, useEffect } from 'react';
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, FlashMode } from 'expo-camera';
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 [hasCameraPermission, setHasCameraPermission] = useState(null);
54
- const [type, setType] = useState(CameraView.Constants.Type.back);
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 (hasCameraPermission === null) {
134
- return <View />;
135
- }
136
-
137
- if (hasCameraPermission === false) {
138
- return <Text>{cameraErrorMessage}</Text>;
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
- type={type}
153
- flashMode={FlashMode.off}
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: (width / 2) - 25
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 { Camera } from 'expo-camera';
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 Camera.requestCameraPermissionsAsync();
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
- const { status: cameraStatus } =
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,
@@ -1,27 +1,28 @@
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';
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.76",
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