feat: urlencoder + file in base64

This commit is contained in:
CorentinTh 2020-04-27 00:39:40 +02:00 committed by Corentin THOMASSET
parent ee4eb30ca2
commit d9f6c55a79
13 changed files with 260 additions and 21 deletions

5
package-lock.json generated
View file

@ -12104,11 +12104,6 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz",
"integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
},
"vue-async-computed": {
"version": "3.8.2",
"resolved": "https://registry.npmjs.org/vue-async-computed/-/vue-async-computed-3.8.2.tgz",
"integrity": "sha512-If5roOhp/x0WWd0TWRD77YsuFoiIw3MbkcRlIB/FE3TqQCPje52eQp5CV5NN/7B0VAyPuGX5JQa+rc9AOcGAYw=="
},
"vue-cli-plugin-vuetify": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.0.5.tgz",

View file

@ -13,7 +13,6 @@
"register-service-worker": "^1.7.1",
"roboto-fontface": "*",
"vue": "^2.6.11",
"vue-async-computed": "^3.8.2",
"vue-cryptojs": "^2.1.4",
"vue-router": "^3.1.6",
"vuetify": "^2.2.11",

View file

@ -89,6 +89,13 @@
child: [
{icon: 'fa-calendar', text: 'Date/Time converter', link: '/date-converter'},
],
},
{
title: 'Web',
child: [
{icon: 'fa-link', text: 'URL encode/decode', link: '/url-encoder'},
{icon: 'fa-file-image-o', text: 'File to Base64', link: '/file-to-base64'},
],
}
],
}),
@ -100,7 +107,7 @@
<style lang="less">
html{
overflow-y: hidden !important;
overflow-y: auto !important;
}
.single-card {
width: 100%;

View file

@ -0,0 +1,77 @@
<template>
<div
class="drop-area pa-4 text-center"
:class="{'drag-over':dragging }"
@dragover.prevent
@drop.prevent="imageDropped"
@dragenter="dragEnter()"
@dragend="dragEnd()"
@dragleave="dragLeave()"
@dragexit="dragExit()"
>
<p>Drag & drop a file here</p>
<p class="or">or</p>
<v-btn depressed>upload manually</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>
</template>
<script>
export default {
name: "FileUploader",
props: ['value'],
data() {
return {
dragging: false,
dragEnterCounter: 0
}
},
methods: {
imageDropped(e) {
this.dragging = false;
const droppedFiles = [...e.dataTransfer.files];
if (!droppedFiles || droppedFiles.length === 0) return;
this.$emit('input', droppedFiles[0])
},
dragEnter() {
this.dragEnterCounter++;
this.dragging = true;
},
dragLeave() {
if(--this.dragEnterCounter <= 0){
this.dragging = false;
}
},
dragEnd() {
this.dragging = false;
},
dragExit() {
this.dragging = false;
}
}
}
</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: #4CAF50;
}
}
</style>

View file

@ -5,7 +5,6 @@ import router from './router'
import vuetify from './plugins/vuetify'
import 'roboto-fontface/css/roboto/roboto-fontface.css'
import 'font-awesome/css/font-awesome.css'
import './plugins/async-computed'
import './plugins/crypto-js'
import './plugins/toast-snackbar'

View file

@ -1,4 +0,0 @@
import Vue from 'vue';
import AsyncComputed from 'vue-async-computed'
Vue.use(AsyncComputed)

View file

@ -1,9 +1,11 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from './routes/Home.vue'
import TokenGenerator from "./components/TokenGenerator";
import Hash from "./components/Hash";
import DateConverter from "./components/DateConverter";
import TokenGenerator from "./routes/tools/TokenGenerator";
import Hash from "./routes/tools/Hash";
import DateConverter from "./routes/tools/DateConverter";
import UrlEncoder from "./routes/tools/UrlEncoder";
import FileToBase64 from "./routes/tools/FileToBase64";
Vue.use(VueRouter)
@ -24,6 +26,14 @@ const routes = [
path: '/date-converter',
component: DateConverter
},
{
path: '/url-encoder',
component: UrlEncoder
},
{
path: '/file-to-base64',
component: FileToBase64
},
{
path: '/about',
name: 'About',

View file

@ -1,6 +1,6 @@
<template>
<v-row justify="center" align="center">
<v-col xl="4" lg="6" md="12">
<v-col cols="12" xl="4" lg="6" md="12">
<v-card class="mb-5">
<v-card-title>Input</v-card-title>
<v-card-text>
@ -37,7 +37,7 @@
</v-card-text>
</v-card>
</v-col>
<v-col xl="4" lg="6" md="12" >
<v-col cols="12" xl="4" lg="6" md="12" >
<v-card>
<v-card-title>Dates formats</v-card-title>
<v-card-text>
@ -61,7 +61,7 @@
</template>
<script>
import {copyToClipboard} from "../utils/helpers";
import {copyToClipboard} from "../../utils/helpers";
export default {
name: "DateConverter",

View file

@ -0,0 +1,70 @@
<template>
<v-row justify="center" align="center">
<v-col cols="12" lg="4" md="6" sm="12">
<v-card>
<v-card-title>File to Base64</v-card-title>
<v-card-text>
<FileUploader v-model="imageFile"/>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" lg="4" md="6" sm="12" v-if="base64">
<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
/>
<div class="text-center mt-4">
<v-btn @click="copyBase64()" depressed>Copy base64</v-btn>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</template>
<script>
import FileUploader from '../../components/FileUploader'
import {copyToClipboard, fileIsImage} from "../../utils/helpers";
export default {
name: "FileToBase64",
components: {FileUploader},
data() {
return {
imageFile: undefined,
base64: '',
isImage: false,
copyBase64(){
copyToClipboard(this.base64)
this.$toast.success('Copied to clipboard.')
}
}
},
watch: {
imageFile() {
this.isImage = fileIsImage(this.imageFile);
const reader = new FileReader();
reader.readAsDataURL(this.imageFile);
reader.onload = () => {
this.base64 = reader.result;
}
reader.onerror = () => {
this.base64 = '[An error as occurred]';
}
}
}
}
</script>
<style scoped>
</style>

View file

@ -30,7 +30,7 @@
<script>
import Vue from 'vue'
import {copyToClipboard} from "../utils/helpers";
import {copyToClipboard} from "../../utils/helpers";
export default {
name: "Hash",

View file

@ -29,7 +29,7 @@
</template>
<script>
import {copyToClipboard} from "../utils/helpers";
import {copyToClipboard} from "../../utils/helpers";
const shuffle = (str) => str.split('').sort(() => 0.5 - Math.random()).join('');
const noop = () => {

View file

@ -0,0 +1,81 @@
<template>
<v-row justify="center" align="center">
<v-col cols="12" lg="4" md="6" sm="12">
<v-card>
<v-card-title>URL Encode</v-card-title>
<v-card-text>
<v-textarea
outlined
label="String to encode"
v-model="encodeInput"
/>
<v-textarea
readonly
outlined
label="URL encoded string"
v-model="encodeOutput"
/>
<div class="text-center">
<v-btn @click="copyText(encodeOutput)" depressed>Copy result</v-btn>
</div>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" lg="4" md="6" sm="12">
<v-card>
<v-card-title>URL Decode</v-card-title>
<v-card-text>
<v-textarea
outlined
label="String to decode"
v-model="decodeInput"
/>
<v-textarea
readonly
outlined
label="URL decoded string"
v-model="decodeOutput"
/>
<div class="text-center">
<v-btn @click="copyText(decodeOutput)" depressed>Copy result</v-btn>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</template>
<script>
import {copyToClipboard} from "../../utils/helpers";
export default {
name: "UrlEncoder",
data(){
return {
encodeInput: 'Hello world :)',
decodeInput: 'Hello%20world%20%3A)',
copyText(text){
copyToClipboard(text)
this.$toast.success('Copied to clipboard.')
}
}
},
computed:{
encodeOutput(){
return encodeURIComponent(this.encodeInput)
},
decodeOutput(){
return decodeURIComponent(this.encodeInput)
},
}
}
</script>
<style scoped>
</style>

View file

@ -8,6 +8,11 @@ const copyToClipboard = (text) => {
return result;
}
export {
copyToClipboard
const fileIsImage = (file) => {
return file.type.split('/')[0] === 'image';
}
export {
copyToClipboard,
fileIsImage
}