Browse Source

add the useImageFetch composable, implements it in UiImage, documents

Olivier Massot 2 years ago
parent
commit
c924d347ad

+ 14 - 22
components/Ui/Image.vue

@@ -1,3 +1,9 @@
+<!--
+Composant Image permettant de charger et d'afficher une image stockée sur les serveurs Opentalent à partir de son id.
+Permet d'afficher une image par défaut si l'image demandée n'est pas disponible ou invalide.
+
+Si la propriété 'upload' est à 'true', propose aussi un input pour uploader une nouvelle image.
+-->
 <template>
   <main>
     <div class="image-wrapper" :style="{width: width + 'px'}">
@@ -7,6 +13,7 @@
         :height="height"
         :width="width"
         aspect-ratio="1"
+        @click="refresh"
       >
         <template #placeholder>
           <v-row
@@ -43,8 +50,6 @@
 
 <script setup lang="ts">
 import {ref, Ref} from "@vue/reactivity";
-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";
@@ -55,10 +60,6 @@ const props = defineProps({
     required: true,
     default: null
   },
-  field: {
-    type: String,
-    required: false
-  },
   defaultImage: {
     type: String,
     required: false
@@ -71,6 +72,10 @@ const props = defineProps({
     type: Number,
     required: false
   },
+  field: {
+    type: String,
+    required: false
+  },
   upload: {
     type: Boolean,
     required: false,
@@ -89,27 +94,14 @@ const defaultImagePath = props.defaultImage ?? imageManager.defaultImage
 
 const openUpload: Ref<Boolean> = ref(false)
 
-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
-}
-
-onMounted(
-    () => {
-      fetchImage()
-    }
-)
+const { data: imageSrc, pending, refresh } = fetch(props.id ?? null, defaultImagePath, props.height, props.width)
 
 const unwatch: WatchStopHandle = watch(() => props.id, async (newValue, oldValue) => {
-  await fetchImage()
+  await refresh()
 })
 
 const onReload = async () => {
-  await fetchImage()
+  await refresh()
   openUpload.value = false
 }
 

+ 12 - 21
composables/data/useImageFetch.ts

@@ -1,34 +1,25 @@
-import {useFetch, FetchResult} from "#app";
+import {FetchResult, useAsyncData} from "#app";
 import {useImageManager} from "~/composables/data/useImageManager";
-import {ref, Ref} from "@vue/reactivity";
 
 interface useImageFetchReturnType {
-    fetch: (id: number | null, defaultImage?: string, height?: number, width?: number) => FetchResult<any>
+    fetch: (id: number | null, defaultImage?: string | null, height?: number, width?: number) => FetchResult<any>
 }
 
-export const useImageFetch = (lazy: boolean = false): useImageFetchReturnType => {
+/**
+ * Sert d'intermédiaire entre les composants et l'ImageManager en fournissant une méthode useAsyncData toute prête.
+ */
+export const useImageFetch = (): useImageFetchReturnType => {
     const { imageManager } = useImageManager()
 
     const fetch = (
-        id: number | null,  // If id is null, fetch shall return the default value
-        defaultImage: string = '',
+        id: number | null,  // If id is null, fetch shall return the default image url
+        defaultImage: string | null = null,
         height: number = 0,
         width: number = 0
-    ): FetchResult<any> => useFetch(
-        // @ts-ignore
-        async () => {
-            const image: Ref<String> = ref(defaultImage ? `assets/images/byDefault/${defaultImage}` : '')
-
-            if (id !== null) {
-                try {
-                    image.value = await imageManager.get(id, height, width)
-                } catch (e) {
-                    console.error(e)
-                }
-            }
-
-            return image
-        }
+    ): FetchResult<string> => useAsyncData(
+        'img' + (id ?? defaultImage ?? 0),
+        () => imageManager.get(id, defaultImage, height, width),
+        { lazy: true, server: false }  // Always fetch images client-side
     )
 
     return { fetch }

+ 3 - 0
services/data/imageManager.ts

@@ -1,6 +1,9 @@
 import ApiRequestService from "./apiRequestService";
 import ImageUtils from "~/services/utils/imageUtils";
 
+/**
+ * Permet le requêtage, l'upload et la manipulation des images via l'API Opentalent
+ */
 class ImageManager {
     private apiRequestService: ApiRequestService;
     public readonly defaultImage = '/images/default/picture.jpeg'

+ 1 - 1
services/menuBuilder/accountMenuBuilder.ts

@@ -79,7 +79,7 @@ export default class AccountMenuBuilder extends AbstractMenuBuilder {
 
     const icon = {
       avatarId: this.accessProfile.avatarId,
-      avatarByDefault: this.accessProfile.gender == 'MISTER' ? 'men-1.png' : 'women-1.png'
+      avatarByDefault: this.accessProfile.gender == 'MISTER' ? '/images/default/men-1.png' : '/images/default/women-1.png'
     }
 
     return this.createGroup('my_account', icon, children, actions)