imageManager.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import ApiRequestService from './apiRequestService'
  2. import ImageUtils from '~/services/utils/imageUtils'
  3. import { FILE_TYPE, FILE_VISIBILITY } from '~/types/enum/enums'
  4. /**
  5. * Permet le requêtage, l'upload et la manipulation des images via l'API Opentalent
  6. */
  7. class ImageManager {
  8. private apiRequestService: ApiRequestService
  9. public static readonly defaultImage = '/images/default/picture.jpeg'
  10. public constructor(apiRequestService: ApiRequestService) {
  11. this.apiRequestService = apiRequestService
  12. }
  13. /**
  14. * Retourne l'image correspondante sous forme d'un blob encodé au format base64,
  15. * ou l'url d'une image par défaut si l'image est introuvable ou si l'id passé en paramètre est null
  16. *
  17. * Attention, les dimensions (hauteur / largeur) ne s'appliqueront pas à l'image par défaut, il est nécessaire de
  18. * les redéfinir dans le composant lui-même.
  19. *
  20. * @param id The id of the image; if null, the url to the default image is returned
  21. * @param defaultImage The path of an image in the 'public' folder, default: '/images/default/picture.jpeg'
  22. * @param height Height of the image (does not apply to default image)
  23. * @param width Width of the image (does not apply to default image)
  24. */
  25. public async get(
  26. id: number | null,
  27. defaultImage: string | null = null,
  28. height: number = 0,
  29. width: number = 0,
  30. ): Promise<string | ArrayBuffer> {
  31. const defaultUrl = defaultImage ?? ImageManager.defaultImage
  32. if (id === null) {
  33. return defaultUrl
  34. }
  35. const imageUrl = `api/download/${id}`
  36. // Set requested size if needed
  37. if (height > 0 || width > 0) {
  38. // @see https://thumbor.readthedocs.io/en/latest/crop_and_resize_algorithms.html
  39. // TODO: ajouter le support de ces options dans ap2i
  40. // url = UrlUtils.join(url, `${height}x${width}`)
  41. }
  42. // Une image doit toujours avoir le time en options pour éviter les problèmes de cache
  43. const query = [this.getCacheKey()]
  44. const response: Response = await this.apiRequestService.get(imageUrl, query)
  45. const blobPart = await response.blob()
  46. if (!response || blobPart.size === 0) {
  47. console.error('Error: image ' + id + ' not found or invalid')
  48. return defaultUrl
  49. }
  50. return await this.toBase64(blobPart)
  51. }
  52. public async upload(
  53. filename: string,
  54. content: string,
  55. visibility: string = FILE_VISIBILITY.NOBODY,
  56. config: string | null = null,
  57. ) {
  58. content = content.replace(/^data:image\/[\w/]+;base64,/, '')
  59. const data = JSON.stringify({
  60. filename,
  61. content,
  62. type: FILE_TYPE.UPLOADED,
  63. visibility,
  64. config,
  65. })
  66. return await this.apiRequestService.post('api/upload', data)
  67. }
  68. /**
  69. * Convert the API response into base64
  70. * @param data
  71. * @protected
  72. */
  73. protected async toBase64(data: BlobPart) {
  74. const blob = ImageUtils.newBlob(data)
  75. return (await ImageUtils.blobToBase64(blob)) ?? ''
  76. }
  77. /**
  78. * On passe cette clé en paramètres des requêtes pour éviter les problèmes de cache
  79. *
  80. * @protected
  81. */
  82. protected getCacheKey() {
  83. return new Date().getTime().toString()
  84. }
  85. }
  86. export default ImageManager