StatelessFIleInput: add maxSize and showIcon (#544)
This commit is contained in:
parent
405a3eda60
commit
69a437a1a8
@ -16,6 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fileIsValid } from '~/plugins/fileUtils'
|
||||
import UploadIcon from '~/assets/images/utils/upload.svg?inline'
|
||||
|
||||
export default {
|
||||
@ -36,6 +37,9 @@ export default {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* The max file size in bytes
|
||||
*/
|
||||
maxSize: {
|
||||
type: Number,
|
||||
default: null,
|
||||
@ -54,22 +58,10 @@ export default {
|
||||
onChange(files, shouldNotReset) {
|
||||
if (!shouldNotReset) this.files = files.target.files
|
||||
|
||||
this.files = [...this.files].filter((file) => {
|
||||
if (this.maxSize === null) {
|
||||
return true
|
||||
} else if (file.size > this.maxSize) {
|
||||
console.log('File size: ' + file.size + ', max size: ' + this.maxSize)
|
||||
alert(
|
||||
'File ' +
|
||||
file.name +
|
||||
' is too big! Must be less than ' +
|
||||
this.$formatBytes(this.maxSize)
|
||||
)
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
const validationOptions = { maxSize: this.maxSize, alertOnInvalid: true }
|
||||
this.files = [...this.files].filter((file) =>
|
||||
fileIsValid(file, validationOptions)
|
||||
)
|
||||
|
||||
if (this.files.length > 0) {
|
||||
this.$emit('change', this.files)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div class="columns">
|
||||
<label class="button" @drop.prevent="handleDrop" @dragover.prevent>
|
||||
<span>
|
||||
<UploadIcon />
|
||||
<UploadIcon v-if="showIcon" />
|
||||
{{ prompt }}
|
||||
</span>
|
||||
<input
|
||||
@ -16,6 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fileIsValid } from '~/plugins/fileUtils'
|
||||
import UploadIcon from '~/assets/images/utils/upload.svg?inline'
|
||||
|
||||
export default {
|
||||
@ -36,24 +37,46 @@ export default {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* The max file size in bytes
|
||||
*/
|
||||
maxSize: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onChange(addedFiles) {
|
||||
this.$emit('change', addedFiles)
|
||||
},
|
||||
/**
|
||||
* @param {FileList} filesToAdd
|
||||
*/
|
||||
addFiles(filesToAdd) {
|
||||
if (!filesToAdd) return
|
||||
|
||||
if (!this.multiple && filesToAdd.length > 0) {
|
||||
this.onChange([filesToAdd[0]])
|
||||
return
|
||||
}
|
||||
const validationOptions = { maxSize: this.maxSize, alertOnInvalid: true }
|
||||
const validFiles = [...filesToAdd].filter((file) =>
|
||||
fileIsValid(file, validationOptions)
|
||||
)
|
||||
|
||||
this.onChange(filesToAdd)
|
||||
if (validFiles.length > 0) {
|
||||
this.onChange(this.multiple ? validFiles : [validFiles[0]])
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {DragEvent} e
|
||||
*/
|
||||
handleDrop(e) {
|
||||
this.addFiles(e.dataTransfer.files)
|
||||
},
|
||||
/**
|
||||
* @param {Event} e native file input event
|
||||
*/
|
||||
handleChange(e) {
|
||||
this.addFiles(e.target.files)
|
||||
},
|
||||
|
||||
27
plugins/fileUtils.js
Normal file
27
plugins/fileUtils.js
Normal file
@ -0,0 +1,27 @@
|
||||
import { formatBytes } from '~/plugins/shorthands'
|
||||
|
||||
/**
|
||||
* @param {File | Blob} file the file to validate
|
||||
* @param {{ maxSize: number, alertOnInvalid: boolean }} validationOptions the
|
||||
* constraints to validate the file against
|
||||
* @param validationOptions.maxSize the max file size in bytes
|
||||
* @param validationOptions.alertOnInvalid if an alert should pop up describing
|
||||
* each validation error
|
||||
* @returns `true` if the file is valid; `false` otherise
|
||||
*/
|
||||
export const fileIsValid = (file, validationOptions) => {
|
||||
const { maxSize, alertOnInvalid } = validationOptions
|
||||
if (maxSize !== null && maxSize !== undefined && file.size > maxSize) {
|
||||
console.log(`File size: ${file.size}, max size: ${maxSize}`)
|
||||
if (alertOnInvalid) {
|
||||
alert(
|
||||
`File ${file.name} is too big! Must be less than ${formatBytes(
|
||||
maxSize
|
||||
)}`
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@ -2,16 +2,7 @@ export default ({ store }, inject) => {
|
||||
inject('user', store.state.user)
|
||||
inject('tag', store.state.tag)
|
||||
inject('auth', store.state.auth)
|
||||
inject('formatNumber', (number) => {
|
||||
const x = +number
|
||||
if (x >= 1000000) {
|
||||
return (x / 1000000).toFixed(2).toString() + 'M'
|
||||
} else if (x >= 10000) {
|
||||
return (x / 1000).toFixed(1).toString() + 'K'
|
||||
} else {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||
}
|
||||
})
|
||||
inject('formatNumber', formatNumber)
|
||||
inject('formatVersion', (versionArray) => {
|
||||
const allVersions = store.state.tag.gameVersions.slice().reverse()
|
||||
const allReleases = allVersions.filter((x) => x.version_type === 'release')
|
||||
@ -98,15 +89,28 @@ export default ({ store }, inject) => {
|
||||
|
||||
return output.join(', ')
|
||||
})
|
||||
inject('formatBytes', (bytes, decimals = 2) => {
|
||||
if (bytes === 0) return '0 Bytes'
|
||||
|
||||
const k = 1024
|
||||
const dm = decimals < 0 ? 0 : decimals
|
||||
const sizes = ['Bytes', 'KiB', 'MiB', 'GiB']
|
||||
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
|
||||
})
|
||||
inject('formatBytes', formatBytes)
|
||||
}
|
||||
|
||||
export const formatNumber = (number) => {
|
||||
const x = +number
|
||||
if (x >= 1000000) {
|
||||
return (x / 1000000).toFixed(2).toString() + 'M'
|
||||
} else if (x >= 10000) {
|
||||
return (x / 1000).toFixed(1).toString() + 'K'
|
||||
} else {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||
}
|
||||
}
|
||||
|
||||
export const formatBytes = (bytes, decimals = 2) => {
|
||||
if (bytes === 0) return '0 Bytes'
|
||||
|
||||
const k = 1024
|
||||
const dm = decimals < 0 ? 0 : decimals
|
||||
const sizes = ['Bytes', 'KiB', 'MiB', 'GiB']
|
||||
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user