@liveblocks/react-ui 2.14.0 → 2.15.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 (272) hide show
  1. package/dist/_private/index.d.mts +24 -22
  2. package/dist/_private/index.d.ts +24 -22
  3. package/dist/_private/index.js +1 -0
  4. package/dist/_private/index.js.map +1 -1
  5. package/dist/_private/index.mjs +1 -0
  6. package/dist/_private/index.mjs.map +1 -1
  7. package/dist/components/Comment.js +358 -256
  8. package/dist/components/Comment.js.map +1 -1
  9. package/dist/components/Comment.mjs +334 -232
  10. package/dist/components/Comment.mjs.map +1 -1
  11. package/dist/components/Composer.js +308 -225
  12. package/dist/components/Composer.js.map +1 -1
  13. package/dist/components/Composer.mjs +288 -206
  14. package/dist/components/Composer.mjs.map +1 -1
  15. package/dist/components/HistoryVersionSummary.js +28 -32
  16. package/dist/components/HistoryVersionSummary.js.map +1 -1
  17. package/dist/components/HistoryVersionSummary.mjs +27 -31
  18. package/dist/components/HistoryVersionSummary.mjs.map +1 -1
  19. package/dist/components/HistoryVersionSummaryList.js +11 -9
  20. package/dist/components/HistoryVersionSummaryList.js.map +1 -1
  21. package/dist/components/HistoryVersionSummaryList.mjs +10 -8
  22. package/dist/components/HistoryVersionSummaryList.mjs.map +1 -1
  23. package/dist/components/InboxNotification.js +202 -143
  24. package/dist/components/InboxNotification.js.map +1 -1
  25. package/dist/components/InboxNotification.mjs +180 -121
  26. package/dist/components/InboxNotification.mjs.map +1 -1
  27. package/dist/components/InboxNotificationList.js +19 -14
  28. package/dist/components/InboxNotificationList.js.map +1 -1
  29. package/dist/components/InboxNotificationList.mjs +17 -12
  30. package/dist/components/InboxNotificationList.mjs.map +1 -1
  31. package/dist/components/Thread.js +104 -86
  32. package/dist/components/Thread.js.map +1 -1
  33. package/dist/components/Thread.mjs +93 -75
  34. package/dist/components/Thread.mjs.map +1 -1
  35. package/dist/components/internal/Attachment.js +161 -113
  36. package/dist/components/internal/Attachment.js.map +1 -1
  37. package/dist/components/internal/Attachment.mjs +150 -102
  38. package/dist/components/internal/Attachment.mjs.map +1 -1
  39. package/dist/components/internal/Attribution.js +15 -13
  40. package/dist/components/internal/Attribution.js.map +1 -1
  41. package/dist/components/internal/Attribution.mjs +15 -13
  42. package/dist/components/internal/Attribution.mjs.map +1 -1
  43. package/dist/components/internal/Avatar.js +27 -20
  44. package/dist/components/internal/Avatar.js.map +1 -1
  45. package/dist/components/internal/Avatar.mjs +23 -16
  46. package/dist/components/internal/Avatar.mjs.map +1 -1
  47. package/dist/components/internal/Button.js +5 -4
  48. package/dist/components/internal/Button.js.map +1 -1
  49. package/dist/components/internal/Button.mjs +4 -3
  50. package/dist/components/internal/Button.mjs.map +1 -1
  51. package/dist/components/internal/Dropdown.js +27 -19
  52. package/dist/components/internal/Dropdown.js.map +1 -1
  53. package/dist/components/internal/Dropdown.mjs +26 -18
  54. package/dist/components/internal/Dropdown.mjs.map +1 -1
  55. package/dist/components/internal/Emoji.js +4 -3
  56. package/dist/components/internal/Emoji.js.map +1 -1
  57. package/dist/components/internal/Emoji.mjs +3 -2
  58. package/dist/components/internal/Emoji.mjs.map +1 -1
  59. package/dist/components/internal/EmojiPicker.js +96 -72
  60. package/dist/components/internal/EmojiPicker.js.map +1 -1
  61. package/dist/components/internal/EmojiPicker.mjs +90 -66
  62. package/dist/components/internal/EmojiPicker.mjs.map +1 -1
  63. package/dist/components/internal/Icon.js +5 -4
  64. package/dist/components/internal/Icon.js.map +1 -1
  65. package/dist/components/internal/Icon.mjs +5 -4
  66. package/dist/components/internal/Icon.mjs.map +1 -1
  67. package/dist/components/internal/InboxNotificationThread.js +53 -38
  68. package/dist/components/internal/InboxNotificationThread.js.map +1 -1
  69. package/dist/components/internal/InboxNotificationThread.mjs +53 -38
  70. package/dist/components/internal/InboxNotificationThread.mjs.map +1 -1
  71. package/dist/components/internal/List.js +8 -6
  72. package/dist/components/internal/List.js.map +1 -1
  73. package/dist/components/internal/List.mjs +6 -4
  74. package/dist/components/internal/List.mjs.map +1 -1
  75. package/dist/components/internal/Room.js +8 -6
  76. package/dist/components/internal/Room.js.map +1 -1
  77. package/dist/components/internal/Room.mjs +7 -5
  78. package/dist/components/internal/Room.mjs.map +1 -1
  79. package/dist/components/internal/Tooltip.js +49 -33
  80. package/dist/components/internal/Tooltip.js.map +1 -1
  81. package/dist/components/internal/Tooltip.mjs +46 -30
  82. package/dist/components/internal/Tooltip.mjs.map +1 -1
  83. package/dist/components/internal/User.js +8 -6
  84. package/dist/components/internal/User.js.map +1 -1
  85. package/dist/components/internal/User.mjs +7 -5
  86. package/dist/components/internal/User.mjs.map +1 -1
  87. package/dist/components.js +12 -29
  88. package/dist/components.js.map +1 -1
  89. package/dist/components.mjs +6 -5
  90. package/dist/components.mjs.map +1 -1
  91. package/dist/config.js +16 -12
  92. package/dist/config.js.map +1 -1
  93. package/dist/config.mjs +13 -9
  94. package/dist/config.mjs.map +1 -1
  95. package/dist/icons/ArrowDown.js +7 -6
  96. package/dist/icons/ArrowDown.js.map +1 -1
  97. package/dist/icons/ArrowDown.mjs +7 -6
  98. package/dist/icons/ArrowDown.mjs.map +1 -1
  99. package/dist/icons/ArrowUp.js +7 -6
  100. package/dist/icons/ArrowUp.js.map +1 -1
  101. package/dist/icons/ArrowUp.mjs +7 -6
  102. package/dist/icons/ArrowUp.mjs.map +1 -1
  103. package/dist/icons/Attachment.js +7 -6
  104. package/dist/icons/Attachment.js.map +1 -1
  105. package/dist/icons/Attachment.mjs +7 -6
  106. package/dist/icons/Attachment.mjs.map +1 -1
  107. package/dist/icons/Bold.js +7 -6
  108. package/dist/icons/Bold.js.map +1 -1
  109. package/dist/icons/Bold.mjs +7 -6
  110. package/dist/icons/Bold.mjs.map +1 -1
  111. package/dist/icons/Check.js +7 -6
  112. package/dist/icons/Check.js.map +1 -1
  113. package/dist/icons/Check.mjs +7 -6
  114. package/dist/icons/Check.mjs.map +1 -1
  115. package/dist/icons/Code.js +7 -6
  116. package/dist/icons/Code.js.map +1 -1
  117. package/dist/icons/Code.mjs +7 -6
  118. package/dist/icons/Code.mjs.map +1 -1
  119. package/dist/icons/Cross.js +12 -8
  120. package/dist/icons/Cross.js.map +1 -1
  121. package/dist/icons/Cross.mjs +12 -8
  122. package/dist/icons/Cross.mjs.map +1 -1
  123. package/dist/icons/Delete.js +7 -6
  124. package/dist/icons/Delete.js.map +1 -1
  125. package/dist/icons/Delete.mjs +7 -6
  126. package/dist/icons/Delete.mjs.map +1 -1
  127. package/dist/icons/Edit.js +7 -6
  128. package/dist/icons/Edit.js.map +1 -1
  129. package/dist/icons/Edit.mjs +7 -6
  130. package/dist/icons/Edit.mjs.map +1 -1
  131. package/dist/icons/Ellipsis.js +21 -16
  132. package/dist/icons/Ellipsis.js.map +1 -1
  133. package/dist/icons/Ellipsis.mjs +21 -16
  134. package/dist/icons/Ellipsis.mjs.map +1 -1
  135. package/dist/icons/Emoji.js +25 -18
  136. package/dist/icons/Emoji.js.map +1 -1
  137. package/dist/icons/Emoji.mjs +25 -18
  138. package/dist/icons/Emoji.mjs.map +1 -1
  139. package/dist/icons/EmojiAdd.js +28 -20
  140. package/dist/icons/EmojiAdd.js.map +1 -1
  141. package/dist/icons/EmojiAdd.mjs +28 -20
  142. package/dist/icons/EmojiAdd.mjs.map +1 -1
  143. package/dist/icons/Italic.js +7 -6
  144. package/dist/icons/Italic.js.map +1 -1
  145. package/dist/icons/Italic.mjs +7 -6
  146. package/dist/icons/Italic.mjs.map +1 -1
  147. package/dist/icons/Mention.js +12 -8
  148. package/dist/icons/Mention.js.map +1 -1
  149. package/dist/icons/Mention.mjs +12 -8
  150. package/dist/icons/Mention.mjs.map +1 -1
  151. package/dist/icons/Resolve.js +14 -10
  152. package/dist/icons/Resolve.js.map +1 -1
  153. package/dist/icons/Resolve.mjs +14 -10
  154. package/dist/icons/Resolve.mjs.map +1 -1
  155. package/dist/icons/Resolved.js +16 -12
  156. package/dist/icons/Resolved.js.map +1 -1
  157. package/dist/icons/Resolved.mjs +16 -12
  158. package/dist/icons/Resolved.mjs.map +1 -1
  159. package/dist/icons/Restore.js +12 -8
  160. package/dist/icons/Restore.js.map +1 -1
  161. package/dist/icons/Restore.mjs +12 -8
  162. package/dist/icons/Restore.mjs.map +1 -1
  163. package/dist/icons/Search.js +7 -6
  164. package/dist/icons/Search.js.map +1 -1
  165. package/dist/icons/Search.mjs +7 -6
  166. package/dist/icons/Search.mjs.map +1 -1
  167. package/dist/icons/Send.js +7 -6
  168. package/dist/icons/Send.js.map +1 -1
  169. package/dist/icons/Send.mjs +7 -6
  170. package/dist/icons/Send.mjs.map +1 -1
  171. package/dist/icons/Spinner.js +8 -7
  172. package/dist/icons/Spinner.js.map +1 -1
  173. package/dist/icons/Spinner.mjs +8 -7
  174. package/dist/icons/Spinner.mjs.map +1 -1
  175. package/dist/icons/Strikethrough.js +7 -6
  176. package/dist/icons/Strikethrough.js.map +1 -1
  177. package/dist/icons/Strikethrough.mjs +7 -6
  178. package/dist/icons/Strikethrough.mjs.map +1 -1
  179. package/dist/icons/Warning.js +14 -10
  180. package/dist/icons/Warning.js.map +1 -1
  181. package/dist/icons/Warning.mjs +14 -10
  182. package/dist/icons/Warning.mjs.map +1 -1
  183. package/dist/icons/index.js +42 -0
  184. package/dist/icons/index.js.map +1 -0
  185. package/dist/icons/index.mjs +19 -0
  186. package/dist/icons/index.mjs.map +1 -0
  187. package/dist/index.d.mts +14 -12
  188. package/dist/index.d.ts +14 -12
  189. package/dist/overrides.js +65 -36
  190. package/dist/overrides.js.map +1 -1
  191. package/dist/overrides.mjs +59 -12
  192. package/dist/overrides.mjs.map +1 -1
  193. package/dist/primitives/Comment/index.js +75 -66
  194. package/dist/primitives/Comment/index.js.map +1 -1
  195. package/dist/primitives/Comment/index.mjs +71 -62
  196. package/dist/primitives/Comment/index.mjs.map +1 -1
  197. package/dist/primitives/Composer/contexts.js +11 -11
  198. package/dist/primitives/Composer/index.js +343 -284
  199. package/dist/primitives/Composer/index.js.map +1 -1
  200. package/dist/primitives/Composer/index.mjs +262 -203
  201. package/dist/primitives/Composer/index.mjs.map +1 -1
  202. package/dist/primitives/Composer/utils.js +20 -21
  203. package/dist/primitives/Composer/utils.js.map +1 -1
  204. package/dist/primitives/Composer/utils.mjs +4 -5
  205. package/dist/primitives/Composer/utils.mjs.map +1 -1
  206. package/dist/primitives/EmojiPicker/contexts.js +3 -3
  207. package/dist/primitives/EmojiPicker/index.js +160 -142
  208. package/dist/primitives/EmojiPicker/index.js.map +1 -1
  209. package/dist/primitives/EmojiPicker/index.mjs +122 -104
  210. package/dist/primitives/EmojiPicker/index.mjs.map +1 -1
  211. package/dist/primitives/FileSize.js +9 -7
  212. package/dist/primitives/FileSize.js.map +1 -1
  213. package/dist/primitives/FileSize.mjs +7 -5
  214. package/dist/primitives/FileSize.mjs.map +1 -1
  215. package/dist/primitives/Timestamp.js +12 -10
  216. package/dist/primitives/Timestamp.js.map +1 -1
  217. package/dist/primitives/Timestamp.mjs +7 -5
  218. package/dist/primitives/Timestamp.mjs.map +1 -1
  219. package/dist/primitives/index.d.mts +24 -23
  220. package/dist/primitives/index.d.ts +24 -23
  221. package/dist/primitives/internal/Emoji.js +7 -5
  222. package/dist/primitives/internal/Emoji.js.map +1 -1
  223. package/dist/primitives/internal/Emoji.mjs +6 -4
  224. package/dist/primitives/internal/Emoji.mjs.map +1 -1
  225. package/dist/shared.js +2 -7
  226. package/dist/shared.js.map +1 -1
  227. package/dist/shared.mjs +2 -7
  228. package/dist/shared.mjs.map +1 -1
  229. package/dist/slate/plugins/auto-links.mjs +1 -1
  230. package/dist/slate/plugins/custom-links.mjs +1 -1
  231. package/dist/slate/plugins/mentions.mjs +1 -1
  232. package/dist/utils/Persist.js +19 -18
  233. package/dist/utils/Persist.js.map +1 -1
  234. package/dist/utils/Persist.mjs +7 -6
  235. package/dist/utils/Persist.mjs.map +1 -1
  236. package/dist/utils/Portal.js +5 -4
  237. package/dist/utils/Portal.js.map +1 -1
  238. package/dist/utils/Portal.mjs +4 -3
  239. package/dist/utils/Portal.mjs.map +1 -1
  240. package/dist/utils/use-controllable-state.js +5 -5
  241. package/dist/utils/use-index.js +7 -7
  242. package/dist/utils/use-initial.js +2 -2
  243. package/dist/utils/use-interval.js +4 -4
  244. package/dist/utils/use-latest.js +3 -3
  245. package/dist/utils/use-observable.js +2 -2
  246. package/dist/utils/use-refs.js +2 -2
  247. package/dist/utils/use-rerender.js +2 -2
  248. package/dist/utils/use-visible.js +24 -2
  249. package/dist/utils/use-visible.js.map +1 -1
  250. package/dist/utils/use-visible.mjs +23 -2
  251. package/dist/utils/use-visible.mjs.map +1 -1
  252. package/dist/utils/use-window-focus.js +2 -2
  253. package/dist/utils/use-window-focus.js.map +1 -1
  254. package/dist/utils/use-window-focus.mjs +1 -1
  255. package/dist/utils/use-window-focus.mjs.map +1 -1
  256. package/dist/version.js +2 -2
  257. package/dist/version.js.map +1 -1
  258. package/dist/version.mjs +2 -2
  259. package/dist/version.mjs.map +1 -1
  260. package/package.json +10 -25
  261. package/dist/utils/use-id.js +0 -29
  262. package/dist/utils/use-id.js.map +0 -1
  263. package/dist/utils/use-id.mjs +0 -27
  264. package/dist/utils/use-id.mjs.map +0 -1
  265. package/dist/utils/use-layout-effect.js +0 -8
  266. package/dist/utils/use-layout-effect.js.map +0 -1
  267. package/dist/utils/use-layout-effect.mjs +0 -6
  268. package/dist/utils/use-layout-effect.mjs.map +0 -1
  269. package/dist/utils/use-transition.js +0 -16
  270. package/dist/utils/use-transition.js.map +0 -1
  271. package/dist/utils/use-transition.mjs +0 -14
  272. package/dist/utils/use-transition.mjs.map +0 -1
@@ -1,23 +1,20 @@
1
- 'use client';
2
1
  'use strict';
3
2
 
3
+ var jsxRuntime = require('react/jsx-runtime');
4
4
  var _private = require('@liveblocks/react/_private');
5
- var React = require('react');
5
+ var react = require('react');
6
6
  var Cross = require('../../icons/Cross.js');
7
7
  var Spinner = require('../../icons/Spinner.js');
8
8
  var Warning = require('../../icons/Warning.js');
9
9
  var overrides = require('../../overrides.js');
10
- require('../../primitives/Comment/index.js');
11
- require('../../primitives/Composer/index.js');
10
+ require('../../primitives/index.js');
12
11
  var contexts = require('../../primitives/Composer/contexts.js');
13
- var utils = require('../../primitives/Composer/utils.js');
14
- require('../../primitives/EmojiPicker/index.js');
15
- require('../../primitives/FileSize.js');
16
- require('../../primitives/Timestamp.js');
17
12
  var classNames = require('../../utils/class-names.js');
18
13
  var formatFileSize = require('../../utils/format-file-size.js');
19
14
  var Tooltip = require('./Tooltip.js');
15
+ var utils = require('../../primitives/Composer/utils.js');
20
16
 
17
+ "use client";
21
18
  const MAX_DISPLAYED_MEDIA_SIZE = 60 * 1024 * 1024;
22
19
  const fileExtensionRegex = /^(.+?)(\.[^.]+)?$/;
23
20
  function splitFileName(name) {
@@ -26,35 +23,35 @@ function splitFileName(name) {
26
23
  }
27
24
  function getAttachmentIconGlyph(mimeType) {
28
25
  if (mimeType === "application/zip" || mimeType === "application/gzip" || mimeType === "application/vnd.rar" || mimeType === "application/x-rar-compressed" || mimeType === "application/x-7z-compressed" || mimeType === "application/x-zip-compressed" || mimeType === "application/x-tar" || mimeType === "application/x-bzip" || mimeType === "application/x-bzip2") {
29
- return /* @__PURE__ */ React.createElement("path", {
26
+ return /* @__PURE__ */ jsxRuntime.jsx("path", {
30
27
  d: "M13 15h2v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1h1a.5.5 0 0 0 .5-.5V20h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 .5-.5V15a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2Z"
31
28
  });
32
29
  }
33
30
  if (mimeType.startsWith("text/") || mimeType.startsWith("font/") || mimeType.startsWith("application/")) {
34
- return /* @__PURE__ */ React.createElement("path", {
31
+ return /* @__PURE__ */ jsxRuntime.jsx("path", {
35
32
  d: "M10 16a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1h-8a.5.5 0 0 1-.5-.5Z"
36
33
  });
37
34
  }
38
35
  if (mimeType.startsWith("image/")) {
39
- return /* @__PURE__ */ React.createElement("path", {
36
+ return /* @__PURE__ */ jsxRuntime.jsx("path", {
40
37
  d: "M12 16h6a1 1 0 0 1 1 1v3l-1.293-1.293a1 1 0 0 0-1.414 0L14.09 20.91l-.464-.386a1 1 0 0 0-1.265-.013l-1.231.985A.995.995 0 0 1 11 21v-4a1 1 0 0 1 1-1Zm-2 1a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-6a2 2 0 0 1-2-2v-4Zm3 2a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"
41
38
  });
42
39
  }
43
40
  if (mimeType.startsWith("video/")) {
44
- return /* @__PURE__ */ React.createElement("path", {
41
+ return /* @__PURE__ */ jsxRuntime.jsx("path", {
45
42
  d: "M12 15.71a1 1 0 0 1 1.49-.872l4.96 2.79a1 1 0 0 1 0 1.744l-4.96 2.79A1 1 0 0 1 12 21.29v-5.58Z"
46
43
  });
47
44
  }
48
45
  if (mimeType.startsWith("audio/")) {
49
- return /* @__PURE__ */ React.createElement("path", {
46
+ return /* @__PURE__ */ jsxRuntime.jsx("path", {
50
47
  d: "M15 15a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 1 0v-7a.5.5 0 0 0-.5-.5Zm-2.5 2.5a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3Zm-2 1a.5.5 0 0 1 1 0v1a.5.5 0 0 1-1 0v-1Zm6-1a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3ZM19 16a.5.5 0 0 0-.5.5v5a.5.5 0 0 0 1 0v-5a.5.5 0 0 0-.5-.5Z"
51
48
  });
52
49
  }
53
50
  return null;
54
51
  }
55
- const AttachmentFileIcon = React.memo(({ mimeType }) => {
56
- const iconGlyph = React.useMemo(() => getAttachmentIconGlyph(mimeType), [mimeType]);
57
- return /* @__PURE__ */ React.createElement("svg", {
52
+ const AttachmentFileIcon = react.memo(({ mimeType }) => {
53
+ const iconGlyph = react.useMemo(() => getAttachmentIconGlyph(mimeType), [mimeType]);
54
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", {
58
55
  className: "lb-attachment-icon",
59
56
  width: 30,
60
57
  height: 30,
@@ -62,19 +59,26 @@ const AttachmentFileIcon = React.memo(({ mimeType }) => {
62
59
  fill: "currentColor",
63
60
  fillRule: "evenodd",
64
61
  clipRule: "evenodd",
65
- xmlns: "http://www.w3.org/2000/svg"
66
- }, /* @__PURE__ */ React.createElement("path", {
67
- d: "M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z",
68
- className: "lb-attachment-icon-shadow"
69
- }), /* @__PURE__ */ React.createElement("path", {
70
- d: "M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z",
71
- className: "lb-attachment-icon-background"
72
- }), /* @__PURE__ */ React.createElement("path", {
73
- d: "M14.382 3.037a4 4 0 0 1 2.29 1.135l6.156 6.157a4 4 0 0 1 1.136 2.289A2 2 0 0 0 22 11h-4a2 2 0 0 1-2-2V5a2 2 0 0 0-1.618-1.963Z",
74
- className: "lb-attachment-icon-fold"
75
- }), iconGlyph && /* @__PURE__ */ React.createElement("g", {
76
- className: "lb-attachment-icon-glyph"
77
- }, iconGlyph));
62
+ xmlns: "http://www.w3.org/2000/svg",
63
+ children: [
64
+ /* @__PURE__ */ jsxRuntime.jsx("path", {
65
+ d: "M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z",
66
+ className: "lb-attachment-icon-shadow"
67
+ }),
68
+ /* @__PURE__ */ jsxRuntime.jsx("path", {
69
+ d: "M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z",
70
+ className: "lb-attachment-icon-background"
71
+ }),
72
+ /* @__PURE__ */ jsxRuntime.jsx("path", {
73
+ d: "M14.382 3.037a4 4 0 0 1 2.29 1.135l6.156 6.157a4 4 0 0 1 1.136 2.289A2 2 0 0 0 22 11h-4a2 2 0 0 1-2-2V5a2 2 0 0 0-1.618-1.963Z",
74
+ className: "lb-attachment-icon-fold"
75
+ }),
76
+ iconGlyph && /* @__PURE__ */ jsxRuntime.jsx("g", {
77
+ className: "lb-attachment-icon-glyph",
78
+ children: iconGlyph
79
+ })
80
+ ]
81
+ });
78
82
  });
79
83
  function AttachmentImagePreview({
80
84
  attachment,
@@ -82,19 +86,25 @@ function AttachmentImagePreview({
82
86
  roomId
83
87
  }) {
84
88
  const { url } = _private.useRoomAttachmentUrl(attachment.id, roomId);
85
- const [isLoaded, setLoaded] = React.useState(false);
86
- const handleLoad = React.useCallback(() => {
89
+ const [isLoaded, setLoaded] = react.useState(false);
90
+ const handleLoad = react.useCallback(() => {
87
91
  setLoaded(true);
88
92
  }, []);
89
- return /* @__PURE__ */ React.createElement(React.Fragment, null, !isLoaded ? /* @__PURE__ */ React.createElement(Spinner.SpinnerIcon, null) : null, url ? /* @__PURE__ */ React.createElement("div", {
90
- className: "lb-attachment-preview-media",
91
- "data-hidden": !isLoaded ? "" : void 0
92
- }, /* @__PURE__ */ React.createElement("img", {
93
- src: url,
94
- loading: "lazy",
95
- onLoad: handleLoad,
96
- onError: markPreviewAsUnsupported
97
- })) : null);
93
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
94
+ children: [
95
+ !isLoaded ? /* @__PURE__ */ jsxRuntime.jsx(Spinner.SpinnerIcon, {}) : null,
96
+ url ? /* @__PURE__ */ jsxRuntime.jsx("div", {
97
+ className: "lb-attachment-preview-media",
98
+ "data-hidden": !isLoaded ? "" : void 0,
99
+ children: /* @__PURE__ */ jsxRuntime.jsx("img", {
100
+ src: url,
101
+ loading: "lazy",
102
+ onLoad: handleLoad,
103
+ onError: markPreviewAsUnsupported
104
+ })
105
+ }) : null
106
+ ]
107
+ });
98
108
  }
99
109
  function AttachmentVideoPreview({
100
110
  attachment,
@@ -102,66 +112,78 @@ function AttachmentVideoPreview({
102
112
  roomId
103
113
  }) {
104
114
  const { url } = _private.useRoomAttachmentUrl(attachment.id, roomId);
105
- const [isLoaded, setLoaded] = React.useState(false);
106
- const handleLoad = React.useCallback(() => {
115
+ const [isLoaded, setLoaded] = react.useState(false);
116
+ const handleLoad = react.useCallback(() => {
107
117
  setLoaded(true);
108
118
  }, []);
109
- return /* @__PURE__ */ React.createElement(React.Fragment, null, !isLoaded ? /* @__PURE__ */ React.createElement(Spinner.SpinnerIcon, null) : null, url ? /* @__PURE__ */ React.createElement("div", {
110
- className: "lb-attachment-preview-media",
111
- "data-hidden": !isLoaded ? "" : void 0
112
- }, /* @__PURE__ */ React.createElement("video", {
113
- src: url,
114
- onLoadedData: handleLoad,
115
- onError: markPreviewAsUnsupported
116
- })) : null);
119
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
120
+ children: [
121
+ !isLoaded ? /* @__PURE__ */ jsxRuntime.jsx(Spinner.SpinnerIcon, {}) : null,
122
+ url ? /* @__PURE__ */ jsxRuntime.jsx("div", {
123
+ className: "lb-attachment-preview-media",
124
+ "data-hidden": !isLoaded ? "" : void 0,
125
+ children: /* @__PURE__ */ jsxRuntime.jsx("video", {
126
+ src: url,
127
+ onLoadedData: handleLoad,
128
+ onError: markPreviewAsUnsupported
129
+ })
130
+ }) : null
131
+ ]
132
+ });
117
133
  }
118
134
  function AttachmentPreview({
119
135
  attachment,
120
136
  allowMediaPreview = true,
121
137
  roomId
122
138
  }) {
123
- const [isUnsupportedPreview, setUnsupportedPreview] = React.useState(false);
139
+ const [isUnsupportedPreview, setUnsupportedPreview] = react.useState(false);
124
140
  const isUploaded = attachment.type === "attachment" || attachment.status === "uploaded";
125
141
  function markPreviewAsUnsupported() {
126
142
  setUnsupportedPreview(true);
127
143
  }
128
144
  if (!isUnsupportedPreview && allowMediaPreview && isUploaded && attachment.size <= MAX_DISPLAYED_MEDIA_SIZE) {
129
145
  if (attachment.mimeType.startsWith("image/")) {
130
- return /* @__PURE__ */ React.createElement(AttachmentImagePreview, {
146
+ return /* @__PURE__ */ jsxRuntime.jsx(AttachmentImagePreview, {
131
147
  attachment,
132
148
  markPreviewAsUnsupported,
133
149
  roomId
134
150
  });
135
151
  }
136
152
  if (attachment.mimeType.startsWith("video/")) {
137
- return /* @__PURE__ */ React.createElement(AttachmentVideoPreview, {
153
+ return /* @__PURE__ */ jsxRuntime.jsx(AttachmentVideoPreview, {
138
154
  attachment,
139
155
  markPreviewAsUnsupported,
140
156
  roomId
141
157
  });
142
158
  }
143
159
  }
144
- return /* @__PURE__ */ React.createElement(AttachmentFileIcon, {
160
+ return /* @__PURE__ */ jsxRuntime.jsx(AttachmentFileIcon, {
145
161
  mimeType: attachment.mimeType
146
162
  });
147
163
  }
148
164
  function AttachmentName({
149
165
  attachment
150
166
  }) {
151
- const { base: fileBaseName, extension: fileExtension } = React.useMemo(() => {
167
+ const { base: fileBaseName, extension: fileExtension } = react.useMemo(() => {
152
168
  return splitFileName(attachment.name);
153
169
  }, [attachment.name]);
154
- return /* @__PURE__ */ React.createElement("span", {
170
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", {
155
171
  className: "lb-attachment-name",
156
- title: attachment.name
157
- }, /* @__PURE__ */ React.createElement("span", {
158
- className: "lb-attachment-name-base"
159
- }, fileBaseName), fileExtension && /* @__PURE__ */ React.createElement("span", {
160
- className: "lb-attachment-name-extension"
161
- }, fileExtension));
172
+ title: attachment.name,
173
+ children: [
174
+ /* @__PURE__ */ jsxRuntime.jsx("span", {
175
+ className: "lb-attachment-name-base",
176
+ children: fileBaseName
177
+ }),
178
+ fileExtension && /* @__PURE__ */ jsxRuntime.jsx("span", {
179
+ className: "lb-attachment-name-extension",
180
+ children: fileExtension
181
+ })
182
+ ]
183
+ });
162
184
  }
163
185
  function useClickOnKeyDown(onKeyDown) {
164
- const handleKeyDown = React.useCallback(
186
+ const handleKeyDown = react.useCallback(
165
187
  (event) => {
166
188
  onKeyDown?.(event);
167
189
  if (event.isDefaultPrevented()) {
@@ -226,7 +248,7 @@ function MediaAttachment({
226
248
  ...props
227
249
  }) {
228
250
  const { isUploading, isError, description, deleteLabel } = useAttachmentContent(attachment, overrides);
229
- const handleDeletePointerDown = React.useCallback(
251
+ const handleDeletePointerDown = react.useCallback(
230
252
  (event) => {
231
253
  if (preventFocusOnDelete) {
232
254
  event.preventDefault();
@@ -235,36 +257,49 @@ function MediaAttachment({
235
257
  [preventFocusOnDelete]
236
258
  );
237
259
  const handleKeyDown = useClickOnKeyDown(onKeyDown);
238
- return /* @__PURE__ */ React.createElement("div", {
260
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", {
239
261
  className: classNames.classNames("lb-attachment lb-media-attachment", className),
240
262
  "data-error": isError ? "" : void 0,
241
263
  ...props,
242
264
  role: onClick ? "button" : void 0,
243
265
  onClick,
244
266
  tabIndex: onClick ? 0 : -1,
245
- onKeyDown: onClick ? handleKeyDown : void 0
246
- }, /* @__PURE__ */ React.createElement("div", {
247
- className: "lb-attachment-preview"
248
- }, isUploading ? /* @__PURE__ */ React.createElement(Spinner.SpinnerIcon, null) : isError ? /* @__PURE__ */ React.createElement(Warning.WarningIcon, null) : /* @__PURE__ */ React.createElement(AttachmentPreview, {
249
- attachment,
250
- allowMediaPreview,
251
- roomId
252
- })), /* @__PURE__ */ React.createElement("div", {
253
- className: "lb-attachment-details"
254
- }, /* @__PURE__ */ React.createElement(AttachmentName, {
255
- attachment
256
- }), /* @__PURE__ */ React.createElement("span", {
257
- className: "lb-attachment-description",
258
- title: description
259
- }, description)), onDeleteClick && /* @__PURE__ */ React.createElement(Tooltip.Tooltip, {
260
- content: deleteLabel
261
- }, /* @__PURE__ */ React.createElement("button", {
262
- type: "button",
263
- className: "lb-attachment-delete",
264
- onClick: onDeleteClick,
265
- onPointerDown: handleDeletePointerDown,
266
- "aria-label": deleteLabel
267
- }, /* @__PURE__ */ React.createElement(Cross.CrossIcon, null))));
267
+ onKeyDown: onClick ? handleKeyDown : void 0,
268
+ children: [
269
+ /* @__PURE__ */ jsxRuntime.jsx("div", {
270
+ className: "lb-attachment-preview",
271
+ children: isUploading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner.SpinnerIcon, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(Warning.WarningIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreview, {
272
+ attachment,
273
+ allowMediaPreview,
274
+ roomId
275
+ })
276
+ }),
277
+ /* @__PURE__ */ jsxRuntime.jsxs("div", {
278
+ className: "lb-attachment-details",
279
+ children: [
280
+ /* @__PURE__ */ jsxRuntime.jsx(AttachmentName, {
281
+ attachment
282
+ }),
283
+ /* @__PURE__ */ jsxRuntime.jsx("span", {
284
+ className: "lb-attachment-description",
285
+ title: description,
286
+ children: description
287
+ })
288
+ ]
289
+ }),
290
+ onDeleteClick && /* @__PURE__ */ jsxRuntime.jsx(Tooltip.Tooltip, {
291
+ content: deleteLabel,
292
+ children: /* @__PURE__ */ jsxRuntime.jsx("button", {
293
+ type: "button",
294
+ className: "lb-attachment-delete",
295
+ onClick: onDeleteClick,
296
+ onPointerDown: handleDeletePointerDown,
297
+ "aria-label": deleteLabel,
298
+ children: /* @__PURE__ */ jsxRuntime.jsx(Cross.CrossIcon, {})
299
+ })
300
+ })
301
+ ]
302
+ });
268
303
  }
269
304
  function FileAttachment({
270
305
  attachment,
@@ -279,7 +314,7 @@ function FileAttachment({
279
314
  ...props
280
315
  }) {
281
316
  const { isUploading, isError, description, deleteLabel } = useAttachmentContent(attachment, overrides);
282
- const handleDeletePointerDown = React.useCallback(
317
+ const handleDeletePointerDown = react.useCallback(
283
318
  (event) => {
284
319
  if (preventFocusOnDelete) {
285
320
  event.preventDefault();
@@ -288,36 +323,49 @@ function FileAttachment({
288
323
  [preventFocusOnDelete]
289
324
  );
290
325
  const handleKeyDown = useClickOnKeyDown(onKeyDown);
291
- return /* @__PURE__ */ React.createElement("div", {
326
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", {
292
327
  className: classNames.classNames("lb-attachment lb-file-attachment", className),
293
328
  "data-error": isError ? "" : void 0,
294
329
  ...props,
295
330
  role: onClick ? "button" : void 0,
296
331
  onClick,
297
332
  tabIndex: onClick ? 0 : -1,
298
- onKeyDown: onClick ? handleKeyDown : void 0
299
- }, /* @__PURE__ */ React.createElement("div", {
300
- className: "lb-attachment-preview"
301
- }, isUploading ? /* @__PURE__ */ React.createElement(Spinner.SpinnerIcon, null) : isError ? /* @__PURE__ */ React.createElement(Warning.WarningIcon, null) : /* @__PURE__ */ React.createElement(AttachmentPreview, {
302
- attachment,
303
- allowMediaPreview,
304
- roomId
305
- })), /* @__PURE__ */ React.createElement("div", {
306
- className: "lb-attachment-details"
307
- }, /* @__PURE__ */ React.createElement(AttachmentName, {
308
- attachment
309
- }), /* @__PURE__ */ React.createElement("span", {
310
- className: "lb-attachment-description",
311
- title: description
312
- }, description)), onDeleteClick && /* @__PURE__ */ React.createElement(Tooltip.Tooltip, {
313
- content: deleteLabel
314
- }, /* @__PURE__ */ React.createElement("button", {
315
- type: "button",
316
- className: "lb-attachment-delete",
317
- onClick: onDeleteClick,
318
- onPointerDown: handleDeletePointerDown,
319
- "aria-label": deleteLabel
320
- }, /* @__PURE__ */ React.createElement(Cross.CrossIcon, null))));
333
+ onKeyDown: onClick ? handleKeyDown : void 0,
334
+ children: [
335
+ /* @__PURE__ */ jsxRuntime.jsx("div", {
336
+ className: "lb-attachment-preview",
337
+ children: isUploading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner.SpinnerIcon, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(Warning.WarningIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreview, {
338
+ attachment,
339
+ allowMediaPreview,
340
+ roomId
341
+ })
342
+ }),
343
+ /* @__PURE__ */ jsxRuntime.jsxs("div", {
344
+ className: "lb-attachment-details",
345
+ children: [
346
+ /* @__PURE__ */ jsxRuntime.jsx(AttachmentName, {
347
+ attachment
348
+ }),
349
+ /* @__PURE__ */ jsxRuntime.jsx("span", {
350
+ className: "lb-attachment-description",
351
+ title: description,
352
+ children: description
353
+ })
354
+ ]
355
+ }),
356
+ onDeleteClick && /* @__PURE__ */ jsxRuntime.jsx(Tooltip.Tooltip, {
357
+ content: deleteLabel,
358
+ children: /* @__PURE__ */ jsxRuntime.jsx("button", {
359
+ type: "button",
360
+ className: "lb-attachment-delete",
361
+ onClick: onDeleteClick,
362
+ onPointerDown: handleDeletePointerDown,
363
+ "aria-label": deleteLabel,
364
+ children: /* @__PURE__ */ jsxRuntime.jsx(Cross.CrossIcon, {})
365
+ })
366
+ })
367
+ ]
368
+ });
321
369
  }
322
370
  function separateMediaAttachments(attachments) {
323
371
  const mediaAttachments = [];
@@ -1 +1 @@
1
- {"version":3,"file":"Attachment.js","sources":["../../../src/components/internal/Attachment.tsx"],"sourcesContent":["\"use client\";\n\nimport type { CommentMixedAttachment } from \"@liveblocks/core\";\nimport { useRoomAttachmentUrl } from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n KeyboardEvent,\n MouseEventHandler,\n PointerEvent,\n} from \"react\";\nimport React, { memo, useCallback, useMemo, useState } from \"react\";\n\nimport { CrossIcon } from \"../../icons/Cross\";\nimport { SpinnerIcon } from \"../../icons/Spinner\";\nimport { WarningIcon } from \"../../icons/Warning\";\nimport type { Overrides } from \"../../overrides\";\nimport { useOverrides } from \"../../overrides\";\nimport { AttachmentTooLargeError } from \"../../primitives\";\nimport { useComposerAttachmentsContextOrNull } from \"../../primitives/Composer/contexts\";\nimport { classNames } from \"../../utils/class-names\";\nimport { formatFileSize } from \"../../utils/format-file-size\";\nimport { Tooltip } from \"./Tooltip\";\n\nconst MAX_DISPLAYED_MEDIA_SIZE = 60 * 1024 * 1024; // 60 MB\n\ninterface AttachmentProps extends ComponentPropsWithoutRef<\"div\"> {\n attachment: CommentMixedAttachment;\n onDeleteClick?: MouseEventHandler<HTMLButtonElement>;\n preventFocusOnDelete?: boolean;\n roomId: string;\n overrides?: Partial<Overrides>;\n allowMediaPreview?: boolean;\n}\n\nconst fileExtensionRegex = /^(.+?)(\\.[^.]+)?$/;\n\nfunction splitFileName(name: string) {\n const match = name.match(fileExtensionRegex);\n\n return { base: match?.[1] ?? name, extension: match?.[2] };\n}\n\nfunction getAttachmentIconGlyph(mimeType: string) {\n if (\n mimeType === \"application/zip\" ||\n mimeType === \"application/gzip\" ||\n mimeType === \"application/vnd.rar\" ||\n mimeType === \"application/x-rar-compressed\" ||\n mimeType === \"application/x-7z-compressed\" ||\n mimeType === \"application/x-zip-compressed\" ||\n mimeType === \"application/x-tar\" ||\n mimeType === \"application/x-bzip\" ||\n mimeType === \"application/x-bzip2\"\n ) {\n return (\n <path d=\"M13 15h2v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1h1a.5.5 0 0 0 .5-.5V20h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 .5-.5V15a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2Z\" />\n );\n }\n\n if (\n mimeType.startsWith(\"text/\") ||\n mimeType.startsWith(\"font/\") ||\n mimeType.startsWith(\"application/\")\n ) {\n return (\n <path d=\"M10 16a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1h-8a.5.5 0 0 1-.5-.5Z\" />\n );\n }\n\n if (mimeType.startsWith(\"image/\")) {\n return (\n <path d=\"M12 16h6a1 1 0 0 1 1 1v3l-1.293-1.293a1 1 0 0 0-1.414 0L14.09 20.91l-.464-.386a1 1 0 0 0-1.265-.013l-1.231.985A.995.995 0 0 1 11 21v-4a1 1 0 0 1 1-1Zm-2 1a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-6a2 2 0 0 1-2-2v-4Zm3 2a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" />\n );\n }\n\n if (mimeType.startsWith(\"video/\")) {\n return (\n <path d=\"M12 15.71a1 1 0 0 1 1.49-.872l4.96 2.79a1 1 0 0 1 0 1.744l-4.96 2.79A1 1 0 0 1 12 21.29v-5.58Z\" />\n );\n }\n\n if (mimeType.startsWith(\"audio/\")) {\n return (\n <path d=\"M15 15a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 1 0v-7a.5.5 0 0 0-.5-.5Zm-2.5 2.5a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3Zm-2 1a.5.5 0 0 1 1 0v1a.5.5 0 0 1-1 0v-1Zm6-1a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3ZM19 16a.5.5 0 0 0-.5.5v5a.5.5 0 0 0 1 0v-5a.5.5 0 0 0-.5-.5Z\" />\n );\n }\n\n return null;\n}\n\nconst AttachmentFileIcon = memo(({ mimeType }: { mimeType: string }) => {\n const iconGlyph = useMemo(() => getAttachmentIconGlyph(mimeType), [mimeType]);\n\n return (\n <svg\n className=\"lb-attachment-icon\"\n width={30}\n height={30}\n viewBox=\"0 0 30 30\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z\"\n className=\"lb-attachment-icon-shadow\"\n />\n <path\n d=\"M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z\"\n className=\"lb-attachment-icon-background\"\n />\n <path\n d=\"M14.382 3.037a4 4 0 0 1 2.29 1.135l6.156 6.157a4 4 0 0 1 1.136 2.289A2 2 0 0 0 22 11h-4a2 2 0 0 1-2-2V5a2 2 0 0 0-1.618-1.963Z\"\n className=\"lb-attachment-icon-fold\"\n />\n\n {iconGlyph && <g className=\"lb-attachment-icon-glyph\">{iconGlyph}</g>}\n </svg>\n );\n});\n\nfunction AttachmentImagePreview({\n attachment,\n markPreviewAsUnsupported,\n roomId,\n}: {\n attachment: CommentMixedAttachment;\n markPreviewAsUnsupported: () => void;\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n const [isLoaded, setLoaded] = useState(false);\n\n const handleLoad = useCallback(() => {\n setLoaded(true);\n }, []);\n\n return (\n <>\n {!isLoaded ? <SpinnerIcon /> : null}\n {url ? (\n <div\n className=\"lb-attachment-preview-media\"\n data-hidden={!isLoaded ? \"\" : undefined}\n >\n <img\n src={url}\n loading=\"lazy\"\n onLoad={handleLoad}\n onError={markPreviewAsUnsupported}\n />\n </div>\n ) : null}\n </>\n );\n}\n\nfunction AttachmentVideoPreview({\n attachment,\n markPreviewAsUnsupported,\n roomId,\n}: {\n attachment: CommentMixedAttachment;\n markPreviewAsUnsupported: () => void;\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n const [isLoaded, setLoaded] = useState(false);\n\n const handleLoad = useCallback(() => {\n setLoaded(true);\n }, []);\n\n return (\n <>\n {!isLoaded ? <SpinnerIcon /> : null}\n {url ? (\n <div\n className=\"lb-attachment-preview-media\"\n data-hidden={!isLoaded ? \"\" : undefined}\n >\n <video\n src={url}\n onLoadedData={handleLoad}\n onError={markPreviewAsUnsupported}\n />\n </div>\n ) : null}\n </>\n );\n}\n\nfunction AttachmentPreview({\n attachment,\n allowMediaPreview = true,\n roomId,\n}: {\n attachment: CommentMixedAttachment;\n allowMediaPreview?: boolean;\n roomId: string;\n}) {\n const [isUnsupportedPreview, setUnsupportedPreview] = useState(false);\n const isUploaded =\n attachment.type === \"attachment\" || attachment.status === \"uploaded\";\n\n function markPreviewAsUnsupported() {\n setUnsupportedPreview(true);\n }\n\n if (\n !isUnsupportedPreview &&\n allowMediaPreview &&\n isUploaded &&\n attachment.size <= MAX_DISPLAYED_MEDIA_SIZE\n ) {\n if (attachment.mimeType.startsWith(\"image/\")) {\n return (\n <AttachmentImagePreview\n attachment={attachment}\n markPreviewAsUnsupported={markPreviewAsUnsupported}\n roomId={roomId}\n />\n );\n }\n\n if (attachment.mimeType.startsWith(\"video/\")) {\n return (\n <AttachmentVideoPreview\n attachment={attachment}\n markPreviewAsUnsupported={markPreviewAsUnsupported}\n roomId={roomId}\n />\n );\n }\n }\n\n return <AttachmentFileIcon mimeType={attachment.mimeType} />;\n}\n\nfunction AttachmentName({\n attachment,\n}: {\n attachment: CommentMixedAttachment;\n}) {\n const { base: fileBaseName, extension: fileExtension } = useMemo(() => {\n return splitFileName(attachment.name);\n }, [attachment.name]);\n\n return (\n <span className=\"lb-attachment-name\" title={attachment.name}>\n <span className=\"lb-attachment-name-base\">{fileBaseName}</span>\n {fileExtension && (\n <span className=\"lb-attachment-name-extension\">{fileExtension}</span>\n )}\n </span>\n );\n}\n\nfunction useClickOnKeyDown(\n onKeyDown?: (event: KeyboardEvent<HTMLDivElement>) => void\n) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n // Simulate a click event on Enter or Space because it's a div\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n\n const clickEvent = new MouseEvent(\"click\", {\n bubbles: true,\n cancelable: true,\n view: window,\n });\n event.target.dispatchEvent(clickEvent);\n }\n },\n [onKeyDown]\n );\n\n return handleKeyDown;\n}\n\nfunction useAttachmentContent(\n attachment: CommentMixedAttachment,\n overrides?: Partial<Overrides>\n) {\n const $ = useOverrides(overrides);\n const composerAttachmentsContext = useComposerAttachmentsContextOrNull();\n const isInComposer = Boolean(composerAttachmentsContext);\n const maxAttachmentSize = composerAttachmentsContext?.maxAttachmentSize;\n\n const status =\n attachment.type === \"localAttachment\" ? attachment.status : undefined;\n const isUploading = status === \"uploading\";\n const isError = status === \"error\";\n\n let description: string;\n\n if (attachment.type === \"localAttachment\" && attachment.status === \"error\") {\n if (attachment.error instanceof AttachmentTooLargeError) {\n if (attachment.error.origin === \"server\") {\n description = $.ATTACHMENT_TOO_LARGE();\n } else {\n description = $.ATTACHMENT_TOO_LARGE(\n maxAttachmentSize\n ? formatFileSize(maxAttachmentSize, $.locale)\n : undefined\n );\n }\n } else {\n description = $.ATTACHMENT_ERROR(attachment.error);\n }\n } else {\n description = formatFileSize(attachment.size, $.locale);\n }\n\n const deleteLabel = isInComposer\n ? $.COMPOSER_REMOVE_ATTACHMENT\n : $.COMMENT_DELETE_ATTACHMENT;\n\n return {\n isUploading,\n isError,\n description,\n deleteLabel,\n };\n}\n\nexport function MediaAttachment({\n attachment,\n overrides,\n onClick,\n onDeleteClick,\n preventFocusOnDelete,\n allowMediaPreview = true,\n roomId,\n className,\n onKeyDown,\n ...props\n}: AttachmentProps) {\n const { isUploading, isError, description, deleteLabel } =\n useAttachmentContent(attachment, overrides);\n\n const handleDeletePointerDown = useCallback(\n (event: PointerEvent<HTMLButtonElement>) => {\n if (preventFocusOnDelete) {\n event.preventDefault();\n }\n },\n [preventFocusOnDelete]\n );\n\n const handleKeyDown = useClickOnKeyDown(onKeyDown);\n\n return (\n <div\n className={classNames(\"lb-attachment lb-media-attachment\", className)}\n data-error={isError ? \"\" : undefined}\n {...props}\n role={onClick ? \"button\" : undefined}\n onClick={onClick}\n tabIndex={onClick ? 0 : -1}\n onKeyDown={onClick ? handleKeyDown : undefined}\n >\n <div className=\"lb-attachment-preview\">\n {isUploading ? (\n <SpinnerIcon />\n ) : isError ? (\n <WarningIcon />\n ) : (\n <AttachmentPreview\n attachment={attachment}\n allowMediaPreview={allowMediaPreview}\n roomId={roomId}\n />\n )}\n </div>\n <div className=\"lb-attachment-details\">\n <AttachmentName attachment={attachment} />\n <span className=\"lb-attachment-description\" title={description}>\n {description}\n </span>\n </div>\n {onDeleteClick && (\n <Tooltip content={deleteLabel}>\n <button\n type=\"button\"\n className=\"lb-attachment-delete\"\n onClick={onDeleteClick}\n onPointerDown={handleDeletePointerDown}\n aria-label={deleteLabel}\n >\n <CrossIcon />\n </button>\n </Tooltip>\n )}\n </div>\n );\n}\n\nexport function FileAttachment({\n attachment,\n overrides,\n onClick,\n onDeleteClick,\n preventFocusOnDelete,\n allowMediaPreview = true,\n roomId,\n className,\n onKeyDown,\n ...props\n}: AttachmentProps) {\n const { isUploading, isError, description, deleteLabel } =\n useAttachmentContent(attachment, overrides);\n\n const handleDeletePointerDown = useCallback(\n (event: PointerEvent<HTMLButtonElement>) => {\n if (preventFocusOnDelete) {\n event.preventDefault();\n }\n },\n [preventFocusOnDelete]\n );\n\n const handleKeyDown = useClickOnKeyDown(onKeyDown);\n\n return (\n <div\n className={classNames(\"lb-attachment lb-file-attachment\", className)}\n data-error={isError ? \"\" : undefined}\n {...props}\n role={onClick ? \"button\" : undefined}\n onClick={onClick}\n tabIndex={onClick ? 0 : -1}\n onKeyDown={onClick ? handleKeyDown : undefined}\n >\n <div className=\"lb-attachment-preview\">\n {isUploading ? (\n <SpinnerIcon />\n ) : isError ? (\n <WarningIcon />\n ) : (\n <AttachmentPreview\n attachment={attachment}\n allowMediaPreview={allowMediaPreview}\n roomId={roomId}\n />\n )}\n </div>\n <div className=\"lb-attachment-details\">\n <AttachmentName attachment={attachment} />\n <span className=\"lb-attachment-description\" title={description}>\n {description}\n </span>\n </div>\n {onDeleteClick && (\n <Tooltip content={deleteLabel}>\n <button\n type=\"button\"\n className=\"lb-attachment-delete\"\n onClick={onDeleteClick}\n onPointerDown={handleDeletePointerDown}\n aria-label={deleteLabel}\n >\n <CrossIcon />\n </button>\n </Tooltip>\n )}\n </div>\n );\n}\n\nexport function separateMediaAttachments<T extends CommentMixedAttachment>(\n attachments: T[]\n) {\n const mediaAttachments: T[] = [];\n const fileAttachments: T[] = [];\n\n for (const attachment of attachments) {\n if (\n (attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\")) &&\n attachment.size <= MAX_DISPLAYED_MEDIA_SIZE\n ) {\n mediaAttachments.push(attachment);\n } else {\n fileAttachments.push(attachment);\n }\n }\n\n return {\n mediaAttachments,\n fileAttachments,\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA;AAWA;AAEA;AACE;AAEA;AACF;AAEA;AACE;AAWE;AACG;AAAO;AAAoP;AAIhQ;AAKE;AACG;AAAO;AAAiP;AAI7P;AACE;AACG;AAAO;AAAiQ;AAI7Q;AACE;AACG;AAAO;AAAiG;AAI7G;AACE;AACG;AAAO;AAAyP;AAIrQ;AACF;AAEA;AACE;AAEA;AACG;AACW;AACH;AACC;AACA;AACH;AACI;AACA;AACH;AAEL;AACG;AACQ;AAEX;AACG;AACQ;AAEX;AACG;AACQ;AAGG;AAAY;AAGjC;AAEA;AAAgC;AAC9B;AACA;AAEF;AAKE;AACA;AAEA;AACE;AAAc;AAGhB;AAIO;AACW;AACoB;AAE7B;AACM;AACG;AACA;AACC;AAMrB;AAEA;AAAgC;AAC9B;AACA;AAEF;AAKE;AACA;AAEA;AACE;AAAc;AAGhB;AAIO;AACW;AACoB;AAE7B;AACM;AACS;AACL;AAMrB;AAEA;AAA2B;AACzB;AACoB;AAEtB;AAKE;AACA;AAGA;AACE;AAA0B;AAG5B;AAME;AACE;AACG;AACC;AACA;AACA;AACF;AAIJ;AACE;AACG;AACC;AACA;AACA;AACF;AAEJ;AAGF;AAAQ;AAAwC;AAClD;AAEA;AAAwB;AAExB;AAGE;AACE;AAAoC;AAGtC;AACG;AAAe;AAAuC;AACpD;AAAe;AAEb;AAAe;AAIxB;AAEA;AAGE;AAAsB;AAElB;AAEA;AACE;AAAA;AAIF;AACE;AAEA;AAA2C;AAChC;AACG;AACN;AAER;AAAqC;AACvC;AACF;AACU;AAGZ;AACF;AAEA;AAIE;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AAEA;AACE;AACE;AACE;AAAqC;AAErC;AAAgB;AAGV;AACN;AACF;AAEA;AAAiD;AACnD;AAEA;AAAsD;AAGxD;AAIA;AAAO;AACL;AACA;AACA;AACA;AAEJ;AAEO;AAAyB;AAC9B;AACA;AACA;AACA;AACA;AACoB;AACpB;AACA;AACA;AAEF;AACE;AAGA;AAAgC;AAE5B;AACE;AAAqB;AACvB;AACF;AACqB;AAGvB;AAEA;AACG;AACqE;AACzC;AACvB;AACuB;AAC3B;AACwB;AACa;AAEpC;AAAc;AAMV;AACC;AACA;AACA;AAIL;AAAc;AACZ;AAAe;AACf;AAAe;AAAmC;AAKlD;AAAiB;AACf;AACM;AACK;AACD;AACM;AACH;AAQxB;AAEO;AAAwB;AAC7B;AACA;AACA;AACA;AACA;AACoB;AACpB;AACA;AACA;AAEF;AACE;AAGA;AAAgC;AAE5B;AACE;AAAqB;AACvB;AACF;AACqB;AAGvB;AAEA;AACG;AACoE;AACxC;AACvB;AACuB;AAC3B;AACwB;AACa;AAEpC;AAAc;AAMV;AACC;AACA;AACA;AAIL;AAAc;AACZ;AAAe;AACf;AAAe;AAAmC;AAKlD;AAAiB;AACf;AACM;AACK;AACD;AACM;AACH;AAQxB;AAEO;AAGL;AACA;AAEA;AACE;AAKE;AAAgC;AAEhC;AAA+B;AACjC;AAGF;AAAO;AACL;AACA;AAEJ;;;;"}
1
+ {"version":3,"file":"Attachment.js","sources":["../../../src/components/internal/Attachment.tsx"],"sourcesContent":["\"use client\";\n\nimport type { CommentMixedAttachment } from \"@liveblocks/core\";\nimport { useRoomAttachmentUrl } from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n KeyboardEvent,\n MouseEventHandler,\n PointerEvent,\n} from \"react\";\nimport { memo, useCallback, useMemo, useState } from \"react\";\n\nimport { CrossIcon } from \"../../icons/Cross\";\nimport { SpinnerIcon } from \"../../icons/Spinner\";\nimport { WarningIcon } from \"../../icons/Warning\";\nimport type { Overrides } from \"../../overrides\";\nimport { useOverrides } from \"../../overrides\";\nimport { AttachmentTooLargeError } from \"../../primitives\";\nimport { useComposerAttachmentsContextOrNull } from \"../../primitives/Composer/contexts\";\nimport { classNames } from \"../../utils/class-names\";\nimport { formatFileSize } from \"../../utils/format-file-size\";\nimport { Tooltip } from \"./Tooltip\";\n\nconst MAX_DISPLAYED_MEDIA_SIZE = 60 * 1024 * 1024; // 60 MB\n\ninterface AttachmentProps extends ComponentPropsWithoutRef<\"div\"> {\n attachment: CommentMixedAttachment;\n onDeleteClick?: MouseEventHandler<HTMLButtonElement>;\n preventFocusOnDelete?: boolean;\n roomId: string;\n overrides?: Partial<Overrides>;\n allowMediaPreview?: boolean;\n}\n\nconst fileExtensionRegex = /^(.+?)(\\.[^.]+)?$/;\n\nfunction splitFileName(name: string) {\n const match = name.match(fileExtensionRegex);\n\n return { base: match?.[1] ?? name, extension: match?.[2] };\n}\n\nfunction getAttachmentIconGlyph(mimeType: string) {\n if (\n mimeType === \"application/zip\" ||\n mimeType === \"application/gzip\" ||\n mimeType === \"application/vnd.rar\" ||\n mimeType === \"application/x-rar-compressed\" ||\n mimeType === \"application/x-7z-compressed\" ||\n mimeType === \"application/x-zip-compressed\" ||\n mimeType === \"application/x-tar\" ||\n mimeType === \"application/x-bzip\" ||\n mimeType === \"application/x-bzip2\"\n ) {\n return (\n <path d=\"M13 15h2v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1h1a.5.5 0 0 0 .5-.5V20h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 .5-.5V15a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2Z\" />\n );\n }\n\n if (\n mimeType.startsWith(\"text/\") ||\n mimeType.startsWith(\"font/\") ||\n mimeType.startsWith(\"application/\")\n ) {\n return (\n <path d=\"M10 16a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1h-8a.5.5 0 0 1-.5-.5Z\" />\n );\n }\n\n if (mimeType.startsWith(\"image/\")) {\n return (\n <path d=\"M12 16h6a1 1 0 0 1 1 1v3l-1.293-1.293a1 1 0 0 0-1.414 0L14.09 20.91l-.464-.386a1 1 0 0 0-1.265-.013l-1.231.985A.995.995 0 0 1 11 21v-4a1 1 0 0 1 1-1Zm-2 1a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-6a2 2 0 0 1-2-2v-4Zm3 2a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" />\n );\n }\n\n if (mimeType.startsWith(\"video/\")) {\n return (\n <path d=\"M12 15.71a1 1 0 0 1 1.49-.872l4.96 2.79a1 1 0 0 1 0 1.744l-4.96 2.79A1 1 0 0 1 12 21.29v-5.58Z\" />\n );\n }\n\n if (mimeType.startsWith(\"audio/\")) {\n return (\n <path d=\"M15 15a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 1 0v-7a.5.5 0 0 0-.5-.5Zm-2.5 2.5a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3Zm-2 1a.5.5 0 0 1 1 0v1a.5.5 0 0 1-1 0v-1Zm6-1a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3ZM19 16a.5.5 0 0 0-.5.5v5a.5.5 0 0 0 1 0v-5a.5.5 0 0 0-.5-.5Z\" />\n );\n }\n\n return null;\n}\n\nconst AttachmentFileIcon = memo(({ mimeType }: { mimeType: string }) => {\n const iconGlyph = useMemo(() => getAttachmentIconGlyph(mimeType), [mimeType]);\n\n return (\n <svg\n className=\"lb-attachment-icon\"\n width={30}\n height={30}\n viewBox=\"0 0 30 30\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z\"\n className=\"lb-attachment-icon-shadow\"\n />\n <path\n d=\"M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z\"\n className=\"lb-attachment-icon-background\"\n />\n <path\n d=\"M14.382 3.037a4 4 0 0 1 2.29 1.135l6.156 6.157a4 4 0 0 1 1.136 2.289A2 2 0 0 0 22 11h-4a2 2 0 0 1-2-2V5a2 2 0 0 0-1.618-1.963Z\"\n className=\"lb-attachment-icon-fold\"\n />\n\n {iconGlyph && <g className=\"lb-attachment-icon-glyph\">{iconGlyph}</g>}\n </svg>\n );\n});\n\nfunction AttachmentImagePreview({\n attachment,\n markPreviewAsUnsupported,\n roomId,\n}: {\n attachment: CommentMixedAttachment;\n markPreviewAsUnsupported: () => void;\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n const [isLoaded, setLoaded] = useState(false);\n\n const handleLoad = useCallback(() => {\n setLoaded(true);\n }, []);\n\n return (\n <>\n {!isLoaded ? <SpinnerIcon /> : null}\n {url ? (\n <div\n className=\"lb-attachment-preview-media\"\n data-hidden={!isLoaded ? \"\" : undefined}\n >\n <img\n src={url}\n loading=\"lazy\"\n onLoad={handleLoad}\n onError={markPreviewAsUnsupported}\n />\n </div>\n ) : null}\n </>\n );\n}\n\nfunction AttachmentVideoPreview({\n attachment,\n markPreviewAsUnsupported,\n roomId,\n}: {\n attachment: CommentMixedAttachment;\n markPreviewAsUnsupported: () => void;\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n const [isLoaded, setLoaded] = useState(false);\n\n const handleLoad = useCallback(() => {\n setLoaded(true);\n }, []);\n\n return (\n <>\n {!isLoaded ? <SpinnerIcon /> : null}\n {url ? (\n <div\n className=\"lb-attachment-preview-media\"\n data-hidden={!isLoaded ? \"\" : undefined}\n >\n <video\n src={url}\n onLoadedData={handleLoad}\n onError={markPreviewAsUnsupported}\n />\n </div>\n ) : null}\n </>\n );\n}\n\nfunction AttachmentPreview({\n attachment,\n allowMediaPreview = true,\n roomId,\n}: {\n attachment: CommentMixedAttachment;\n allowMediaPreview?: boolean;\n roomId: string;\n}) {\n const [isUnsupportedPreview, setUnsupportedPreview] = useState(false);\n const isUploaded =\n attachment.type === \"attachment\" || attachment.status === \"uploaded\";\n\n function markPreviewAsUnsupported() {\n setUnsupportedPreview(true);\n }\n\n if (\n !isUnsupportedPreview &&\n allowMediaPreview &&\n isUploaded &&\n attachment.size <= MAX_DISPLAYED_MEDIA_SIZE\n ) {\n if (attachment.mimeType.startsWith(\"image/\")) {\n return (\n <AttachmentImagePreview\n attachment={attachment}\n markPreviewAsUnsupported={markPreviewAsUnsupported}\n roomId={roomId}\n />\n );\n }\n\n if (attachment.mimeType.startsWith(\"video/\")) {\n return (\n <AttachmentVideoPreview\n attachment={attachment}\n markPreviewAsUnsupported={markPreviewAsUnsupported}\n roomId={roomId}\n />\n );\n }\n }\n\n return <AttachmentFileIcon mimeType={attachment.mimeType} />;\n}\n\nfunction AttachmentName({\n attachment,\n}: {\n attachment: CommentMixedAttachment;\n}) {\n const { base: fileBaseName, extension: fileExtension } = useMemo(() => {\n return splitFileName(attachment.name);\n }, [attachment.name]);\n\n return (\n <span className=\"lb-attachment-name\" title={attachment.name}>\n <span className=\"lb-attachment-name-base\">{fileBaseName}</span>\n {fileExtension && (\n <span className=\"lb-attachment-name-extension\">{fileExtension}</span>\n )}\n </span>\n );\n}\n\nfunction useClickOnKeyDown(\n onKeyDown?: (event: KeyboardEvent<HTMLDivElement>) => void\n) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n // Simulate a click event on Enter or Space because it's a div\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n\n const clickEvent = new MouseEvent(\"click\", {\n bubbles: true,\n cancelable: true,\n view: window,\n });\n event.target.dispatchEvent(clickEvent);\n }\n },\n [onKeyDown]\n );\n\n return handleKeyDown;\n}\n\nfunction useAttachmentContent(\n attachment: CommentMixedAttachment,\n overrides?: Partial<Overrides>\n) {\n const $ = useOverrides(overrides);\n const composerAttachmentsContext = useComposerAttachmentsContextOrNull();\n const isInComposer = Boolean(composerAttachmentsContext);\n const maxAttachmentSize = composerAttachmentsContext?.maxAttachmentSize;\n\n const status =\n attachment.type === \"localAttachment\" ? attachment.status : undefined;\n const isUploading = status === \"uploading\";\n const isError = status === \"error\";\n\n let description: string;\n\n if (attachment.type === \"localAttachment\" && attachment.status === \"error\") {\n if (attachment.error instanceof AttachmentTooLargeError) {\n if (attachment.error.origin === \"server\") {\n description = $.ATTACHMENT_TOO_LARGE();\n } else {\n description = $.ATTACHMENT_TOO_LARGE(\n maxAttachmentSize\n ? formatFileSize(maxAttachmentSize, $.locale)\n : undefined\n );\n }\n } else {\n description = $.ATTACHMENT_ERROR(attachment.error);\n }\n } else {\n description = formatFileSize(attachment.size, $.locale);\n }\n\n const deleteLabel = isInComposer\n ? $.COMPOSER_REMOVE_ATTACHMENT\n : $.COMMENT_DELETE_ATTACHMENT;\n\n return {\n isUploading,\n isError,\n description,\n deleteLabel,\n };\n}\n\nexport function MediaAttachment({\n attachment,\n overrides,\n onClick,\n onDeleteClick,\n preventFocusOnDelete,\n allowMediaPreview = true,\n roomId,\n className,\n onKeyDown,\n ...props\n}: AttachmentProps) {\n const { isUploading, isError, description, deleteLabel } =\n useAttachmentContent(attachment, overrides);\n\n const handleDeletePointerDown = useCallback(\n (event: PointerEvent<HTMLButtonElement>) => {\n if (preventFocusOnDelete) {\n event.preventDefault();\n }\n },\n [preventFocusOnDelete]\n );\n\n const handleKeyDown = useClickOnKeyDown(onKeyDown);\n\n return (\n <div\n className={classNames(\"lb-attachment lb-media-attachment\", className)}\n data-error={isError ? \"\" : undefined}\n {...props}\n role={onClick ? \"button\" : undefined}\n onClick={onClick}\n tabIndex={onClick ? 0 : -1}\n onKeyDown={onClick ? handleKeyDown : undefined}\n >\n <div className=\"lb-attachment-preview\">\n {isUploading ? (\n <SpinnerIcon />\n ) : isError ? (\n <WarningIcon />\n ) : (\n <AttachmentPreview\n attachment={attachment}\n allowMediaPreview={allowMediaPreview}\n roomId={roomId}\n />\n )}\n </div>\n <div className=\"lb-attachment-details\">\n <AttachmentName attachment={attachment} />\n <span className=\"lb-attachment-description\" title={description}>\n {description}\n </span>\n </div>\n {onDeleteClick && (\n <Tooltip content={deleteLabel}>\n <button\n type=\"button\"\n className=\"lb-attachment-delete\"\n onClick={onDeleteClick}\n onPointerDown={handleDeletePointerDown}\n aria-label={deleteLabel}\n >\n <CrossIcon />\n </button>\n </Tooltip>\n )}\n </div>\n );\n}\n\nexport function FileAttachment({\n attachment,\n overrides,\n onClick,\n onDeleteClick,\n preventFocusOnDelete,\n allowMediaPreview = true,\n roomId,\n className,\n onKeyDown,\n ...props\n}: AttachmentProps) {\n const { isUploading, isError, description, deleteLabel } =\n useAttachmentContent(attachment, overrides);\n\n const handleDeletePointerDown = useCallback(\n (event: PointerEvent<HTMLButtonElement>) => {\n if (preventFocusOnDelete) {\n event.preventDefault();\n }\n },\n [preventFocusOnDelete]\n );\n\n const handleKeyDown = useClickOnKeyDown(onKeyDown);\n\n return (\n <div\n className={classNames(\"lb-attachment lb-file-attachment\", className)}\n data-error={isError ? \"\" : undefined}\n {...props}\n role={onClick ? \"button\" : undefined}\n onClick={onClick}\n tabIndex={onClick ? 0 : -1}\n onKeyDown={onClick ? handleKeyDown : undefined}\n >\n <div className=\"lb-attachment-preview\">\n {isUploading ? (\n <SpinnerIcon />\n ) : isError ? (\n <WarningIcon />\n ) : (\n <AttachmentPreview\n attachment={attachment}\n allowMediaPreview={allowMediaPreview}\n roomId={roomId}\n />\n )}\n </div>\n <div className=\"lb-attachment-details\">\n <AttachmentName attachment={attachment} />\n <span className=\"lb-attachment-description\" title={description}>\n {description}\n </span>\n </div>\n {onDeleteClick && (\n <Tooltip content={deleteLabel}>\n <button\n type=\"button\"\n className=\"lb-attachment-delete\"\n onClick={onDeleteClick}\n onPointerDown={handleDeletePointerDown}\n aria-label={deleteLabel}\n >\n <CrossIcon />\n </button>\n </Tooltip>\n )}\n </div>\n );\n}\n\nexport function separateMediaAttachments<T extends CommentMixedAttachment>(\n attachments: T[]\n) {\n const mediaAttachments: T[] = [];\n const fileAttachments: T[] = [];\n\n for (const attachment of attachments) {\n if (\n (attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\")) &&\n attachment.size <= MAX_DISPLAYED_MEDIA_SIZE\n ) {\n mediaAttachments.push(attachment);\n } else {\n fileAttachments.push(attachment);\n }\n }\n\n return {\n mediaAttachments,\n fileAttachments,\n };\n}\n"],"names":["jsx","memo","useMemo","jsxs","useRoomAttachmentUrl","useState","useCallback","Fragment","SpinnerIcon","overrides","useOverrides","useComposerAttachmentsContextOrNull","AttachmentTooLargeError","formatFileSize","classNames","WarningIcon","Tooltip","CrossIcon"],"mappings":"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"}