@memori.ai/memori-react 8.15.1 → 8.16.0

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 (166) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/components/Chat/Chat.css +2 -1
  3. package/dist/components/Chat/Chat.js +17 -17
  4. package/dist/components/Chat/Chat.js.map +1 -1
  5. package/dist/components/ChatBubble/ChatBubble.css +1 -1
  6. package/dist/components/ContentPreviewModal/ContentPreviewModal.css +114 -0
  7. package/dist/components/ContentPreviewModal/ContentPreviewModal.d.ts +14 -0
  8. package/dist/components/ContentPreviewModal/ContentPreviewModal.js +18 -0
  9. package/dist/components/ContentPreviewModal/ContentPreviewModal.js.map +1 -0
  10. package/dist/components/ContentPreviewModal/index.d.ts +2 -0
  11. package/dist/components/ContentPreviewModal/index.js +9 -0
  12. package/dist/components/ContentPreviewModal/index.js.map +1 -0
  13. package/dist/components/FilePreview/FilePreview.css +1 -1
  14. package/dist/components/FilePreview/FilePreview.js +43 -13
  15. package/dist/components/FilePreview/FilePreview.js.map +1 -1
  16. package/dist/components/MediaWidget/DocumentCard.d.ts +3 -0
  17. package/dist/components/MediaWidget/DocumentCard.js +9 -0
  18. package/dist/components/MediaWidget/DocumentCard.js.map +1 -0
  19. package/dist/components/MediaWidget/MediaItemWidget.css +946 -19
  20. package/dist/components/MediaWidget/MediaItemWidget.d.ts +5 -36
  21. package/dist/components/MediaWidget/MediaItemWidget.js +295 -198
  22. package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
  23. package/dist/components/MediaWidget/MediaItemWidget.types.d.ts +62 -0
  24. package/dist/components/MediaWidget/MediaItemWidget.types.js +3 -0
  25. package/dist/components/MediaWidget/MediaItemWidget.types.js.map +1 -0
  26. package/dist/components/MediaWidget/MediaItemWidget.utils.d.ts +23 -0
  27. package/dist/components/MediaWidget/MediaItemWidget.utils.js +162 -0
  28. package/dist/components/MediaWidget/MediaItemWidget.utils.js.map +1 -0
  29. package/dist/components/MediaWidget/MediaPreviewModal.d.ts +15 -0
  30. package/dist/components/MediaWidget/MediaPreviewModal.js +162 -0
  31. package/dist/components/MediaWidget/MediaPreviewModal.js.map +1 -0
  32. package/dist/components/MediaWidget/MediaWidget.js +1 -2
  33. package/dist/components/MediaWidget/MediaWidget.js.map +1 -1
  34. package/dist/components/Snippet/Snippet.css +64 -33
  35. package/dist/components/Snippet/Snippet.js +17 -4
  36. package/dist/components/Snippet/Snippet.js.map +1 -1
  37. package/dist/components/StartPanel/StartPanel.js +1 -2
  38. package/dist/components/StartPanel/StartPanel.js.map +1 -1
  39. package/dist/components/UploadButton/UploadButton.css +0 -5
  40. package/dist/components/layouts/WebsiteAssistant.js +8 -8
  41. package/dist/components/layouts/WebsiteAssistant.js.map +1 -1
  42. package/dist/components/layouts/chat.css +1 -1
  43. package/dist/components/layouts/website-assistant.css +405 -197
  44. package/dist/helpers/constants.js +0 -7
  45. package/dist/helpers/constants.js.map +1 -1
  46. package/dist/helpers/utils.d.ts +1 -0
  47. package/dist/helpers/utils.js +3 -1
  48. package/dist/helpers/utils.js.map +1 -1
  49. package/dist/index.js +43 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/styles.css +0 -2
  52. package/dist/version.d.ts +1 -0
  53. package/dist/version.js +5 -0
  54. package/dist/version.js.map +1 -0
  55. package/esm/components/Chat/Chat.css +2 -1
  56. package/esm/components/Chat/Chat.js +17 -17
  57. package/esm/components/Chat/Chat.js.map +1 -1
  58. package/esm/components/ChatBubble/ChatBubble.css +1 -1
  59. package/esm/components/ContentPreviewModal/ContentPreviewModal.css +114 -0
  60. package/esm/components/ContentPreviewModal/ContentPreviewModal.d.ts +14 -0
  61. package/esm/components/ContentPreviewModal/ContentPreviewModal.js +15 -0
  62. package/esm/components/ContentPreviewModal/ContentPreviewModal.js.map +1 -0
  63. package/esm/components/ContentPreviewModal/index.d.ts +2 -0
  64. package/esm/components/ContentPreviewModal/index.js +2 -0
  65. package/esm/components/ContentPreviewModal/index.js.map +1 -0
  66. package/esm/components/FilePreview/FilePreview.css +1 -1
  67. package/esm/components/FilePreview/FilePreview.js +44 -14
  68. package/esm/components/FilePreview/FilePreview.js.map +1 -1
  69. package/esm/components/MediaWidget/DocumentCard.d.ts +3 -0
  70. package/esm/components/MediaWidget/DocumentCard.js +5 -0
  71. package/esm/components/MediaWidget/DocumentCard.js.map +1 -0
  72. package/esm/components/MediaWidget/MediaItemWidget.css +946 -19
  73. package/esm/components/MediaWidget/MediaItemWidget.d.ts +5 -36
  74. package/esm/components/MediaWidget/MediaItemWidget.js +296 -197
  75. package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
  76. package/esm/components/MediaWidget/MediaItemWidget.types.d.ts +62 -0
  77. package/esm/components/MediaWidget/MediaItemWidget.types.js +2 -0
  78. package/esm/components/MediaWidget/MediaItemWidget.types.js.map +1 -0
  79. package/esm/components/MediaWidget/MediaItemWidget.utils.d.ts +23 -0
  80. package/esm/components/MediaWidget/MediaItemWidget.utils.js +149 -0
  81. package/esm/components/MediaWidget/MediaItemWidget.utils.js.map +1 -0
  82. package/esm/components/MediaWidget/MediaPreviewModal.d.ts +15 -0
  83. package/esm/components/MediaWidget/MediaPreviewModal.js +157 -0
  84. package/esm/components/MediaWidget/MediaPreviewModal.js.map +1 -0
  85. package/esm/components/MediaWidget/MediaWidget.js +1 -2
  86. package/esm/components/MediaWidget/MediaWidget.js.map +1 -1
  87. package/esm/components/Snippet/Snippet.css +64 -33
  88. package/esm/components/Snippet/Snippet.js +18 -5
  89. package/esm/components/Snippet/Snippet.js.map +1 -1
  90. package/esm/components/StartPanel/StartPanel.js +1 -2
  91. package/esm/components/StartPanel/StartPanel.js.map +1 -1
  92. package/esm/components/UploadButton/UploadButton.css +0 -5
  93. package/esm/components/layouts/WebsiteAssistant.js +8 -8
  94. package/esm/components/layouts/WebsiteAssistant.js.map +1 -1
  95. package/esm/components/layouts/chat.css +1 -1
  96. package/esm/components/layouts/website-assistant.css +405 -197
  97. package/esm/helpers/constants.js +0 -7
  98. package/esm/helpers/constants.js.map +1 -1
  99. package/esm/helpers/utils.d.ts +1 -0
  100. package/esm/helpers/utils.js +1 -0
  101. package/esm/helpers/utils.js.map +1 -1
  102. package/esm/index.js +43 -1
  103. package/esm/index.js.map +1 -1
  104. package/esm/styles.css +0 -2
  105. package/esm/version.d.ts +1 -0
  106. package/esm/version.js +2 -0
  107. package/esm/version.js.map +1 -0
  108. package/package.json +5 -3
  109. package/src/components/Chat/Chat.css +2 -1
  110. package/src/components/Chat/Chat.stories.tsx +124 -0
  111. package/src/components/Chat/Chat.tsx +72 -71
  112. package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +567 -1034
  113. package/src/components/ChatBubble/ChatBubble.css +1 -1
  114. package/src/components/ContentPreviewModal/ContentPreviewModal.css +114 -0
  115. package/src/components/ContentPreviewModal/ContentPreviewModal.tsx +69 -0
  116. package/src/components/ContentPreviewModal/index.ts +2 -0
  117. package/src/components/FilePreview/FilePreview.css +1 -1
  118. package/src/components/FilePreview/FilePreview.tsx +60 -37
  119. package/src/components/FilePreview/__snapshots__/FilePreview.test.tsx.snap +15 -105
  120. package/src/components/MediaWidget/DocumentCard.test.tsx +45 -0
  121. package/src/components/MediaWidget/DocumentCard.tsx +19 -0
  122. package/src/components/MediaWidget/MediaItemWidget.css +946 -19
  123. package/src/components/MediaWidget/MediaItemWidget.test.tsx +89 -1
  124. package/src/components/MediaWidget/MediaItemWidget.tsx +734 -461
  125. package/src/components/MediaWidget/MediaItemWidget.types.ts +65 -0
  126. package/src/components/MediaWidget/MediaItemWidget.utils.test.ts +324 -0
  127. package/src/components/MediaWidget/MediaItemWidget.utils.ts +194 -0
  128. package/src/components/MediaWidget/MediaPreviewModal.test.tsx +271 -0
  129. package/src/components/MediaWidget/MediaPreviewModal.tsx +423 -0
  130. package/src/components/MediaWidget/MediaWidget.stories.tsx +193 -0
  131. package/src/components/MediaWidget/MediaWidget.tsx +2 -4
  132. package/src/components/MediaWidget/__snapshots__/DocumentCard.test.tsx.snap +24 -0
  133. package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +162 -170
  134. package/src/components/MediaWidget/__snapshots__/MediaWidget.test.tsx.snap +21 -63
  135. package/src/components/Snippet/Snippet.css +64 -33
  136. package/src/components/Snippet/Snippet.tsx +30 -21
  137. package/src/components/Snippet/__snapshots__/Snippet.test.tsx.snap +314 -297
  138. package/src/components/StartPanel/StartPanel.tsx +0 -9
  139. package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +12 -636
  140. package/src/components/UploadButton/UploadButton.css +0 -5
  141. package/src/components/layouts/WebsiteAssistant.tsx +66 -62
  142. package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +1 -53
  143. package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +2 -106
  144. package/src/components/layouts/__snapshots__/HiddenChat.test.tsx.snap +1 -53
  145. package/src/components/layouts/__snapshots__/Totem.test.tsx.snap +1 -53
  146. package/src/components/layouts/__snapshots__/WebsiteAssistant.test.tsx.snap +32 -33
  147. package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +1 -53
  148. package/src/components/layouts/chat.css +1 -1
  149. package/src/components/layouts/layouts.stories.tsx +68 -0
  150. package/src/components/layouts/website-assistant.css +405 -197
  151. package/src/helpers/constants.ts +0 -7
  152. package/src/helpers/utils.ts +4 -0
  153. package/src/index.test.tsx +8 -0
  154. package/src/index.tsx +51 -1
  155. package/src/styles.css +0 -2
  156. package/src/version.ts +2 -0
  157. package/src/components/AttachmentLinkModal/AttachmentLinkModal.css +0 -68
  158. package/src/components/AttachmentLinkModal/AttachmentLinkModal.stories.tsx +0 -32
  159. package/src/components/AttachmentLinkModal/AttachmentLinkModal.test.tsx +0 -10
  160. package/src/components/AttachmentLinkModal/AttachmentLinkModal.tsx +0 -131
  161. package/src/components/AttachmentLinkModal/__snapshots__/AttachmentLinkModal.test.tsx.snap +0 -9
  162. package/src/components/MediaWidget/LinkItemWidget.css +0 -46
  163. package/src/components/MediaWidget/LinkItemWidget.stories.tsx +0 -61
  164. package/src/components/MediaWidget/LinkItemWidget.test.tsx +0 -33
  165. package/src/components/MediaWidget/LinkItemWidget.tsx +0 -204
  166. package/src/components/MediaWidget/__snapshots__/LinkItemWidget.test.tsx.snap +0 -253
@@ -1,197 +1,302 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useState, memo } from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useState, memo, useRef, } from 'react';
3
3
  import { getResourceUrl } from '../../helpers/media';
4
+ import { stripDocumentAttachmentTags, } from '../../helpers/utils';
4
5
  import { getTranslation } from '../../helpers/translations';
5
6
  import { prismSyntaxLangs } from '../../helpers/constants';
6
7
  import ModelViewer from '../CustomGLBModelViewer/ModelViewer';
7
8
  import Snippet from '../Snippet/Snippet';
8
9
  import Card from '../ui/Card';
9
- import Modal from '../ui/Modal';
10
- import Button from '../ui/Button';
11
10
  import File from '../icons/File';
12
- import FilePdf from '../icons/FilePdf';
13
- import FileExcel from '../icons/FileExcel';
14
- import FileWord from '../icons/FileWord';
15
- import Copy from '../icons/Copy';
16
11
  import { Transition } from '@headlessui/react';
17
- import { stripHTML } from '../../helpers/utils';
18
12
  import cx from 'classnames';
19
- export const RenderMediaItem = ({ isChild = false, item, sessionID, tenantID, preview = false, baseURL, apiURL, onClick, customMediaRenderer, }) => {
20
- var _a, _b;
21
- const [modalOpen, setModalOpen] = useState(false);
13
+ import Sound from '../icons/Sound';
14
+ import Link from '../icons/Link';
15
+ import { ellipsis } from 'ellipsed';
16
+ import { formatBytes, getFileExtensionFromUrl, getFileExtensionFromMime, countLines, shouldUseDarkFileCard, fetchLinkPreview, getContentSize, normalizeUrl, getImageDisplaySource, FALLBACK_IMAGE_BASE64, TEXT_FILE_EXTENSIONS, IMAGE_MIME_TYPES, } from './MediaItemWidget.utils';
17
+ import { DocumentCard } from './DocumentCard';
18
+ import { MediaPreviewModal } from './MediaPreviewModal';
19
+ const CODE_MIME_TYPES = prismSyntaxLangs.map(l => l.mimeType);
20
+ const IMAGE_MODAL_MIME_TYPES = [
21
+ 'image/jpeg',
22
+ 'image/png',
23
+ 'image/jpg',
24
+ 'image/gif',
25
+ ];
26
+ function isImageMime(mimeType) {
27
+ return IMAGE_MODAL_MIME_TYPES.includes(mimeType);
28
+ }
29
+ export const RenderMediaItem = memo(function RenderMediaItem({ isChild: _isChild = false, item, sessionID, tenantID, preview = false, baseURL, apiURL, onClick: _onClick, customMediaRenderer, descriptionOneLine = false, onLinkPreviewInfo, }) {
30
+ var _a, _b, _c, _d;
22
31
  const [copyNotification, setCopyNotification] = useState(false);
23
32
  const [imageError, setImageError] = useState(false);
24
- const url = getResourceUrl({
33
+ const [link, setLink] = useState(null);
34
+ const onLinkPreviewInfoRef = useRef(onLinkPreviewInfo);
35
+ onLinkPreviewInfoRef.current = onLinkPreviewInfo;
36
+ const resourceUrl = getResourceUrl({
25
37
  resourceURI: item.url,
26
38
  sessionID,
27
39
  tenantID,
28
40
  baseURL,
29
41
  apiURL,
30
42
  });
43
+ const normURL = normalizeUrl(item.url);
44
+ useEffect(() => {
45
+ if (item.mimeType !== 'text/html' ||
46
+ !normURL ||
47
+ normURL === (link === null || link === void 0 ? void 0 : link.urlKey) ||
48
+ !baseURL) {
49
+ return;
50
+ }
51
+ let cancelled = false;
52
+ fetchLinkPreview(normURL, baseURL).then(siteInfo => {
53
+ if (cancelled)
54
+ return;
55
+ setLink(siteInfo
56
+ ? { ...siteInfo, urlKey: normURL }
57
+ : null);
58
+ if (siteInfo && onLinkPreviewInfoRef.current) {
59
+ onLinkPreviewInfoRef.current(siteInfo);
60
+ }
61
+ });
62
+ return () => {
63
+ cancelled = true;
64
+ };
65
+ }, [item === null || item === void 0 ? void 0 : item.url, baseURL, item.mimeType, normURL, link === null || link === void 0 ? void 0 : link.urlKey]);
31
66
  const customRenderer = customMediaRenderer === null || customMediaRenderer === void 0 ? void 0 : customMediaRenderer(item.mimeType);
32
67
  if (customRenderer) {
33
68
  return customRenderer;
34
69
  }
35
- const isCodeSnippet = prismSyntaxLangs
36
- .map(l => l.mimeType)
37
- .includes(item.mimeType);
70
+ const isCodeSnippet = CODE_MIME_TYPES.includes(item.mimeType);
38
71
  const isHTML = item.mimeType === 'text/html';
39
- const isImageRGB = ((_a = item.url) === null || _a === void 0 ? void 0 : _a.startsWith('rgb(')) || ((_b = item.url) === null || _b === void 0 ? void 0 : _b.startsWith('rgba('));
40
- const isValidUrl = (urlString) => {
41
- if (!urlString)
42
- return false;
43
- try {
44
- new URL(urlString);
45
- return true;
46
- }
47
- catch (_a) {
48
- return false;
49
- }
50
- };
51
- const getImageSrc = () => {
52
- var _a, _b;
53
- if (isValidUrl(url) || isValidUrl(item.url)) {
54
- return url || item.url;
55
- }
56
- else if (((_a = item.url) === null || _a === void 0 ? void 0 : _a.startsWith('rgb(')) || ((_b = item.url) === null || _b === void 0 ? void 0 : _b.startsWith('rgba('))) {
57
- return item.url;
58
- }
59
- else if (item.content) {
60
- return `data:${item.mimeType};base64,${item.content}`;
61
- }
62
- return undefined;
63
- };
64
- const imageSrc = getImageSrc();
65
- const fallbackImage = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgZmlsbD0iI2YwZjBmMCIvPjx0ZXh0IHg9IjUwJSIgeT0iNTAlIiBmb250LWZhbWlseT0iQXJpYWwsIHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTQiIGZpbGw9IiM5OTk5OTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGR5PSIuM2VtIj5JbWFnZSBub3QgYXZhaWxhYmxlPC90ZXh0Pjwvc3ZnPg==';
66
- const renderMediaContent = (item) => {
67
- switch (item.mimeType) {
72
+ const isDocumentAttachment = ((_a = item.properties) === null || _a === void 0 ? void 0 : _a.isDocumentAttachment) === true;
73
+ const isAttachedFile = ((_b = item.properties) === null || _b === void 0 ? void 0 : _b.isAttachedFile) === true;
74
+ const imageDisplay = getImageDisplaySource(item, resourceUrl);
75
+ const { src: imageSrc, isRgb: isImageRGB } = imageDisplay;
76
+ const linkTitle = item.title && item.title.length > 0 ? item.title : link === null || link === void 0 ? void 0 : link.title;
77
+ const linkDescription = link === null || link === void 0 ? void 0 : link.description;
78
+ const linkVideo = link === null || link === void 0 ? void 0 : link.video;
79
+ const linkImage = (_c = link === null || link === void 0 ? void 0 : link.image) !== null && _c !== void 0 ? _c : (_d = link === null || link === void 0 ? void 0 : link.images) === null || _d === void 0 ? void 0 : _d[0];
80
+ const renderMediaContent = useCallback((medium) => {
81
+ const url = getResourceUrl({
82
+ resourceURI: medium.url,
83
+ sessionID,
84
+ tenantID,
85
+ baseURL,
86
+ apiURL,
87
+ });
88
+ switch (medium.mimeType) {
68
89
  case 'image/jpeg':
69
90
  case 'image/png':
70
91
  case 'image/jpg':
71
92
  case 'image/gif':
72
- return isImageRGB ? (_jsxs("picture", { className: "memori-media-item--figure", children: [_jsx("div", { className: "memori-media-item--rgb-item", style: {
73
- backgroundColor: item.url,
74
- } }), item.title && (_jsx("figcaption", { className: "memori-media-item--figure-caption", children: item.title }))] })) : (_jsxs("picture", { className: "memori-media-item--figure", children: [!preview && imageSrc && (_jsx("source", { srcSet: imageSrc, type: item.mimeType })), _jsx("img", { alt: item.title, src: imageError || !imageSrc ? fallbackImage : imageSrc, onError: () => setImageError(true) }), item.title && (_jsx("figcaption", { className: "memori-media-item--figure-caption", children: item.title }))] }));
75
- case 'application/msword':
76
- case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
77
- return _jsx(FileWord, { className: "memori-media-item--icon" });
78
- case 'application/vnd.ms-excel':
79
- case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
80
- return _jsx(FileExcel, { className: "memori-media-item--icon" });
81
- case 'application/pdf':
82
- return _jsx(FilePdf, { className: "memori-media-item--icon" });
93
+ return isImageRGB ? (_jsx("picture", { className: "memori-media-item--figure", children: _jsx("div", { className: "memori-media-item--rgb-item", style: { backgroundColor: medium.url } }) })) : (_jsxs("picture", { className: "memori-media-item--figure", children: [!preview && imageSrc && (_jsx("source", { srcSet: imageSrc, type: medium.mimeType })), _jsx("img", { alt: medium.title, src: imageError || !imageSrc ? FALLBACK_IMAGE_BASE64 : imageSrc, onError: () => setImageError(true) })] }));
83
94
  case 'video/mp4':
84
95
  case 'video/quicktime':
85
96
  case 'video/avi':
86
97
  case 'video/mpeg':
87
- return (_jsxs("video", { style: { width: '100%', height: '100%' }, controls: true, src: url, title: item.title, children: [item.mimeType === 'video/quicktime' && (_jsx("source", { src: item.url, type: "video/mp4" })), _jsx("source", { src: item.url, type: item.mimeType }), "Your browser does not support this video format.", _jsx("br", {}), _jsx("a", { href: item.url, target: "_blank", rel: "noopener noreferrer", children: "Download the video" })] }));
98
+ return (_jsxs("div", { className: "memori-media-item--video-container", children: [_jsxs("video", { className: "memori-media-item--video-player", controls: true, src: url, title: medium.title, children: [medium.mimeType === 'video/quicktime' && (_jsx("source", { src: medium.url, type: "video/mp4" })), _jsx("source", { src: medium.url, type: medium.mimeType }), "Your browser does not support this video format."] }), _jsx("div", { className: "memori-media-item--video-overlay hidden", children: _jsx("svg", { className: "memori-media-item--play-icon", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M8 5v14l11-7z" }) }) })] }));
88
99
  case 'audio/mpeg3':
89
100
  case 'audio/wav':
90
101
  case 'audio/mpeg':
91
- return (_jsx("audio", { style: { width: '100%', height: '100%' }, controls: true, src: url }));
102
+ return (_jsxs("div", { className: "memori-media-item--audio-container", children: [_jsx("div", { className: "memori-media-item--audio-icon", children: _jsx(Sound, {}) }), _jsx("audio", { className: "memori-media-item--audio-player", controls: true, src: url })] }));
92
103
  case 'model/gltf-binary':
93
- return (_jsx(ModelViewer, { src: url, alt: "", poster: "data:image/png;base64,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" }));
104
+ return (_jsx("div", { className: "memori-media-item--model-container", children: _jsx("div", { className: "memori-media-item--model-viewer", children: _jsx(ModelViewer, { src: url, alt: "", poster: "data:image/png;base64,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" }) }) }));
105
+ case 'text/html':
106
+ return (_jsx(DocumentCard, { title: medium.title || 'File', badge: getFileExtensionFromMime(medium.mimeType), meta: (() => {
107
+ const size = getContentSize(medium);
108
+ return size != null && size > 0 ? formatBytes(size) : null;
109
+ })(), icon: _jsx(Link, { className: "memori-media-item--document-icon-svg" }) }));
94
110
  default:
95
- return _jsx(File, { className: "memori-media-item--icon" });
111
+ return (_jsx(DocumentCard, { title: medium.title || 'File', badge: getFileExtensionFromMime(medium.mimeType), meta: (() => {
112
+ const size = getContentSize(medium);
113
+ return size != null && size > 0 ? formatBytes(size) : null;
114
+ })(), icon: _jsx(File, { className: "memori-media-item--document-icon-svg" }) }));
96
115
  }
97
- };
98
- if ((isCodeSnippet && item.content) || isHTML) {
99
- return (_jsxs(_Fragment, { children: [_jsx("a", { className: "memori-media-item--link", href: "#", onClick: e => {
100
- e.preventDefault();
101
- setModalOpen(true);
102
- }, title: item.title, children: _jsx(Card, { hoverable: true, cover: renderMediaContent(item), title: item.title }) }), _jsx(Modal, { open: modalOpen, onClose: () => setModalOpen(false), title: item.title, className: "memori-media-item-preview--modal", width: "80%", widthMd: "90%", children: _jsx("div", { className: "memori-media-item-preview--content", children: _jsx(Snippet, { medium: item, showCopyButton: true }) }) })] }));
103
- }
104
- if (!item.url &&
105
- (item === null || item === void 0 ? void 0 : item.type) === 'document' &&
106
- item.content &&
107
- !['image/jpeg', 'image/png', 'image/jpg', 'image/gif'].includes(item.mimeType)) {
108
- return (_jsxs(_Fragment, { children: [_jsx("a", { className: "memori-media-item--link", href: "#", onClick: e => {
109
- e.preventDefault();
110
- setModalOpen(true);
111
- }, title: item.title, children: _jsx(Card, { hoverable: true, cover: renderMediaContent(item), title: item.title }) }), _jsx(Modal, { open: modalOpen, onClose: () => setModalOpen(false), title: item.title, className: "memori-media-item-preview--modal", width: "60%", widthMd: "70%", footer: _jsx("div", { style: {
112
- display: 'flex',
113
- justifyContent: 'flex-end',
114
- gap: '0.5rem',
115
- }, children: _jsx(Button, { onClick: async () => {
116
- try {
117
- await navigator.clipboard.writeText(item.content || '');
118
- setCopyNotification(true);
119
- setTimeout(() => setCopyNotification(false), 2000);
120
- }
121
- catch (err) {
122
- console.error('Failed to copy content:', err);
123
- }
124
- }, icon: _jsx(Copy, {}), children: copyNotification ? 'Copied!' : 'Copy Content' }) }), children: _jsx("div", { className: "memori-media-item-preview--content", children: _jsx("div", { className: "memori-media-item-preview--text", dangerouslySetInnerHTML: {
125
- __html: stripHTML(item.content || ''),
126
- } }) }) })] }));
127
- }
128
- switch (item.mimeType) {
129
- case 'image/jpeg':
130
- case 'image/png':
131
- case 'image/jpg':
132
- case 'image/gif':
133
- return isImageRGB ? (_jsx(Card, { hoverable: true, className: "memori-media-item--card memori-media-item--image", cover: renderMediaContent(item) })) : (_jsx("a", { className: "memori-media-item--link", href: imageSrc || '#', onClick: e => {
134
- if (isChild) {
116
+ }, [
117
+ sessionID,
118
+ tenantID,
119
+ baseURL,
120
+ apiURL,
121
+ preview,
122
+ imageSrc,
123
+ imageError,
124
+ isImageRGB,
125
+ linkImage,
126
+ linkVideo,
127
+ ]);
128
+ const fileExtensionFromUrl = getFileExtensionFromUrl(normURL || item.url);
129
+ const fileExtensionFromMime = getFileExtensionFromMime(item.mimeType);
130
+ const fileExtension = fileExtensionFromUrl || fileExtensionFromMime;
131
+ const isFile = shouldUseDarkFileCard(item, fileExtensionFromUrl, item.mimeType);
132
+ const isTextFile = TEXT_FILE_EXTENSIONS.includes(fileExtension || '');
133
+ const lineCount = isTextFile && item.content ? countLines(item.content) : null;
134
+ const lineText = lineCount !== null
135
+ ? lineCount === 1
136
+ ? '1 line'
137
+ : `${lineCount} lines`
138
+ : null;
139
+ if (isFile && !isCodeSnippet) {
140
+ const contentSize = getContentSize(item);
141
+ const sizeText = contentSize != null && contentSize > 0 ? formatBytes(contentSize) : null;
142
+ const displayName = item.title || linkTitle || 'File';
143
+ const metaParts = [lineText, sizeText].filter(Boolean);
144
+ const metaLine = metaParts.length > 0 ? metaParts.join(' · ') : null;
145
+ if ((isDocumentAttachment || isAttachedFile) && item.mediumID && _onClick) {
146
+ return (_jsx("div", { onClick: () => _onClick(item), className: "memori-media-item--link memori-media-item--document-link", style: { cursor: 'pointer' }, title: displayName, role: "button", tabIndex: 0, onKeyDown: e => {
147
+ if (e.key === 'Enter' || e.key === ' ') {
135
148
  e.preventDefault();
149
+ _onClick(item);
136
150
  }
137
- if (onClick) {
138
- e.preventDefault();
139
- onClick(item.mediumID);
151
+ }, children: _jsx(DocumentCard, { title: displayName, badge: item.mimeType === 'text/html' && !!item.url
152
+ ? 'Link'
153
+ : fileExtension, meta: metaLine, icon: item.mimeType === 'text/html' ? (_jsx(Link, { className: "memori-media-item--document-icon-svg" })) : (_jsx(File, { className: "memori-media-item--document-icon-svg" })) }) }));
154
+ }
155
+ const getFileCardHref = () => {
156
+ var _a;
157
+ if (item.url) {
158
+ return (getResourceUrl({
159
+ resourceURI: item.url,
160
+ sessionID,
161
+ tenantID,
162
+ baseURL,
163
+ apiURL,
164
+ }) ||
165
+ item.url ||
166
+ '#');
167
+ }
168
+ if (isHTML && item.content) {
169
+ let htmlContent = item.content;
170
+ if (((_a = item.properties) === null || _a === void 0 ? void 0 : _a.isDocumentAttachment) ||
171
+ htmlContent.includes('document_attachment') ||
172
+ htmlContent.includes('<document_attachment')) {
173
+ if (htmlContent.includes('&lt;') || htmlContent.includes('&quot;')) {
174
+ const div = document.createElement('div');
175
+ div.innerHTML = htmlContent;
176
+ htmlContent = div.textContent || div.innerText || htmlContent;
140
177
  }
141
- if (!imageSrc || imageError) {
178
+ htmlContent = stripDocumentAttachmentTags(htmlContent);
179
+ }
180
+ const blob = new Blob([htmlContent], { type: 'text/html' });
181
+ return URL.createObjectURL(blob);
182
+ }
183
+ if (item.content) {
184
+ const blob = new Blob([item.content], {
185
+ type: item.mimeType || 'text/plain',
186
+ });
187
+ return URL.createObjectURL(blob);
188
+ }
189
+ return '#';
190
+ };
191
+ const hrefUrl = getFileCardHref();
192
+ return (_jsx("a", { href: hrefUrl, target: "_blank", rel: "noopener noreferrer", className: "memori-media-item--link memori-media-item--document-link", title: displayName, children: _jsx(DocumentCard, { title: displayName, badge: item.mimeType === 'text/html' && !!item.url ? 'Link' : fileExtension, meta: metaLine, icon: item.mimeType === 'text/html' ? (_jsx(Link, { className: "memori-media-item--document-icon-svg" })) : (_jsx(File, { className: "memori-media-item--document-icon-svg" })) }) }));
193
+ }
194
+ if (isCodeSnippet && item.content && item.mediumID && _onClick) {
195
+ return (_jsx("div", { className: "memori-media-item--link", style: { cursor: 'pointer' }, onClick: () => _onClick(item), title: item.title, role: "button", tabIndex: 0, onKeyDown: e => {
196
+ if (e.key === 'Enter' || e.key === ' ') {
197
+ e.preventDefault();
198
+ _onClick(item);
199
+ }
200
+ }, children: _jsx(Card, { hoverable: true, cover: renderMediaContent(item), title: item.title }) }));
201
+ }
202
+ if (isHTML && (linkImage || linkVideo || linkDescription)) {
203
+ const coverSrc = (linkImage === null || linkImage === void 0 ? void 0 : linkImage.includes('data:image')) === true
204
+ ? undefined
205
+ : (linkImage === null || linkImage === void 0 ? void 0 : linkImage.startsWith('https'))
206
+ ? linkImage
207
+ : linkImage
208
+ ? `https://${linkImage.replace('http://', '')}`
209
+ : undefined;
210
+ return (_jsx("a", { href: item.url || '#', target: "_blank", rel: "noopener noreferrer", className: "memori-media-item--link", title: linkTitle, children: _jsx(Card, { hoverable: true, className: cx('memori-media-item--card', {
211
+ 'memori-media-item--card-description-oneline': descriptionOneLine,
212
+ 'memori-media-item--card-has-image': !!linkImage,
213
+ 'memori-media-item--card-has-video': !!linkVideo,
214
+ }), cover: linkVideo ? (_jsx("iframe", { width: "100%", height: "100%", src: linkVideo, title: "Video player", frameBorder: "0", allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", allowFullScreen: true })) : linkImage ? (_jsx("img", { className: "memori-media-item--card-cover-img", src: coverSrc, alt: linkTitle })) : (_jsx("div", { className: "memori-media-item--card-cover-icon", children: _jsx(Link, { className: "memori-media-item--icon" }) })), title: linkTitle, description: linkDescription }) }));
215
+ }
216
+ useEffect(() => {
217
+ if (!linkDescription)
218
+ return;
219
+ const t = setTimeout(() => {
220
+ ellipsis('.memori-media-item--card .memori-card--description', 3, {
221
+ responsive: true,
222
+ });
223
+ }, 300);
224
+ return () => clearTimeout(t);
225
+ }, [linkDescription, item.mediumID]);
226
+ if (isImageMime(item.mimeType)) {
227
+ if (isImageRGB) {
228
+ return (_jsx(Card, { hoverable: true, className: "memori-media-item--card memori-media-item--image", cover: renderMediaContent(item) }));
229
+ }
230
+ if (item.mediumID && _onClick) {
231
+ return (_jsx("div", { onClick: () => _onClick(item), className: "memori-media-item--link memori-media-item--image-link", style: { cursor: 'pointer' }, title: item.title, role: "button", tabIndex: 0, onKeyDown: e => {
232
+ if (e.key === 'Enter' || e.key === ' ') {
142
233
  e.preventDefault();
234
+ _onClick(item);
143
235
  }
144
- }, target: "_blank", rel: "noopener noreferrer", title: item.title, children: _jsx(Card, { hoverable: true, className: "memori-media-item--card memori-media-item--image", cover: renderMediaContent(item) }) }));
145
- case 'application/msword':
146
- case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
147
- case 'application/vnd.ms-excel':
148
- case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
149
- case 'application/pdf':
150
- return (_jsx("a", { className: "memori-media-item--link", href: url, target: "_blank", rel: "noopener noreferrer", title: item.title, children: _jsx(Card, { hoverable: true, cover: renderMediaContent(item), title: item.title }) }));
236
+ }, children: _jsx(Card, { hoverable: true, className: "memori-media-item--card memori-media-item--image", cover: renderMediaContent(item) }) }));
237
+ }
238
+ return (_jsx(Card, { hoverable: true, className: "memori-media-item--card memori-media-item--image", cover: renderMediaContent(item) }));
239
+ }
240
+ switch (item.mimeType) {
151
241
  case 'video/mp4':
152
242
  case 'video/quicktime':
153
243
  case 'video/avi':
154
244
  case 'video/mpeg':
155
- return (_jsx("a", { className: "memori-media-item--link", href: url, onClick: e => {
156
- if (isChild) {
157
- e.preventDefault();
158
- }
159
- if (onClick) {
160
- e.preventDefault();
161
- onClick(item.mediumID);
162
- }
163
- }, target: "_blank", rel: "noopener noreferrer", title: item.title, children: _jsx(Card, { hoverable: true, cover: renderMediaContent(item), title: item.title }) }));
245
+ return (_jsx("a", { className: "memori-media-item--link", href: resourceUrl || '#', target: "_blank", rel: "noopener noreferrer", title: item.title, children: renderMediaContent(item) }));
164
246
  case 'audio/mpeg3':
165
247
  case 'audio/wav':
166
248
  case 'audio/mpeg':
167
- return (_jsx("a", { className: "memori-media-item--link", href: url, target: "_blank", rel: "noopener noreferrer", title: item.title, children: _jsx(Card, { hoverable: true, cover: renderMediaContent(item), title: item.title }) }));
168
249
  case 'model/gltf-binary':
169
- return _jsx(Card, { hoverable: true, cover: renderMediaContent(item) });
250
+ if (resourceUrl) {
251
+ return (_jsx("a", { className: "memori-media-item--link", href: resourceUrl, target: "_blank", rel: "noopener noreferrer", title: item.title, children: renderMediaContent(item) }));
252
+ }
253
+ return renderMediaContent(item);
170
254
  default:
171
- return (_jsx("a", { className: "memori-media-item--link", href: url, target: "_blank", rel: "noopener noreferrer", title: item.title, children: _jsx(Card, { hoverable: true, cover: renderMediaContent(item), title: item.title }) }));
255
+ return (_jsx("a", { className: "memori-media-item--link", href: resourceUrl || '#', target: "_blank", rel: "noopener noreferrer", title: item.title, children: renderMediaContent(item) }));
172
256
  }
173
- };
174
- const countLines = (content) => {
175
- if (!content)
176
- return 0;
177
- return content.split(/\r\n|\r|\n/).length;
178
- };
179
- export const RenderSnippetItem = ({ item, sessionID: _sessionID, tenantID: _tenantID, baseURL: _baseURL, apiURL: _apiURL, onClick, }) => {
257
+ });
258
+ export const RenderSnippetItem = memo(function RenderSnippetItem({ item, onClick: _onClick, sessionID, tenantID, baseURL, apiURL, }) {
180
259
  var _a, _b;
260
+ void _onClick;
261
+ const resourceUrl = getResourceUrl({
262
+ resourceURI: item.url,
263
+ sessionID,
264
+ tenantID,
265
+ baseURL,
266
+ apiURL,
267
+ });
268
+ const hasUrl = !!(resourceUrl && resourceUrl !== '#');
181
269
  const lineCount = countLines(item.content);
182
270
  const contentLength = (_b = (_a = item.content) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
183
271
  const isShortSnippet = lineCount <= 5 && contentLength <= 200;
272
+ const lineText = lineCount === 1 ? '1 riga' : `${lineCount} righe`;
184
273
  if (isShortSnippet) {
185
- return (_jsx("div", { className: "memori-media-item--snippet-direct", children: _jsx(Card, { className: "memori-media-item--card memori-media-item--snippet", children: _jsx("div", { className: "memori-media-item--snippet-preview", children: _jsx(Snippet, { showCopyButton: true, preview: false, medium: item }) }) }) }));
274
+ return (_jsx("div", { className: "memori-media-item--snippet-direct", children: _jsx(Card, { className: "memori-media-item--card memori-media-item--snippet", children: _jsxs("div", { className: "memori-media-item--snippet-body", children: [_jsx("div", { className: "memori-media-item--snippet-title", children: item.title }), _jsx("div", { className: "memori-media-item--snippet-preview", children: _jsx(Snippet, { showCopyButton: true, preview: false, medium: item }) }), _jsx("div", { className: "memori-media-item--snippet-header", children: _jsx("span", { className: "memori-media-item--snippet-meta", children: lineText }) })] }) }) }));
186
275
  }
187
- return (_jsx(_Fragment, { children: _jsx("a", { href: "#", onClick: e => {
276
+ const snippetHref = hasUrl
277
+ ? resourceUrl
278
+ : item.content
279
+ ? (() => {
280
+ const blob = new Blob([item.content], {
281
+ type: item.mimeType || 'text/plain',
282
+ });
283
+ return URL.createObjectURL(blob);
284
+ })()
285
+ : '#';
286
+ return (_jsx("div", { onClick: () => {
287
+ if (item.mediumID && _onClick) {
288
+ _onClick(item);
289
+ }
290
+ }, style: { cursor: 'pointer' }, role: "button", tabIndex: 0, onKeyDown: e => {
291
+ if (e.key === 'Enter' || e.key === ' ') {
188
292
  e.preventDefault();
189
- if (onClick) {
190
- onClick(item.mediumID);
293
+ if (item.mediumID && _onClick) {
294
+ _onClick(item);
191
295
  }
192
- }, className: "memori-media-item--link", title: item.title, children: _jsx(Card, { hoverable: true, className: "memori-media-item--card memori-media-item--snippet", children: _jsx("div", { className: "memori-media-item--snippet-preview", children: _jsx(Snippet, { showCopyButton: false, preview: true, medium: item }) }) }) }) }));
193
- };
194
- const MediaItemWidget = ({ items, sessionID, tenantID, translateTo, baseURL, apiURL, customMediaRenderer, fromUser = false, }) => {
296
+ }
297
+ }, className: "memori-media-item--link", title: item.title, children: _jsx(Card, { hoverable: true, className: "memori-media-item--card memori-media-item--snippet", children: _jsxs("div", { className: "memori-media-item--snippet-body", children: [_jsx("div", { className: "memori-media-item--snippet-title", children: item.title }), _jsx("div", { className: "memori-media-item--snippet-preview", children: _jsx(Snippet, { showCopyButton: false, preview: true, medium: item }) }), _jsx("div", { className: "memori-media-item--snippet-header", children: _jsx("span", { className: "memori-media-item--snippet-meta", children: lineText }) })] }) }) }));
298
+ });
299
+ const MediaItemWidget = ({ items, sessionID, tenantID, translateTo, baseURL, apiURL, customMediaRenderer, fromUser = false, descriptionOneLine = false, onLinkPreviewInfo, }) => {
195
300
  const [media, setMedia] = useState(items);
196
301
  const [openModalMedium, setOpenModalMedium] = useState();
197
302
  useEffect(() => {
@@ -200,82 +305,76 @@ const MediaItemWidget = ({ items, sessionID, tenantID, translateTo, baseURL, api
200
305
  const translateMediaCaptions = useCallback(async () => {
201
306
  if (!translateTo)
202
307
  return;
203
- const translatedMedia = await Promise.all((items !== null && items !== void 0 ? items : []).map(async (media) => {
308
+ const translated = await Promise.all((items !== null && items !== void 0 ? items : []).map(async (m) => {
204
309
  var _a;
205
- if (media.title) {
206
- try {
207
- const tTitle = await getTranslation(media.title, translateTo);
208
- return { ...media, title: (_a = tTitle.text) !== null && _a !== void 0 ? _a : media.title };
209
- }
210
- catch (e) {
211
- console.error(e);
212
- return media;
213
- }
310
+ if (!m.title)
311
+ return m;
312
+ try {
313
+ const t = await getTranslation(m.title, translateTo);
314
+ return { ...m, title: (_a = t.text) !== null && _a !== void 0 ? _a : m.title };
214
315
  }
215
- else {
216
- return media;
316
+ catch (e) {
317
+ console.error(e);
318
+ return m;
217
319
  }
218
320
  }));
219
- setMedia(translatedMedia);
321
+ setMedia(translated);
220
322
  }, [translateTo, items]);
221
323
  useEffect(() => {
222
324
  if (translateTo)
223
325
  translateMediaCaptions();
224
326
  }, [translateTo, translateMediaCaptions]);
225
- const nonCodeDisplayMedia = media
226
- .filter(m => {
227
- var _a;
228
- return !((_a = m.properties) === null || _a === void 0 ? void 0 : _a.executable) &&
229
- !prismSyntaxLangs.map(l => l.mimeType).includes(m.mimeType);
230
- })
327
+ const nonCodeDisplayMedia = useMemo(() => media
328
+ .filter(m => { var _a; return !((_a = m.properties) === null || _a === void 0 ? void 0 : _a.executable) && !CODE_MIME_TYPES.includes(m.mimeType); })
231
329
  .sort((a, b) => {
232
- return a.creationTimestamp > b.creationTimestamp
233
- ? 1
234
- : a.creationTimestamp < b.creationTimestamp
235
- ? -1
236
- : 0;
237
- });
238
- const codeSnippets = media.filter(m => {
239
- var _a;
240
- return !((_a = m.properties) === null || _a === void 0 ? void 0 : _a.executable) &&
241
- prismSyntaxLangs.map(l => l.mimeType).includes(m.mimeType);
242
- });
243
- const cssExecutableCode = media.filter(m => { var _a; return m.mimeType === 'text/css' && !!((_a = m.properties) === null || _a === void 0 ? void 0 : _a.executable); });
244
- return (_jsxs(Transition, { appear: true, show: true, as: "div", className: "memori-media-items", children: [!!nonCodeDisplayMedia.length && (_jsx("div", { className: cx('memori-media-items--grid memori-chat-scroll-item', {
330
+ var _a, _b;
331
+ const at = (_a = a.creationTimestamp) !== null && _a !== void 0 ? _a : 0;
332
+ const bt = (_b = b.creationTimestamp) !== null && _b !== void 0 ? _b : 0;
333
+ return at > bt ? 1 : at < bt ? -1 : 0;
334
+ }), [media]);
335
+ const codeSnippets = useMemo(() => media.filter(m => { var _a; return !((_a = m.properties) === null || _a === void 0 ? void 0 : _a.executable) && CODE_MIME_TYPES.includes(m.mimeType); }), [media]);
336
+ const cssExecutableCode = useMemo(() => media.filter(m => { var _a; return m.mimeType === 'text/css' && !!((_a = m.properties) === null || _a === void 0 ? void 0 : _a.executable); }), [media]);
337
+ const imageCount = useMemo(() => nonCodeDisplayMedia.filter(m => IMAGE_MIME_TYPES.includes(m.mimeType)).length, [nonCodeDisplayMedia]);
338
+ const handleMediaItemClick = useCallback((item) => {
339
+ setOpenModalMedium(item);
340
+ }, []);
341
+ const handleSnippetClick = useCallback((item) => {
342
+ setOpenModalMedium(item);
343
+ }, []);
344
+ const handleCloseModal = useCallback(() => {
345
+ setOpenModalMedium(undefined);
346
+ }, []);
347
+ const handleModalNavigate = useCallback((mediumID) => {
348
+ setOpenModalMedium(media.find(m => m.mediumID === mediumID));
349
+ }, [media]);
350
+ return (_jsxs(Transition, { appear: true, show: true, as: "div", className: "memori-media-items", children: [nonCodeDisplayMedia.length > 0 && (_jsx("div", { className: cx('memori-media-items--grid memori-chat-scroll-item', {
245
351
  'memori-media-items--user': fromUser,
246
352
  'memori-media-items--agent': !fromUser,
247
- }), children: nonCodeDisplayMedia.map((item, index) => (_jsx(Transition.Child, { as: "div", className: "memori-media-item", enter: `ease-out duration-500 delay-${index * 100}`, enterFrom: "opacity-0 scale-95", enterTo: "opacity-1 scale-100", leave: "ease-in duration-300", leaveFrom: "opacity-1 scale-100", leaveTo: "opacity-0 scale-95", children: _jsx(RenderMediaItem, { isChild: true, sessionID: sessionID, tenantID: tenantID, baseURL: baseURL, apiURL: apiURL, onClick: mediumID => {
248
- setOpenModalMedium(nonCodeDisplayMedia.find(m => m.mediumID === mediumID));
249
- }, item: {
250
- ...item,
251
- title: item.title,
252
- url: item.url,
253
- content: item.content,
254
- type: 'document',
255
- }, customMediaRenderer: customMediaRenderer }) }, item.url + '&index=' + index))) })), !!codeSnippets.length && (_jsx("div", { className: cx('memori-media-items--grid memori-chat-scroll-item', {
353
+ 'memori-media-items--single': imageCount === 1,
354
+ 'memori-media-items--few': imageCount >= 2 && imageCount <= 4,
355
+ 'memori-media-items--many': imageCount >= 5,
356
+ }), children: nonCodeDisplayMedia.map((item, index) => {
357
+ var _a, _b;
358
+ return (_jsx(Transition.Child, { as: "div", className: "memori-media-item", enter: `ease-out duration-500 delay-${index * 100}`, enterFrom: "opacity-0 scale-95", enterTo: "opacity-1 scale-100", leave: "ease-in duration-300", leaveFrom: "opacity-1 scale-100", leaveTo: "opacity-0 scale-95", children: _jsx(RenderMediaItem, { isChild: true, sessionID: sessionID, tenantID: tenantID, baseURL: baseURL, apiURL: apiURL, onClick: handleMediaItemClick, item: {
359
+ ...item,
360
+ title: item.title,
361
+ url: item.url,
362
+ content: item.content,
363
+ type: 'document',
364
+ }, customMediaRenderer: customMediaRenderer, descriptionOneLine: descriptionOneLine, onLinkPreviewInfo: onLinkPreviewInfo }) }, `media-${index}-${(_b = (_a = item.mediumID) !== null && _a !== void 0 ? _a : item.url) !== null && _b !== void 0 ? _b : 'n'}`));
365
+ }) })), codeSnippets.length > 0 && (_jsx("div", { className: cx('memori-media-items--grid memori-chat-scroll-item', {
256
366
  'memori-media-items--user': fromUser,
257
367
  'memori-media-items--agent': !fromUser,
258
- }), children: codeSnippets.map((item, index) => (_jsx(Transition.Child, { as: "div", className: "memori-media-item", enter: `ease-out duration-500 delay-${index * 100}`, enterFrom: "opacity-0 scale-95", enterTo: "opacity-1 scale-100", leave: "ease-in duration-300", leaveFrom: "opacity-1 scale-100", leaveTo: "opacity-0 scale-95", children: _jsx(RenderSnippetItem, { sessionID: sessionID, tenantID: tenantID, baseURL: baseURL, apiURL: apiURL, onClick: mediumID => {
259
- const foundMedium = codeSnippets.find(m => m.mediumID === mediumID);
260
- setOpenModalMedium(foundMedium);
261
- }, item: {
262
- ...item,
263
- title: item.title,
264
- url: item.url,
265
- content: item.content,
266
- type: 'document',
267
- } }) }, item.mediumID + '&index=' + index))) })), cssExecutableCode.map(medium => (_jsx("style", { dangerouslySetInnerHTML: { __html: medium.content || '' } }, medium.mediumID))), openModalMedium && (_jsx(Modal, { width: "100%", widthMd: "100%", className: "memori-media-item--modal", open: !!openModalMedium, onClose: () => setOpenModalMedium(undefined), footer: null, children: prismSyntaxLangs
268
- .map(l => l.mimeType)
269
- .includes(openModalMedium.mimeType) ? (_jsx("div", { style: {
270
- minHeight: '100%',
271
- background: 'none',
272
- }, className: "memori-media-item-preview--content", children: _jsx(Snippet, { preview: false, medium: openModalMedium }) })) : (_jsx(RenderMediaItem, { isChild: true, sessionID: sessionID, tenantID: tenantID, baseURL: baseURL, apiURL: apiURL, item: {
273
- ...openModalMedium,
274
- title: openModalMedium.title,
275
- url: openModalMedium.url,
276
- content: openModalMedium.content,
277
- type: 'document',
278
- }, customMediaRenderer: customMediaRenderer })) }))] }));
368
+ }), children: codeSnippets.map((item, index) => {
369
+ var _a, _b;
370
+ return (_jsx(Transition.Child, { as: "div", className: "memori-media-item", enter: `ease-out duration-500 delay-${index * 100}`, enterFrom: "opacity-0 scale-95", enterTo: "opacity-1 scale-100", leave: "ease-in duration-300", leaveFrom: "opacity-1 scale-100", leaveTo: "opacity-0 scale-95", children: _jsx(RenderSnippetItem, { sessionID: sessionID, tenantID: tenantID, baseURL: baseURL, apiURL: apiURL, onClick: handleSnippetClick, item: {
371
+ ...item,
372
+ title: item.title,
373
+ url: item.url,
374
+ content: item.content,
375
+ type: 'document',
376
+ } }) }, `snippet-${index}-${(_b = (_a = item.mediumID) !== null && _a !== void 0 ? _a : item.url) !== null && _b !== void 0 ? _b : 'n'}`));
377
+ }) })), cssExecutableCode.map(m => (_jsx("style", { dangerouslySetInnerHTML: { __html: m.content || '' } }, m.mediumID))), openModalMedium && (_jsx(MediaPreviewModal, { medium: openModalMedium, onClose: handleCloseModal, sessionID: sessionID, tenantID: tenantID, baseURL: baseURL, apiURL: apiURL, customMediaRenderer: customMediaRenderer, descriptionOneLine: descriptionOneLine, onLinkPreviewInfo: onLinkPreviewInfo, onMediumClick: handleModalNavigate }))] }));
279
378
  };
280
379
  export default memo(MediaItemWidget);
281
380
  //# sourceMappingURL=MediaItemWidget.js.map