diff options
Diffstat (limited to 'src/components/ui/ImageUpload.tsx')
-rw-r--r-- | src/components/ui/ImageUpload.tsx | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/src/components/ui/ImageUpload.tsx b/src/components/ui/ImageUpload.tsx index 3a396f56c..7732928f8 100644 --- a/src/components/ui/ImageUpload.tsx +++ b/src/components/ui/ImageUpload.tsx | |||
@@ -4,6 +4,7 @@ import { Field } from 'mobx-react-form'; | |||
4 | import classnames from 'classnames'; | 4 | import classnames from 'classnames'; |
5 | import Dropzone from 'react-dropzone'; | 5 | import Dropzone from 'react-dropzone'; |
6 | import { mdiDelete, mdiFileImage } from '@mdi/js'; | 6 | import { mdiDelete, mdiFileImage } from '@mdi/js'; |
7 | import prettyBytes from 'pretty-bytes'; | ||
7 | import { isWindows } from '../../environment'; | 8 | import { isWindows } from '../../environment'; |
8 | import Icon from './icon'; | 9 | import Icon from './icon'; |
9 | 10 | ||
@@ -13,20 +14,33 @@ type Props = { | |||
13 | multiple: boolean; | 14 | multiple: boolean; |
14 | textDelete: string; | 15 | textDelete: string; |
15 | textUpload: string; | 16 | textUpload: string; |
17 | textMaxFileSize: string; | ||
18 | textMaxFileSizeError: string; | ||
19 | maxSize?: number; | ||
20 | maxFiles?: number; | ||
21 | messages: any; | ||
16 | }; | 22 | }; |
17 | 23 | ||
18 | // Should this file be converted into the coding style similar to './toggle/index.tsx'? | 24 | // Should this file be converted into the coding style similar to './toggle/index.tsx'? |
19 | class ImageUpload extends Component<Props> { | 25 | class ImageUpload extends Component<Props> { |
20 | static defaultProps = { | 26 | static defaultProps = { |
21 | multiple: false, | 27 | multiple: false, |
28 | maxSize: Number.POSITIVE_INFINITY, | ||
29 | maxFiles: 0, | ||
22 | }; | 30 | }; |
23 | 31 | ||
24 | state = { | 32 | state = { |
25 | path: null, | 33 | path: null, |
34 | errorState: false, | ||
26 | }; | 35 | }; |
27 | 36 | ||
28 | onDrop(acceptedFiles) { | 37 | errorMessage = { |
38 | message: '', | ||
39 | }; | ||
40 | |||
41 | onDropAccepted(acceptedFiles) { | ||
29 | const { field } = this.props; | 42 | const { field } = this.props; |
43 | this.setState({ errorState: false }); | ||
30 | 44 | ||
31 | for (const file of acceptedFiles) { | 45 | for (const file of acceptedFiles) { |
32 | const imgPath = isWindows ? file.path.replace(/\\/g, '/') : file.path; | 46 | const imgPath = isWindows ? file.path.replace(/\\/g, '/') : file.path; |
@@ -40,14 +54,43 @@ class ImageUpload extends Component<Props> { | |||
40 | field.set(''); | 54 | field.set(''); |
41 | } | 55 | } |
42 | 56 | ||
57 | onDropRejected(rejectedFiles): void { | ||
58 | for (const file of rejectedFiles) { | ||
59 | for (const error of file.errors) { | ||
60 | if (error.code === 'file-too-large') { | ||
61 | this.setState({ errorState: true }); | ||
62 | this.setState( | ||
63 | (this.errorMessage = { | ||
64 | message: this.props.textMaxFileSizeError, | ||
65 | }), | ||
66 | ); | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | |||
43 | render() { | 72 | render() { |
44 | const { field, className, multiple, textDelete, textUpload } = this.props; | 73 | const { |
74 | field, | ||
75 | className, | ||
76 | multiple, | ||
77 | textDelete, | ||
78 | textUpload, | ||
79 | textMaxFileSize, | ||
80 | maxSize, | ||
81 | maxFiles, | ||
82 | } = this.props; | ||
45 | 83 | ||
46 | const cssClasses = classnames({ | 84 | const cssClasses = classnames({ |
47 | 'image-upload__dropzone': true, | 85 | 'image-upload__dropzone': true, |
48 | [`${className}`]: className, | 86 | [`${className}`]: className, |
49 | }); | 87 | }); |
50 | 88 | ||
89 | const maxSizeParse: number = | ||
90 | maxSize === undefined || maxSize === Number.POSITIVE_INFINITY | ||
91 | ? 0 | ||
92 | : maxSize; | ||
93 | |||
51 | return ( | 94 | return ( |
52 | <div className="image-upload-wrapper"> | 95 | <div className="image-upload-wrapper"> |
53 | <label className="franz-form__label" htmlFor="iconUpload"> | 96 | <label className="franz-form__label" htmlFor="iconUpload"> |
@@ -83,9 +126,13 @@ class ImageUpload extends Component<Props> { | |||
83 | </> | 126 | </> |
84 | ) : ( | 127 | ) : ( |
85 | <Dropzone | 128 | <Dropzone |
86 | onDrop={this.onDrop.bind(this)} | 129 | onDropAccepted={this.onDropAccepted.bind(this)} |
130 | onDropRejected={this.onDropRejected.bind(this)} | ||
87 | multiple={multiple} | 131 | multiple={multiple} |
88 | accept="image/jpeg, image/png, image/svg+xml" | 132 | accept="image/jpeg, image/png, image/svg+xml" |
133 | minSize={0} | ||
134 | maxSize={maxSize} | ||
135 | maxFiles={maxFiles} | ||
89 | > | 136 | > |
90 | {({ getRootProps, getInputProps }) => ( | 137 | {({ getRootProps, getInputProps }) => ( |
91 | <div {...getRootProps()} className={cssClasses}> | 138 | <div {...getRootProps()} className={cssClasses}> |
@@ -97,6 +144,17 @@ class ImageUpload extends Component<Props> { | |||
97 | </Dropzone> | 144 | </Dropzone> |
98 | )} | 145 | )} |
99 | </div> | 146 | </div> |
147 | {maxSizeParse !== 0 && ( | ||
148 | <span className="image-upload-wrapper__file-size"> | ||
149 | {textMaxFileSize}{' '} | ||
150 | {prettyBytes(maxSizeParse, { maximumFractionDigits: 1 })} | ||
151 | </span> | ||
152 | )} | ||
153 | {this.state.errorState && ( | ||
154 | <span className="image-upload-wrapper__file-size-error"> | ||
155 | {this.errorMessage.message} | ||
156 | </span> | ||
157 | )} | ||
100 | </div> | 158 | </div> |
101 | ); | 159 | ); |
102 | } | 160 | } |