UNPKG

react-native-surveys

Version:

Build your own forms, surveys and polls for your React Native apps.

236 lines (225 loc) 6.08 kB
function _extends() { _extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import React, { memo, useState, useEffect, Fragment } from "react"; import { View, StyleSheet, Text, Dimensions } from "react-native"; import { useDropzone } from "../../api/react-dropzone"; import { colors, MAX_FORM_WIDTH } from "../../theme"; import { UploadIcon } from "../../assets/icons"; import FilePreview from "../../components/FilePreview"; import QuestionHeader from "../../components/QuestionHeader"; import { config } from "../../config"; const { width } = Dimensions.get("window"); const FilesUpload = ({ block, form, isPreview, currentPageIndex, blockIndex, allBlocks }) => { const [error, setError] = useState(false); const [files, updateFiles] = useState(block.files || []); const { accept } = block; const onDrop = (acceptedFiles, rejectedFiles) => { if (rejectedFiles.length > 0) { setError( rejectedFiles.filter(f => f.type.indexOf("image") < 0).length > 0 ? "Sorry, you can only upload images." : "File exceeded max 5mb size." ); } else { setError(false); } if (files.length + acceptedFiles.length > config.MAX_UPLOAD_FILES_NUMBER) { setError( `Files limit reached. Max ${config.MAX_UPLOAD_FILES_NUMBER} files.` ); } const updatedFiles = [ ...files, ...acceptedFiles.map(file => Object.assign(file, { preview: URL.createObjectURL(file) }) ) ].slice(0, config.MAX_UPLOAD_FILES_NUMBER); block.files = block.files || []; updatedFiles.forEach((file, i) => { if (block.files[i] && block.files[i].name === file.name) return; const reader = new FileReader(); reader.readAsDataURL(file); reader.onloadend = () => { block.files[i] = { name: file.name, type: file.type, base64: reader.result }; }; }); block.value = returnFilesBlockValue(updatedFiles.length); updateFiles(updatedFiles); }; const removeFile = file => { const updatedFiles = files.filter(f => f.name !== file.name); block.files = block.files.filter(f => f.name !== file.name); block.value = returnFilesBlockValue(updatedFiles.length); updateFiles(updatedFiles); setError(false); }; const returnFilesBlockValue = (numberOfFiles = 0) => { if (numberOfFiles <= 0) return ""; const noun = numberOfFiles === 1 ? "file" : "files"; return `Uploaded ${numberOfFiles} ${noun}`; }; useEffect( () => () => { files.forEach(file => URL.revokeObjectURL(file.preview)); }, [files] ); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, noKeyboard: true, disabled: isPreview, multiple: true, accept: accept || "", maxSize: 5000000 }); const dropStyle = { cursor: isPreview ? "auto" : "pointer", flexDirection: files.length > 0 ? "row" : "column", justifyContent: files.length > 0 ? "flex-start" : "center", backgroundColor: isDragActive ? `${colors.success}10` : colors.white, borderWidth: 1, borderStyle: "solid", borderColor: isDragActive ? colors.success : colors.border, position: "relative", display: "flex", alignItems: "center", flexWrap: "wrap", minHeight: 150, padding: width <= 500 ? 16 : 24, boxSizing: "border-box", width: "100%", borderRadius: 4 }; const placeholderStyle = { fontSize: 13, color: isDragActive ? colors.add : colors.darkgrey, paddingTop: 8, textAlign: "center" }; return React.createElement( View, { style: styles.container }, React.createElement(QuestionHeader, { form: form, block: block, currentPageIndex: currentPageIndex, blockIndex: blockIndex, allBlocks: allBlocks }), React.createElement( View, { style: styles.inputContainer }, React.createElement( "div", _extends( { style: dropStyle }, getRootProps(), { className: "dropZone" } ), React.createElement( "input", _extends( { style: { display: "none", position: "absolute", width: 0, height: 0 } }, getInputProps() ) ), files.map((file, i) => React.createElement(FilePreview, { removeFile: removeFile, isPreview: isPreview, file: file, key: file.name + i }) ), files.length === 0 && React.createElement( Fragment, null, React.createElement(UploadIcon, { size: 32 }), React.createElement( Text, { style: placeholderStyle }, "Drop your files here or click to browse" ) ) ), error && React.createElement( Text, { style: styles.error }, error ) ) ); }; const styles = StyleSheet.create({ container: { display: "flex", flexDirection: "column", alignItems: "center" }, inputContainer: { display: "flex", width: "100%", backgroundColor: "transparent", alignItems: "flex-start", maxWidth: MAX_FORM_WIDTH, paddingHorizontal: 24, paddingVertical: 24 }, error: { fontSize: 14, color: colors.error, paddingVertical: 8, paddingHorizontal: 4 } }); export default memo(FilesUpload);