feat: FileUploader + Base64

Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
This commit is contained in:
Corentin Thomasset 2020-05-31 22:31:14 +02:00 committed by Corentin THOMASSET
parent e67e4cf547
commit 805716910a
7 changed files with 251 additions and 205 deletions

View file

@ -1,7 +1,7 @@
<template>
<div
class="drop-area pa-4 text-center"
:class="{'drag-over':dragging }"
:class="{'drag-over':dragging, 'pb-0':!loading}"
@dragover.prevent
@drop.prevent="imageDropped"
@dragenter="dragEnter()"
@ -9,47 +9,112 @@
@dragleave="dragLeave()"
@dragexit="dragExit()"
>
<p>Drag & drop a file here</p>
<p class="or">or</p>
<v-btn depressed>select a file</v-btn>
<p class="or">or</p>
<v-text-field outlined dense label="Paste an url to the file" hide-details></v-text-field>
<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"
@click:append="urlFilled(url)"
@keypress.enter="urlFilled(url)"
v-model="url"
append-icon="fa-arrow-right"
dense
label="Paste the file url"
outlined
:error-messages="urlErrors"
/>
</div>
</div>
</div>
</template>
<script>
import * as axios from "axios";
export default {
name: "FileUploader",
props: ['value'],
props: {
allowUrl: {
type: Boolean,
default: true
}
},
data() {
return {
dragging: false,
dragEnterCounter: 0
urlErrors: undefined,
dragEnterCounter: 0,
url: '',
loading: false
}
},
methods: {
imageDropped(e) {
this.dragging = false;
const droppedFiles = [...e.dataTransfer.files];
if (!droppedFiles || droppedFiles.length === 0) return;
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;
}
}
this.$emit('input', droppedFiles[0])
},
dragEnter() {
this.dragEnterCounter++;
this.dragging = true;
},
dragLeave() {
if(--this.dragEnterCounter <= 0){
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()
}
}
}
@ -73,5 +138,11 @@
border-color: #4CAF50;
}
.v-input__icon {
button {
margin-top: 0 !important;
}
}
}
</style>