mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-21 07:16:15 -04:00
291 lines
6.9 KiB
Vue
291 lines
6.9 KiB
Vue
<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>
|
|
import * as axios from 'axios'
|
|
export default {
|
|
name: 'FileUploader',
|
|
props: {
|
|
allowUrl: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
dragging: false,
|
|
urlErrors: undefined,
|
|
dragEnterCounter: 0,
|
|
url: '',
|
|
loading: false
|
|
}
|
|
},
|
|
methods: {
|
|
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 #363636;
|
|
border-radius: 10px;
|
|
& > *, .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>
|
|
|
|
<!--<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: string|null = null-->
|
|
<!-- dragEnterCounter = 0-->
|
|
<!-- url = ''-->
|
|
<!-- loading = false-->
|
|
|
|
<!-- imageDropped(e: DragEvent) {-->
|
|
<!-- this.dragging = false-->
|
|
<!-- if (e.dataTransfer.items.length > 0) {-->
|
|
<!-- const item = e.dataTransfer.items[0]-->
|
|
<!-- switch (item.kind) {-->
|
|
<!-- case 'string':-->
|
|
<!-- item.getAsString((url: string) => 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: string) {-->
|
|
<!-- if (url && url.length > 0) {-->
|
|
<!-- this.loading = true-->
|
|
<!-- try {-->
|
|
<!-- const {data, headers} = await this.$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: 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>-->
|