Skip to content
This repository was archived by the owner on Aug 3, 2024. It is now read-only.

Commit 69a437a

Browse files
authored
StatelessFIleInput: add maxSize and showIcon (#544)
1 parent 405a3ed commit 69a437a

File tree

4 files changed

+86
-40
lines changed

4 files changed

+86
-40
lines changed

components/ui/SmartFileInput.vue

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
</template>
1717

1818
<script>
19+
import { fileIsValid } from '~/plugins/fileUtils'
1920
import UploadIcon from '~/assets/images/utils/upload.svg?inline'
2021
2122
export default {
@@ -36,6 +37,9 @@ export default {
3637
type: String,
3738
default: null,
3839
},
40+
/**
41+
* The max file size in bytes
42+
*/
3943
maxSize: {
4044
type: Number,
4145
default: null,
@@ -54,22 +58,10 @@ export default {
5458
onChange(files, shouldNotReset) {
5559
if (!shouldNotReset) this.files = files.target.files
5660
57-
this.files = [...this.files].filter((file) => {
58-
if (this.maxSize === null) {
59-
return true
60-
} else if (file.size > this.maxSize) {
61-
console.log('File size: ' + file.size + ', max size: ' + this.maxSize)
62-
alert(
63-
'File ' +
64-
file.name +
65-
' is too big! Must be less than ' +
66-
this.$formatBytes(this.maxSize)
67-
)
68-
return false
69-
} else {
70-
return true
71-
}
72-
})
61+
const validationOptions = { maxSize: this.maxSize, alertOnInvalid: true }
62+
this.files = [...this.files].filter((file) =>
63+
fileIsValid(file, validationOptions)
64+
)
7365
7466
if (this.files.length > 0) {
7567
this.$emit('change', this.files)

components/ui/StatelessFileInput.vue

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="columns">
33
<label class="button" @drop.prevent="handleDrop" @dragover.prevent>
44
<span>
5-
<UploadIcon />
5+
<UploadIcon v-if="showIcon" />
66
{{ prompt }}
77
</span>
88
<input
@@ -16,6 +16,7 @@
1616
</template>
1717

1818
<script>
19+
import { fileIsValid } from '~/plugins/fileUtils'
1920
import UploadIcon from '~/assets/images/utils/upload.svg?inline'
2021
2122
export default {
@@ -36,24 +37,46 @@ export default {
3637
type: String,
3738
default: null,
3839
},
40+
/**
41+
* The max file size in bytes
42+
*/
43+
maxSize: {
44+
type: Number,
45+
default: null,
46+
},
47+
showIcon: {
48+
type: Boolean,
49+
default: true,
50+
},
3951
},
4052
methods: {
4153
onChange(addedFiles) {
4254
this.$emit('change', addedFiles)
4355
},
56+
/**
57+
* @param {FileList} filesToAdd
58+
*/
4459
addFiles(filesToAdd) {
4560
if (!filesToAdd) return
4661
47-
if (!this.multiple && filesToAdd.length > 0) {
48-
this.onChange([filesToAdd[0]])
49-
return
50-
}
62+
const validationOptions = { maxSize: this.maxSize, alertOnInvalid: true }
63+
const validFiles = [...filesToAdd].filter((file) =>
64+
fileIsValid(file, validationOptions)
65+
)
5166
52-
this.onChange(filesToAdd)
67+
if (validFiles.length > 0) {
68+
this.onChange(this.multiple ? validFiles : [validFiles[0]])
69+
}
5370
},
71+
/**
72+
* @param {DragEvent} e
73+
*/
5474
handleDrop(e) {
5575
this.addFiles(e.dataTransfer.files)
5676
},
77+
/**
78+
* @param {Event} e native file input event
79+
*/
5780
handleChange(e) {
5881
this.addFiles(e.target.files)
5982
},

plugins/fileUtils.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { formatBytes } from '~/plugins/shorthands'
2+
3+
/**
4+
* @param {File | Blob} file the file to validate
5+
* @param {{ maxSize: number, alertOnInvalid: boolean }} validationOptions the
6+
* constraints to validate the file against
7+
* @param validationOptions.maxSize the max file size in bytes
8+
* @param validationOptions.alertOnInvalid if an alert should pop up describing
9+
* each validation error
10+
* @returns `true` if the file is valid; `false` otherise
11+
*/
12+
export const fileIsValid = (file, validationOptions) => {
13+
const { maxSize, alertOnInvalid } = validationOptions
14+
if (maxSize !== null && maxSize !== undefined && file.size > maxSize) {
15+
console.log(`File size: ${file.size}, max size: ${maxSize}`)
16+
if (alertOnInvalid) {
17+
alert(
18+
`File ${file.name} is too big! Must be less than ${formatBytes(
19+
maxSize
20+
)}`
21+
)
22+
}
23+
return false
24+
}
25+
26+
return true
27+
}

plugins/shorthands.js

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,7 @@ export default ({ store }, inject) => {
22
inject('user', store.state.user)
33
inject('tag', store.state.tag)
44
inject('auth', store.state.auth)
5-
inject('formatNumber', (number) => {
6-
const x = +number
7-
if (x >= 1000000) {
8-
return (x / 1000000).toFixed(2).toString() + 'M'
9-
} else if (x >= 10000) {
10-
return (x / 1000).toFixed(1).toString() + 'K'
11-
} else {
12-
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
13-
}
14-
})
5+
inject('formatNumber', formatNumber)
156
inject('formatVersion', (versionArray) => {
167
const allVersions = store.state.tag.gameVersions.slice().reverse()
178
const allReleases = allVersions.filter((x) => x.version_type === 'release')
@@ -98,15 +89,28 @@ export default ({ store }, inject) => {
9889

9990
return output.join(', ')
10091
})
101-
inject('formatBytes', (bytes, decimals = 2) => {
102-
if (bytes === 0) return '0 Bytes'
92+
inject('formatBytes', formatBytes)
93+
}
10394

104-
const k = 1024
105-
const dm = decimals < 0 ? 0 : decimals
106-
const sizes = ['Bytes', 'KiB', 'MiB', 'GiB']
95+
export const formatNumber = (number) => {
96+
const x = +number
97+
if (x >= 1000000) {
98+
return (x / 1000000).toFixed(2).toString() + 'M'
99+
} else if (x >= 10000) {
100+
return (x / 1000).toFixed(1).toString() + 'K'
101+
} else {
102+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
103+
}
104+
}
107105

108-
const i = Math.floor(Math.log(bytes) / Math.log(k))
106+
export const formatBytes = (bytes, decimals = 2) => {
107+
if (bytes === 0) return '0 Bytes'
109108

110-
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
111-
})
109+
const k = 1024
110+
const dm = decimals < 0 ? 0 : decimals
111+
const sizes = ['Bytes', 'KiB', 'MiB', 'GiB']
112+
113+
const i = Math.floor(Math.log(bytes) / Math.log(k))
114+
115+
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
112116
}

0 commit comments

Comments
 (0)