-
-
Save Aliath/25dde43cc0e59d3cbaec5b5cbb62100f to your computer and use it in GitHub Desktop.
import { Platform, ActionSheetIOS } from 'react-native'; | |
import DocumentPicker from 'react-native-document-picker'; | |
import ImagePicker from 'react-native-image-picker'; | |
import RNFS from 'react-native-fs'; | |
type Captions = { | |
image: string, | |
document: string, | |
cancel: string, | |
title: string, | |
}; | |
export class AttachmentPicker { | |
private captions: Captions; | |
constructor(captions: Captions = { image: 'Image', document: 'Document', cancel: 'Cancel', title: 'Pick type of media' }) { | |
this.captions = captions; | |
} | |
pick = () => { | |
if (Platform.OS === 'ios') { | |
return this.pickIOS(); | |
} | |
return new Promise((resolve, reject) => { | |
return this.pickDocument(resolve, reject); | |
}); | |
} | |
pickIOS = () => { | |
return new Promise((resolve, reject) => { | |
const { image, document, cancel, title } = this.captions; | |
const options = [image, document, cancel]; | |
const handlers = [this.pickImage, this.pickDocument, this.pickClosed]; | |
const cancelButtonIndex = options.indexOf(cancel); | |
ActionSheetIOS.showActionSheetWithOptions( | |
{ options, cancelButtonIndex, title }, | |
buttonIndex => { handlers[buttonIndex](resolve, reject); } | |
); | |
}); | |
} | |
pickImage = (resolve: (payload: any) => void, reject: (payload: any) => void) => { | |
ImagePicker.showImagePicker(response => { | |
if (response.didCancel) { | |
reject(new Error('Action cancelled!')); | |
} else { | |
const { data: b64Content, type: fileType } = response; | |
const b64 = `data:${fileType};base64,${b64Content}`; | |
const fileExtension = String(fileType).substr(String(fileType).indexOf('/') + 1); | |
resolve({ b64, fileType, fileExtension }); | |
} | |
}); | |
} | |
pickDocument = async (resolve: (payload: any) => void, reject: (payload: any) => void) => { | |
try { | |
const result = await DocumentPicker.pick({ | |
type: [DocumentPicker.types.images, DocumentPicker.types.pdf] | |
}); | |
const fileType = result.type; | |
const fileExtension = fileType.substr(fileType.indexOf('/') + 1); | |
const realURI = Platform.select({ android: result.uri, ios: decodeURI(result.uri), }) | |
const b64Content = await RNFS.readFile(realURI, "base64") | |
const b64 = `data:${fileType};base64,${b64Content}`; | |
resolve({ b64, fileType, fileExtension }); | |
} catch { | |
reject(new Error('Action cancelled!')); | |
} | |
} | |
pickClosed = (_: any, reject: (payload: any) => void) => { | |
reject(new Error('Action cancelled!')); | |
} | |
} | |
// example of use: | |
(async () => { | |
const attachmentPicker = new AttachmentPicker(); | |
const response = await attachmentPicker.pick(); | |
})(); |
Just one thing to note here that i have faced an issue on ios when picking a document that has spaces in its filename to read it as base64.
I solved it by using this:
const realURI = Platform.select({ android: result.uri, ios: decodeURI(result.uri), })
const b64Content = await RNFS.readFile(realURI, "base64")
Thank you! Corrected. 😄
Hello
is their a simple .js version of this code. It is giving error because of typescript and my project doesn't uses typescript
Hello, nope but as typescript is just superset of js you can compile it straight into pure js.
do I need to add "react-native-image-picker" to my project to use this ?
Bit confused,
can you please provide a sample code, How to use it.
Thanks man!! you saved me a lot of time
const realURI = Platform.select({ android: result.uri, ios: decodeURI(result.uri), })
Thanks bro. As I could not fetch the Sha1 due to the path not being valid.
Thanks ! Be aware that some adaptations are needed to fit with latest version of the image picker but most of the work is already done ^^
Thanks man, you saved my life! 🥇
thanks for your wrapper code syntax, i modified according to my requirements
Yes, create instance of the class and use pick method on it.