Skip to content

Instantly share code, notes, and snippets.

@macrozone
Created March 27, 2017 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macrozone/9865c41346da0845a49b7378d706f6a1 to your computer and use it in GitHub Desktop.
Save macrozone/9865c41346da0845a49b7378d706f6a1 to your computer and use it in GitHub Desktop.
import React from 'react';
import withTheme from '/lib/withTheme';
import { withUploader } from '@panter/manul-files';
import { useDeps, composeAll } from 'mantra-core';
import BoxedImage from '/client/modules/core/components/boxed_image';
import { connectField } from 'uniforms';
import DropZone from 'react-dropzone';
import { Styles } from './TextField';
import formCol from './FormCol';
import _ from 'lodash';
import Link from '/client/modules/core/components/link';
import { ErrorBox } from './ErrorField';
import { withHandlers } from 'recompose';
import { T } from '@panter/manul-i18n';
const isIOSCordova = () =>
/* global Meteor */
/* global window */
Meteor && Meteor.isCordova && _.get(window, 'cordova.platformId') === 'ios';
const enhance = composeAll(
withUploader,
withHandlers({
onUploadError: ({ context }) => (error) => {
context().Alerts.show({ message: context().i18n.t('upload.error'), error });
},
onUploadSuccess: ({ context }) => () => {
context().Alerts.show({ message: context().i18n.t('upload.success') });
},
}),
useDeps(context => ({
context: () => context,
}))
);
export const File = enhance(withTheme(Styles, ({
label,
onChange,
onUploadError,
upload,
progress,
status,
styles,
id,
imageOptions = {
aspectRatio: 1,
crop: false,
},
fileRestrictions = {
allowedFileTypes: [],
maxSize: null,
},
value,
errorMessage,
}) => (
<section style={styles.container}>
<label htmlFor={id} style={[styles.label]}>{label}</label>
<div style={styles.input}>
{value ? <Link isFile href={value}><T>files.showFile</T></Link> : null}
<div style={{ marginTop: 30 }}>
{status === 'transferring' ?
<p>progress: {progress}</p> :
<DropZone
id={id}
multiple={false}
accept={fileRestrictions.allowedFileTypes.join(',')}
maxSize={fileRestrictions.maxSizeClient || fileRestrictions.maxSize}
style={{
width: '100%',
height: '100%',
minWidth: 100,
minHeight: 100,
cursor: 'pointer',
position: 'relative',
border: '1px dashed black',
}}
onDrop={
(files) => {
if (files.length > 0) {
/* eslint no-console: 0*/
upload(files[0], (error, url) => (error ? console.error(error) : onChange(url)));
}
}
}
onDropRejected={
(files) => {
files.forEach(() => onUploadError('upload.errors.notaccepted'));
}
}
>
{
/**
there is an issue on ios cordova https://github.com/okonet/react-dropzone/issues/354
and an even stranger workaround:
My first idea was to make the hidden input-type-file visible, but this did not workaround.
What DOES work is to add an additional input type. HOWEVER, we dont need to attach an onChange,
strangely, the original onChange of the still hidden input fires when you select a photo!
Sometimes its magic...
**/
isIOSCordova() &&
<input
type="file"
accept={fileRestrictions.allowedFileTypes.join(',')}
style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, opacity: 0, zIndex: 100 }}
/>
}
{_.some(fileRestrictions.allowedFileTypes, type => type.startsWith('image')) ?
<BoxedImage
aspectRatio={imageOptions.aspectRatio}
imageUrl={value}
crop={imageOptions.crop}
/> : null
}
</DropZone>
}
</div>
</div>
{errorMessage && <ErrorBox errorMessage={errorMessage} />}
</section>
), { radium: true, radiumState: true }));
export default connectField(formCol(File));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment