From 985fd13f180faa79187adf032f4e752e7d07d5af Mon Sep 17 00:00:00 2001 From: Ryan Debouvries Date: Wed, 21 Feb 2024 16:13:15 +0100 Subject: [PATCH] fix(delete_images): Change the way of deleting image to be more efficient and carry the deletion of objects --- src/components/InputModuleAttribute.vue | 3 +++ src/models/Module.ts | 24 ++++++++++++++--- src/models/ModulePart.ts | 23 +++++++++++++--- src/models/ModulePartElement.ts | 9 ++++--- src/stores/data.ts | 35 ++++++++++++++++--------- 5 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/components/InputModuleAttribute.vue b/src/components/InputModuleAttribute.vue index 9446a456..015b2db8 100644 --- a/src/components/InputModuleAttribute.vue +++ b/src/components/InputModuleAttribute.vue @@ -120,6 +120,9 @@ async function handleFileUpload(e: Event) { dataStore.editModule("file", file); } + // Clear the input file uploaded + input.value = ""; + // Preview the image await dataStore.loadImageUrl(); } diff --git a/src/models/Module.ts b/src/models/Module.ts index ae768fcd..e9b98ef9 100644 --- a/src/models/Module.ts +++ b/src/models/Module.ts @@ -48,6 +48,13 @@ export class Module { } deletePart(partIndex: number) { + // Get the datastore + const dataStore = useDataStore(); + // Mark the images to be deleted + for (const imageRef of this.parts[partIndex].getAllImages()) { + dataStore.imagesToDelete.push(imageRef); + } + // Delete the part this.parts.splice(partIndex, 1); } @@ -88,6 +95,14 @@ export class Module { ); } + getAllImages() { + let images = this.image !== "" ? [this.image] : []; + this.parts.forEach((part) => { + images = images.concat(part.getAllImages()); + }); + return images; + } + async uploadImagesToFirebase(originModule: Module) { // Get the datastore const dataStore = useDataStore(); @@ -97,7 +112,10 @@ export class Module { // Generate a new reference by a generated id and the same extension of the file const newRef = generateRandomId() + this.file.name.slice(this.file.name.lastIndexOf(".")); // Upload the file to firebase - await dataStore.uploadFileToFirebase(this.file, newRef, this.image); + await dataStore.uploadFileToFirebase(this.file, newRef); + // Mark the old reference to be deleted + if (this.image !== "") dataStore.imagesToDelete.push(this.image); + // Set the new reference to the image property this.image = newRef; } @@ -108,8 +126,8 @@ export class Module { this.image !== originModule.image && this.title === originModule.title ) { - // Delete the image from firebase - await dataStore.deleteFileFromFirebase(originModule.image); + // Mark the image to be deleted + dataStore.imagesToDelete.push(originModule.image); } // Upload the images of the parts to firebase diff --git a/src/models/ModulePart.ts b/src/models/ModulePart.ts index 69a65dc7..3638ee07 100644 --- a/src/models/ModulePart.ts +++ b/src/models/ModulePart.ts @@ -35,6 +35,12 @@ export class ModulePart { } deleteElement(eltIndex: number) { + // Get the datastore + const dataStore = useDataStore(); + // Mark the image to be deleted + const imageRef = this.elements[eltIndex].image; + if (imageRef !== "") dataStore.imagesToDelete.push(imageRef); + // Delete the element this.elements.splice(eltIndex, 1); } @@ -68,6 +74,14 @@ export class ModulePart { ); } + getAllImages() { + let images = this.image !== "" ? [this.image] : []; + for (const element of this.elements) { + if (element.image !== "") images = images.concat([element.image]); + } + return images; + } + async uploadImagesToFirebase(originPart: ModulePart) { // Get the datastore const dataStore = useDataStore(); @@ -77,7 +91,10 @@ export class ModulePart { // Generate a new reference by a generated id and the same extension of the file const newRef = generateRandomId() + this.file.name.slice(this.file.name.lastIndexOf(".")); // Upload the file to firebase - await dataStore.uploadFileToFirebase(this.file, newRef, this.image); + await dataStore.uploadFileToFirebase(this.file, newRef); + // Mark the old reference to be deleted + if (this.image !== "") dataStore.imagesToDelete.push(this.image); + // Set the new reference to the image property this.image = newRef; } @@ -88,8 +105,8 @@ export class ModulePart { this.image !== originPart.image && this.subtitle === originPart.subtitle ) { - // Delete the image from firebase - await dataStore.deleteFileFromFirebase(originPart.image); + // Mark the image to be deleted + dataStore.imagesToDelete.push(originPart.image); } // Upload the images of the elements to firebase diff --git a/src/models/ModulePartElement.ts b/src/models/ModulePartElement.ts index c5e9edaf..dbab4827 100644 --- a/src/models/ModulePartElement.ts +++ b/src/models/ModulePartElement.ts @@ -37,7 +37,10 @@ export class ModulePartElement { // Generate a new reference by a generated id and the same extension of the file const newRef = generateRandomId() + this.file.name.slice(this.file.name.lastIndexOf(".")); // Upload the file to firebase - await dataStore.uploadFileToFirebase(this.file, newRef, this.image); + await dataStore.uploadFileToFirebase(this.file, newRef); + // Mark the old reference to be deleted + if (this.image !== "") dataStore.imagesToDelete.push(this.image); + // Set the new reference to the image property this.image = newRef; } @@ -48,8 +51,8 @@ export class ModulePartElement { this.image !== originElement.image && this.text === originElement.text ) { - // Delete the image from firebase - await dataStore.deleteFileFromFirebase(originElement.image); + // Mark the image to be deleted + dataStore.imagesToDelete.push(originElement.image); } } } diff --git a/src/stores/data.ts b/src/stores/data.ts index b2cdd409..f75ad838 100644 --- a/src/stores/data.ts +++ b/src/stores/data.ts @@ -19,6 +19,7 @@ interface DataState { accountsEdited: Map; tipsEdited: Array; moduleEdited: Module; + imagesToDelete: Array; currentRoute: RouteLocationNormalizedLoaded; imageUrl: string; toSave: boolean; @@ -34,6 +35,7 @@ export const useDataStore = defineStore("dataStore", { accountsEdited: new Map(), tipsEdited: Array(), moduleEdited: {} as Module, + imagesToDelete: Array(), currentRoute: {} as RouteLocationNormalizedLoaded, imageUrl: "", toSave: false, @@ -47,6 +49,7 @@ export const useDataStore = defineStore("dataStore", { getAccountsEdited: (state: DataState) => state.accountsEdited, getTipsEdited: (state: DataState) => state.tipsEdited, getModuleEdited: (state: DataState) => state.moduleEdited, + getImagesToDelete: (state: DataState) => state.imagesToDelete, getCurrentRoute: (state: DataState) => state.currentRoute, getImageUrl: (state: DataState) => state.imageUrl, needToSave: (state: DataState) => state.toSave, @@ -62,6 +65,7 @@ export const useDataStore = defineStore("dataStore", { this.accountsEdited = new Map(); this.tipsEdited = Array(); this.moduleEdited = {} as Module; + this.imagesToDelete = Array(); this.imageUrl = ""; this.toSave = false; }, @@ -100,6 +104,11 @@ export const useDataStore = defineStore("dataStore", { } }, deleteModule(id: string) { + // Mark the images to be deleted + const deletedModule = this.modulesEdited.get(id)!; + for (const imageRef of deletedModule.getAllImages()) { + this.imagesToDelete.push(imageRef); + } // Change local datas to delete module this.modulesEdited.delete(id); // Update order @@ -238,18 +247,27 @@ export const useDataStore = defineStore("dataStore", { await setDoc(doc(modulesCollection, id), module.toJsonObject()); } } - // Delete accounts + // Delete modules for (const id of this.modules.keys()) { if (!this.modulesEdited.has(id)) { // This module has been deleted await deleteDoc(doc(modulesCollection, id)); } } + // Delete images that need to be deleted + for (const imageRef of this.imagesToDelete) { + await this.deleteFileFromFirebase(imageRef); + } + // Reload modules this.loadModulesFromFirebase(); }, saveModuleToFirebase: async function (id: string) { // Upload images to firebase await this.moduleEdited.uploadImagesToFirebase(this.module); + // Delete images that need to be deleted + for (const imageRef of this.imagesToDelete) { + await this.deleteFileFromFirebase(imageRef); + } // Replace existing module await setDoc(doc(modulesCollection, id), this.moduleEdited.toJsonObject()); // Reload module @@ -283,21 +301,14 @@ export const useDataStore = defineStore("dataStore", { // Reload accounts this.loadAccountsFromFirebase(); }, - uploadFileToFirebase: async function (file: File, newRef: string, oldRef: string) { + uploadFileToFirebase: async function (file: File, newRef: string) { // Create a storage reference const storageRef = ref(storage, newRef); // Upload the new file - await uploadBytes(storageRef, file) - .then(async () => { - // Remove old file if exists - if (oldRef !== "") { - await this.deleteFileFromFirebase(oldRef); - } - }) - .catch((error) => { - console.error(error); - }); + await uploadBytes(storageRef, file).catch((error) => { + console.error(error); + }); }, deleteFileFromFirebase: async function (oldRef: string) { // Delete the file from firebase