소스 검색

restore a fonctionnal UiImage

Olivier Massot 2 년 전
부모
커밋
7ee7157918
2개의 변경된 파일60개의 추가작업 그리고 26개의 파일을 삭제
  1. 26 18
      components/Ui/Image.vue
  2. 34 8
      services/data/imageManager.ts

+ 26 - 18
components/Ui/Image.vue

@@ -2,7 +2,7 @@
   <main>
     <div class="image-wrapper" :style="{width: width + 'px'}">
       <v-img
-        :src="imgSrcReload ? imgSrcReload : image"
+        :src="imageSrc"
         :lazy-src="defaultImagePath"
         :height="height"
         :width="width"
@@ -18,8 +18,7 @@
             <v-progress-circular
               :indeterminate="true"
               color="grey lighten-1"
-            >
-            </v-progress-circular>
+            />
           </v-row>
         </template>
       </v-img>
@@ -48,11 +47,13 @@ import {useContext} from "unctx";
 import {useNuxtApp} from "#app";
 import {useImageFetch} from "~/composables/data/useImageFetch";
 import {onUnmounted, watch, WatchStopHandle} from "@vue/runtime-core";
+import {useImageManager} from "~/composables/data/useImageManager";
 
 const props = defineProps({
   id: {
     type: Number,
-    required: false
+    required: true,
+    default: null
   },
   field: {
     type: String,
@@ -60,8 +61,7 @@ const props = defineProps({
   },
   defaultImage: {
     type: String,
-    required: false,
-    default: 'picture.jpeg'
+    required: false
   },
   height: {
     type: Number,
@@ -82,25 +82,34 @@ const props = defineProps({
   }
 })
 
-// fetchOnServer: false,  // TODO: je ne sais pas encore par quoi remplacer ça...
+const { imageManager } = useImageManager()
+const { fetch } = useImageFetch()
 
-const defaultImagePath = `/images/default/${props.defaultImage}`
+const defaultImagePath = props.defaultImage ?? imageManager.defaultImage
 
 const openUpload: Ref<Boolean> = ref(false)
-const imgSrcReload: Ref<any> = ref(null)
-const { $config } = useNuxtApp()
 
-const { fetch } = useImageFetch()
-const fetchImage = () => fetch(props.id ?? null, props.defaultImage, props.height, props.width)
+const imageSrc: Ref<string | null> = ref(null)
+let pending = ref(true)
+
+const fetchImage = async () => {
+  pending.value = true
+  imageSrc.value = await imageManager.get(props.id ?? null, defaultImagePath, props.height, props.width)
+  pending.value = false
+}
 
-const {data: image, pending} = fetchImage()
+onMounted(
+    () => {
+      fetchImage()
+    }
+)
 
 const unwatch: WatchStopHandle = watch(() => props.id, async (newValue, oldValue) => {
-  imgSrcReload.value = await fetch(newValue as number, props.defaultImage, props.height, props.width)
+  await fetchImage()
 })
 
-const onReload = () => {
-  fetchImage()
+const onReload = async () => {
+  await fetchImage()
   openUpload.value = false
 }
 
@@ -108,8 +117,7 @@ const onReload = () => {
  * Quand on souhaite faire un reset de l'image
  */
 const reset = () => {
-  imgSrcReload.value = null
-  image.value = require(defaultImagePath)
+  imageSrc.value = defaultImagePath
   openUpload.value = false
 }
 

+ 34 - 8
services/data/imageManager.ts

@@ -3,14 +3,38 @@ import ImageUtils from "~/services/utils/imageUtils";
 
 class ImageManager {
     private apiRequestService: ApiRequestService;
+    public readonly defaultImage = '/images/default/picture.jpeg'
 
     public constructor(apiRequestService: ApiRequestService) {
         this.apiRequestService = apiRequestService
     }
 
-    public async get(id: number, height: number = 0, width: number = 0) {
+    /**
+     * Retourne l'image correspondante sous forme d'un blob encodé au format base64,
+     * ou l'url d'une image par défaut si l'image est introuvable ou si l'id passé en paramètre est null
+     *
+     * Attention, les dimensions (hauteur / largeur) ne s'appliqueront pas à l'image par défaut, il est nécessaire de
+     * les redéfinir dans le composant lui-même.
+     *
+     * @param id  The id of the image; if null, the url to the default image is returned
+     * @param defaultImage The path of an image in the 'public' folder, default: '/images/default/picture.jpeg'
+     * @param height  Height of the image (does not apply to default image)
+     * @param width   Width of the image (does not apply to default image)
+     */
+    public async get(
+        id: number | null,
+        defaultImage: string | null,
+        height: number = 0,
+        width: number = 0
+    ): Promise<string> {
+
+        const defaultUrl = defaultImage ?? this.defaultImage
+
+        if (id === null) {
+            return defaultUrl
+        }
 
-        let url = `api/download/${id}`
+        const imageUrl = `api/download/${id}`
 
         // Set requested size if needed
         if (height > 0 || width > 0) {
@@ -19,17 +43,19 @@ class ImageManager {
             // url = Url.join(url, `${height}x${width}`)
         }
 
-        // Une image doit toujours avoir le time en options pour éviter les problème de cache
+        // Une image doit toujours avoir le time en options pour éviter les problèmes de cache
         const query = [new Date().getTime().toString()]
 
-        const response: any = await this.apiRequestService.get(url, query)
+        const response: any = await this.apiRequestService.get(imageUrl, query)
+        // console.log(response)
 
-        if(!response.data || response.data.size === 0) {
-            throw new Error('Error: image not found or invalid')
+        if(!response || response.size === 0) {
+            console.error('Error: image ' + id + ' not found or invalid')
+            return defaultUrl
         }
 
-        const blob = await ImageUtils.newBlob(response.data)
-        return await ImageUtils.blobToBase64(blob);
+        const blob = await ImageUtils.newBlob(response)
+        return await ImageUtils.blobToBase64(blob)
     }
 }