Last active
October 13, 2024 12:00
-
-
Save Aliath/25dde43cc0e59d3cbaec5b5cbb62100f to your computer and use it in GitHub Desktop.
Wrapper for the react-native-image-picker and react-native-document-picker. Allow to pick media from gallery on iOS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
})(); |
Thanks man, you saved my life! 🥇
thanks for your wrapper code syntax, i modified according to my requirements
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 ^^