feat: added file-to-base64

This commit is contained in:
Corentin Thomasset 2021-03-14 21:20:35 +01:00
parent 5fa81533d9
commit 1034296359
No known key found for this signature in database
GPG key ID: DBD997E935996158
5 changed files with 316 additions and 47 deletions

148
components/FileUploader.vue Normal file
View file

@ -0,0 +1,148 @@
<template>
<div
class="drop-area pa-4 text-center"
:class="{'drag-over':dragging, 'pb-0':!loading}"
@dragover.prevent
@drop.prevent="imageDropped"
@dragenter="dragEnter()"
@dragend="dragEnd()"
@dragleave="dragLeave()"
@dragexit="dragExit()"
>
<div v-if="loading">
<v-progress-circular
indeterminate
color="primary"
/>
</div>
<div v-else>
<p>Drag & drop a file here</p>
<p class="or">
or
</p>
<v-btn depressed @click="manualUploadClicked">
select a file
</v-btn>
<input ref="uploadInput" type="file" hidden @change="(e) => handleFiles(e.target.files[0])">
<div v-if="allowUrl">
<p class="or">
or
</p>
<v-text-field
ref="urlInput"
v-model="url"
append-icon="fa-arrow-right"
dense
label="Paste the file url"
outlined
:error-messages="urlErrors"
@click:append="urlFilled(url)"
@keypress.enter="urlFilled(url)"
/>
</div>
</div>
</div>
</template>
<script lang="ts">
import {Component, Prop, Vue} from 'nuxt-property-decorator'
@Component
export default class FileUploader extends Vue {
@Prop({default: true}) readonly allowUrl!: boolean
dragging = false
urlErrors = null
dragEnterCounter = 0
url = ''
loading = false
imageDropped(e) {
this.dragging = false
if (e.dataTransfer.items.length > 0) {
const item = e.dataTransfer.items[0]
switch (item.kind) {
case 'string':
item.getAsString(url => this.urlFilled(url))
break
case 'file':
this.handleFiles(item.getAsFile())
break
}
}
}
dragEnter() {
this.dragEnterCounter++
this.dragging = true
}
dragLeave() {
if (--this.dragEnterCounter <= 0) {
this.dragging = false
}
}
async urlFilled(url) {
if (url && url.length > 0) {
this.loading = true
try {
const {data, headers} = await axios.get(url)
const name = url.split('/').pop()
const file = new File([data], name, {type: headers['content-type']})
this.handleFiles(file)
} catch (ignored) {
this.urlErrors = 'Incorrect url'
}
this.loading = false
}
}
dragEnd() {
this.dragging = false
}
dragExit() {
this.dragging = false
}
handleFiles(file) {
if (!file) {
return
}
this.$emit('input', file)
}
manualUploadClicked() {
this.$refs.uploadInput.click()
}
}
</script>
<style lang="less">
.drop-area {
border: 2px dashed rgba(255,255,255,0.3);
border-radius: 10px;
background-color: rgba(255, 255, 255, 0.03);
& > *, .v-btn {
margin: 0 !important;
}
.or {
opacity: 0.7;
margin: 5px 0 !important;
}
&.drag-over {
border-color: var(--v-primary-base);
}
.v-input__icon {
button {
margin-top: 0 !important;
}
}
}
</style>