imageManager.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import ApiRequestService from './apiRequestService'
  2. import FileUtils from '~/services/utils/fileUtils'
  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/file/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 blobPart = await this.apiRequestService.get(imageUrl, query);
  45. if (!blobPart) {
  46. console.error('Error: image ' + id + ' not found');
  47. return defaultUrl;
  48. }
  49. if (!(blobPart instanceof Blob) || blobPart.size === 0) {
  50. console.error('Error: image ' + id + ' is invalid');
  51. return defaultUrl;
  52. }
  53. return await this.toBase64(blobPart)
  54. }
  55. public async upload(
  56. filename: string,
  57. content: string,
  58. visibility: string = FILE_VISIBILITY.NOBODY,
  59. config: string | null = null,
  60. ) {
  61. content = content.replace(/^data:image\/[\w/]+;base64,/, '')
  62. const data = JSON.stringify({
  63. filename,
  64. content,
  65. type: FILE_TYPE.UPLOADED,
  66. visibility,
  67. config,
  68. })
  69. return await this.apiRequestService.post('api/upload', data)
  70. }
  71. /**
  72. * Convert the API response into base64
  73. * @param data
  74. * @protected
  75. */
  76. protected async toBase64(data: BlobPart) {
  77. const blob = FileUtils.newBlob(data)
  78. return (await FileUtils.blobToBase64(blob)) ?? ''
  79. }
  80. /**
  81. * On passe cette clé en paramètres des requêtes pour éviter les problèmes de cache
  82. *
  83. * @protected
  84. */
  85. protected getCacheKey() {
  86. return new Date().getTime().toString()
  87. }
  88. }
  89. export default ImageManager