| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- import type ApiRequestService from './apiRequestService'
- import FileUtils from '~/services/utils/fileUtils'
- import { FILE_TYPE, FILE_VISIBILITY, IMAGE_SIZE } from '~/types/enum/enums'
- import type { AssociativeArray } from '~/types/data'
- import UrlUtils from '~/services/utils/urlUtils'
- /**
- * 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 soit d'une URL, soit d'un blob encodé au format base64.
- *
- * Retourne l'url de l'image par défaut si l'image est introuvable
- * ou si l'id passé en paramètre est null.
- *
- * @param id The id of the image; if null, the url to the default image is returned
- * @param size
- * @param defaultImage The path of an image in the 'public' folder, default: '/images/default/picture.jpeg'
- */
- public get(
- id: number | string | null,
- size: IMAGE_SIZE = IMAGE_SIZE.MD,
- defaultImage: string | null = null,
- ): Promise<string> {
- const defaultUrl = defaultImage ?? ImageManager.defaultImage
- if (id === null) {
- return Promise.resolve(defaultUrl)
- }
- const matches = id.toString().match(/\/api\/files\/(\d+)(?:\/\w+)?/)
- if (matches) {
- // Lors de l'enregistrement d'une entité, les ids des objets liés sont
- // temporairement convertis en IRI. Avec la réactivité, ceci peut
- // générer une erreur temporaire avec les liens des images, d'où ce patch.
- id = parseInt(matches[1])
- }
- if (!(typeof id === 'number' && Number.isInteger(id))) {
- throw new TypeError('Error: image ' + id + ' is invalid')
- }
- try {
- return size === IMAGE_SIZE.RAW
- ? this.getRaw(id)
- : this.getProcessed(id, size)
- } catch (error) {
- console.error(error)
- return Promise.resolve(defaultUrl)
- }
- }
- /**
- * Retourne une image dimensionnée et cropped depuis le cache Liip.
- *
- * @param id The id of the image; if null, the url to the default image is returned
- * @param size
- */
- private async getProcessed(
- id: number | null,
- size: IMAGE_SIZE = IMAGE_SIZE.MD,
- ): Promise<string> {
- const imageUrl = `api/image/download/${id}/${size}`
- // Une image doit toujours avoir le time en options pour éviter les problèmes de cache
- const query: AssociativeArray = { 0: this.getCacheKey() }
- const response = await this.apiRequestService.get(imageUrl, query)
- const cachedImageUrl = response.toString()
- if (!cachedImageUrl) {
- throw new Error('Error: image ' + id + ' not found')
- }
- return UrlUtils.addQuery(cachedImageUrl, query)
- }
- /**
- * Retourne l'image non traitée. Utilisé entre autres pour le
- * cropper du UiInputImage.
- *
- * @param id
- * @private
- */
- private async getRaw(id: number | null): Promise<string> {
- const imageUrl = `api/file/download/${id}`
- // Une image doit toujours avoir le time en options pour éviter les problèmes de cache
- const query = [this.getCacheKey()]
- const blobPart = await this.apiRequestService.get(imageUrl, query)
- if (!blobPart) {
- throw new Error('Error: image ' + id + ' not found')
- }
- if (!(blobPart instanceof Blob) || blobPart.size === 0) {
- throw new Error('Error: image ' + id + ' is invalid')
- }
- 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 = FileUtils.newBlob(data)
- return (await FileUtils.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
|