diff --git a/.gitignore b/.gitignore index aee18b0..fb95957 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,9 @@ dist # Compiled SCSS public/stylesheets/*.css* + +# Json DB +db.json + +# Uploaded images +public/images/upload/ diff --git a/public/javascripts/settings/decks.js b/public/javascripts/settings/decks.js index a5b78d3..0cd4f04 100644 --- a/public/javascripts/settings/decks.js +++ b/public/javascripts/settings/decks.js @@ -4,6 +4,8 @@ const deck = document.getElementById("deck"); const modal = document.getElementById("modal"); const type = document.getElementById("type"); const title = document.getElementById("title"); +const image = document.getElementById("image"); +const upload = document.getElementById("upload"); const customs = document.getElementById("customs"); const form = modal.querySelector("form"); let modalInstance, types, slot; @@ -61,10 +63,11 @@ socket.on("getSlot", data => { if (data.data) { title.value = data.data.text; + image.value = data.data.image ? data.data.image : ""; type.querySelector(`option[value=${data.data.type}]`).selected = true; customFields(data.data.options); } else - type.value = title.value = ""; + type.value = title.value = image.value = ""; M.updateTextFields(); M.FormSelect.init(type); @@ -95,6 +98,27 @@ socket.on("setSlot", data => { } }); +socket.on("uploadImage", data => { + if (data.error) + console.log(data.error); + else if (data) + image.value = data +}); + +upload.addEventListener("dragover", ev => { + ev.preventDefault(); +}, true); + +upload.addEventListener("drop", ev => { + ev.preventDefault(); + uploadImage(ev.dataTransfer.files) +}, true); + +upload.addEventListener("change", ev => { + ev.stopPropagation(); + uploadImage(upload.files) +}); + deckSelect.addEventListener("change", ev => { ev.stopPropagation(); socket.emit("getDeck", deckSelect.value); @@ -110,7 +134,7 @@ document.getElementById("save").addEventListener("click", ev => { if (!slot.data) slot.data = {}; - for (const k of ["text", "type"]) { //image + for (const k of ["text", "type", "image"]) { slot.data[k] = data[k]; delete data[k]; } @@ -174,3 +198,15 @@ function customFields(values) { } M.updateTextFields(); } + +function uploadImage(files) { + if (files.length === 0) + alert("No image !"); + else if (files.length > 1) + alert("Only one image !"); + else if (!files[0].type.match(/image.*/)) + alert("Not a image !"); + else + socket.emit("uploadImage", files[0]); + M.updateTextFields(); +} diff --git a/public/stylesheets/style.sass b/public/stylesheets/style.sass index 8091472..58fb01e 100644 --- a/public/stylesheets/style.sass +++ b/public/stylesheets/style.sass @@ -20,5 +20,5 @@ justify-content: center #deck>div>div>img - max-height: 15vh - max-width: 15vh + max-height: 100% + max-width: 100% diff --git a/sockets/index.js b/sockets/index.js index 092f94e..17f39f3 100644 --- a/sockets/index.js +++ b/sockets/index.js @@ -5,6 +5,7 @@ module.exports = socket => { socket.on("getType", require("./getType")(socket)); socket.on("setSlot", require("./setSlot")(socket)); socket.on("trigger", require("./trigger")(socket)); + socket.on("uploadImage", require("./uploadImage")(socket)); console.log("New connection !"); socket.emit("connected"); }; diff --git a/sockets/uploadImage.js b/sockets/uploadImage.js new file mode 100644 index 0000000..b24e044 --- /dev/null +++ b/sockets/uploadImage.js @@ -0,0 +1,17 @@ +const fs = require("fs"); +const crypto = require('crypto'); +const basePath = "./public/images/upload/"; + + +function hash(data) { + return crypto.createHash("sha256").update(data).digest("hex"); +} + +module.exports = socket => { + return data => { + let uuid = hash(data); + if (!(uuid in fs.readdirSync(basePath))) + fs.writeFileSync(basePath+uuid, data); + socket.emit("uploadImage", (basePath+uuid).replace("./public", "")) + } +}; diff --git a/views/settings/decks.pug b/views/settings/decks.pug index 3c07d1d..c5c5ddd 100644 --- a/views/settings/decks.pug +++ b/views/settings/decks.pug @@ -13,8 +13,15 @@ block settings form.col.s12 .row .input-field.col.s12 - input#title(type="text" name="text" required).validate + input#title(type="text" name="text" minlength=1 required).validate label(for="title") Text + .row + .input-field.col.s8 + input#image(type="text" name="image").validate + label(for="image") Image + span.helper-text File URL or upload + .input-field.col.s4 + input#upload(type="file" accept="image/*" multiple=false) .row .input-field.col.s12 select#type(name="type" required).validate