import ApiRequestService from './apiRequestService' import ImageUtils from '~/services/utils/imageUtils' import { FILE_TYPE, FILE_VISIBILITY } from '~/types/enum/enums' /** * Permet le requêtage, l'upload et la manipulation des images via l'API Opentalent */ class ImageManager { private apiRequestService: ApiRequestService public static readonly defaultImage = '/images/default/picture.jpeg' public constructor(apiRequestService: ApiRequestService) { this.apiRequestService = apiRequestService } /** * 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 = null, height: number = 0, width: number = 0, ): Promise { const defaultUrl = defaultImage ?? ImageManager.defaultImage if (id === null) { return defaultUrl } const imageUrl = `api/download/${id}` // Set requested size if needed if (height > 0 || width > 0) { // @see https://thumbor.readthedocs.io/en/latest/crop_and_resize_algorithms.html // TODO: ajouter le support de ces options dans ap2i // url = UrlUtils.join(url, `${height}x${width}`) } // Une image doit toujours avoir le time en options pour éviter les problèmes de cache const query = [this.getCacheKey()] const response: Response = await this.apiRequestService.get(imageUrl, query) if (!response) { console.error('Error: image ' + id + ' not found') return defaultUrl } const blobPart = await response.blob() if (blobPart.size === 0) { console.error('Error: image ' + id + ' is invalid') return defaultUrl } return await this.toBase64(blobPart) } public async upload( filename: string, content: string, visibility: string = FILE_VISIBILITY.NOBODY, config: string | null = null, ) { content = content.replace(/^data:image\/[\w/]+;base64,/, '') const data = JSON.stringify({ filename, content, type: FILE_TYPE.UPLOADED, visibility, config, }) return await this.apiRequestService.post('api/upload', data) } /** * Convert the API response into base64 * @param data * @protected */ protected async toBase64(data: BlobPart) { const blob = ImageUtils.newBlob(data) return (await ImageUtils.blobToBase64(blob)) ?? '' } /** * On passe cette clé en paramètres des requêtes pour éviter les problèmes de cache * * @protected */ protected getCacheKey() { return new Date().getTime().toString() } } export default ImageManager