mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-24 16:56:14 -04:00
feat: FileUploader + Base64
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
This commit is contained in:
parent
da092a9bd3
commit
1876db0ddc
7 changed files with 251 additions and 205 deletions
Binary file not shown.
Before Width: | Height: | Size: 6.7 KiB |
|
@ -1 +0,0 @@
|
|||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg>
|
Before Width: | Height: | Size: 539 B |
|
@ -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>
|
|
@ -4,21 +4,21 @@
|
|||
<v-card>
|
||||
<v-card-title>File to Base64</v-card-title>
|
||||
<v-card-text>
|
||||
<FileUploader v-model="imageFile"/>
|
||||
<FileUploader v-model="file"/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" lg="4" md="6" sm="12" v-if="base64">
|
||||
<v-col cols="12" lg="4" md="6" sm="12" v-if="base64 || loading">
|
||||
<v-card>
|
||||
<v-card-title>Result</v-card-title>
|
||||
<v-card-text>
|
||||
<v-img :src="base64" class="mb-4" v-if="isImage"/>
|
||||
<v-textarea
|
||||
label="File in base 64"
|
||||
outlined
|
||||
readonly
|
||||
v-model="base64"
|
||||
hide-details
|
||||
:loading="loading"
|
||||
/>
|
||||
<div class="text-center mt-4">
|
||||
<v-btn @click="copyBase64()" depressed>Copy base64</v-btn>
|
||||
|
@ -32,34 +32,36 @@
|
|||
|
||||
<script>
|
||||
import FileUploader from '../../components/FileUploader'
|
||||
import {copyToClipboard, fileIsImage} from "../../utils/helpers";
|
||||
import {copyToClipboard} from "../../utils/helpers";
|
||||
|
||||
export default {
|
||||
name: "FileToBase64",
|
||||
components: {FileUploader},
|
||||
data() {
|
||||
return {
|
||||
imageFile: undefined,
|
||||
file: undefined,
|
||||
loading: false,
|
||||
base64: '',
|
||||
isImage: false,
|
||||
copyBase64(){
|
||||
copyBase64() {
|
||||
copyToClipboard(this.base64)
|
||||
this.$toast.success('Copied to clipboard.')
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
handleBase64(base64){
|
||||
this.base64 = base64;
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
imageFile() {
|
||||
this.isImage = fileIsImage(this.imageFile);
|
||||
|
||||
file() {
|
||||
this.loading = true;
|
||||
this.base64 = '';
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(this.imageFile);
|
||||
reader.onload = () => {
|
||||
this.base64 = reader.result;
|
||||
}
|
||||
reader.onerror = () => {
|
||||
this.base64 = '[An error as occurred]';
|
||||
}
|
||||
reader.onload = () => this.handleBase64(reader.result);
|
||||
reader.onerror = () => this.handleBase64('[An error as occurred]');
|
||||
reader.readAsDataURL(this.file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue