useImageViewer.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { ref, unref, watchEffect } from 'vue'
  3. import { canPreviewFile } from '#shared/utils/files.ts'
  4. import type { MaybeRef } from '@vueuse/shared'
  5. interface ImagePreview {
  6. src?: string
  7. title?: string
  8. }
  9. export interface ImageViewerFile {
  10. name?: string
  11. content?: string
  12. preview?: string
  13. inline?: string
  14. type?: Maybe<string>
  15. }
  16. export interface ViewerOptions {
  17. images: ImagePreview[]
  18. index: number
  19. visible: boolean
  20. }
  21. export const imageViewerOptions = ref<ViewerOptions>({
  22. visible: false,
  23. index: 0,
  24. images: [],
  25. })
  26. export const useImageViewer = (viewFiles: MaybeRef<ImageViewerFile[]>) => {
  27. const indexMap = new WeakMap<ImageViewerFile, number>()
  28. let images: ImagePreview[] = []
  29. watchEffect(() => {
  30. images = unref(viewFiles)
  31. .filter((file) => {
  32. const canPreview = canPreviewFile(file.type)
  33. return canPreview && canPreview === 'image'
  34. })
  35. .map((image, index) => {
  36. // we need to keep track of indexes, because they might
  37. // be different from original files, if they had non-image uploads
  38. indexMap.set(image, index)
  39. return {
  40. src: image.inline || image.preview || image.content,
  41. title: image.name,
  42. }
  43. })
  44. })
  45. const showImage = (image: ImageViewerFile) => {
  46. const foundIndex = indexMap.get(image) ?? 0
  47. imageViewerOptions.value = {
  48. index: foundIndex,
  49. images,
  50. visible: true,
  51. }
  52. }
  53. const hideImage = () => {
  54. imageViewerOptions.value = {
  55. images: [],
  56. index: 0,
  57. visible: false,
  58. }
  59. }
  60. const isViewable = (file: ImageViewerFile) => indexMap.has(file)
  61. return {
  62. isViewable,
  63. showImage,
  64. hideImage,
  65. }
  66. }