@holper/react-native-holper-storybook 0.6.35 → 0.6.37
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/ImagePicker/index.js +7 -13
- package/lib/components/Select/index.js +2 -2
- package/lib/components/Select/style.js +6 -1
- package/lib/components/TakePicture/index.js +87 -59
- package/lib/components/TimeOutButton/index.js +69 -59
- package/lib/components/UploadDocument/index.js +65 -43
- package/package.json +2 -2
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
|
-
import {Camera} from 'expo-camera';
|
|
3
2
|
import * as ExpoImagePicker from 'expo-image-picker';
|
|
4
3
|
|
|
5
4
|
const ImagePicker = async (avatar) => {
|
|
6
|
-
const {status} = await Camera.requestCameraPermissionsAsync();
|
|
7
|
-
|
|
8
|
-
if (status !== 'granted') {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
5
|
const image = await ExpoImagePicker.launchImageLibraryAsync({
|
|
13
|
-
mediaTypes: ExpoImagePicker.MediaTypeOptions.
|
|
6
|
+
mediaTypes: ExpoImagePicker.MediaTypeOptions.Images,
|
|
14
7
|
allowsEditing: avatar,
|
|
15
|
-
aspect: [4, 3]
|
|
8
|
+
aspect: [4, 3],
|
|
9
|
+
quality: 1,
|
|
16
10
|
});
|
|
17
11
|
|
|
18
|
-
if (image.
|
|
12
|
+
if (image.canceled) {
|
|
19
13
|
return;
|
|
20
14
|
}
|
|
21
15
|
|
|
22
|
-
return image;
|
|
16
|
+
return image.assets[0].uri;
|
|
23
17
|
};
|
|
24
18
|
|
|
25
19
|
ImagePicker.defaultProps = {
|
|
26
|
-
avatar: false
|
|
20
|
+
avatar: false,
|
|
27
21
|
};
|
|
28
22
|
|
|
29
23
|
ImagePicker.propTypes = {
|
|
30
|
-
avatar: PropTypes.bool
|
|
24
|
+
avatar: PropTypes.bool,
|
|
31
25
|
};
|
|
32
26
|
|
|
33
27
|
export default ImagePicker;
|
|
@@ -3,12 +3,12 @@ import { View } from "react-native";
|
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import DropDownPicker from "react-native-dropdown-picker";
|
|
5
5
|
import style, {
|
|
6
|
-
fontStyle,
|
|
7
6
|
includesSelect,
|
|
8
7
|
placeholderStyle,
|
|
9
8
|
listItemLabelStyle,
|
|
10
9
|
listItemContainerStyle,
|
|
11
10
|
selectedItemLabelStyle,
|
|
11
|
+
textStyle,
|
|
12
12
|
} from "./style";
|
|
13
13
|
import { useEffect } from "react";
|
|
14
14
|
|
|
@@ -51,7 +51,7 @@ const Select = ({
|
|
|
51
51
|
listItemContainerStyle={listItemContainerStyle}
|
|
52
52
|
selectedItemLabelStyle={selectedItemLabelStyle}
|
|
53
53
|
listMode="MODAL"
|
|
54
|
-
textStyle={
|
|
54
|
+
textStyle={textStyle}
|
|
55
55
|
dropDownContainerStyle={{
|
|
56
56
|
...includesSelect[variant],
|
|
57
57
|
height: "auto",
|
|
@@ -21,7 +21,7 @@ export default {
|
|
|
21
21
|
},
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
const fontStyle = {
|
|
25
25
|
color: Colors.darkblue,
|
|
26
26
|
fontFamily: "poppins_regular",
|
|
27
27
|
};
|
|
@@ -74,3 +74,8 @@ export const listItemContainerStyle = {
|
|
|
74
74
|
export const selectedItemLabelStyle = {
|
|
75
75
|
fontFamily: "poppins_semiBold",
|
|
76
76
|
};
|
|
77
|
+
|
|
78
|
+
export const textStyle = {
|
|
79
|
+
...fontStyle,
|
|
80
|
+
fontSize: 16,
|
|
81
|
+
};
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import React, {useState, useRef, useEffect} from 'react';
|
|
1
|
+
import React, { useState, useRef, useEffect } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Modal,
|
|
5
|
+
TouchableOpacity,
|
|
6
|
+
Platform,
|
|
7
|
+
View,
|
|
8
|
+
ActivityIndicator,
|
|
9
|
+
} from 'react-native';
|
|
4
10
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
|
5
|
-
import {Camera} from 'expo-camera';
|
|
11
|
+
import { Camera, FlashMode } from 'expo-camera';
|
|
6
12
|
import * as ImageManipulator from 'expo-image-manipulator';
|
|
7
|
-
import {Svg, Defs, Rect, Mask, Circle} from 'react-native-svg';
|
|
13
|
+
import { Svg, Defs, Rect, Mask, Circle } from 'react-native-svg';
|
|
8
14
|
import Text from '../Text';
|
|
9
15
|
import Container from '../Container';
|
|
10
16
|
import ImageResponsive from '../ImageResponsive';
|
|
11
|
-
import {Colors} from '../../configs/constants';
|
|
17
|
+
import { Colors } from '../../configs/constants';
|
|
12
18
|
import style from './style';
|
|
13
19
|
|
|
14
20
|
const DESIRED_RATIO = '16:9';
|
|
@@ -20,77 +26,85 @@ const SvgCircle = () => {
|
|
|
20
26
|
<Svg height='100%' width='100%'>
|
|
21
27
|
<Defs>
|
|
22
28
|
<Mask id='mask' x='0' y='0' height='100%' width='100%'>
|
|
23
|
-
<Rect height='100%' width='100%' fill={Colors.white}/>
|
|
24
|
-
<Circle r='29%' cx='50%' cy='50%' fill={Colors.darkgray}/>
|
|
29
|
+
<Rect height='100%' width='100%' fill={Colors.white} />
|
|
30
|
+
<Circle r='29%' cx='50%' cy='50%' fill={Colors.darkgray} />
|
|
25
31
|
</Mask>
|
|
26
32
|
</Defs>
|
|
27
|
-
<Rect
|
|
33
|
+
<Rect
|
|
34
|
+
height='100%'
|
|
35
|
+
width='100%'
|
|
36
|
+
fill='rgba(0, 0, 0, 0.8)'
|
|
37
|
+
mask='url(#mask)'
|
|
38
|
+
fill-opacity='0'
|
|
39
|
+
/>
|
|
28
40
|
</Svg>
|
|
29
41
|
);
|
|
30
42
|
};
|
|
31
43
|
|
|
32
44
|
const TakePicture = ({
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
visible,
|
|
46
|
+
onClose,
|
|
47
|
+
avatar,
|
|
48
|
+
cameraErrorMessage,
|
|
49
|
+
processingPictureMessage,
|
|
50
|
+
repeatPictureText,
|
|
51
|
+
usePictureText,
|
|
52
|
+
}) => {
|
|
41
53
|
const [hasCameraPermission, setHasCameraPermission] = useState(null);
|
|
42
54
|
const [type, setType] = useState(Camera.Constants.Type.back);
|
|
43
|
-
const [flash, setFlash] = useState(false);
|
|
44
55
|
const [image, setImage] = useState(null);
|
|
45
56
|
const [takingPicture, setTakingPicture] = useState(false);
|
|
46
|
-
const [ratio, setRatio] = useState(
|
|
57
|
+
const [ratio, setRatio] = useState(DESIRED_RATIO);
|
|
47
58
|
const camera = useRef();
|
|
48
59
|
|
|
49
60
|
useEffect(() => {
|
|
50
|
-
let mounted = true;
|
|
51
61
|
(async () => {
|
|
52
|
-
const {status} = await Camera.
|
|
53
|
-
|
|
54
|
-
setHasCameraPermission(status === 'granted');
|
|
55
|
-
}
|
|
62
|
+
const { status } = await Camera.requestCameraPermissionsAsync();
|
|
63
|
+
setHasCameraPermission(status === 'granted');
|
|
56
64
|
})();
|
|
57
|
-
|
|
58
|
-
return () => mounted = false;
|
|
59
65
|
}, [visible]);
|
|
60
66
|
|
|
61
67
|
const prepareRatio = async () => {
|
|
62
68
|
if (isAndroid && camera) {
|
|
63
|
-
const ratios = await
|
|
69
|
+
const ratios = await Camera.getSupportedRatiosAsync();
|
|
64
70
|
|
|
65
71
|
// See if the current device has your desired ratio, otherwise get the maximum supported one
|
|
66
72
|
// Usually the last element of 'ratios' is the maximum supported ratio
|
|
67
|
-
const supportedRatio =
|
|
73
|
+
const supportedRatio =
|
|
74
|
+
ratios.find((ratio) => ratio === DESIRED_RATIO) ||
|
|
75
|
+
ratios[ratios.length - 1];
|
|
68
76
|
|
|
69
77
|
setRatio(supportedRatio);
|
|
70
78
|
}
|
|
71
79
|
};
|
|
72
80
|
|
|
73
81
|
const flipCamera = () => {
|
|
74
|
-
setType(
|
|
82
|
+
setType(
|
|
83
|
+
type === Camera.Constants.Type.back
|
|
84
|
+
? Camera.Constants.Type.front
|
|
85
|
+
: Camera.Constants.Type.back
|
|
86
|
+
);
|
|
75
87
|
};
|
|
76
88
|
|
|
77
89
|
const takePicture = async () => {
|
|
78
90
|
if (camera) {
|
|
79
91
|
setTakingPicture(true);
|
|
80
|
-
const tempImage = await camera.current.takePictureAsync({quality: 1.0});
|
|
92
|
+
const tempImage = await camera.current.takePictureAsync({ quality: 1.0 });
|
|
81
93
|
|
|
82
94
|
if (avatar) {
|
|
83
95
|
const image = await ImageManipulator.manipulateAsync(
|
|
84
96
|
tempImage.localUri || tempImage.uri,
|
|
85
|
-
[
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
[
|
|
98
|
+
{
|
|
99
|
+
crop: {
|
|
100
|
+
originX: 0,
|
|
101
|
+
originY: (tempImage.height - tempImage.width) / 2,
|
|
102
|
+
width: tempImage.width,
|
|
103
|
+
height: tempImage.width,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
{ compress: 1.0, format: ImageManipulator.SaveFormat.PNG }
|
|
94
108
|
);
|
|
95
109
|
|
|
96
110
|
setImage(image);
|
|
@@ -117,7 +131,7 @@ const TakePicture = ({
|
|
|
117
131
|
};
|
|
118
132
|
|
|
119
133
|
if (hasCameraPermission === null) {
|
|
120
|
-
return <View/>;
|
|
134
|
+
return <View />;
|
|
121
135
|
}
|
|
122
136
|
|
|
123
137
|
if (hasCameraPermission === false) {
|
|
@@ -129,41 +143,54 @@ const TakePicture = ({
|
|
|
129
143
|
animationType='slide'
|
|
130
144
|
transparent={false}
|
|
131
145
|
visible={visible}
|
|
132
|
-
onRequestClose={() => {
|
|
133
|
-
}}
|
|
146
|
+
onRequestClose={() => {}}
|
|
134
147
|
>
|
|
135
148
|
<Container style={style.cameraContainer}>
|
|
136
149
|
<Camera
|
|
137
150
|
ref={camera}
|
|
138
151
|
style={style.cameraContainer}
|
|
139
152
|
type={type}
|
|
140
|
-
flashMode={
|
|
153
|
+
flashMode={FlashMode.off}
|
|
141
154
|
onCameraReady={prepareRatio} // You can only get the supported ratios when the camera is mounted
|
|
142
155
|
ratio={ratio}
|
|
143
156
|
>
|
|
144
|
-
{avatar && isiOS && <SvgCircle/>}
|
|
157
|
+
{avatar && isiOS && <SvgCircle />}
|
|
145
158
|
|
|
146
159
|
<View style={style.cameraFlipContainer}>
|
|
147
160
|
<TouchableOpacity onPress={closeModal} style={style.closeIcon}>
|
|
148
|
-
<Ionicons
|
|
161
|
+
<Ionicons
|
|
162
|
+
name='close-outline'
|
|
163
|
+
color={Colors.darkblue}
|
|
164
|
+
size={24}
|
|
165
|
+
/>
|
|
149
166
|
</TouchableOpacity>
|
|
150
167
|
<TouchableOpacity style={style.cameraFlipBtn} onPress={flipCamera}>
|
|
151
|
-
<Ionicons
|
|
168
|
+
<Ionicons
|
|
169
|
+
name='camera-reverse-outline'
|
|
170
|
+
style={style.cameraFlipIcon}
|
|
171
|
+
color={Colors.white}
|
|
172
|
+
size={40}
|
|
173
|
+
/>
|
|
152
174
|
</TouchableOpacity>
|
|
153
|
-
<TouchableOpacity
|
|
154
|
-
|
|
175
|
+
<TouchableOpacity
|
|
176
|
+
style={style.cameraRecordBtn}
|
|
177
|
+
onPress={takePicture}
|
|
178
|
+
>
|
|
179
|
+
<Ionicons
|
|
180
|
+
name='radio-button-on-outline'
|
|
181
|
+
color={Colors.red}
|
|
182
|
+
size={60}
|
|
183
|
+
/>
|
|
155
184
|
</TouchableOpacity>
|
|
156
185
|
</View>
|
|
157
186
|
|
|
158
|
-
{avatar && isAndroid && <SvgCircle/>}
|
|
187
|
+
{avatar && isAndroid && <SvgCircle />}
|
|
159
188
|
</Camera>
|
|
160
189
|
|
|
161
190
|
{takingPicture && (
|
|
162
191
|
<View style={style.cameraTakingPictureOverlay}>
|
|
163
|
-
<ActivityIndicator color={Colors.darkblue}/>
|
|
164
|
-
<Text color='white'>
|
|
165
|
-
{processingPictureMessage} ...
|
|
166
|
-
</Text>
|
|
192
|
+
<ActivityIndicator color={Colors.darkblue} />
|
|
193
|
+
<Text color='white'>{processingPictureMessage} ...</Text>
|
|
167
194
|
</View>
|
|
168
195
|
)}
|
|
169
196
|
|
|
@@ -171,12 +198,14 @@ const TakePicture = ({
|
|
|
171
198
|
animationType='slide'
|
|
172
199
|
transparent={false}
|
|
173
200
|
visible={image !== null}
|
|
174
|
-
onRequestClose={() => {
|
|
175
|
-
}}
|
|
201
|
+
onRequestClose={() => {}}
|
|
176
202
|
>
|
|
177
203
|
<View style={style.cameraTakenImageContainer}>
|
|
178
204
|
<ImageResponsive
|
|
179
|
-
source={{
|
|
205
|
+
source={{
|
|
206
|
+
uri: image ? image.uri : null,
|
|
207
|
+
cache: 'only-if-cached',
|
|
208
|
+
}}
|
|
180
209
|
style={avatar ? style.cameraTakenImage : style.cameraContainer}
|
|
181
210
|
/>
|
|
182
211
|
|
|
@@ -201,13 +230,12 @@ const TakePicture = ({
|
|
|
201
230
|
|
|
202
231
|
TakePicture.defaultProps = {
|
|
203
232
|
visible: false,
|
|
204
|
-
onClose: () => {
|
|
205
|
-
},
|
|
233
|
+
onClose: () => {},
|
|
206
234
|
avatar: false,
|
|
207
235
|
cameraErrorMessage: ' ',
|
|
208
236
|
processingPictureMessage: ' ',
|
|
209
237
|
repeatPictureText: ' ',
|
|
210
|
-
usePictureText: ' '
|
|
238
|
+
usePictureText: ' ',
|
|
211
239
|
};
|
|
212
240
|
|
|
213
241
|
TakePicture.propTypes = {
|
|
@@ -217,7 +245,7 @@ TakePicture.propTypes = {
|
|
|
217
245
|
cameraErrorMessage: PropTypes.string.isRequired,
|
|
218
246
|
processingPictureMessage: PropTypes.string.isRequired,
|
|
219
247
|
repeatPictureText: PropTypes.string.isRequired,
|
|
220
|
-
usePictureText: PropTypes.string.isRequired
|
|
248
|
+
usePictureText: PropTypes.string.isRequired,
|
|
221
249
|
};
|
|
222
250
|
|
|
223
251
|
export default TakePicture;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useEffect,
|
|
4
|
+
useState,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
} from 'react';
|
|
2
7
|
import PropTypes from 'prop-types';
|
|
3
8
|
import { TouchableOpacity, View, Dimensions } from 'react-native';
|
|
4
9
|
import style from './style';
|
|
@@ -6,76 +11,81 @@ import style from './style';
|
|
|
6
11
|
const { width } = Dimensions.get('window');
|
|
7
12
|
const BUTTON_WIDTH = width * 0.6;
|
|
8
13
|
|
|
14
|
+
const TimeOutButton = forwardRef(
|
|
15
|
+
({ onPress, time, warning, children }, ref) => {
|
|
16
|
+
const [elapsedTime, setElapsedTime] = useState(0);
|
|
17
|
+
const [interval, setLocalInterval] = useState();
|
|
9
18
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
let isCancelled = false;
|
|
21
|
+
try {
|
|
22
|
+
setLocalInterval(
|
|
23
|
+
setInterval(() => {
|
|
24
|
+
if (!isCancelled) {
|
|
25
|
+
setElapsedTime((elapsedTime) => elapsedTime + 1);
|
|
26
|
+
}
|
|
27
|
+
}, 1)
|
|
28
|
+
);
|
|
29
|
+
} catch (e) {
|
|
18
30
|
if (!isCancelled) {
|
|
19
|
-
|
|
31
|
+
throw e;
|
|
20
32
|
}
|
|
21
|
-
}, 1));
|
|
22
|
-
} catch (e) {
|
|
23
|
-
if (!isCancelled) {
|
|
24
|
-
throw e;
|
|
25
33
|
}
|
|
26
|
-
}
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
return () => {
|
|
36
|
+
clearInterval(interval);
|
|
37
|
+
isCancelled = true;
|
|
38
|
+
};
|
|
39
|
+
}, []);
|
|
40
|
+
|
|
41
|
+
useImperativeHandle(ref, () => ({
|
|
42
|
+
onStop() {
|
|
43
|
+
clearInterval(interval);
|
|
44
|
+
},
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
const watchInterval = () => {
|
|
48
|
+
if (elapsedTime >= time) {
|
|
49
|
+
clearInterval(interval);
|
|
50
|
+
onPress();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return elapsedTime <= time
|
|
54
|
+
? (BUTTON_WIDTH * (time - elapsedTime)) / time
|
|
55
|
+
: BUTTON_WIDTH;
|
|
31
56
|
};
|
|
32
|
-
}, []);
|
|
33
57
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
}));
|
|
58
|
+
const checkWarningPercent = () => {
|
|
59
|
+
return elapsedTime <= time ? time * 0.3 > time - elapsedTime : false;
|
|
60
|
+
};
|
|
39
61
|
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
const onLocalPress = () => {
|
|
63
|
+
setElapsedTime(time);
|
|
42
64
|
clearInterval(interval);
|
|
43
65
|
onPress();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return elapsedTime <= time ? BUTTON_WIDTH * (time - elapsedTime) / time : BUTTON_WIDTH
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const checkWarningPercent = () => {
|
|
50
|
-
return elapsedTime <= time ? (time * 0.3) > (time - elapsedTime) : false;
|
|
51
|
-
}
|
|
66
|
+
};
|
|
52
67
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
return (
|
|
69
|
+
<TouchableOpacity
|
|
70
|
+
style={[style.button, style.buttonBg]}
|
|
71
|
+
onPress={onLocalPress}
|
|
72
|
+
>
|
|
73
|
+
<View
|
|
74
|
+
style={[
|
|
75
|
+
style.button,
|
|
76
|
+
warning
|
|
77
|
+
? checkWarningPercent()
|
|
78
|
+
? style.buttonOverlayWarning
|
|
79
|
+
: style.buttonOverlay
|
|
80
|
+
: style.buttonOverlay,
|
|
81
|
+
{ width: watchInterval() },
|
|
82
|
+
]}
|
|
83
|
+
/>
|
|
84
|
+
{children}
|
|
85
|
+
</TouchableOpacity>
|
|
86
|
+
);
|
|
57
87
|
}
|
|
58
|
-
|
|
59
|
-
return (
|
|
60
|
-
<TouchableOpacity
|
|
61
|
-
style={[
|
|
62
|
-
style.button,
|
|
63
|
-
style.buttonBg
|
|
64
|
-
]}
|
|
65
|
-
onPress={onLocalPress}
|
|
66
|
-
>
|
|
67
|
-
<View style={[
|
|
68
|
-
style.button,
|
|
69
|
-
warning ?
|
|
70
|
-
(checkWarningPercent() ? style.buttonOverlayWarning : style.buttonOverlay)
|
|
71
|
-
: style.buttonOverlay,
|
|
72
|
-
{width: watchInterval()}
|
|
73
|
-
]}
|
|
74
|
-
/>
|
|
75
|
-
{children}
|
|
76
|
-
</TouchableOpacity>
|
|
77
|
-
);
|
|
78
|
-
});
|
|
88
|
+
);
|
|
79
89
|
|
|
80
90
|
TimeOutButton.defaultProps = {
|
|
81
91
|
children: null,
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import React, {useState, useEffect} from 'react';
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
View,
|
|
5
|
+
TouchableOpacity,
|
|
6
|
+
ActivityIndicator,
|
|
7
|
+
Platform,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import { Camera } from 'expo-camera';
|
|
5
10
|
import * as MediaLibrary from 'expo-media-library';
|
|
6
11
|
import * as ExpoImagePicker from 'expo-image-picker';
|
|
7
12
|
import Text from '../Text';
|
|
@@ -10,26 +15,26 @@ import ConfirmationModal from '../ConfirmationModal';
|
|
|
10
15
|
import ImagePicker from '../ImagePicker';
|
|
11
16
|
import ImageViewer from '../ImageViewer';
|
|
12
17
|
import TakePicture from '../TakePicture';
|
|
13
|
-
import {Colors} from '../../configs/constants';
|
|
18
|
+
import { Colors } from '../../configs/constants';
|
|
14
19
|
import style from './style';
|
|
15
20
|
|
|
16
21
|
const iOS = Platform.OS === 'ios';
|
|
17
22
|
|
|
18
23
|
const UploadDocument = ({
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
title,
|
|
25
|
+
description,
|
|
26
|
+
icon,
|
|
27
|
+
completed,
|
|
28
|
+
isAvatarPicker,
|
|
29
|
+
uploadButtonText,
|
|
30
|
+
reUploadButtonText,
|
|
31
|
+
mediaModal,
|
|
32
|
+
takePicture,
|
|
33
|
+
inverted,
|
|
34
|
+
onSelectImage,
|
|
35
|
+
file,
|
|
36
|
+
onPermissionDenied,
|
|
37
|
+
}) => {
|
|
33
38
|
const [showMediaModal, setShowMediaModal] = useState(false);
|
|
34
39
|
const [showCamera, setShowCamera] = useState(false);
|
|
35
40
|
const [image, setImage] = useState(null);
|
|
@@ -38,10 +43,9 @@ const UploadDocument = ({
|
|
|
38
43
|
useEffect(() => {
|
|
39
44
|
(async () => {
|
|
40
45
|
await Camera.requestCameraPermissionsAsync();
|
|
41
|
-
iOS
|
|
42
|
-
await MediaLibrary.requestPermissionsAsync()
|
|
43
|
-
await ExpoImagePicker.getMediaLibraryPermissionsAsync();
|
|
44
|
-
|
|
46
|
+
iOS
|
|
47
|
+
? await MediaLibrary.requestPermissionsAsync()
|
|
48
|
+
: await ExpoImagePicker.getMediaLibraryPermissionsAsync();
|
|
45
49
|
})();
|
|
46
50
|
});
|
|
47
51
|
|
|
@@ -56,7 +60,8 @@ const UploadDocument = ({
|
|
|
56
60
|
|
|
57
61
|
switch (method) {
|
|
58
62
|
case 'camera':
|
|
59
|
-
const {status: cameraStatus} =
|
|
63
|
+
const { status: cameraStatus } =
|
|
64
|
+
await Camera.getCameraPermissionsAsync();
|
|
60
65
|
|
|
61
66
|
if (cameraStatus !== 'granted') {
|
|
62
67
|
onPermissionDenied();
|
|
@@ -67,11 +72,11 @@ const UploadDocument = ({
|
|
|
67
72
|
break;
|
|
68
73
|
case 'gallery':
|
|
69
74
|
setTimeout(async () => {
|
|
70
|
-
const {status: galleryStatus} = iOS
|
|
71
|
-
await MediaLibrary.requestPermissionsAsync()
|
|
72
|
-
await ExpoImagePicker.getMediaLibraryPermissionsAsync();
|
|
75
|
+
const { status: galleryStatus } = iOS
|
|
76
|
+
? await MediaLibrary.requestPermissionsAsync()
|
|
77
|
+
: await ExpoImagePicker.getMediaLibraryPermissionsAsync();
|
|
73
78
|
|
|
74
|
-
if (galleryStatus !== 'granted') {
|
|
79
|
+
if (galleryStatus !== 'granted' && iOS) {
|
|
75
80
|
onPermissionDenied();
|
|
76
81
|
return;
|
|
77
82
|
}
|
|
@@ -96,7 +101,9 @@ const UploadDocument = ({
|
|
|
96
101
|
<View style={style.uploadedContainer}>
|
|
97
102
|
<View>
|
|
98
103
|
<ImageViewer
|
|
99
|
-
source={{
|
|
104
|
+
source={{
|
|
105
|
+
uri: typeof image === 'object' ? image.uri : image,
|
|
106
|
+
}}
|
|
100
107
|
style={style.image}
|
|
101
108
|
resizeMode='cover'
|
|
102
109
|
avatar
|
|
@@ -111,17 +118,34 @@ const UploadDocument = ({
|
|
|
111
118
|
)}
|
|
112
119
|
</View>
|
|
113
120
|
<View style={style.reUploadButtons}>
|
|
114
|
-
<Text
|
|
121
|
+
<Text
|
|
122
|
+
style={style.titleUploaded}
|
|
123
|
+
numberOfLines={1}
|
|
124
|
+
ellipsizeMode='tail'
|
|
125
|
+
>
|
|
126
|
+
{title}
|
|
127
|
+
</Text>
|
|
115
128
|
<TouchableOpacity onPress={() => setShowMediaModal(true)}>
|
|
116
|
-
<Text size='tiny' style={style.reUpload}>
|
|
129
|
+
<Text size='tiny' style={style.reUpload}>
|
|
130
|
+
{reUploadButtonText}
|
|
131
|
+
</Text>
|
|
117
132
|
</TouchableOpacity>
|
|
118
133
|
</View>
|
|
119
134
|
</View>
|
|
120
135
|
) : (
|
|
121
136
|
<View style={style.noUploaded}>
|
|
122
137
|
{icon}
|
|
123
|
-
<Text
|
|
124
|
-
|
|
138
|
+
<Text
|
|
139
|
+
size='large'
|
|
140
|
+
style={style.title}
|
|
141
|
+
numberOfLines={1}
|
|
142
|
+
ellipsizeMode='tail'
|
|
143
|
+
>
|
|
144
|
+
{title}
|
|
145
|
+
</Text>
|
|
146
|
+
<Text size='small' style={style.description}>
|
|
147
|
+
{description}
|
|
148
|
+
</Text>
|
|
125
149
|
<Button variant='dim' onPress={() => setShowMediaModal(true)}>
|
|
126
150
|
<Text>{uploadButtonText}</Text>
|
|
127
151
|
</Button>
|
|
@@ -147,7 +171,7 @@ const UploadDocument = ({
|
|
|
147
171
|
repeatPictureText={takePicture.repeatPictureText}
|
|
148
172
|
usePictureText={takePicture.usePictureText}
|
|
149
173
|
avatar={isAvatarPicker}
|
|
150
|
-
onClose={image => {
|
|
174
|
+
onClose={(image) => {
|
|
151
175
|
setShowCamera(false);
|
|
152
176
|
if (image) {
|
|
153
177
|
selectImage(image);
|
|
@@ -167,23 +191,21 @@ UploadDocument.defaultProps = {
|
|
|
167
191
|
inverted: false,
|
|
168
192
|
isAvatarPicker: false,
|
|
169
193
|
icon: null,
|
|
170
|
-
onSelectImage: () => {
|
|
171
|
-
},
|
|
194
|
+
onSelectImage: () => {},
|
|
172
195
|
file: null,
|
|
173
|
-
onPermissionDenied: () => {
|
|
174
|
-
},
|
|
196
|
+
onPermissionDenied: () => {},
|
|
175
197
|
mediaModal: {
|
|
176
198
|
title: ' ',
|
|
177
199
|
confirmText: ' ',
|
|
178
200
|
cancelText: ' ',
|
|
179
|
-
description: ' '
|
|
201
|
+
description: ' ',
|
|
180
202
|
},
|
|
181
203
|
takePicture: {
|
|
182
204
|
cameraErrorMessage: ' ',
|
|
183
205
|
processingPictureMessage: ' ',
|
|
184
206
|
repeatPictureText: ' ',
|
|
185
|
-
usePictureText: ' '
|
|
186
|
-
}
|
|
207
|
+
usePictureText: ' ',
|
|
208
|
+
},
|
|
187
209
|
};
|
|
188
210
|
|
|
189
211
|
UploadDocument.propTypes = {
|
|
@@ -202,14 +224,14 @@ UploadDocument.propTypes = {
|
|
|
202
224
|
title: PropTypes.string,
|
|
203
225
|
confirmText: PropTypes.string,
|
|
204
226
|
cancelText: PropTypes.string,
|
|
205
|
-
description: PropTypes.string
|
|
227
|
+
description: PropTypes.string,
|
|
206
228
|
}),
|
|
207
229
|
takePicture: PropTypes.shape({
|
|
208
230
|
cameraErrorMessage: PropTypes.string,
|
|
209
231
|
processingPictureMessage: PropTypes.string,
|
|
210
232
|
repeatPictureText: PropTypes.string,
|
|
211
|
-
usePictureText: PropTypes.string
|
|
212
|
-
})
|
|
233
|
+
usePictureText: PropTypes.string,
|
|
234
|
+
}),
|
|
213
235
|
};
|
|
214
236
|
|
|
215
237
|
export default UploadDocument;
|
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.37",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"files": [
|
|
8
8
|
"lib",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"prop-types": "^15.8.1",
|
|
42
42
|
"react": "18.2.0",
|
|
43
43
|
"react-dom": "18.2.0",
|
|
44
|
-
"react-native": "0.71.
|
|
44
|
+
"react-native": "0.71.8",
|
|
45
45
|
"react-native-countdown-circle-timer": "^3.0.9",
|
|
46
46
|
"react-native-deck-swiper": "^2.0.5",
|
|
47
47
|
"react-native-dropdown-picker": "^5.4.6",
|