@acorex/components 21.0.3-next.39 → 21.0.3-next.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/{conversation2 → conversation}/README.md +23 -23
  2. package/fesm2022/acorex-components-button.mjs +4 -4
  3. package/fesm2022/acorex-components-button.mjs.map +1 -1
  4. package/fesm2022/acorex-components-conversation-acorex-components-conversation-YhVa42TC.mjs +13711 -0
  5. package/fesm2022/acorex-components-conversation-acorex-components-conversation-YhVa42TC.mjs.map +1 -0
  6. package/fesm2022/acorex-components-conversation-audio-attachment.component-CLvS3W8F.mjs +119 -0
  7. package/fesm2022/acorex-components-conversation-audio-attachment.component-CLvS3W8F.mjs.map +1 -0
  8. package/fesm2022/acorex-components-conversation-audio-composer.payload-BHQJNyXz.mjs +59 -0
  9. package/fesm2022/acorex-components-conversation-audio-composer.payload-BHQJNyXz.mjs.map +1 -0
  10. package/fesm2022/acorex-components-conversation-audio-picker.component-BD_fN2Ip.mjs +432 -0
  11. package/fesm2022/acorex-components-conversation-audio-picker.component-BD_fN2Ip.mjs.map +1 -0
  12. package/fesm2022/acorex-components-conversation-audio-renderer.component-CcxVVprx.mjs +177 -0
  13. package/fesm2022/acorex-components-conversation-audio-renderer.component-CcxVVprx.mjs.map +1 -0
  14. package/fesm2022/acorex-components-conversation-audio.payload-Bag4aTut.mjs +54 -0
  15. package/fesm2022/acorex-components-conversation-audio.payload-Bag4aTut.mjs.map +1 -0
  16. package/fesm2022/acorex-components-conversation-composer-action-choice-dialog.component-C28hl7iD.mjs +101 -0
  17. package/fesm2022/acorex-components-conversation-composer-action-choice-dialog.component-C28hl7iD.mjs.map +1 -0
  18. package/fesm2022/acorex-components-conversation-conversation-audio.file-type-CfGSVnMA.mjs +100 -0
  19. package/fesm2022/acorex-components-conversation-conversation-audio.file-type-CfGSVnMA.mjs.map +1 -0
  20. package/fesm2022/acorex-components-conversation-conversation-file.file-type-DB-2xhaC.mjs +121 -0
  21. package/fesm2022/acorex-components-conversation-conversation-file.file-type-DB-2xhaC.mjs.map +1 -0
  22. package/fesm2022/acorex-components-conversation-conversation-image.file-type-C02OzZZB.mjs +84 -0
  23. package/fesm2022/acorex-components-conversation-conversation-image.file-type-C02OzZZB.mjs.map +1 -0
  24. package/fesm2022/acorex-components-conversation-conversation-info-media-view.component-Mhk7JE6K.mjs +238 -0
  25. package/fesm2022/acorex-components-conversation-conversation-info-media-view.component-Mhk7JE6K.mjs.map +1 -0
  26. package/fesm2022/acorex-components-conversation-conversation-info-panel.component-CNaM5ajR.mjs +1080 -0
  27. package/fesm2022/acorex-components-conversation-conversation-info-panel.component-CNaM5ajR.mjs.map +1 -0
  28. package/fesm2022/acorex-components-conversation-conversation-video.file-type-Pescv4Vu.mjs +102 -0
  29. package/fesm2022/acorex-components-conversation-conversation-video.file-type-Pescv4Vu.mjs.map +1 -0
  30. package/fesm2022/acorex-components-conversation-conversation-voice.file-type-DDd47o4r.mjs +90 -0
  31. package/fesm2022/acorex-components-conversation-conversation-voice.file-type-DDd47o4r.mjs.map +1 -0
  32. package/fesm2022/acorex-components-conversation-emoji-categories-C7Gm95V0.mjs +1840 -0
  33. package/fesm2022/acorex-components-conversation-emoji-categories-C7Gm95V0.mjs.map +1 -0
  34. package/fesm2022/acorex-components-conversation-fallback-renderer.component-CYh_6O6j.mjs +44 -0
  35. package/fesm2022/acorex-components-conversation-fallback-renderer.component-CYh_6O6j.mjs.map +1 -0
  36. package/fesm2022/acorex-components-conversation-file-composer.payload-Dy7aG-EH.mjs +64 -0
  37. package/fesm2022/acorex-components-conversation-file-composer.payload-Dy7aG-EH.mjs.map +1 -0
  38. package/fesm2022/acorex-components-conversation-file-picker.component-DCVgl33l.mjs +468 -0
  39. package/fesm2022/acorex-components-conversation-file-picker.component-DCVgl33l.mjs.map +1 -0
  40. package/fesm2022/acorex-components-conversation-file-renderer.component-DgCi06Mg.mjs +125 -0
  41. package/fesm2022/acorex-components-conversation-file-renderer.component-DgCi06Mg.mjs.map +1 -0
  42. package/fesm2022/acorex-components-conversation-file.payload-DyFxTQYn.mjs +50 -0
  43. package/fesm2022/acorex-components-conversation-file.payload-DyFxTQYn.mjs.map +1 -0
  44. package/fesm2022/acorex-components-conversation-format-media-DUD4vA6F.mjs +21 -0
  45. package/fesm2022/acorex-components-conversation-format-media-DUD4vA6F.mjs.map +1 -0
  46. package/fesm2022/acorex-components-conversation-image-attachment.component-CLMGxXPl.mjs +77 -0
  47. package/fesm2022/acorex-components-conversation-image-attachment.component-CLMGxXPl.mjs.map +1 -0
  48. package/fesm2022/acorex-components-conversation-image-picker.component-CS343UDa.mjs +407 -0
  49. package/fesm2022/acorex-components-conversation-image-picker.component-CS343UDa.mjs.map +1 -0
  50. package/fesm2022/acorex-components-conversation-image-renderer.component-Cy0TA6cL.mjs +83 -0
  51. package/fesm2022/acorex-components-conversation-image-renderer.component-Cy0TA6cL.mjs.map +1 -0
  52. package/fesm2022/acorex-components-conversation-index-3V2b14I0.mjs +184 -0
  53. package/fesm2022/acorex-components-conversation-index-3V2b14I0.mjs.map +1 -0
  54. package/fesm2022/acorex-components-conversation-index-MCvfr9Zd.mjs +266 -0
  55. package/fesm2022/acorex-components-conversation-index-MCvfr9Zd.mjs.map +1 -0
  56. package/fesm2022/acorex-components-conversation-location-picker.component-DcNQzuoU.mjs +149 -0
  57. package/fesm2022/acorex-components-conversation-location-picker.component-DcNQzuoU.mjs.map +1 -0
  58. package/fesm2022/acorex-components-conversation-location-renderer.component-Cw2PB0LM.mjs +118 -0
  59. package/fesm2022/acorex-components-conversation-location-renderer.component-Cw2PB0LM.mjs.map +1 -0
  60. package/fesm2022/acorex-components-conversation-media-formatters-DV3wEEno.mjs +17 -0
  61. package/fesm2022/acorex-components-conversation-media-formatters-DV3wEEno.mjs.map +1 -0
  62. package/fesm2022/acorex-components-conversation-media-playback-info-bar-banner.component-DbWUl6M2.mjs +140 -0
  63. package/fesm2022/acorex-components-conversation-media-playback-info-bar-banner.component-DbWUl6M2.mjs.map +1 -0
  64. package/fesm2022/acorex-components-conversation-message-renderer-copy-host.component-oXTr_Lfq.mjs +33 -0
  65. package/fesm2022/acorex-components-conversation-message-renderer-copy-host.component-oXTr_Lfq.mjs.map +1 -0
  66. package/fesm2022/acorex-components-conversation-message-renderer-state.component-Dp-JdHWr.mjs +172 -0
  67. package/fesm2022/acorex-components-conversation-message-renderer-state.component-Dp-JdHWr.mjs.map +1 -0
  68. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-Du8Lj9Sp.mjs +224 -0
  69. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-Du8Lj9Sp.mjs.map +1 -0
  70. package/fesm2022/acorex-components-conversation-pagination-demo-data-oIT_YJmN.mjs +81 -0
  71. package/fesm2022/acorex-components-conversation-pagination-demo-data-oIT_YJmN.mjs.map +1 -0
  72. package/fesm2022/acorex-components-conversation-picker-header.component-BneIFjXq.mjs +91 -0
  73. package/fesm2022/acorex-components-conversation-picker-header.component-BneIFjXq.mjs.map +1 -0
  74. package/fesm2022/acorex-components-conversation-picker-toolbar.component-BthRvEeE.mjs +537 -0
  75. package/fesm2022/acorex-components-conversation-picker-toolbar.component-BthRvEeE.mjs.map +1 -0
  76. package/fesm2022/acorex-components-conversation-picker-upload-C-PlKPaU.mjs +163 -0
  77. package/fesm2022/acorex-components-conversation-picker-upload-C-PlKPaU.mjs.map +1 -0
  78. package/fesm2022/acorex-components-conversation-playback-banner-sync-D8FFKde6.mjs +68 -0
  79. package/fesm2022/acorex-components-conversation-playback-banner-sync-D8FFKde6.mjs.map +1 -0
  80. package/fesm2022/acorex-components-conversation-renderer-shared.styles-Digah3Zn.mjs +95 -0
  81. package/fesm2022/acorex-components-conversation-renderer-shared.styles-Digah3Zn.mjs.map +1 -0
  82. package/fesm2022/acorex-components-conversation-search.component-B-nc6xiA.mjs +187 -0
  83. package/fesm2022/acorex-components-conversation-search.component-B-nc6xiA.mjs.map +1 -0
  84. package/fesm2022/acorex-components-conversation-send-message-media-BRklgfV7.mjs +170 -0
  85. package/fesm2022/acorex-components-conversation-send-message-media-BRklgfV7.mjs.map +1 -0
  86. package/fesm2022/acorex-components-conversation-shared-storage.seed-J9PA4l3c.mjs +750 -0
  87. package/fesm2022/acorex-components-conversation-shared-storage.seed-J9PA4l3c.mjs.map +1 -0
  88. package/fesm2022/acorex-components-conversation-sticker-renderer.component-BmBwy7Ig.mjs +103 -0
  89. package/fesm2022/acorex-components-conversation-sticker-renderer.component-BmBwy7Ig.mjs.map +1 -0
  90. package/fesm2022/acorex-components-conversation-system-renderer.component-uie3tm5N.mjs +55 -0
  91. package/fesm2022/acorex-components-conversation-system-renderer.component-uie3tm5N.mjs.map +1 -0
  92. package/fesm2022/acorex-components-conversation-text-renderer.component-DNAquHYK.mjs +109 -0
  93. package/fesm2022/acorex-components-conversation-text-renderer.component-DNAquHYK.mjs.map +1 -0
  94. package/fesm2022/acorex-components-conversation-video-attachment.component-CGaUhnSb.mjs +105 -0
  95. package/fesm2022/acorex-components-conversation-video-attachment.component-CGaUhnSb.mjs.map +1 -0
  96. package/fesm2022/acorex-components-conversation-video-composer.payload-DMqRkafr.mjs +62 -0
  97. package/fesm2022/acorex-components-conversation-video-composer.payload-DMqRkafr.mjs.map +1 -0
  98. package/fesm2022/acorex-components-conversation-video-picker.component-DPwSBnoH.mjs +446 -0
  99. package/fesm2022/acorex-components-conversation-video-picker.component-DPwSBnoH.mjs.map +1 -0
  100. package/fesm2022/acorex-components-conversation-video-renderer.component-DKa9mUe2.mjs +181 -0
  101. package/fesm2022/acorex-components-conversation-video-renderer.component-DKa9mUe2.mjs.map +1 -0
  102. package/fesm2022/acorex-components-conversation-video.payload-C8QaqxuX.mjs +54 -0
  103. package/fesm2022/acorex-components-conversation-video.payload-C8QaqxuX.mjs.map +1 -0
  104. package/fesm2022/acorex-components-conversation-voice-composer.payload-DLVow7ex.mjs +17 -0
  105. package/fesm2022/acorex-components-conversation-voice-composer.payload-DLVow7ex.mjs.map +1 -0
  106. package/fesm2022/acorex-components-conversation-voice-recorder.component-D_rdANZN.mjs +344 -0
  107. package/fesm2022/acorex-components-conversation-voice-recorder.component-D_rdANZN.mjs.map +1 -0
  108. package/fesm2022/acorex-components-conversation-voice-renderer.component-BY5FJcT8.mjs +270 -0
  109. package/fesm2022/acorex-components-conversation-voice-renderer.component-BY5FJcT8.mjs.map +1 -0
  110. package/fesm2022/acorex-components-conversation.mjs +2 -0
  111. package/fesm2022/acorex-components-conversation.mjs.map +1 -0
  112. package/fesm2022/acorex-components-kbd.mjs +2 -2
  113. package/fesm2022/acorex-components-kbd.mjs.map +1 -1
  114. package/fesm2022/acorex-components-scheduler-picker.mjs +22 -14
  115. package/fesm2022/acorex-components-scheduler-picker.mjs.map +1 -1
  116. package/fesm2022/acorex-components-side-menu.mjs +4 -13
  117. package/fesm2022/acorex-components-side-menu.mjs.map +1 -1
  118. package/fesm2022/acorex-components-tree-view.mjs +2 -2
  119. package/fesm2022/acorex-components-tree-view.mjs.map +1 -1
  120. package/package.json +6 -10
  121. package/types/{acorex-components-conversation2.d.ts → acorex-components-conversation.d.ts} +1127 -1928
  122. package/types/acorex-components-scheduler-picker.d.ts +2 -0
  123. package/types/acorex-components-side-menu.d.ts +1 -3
  124. package/fesm2022/acorex-components-conversation2.mjs +0 -22347
  125. package/fesm2022/acorex-components-conversation2.mjs.map +0 -1
  126. package/fesm2022/acorex-components-sidebar.mjs +0 -275
  127. package/fesm2022/acorex-components-sidebar.mjs.map +0 -1
  128. package/sidebar/README.md +0 -5
  129. package/types/acorex-components-sidebar.d.ts +0 -132
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-components-conversation-file-picker.component-DCVgl33l.mjs","sources":["../../../../packages/components/conversation/src/lib/plugins/composer/components/file-picker/file-picker.component.ts"],"sourcesContent":["/**\n * File Picker Component\n * General-purpose file attachment interface for the composer\n */\n\nimport { AXUploaderService } from '@acorex/cdk/uploader';\nimport { AXProgressBarModule } from '@acorex/components/progress-bar';\nimport type { AXPopupRef } from '@acorex/components/popup';\nimport { AXToastService } from '@acorex/components/toast';\nimport { AXFileService, AXFileTypeRegistryService, runFileTypeUtility, runFileTypeUtilityForFile, type AXFileType } from '@acorex/core/file';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport { CommonModule } from '@angular/common';\nimport { Component, OnDestroy, PLATFORM_ID, computed, inject, input, signal } from '@angular/core';\nimport { AXConversationComposerService } from '../../../../components/composer/composer.service';\nimport { AXConversation, AXConversationSendMessageCommand } from '../../../../models';\nimport { AXConversationPickerFooterComponent } from '../picker-footer/picker-footer.component';\nimport { AXConversationPickerHeaderComponent } from '../picker-header/picker-header.component';\nimport { AXConversationPickerCaptionComponent } from '../shared/picker-caption.component';\nimport { AXConversationPickerEmptyComponent } from '../shared/picker-empty.component';\nimport { AX_CONVERSATION_PICKER_SHARED_STYLES } from '../shared/picker-shared.styles';\nimport { AXConversationPickerShellComponent } from '../shared/picker-shell.component';\nimport { AXConversationPickerToolbarComponent } from '../shared/picker-toolbar.component';\nimport {\n cleanupPickerUploads,\n dismissComposerPickerHost,\n getPickerCancelUploadLabel,\n isUploadAborted,\n seedPickerInitialFiles,\n limitFilesToCapacity,\n notifyMaxFilesCapacityExceeded,\n notifyPickerValidationErrors,\n pickerItemToUploadResult,\n uploadPickerFile,\n} from '../shared/picker-upload';\nimport { fileItemFromUpload } from './file-composer.payload';\nimport { AX_CONVERSATION_FILE_CATALOG, AX_CONVERSATION_FILE_PRESENTATION, createConversationFileFileType } from './index';\n\ninterface AXConversationAttachedFile {\n file: File;\n preview?: string;\n icon: string;\n type: 'image' | 'video' | 'audio' | 'file';\n uploadProgress?: number;\n uploading?: boolean;\n uploaded?: boolean;\n uploadedUrl?: string;\n mediaId?: string;\n error?: string;\n abortController?: AbortController;\n}\n\n@Component({\n selector: 'ax-conversation-file-picker',\n imports: [\n CommonModule,\n AXProgressBarModule,\n AXTranslationModule,\n AXConversationPickerHeaderComponent,\n AXConversationPickerFooterComponent,\n AXConversationPickerEmptyComponent,\n AXConversationPickerToolbarComponent,\n AXConversationPickerCaptionComponent,\n AXConversationPickerShellComponent,\n ],\n template: `\n <ax-conversation-picker-shell\n [fileType]=\"catalogFileType\"\n [multiple]=\"allowMultiple()\"\n (filesSelected)=\"handleFiles($event)\"\n (dragEnter)=\"isDragging.set(true)\"\n (dragLeave)=\"isDragging.set(false)\"\n >\n <ax-conversation-picker-header [title]=\"translation.translateSync('@acorex:chat.pickers.files.title')\" (onClose)=\"cancel()\" />\n\n <div class=\"ax-conversation-picker__scroll\">\n @if (files().length === 0) {\n <ax-conversation-picker-empty\n [title]=\"getEmptyTitle()\"\n [hint]=\"getEmptySubtitle()\"\n [iconClass]=\"emptyIconClass()\"\n [dragOver]=\"isDragging()\"\n />\n } @else {\n <div class=\"ax-conversation-picker__body\">\n <ax-conversation-picker-toolbar\n [countLabel]=\"getSelectedCountText()\"\n [addMoreLabel]=\"translation.translateSync('@acorex:chat.pickers.common.add-more')\"\n />\n\n <div class=\"ax-conversation-picker__list\">\n @for (file of files(); track $index) {\n <div class=\"ax-conversation-picker__row\">\n <div class=\"ax-conversation-picker__thumb\">\n @if (file.type === 'image' && file.preview) {\n <img [src]=\"file.preview\" [alt]=\"file.file.name\" />\n } @else {\n <i [class]=\"file.icon\"></i>\n }\n </div>\n <div class=\"ax-conversation-picker__details\">\n <div class=\"ax-conversation-picker__name\">{{ file.file.name }}</div>\n <div class=\"ax-conversation-picker__status\">\n @if (file.uploading) {\n <span>{{ getUploadingLabel(file.uploadProgress ?? 0) }}</span>\n } @else if (file.uploaded) {\n <span class=\"ax-conversation-picker__status--ok\"\n ><i class=\"fa-light fa-check\"></i>\n {{ translation.translateSync('@acorex:chat.pickers.files.uploaded') }}</span\n >\n } @else if (file.error) {\n <span class=\"ax-conversation-picker__status--err\"\n ><i class=\"fa-light fa-xmark\"></i> {{ file.error }}</span\n >\n } @else {\n <span>{{ formatFileSize(file.file.size) }}</span>\n }\n </div>\n @if (file.uploading || file.uploaded) {\n <div class=\"ax-conversation-picker__progress\">\n <ax-progress-bar [progress]=\"file.uploadProgress || 0\" [mode]=\"'determinate'\" [height]=\"3\" />\n </div>\n }\n </div>\n <button\n type=\"button\"\n class=\"ax-conversation-picker__remove\"\n (click)=\"removeFile($index)\"\n [attr.aria-label]=\"\n file.uploading\n ? getCancelUploadLabel()\n : translation.translateSync('@acorex:chat.pickers.common.remove')\n \"\n >\n <i class=\"fa-light fa-xmark\"></i>\n </button>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <ax-conversation-picker-caption [(caption)]=\"caption\" />\n\n @if (files().length > 0) {\n <ax-conversation-picker-footer\n [sendText]=\"getSendButtonText()\"\n [sendDisabled]=\"!canSend()\"\n (onCancel)=\"cancel()\"\n (onSend)=\"sendFiles()\"\n />\n }\n </ax-conversation-picker-shell>\n `,\n styles: [AX_CONVERSATION_PICKER_SHARED_STYLES],\n})\nexport class AXConversationFilePickerComponent implements OnDestroy {\n private uploadsDismissed = false;\n private retainUploadedOnDismiss = false;\n private readonly uploader = inject(AXUploaderService);\n private readonly fileService = inject(AXFileService);\n private readonly fileTypeRegistry = inject(AXFileTypeRegistryService);\n private readonly platformId = inject(PLATFORM_ID);\n readonly service = input<AXConversationComposerService | undefined>();\n private readonly composerServiceFromInjector = inject(AXConversationComposerService, { optional: true });\n\n private get composerService(): AXConversationComposerService {\n const svc = this.service() ?? this.composerServiceFromInjector;\n if (!svc) {\n throw new Error('AXConversationComposerService is required for the file picker');\n }\n return svc;\n }\n private readonly toast = inject(AXToastService);\n readonly translation = inject(AXTranslationService);\n\n readonly conversation = input.required<AXConversation>();\n readonly maxFiles = input<number>(10);\n readonly initialFiles = input<File[]>([]);\n readonly __popup__ = input<AXPopupRef | undefined>();\n\n readonly catalogFileType = AX_CONVERSATION_FILE_CATALOG;\n\n readonly allowMultiple = computed(() => this.maxFiles() > 1);\n\n readonly files = signal<AXConversationAttachedFile[]>([]);\n readonly isDragging = signal(false);\n readonly isUploading = signal(false);\n readonly emptyIconClass = computed(() =>\n this.isDragging() ? 'fa-light fa-cloud-arrow-up' : AX_CONVERSATION_FILE_PRESENTATION.icon,\n );\n\n private catalogFileTypeDef?: AXFileType;\n caption = '';\n\n constructor() {\n this.fileTypeRegistry.registerTypes([createConversationFileFileType()]);\n seedPickerInitialFiles(this.initialFiles, (files) => this.handleFiles(files));\n }\n\n private createUtilityContext() {\n return {\n readAsDataUrl: (file: File | Blob) => this.fileService.blobToBase64(file),\n platformId: this.platformId,\n };\n }\n\n private async getCatalogFileTypeDef(): Promise<AXFileType | undefined> {\n this.catalogFileTypeDef ??= await this.fileService.getFileType(this.catalogFileType);\n return this.catalogFileTypeDef;\n }\n\n private pickerKind(catalogName: string): AXConversationAttachedFile['type'] {\n if (catalogName === 'conversation-image') return 'image';\n if (catalogName === 'conversation-video') return 'video';\n if (catalogName === 'conversation-audio') return 'audio';\n return 'file';\n }\n\n async handleFiles(fileList: File[]): Promise<void> {\n const max = this.maxFiles();\n const capacity = limitFilesToCapacity(fileList, this.files().length, max);\n if (capacity.length < fileList.length) {\n notifyMaxFilesCapacityExceeded(this.toast, this.translation, max);\n }\n if (capacity.length === 0) {\n return;\n }\n\n const { accepted, rejected } = await this.uploader.validateFiles(capacity, this.catalogFileType);\n\n notifyPickerValidationErrors(this.toast, this.translation, rejected);\n\n const fileType = await this.getCatalogFileTypeDef();\n const ctx = this.createUtilityContext();\n\n for (const file of accepted) {\n try {\n const previewResult = fileType\n ? await runFileTypeUtilityForFile(fileType, ctx, file, 'preview')\n : undefined;\n const rowCatalogResult = fileType\n ? await runFileTypeUtilityForFile(fileType, ctx, file, 'pickerCatalog')\n : undefined;\n const preview = typeof previewResult === 'string' ? previewResult : undefined;\n const rowCatalog = typeof rowCatalogResult === 'string' ? rowCatalogResult : this.catalogFileType;\n const rowType = await this.fileService.getFileType(rowCatalog);\n const icon = rowType?.icon ?? fileType?.icon ?? 'fa-light fa-file';\n const pickerKind = this.pickerKind(rowCatalog);\n\n let fileIndex = -1;\n this.files.update((files) => {\n fileIndex = files.length;\n return [...files, { file, preview, icon, type: pickerKind, uploadProgress: 0, uploading: true }];\n });\n\n if (fileIndex >= 0) {\n void this.uploadFile(fileIndex, file);\n }\n } catch (error) {\n console.error('Failed to process file:', error);\n }\n }\n }\n\n private async uploadFile(index: number, file: File): Promise<void> {\n const abortController = new AbortController();\n this.files.update((files) => {\n const updated = [...files];\n updated[index] = { ...updated[index], abortController };\n return updated;\n });\n\n try {\n const result = await this.uploadFileWithProgress(\n file,\n (progress) => {\n this.updateFileProgress(index, progress, true);\n },\n abortController.signal,\n );\n\n this.updateFileProgress(index, 100, false, true, result.url, result.mediaId);\n } catch (error) {\n if (this.uploadsDismissed || isUploadAborted(error, abortController.signal)) {\n return;\n }\n console.error('Failed to upload file:', error);\n this.updateFileProgress(\n index,\n 0,\n false,\n false,\n undefined,\n undefined,\n this.translation.translateSync('@acorex:chat.errors.upload-failed'),\n );\n }\n }\n\n removeFile(index: number): void {\n const item = this.files()[index];\n if (item) {\n cleanupPickerUploads(this.uploader, [item]);\n }\n this.files.update((files) => files.filter((_, i) => i !== index));\n }\n\n async sendFiles(): Promise<void> {\n const fileList = this.files();\n if (fileList.length === 0) return;\n\n // Check if all files are uploaded\n const allUploaded = fileList.every((f) => f.uploaded && !f.error);\n if (!allUploaded) {\n console.warn('Some files are still uploading or failed');\n return;\n }\n\n const files = fileList.flatMap((f) => {\n const result = pickerItemToUploadResult(f);\n return result ? [fileItemFromUpload(f.file, result)] : [];\n });\n\n if (files.length === 0) {\n return;\n }\n\n const command: AXConversationSendMessageCommand = {\n conversationId: this.conversation().id,\n type: 'file',\n payload: {\n type: 'file',\n files,\n caption: this.caption.trim() || undefined,\n },\n };\n\n this.retainUploadedOnDismiss = true;\n const popup = this.__popup__();\n this.dismissPicker();\n dismissComposerPickerHost(this.composerService, popup);\n\n void this.composerService.sendMessage(command).catch(() => {\n this.retainUploadedOnDismiss = false;\n });\n }\n\n private updateFileProgress(\n index: number,\n progress: number,\n uploading: boolean,\n uploaded = false,\n uploadedUrl?: string,\n mediaId?: string,\n error?: string,\n ): void {\n if (this.uploadsDismissed) {\n return;\n }\n this.files.update((files) => {\n const updated = [...files];\n updated[index] = {\n ...updated[index],\n uploadProgress: progress,\n uploading,\n uploaded,\n uploadedUrl,\n mediaId,\n error,\n };\n return updated;\n });\n }\n\n private async uploadFileWithProgress(\n file: File,\n onProgress: (progress: number) => void,\n signal?: AbortSignal,\n ): Promise<{ url: string; mediaId?: string; thumbnailUrl?: string; size: number; mimeType: string }> {\n return uploadPickerFile(this.uploader, this.conversation().id, file, onProgress, signal);\n }\n\n cancel(): void {\n this.dismissPicker();\n dismissComposerPickerHost(this.composerService, this.__popup__());\n }\n\n ngOnDestroy(): void {\n this.dismissPicker();\n }\n\n private dismissPicker(): void {\n if (this.uploadsDismissed) {\n return;\n }\n this.uploadsDismissed = true;\n const snapshot = [...this.files()];\n cleanupPickerUploads(this.uploader, snapshot, {\n retainUploaded: this.retainUploadedOnDismiss,\n });\n this.retainUploadedOnDismiss = false;\n this.files.set([]);\n this.caption = '';\n }\n\n getCancelUploadLabel(): string {\n return getPickerCancelUploadLabel(this.translation);\n }\n\n formatFileSize(bytes: number): string {\n const fileType = this.catalogFileTypeDef;\n const result = fileType\n ? runFileTypeUtility(fileType, this.createUtilityContext(), undefined, 'formatSize', bytes)\n : undefined;\n return typeof result === 'string' ? result : `${bytes} B`;\n }\n\n canSend(): boolean {\n const fileList = this.files();\n if (fileList.length === 0) return false;\n\n // Can send if all files are uploaded and no errors\n return fileList.every((f) => f.uploaded && !f.error && !f.uploading);\n }\n\n getSendButtonText(): string {\n const fileList = this.files();\n const uploadingCount = fileList.filter((f) => f.uploading).length;\n const uploadedCount = fileList.filter((f) => f.uploaded).length;\n\n if (uploadingCount > 0) {\n return this.translation.translateSync('@acorex:chat.pickers.files.uploading-count', {\n params: { count: uploadingCount },\n });\n }\n\n if (uploadedCount === fileList.length) {\n return this.translation.translateSync('@acorex:chat.pickers.files.send-count', {\n params: { count: fileList.length },\n });\n }\n\n return this.translation.translateSync('@acorex:chat.pickers.files.ready-count', {\n params: { ready: uploadedCount, total: fileList.length },\n });\n }\n\n getEmptyTitle(): string {\n return this.isDragging()\n ? this.translation.translateSync('@acorex:chat.pickers.files.drop-here')\n : this.translation.translateSync('@acorex:chat.pickers.files.select');\n }\n\n getEmptySubtitle(): string {\n return this.isDragging()\n ? this.translation.translateSync('@acorex:chat.pickers.common.release-to-upload')\n : this.translation.translateSync('@acorex:chat.pickers.common.click-to-browse');\n }\n\n getSelectedCountText(): string {\n return this.translation.translateSync('@acorex:chat.pickers.files.selected-count', {\n params: { count: this.files().length },\n });\n }\n\n getUploadingLabel(progress: number): string {\n return this.translation.translateSync('@acorex:chat.pickers.files.uploading-progress', {\n params: { progress },\n });\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ import { AXFileTypeRegistryService } from '@acorex/core/file';
2
+ import { CommonModule } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { input, computed, ChangeDetectionStrategy, Component, inject } from '@angular/core';
5
+ import { normalizeFilePayload } from './acorex-components-conversation-file.payload-DyFxTQYn.mjs';
6
+ import { A as AXConversationMessageRendererCopyHostComponent, m as mediaCopyText } from './acorex-components-conversation-message-renderer-copy-host.component-oXTr_Lfq.mjs';
7
+ import { w as toUploaderReference, x as createResolvedMediaUrlSignal, y as pickDisplayMediaUrl, l as copyWithFileTypeFallback } from './acorex-components-conversation-acorex-components-conversation-YhVa42TC.mjs';
8
+ import { a as formatFileByteSize } from './acorex-components-conversation-format-media-DUD4vA6F.mjs';
9
+ import { A as AXConversationMessageRendererStateComponent } from './acorex-components-conversation-message-renderer-state.component-Dp-JdHWr.mjs';
10
+ import './acorex-components-conversation-renderer-shared.styles-Digah3Zn.mjs';
11
+
12
+ const AX_CONVERSATION_EXT_COLORS = {
13
+ pdf: 'rgb(var(--ax-sys-color-danger-500))',
14
+ doc: 'rgb(var(--ax-sys-color-primary-500))',
15
+ docx: 'rgb(var(--ax-sys-color-primary-500))',
16
+ xls: 'rgb(var(--ax-sys-color-success-500))',
17
+ xlsx: 'rgb(var(--ax-sys-color-success-500))',
18
+ ppt: 'rgb(var(--ax-sys-color-warning-500))',
19
+ pptx: 'rgb(var(--ax-sys-color-warning-500))',
20
+ zip: 'rgb(var(--ax-sys-color-secondary-600))',
21
+ };
22
+ class AXConversationFileAttachmentComponent {
23
+ constructor() {
24
+ this.item = input.required(...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
25
+ this.mediaReference = computed(() => toUploaderReference(this.item()), ...(ngDevMode ? [{ debugName: "mediaReference" }] : /* istanbul ignore next */ []));
26
+ this.resolvedUrl = createResolvedMediaUrlSignal(this.mediaReference);
27
+ this.fileUrl = computed(() => pickDisplayMediaUrl(this.resolvedUrl(), this.item().url), ...(ngDevMode ? [{ debugName: "fileUrl" }] : /* istanbul ignore next */ []));
28
+ this.fileName = computed(() => this.item().name || 'file', ...(ngDevMode ? [{ debugName: "fileName" }] : /* istanbul ignore next */ []));
29
+ this.fileSize = computed(() => this.item().size ?? 0, ...(ngDevMode ? [{ debugName: "fileSize" }] : /* istanbul ignore next */ []));
30
+ this.fileExtension = computed(() => {
31
+ const name = this.fileName();
32
+ const parts = name.split('.');
33
+ return parts.length > 1 ? parts[parts.length - 1] : 'FILE';
34
+ }, ...(ngDevMode ? [{ debugName: "fileExtension" }] : /* istanbul ignore next */ []));
35
+ this.swatchColor = computed(() => {
36
+ const ext = this.fileExtension().toLowerCase();
37
+ return AX_CONVERSATION_EXT_COLORS[ext] ?? 'rgb(var(--ax-sys-color-secondary-500))';
38
+ }, ...(ngDevMode ? [{ debugName: "swatchColor" }] : /* istanbul ignore next */ []));
39
+ this.formattedSize = computed(() => formatFileByteSize(this.fileSize()), ...(ngDevMode ? [{ debugName: "formattedSize" }] : /* istanbul ignore next */ []));
40
+ }
41
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationFileAttachmentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
42
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: AXConversationFileAttachmentComponent, isStandalone: true, selector: "ax-conversation-file-attachment", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
43
+ <a class="ax-conversation-file" [href]="fileUrl()" [download]="fileName()" target="_blank" rel="noopener noreferrer">
44
+ <span class="ax-conversation-file__badge" [style.background]="swatchColor()">{{ fileExtension() }}</span>
45
+ <span class="ax-conversation-file__body">
46
+ <span class="ax-conversation-file__name">{{ fileName() }}</span>
47
+ <span class="ax-conversation-file__meta">{{ formattedSize() }}</span>
48
+ </span>
49
+ <i class="fa-light fa-arrow-down-to-line ax-conversation-file__icon" aria-hidden="true"></i>
50
+ </a>
51
+ `, isInline: true, styles: [":host{display:block}.ax-conversation-file{display:flex;align-items:center;gap:.625rem;width:100%;min-height:2.75rem;padding:.5rem .625rem;border-radius:var(--ax-sys-border-radius, .5rem);border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));text-decoration:none;touch-action:manipulation;transition:border-color .15s ease,background-color .15s ease}@media(hover:hover){.ax-conversation-file:hover{border-color:rgb(var(--ax-sys-color-primary-500));background:rgb(var(--ax-sys-color-light-surface))}}.ax-conversation-file__badge{flex-shrink:0;width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;border-radius:var(--ax-sys-border-radius, .375rem);font-weight:600;font-size:.5625rem;text-transform:uppercase;color:rgb(var(--ax-sys-color-light))}.ax-conversation-file__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.ax-conversation-file__name{font-size:.8125rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ax-conversation-file__meta{font-size:.6875rem;color:rgba(var(--ax-sys-color-on-surface),.65)}.ax-conversation-file__icon{flex-shrink:0;font-size:.875rem;color:rgba(var(--ax-sys-color-on-surface),.55)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
52
+ }
53
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationFileAttachmentComponent, decorators: [{
54
+ type: Component,
55
+ args: [{ selector: 'ax-conversation-file-attachment', imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
56
+ <a class="ax-conversation-file" [href]="fileUrl()" [download]="fileName()" target="_blank" rel="noopener noreferrer">
57
+ <span class="ax-conversation-file__badge" [style.background]="swatchColor()">{{ fileExtension() }}</span>
58
+ <span class="ax-conversation-file__body">
59
+ <span class="ax-conversation-file__name">{{ fileName() }}</span>
60
+ <span class="ax-conversation-file__meta">{{ formattedSize() }}</span>
61
+ </span>
62
+ <i class="fa-light fa-arrow-down-to-line ax-conversation-file__icon" aria-hidden="true"></i>
63
+ </a>
64
+ `, styles: [":host{display:block}.ax-conversation-file{display:flex;align-items:center;gap:.625rem;width:100%;min-height:2.75rem;padding:.5rem .625rem;border-radius:var(--ax-sys-border-radius, .5rem);border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));text-decoration:none;touch-action:manipulation;transition:border-color .15s ease,background-color .15s ease}@media(hover:hover){.ax-conversation-file:hover{border-color:rgb(var(--ax-sys-color-primary-500));background:rgb(var(--ax-sys-color-light-surface))}}.ax-conversation-file__badge{flex-shrink:0;width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;border-radius:var(--ax-sys-border-radius, .375rem);font-weight:600;font-size:.5625rem;text-transform:uppercase;color:rgb(var(--ax-sys-color-light))}.ax-conversation-file__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.ax-conversation-file__name{font-size:.8125rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ax-conversation-file__meta{font-size:.6875rem;color:rgba(var(--ax-sys-color-on-surface),.65)}.ax-conversation-file__icon{flex-shrink:0;font-size:.875rem;color:rgba(var(--ax-sys-color-on-surface),.55)}\n"] }]
65
+ }], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }] } });
66
+
67
+ class AXConversationFileRendererComponent extends AXConversationMessageRendererCopyHostComponent {
68
+ constructor() {
69
+ super(...arguments);
70
+ this.fileTypes = inject(AXFileTypeRegistryService);
71
+ this.message = input.required(...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
72
+ this.rendererState = computed(() => ({
73
+ deliveryStatus: this.message().status,
74
+ contentState: 'ready',
75
+ }), ...(ngDevMode ? [{ debugName: "rendererState" }] : /* istanbul ignore next */ []));
76
+ this.payload = computed(() => normalizeFilePayload(this.message().payload), ...(ngDevMode ? [{ debugName: "payload" }] : /* istanbul ignore next */ []));
77
+ this.files = computed(() => this.payload().files, ...(ngDevMode ? [{ debugName: "files" }] : /* istanbul ignore next */ []));
78
+ this.caption = computed(() => this.payload().caption?.trim() || '', ...(ngDevMode ? [{ debugName: "caption" }] : /* istanbul ignore next */ []));
79
+ }
80
+ copy() {
81
+ return copyWithFileTypeFallback(this.message(), this.fileTypes, () => {
82
+ const p = this.payload();
83
+ if (p.files.length === 1) {
84
+ const file = p.files[0];
85
+ const name = file.name?.trim() || 'File';
86
+ const url = file.url?.trim();
87
+ return url ? `${name}\n${url}` : name;
88
+ }
89
+ return mediaCopyText(p.caption, 'File', 'files', p.files.length, p.files.map((file) => file.name?.trim() || file.url?.trim()));
90
+ });
91
+ }
92
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationFileRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
93
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXConversationFileRendererComponent, isStandalone: true, selector: "ax-conversation-file-renderer", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
94
+ <div class="ax-conversation-msg ax-conversation-msg--wide">
95
+ <ax-conversation-message-renderer-state [rendererState]="rendererState()" [message]="message()" />
96
+ <div class="ax-conversation-msg__stack">
97
+ @for (file of files(); track file.mediaId ?? file.url) {
98
+ <ax-conversation-file-attachment [item]="file" />
99
+ }
100
+ </div>
101
+ @if (caption()) {
102
+ <p class="ax-conversation-msg__caption">{{ caption() }}</p>
103
+ }
104
+ </div>
105
+ `, isInline: true, styles: [":host{display:block;max-width:100%}.ax-conversation-msg,.ax-conversation-msg__stack{display:flex;flex-direction:column;gap:.375rem}.ax-conversation-msg__grid{display:grid;gap:2px;width:100%;border-radius:var(--ax-sys-border-radius, .5rem);overflow:hidden;background:rgb(var(--ax-sys-color-border-light-surface))}.ax-conversation-msg__grid--single{grid-template-columns:1fr}.ax-conversation-msg__grid--single ::ng-deep .ax-conversation-image-attachment{max-height:min(50dvh,20rem)}.ax-conversation-msg__grid--dual{grid-template-columns:repeat(2,1fr)}.ax-conversation-msg__grid--multi{grid-template-columns:repeat(3,1fr);grid-auto-rows:10rem}@container (max-width: 380px){.ax-conversation-msg__grid--multi{grid-template-columns:repeat(2,1fr);grid-auto-rows:10rem}}.ax-conversation-msg__caption{margin:0;padding:0 .125rem;font-size:.8125rem;line-height:1.4;word-break:break-word;opacity:.88}.ax-conversation-msg--flush{width:100%;max-width:100%;gap:0}.ax-conversation-msg--flush .ax-conversation-msg__caption{padding:.375rem .625rem 0}.ax-conversation-msg--flush .ax-conversation-msg__grid{border-radius:0;background:transparent}.ax-conversation-msg--flush .ax-conversation-msg__stack{gap:2px}.ax-conversation-msg--flush ::ng-deep .ax-conversation-video{border-radius:0}.ax-conversation-msg__card{border-radius:var(--ax-sys-border-radius, .5rem);border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-surface));overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXConversationFileAttachmentComponent, selector: "ax-conversation-file-attachment", inputs: ["item"] }, { kind: "component", type: AXConversationMessageRendererStateComponent, selector: "ax-conversation-message-renderer-state", inputs: ["rendererState", "message", "contentErrorLabel", "deliveryFailedLabel", "showContentErrorChrome", "contentErrorStyle", "contentErrorIconClass", "placement", "contentRetryEnabled"], outputs: ["contentRetry"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
106
+ }
107
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationFileRendererComponent, decorators: [{
108
+ type: Component,
109
+ args: [{ selector: 'ax-conversation-file-renderer', imports: [CommonModule, AXConversationFileAttachmentComponent, AXConversationMessageRendererStateComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
110
+ <div class="ax-conversation-msg ax-conversation-msg--wide">
111
+ <ax-conversation-message-renderer-state [rendererState]="rendererState()" [message]="message()" />
112
+ <div class="ax-conversation-msg__stack">
113
+ @for (file of files(); track file.mediaId ?? file.url) {
114
+ <ax-conversation-file-attachment [item]="file" />
115
+ }
116
+ </div>
117
+ @if (caption()) {
118
+ <p class="ax-conversation-msg__caption">{{ caption() }}</p>
119
+ }
120
+ </div>
121
+ `, styles: [":host{display:block;max-width:100%}.ax-conversation-msg,.ax-conversation-msg__stack{display:flex;flex-direction:column;gap:.375rem}.ax-conversation-msg__grid{display:grid;gap:2px;width:100%;border-radius:var(--ax-sys-border-radius, .5rem);overflow:hidden;background:rgb(var(--ax-sys-color-border-light-surface))}.ax-conversation-msg__grid--single{grid-template-columns:1fr}.ax-conversation-msg__grid--single ::ng-deep .ax-conversation-image-attachment{max-height:min(50dvh,20rem)}.ax-conversation-msg__grid--dual{grid-template-columns:repeat(2,1fr)}.ax-conversation-msg__grid--multi{grid-template-columns:repeat(3,1fr);grid-auto-rows:10rem}@container (max-width: 380px){.ax-conversation-msg__grid--multi{grid-template-columns:repeat(2,1fr);grid-auto-rows:10rem}}.ax-conversation-msg__caption{margin:0;padding:0 .125rem;font-size:.8125rem;line-height:1.4;word-break:break-word;opacity:.88}.ax-conversation-msg--flush{width:100%;max-width:100%;gap:0}.ax-conversation-msg--flush .ax-conversation-msg__caption{padding:.375rem .625rem 0}.ax-conversation-msg--flush .ax-conversation-msg__grid{border-radius:0;background:transparent}.ax-conversation-msg--flush .ax-conversation-msg__stack{gap:2px}.ax-conversation-msg--flush ::ng-deep .ax-conversation-video{border-radius:0}.ax-conversation-msg__card{border-radius:var(--ax-sys-border-radius, .5rem);border:1px solid rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-surface));overflow:hidden}\n"] }]
122
+ }], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }] } });
123
+
124
+ export { AXConversationFileRendererComponent };
125
+ //# sourceMappingURL=acorex-components-conversation-file-renderer.component-DgCi06Mg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-components-conversation-file-renderer.component-DgCi06Mg.mjs","sources":["../../../../packages/components/conversation/src/lib/plugins/message-list/components/shared/file-attachment.component.ts","../../../../packages/components/conversation/src/lib/plugins/message-list/components/file-renderer/file-renderer.component.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport type { AXConversationFileMediaItem } from '../../../../models';\nimport { pickDisplayMediaUrl } from '../../../composer/components/shared/persisted-media-url';\nimport { toUploaderReference } from './attachment-uploader-reference';\nimport { formatFileByteSize } from './format-media';\nimport { createResolvedMediaUrlSignal } from './media-url-resolve';\n\nconst AX_CONVERSATION_EXT_COLORS: Record<string, string> = {\n pdf: 'rgb(var(--ax-sys-color-danger-500))',\n doc: 'rgb(var(--ax-sys-color-primary-500))',\n docx: 'rgb(var(--ax-sys-color-primary-500))',\n xls: 'rgb(var(--ax-sys-color-success-500))',\n xlsx: 'rgb(var(--ax-sys-color-success-500))',\n ppt: 'rgb(var(--ax-sys-color-warning-500))',\n pptx: 'rgb(var(--ax-sys-color-warning-500))',\n zip: 'rgb(var(--ax-sys-color-secondary-600))',\n};\n\n@Component({\n selector: 'ax-conversation-file-attachment',\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <a class=\"ax-conversation-file\" [href]=\"fileUrl()\" [download]=\"fileName()\" target=\"_blank\" rel=\"noopener noreferrer\">\n <span class=\"ax-conversation-file__badge\" [style.background]=\"swatchColor()\">{{ fileExtension() }}</span>\n <span class=\"ax-conversation-file__body\">\n <span class=\"ax-conversation-file__name\">{{ fileName() }}</span>\n <span class=\"ax-conversation-file__meta\">{{ formattedSize() }}</span>\n </span>\n <i class=\"fa-light fa-arrow-down-to-line ax-conversation-file__icon\" aria-hidden=\"true\"></i>\n </a>\n `,\n styles: [\n `\n :host {\n display: block;\n }\n\n .ax-conversation-file {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n width: 100%;\n min-height: 2.75rem;\n padding: 0.5rem 0.625rem;\n border-radius: var(--ax-sys-border-radius, 0.5rem);\n border: 1px solid rgb(var(--ax-sys-color-border-light-surface));\n background: rgb(var(--ax-sys-color-surface));\n color: rgb(var(--ax-sys-color-on-surface));\n text-decoration: none;\n touch-action: manipulation;\n transition:\n border-color 0.15s ease,\n background-color 0.15s ease;\n }\n\n @media (hover: hover) {\n .ax-conversation-file:hover {\n border-color: rgb(var(--ax-sys-color-primary-500));\n background: rgb(var(--ax-sys-color-light-surface));\n }\n }\n\n .ax-conversation-file__badge {\n flex-shrink: 0;\n width: 2.5rem;\n height: 2.5rem;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--ax-sys-border-radius, 0.375rem);\n font-weight: 600;\n font-size: 0.5625rem;\n text-transform: uppercase;\n color: rgb(var(--ax-sys-color-light));\n }\n\n .ax-conversation-file__body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n }\n\n .ax-conversation-file__name {\n font-size: 0.8125rem;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .ax-conversation-file__meta {\n font-size: 0.6875rem;\n color: rgba(var(--ax-sys-color-on-surface), 0.65);\n }\n\n .ax-conversation-file__icon {\n flex-shrink: 0;\n font-size: 0.875rem;\n color: rgba(var(--ax-sys-color-on-surface), 0.55);\n }\n `,\n ],\n})\nexport class AXConversationFileAttachmentComponent {\n readonly item = input.required<AXConversationFileMediaItem>();\n\n private readonly mediaReference = computed(() => toUploaderReference(this.item()));\n private readonly resolvedUrl = createResolvedMediaUrlSignal(this.mediaReference);\n\n readonly fileUrl = computed(() => pickDisplayMediaUrl(this.resolvedUrl(), this.item().url));\n readonly fileName = computed(() => this.item().name || 'file');\n readonly fileSize = computed(() => this.item().size ?? 0);\n\n readonly fileExtension = computed(() => {\n const name = this.fileName();\n const parts = name.split('.');\n return parts.length > 1 ? parts[parts.length - 1]! : 'FILE';\n });\n\n readonly swatchColor = computed(() => {\n const ext = this.fileExtension().toLowerCase();\n return AX_CONVERSATION_EXT_COLORS[ext] ?? 'rgb(var(--ax-sys-color-secondary-500))';\n });\n\n readonly formattedSize = computed(() => formatFileByteSize(this.fileSize()));\n}\n","import { AXFileTypeRegistryService } from '@acorex/core/file';\nimport { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport type { AXConversationFilePayload, AXConversationMessage } from '../../../../models';\nimport { normalizeFilePayload } from './file.payload';\nimport {\n AXConversationMessageRendererCopyHostComponent,\n mediaCopyText,\n} from '../shared/message-renderer-copy-host.component';\nimport { copyWithFileTypeFallback } from '../../../../utils/file-type-message.resolve';\nimport { AXConversationFileAttachmentComponent } from '../shared/file-attachment.component';\nimport { AXConversationMessageRendererStateComponent } from '../shared/message-renderer-state.component';\nimport { AX_CONVERSATION_RENDERER_SHARED_STYLES } from '../shared/renderer-shared.styles';\n\n@Component({\n selector: 'ax-conversation-file-renderer',\n imports: [CommonModule, AXConversationFileAttachmentComponent, AXConversationMessageRendererStateComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"ax-conversation-msg ax-conversation-msg--wide\">\n <ax-conversation-message-renderer-state [rendererState]=\"rendererState()\" [message]=\"message()\" />\n <div class=\"ax-conversation-msg__stack\">\n @for (file of files(); track file.mediaId ?? file.url) {\n <ax-conversation-file-attachment [item]=\"file\" />\n }\n </div>\n @if (caption()) {\n <p class=\"ax-conversation-msg__caption\">{{ caption() }}</p>\n }\n </div>\n `,\n styles: [AX_CONVERSATION_RENDERER_SHARED_STYLES],\n})\nexport class AXConversationFileRendererComponent extends AXConversationMessageRendererCopyHostComponent {\n private readonly fileTypes = inject(AXFileTypeRegistryService);\n\n readonly message = input.required<AXConversationMessage>();\n readonly rendererState = computed(() => ({\n deliveryStatus: this.message().status,\n contentState: 'ready' as const,\n }));\n\n readonly payload = computed(() => normalizeFilePayload(this.message().payload as AXConversationFilePayload));\n readonly files = computed(() => this.payload().files);\n readonly caption = computed(() => this.payload().caption?.trim() || '');\n\n copy(): Promise<string> {\n return copyWithFileTypeFallback(this.message(), this.fileTypes, () => {\n const p = this.payload();\n if (p.files.length === 1) {\n const file = p.files[0];\n const name = file.name?.trim() || 'File';\n const url = file.url?.trim();\n return url ? `${name}\\n${url}` : name;\n }\n return mediaCopyText(\n p.caption,\n 'File',\n 'files',\n p.files.length,\n p.files.map((file) => file.name?.trim() || file.url?.trim()),\n );\n });\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { s as resolvePersistableMediaUrl, c as resolvePersistedThumbnailUrl } from './acorex-components-conversation-acorex-components-conversation-YhVa42TC.mjs';
2
+
3
+ function loose(payload) {
4
+ return payload;
5
+ }
6
+ function str(value) {
7
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
8
+ }
9
+ function sanitizeFileItem(item) {
10
+ const url = resolvePersistableMediaUrl(item.url);
11
+ const thumbnailUrl = resolvePersistedThumbnailUrl(item.thumbnailUrl, url);
12
+ if (url === item.url && thumbnailUrl === item.thumbnailUrl) {
13
+ return item;
14
+ }
15
+ return { ...item, url, thumbnailUrl };
16
+ }
17
+ function normalizeFilePayload(payload) {
18
+ const raw = loose(payload);
19
+ const existing = raw['files'];
20
+ if (Array.isArray(existing) && existing.length > 0) {
21
+ return {
22
+ type: 'file',
23
+ files: existing.map(sanitizeFileItem),
24
+ caption: payload.caption,
25
+ };
26
+ }
27
+ const url = resolvePersistableMediaUrl(str(raw['url']));
28
+ const mediaId = str(raw['mediaId']);
29
+ if (url || mediaId) {
30
+ return {
31
+ type: 'file',
32
+ caption: payload.caption,
33
+ files: [
34
+ {
35
+ ...(url ? { url } : {}),
36
+ name: str(raw['name']) ?? 'file',
37
+ mimeType: str(raw['mimeType']) ?? 'application/octet-stream',
38
+ size: typeof raw['size'] === 'number' ? raw['size'] : undefined,
39
+ mediaId,
40
+ thumbnailUrl: resolvePersistedThumbnailUrl(str(raw['thumbnailUrl']), url),
41
+ extension: str(raw['extension']),
42
+ },
43
+ ],
44
+ };
45
+ }
46
+ return { type: 'file', files: [], caption: payload.caption };
47
+ }
48
+
49
+ export { normalizeFilePayload };
50
+ //# sourceMappingURL=acorex-components-conversation-file.payload-DyFxTQYn.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-components-conversation-file.payload-DyFxTQYn.mjs","sources":["../../../../packages/components/conversation/src/lib/plugins/message-list/components/file-renderer/file.payload.ts"],"sourcesContent":["import type { AXConversationFileMediaItem, AXConversationFilePayload } from '../../../../models';\nimport {\n resolvePersistableMediaUrl,\n resolvePersistedThumbnailUrl,\n} from '../../../composer/components/shared/persisted-media-url';\n\ntype AXConversationLooseRecord = Record<string, unknown>;\n\nfunction loose(payload: AXConversationFilePayload): AXConversationLooseRecord {\n return payload as unknown as AXConversationLooseRecord;\n}\n\nfunction str(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction sanitizeFileItem(item: AXConversationFileMediaItem): AXConversationFileMediaItem {\n const url = resolvePersistableMediaUrl(item.url);\n const thumbnailUrl = resolvePersistedThumbnailUrl(item.thumbnailUrl, url);\n if (url === item.url && thumbnailUrl === item.thumbnailUrl) {\n return item;\n }\n return { ...item, url, thumbnailUrl };\n}\n\nexport function normalizeFilePayload(payload: AXConversationFilePayload): AXConversationFilePayload {\n const raw = loose(payload);\n const existing = raw['files'];\n if (Array.isArray(existing) && existing.length > 0) {\n return {\n type: 'file',\n files: (existing as AXConversationFileMediaItem[]).map(sanitizeFileItem),\n caption: payload.caption,\n };\n }\n\n const url = resolvePersistableMediaUrl(str(raw['url']));\n const mediaId = str(raw['mediaId']);\n if (url || mediaId) {\n return {\n type: 'file',\n caption: payload.caption,\n files: [\n {\n ...(url ? { url } : {}),\n name: str(raw['name']) ?? 'file',\n mimeType: str(raw['mimeType']) ?? 'application/octet-stream',\n size: typeof raw['size'] === 'number' ? raw['size'] : undefined,\n mediaId,\n thumbnailUrl: resolvePersistedThumbnailUrl(str(raw['thumbnailUrl']), url),\n extension: str(raw['extension']),\n },\n ],\n };\n }\n\n return { type: 'file', files: [], caption: payload.caption };\n}\n"],"names":[],"mappings":";;AAQA,SAAS,KAAK,CAAC,OAAkC,EAAA;AAC/C,IAAA,OAAO,OAA+C;AACxD;AAEA,SAAS,GAAG,CAAC,KAAc,EAAA;AACzB,IAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,SAAS;AAC1E;AAEA,SAAS,gBAAgB,CAAC,IAAiC,EAAA;IACzD,MAAM,GAAG,GAAG,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC;IAChD,MAAM,YAAY,GAAG,4BAA4B,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC;AACzE,IAAA,IAAI,GAAG,KAAK,IAAI,CAAC,GAAG,IAAI,YAAY,KAAK,IAAI,CAAC,YAAY,EAAE;AAC1D,QAAA,OAAO,IAAI;IACb;IACA,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE;AACvC;AAEM,SAAU,oBAAoB,CAAC,OAAkC,EAAA;AACrE,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC;AAC1B,IAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC;AAC7B,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;QAClD,OAAO;AACL,YAAA,IAAI,EAAE,MAAM;AACZ,YAAA,KAAK,EAAG,QAA0C,CAAC,GAAG,CAAC,gBAAgB,CAAC;YACxE,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB;IACH;AAEA,IAAA,MAAM,GAAG,GAAG,0BAA0B,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACnC,IAAA,IAAI,GAAG,IAAI,OAAO,EAAE;QAClB,OAAO;AACL,YAAA,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,OAAO,CAAC,OAAO;AACxB,YAAA,KAAK,EAAE;AACL,gBAAA;AACE,oBAAA,IAAI,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;oBACvB,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,MAAM;oBAChC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,0BAA0B;AAC5D,oBAAA,IAAI,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS;oBAC/D,OAAO;AACP,oBAAA,YAAY,EAAE,4BAA4B,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,EAAE,GAAG,CAAC;AACzE,oBAAA,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACjC,iBAAA;AACF,aAAA;SACF;IACH;AAEA,IAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;AAC9D;;;;"}
@@ -0,0 +1,21 @@
1
+ /** Shared formatting for message renderer UIs. */
2
+ function formatMediaDuration(seconds) {
3
+ if (!Number.isFinite(seconds)) {
4
+ return '0:00';
5
+ }
6
+ const m = Math.floor(seconds / 60);
7
+ const s = Math.floor(seconds % 60);
8
+ return `${m}:${s.toString().padStart(2, '0')}`;
9
+ }
10
+ function formatFileByteSize(bytes) {
11
+ if (bytes === 0) {
12
+ return '0 B';
13
+ }
14
+ const k = 1024;
15
+ const sizes = ['B', 'KB', 'MB', 'GB'];
16
+ const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), sizes.length - 1);
17
+ return `${Math.round((bytes / k ** i) * 100) / 100} ${sizes[i]}`;
18
+ }
19
+
20
+ export { formatFileByteSize as a, formatMediaDuration as f };
21
+ //# sourceMappingURL=acorex-components-conversation-format-media-DUD4vA6F.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-components-conversation-format-media-DUD4vA6F.mjs","sources":["../../../../packages/components/conversation/src/lib/plugins/message-list/components/shared/format-media.ts"],"sourcesContent":["/** Shared formatting for message renderer UIs. */\n\nexport function formatMediaDuration(seconds: number): string {\n if (!Number.isFinite(seconds)) {\n return '0:00';\n }\n const m = Math.floor(seconds / 60);\n const s = Math.floor(seconds % 60);\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\nexport function formatFileByteSize(bytes: number): string {\n if (bytes === 0) {\n return '0 B';\n }\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'] as const;\n const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), sizes.length - 1);\n return `${Math.round((bytes / k ** i) * 100) / 100} ${sizes[i]}`;\n}\n"],"names":[],"mappings":"AAAA;AAEM,SAAU,mBAAmB,CAAC,OAAe,EAAA;IACjD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;AAC7B,QAAA,OAAO,MAAM;IACf;IACA,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;IAClC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;AAClC,IAAA,OAAO,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;AAChD;AAEM,SAAU,kBAAkB,CAAC,KAAa,EAAA;AAC9C,IAAA,IAAI,KAAK,KAAK,CAAC,EAAE;AACf,QAAA,OAAO,KAAK;IACd;IACA,MAAM,CAAC,GAAG,IAAI;IACd,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU;AAC9C,IAAA,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/E,OAAO,CAAA,EAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAA,CAAA,EAAI,KAAK,CAAC,CAAC,CAAC,CAAA,CAAE;AAClE;;;;"}
@@ -0,0 +1,77 @@
1
+ import { DOCUMENT, isPlatformBrowser } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, PLATFORM_ID, input, signal, computed, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { w as toUploaderReference, x as createResolvedMediaUrlSignal, y as pickDisplayMediaUrl } from './acorex-components-conversation-acorex-components-conversation-YhVa42TC.mjs';
5
+
6
+ class AXConversationImageAttachmentComponent {
7
+ constructor() {
8
+ this.platformId = inject(PLATFORM_ID);
9
+ this.document = inject(DOCUMENT);
10
+ this.item = input.required(...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
11
+ this.alt = input('Image', ...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
12
+ this.ready = signal(false, ...(ngDevMode ? [{ debugName: "ready" }] : /* istanbul ignore next */ []));
13
+ this.mediaReference = computed(() => toUploaderReference(this.item()), ...(ngDevMode ? [{ debugName: "mediaReference" }] : /* istanbul ignore next */ []));
14
+ this.resolvedUrl = createResolvedMediaUrlSignal(this.mediaReference);
15
+ this.displayUrl = computed(() => pickDisplayMediaUrl(this.resolvedUrl(), this.item().thumbnailUrl, this.item().url), ...(ngDevMode ? [{ debugName: "displayUrl" }] : /* istanbul ignore next */ []));
16
+ effect(() => {
17
+ this.displayUrl();
18
+ this.item().mediaId;
19
+ untracked(() => this.ready.set(false));
20
+ });
21
+ }
22
+ onImageLoad() {
23
+ this.ready.set(true);
24
+ }
25
+ onImageError() {
26
+ this.ready.set(false);
27
+ }
28
+ toggleFullscreen(event) {
29
+ if (!isPlatformBrowser(this.platformId)) {
30
+ return;
31
+ }
32
+ const img = event.currentTarget.querySelector('img');
33
+ if (!(img instanceof HTMLImageElement) || !img.requestFullscreen) {
34
+ return;
35
+ }
36
+ if (this.document.fullscreenElement === img) {
37
+ void this.document.exitFullscreen();
38
+ return;
39
+ }
40
+ void img.requestFullscreen();
41
+ }
42
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationImageAttachmentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
43
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXConversationImageAttachmentComponent, isStandalone: true, selector: "ax-conversation-image-attachment", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
44
+ <button
45
+ type="button"
46
+ class="ax-conversation-image-attachment"
47
+ [class.ax-conversation-image-attachment--ready]="ready()"
48
+ [class.ax-conversation-image-attachment--loading]="!displayUrl()"
49
+ (click)="toggleFullscreen($event)"
50
+ [attr.aria-label]="alt()"
51
+ >
52
+ @if (displayUrl(); as src) {
53
+ <img [src]="src" [alt]="alt()" loading="lazy" (load)="onImageLoad()" (error)="onImageError()" />
54
+ }
55
+ </button>
56
+ `, isInline: true, styles: [":host{display:block;min-width:0;min-height:0}.ax-conversation-image-attachment{display:block;width:100%;height:100%;min-height:4.5rem;padding:0;border-radius:.5rem;border:none;background:rgb(var(--ax-sys-color-light-surface));overflow:hidden}.ax-conversation-image-attachment--loading{background:rgba(var(--ax-sys-color-on-surface),.06)}.ax-conversation-image-attachment img{width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .15s ease}.ax-conversation-image-attachment img:fullscreen{width:100%;height:100%;object-fit:contain;background:#000}.ax-conversation-image-attachment--ready img{opacity:1}.ax-conversation-image-attachment:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-500));outline-offset:2px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
57
+ }
58
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationImageAttachmentComponent, decorators: [{
59
+ type: Component,
60
+ args: [{ selector: 'ax-conversation-image-attachment', changeDetection: ChangeDetectionStrategy.OnPush, template: `
61
+ <button
62
+ type="button"
63
+ class="ax-conversation-image-attachment"
64
+ [class.ax-conversation-image-attachment--ready]="ready()"
65
+ [class.ax-conversation-image-attachment--loading]="!displayUrl()"
66
+ (click)="toggleFullscreen($event)"
67
+ [attr.aria-label]="alt()"
68
+ >
69
+ @if (displayUrl(); as src) {
70
+ <img [src]="src" [alt]="alt()" loading="lazy" (load)="onImageLoad()" (error)="onImageError()" />
71
+ }
72
+ </button>
73
+ `, styles: [":host{display:block;min-width:0;min-height:0}.ax-conversation-image-attachment{display:block;width:100%;height:100%;min-height:4.5rem;padding:0;border-radius:.5rem;border:none;background:rgb(var(--ax-sys-color-light-surface));overflow:hidden}.ax-conversation-image-attachment--loading{background:rgba(var(--ax-sys-color-on-surface),.06)}.ax-conversation-image-attachment img{width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .15s ease}.ax-conversation-image-attachment img:fullscreen{width:100%;height:100%;object-fit:contain;background:#000}.ax-conversation-image-attachment--ready img{opacity:1}.ax-conversation-image-attachment:focus-visible{outline:2px solid rgb(var(--ax-sys-color-primary-500));outline-offset:2px}\n"] }]
74
+ }], ctorParameters: () => [], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }] } });
75
+
76
+ export { AXConversationImageAttachmentComponent as A };
77
+ //# sourceMappingURL=acorex-components-conversation-image-attachment.component-CLMGxXPl.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-components-conversation-image-attachment.component-CLMGxXPl.mjs","sources":["../../../../packages/components/conversation/src/lib/plugins/message-list/components/shared/image-attachment.component.ts"],"sourcesContent":["import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n PLATFORM_ID,\n computed,\n effect,\n inject,\n input,\n signal,\n untracked,\n} from '@angular/core';\nimport type { AXConversationImageMediaItem } from '../../../../models';\nimport { pickDisplayMediaUrl } from '../../../composer/components/shared/persisted-media-url';\nimport { toUploaderReference } from './attachment-uploader-reference';\nimport { createResolvedMediaUrlSignal } from './media-url-resolve';\n\n@Component({\n selector: 'ax-conversation-image-attachment',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <button\n type=\"button\"\n class=\"ax-conversation-image-attachment\"\n [class.ax-conversation-image-attachment--ready]=\"ready()\"\n [class.ax-conversation-image-attachment--loading]=\"!displayUrl()\"\n (click)=\"toggleFullscreen($event)\"\n [attr.aria-label]=\"alt()\"\n >\n @if (displayUrl(); as src) {\n <img [src]=\"src\" [alt]=\"alt()\" loading=\"lazy\" (load)=\"onImageLoad()\" (error)=\"onImageError()\" />\n }\n </button>\n `,\n styles: [\n `\n :host {\n display: block;\n min-width: 0;\n min-height: 0;\n }\n\n .ax-conversation-image-attachment {\n display: block;\n width: 100%;\n height: 100%;\n min-height: 4.5rem;\n padding: 0;\n border-radius: 0.5rem;\n border: none;\n background: rgb(var(--ax-sys-color-light-surface));\n overflow: hidden;\n }\n\n .ax-conversation-image-attachment--loading {\n background: rgba(var(--ax-sys-color-on-surface), 0.06);\n }\n\n .ax-conversation-image-attachment img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n opacity: 0;\n transition: opacity 0.15s ease;\n }\n\n .ax-conversation-image-attachment img:fullscreen {\n width: 100%;\n height: 100%;\n object-fit: contain;\n background: #000;\n }\n\n .ax-conversation-image-attachment--ready img {\n opacity: 1;\n }\n\n .ax-conversation-image-attachment:focus-visible {\n outline: 2px solid rgb(var(--ax-sys-color-primary-500));\n outline-offset: 2px;\n }\n `,\n ],\n})\nexport class AXConversationImageAttachmentComponent {\n private readonly platformId = inject(PLATFORM_ID);\n private readonly document = inject(DOCUMENT);\n\n readonly item = input.required<AXConversationImageMediaItem>();\n readonly alt = input('Image');\n\n readonly ready = signal(false);\n\n private readonly mediaReference = computed(() => toUploaderReference(this.item()));\n private readonly resolvedUrl = createResolvedMediaUrlSignal(this.mediaReference);\n\n readonly displayUrl = computed(() =>\n pickDisplayMediaUrl(this.resolvedUrl(), this.item().thumbnailUrl, this.item().url),\n );\n\n constructor() {\n effect(() => {\n this.displayUrl();\n this.item().mediaId;\n untracked(() => this.ready.set(false));\n });\n }\n\n onImageLoad(): void {\n this.ready.set(true);\n }\n\n onImageError(): void {\n this.ready.set(false);\n }\n\n toggleFullscreen(event: MouseEvent): void {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n const img = (event.currentTarget as HTMLElement).querySelector('img');\n if (!(img instanceof HTMLImageElement) || !img.requestFullscreen) {\n return;\n }\n if (this.document.fullscreenElement === img) {\n void this.document.exitFullscreen();\n return;\n }\n void img.requestFullscreen();\n }\n}\n"],"names":[],"mappings":"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"}