1- import React , { PropsWithChildren , useMemo , ComponentType } from 'react' ;
2- import {
3- View ,
4- StyleSheet ,
5- Rationale ,
6- TouchableOpacity ,
7- ModalProps ,
8- ImageURISource ,
9- ImageRequireSource ,
10- } from 'react-native' ;
11- import { CameraOptions , ImagePickerResponse } from 'react-native-image-picker' ;
1+ import React , { useMemo } from 'react' ;
2+ import { View , StyleSheet , TouchableOpacity } from 'react-native' ;
123import { Theme , Flex , ActionSheet , ActionSheetItem , TransitionImage , Icon } from '@uiw/react-native' ;
134import ImageView from 'react-native-image-viewing' ;
145import { useTheme } from '@shopify/restyle' ;
156import useImagePicker from './useImagePicker' ;
16-
17- export type ImageSource = ImageURISource | ImageRequireSource ;
18- export interface File {
19- fileName : string ;
20- fileType : string ;
21- uri : string ;
22- fileSize ?: number ;
23- }
24-
25- export type ImagePickerProps = PropsWithChildren < {
26- /** 宽度 */
27- width ?: number ;
28- /** 高度 */
29- height ?: number ;
30- /** 当前选择的图片uri */
31- value ?: string [ ] ;
32- /** 其他图片自定义配置,详细参考react-native-image-picker的option配置 */
33- options ?: CameraOptions ;
34- /** 上传图片后是否在背景图展示,如果为 true 上传后会自动展示上传图片(此时只能上传一张) */
35- showUploadImg ?: boolean ;
36- /** 上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传,同时可以在里面执行一些上传提示操作 */
37- beforeUpload ?: ( file : File [ ] ) => boolean | ( ( file : File ) => Promise < boolean > ) ;
38- /** 上传 */
39- upload ?: ( file : File [ ] ) => string [ ] ;
40- /** 上传完成 */
41- uploadFinish ?: ( result ?: string [ ] | undefined ) => void ;
42- /** 取消上传事件回调 */
43- onCancel ?: ( response : ImagePickerResponse ) => void ;
44- /** 上传失败事件回调 */
45- onFail ?: ( response : ImagePickerResponse ) => void ;
46- /** 授权失败的回调 */
47- onGrantFail ?: ( ) => void ;
48- /** 预览时长按图片保存回调 */
49- onSave ?: ( ( image : any ) => void ) | undefined ;
50- /** 打开相册授权的文本 */
51- libraryRationale ?: Rationale ;
52- /** 打开摄像头授权的文本 */
53- cameraRationale ?: Rationale ;
54- /** 打开相册文本 */
55- launchLibraryText ?: string ;
56- /** 打开摄像头文本 */
57- launchCameraText ?: string ;
58- /** 从相册选择多少张图片 */
59- selectionLimit ?: number ;
60- // ImageViewProps
61- onLongPress ?: ( image : ImageSource ) => void ;
62- onImageIndexChange ?: ( imageIndex : number ) => void ;
63- presentationStyle ?: ModalProps [ 'presentationStyle' ] ;
64- animationType ?: ModalProps [ 'animationType' ] ;
65- backgroundColor ?: string ;
66- swipeToCloseEnabled ?: boolean ;
67- doubleTapToZoomEnabled ?: boolean ;
68- delayLongPress ?: number ;
69- HeaderComponent ?: ComponentType < {
70- imageIndex : number ;
71- } > ;
72- FooterComponent ?: ComponentType < {
73- imageIndex : number ;
74- } > ;
75- } > ;
7+ import { ImagePickerProps } from './types' ;
768
779const ImagePicker = ( {
7810 width = 100 ,
@@ -81,6 +13,9 @@ const ImagePicker = ({
8113 value = [ ] ,
8214 options,
8315 showUploadImg = true ,
16+ disabled = false ,
17+ readOnly = false ,
18+ maxCount = undefined ,
8419 beforeUpload,
8520 upload,
8621 uploadFinish,
@@ -109,8 +44,6 @@ const ImagePicker = ({
10944 const styles = createStyles ( {
11045 width : width ,
11146 height : height ,
112- borderColor : theme . colors . border ,
113- backgroundColor : theme . colors . mask ,
11447 } ) ;
11548
11649 const {
@@ -153,11 +86,13 @@ const ImagePicker = ({
15386 disabled = { loading }
15487 onPress = { ( ) => previewImage ( index ) }
15588 />
156- < View style = { styles . deleteBox } >
157- < TouchableOpacity disabled = { loading } onPress = { ( ) => deleteImage ( index ) } >
158- < Icon name = "close" color = "#fff" size = { 10 } />
159- </ TouchableOpacity >
160- </ View >
89+ { ! readOnly && (
90+ < View style = { styles . deleteBox } >
91+ < TouchableOpacity disabled = { loading } onPress = { ( ) => deleteImage ( index ) } >
92+ < Icon name = "close" color = "#fff" size = { 10 } />
93+ </ TouchableOpacity >
94+ </ View >
95+ ) }
16196 </ View >
16297 </ View >
16398 </ Flex . Item >
@@ -166,6 +101,31 @@ const ImagePicker = ({
166101 return null ;
167102 } , [ showUploadImg , JSON . stringify ( currentImgSource ) ] ) ;
168103
104+ const uploader = useMemo ( ( ) => {
105+ if ( readOnly || currentImgSource . length === maxCount ) {
106+ return null ;
107+ }
108+ return (
109+ < Flex . Item >
110+ < View
111+ style = { [
112+ styles . box ,
113+ { backgroundColor : disabled ? theme . colors . disabled : theme . colors . primary500 || '#eff2f5' } ,
114+ ] }
115+ >
116+ < TouchableOpacity
117+ activeOpacity = { 0.5 }
118+ onPress = { handlePress }
119+ disabled = { disabled || loading }
120+ style = { { justifyContent : 'center' , alignItems : 'center' , width, height } }
121+ >
122+ < Icon name = "camera-o" color = "#dcdee0" size = { 24 } />
123+ </ TouchableOpacity >
124+ </ View >
125+ </ Flex . Item >
126+ ) ;
127+ } , [ readOnly , maxCount , JSON . stringify ( currentImgSource ) , disabled ] ) ;
128+
169129 const previewImages = useMemo ( ( ) => {
170130 return currentImgSource . map ( ( item ) => ( { uri : item } ) ) ;
171131 } , [ JSON . stringify ( currentImgSource ) , current ] ) ;
@@ -174,18 +134,7 @@ const ImagePicker = ({
174134 < View >
175135 < Flex justify = "start" wrap = "wrap" >
176136 { pictureList }
177- < Flex . Item >
178- < View style = { styles . box } >
179- < TouchableOpacity
180- activeOpacity = { 0.5 }
181- onPress = { handlePress }
182- disabled = { loading }
183- style = { { justifyContent : 'center' , alignItems : 'center' , width, height } }
184- >
185- < Icon name = "camera-o" color = { theme . colors . gray300 || '#ccc' } size = { 24 } />
186- </ TouchableOpacity >
187- </ View >
188- </ Flex . Item >
137+ { uploader }
189138 </ Flex >
190139 < ActionSheet onCancel = { setLaunchVisibleFalse } visible = { launchVisible } >
191140 < ActionSheetItem disabled = { loading } onPress = { launchLibrary } >
@@ -206,18 +155,14 @@ const ImagePicker = ({
206155 ) ;
207156} ;
208157
209- function createStyles ( { width = 100 , height = 100 , borderColor = '#CCCCCC' , backgroundColor = '#fff' } ) {
158+ function createStyles ( { width = 100 , height = 100 } ) {
210159 return StyleSheet . create ( {
211160 box : {
212161 width : width ,
213162 height : height ,
214- borderWidth : 1 ,
215- borderStyle : 'solid' ,
216- borderColor : borderColor ,
217163 borderRadius : 2 ,
218164 justifyContent : 'center' ,
219165 alignItems : 'center' ,
220- backgroundColor : backgroundColor ,
221166 margin : 4 ,
222167 } ,
223168 deleteBox : {
0 commit comments