@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.
- package/dist/_private/index.d.mts +24 -22
- package/dist/_private/index.d.ts +24 -22
- package/dist/_private/index.js +1 -0
- package/dist/_private/index.js.map +1 -1
- package/dist/_private/index.mjs +1 -0
- package/dist/_private/index.mjs.map +1 -1
- package/dist/components/Comment.js +358 -256
- package/dist/components/Comment.js.map +1 -1
- package/dist/components/Comment.mjs +334 -232
- package/dist/components/Comment.mjs.map +1 -1
- package/dist/components/Composer.js +308 -225
- package/dist/components/Composer.js.map +1 -1
- package/dist/components/Composer.mjs +288 -206
- package/dist/components/Composer.mjs.map +1 -1
- package/dist/components/HistoryVersionSummary.js +28 -32
- package/dist/components/HistoryVersionSummary.js.map +1 -1
- package/dist/components/HistoryVersionSummary.mjs +27 -31
- package/dist/components/HistoryVersionSummary.mjs.map +1 -1
- package/dist/components/HistoryVersionSummaryList.js +11 -9
- package/dist/components/HistoryVersionSummaryList.js.map +1 -1
- package/dist/components/HistoryVersionSummaryList.mjs +10 -8
- package/dist/components/HistoryVersionSummaryList.mjs.map +1 -1
- package/dist/components/InboxNotification.js +202 -143
- package/dist/components/InboxNotification.js.map +1 -1
- package/dist/components/InboxNotification.mjs +180 -121
- package/dist/components/InboxNotification.mjs.map +1 -1
- package/dist/components/InboxNotificationList.js +19 -14
- package/dist/components/InboxNotificationList.js.map +1 -1
- package/dist/components/InboxNotificationList.mjs +17 -12
- package/dist/components/InboxNotificationList.mjs.map +1 -1
- package/dist/components/Thread.js +104 -86
- package/dist/components/Thread.js.map +1 -1
- package/dist/components/Thread.mjs +93 -75
- package/dist/components/Thread.mjs.map +1 -1
- package/dist/components/internal/Attachment.js +161 -113
- package/dist/components/internal/Attachment.js.map +1 -1
- package/dist/components/internal/Attachment.mjs +150 -102
- package/dist/components/internal/Attachment.mjs.map +1 -1
- package/dist/components/internal/Attribution.js +15 -13
- package/dist/components/internal/Attribution.js.map +1 -1
- package/dist/components/internal/Attribution.mjs +15 -13
- package/dist/components/internal/Attribution.mjs.map +1 -1
- package/dist/components/internal/Avatar.js +27 -20
- package/dist/components/internal/Avatar.js.map +1 -1
- package/dist/components/internal/Avatar.mjs +23 -16
- package/dist/components/internal/Avatar.mjs.map +1 -1
- package/dist/components/internal/Button.js +5 -4
- package/dist/components/internal/Button.js.map +1 -1
- package/dist/components/internal/Button.mjs +4 -3
- package/dist/components/internal/Button.mjs.map +1 -1
- package/dist/components/internal/Dropdown.js +27 -19
- package/dist/components/internal/Dropdown.js.map +1 -1
- package/dist/components/internal/Dropdown.mjs +26 -18
- package/dist/components/internal/Dropdown.mjs.map +1 -1
- package/dist/components/internal/Emoji.js +4 -3
- package/dist/components/internal/Emoji.js.map +1 -1
- package/dist/components/internal/Emoji.mjs +3 -2
- package/dist/components/internal/Emoji.mjs.map +1 -1
- package/dist/components/internal/EmojiPicker.js +96 -72
- package/dist/components/internal/EmojiPicker.js.map +1 -1
- package/dist/components/internal/EmojiPicker.mjs +90 -66
- package/dist/components/internal/EmojiPicker.mjs.map +1 -1
- package/dist/components/internal/Icon.js +5 -4
- package/dist/components/internal/Icon.js.map +1 -1
- package/dist/components/internal/Icon.mjs +5 -4
- package/dist/components/internal/Icon.mjs.map +1 -1
- package/dist/components/internal/InboxNotificationThread.js +53 -38
- package/dist/components/internal/InboxNotificationThread.js.map +1 -1
- package/dist/components/internal/InboxNotificationThread.mjs +53 -38
- package/dist/components/internal/InboxNotificationThread.mjs.map +1 -1
- package/dist/components/internal/List.js +8 -6
- package/dist/components/internal/List.js.map +1 -1
- package/dist/components/internal/List.mjs +6 -4
- package/dist/components/internal/List.mjs.map +1 -1
- package/dist/components/internal/Room.js +8 -6
- package/dist/components/internal/Room.js.map +1 -1
- package/dist/components/internal/Room.mjs +7 -5
- package/dist/components/internal/Room.mjs.map +1 -1
- package/dist/components/internal/Tooltip.js +49 -33
- package/dist/components/internal/Tooltip.js.map +1 -1
- package/dist/components/internal/Tooltip.mjs +46 -30
- package/dist/components/internal/Tooltip.mjs.map +1 -1
- package/dist/components/internal/User.js +8 -6
- package/dist/components/internal/User.js.map +1 -1
- package/dist/components/internal/User.mjs +7 -5
- package/dist/components/internal/User.mjs.map +1 -1
- package/dist/components.js +12 -29
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +6 -5
- package/dist/components.mjs.map +1 -1
- package/dist/config.js +16 -12
- package/dist/config.js.map +1 -1
- package/dist/config.mjs +13 -9
- package/dist/config.mjs.map +1 -1
- package/dist/icons/ArrowDown.js +7 -6
- package/dist/icons/ArrowDown.js.map +1 -1
- package/dist/icons/ArrowDown.mjs +7 -6
- package/dist/icons/ArrowDown.mjs.map +1 -1
- package/dist/icons/ArrowUp.js +7 -6
- package/dist/icons/ArrowUp.js.map +1 -1
- package/dist/icons/ArrowUp.mjs +7 -6
- package/dist/icons/ArrowUp.mjs.map +1 -1
- package/dist/icons/Attachment.js +7 -6
- package/dist/icons/Attachment.js.map +1 -1
- package/dist/icons/Attachment.mjs +7 -6
- package/dist/icons/Attachment.mjs.map +1 -1
- package/dist/icons/Bold.js +7 -6
- package/dist/icons/Bold.js.map +1 -1
- package/dist/icons/Bold.mjs +7 -6
- package/dist/icons/Bold.mjs.map +1 -1
- package/dist/icons/Check.js +7 -6
- package/dist/icons/Check.js.map +1 -1
- package/dist/icons/Check.mjs +7 -6
- package/dist/icons/Check.mjs.map +1 -1
- package/dist/icons/Code.js +7 -6
- package/dist/icons/Code.js.map +1 -1
- package/dist/icons/Code.mjs +7 -6
- package/dist/icons/Code.mjs.map +1 -1
- package/dist/icons/Cross.js +12 -8
- package/dist/icons/Cross.js.map +1 -1
- package/dist/icons/Cross.mjs +12 -8
- package/dist/icons/Cross.mjs.map +1 -1
- package/dist/icons/Delete.js +7 -6
- package/dist/icons/Delete.js.map +1 -1
- package/dist/icons/Delete.mjs +7 -6
- package/dist/icons/Delete.mjs.map +1 -1
- package/dist/icons/Edit.js +7 -6
- package/dist/icons/Edit.js.map +1 -1
- package/dist/icons/Edit.mjs +7 -6
- package/dist/icons/Edit.mjs.map +1 -1
- package/dist/icons/Ellipsis.js +21 -16
- package/dist/icons/Ellipsis.js.map +1 -1
- package/dist/icons/Ellipsis.mjs +21 -16
- package/dist/icons/Ellipsis.mjs.map +1 -1
- package/dist/icons/Emoji.js +25 -18
- package/dist/icons/Emoji.js.map +1 -1
- package/dist/icons/Emoji.mjs +25 -18
- package/dist/icons/Emoji.mjs.map +1 -1
- package/dist/icons/EmojiAdd.js +28 -20
- package/dist/icons/EmojiAdd.js.map +1 -1
- package/dist/icons/EmojiAdd.mjs +28 -20
- package/dist/icons/EmojiAdd.mjs.map +1 -1
- package/dist/icons/Italic.js +7 -6
- package/dist/icons/Italic.js.map +1 -1
- package/dist/icons/Italic.mjs +7 -6
- package/dist/icons/Italic.mjs.map +1 -1
- package/dist/icons/Mention.js +12 -8
- package/dist/icons/Mention.js.map +1 -1
- package/dist/icons/Mention.mjs +12 -8
- package/dist/icons/Mention.mjs.map +1 -1
- package/dist/icons/Resolve.js +14 -10
- package/dist/icons/Resolve.js.map +1 -1
- package/dist/icons/Resolve.mjs +14 -10
- package/dist/icons/Resolve.mjs.map +1 -1
- package/dist/icons/Resolved.js +16 -12
- package/dist/icons/Resolved.js.map +1 -1
- package/dist/icons/Resolved.mjs +16 -12
- package/dist/icons/Resolved.mjs.map +1 -1
- package/dist/icons/Restore.js +12 -8
- package/dist/icons/Restore.js.map +1 -1
- package/dist/icons/Restore.mjs +12 -8
- package/dist/icons/Restore.mjs.map +1 -1
- package/dist/icons/Search.js +7 -6
- package/dist/icons/Search.js.map +1 -1
- package/dist/icons/Search.mjs +7 -6
- package/dist/icons/Search.mjs.map +1 -1
- package/dist/icons/Send.js +7 -6
- package/dist/icons/Send.js.map +1 -1
- package/dist/icons/Send.mjs +7 -6
- package/dist/icons/Send.mjs.map +1 -1
- package/dist/icons/Spinner.js +8 -7
- package/dist/icons/Spinner.js.map +1 -1
- package/dist/icons/Spinner.mjs +8 -7
- package/dist/icons/Spinner.mjs.map +1 -1
- package/dist/icons/Strikethrough.js +7 -6
- package/dist/icons/Strikethrough.js.map +1 -1
- package/dist/icons/Strikethrough.mjs +7 -6
- package/dist/icons/Strikethrough.mjs.map +1 -1
- package/dist/icons/Warning.js +14 -10
- package/dist/icons/Warning.js.map +1 -1
- package/dist/icons/Warning.mjs +14 -10
- package/dist/icons/Warning.mjs.map +1 -1
- package/dist/icons/index.js +42 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/index.mjs +19 -0
- package/dist/icons/index.mjs.map +1 -0
- package/dist/index.d.mts +14 -12
- package/dist/index.d.ts +14 -12
- package/dist/overrides.js +65 -36
- package/dist/overrides.js.map +1 -1
- package/dist/overrides.mjs +59 -12
- package/dist/overrides.mjs.map +1 -1
- package/dist/primitives/Comment/index.js +75 -66
- package/dist/primitives/Comment/index.js.map +1 -1
- package/dist/primitives/Comment/index.mjs +71 -62
- package/dist/primitives/Comment/index.mjs.map +1 -1
- package/dist/primitives/Composer/contexts.js +11 -11
- package/dist/primitives/Composer/index.js +343 -284
- package/dist/primitives/Composer/index.js.map +1 -1
- package/dist/primitives/Composer/index.mjs +262 -203
- package/dist/primitives/Composer/index.mjs.map +1 -1
- package/dist/primitives/Composer/utils.js +20 -21
- package/dist/primitives/Composer/utils.js.map +1 -1
- package/dist/primitives/Composer/utils.mjs +4 -5
- package/dist/primitives/Composer/utils.mjs.map +1 -1
- package/dist/primitives/EmojiPicker/contexts.js +3 -3
- package/dist/primitives/EmojiPicker/index.js +160 -142
- package/dist/primitives/EmojiPicker/index.js.map +1 -1
- package/dist/primitives/EmojiPicker/index.mjs +122 -104
- package/dist/primitives/EmojiPicker/index.mjs.map +1 -1
- package/dist/primitives/FileSize.js +9 -7
- package/dist/primitives/FileSize.js.map +1 -1
- package/dist/primitives/FileSize.mjs +7 -5
- package/dist/primitives/FileSize.mjs.map +1 -1
- package/dist/primitives/Timestamp.js +12 -10
- package/dist/primitives/Timestamp.js.map +1 -1
- package/dist/primitives/Timestamp.mjs +7 -5
- package/dist/primitives/Timestamp.mjs.map +1 -1
- package/dist/primitives/index.d.mts +24 -23
- package/dist/primitives/index.d.ts +24 -23
- package/dist/primitives/internal/Emoji.js +7 -5
- package/dist/primitives/internal/Emoji.js.map +1 -1
- package/dist/primitives/internal/Emoji.mjs +6 -4
- package/dist/primitives/internal/Emoji.mjs.map +1 -1
- package/dist/shared.js +2 -7
- package/dist/shared.js.map +1 -1
- package/dist/shared.mjs +2 -7
- package/dist/shared.mjs.map +1 -1
- package/dist/slate/plugins/auto-links.mjs +1 -1
- package/dist/slate/plugins/custom-links.mjs +1 -1
- package/dist/slate/plugins/mentions.mjs +1 -1
- package/dist/utils/Persist.js +19 -18
- package/dist/utils/Persist.js.map +1 -1
- package/dist/utils/Persist.mjs +7 -6
- package/dist/utils/Persist.mjs.map +1 -1
- package/dist/utils/Portal.js +5 -4
- package/dist/utils/Portal.js.map +1 -1
- package/dist/utils/Portal.mjs +4 -3
- package/dist/utils/Portal.mjs.map +1 -1
- package/dist/utils/use-controllable-state.js +5 -5
- package/dist/utils/use-index.js +7 -7
- package/dist/utils/use-initial.js +2 -2
- package/dist/utils/use-interval.js +4 -4
- package/dist/utils/use-latest.js +3 -3
- package/dist/utils/use-observable.js +2 -2
- package/dist/utils/use-refs.js +2 -2
- package/dist/utils/use-rerender.js +2 -2
- package/dist/utils/use-visible.js +24 -2
- package/dist/utils/use-visible.js.map +1 -1
- package/dist/utils/use-visible.mjs +23 -2
- package/dist/utils/use-visible.mjs.map +1 -1
- package/dist/utils/use-window-focus.js +2 -2
- package/dist/utils/use-window-focus.js.map +1 -1
- package/dist/utils/use-window-focus.mjs +1 -1
- package/dist/utils/use-window-focus.mjs.map +1 -1
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/dist/version.mjs +2 -2
- package/dist/version.mjs.map +1 -1
- package/package.json +10 -25
- package/dist/utils/use-id.js +0 -29
- package/dist/utils/use-id.js.map +0 -1
- package/dist/utils/use-id.mjs +0 -27
- package/dist/utils/use-id.mjs.map +0 -1
- package/dist/utils/use-layout-effect.js +0 -8
- package/dist/utils/use-layout-effect.js.map +0 -1
- package/dist/utils/use-layout-effect.mjs +0 -6
- package/dist/utils/use-layout-effect.mjs.map +0 -1
- package/dist/utils/use-transition.js +0 -16
- package/dist/utils/use-transition.js.map +0 -1
- package/dist/utils/use-transition.mjs +0 -14
- 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
|
|
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/
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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 =
|
|
56
|
-
const iconGlyph =
|
|
57
|
-
return /* @__PURE__ */
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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] =
|
|
86
|
-
const handleLoad =
|
|
89
|
+
const [isLoaded, setLoaded] = react.useState(false);
|
|
90
|
+
const handleLoad = react.useCallback(() => {
|
|
87
91
|
setLoaded(true);
|
|
88
92
|
}, []);
|
|
89
|
-
return /* @__PURE__ */
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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] =
|
|
106
|
-
const handleLoad =
|
|
115
|
+
const [isLoaded, setLoaded] = react.useState(false);
|
|
116
|
+
const handleLoad = react.useCallback(() => {
|
|
107
117
|
setLoaded(true);
|
|
108
118
|
}, []);
|
|
109
|
-
return /* @__PURE__ */
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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] =
|
|
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__ */
|
|
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__ */
|
|
153
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AttachmentVideoPreview, {
|
|
138
154
|
attachment,
|
|
139
155
|
markPreviewAsUnsupported,
|
|
140
156
|
roomId
|
|
141
157
|
});
|
|
142
158
|
}
|
|
143
159
|
}
|
|
144
|
-
return /* @__PURE__ */
|
|
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 } =
|
|
167
|
+
const { base: fileBaseName, extension: fileExtension } = react.useMemo(() => {
|
|
152
168
|
return splitFileName(attachment.name);
|
|
153
169
|
}, [attachment.name]);
|
|
154
|
-
return /* @__PURE__ */
|
|
170
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", {
|
|
155
171
|
className: "lb-attachment-name",
|
|
156
|
-
title: attachment.name
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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 =
|
|
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 =
|
|
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__ */
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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 =
|
|
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__ */
|
|
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
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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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"}
|