Skip to content
Snippets Groups Projects
Commit 4809a991 authored by Trirst's avatar Trirst
Browse files

Set tags of an image after uploading it. Massive overhaul to ImageUpload.vue

parent 4c0ea671
No related branches found
No related tags found
No related merge requests found
Pipeline #890 passed
<template> <template>
<div> <div>
<div class="m-2">
Click on the image's preview to remove the entry from uploading
</div>
<div
v-for="(image, id) in imageList"
:key="image.url"
class="flex flex-row"
>
<img
:src="image.url"
@click="removeImage(id)"
alt=""
class="max-w-xs m-4"
/>
<form :id="'image-update-form-' + id" class="flex flex-col">
<input
type="text"
placeholder="Source"
name="source"
class="inputBox inputPayload"
/>
<input
type="text"
placeholder="Parent"
name="parent"
class="inputBox inputPayload"
/>
<textarea
type="text"
placeholder="Commentary"
name="commentary"
class="inputBox inputPayload"
/>
<textarea
type="text"
placeholder="Commentary translation"
name="commentary_translation"
class="inputBox inputPayload"
/>
</form>
</div>
<div <div
class="h-48 m-4 border-dotted border-4 border-gray-400" class="h-48 m-4 border-dotted border-4 border-gray-400"
@drop.prevent=" @drop.prevent="
...@@ -79,7 +38,7 @@ ...@@ -79,7 +38,7 @@
Please upload PNG, JPEG or GIF image only. Please upload PNG, JPEG or GIF image only.
</WarningBox> </WarningBox>
<button <button
v-show="imageList.length" v-show="imageUploadList.length"
@click="submitImage" @click="submitImage"
class=" class="
border border-gray-500 border border-gray-500
...@@ -95,12 +54,68 @@ ...@@ -95,12 +54,68 @@
Submit Submit
</button> </button>
</div> </div>
<strong class="m-2" v-show="imageUploadList.length">
Click on the image's preview to remove the entry from uploading
</strong>
<div
v-for="(image, id) in imageUploadList"
:key="image.url"
class="flex flex-row divide-y-4 divide-gray-600 divide-dashed"
>
<img
:src="image.url"
@click="removeImage(id)"
alt=""
class="max-w-xs m-4"
/>
<div class="flex flex-col flex-1">
<form :id="'image-update-form-' + id" class="flex flex-col flex-1">
<input
type="text"
placeholder="Source"
name="source"
autocomplete="off"
class="inputBox inputPayload"
/>
<input
type="text"
placeholder="Parent"
name="parent"
autocomplete="off"
class="inputBox inputPayload"
/>
<textarea
type="text"
placeholder="Commentary"
name="commentary"
autocomplete="off"
class="inputBox inputPayload resize-none flex-1"
/>
<textarea
type="text"
placeholder="Commentary translation"
name="commentary_translation"
autocomplete="off"
class="inputBox inputPayload resize-none flex-1"
/>
</form>
<input
type="text"
placeholder="Tags"
name="tags"
autocomplete="off"
:id="'tagsInput' + id"
class="inputBox inputPayload"
/>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import { mapActions, mapState } from "vuex"; import { mapActions, mapState } from "vuex";
import WarningBox from "@/components/WarningBox.vue"; import WarningBox from "@/components/WarningBox.vue";
import paths from "@/assets/js/paths.js";
export default { export default {
components: { components: {
...@@ -108,7 +123,7 @@ export default { ...@@ -108,7 +123,7 @@ export default {
}, },
data: () => { data: () => {
return { return {
imageList: [], imageUploadList: [],
invalidType: false, invalidType: false,
}; };
}, },
...@@ -118,17 +133,18 @@ export default { ...@@ -118,17 +133,18 @@ export default {
methods: { methods: {
updateWrapper(event) { updateWrapper(event) {
this.checkImageType(event) this.checkImageType(event)
? this.updateImageList(event) ? this.updateImageUploadList(event)
: (this.$refs.imageInput.value = ""); : (this.$refs.imageInput.value = "");
}, },
updateImageList(event) { updateImageUploadList(event) {
this.imageList = this.imageList.concat( this.imageUploadList = this.imageUploadList.concat(
event event
? this.addMetadata([...event.dataTransfer.files]) ? this.mapFilesToPreviews([...event.dataTransfer.files])
: this.addMetadata([...this.$refs.imageInput.files]) : this.mapFilesToPreviews([...this.$refs.imageInput.files])
); );
}, },
addMetadata(files) { // Return an array of objects whose fields are the image's file and the preview's URL
mapFilesToPreviews(files) {
let tempArray = []; let tempArray = [];
files.forEach((file) => { files.forEach((file) => {
tempArray.push({ file, url: URL.createObjectURL(file) }); tempArray.push({ file, url: URL.createObjectURL(file) });
...@@ -137,11 +153,11 @@ export default { ...@@ -137,11 +153,11 @@ export default {
}, },
checkImageType(event) { checkImageType(event) {
const acceptedTypes = ["image/png", "image/jpeg", "image/gif"]; const acceptedTypes = ["image/png", "image/jpeg", "image/gif"];
let imageList = event let imageUploadList = event
? [...event.dataTransfer.files] ? [...event.dataTransfer.files]
: [...this.$refs.imageInput.files]; : [...this.$refs.imageInput.files];
for (let i = 0; i < imageList.length; i++) { for (let i = 0; i < imageUploadList.length; i++) {
if (!acceptedTypes.includes(imageList[i].type)) { if (!acceptedTypes.includes(imageUploadList[i].type)) {
this.invalidType = true; this.invalidType = true;
return false; return false;
} }
...@@ -150,21 +166,22 @@ export default { ...@@ -150,21 +166,22 @@ export default {
return true; return true;
}, },
removeImage(id) { removeImage(id) {
this.imageList.splice(id, 1); this.imageUploadList.splice(id, 1);
}, },
async submitImage() { async submitImage() {
let formData = new FormData(); let formData = new FormData();
for (let i = 0; i < this.imageList.length; i++) { for (let i = 0; i < this.imageUploadList.length; i++) {
formData.set("image", this.imageList[i].file); formData.set("image", this.imageUploadList[i].file);
let data = await this.postImage(formData); let data = await this.postImageFile(formData);
this.updateImage( this.setImageInfo(
data.snowflake, data.snowflake,
this.serializeForm("image-update-form-" + i) this.serializeForm("image-update-form-" + i)
); );
this.setImageTags(data.snowflake, "tagsInput" + i);
} }
// Clean up // Clean up
this.invalidType = false; this.invalidType = false;
this.imageList = []; this.imageUploadList = [];
}, },
// Serialize form inputs into JSON object that can be sent to API // Serialize form inputs into JSON object that can be sent to API
serializeForm(formID) { serializeForm(formID) {
...@@ -172,7 +189,9 @@ export default { ...@@ -172,7 +189,9 @@ export default {
Object.fromEntries(new FormData(document.getElementById(formID))) Object.fromEntries(new FormData(document.getElementById(formID)))
); );
}, },
async updateImage(flake, imageUpdatePayload) { // Send an image update payload including 4 fields: "source", "parent", "commentary",
// "commentary translation" to paths.ImageField
async setImageInfo(flake, imageUpdatePayload) {
const options = { const options = {
method: "PATCH", method: "PATCH",
headers: { headers: {
...@@ -182,7 +201,20 @@ export default { ...@@ -182,7 +201,20 @@ export default {
}; };
await fetch(`/api/image/${flake}`, options); await fetch(`/api/image/${flake}`, options);
}, },
async postImage(fd) { async setImageTags(flake, tagsInputID) {
const tags = document
.getElementById(tagsInputID)
.value.split(" ")
.filter((element) => element.length > 0);
const options = {
method: "PUT",
};
for (let i = 0; i < tags.length; i++) {
await fetch(paths.ImageTagField(flake, tags[i]), options);
}
},
async postImageFile(fd) {
const options = { const options = {
method: "POST", method: "POST",
headers: { headers: {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment