@liveblocks/react-ui 2.15.0-debug1 → 2.15.1
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.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 +8 -6
- package/dist/components/Comment.js.map +1 -1
- package/dist/components/Comment.mjs +5 -3
- package/dist/components/Comment.mjs.map +1 -1
- package/dist/components/Composer.js +5 -2
- package/dist/components/Composer.js.map +1 -1
- package/dist/components/Composer.mjs +9 -7
- package/dist/components/Composer.mjs.map +1 -1
- package/dist/components/HistoryVersionSummary.js +4 -10
- package/dist/components/HistoryVersionSummary.js.map +1 -1
- package/dist/components/HistoryVersionSummary.mjs +4 -10
- package/dist/components/HistoryVersionSummary.mjs.map +1 -1
- package/dist/components/HistoryVersionSummaryList.js +2 -0
- package/dist/components/HistoryVersionSummaryList.js.map +1 -1
- package/dist/components/HistoryVersionSummaryList.mjs +2 -0
- package/dist/components/HistoryVersionSummaryList.mjs.map +1 -1
- package/dist/components/InboxNotification.js +2 -0
- package/dist/components/InboxNotification.js.map +1 -1
- package/dist/components/InboxNotification.mjs +2 -0
- package/dist/components/InboxNotification.mjs.map +1 -1
- package/dist/components/InboxNotificationList.js +2 -0
- package/dist/components/InboxNotificationList.js.map +1 -1
- package/dist/components/InboxNotificationList.mjs +4 -2
- package/dist/components/InboxNotificationList.mjs.map +1 -1
- package/dist/components/Thread.js +2 -0
- package/dist/components/Thread.js.map +1 -1
- package/dist/components/Thread.mjs +2 -0
- package/dist/components/Thread.mjs.map +1 -1
- package/dist/components/internal/Attachment.js +4 -6
- package/dist/components/internal/Attachment.js.map +1 -1
- package/dist/components/internal/Attachment.mjs +6 -8
- package/dist/components/internal/Attachment.mjs.map +1 -1
- package/dist/components/internal/Avatar.js +2 -0
- package/dist/components/internal/Avatar.js.map +1 -1
- package/dist/components/internal/Avatar.mjs +2 -0
- package/dist/components/internal/Avatar.mjs.map +1 -1
- package/dist/components/internal/Button.js +2 -0
- package/dist/components/internal/Button.js.map +1 -1
- package/dist/components/internal/Button.mjs +2 -0
- package/dist/components/internal/Button.mjs.map +1 -1
- package/dist/components/internal/Dropdown.js +2 -0
- package/dist/components/internal/Dropdown.js.map +1 -1
- package/dist/components/internal/Dropdown.mjs +3 -1
- package/dist/components/internal/Dropdown.mjs.map +1 -1
- package/dist/components/internal/EmojiPicker.mjs +2 -2
- package/dist/components/internal/Room.js +2 -0
- package/dist/components/internal/Room.js.map +1 -1
- package/dist/components/internal/Room.mjs +2 -0
- package/dist/components/internal/Room.mjs.map +1 -1
- package/dist/components/internal/Tooltip.js +2 -0
- package/dist/components/internal/Tooltip.js.map +1 -1
- package/dist/components/internal/Tooltip.mjs +2 -0
- package/dist/components/internal/Tooltip.mjs.map +1 -1
- package/dist/components/internal/User.js +2 -0
- package/dist/components/internal/User.js.map +1 -1
- package/dist/components/internal/User.mjs +2 -0
- package/dist/components/internal/User.mjs.map +1 -1
- package/dist/components.js +2 -0
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +2 -0
- package/dist/components.mjs.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/config.mjs +2 -0
- package/dist/config.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/overrides.js +2 -0
- package/dist/overrides.js.map +1 -1
- package/dist/overrides.mjs +2 -0
- package/dist/overrides.mjs.map +1 -1
- package/dist/primitives/Composer/index.js +15 -13
- package/dist/primitives/Composer/index.js.map +1 -1
- package/dist/primitives/Composer/index.mjs +11 -9
- package/dist/primitives/Composer/index.mjs.map +1 -1
- package/dist/primitives/Composer/utils.js +2 -1
- package/dist/primitives/Composer/utils.js.map +1 -1
- package/dist/primitives/Composer/utils.mjs +4 -3
- package/dist/primitives/Composer/utils.mjs.map +1 -1
- package/dist/primitives/EmojiPicker/index.js +2 -0
- package/dist/primitives/EmojiPicker/index.js.map +1 -1
- package/dist/primitives/EmojiPicker/index.mjs +4 -2
- package/dist/primitives/EmojiPicker/index.mjs.map +1 -1
- package/dist/primitives/FileSize.js +2 -0
- package/dist/primitives/FileSize.js.map +1 -1
- package/dist/primitives/FileSize.mjs +2 -0
- package/dist/primitives/FileSize.mjs.map +1 -1
- package/dist/primitives/Timestamp.js +2 -0
- package/dist/primitives/Timestamp.js.map +1 -1
- package/dist/primitives/Timestamp.mjs +2 -0
- package/dist/primitives/Timestamp.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 +2 -0
- package/dist/utils/Persist.js.map +1 -1
- package/dist/utils/Persist.mjs +3 -1
- package/dist/utils/Persist.mjs.map +1 -1
- package/dist/utils/Portal.js +2 -0
- package/dist/utils/Portal.js.map +1 -1
- package/dist/utils/Portal.mjs +2 -0
- package/dist/utils/Portal.mjs.map +1 -1
- package/dist/utils/use-visible.js +22 -0
- 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/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 +8 -21
package/dist/_private/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var Button = require('../components/internal/Button.js');
|
|
4
4
|
var List = require('../components/internal/List.js');
|
|
5
5
|
var User = require('../components/internal/User.js');
|
|
6
|
+
require('../icons/index.js');
|
|
6
7
|
var ArrowDown = require('../icons/ArrowDown.js');
|
|
7
8
|
var ArrowUp = require('../icons/ArrowUp.js');
|
|
8
9
|
var Attachment = require('../icons/Attachment.js');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/_private/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Button } from '../components/internal/Button.mjs';
|
|
2
2
|
export { List } from '../components/internal/List.mjs';
|
|
3
3
|
export { User } from '../components/internal/User.mjs';
|
|
4
|
+
import '../icons/index.mjs';
|
|
4
5
|
export { ArrowDownIcon } from '../icons/ArrowDown.mjs';
|
|
5
6
|
export { ArrowUpIcon } from '../icons/ArrowUp.mjs';
|
|
6
7
|
export { AttachmentIcon } from '../icons/Attachment.mjs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
'use strict';
|
|
2
3
|
|
|
3
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -11,8 +12,8 @@ var Edit = require('../icons/Edit.js');
|
|
|
11
12
|
var Ellipsis = require('../icons/Ellipsis.js');
|
|
12
13
|
var EmojiAdd = require('../icons/EmojiAdd.js');
|
|
13
14
|
var overrides = require('../overrides.js');
|
|
14
|
-
var index
|
|
15
|
-
var index = require('../primitives/Composer/index.js');
|
|
15
|
+
var index = require('../primitives/Comment/index.js');
|
|
16
|
+
var index$1 = require('../primitives/Composer/index.js');
|
|
16
17
|
var Timestamp = require('../primitives/Timestamp.js');
|
|
17
18
|
var shared = require('../shared.js');
|
|
18
19
|
var mentions = require('../slate/plugins/mentions.js');
|
|
@@ -54,6 +55,7 @@ function _interopNamespaceDefault(e) {
|
|
|
54
55
|
|
|
55
56
|
var TogglePrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(TogglePrimitive);
|
|
56
57
|
|
|
58
|
+
|
|
57
59
|
const REACTIONS_TRUNCATE = 5;
|
|
58
60
|
function CommentMention({
|
|
59
61
|
userId,
|
|
@@ -61,7 +63,7 @@ function CommentMention({
|
|
|
61
63
|
...props
|
|
62
64
|
}) {
|
|
63
65
|
const currentId = shared.useCurrentUserId();
|
|
64
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(index
|
|
66
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(index.Mention, {
|
|
65
67
|
className: classNames.classNames("lb-comment-mention", className),
|
|
66
68
|
"data-self": userId === currentId ? "" : void 0,
|
|
67
69
|
...props,
|
|
@@ -79,7 +81,7 @@ function CommentLink({
|
|
|
79
81
|
className,
|
|
80
82
|
...props
|
|
81
83
|
}) {
|
|
82
|
-
return /* @__PURE__ */ jsxRuntime.jsx(index
|
|
84
|
+
return /* @__PURE__ */ jsxRuntime.jsx(index.Link, {
|
|
83
85
|
className: classNames.classNames("lb-comment-link", className),
|
|
84
86
|
href,
|
|
85
87
|
...props,
|
|
@@ -587,7 +589,7 @@ const Comment = react.forwardRef(
|
|
|
587
589
|
shortcut: /* @__PURE__ */ jsxRuntime.jsx(Tooltip.ShortcutTooltipKey, {
|
|
588
590
|
name: "enter"
|
|
589
591
|
}),
|
|
590
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(index.Submit, {
|
|
592
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Submit, {
|
|
591
593
|
asChild: true,
|
|
592
594
|
children: /* @__PURE__ */ jsxRuntime.jsx(Button.Button, {
|
|
593
595
|
variant: "primary",
|
|
@@ -608,7 +610,7 @@ const Comment = react.forwardRef(
|
|
|
608
610
|
roomId: comment.roomId
|
|
609
611
|
}) : comment.body ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
610
612
|
children: [
|
|
611
|
-
/* @__PURE__ */ jsxRuntime.jsx(index
|
|
613
|
+
/* @__PURE__ */ jsxRuntime.jsx(index.Body, {
|
|
612
614
|
className: "lb-comment-body",
|
|
613
615
|
body: comment.body,
|
|
614
616
|
components: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Comment.js","sources":["../../src/components/Comment.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n CommentAttachment,\n CommentData,\n CommentReaction as CommentReactionData,\n} from \"@liveblocks/core\";\nimport {\n useAddRoomCommentReaction,\n useDeleteRoomComment,\n useEditRoomComment,\n useMarkRoomThreadAsRead,\n useRemoveRoomCommentReaction,\n useRoomAttachmentUrl,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n FormEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { CheckIcon } from \"../icons/Check\";\nimport { CrossIcon } from \"../icons/Cross\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EditIcon } from \"../icons/Edit\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { EmojiAddIcon } from \"../icons/EmojiAdd\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport type { ComposerSubmitComment } from \"../primitives\";\nimport * as CommentPrimitive from \"../primitives/Comment\";\nimport type {\n CommentBodyLinkProps,\n CommentBodyMentionProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"../primitives/Comment/types\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { CommentAttachmentArgs } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { download } from \"../utils/download\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useVisibleCallback } from \"../utils/use-visible\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport {\n FileAttachment,\n MediaAttachment,\n separateMediaAttachments,\n} from \"./internal/Attachment\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport { Emoji } from \"./internal/Emoji\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { List } from \"./internal/List\";\nimport {\n ShortcutTooltip,\n ShortcutTooltipKey,\n Tooltip,\n TooltipProvider,\n} from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\nconst REACTIONS_TRUNCATE = 5;\n\nexport interface CommentProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The comment to display.\n */\n comment: CommentData;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n\n /**\n * Whether to show the comment if it was deleted. If set to `false`, it will render deleted comments as `null`.\n */\n showDeleted?: boolean;\n\n /**\n * Whether to show reactions.\n */\n showReactions?: boolean;\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n\n /**\n * Whether to show the composer's formatting controls when editing the comment.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comment's content.\n */\n indentContent?: boolean;\n\n /**\n * The event handler called when the comment is edited.\n */\n onCommentEdit?: (comment: CommentData) => void;\n\n /**\n * The event handler called when the comment is deleted.\n */\n onCommentDelete?: (comment: CommentData) => void;\n\n /**\n * The event handler called when clicking on the author.\n */\n onAuthorClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: (\n args: CommentAttachmentArgs,\n event: MouseEvent<HTMLElement>\n ) => void;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n autoMarkReadThreadId?: string;\n\n /**\n * @internal\n */\n additionalActions?: ReactNode;\n\n /**\n * @internal\n */\n additionalActionsClassName?: string;\n}\n\ninterface CommentReactionButtonProps\n extends ComponentPropsWithoutRef<typeof Button> {\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ninterface CommentReactionProps extends ComponentPropsWithoutRef<\"button\"> {\n comment: CommentData;\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ntype CommentNonInteractiveReactionProps = Omit<CommentReactionProps, \"comment\">;\n\ninterface CommentAttachmentProps extends ComponentProps<typeof FileAttachment> {\n attachment: CommentAttachment;\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n}\n\nexport function CommentMention({\n userId,\n className,\n ...props\n}: CommentBodyMentionProps & CommentMentionProps) {\n const currentId = useCurrentUserId();\n return (\n <CommentPrimitive.Mention\n className={classNames(\"lb-comment-mention\", className)}\n data-self={userId === currentId ? \"\" : undefined}\n {...props}\n >\n {MENTION_CHARACTER}\n <User userId={userId} />\n </CommentPrimitive.Mention>\n );\n}\n\nexport function CommentLink({\n href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <CommentPrimitive.Link\n className={classNames(\"lb-comment-link\", className)}\n href={href}\n {...props}\n >\n {children}\n </CommentPrimitive.Link>\n );\n}\n\nexport function CommentNonInteractiveLink({\n href: _href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <span className={classNames(\"lb-comment-link\", className)} {...props}>\n {children}\n </span>\n );\n}\n\nconst CommentReactionButton = forwardRef<\n HTMLButtonElement,\n CommentReactionButtonProps\n>(({ reaction, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n return (\n <Button\n className={classNames(\"lb-comment-reaction\", className)}\n variant=\"outline\"\n aria-label={$.COMMENT_REACTION_DESCRIPTION(\n reaction.emoji,\n reaction.users.length\n )}\n {...props}\n ref={forwardedRef}\n >\n <Emoji className=\"lb-comment-reaction-emoji\" emoji={reaction.emoji} />\n <span className=\"lb-comment-reaction-count\">{reaction.users.length}</span>\n </Button>\n );\n});\n\nexport const CommentReaction = forwardRef<\n HTMLButtonElement,\n CommentReactionProps\n>(({ comment, reaction, overrides, disabled, ...props }, forwardedRef) => {\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n const $ = useOverrides(overrides);\n const tooltipContent = useMemo(\n () => (\n <span>\n {$.COMMENT_REACTION_LIST(\n <List\n values={reaction.users.map((users) => (\n <User key={users.id} userId={users.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={REACTIONS_TRUNCATE}\n locale={$.locale}\n />,\n reaction.emoji,\n reaction.users.length\n )}\n </span>\n ),\n [$, reaction]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handlePressedChange = useCallback(\n (isPressed: boolean) => {\n if (isPressed) {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n } else {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n }\n },\n [addReaction, comment.threadId, comment.id, reaction.emoji, removeReaction]\n );\n\n return (\n <Tooltip\n content={tooltipContent}\n multiline\n className=\"lb-comment-reaction-tooltip\"\n >\n <TogglePrimitive.Root\n asChild\n pressed={isActive}\n onPressedChange={handlePressedChange}\n onClick={stopPropagation}\n disabled={disabled}\n ref={forwardedRef}\n >\n <CommentReactionButton\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n />\n </TogglePrimitive.Root>\n </Tooltip>\n );\n});\n\nexport const CommentNonInteractiveReaction = forwardRef<\n HTMLButtonElement,\n CommentNonInteractiveReactionProps\n>(({ reaction, overrides, ...props }, forwardedRef) => {\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n\n return (\n <CommentReactionButton\n disableable={false}\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nfunction openAttachment({ attachment, url }: CommentAttachmentArgs) {\n // Open the attachment in a new tab if the attachment is a PDF,\n // an image, a video, or audio. Otherwise, download it.\n if (\n attachment.mimeType === \"application/pdf\" ||\n attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\") ||\n attachment.mimeType.startsWith(\"audio/\")\n ) {\n window.open(url, \"_blank\");\n } else {\n download(url, attachment.name);\n }\n}\n\nfunction CommentMediaAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <MediaAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nfunction CommentFileAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nexport function CommentNonInteractiveFileAttachment({\n className,\n ...props\n}: CommentAttachmentProps) {\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n allowMediaPreview={false}\n {...props}\n />\n );\n}\n\n// A void component (which doesn't render anything) responsible for marking a thread\n// as read when the comment it's used in becomes visible.\n// Moving this logic into a separate component allows us to use the visibility\n// and focus hooks \"conditionally\" by conditionally rendering this component.\nfunction AutoMarkReadThreadIdHandler({\n threadId,\n roomId,\n commentRef,\n}: {\n threadId: string;\n roomId: string;\n commentRef: RefObject<HTMLElement>;\n}) {\n const markThreadAsRead = useMarkRoomThreadAsRead(roomId);\n const isWindowFocused = useWindowFocus();\n\n useVisibleCallback(\n commentRef,\n () => {\n markThreadAsRead(threadId);\n },\n {\n // The underlying IntersectionObserver is only enabled when the window is focused\n enabled: isWindowFocused,\n }\n );\n\n return null;\n}\n\n/**\n * Displays a single comment.\n *\n * @example\n * <>\n * {thread.comments.map((comment) => (\n * <Comment key={comment.id} comment={comment} />\n * ))}\n * </>\n */\nexport const Comment = forwardRef<HTMLDivElement, CommentProps>(\n (\n {\n comment,\n indentContent = true,\n showDeleted,\n showActions = \"hover\",\n showReactions = true,\n showAttachments = true,\n showComposerFormattingControls = true,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onCommentEdit,\n onCommentDelete,\n overrides,\n className,\n additionalActions,\n additionalActionsClassName,\n autoMarkReadThreadId,\n ...props\n },\n forwardedRef\n ) => {\n const ref = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, ref);\n const currentUserId = useCurrentUserId();\n const deleteComment = useDeleteRoomComment(comment.roomId);\n const editComment = useEditRoomComment(comment.roomId);\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const $ = useOverrides(overrides);\n const [isEditing, setEditing] = useState(false);\n const [isTarget, setTarget] = useState(false);\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const [isReactionActionOpen, setReactionActionOpen] = useState(false);\n const { mediaAttachments, fileAttachments } = useMemo(() => {\n return separateMediaAttachments(comment.attachments);\n }, [comment.attachments]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEdit = useCallback(() => {\n setEditing(true);\n }, []);\n\n const handleEditCancel = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setEditing(false);\n },\n []\n );\n\n const handleEditSubmit = useCallback(\n (\n { body, attachments }: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentEdit?.(comment);\n\n event.preventDefault();\n setEditing(false);\n editComment({\n commentId: comment.id,\n threadId: comment.threadId,\n body,\n attachments,\n });\n },\n [comment, editComment, onCommentEdit]\n );\n\n const handleDelete = useCallback(() => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentDelete?.(comment);\n\n deleteComment({\n commentId: comment.id,\n threadId: comment.threadId,\n });\n }, [comment, deleteComment, onCommentDelete]);\n\n const handleAuthorClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n onAuthorClick?.(comment.userId, event);\n },\n [comment.userId, onAuthorClick]\n );\n\n const handleReactionSelect = useCallback(\n (emoji: string) => {\n const reactionIndex = comment.reactions.findIndex(\n (reaction) => reaction.emoji === emoji\n );\n\n if (\n reactionIndex >= 0 &&\n currentUserId &&\n comment.reactions[reactionIndex]?.users.some(\n (user) => user.id === currentUserId\n )\n ) {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n } else {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n }\n },\n [\n addReaction,\n comment.id,\n comment.reactions,\n comment.threadId,\n removeReaction,\n currentUserId,\n ]\n );\n\n useEffect(() => {\n const isWindowDefined = typeof window !== \"undefined\";\n if (!isWindowDefined) return;\n\n const hash = window.location.hash;\n const commentId = hash.slice(1);\n\n if (commentId === comment.id) {\n setTarget(true);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!showDeleted && !comment.body) {\n return null;\n }\n\n return (\n <TooltipProvider>\n {autoMarkReadThreadId && (\n <AutoMarkReadThreadIdHandler\n commentRef={ref}\n threadId={autoMarkReadThreadId}\n roomId={comment.roomId}\n />\n )}\n <div\n id={comment.id}\n className={classNames(\n \"lb-root lb-comment\",\n indentContent && \"lb-comment:indent-content\",\n showActions === \"hover\" && \"lb-comment:show-actions-hover\",\n (isMoreActionOpen || isReactionActionOpen) &&\n \"lb-comment:action-open\",\n className\n )}\n data-deleted={!comment.body ? \"\" : undefined}\n data-editing={isEditing ? \"\" : undefined}\n // In some cases, `:target` doesn't work as expected so we also define it manually.\n data-target={isTarget ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={mergedRefs}\n >\n <div className=\"lb-comment-header\">\n <div className=\"lb-comment-details\">\n <Avatar\n className=\"lb-comment-avatar\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-details-labels\">\n <User\n className=\"lb-comment-author\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-date\">\n <Timestamp\n locale={$.locale}\n date={comment.createdAt}\n className=\"lb-date lb-comment-date-created\"\n />\n {comment.editedAt && comment.body && (\n <>\n {\" \"}\n <span className=\"lb-comment-date-edited\">\n {$.COMMENT_EDITED}\n </span>\n </>\n )}\n </span>\n </span>\n </div>\n {showActions && !isEditing && (\n <div\n className={classNames(\n \"lb-comment-actions\",\n additionalActionsClassName\n )}\n >\n {additionalActions ?? null}\n {showReactions && (\n <EmojiPicker\n onEmojiSelect={handleReactionSelect}\n onOpenChange={setReactionActionOpen}\n >\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n >\n <EmojiAddIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n )}\n {comment.userId === currentUserId && (\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n <DropdownItem\n onSelect={handleEdit}\n onClick={stopPropagation}\n >\n <EditIcon className=\"lb-dropdown-item-icon\" />\n {$.COMMENT_EDIT}\n </DropdownItem>\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n >\n <DeleteIcon className=\"lb-dropdown-item-icon\" />\n {$.COMMENT_DELETE}\n </DropdownItem>\n </>\n }\n >\n <Tooltip content={$.COMMENT_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n disabled={!comment.body}\n onClick={stopPropagation}\n aria-label={$.COMMENT_MORE}\n >\n <EllipsisIcon className=\"lb-button-icon\" />\n </Button>\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n )}\n </div>\n )}\n </div>\n <div className=\"lb-comment-content\">\n {isEditing ? (\n <Composer\n className=\"lb-comment-composer\"\n onComposerSubmit={handleEditSubmit}\n defaultValue={comment.body}\n defaultAttachments={comment.attachments}\n autoFocus\n showAttribution={false}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n actions={\n <>\n <Tooltip\n content={$.COMMENT_EDIT_COMPOSER_CANCEL}\n aria-label={$.COMMENT_EDIT_COMPOSER_CANCEL}\n >\n <Button\n className=\"lb-composer-action\"\n onClick={handleEditCancel}\n >\n <CrossIcon className=\"lb-button-icon\" />\n </Button>\n </Tooltip>\n <ShortcutTooltip\n content={$.COMMENT_EDIT_COMPOSER_SAVE}\n shortcut={<ShortcutTooltipKey name=\"enter\" />}\n >\n <ComposerPrimitive.Submit asChild>\n <Button\n variant=\"primary\"\n className=\"lb-composer-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_EDIT_COMPOSER_SAVE}\n >\n <CheckIcon className=\"lb-button-icon\" />\n </Button>\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n }\n overrides={{\n COMPOSER_PLACEHOLDER: $.COMMENT_EDIT_COMPOSER_PLACEHOLDER,\n }}\n roomId={comment.roomId}\n />\n ) : comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: ({ userId }) => (\n <CommentMention\n userId={userId}\n onClick={(event) => onMentionClick?.(userId, event)}\n />\n ),\n Link: CommentLink,\n }}\n />\n {showAttachments &&\n (mediaAttachments.length > 0 || fileAttachments.length > 0) ? (\n <div className=\"lb-comment-attachments\">\n {mediaAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {mediaAttachments.map((attachment) => (\n <CommentMediaAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n {fileAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {fileAttachments.map((attachment) => (\n <CommentFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentReaction\n key={reaction.emoji}\n comment={comment}\n reaction={reaction}\n overrides={overrides}\n />\n ))}\n <EmojiPicker onEmojiSelect={handleReactionSelect}>\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-reaction lb-comment-reaction-add\"\n variant=\"outline\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n >\n <EmojiAddIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n </TooltipProvider>\n );\n }\n);\n"],"names":["useCurrentUserId","jsxs","CommentPrimitive.Mention","classNames","MENTION_CHARACTER","jsx","User","CommentPrimitive.Link","forwardRef","overrides","useOverrides","Button","Emoji","useAddRoomCommentReaction","useRemoveRoomCommentReaction","useMemo","List","useCallback","Tooltip","TogglePrimitive","download","useRoomAttachmentUrl","MediaAttachment","FileAttachment","useMarkRoomThreadAsRead","useWindowFocus","useVisibleCallback","useRef","useRefs","useDeleteRoomComment","useEditRoomComment","useState","separateMediaAttachments","useEffect","TooltipProvider","Avatar","Timestamp","Fragment","EmojiPicker","EmojiPickerTrigger","EmojiAddIcon","Dropdown","DropdownItem","EditIcon","DeleteIcon","DropdownTrigger","EllipsisIcon","Composer","CrossIcon","ShortcutTooltip","ShortcutTooltipKey","ComposerPrimitive.Submit","CheckIcon","CommentPrimitive.Body"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Comment.js","sources":["../../src/components/Comment.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n CommentAttachment,\n CommentData,\n CommentReaction as CommentReactionData,\n} from \"@liveblocks/core\";\nimport {\n useAddRoomCommentReaction,\n useDeleteRoomComment,\n useEditRoomComment,\n useMarkRoomThreadAsRead,\n useRemoveRoomCommentReaction,\n useRoomAttachmentUrl,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n FormEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { CheckIcon } from \"../icons/Check\";\nimport { CrossIcon } from \"../icons/Cross\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EditIcon } from \"../icons/Edit\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { EmojiAddIcon } from \"../icons/EmojiAdd\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport type { ComposerSubmitComment } from \"../primitives\";\nimport * as CommentPrimitive from \"../primitives/Comment\";\nimport type {\n CommentBodyLinkProps,\n CommentBodyMentionProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"../primitives/Comment/types\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { CommentAttachmentArgs } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { download } from \"../utils/download\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useVisibleCallback } from \"../utils/use-visible\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport {\n FileAttachment,\n MediaAttachment,\n separateMediaAttachments,\n} from \"./internal/Attachment\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport { Emoji } from \"./internal/Emoji\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { List } from \"./internal/List\";\nimport {\n ShortcutTooltip,\n ShortcutTooltipKey,\n Tooltip,\n TooltipProvider,\n} from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\nconst REACTIONS_TRUNCATE = 5;\n\nexport interface CommentProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The comment to display.\n */\n comment: CommentData;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n\n /**\n * Whether to show the comment if it was deleted. If set to `false`, it will render deleted comments as `null`.\n */\n showDeleted?: boolean;\n\n /**\n * Whether to show reactions.\n */\n showReactions?: boolean;\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n\n /**\n * Whether to show the composer's formatting controls when editing the comment.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comment's content.\n */\n indentContent?: boolean;\n\n /**\n * The event handler called when the comment is edited.\n */\n onCommentEdit?: (comment: CommentData) => void;\n\n /**\n * The event handler called when the comment is deleted.\n */\n onCommentDelete?: (comment: CommentData) => void;\n\n /**\n * The event handler called when clicking on the author.\n */\n onAuthorClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: (\n args: CommentAttachmentArgs,\n event: MouseEvent<HTMLElement>\n ) => void;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n autoMarkReadThreadId?: string;\n\n /**\n * @internal\n */\n additionalActions?: ReactNode;\n\n /**\n * @internal\n */\n additionalActionsClassName?: string;\n}\n\ninterface CommentReactionButtonProps\n extends ComponentPropsWithoutRef<typeof Button> {\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ninterface CommentReactionProps extends ComponentPropsWithoutRef<\"button\"> {\n comment: CommentData;\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ntype CommentNonInteractiveReactionProps = Omit<CommentReactionProps, \"comment\">;\n\ninterface CommentAttachmentProps extends ComponentProps<typeof FileAttachment> {\n attachment: CommentAttachment;\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n}\n\nexport function CommentMention({\n userId,\n className,\n ...props\n}: CommentBodyMentionProps & CommentMentionProps) {\n const currentId = useCurrentUserId();\n return (\n <CommentPrimitive.Mention\n className={classNames(\"lb-comment-mention\", className)}\n data-self={userId === currentId ? \"\" : undefined}\n {...props}\n >\n {MENTION_CHARACTER}\n <User userId={userId} />\n </CommentPrimitive.Mention>\n );\n}\n\nexport function CommentLink({\n href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <CommentPrimitive.Link\n className={classNames(\"lb-comment-link\", className)}\n href={href}\n {...props}\n >\n {children}\n </CommentPrimitive.Link>\n );\n}\n\nexport function CommentNonInteractiveLink({\n href: _href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <span className={classNames(\"lb-comment-link\", className)} {...props}>\n {children}\n </span>\n );\n}\n\nconst CommentReactionButton = forwardRef<\n HTMLButtonElement,\n CommentReactionButtonProps\n>(({ reaction, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n return (\n <Button\n className={classNames(\"lb-comment-reaction\", className)}\n variant=\"outline\"\n aria-label={$.COMMENT_REACTION_DESCRIPTION(\n reaction.emoji,\n reaction.users.length\n )}\n {...props}\n ref={forwardedRef}\n >\n <Emoji className=\"lb-comment-reaction-emoji\" emoji={reaction.emoji} />\n <span className=\"lb-comment-reaction-count\">{reaction.users.length}</span>\n </Button>\n );\n});\n\nexport const CommentReaction = forwardRef<\n HTMLButtonElement,\n CommentReactionProps\n>(({ comment, reaction, overrides, disabled, ...props }, forwardedRef) => {\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n const $ = useOverrides(overrides);\n const tooltipContent = useMemo(\n () => (\n <span>\n {$.COMMENT_REACTION_LIST(\n <List\n values={reaction.users.map((users) => (\n <User key={users.id} userId={users.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={REACTIONS_TRUNCATE}\n locale={$.locale}\n />,\n reaction.emoji,\n reaction.users.length\n )}\n </span>\n ),\n [$, reaction]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handlePressedChange = useCallback(\n (isPressed: boolean) => {\n if (isPressed) {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n } else {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n }\n },\n [addReaction, comment.threadId, comment.id, reaction.emoji, removeReaction]\n );\n\n return (\n <Tooltip\n content={tooltipContent}\n multiline\n className=\"lb-comment-reaction-tooltip\"\n >\n <TogglePrimitive.Root\n asChild\n pressed={isActive}\n onPressedChange={handlePressedChange}\n onClick={stopPropagation}\n disabled={disabled}\n ref={forwardedRef}\n >\n <CommentReactionButton\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n />\n </TogglePrimitive.Root>\n </Tooltip>\n );\n});\n\nexport const CommentNonInteractiveReaction = forwardRef<\n HTMLButtonElement,\n CommentNonInteractiveReactionProps\n>(({ reaction, overrides, ...props }, forwardedRef) => {\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n\n return (\n <CommentReactionButton\n disableable={false}\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nfunction openAttachment({ attachment, url }: CommentAttachmentArgs) {\n // Open the attachment in a new tab if the attachment is a PDF,\n // an image, a video, or audio. Otherwise, download it.\n if (\n attachment.mimeType === \"application/pdf\" ||\n attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\") ||\n attachment.mimeType.startsWith(\"audio/\")\n ) {\n window.open(url, \"_blank\");\n } else {\n download(url, attachment.name);\n }\n}\n\nfunction CommentMediaAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <MediaAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nfunction CommentFileAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nexport function CommentNonInteractiveFileAttachment({\n className,\n ...props\n}: CommentAttachmentProps) {\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n allowMediaPreview={false}\n {...props}\n />\n );\n}\n\n// A void component (which doesn't render anything) responsible for marking a thread\n// as read when the comment it's used in becomes visible.\n// Moving this logic into a separate component allows us to use the visibility\n// and focus hooks \"conditionally\" by conditionally rendering this component.\nfunction AutoMarkReadThreadIdHandler({\n threadId,\n roomId,\n commentRef,\n}: {\n threadId: string;\n roomId: string;\n commentRef: RefObject<HTMLElement>;\n}) {\n const markThreadAsRead = useMarkRoomThreadAsRead(roomId);\n const isWindowFocused = useWindowFocus();\n\n useVisibleCallback(\n commentRef,\n () => {\n markThreadAsRead(threadId);\n },\n {\n // The underlying IntersectionObserver is only enabled when the window is focused\n enabled: isWindowFocused,\n }\n );\n\n return null;\n}\n\n/**\n * Displays a single comment.\n *\n * @example\n * <>\n * {thread.comments.map((comment) => (\n * <Comment key={comment.id} comment={comment} />\n * ))}\n * </>\n */\nexport const Comment = forwardRef<HTMLDivElement, CommentProps>(\n (\n {\n comment,\n indentContent = true,\n showDeleted,\n showActions = \"hover\",\n showReactions = true,\n showAttachments = true,\n showComposerFormattingControls = true,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onCommentEdit,\n onCommentDelete,\n overrides,\n className,\n additionalActions,\n additionalActionsClassName,\n autoMarkReadThreadId,\n ...props\n },\n forwardedRef\n ) => {\n const ref = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, ref);\n const currentUserId = useCurrentUserId();\n const deleteComment = useDeleteRoomComment(comment.roomId);\n const editComment = useEditRoomComment(comment.roomId);\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const $ = useOverrides(overrides);\n const [isEditing, setEditing] = useState(false);\n const [isTarget, setTarget] = useState(false);\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const [isReactionActionOpen, setReactionActionOpen] = useState(false);\n const { mediaAttachments, fileAttachments } = useMemo(() => {\n return separateMediaAttachments(comment.attachments);\n }, [comment.attachments]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEdit = useCallback(() => {\n setEditing(true);\n }, []);\n\n const handleEditCancel = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setEditing(false);\n },\n []\n );\n\n const handleEditSubmit = useCallback(\n (\n { body, attachments }: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentEdit?.(comment);\n\n event.preventDefault();\n setEditing(false);\n editComment({\n commentId: comment.id,\n threadId: comment.threadId,\n body,\n attachments,\n });\n },\n [comment, editComment, onCommentEdit]\n );\n\n const handleDelete = useCallback(() => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentDelete?.(comment);\n\n deleteComment({\n commentId: comment.id,\n threadId: comment.threadId,\n });\n }, [comment, deleteComment, onCommentDelete]);\n\n const handleAuthorClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n onAuthorClick?.(comment.userId, event);\n },\n [comment.userId, onAuthorClick]\n );\n\n const handleReactionSelect = useCallback(\n (emoji: string) => {\n const reactionIndex = comment.reactions.findIndex(\n (reaction) => reaction.emoji === emoji\n );\n\n if (\n reactionIndex >= 0 &&\n currentUserId &&\n comment.reactions[reactionIndex]?.users.some(\n (user) => user.id === currentUserId\n )\n ) {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n } else {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n }\n },\n [\n addReaction,\n comment.id,\n comment.reactions,\n comment.threadId,\n removeReaction,\n currentUserId,\n ]\n );\n\n useEffect(() => {\n const isWindowDefined = typeof window !== \"undefined\";\n if (!isWindowDefined) return;\n\n const hash = window.location.hash;\n const commentId = hash.slice(1);\n\n if (commentId === comment.id) {\n setTarget(true);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!showDeleted && !comment.body) {\n return null;\n }\n\n return (\n <TooltipProvider>\n {autoMarkReadThreadId && (\n <AutoMarkReadThreadIdHandler\n commentRef={ref}\n threadId={autoMarkReadThreadId}\n roomId={comment.roomId}\n />\n )}\n <div\n id={comment.id}\n className={classNames(\n \"lb-root lb-comment\",\n indentContent && \"lb-comment:indent-content\",\n showActions === \"hover\" && \"lb-comment:show-actions-hover\",\n (isMoreActionOpen || isReactionActionOpen) &&\n \"lb-comment:action-open\",\n className\n )}\n data-deleted={!comment.body ? \"\" : undefined}\n data-editing={isEditing ? \"\" : undefined}\n // In some cases, `:target` doesn't work as expected so we also define it manually.\n data-target={isTarget ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={mergedRefs}\n >\n <div className=\"lb-comment-header\">\n <div className=\"lb-comment-details\">\n <Avatar\n className=\"lb-comment-avatar\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-details-labels\">\n <User\n className=\"lb-comment-author\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-date\">\n <Timestamp\n locale={$.locale}\n date={comment.createdAt}\n className=\"lb-date lb-comment-date-created\"\n />\n {comment.editedAt && comment.body && (\n <>\n {\" \"}\n <span className=\"lb-comment-date-edited\">\n {$.COMMENT_EDITED}\n </span>\n </>\n )}\n </span>\n </span>\n </div>\n {showActions && !isEditing && (\n <div\n className={classNames(\n \"lb-comment-actions\",\n additionalActionsClassName\n )}\n >\n {additionalActions ?? null}\n {showReactions && (\n <EmojiPicker\n onEmojiSelect={handleReactionSelect}\n onOpenChange={setReactionActionOpen}\n >\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n >\n <EmojiAddIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n )}\n {comment.userId === currentUserId && (\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n <DropdownItem\n onSelect={handleEdit}\n onClick={stopPropagation}\n >\n <EditIcon className=\"lb-dropdown-item-icon\" />\n {$.COMMENT_EDIT}\n </DropdownItem>\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n >\n <DeleteIcon className=\"lb-dropdown-item-icon\" />\n {$.COMMENT_DELETE}\n </DropdownItem>\n </>\n }\n >\n <Tooltip content={$.COMMENT_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n disabled={!comment.body}\n onClick={stopPropagation}\n aria-label={$.COMMENT_MORE}\n >\n <EllipsisIcon className=\"lb-button-icon\" />\n </Button>\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n )}\n </div>\n )}\n </div>\n <div className=\"lb-comment-content\">\n {isEditing ? (\n <Composer\n className=\"lb-comment-composer\"\n onComposerSubmit={handleEditSubmit}\n defaultValue={comment.body}\n defaultAttachments={comment.attachments}\n autoFocus\n showAttribution={false}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n actions={\n <>\n <Tooltip\n content={$.COMMENT_EDIT_COMPOSER_CANCEL}\n aria-label={$.COMMENT_EDIT_COMPOSER_CANCEL}\n >\n <Button\n className=\"lb-composer-action\"\n onClick={handleEditCancel}\n >\n <CrossIcon className=\"lb-button-icon\" />\n </Button>\n </Tooltip>\n <ShortcutTooltip\n content={$.COMMENT_EDIT_COMPOSER_SAVE}\n shortcut={<ShortcutTooltipKey name=\"enter\" />}\n >\n <ComposerPrimitive.Submit asChild>\n <Button\n variant=\"primary\"\n className=\"lb-composer-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_EDIT_COMPOSER_SAVE}\n >\n <CheckIcon className=\"lb-button-icon\" />\n </Button>\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n }\n overrides={{\n COMPOSER_PLACEHOLDER: $.COMMENT_EDIT_COMPOSER_PLACEHOLDER,\n }}\n roomId={comment.roomId}\n />\n ) : comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: ({ userId }) => (\n <CommentMention\n userId={userId}\n onClick={(event) => onMentionClick?.(userId, event)}\n />\n ),\n Link: CommentLink,\n }}\n />\n {showAttachments &&\n (mediaAttachments.length > 0 || fileAttachments.length > 0) ? (\n <div className=\"lb-comment-attachments\">\n {mediaAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {mediaAttachments.map((attachment) => (\n <CommentMediaAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n {fileAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {fileAttachments.map((attachment) => (\n <CommentFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentReaction\n key={reaction.emoji}\n comment={comment}\n reaction={reaction}\n overrides={overrides}\n />\n ))}\n <EmojiPicker onEmojiSelect={handleReactionSelect}>\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-reaction lb-comment-reaction-add\"\n variant=\"outline\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n >\n <EmojiAddIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n </TooltipProvider>\n );\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAqFA;AA0GO;AAAwB;AAC7B;AACA;AAEF;AACE;AACA;AACG;AACsD;AACd;AACnC;AAEH;AAAA;AACA;AAAK;AAAgB;AAAA;AAG5B;AAEO;AAAqB;AAC1B;AACA;AACA;AAEF;AACE;AACG;AACmD;AAClD;AACI;AAEH;AAGP;AAEO;AAAmC;AAClC;AACN;AACA;AAEF;AACE;AACG;AAAuD;AAAO;AAC5D;AAGP;AAEA;AAIE;AACA;AACG;AACuD;AAC9C;AACM;AACH;AACM;AACjB;AACI;AACC;AAEL;AAAC;AAAgB;AAA4C;AAAO;AACnE;AAAe;AAA4C;AAAO;AAAA;AAGzE;AAEa;AAIX;AACA;AACA;AACA;AACE;AAA4D;AAE9D;AACA;AAAuB;AAElB;AACI;AACA;AAEI;AAAkC;AAAe;AACnD;AACkB;AACT;AACA;AACZ;AACS;AACM;AACjB;AACF;AAEU;AAGd;AACE;AAAsB;AAGxB;AAA4B;AAExB;AACE;AAAY;AACQ;AACC;AACH;AACjB;AAED;AAAe;AACK;AACC;AACH;AACjB;AACH;AACF;AAC0E;AAG5E;AACG;AACU;AACA;AACC;AAET;AACQ;AACE;AACQ;AACR;AACT;AACK;AAEJ;AAC4B;AAC3B;AACA;AACI;AACN;AACF;AAGN;AAEa;AAIX;AACA;AACE;AAA4D;AAG9D;AACG;AACc;AACc;AAC3B;AACA;AACI;AACC;AAGX;AAEA;AAGE;AAME;AAAyB;AAEzB;AAA6B;AAEjC;AAEA;AAAgC;AAC9B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEA;AAA+B;AAC7B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEO;AAA6C;AAClD;AAEF;AACE;AACG;AACyD;AACrC;AACf;AAGV;AAMA;AAAqC;AACnC;AACA;AAEF;AAKE;AACA;AAEA;AAAA;AACE;AAEE;AAAyB;AAC3B;AACA;AAEW;AACX;AAGF;AACF;AAYO;AAAgB;AAEnB;AACE;AACgB;AAChB;AACc;AACE;AACE;AACe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACE;AAAmD;AAGrD;AACE;AAAsB;AAGxB;AACE;AAAe;AAGjB;AAAyB;AAErB;AACA;AAAgB;AAClB;AACC;AAGH;AAAyB;AAMrB;AAEA;AACA;AACA;AAAY;AACS;AACD;AAClB;AACA;AACD;AACH;AACoC;AAGtC;AAEE;AAEA;AAAc;AACO;AACD;AACnB;AAGH;AAA0B;AAEtB;AAAqC;AACvC;AAC8B;AAGhC;AAA6B;AAEzB;AAAwC;AACL;AAGnC;AAG0C;AAChB;AAGxB;AAAe;AACK;AACC;AACnB;AACD;AAED;AAAY;AACQ;AACC;AACnB;AACD;AACH;AACF;AACA;AACE;AACQ;AACA;AACA;AACR;AACA;AACF;AAGF;AACE;AACA;AAAsB;AAEtB;AACA;AAEA;AACE;AAAc;AAChB;AAGF;AACE;AAAO;AAGT;AACG;AACE;AACE;AACa;AACF;AACM;AAClB;AAED;AACa;AACD;AACT;AACiB;AACU;AAEzB;AACF;AACF;AACmC;AACJ;AAEF;AACtB;AACH;AACC;AAEL;AAAC;AAAc;AACb;AAAC;AAAc;AACb;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACI;AACJ;AACZ;AAEE;AACG;AAAA;AACA;AAAe;AACX;AACL;AAAA;AACF;AAAA;AAEJ;AAAA;AACF;AAAA;AACF;AAEG;AACY;AACT;AACA;AACF;AAEC;AAAqB;AAEnB;AACgB;AACD;AAEb;AAAmB;AACjB;AAA0B;AACxB;AACW;AACD;AACK;AAEb;AAAuB;AAAiB;AAC3C;AACF;AACF;AACF;AAGC;AACO;AACQ;AACR;AAEJ;AACE;AAAC;AACW;AACD;AAET;AAAC;AAAmB;AAAwB;AACzC;AAAA;AACL;AACC;AACW;AACD;AAET;AAAC;AAAqB;AAAwB;AAC3C;AAAA;AACL;AAAA;AACF;AAGD;AAAmB;AACjB;AAAuB;AACrB;AACW;AACS;AACV;AACK;AAEb;AAAuB;AAAiB;AAC3C;AACF;AACF;AACF;AAAA;AAEJ;AAAA;AAEJ;AACC;AAAc;AAEV;AACW;AACQ;AACI;AACM;AACnB;AACQ;AACjB;AACwB;AAEtB;AACE;AAAC;AACY;AACG;AAEb;AACW;AACD;AAER;AAAoB;AAAiB;AACxC;AACF;AACC;AACY;AACA;AAAwB;AAAQ;AAE1C;AAAgC;AAC9B;AACS;AACE;AACD;AACK;AAEb;AAAoB;AAAiB;AACxC;AACF;AACF;AAAA;AACF;AAES;AACe;AAC1B;AACgB;AAGlB;AACE;AAAC;AACW;AACI;AACF;AAEP;AACC;AACkD;AACpD;AAEI;AACR;AACF;AAGG;AAAc;AACZ;AACE;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAED;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAAA;AAEJ;AAED;AAAc;AACZ;AACE;AAEC;AACA;AACA;AAEH;AACA;AAA2B;AACzB;AAAmB;AACjB;AAA0B;AACxB;AACW;AACF;AACC;AACK;AAEb;AAAuB;AAAiB;AAC3C;AACF;AACF;AACF;AAAA;AACF;AAAA;AAIH;AAAc;AACZ;AAAY;AAAwB;AAAgB;AACvD;AAEJ;AAAA;AACF;AAAA;AACF;AAGN;;;;;;;;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { useAddRoomCommentReaction, useRemoveRoomCommentReaction,
|
|
3
|
+
import { useAddRoomCommentReaction, useRemoveRoomCommentReaction, useRoomAttachmentUrl, useMarkRoomThreadAsRead, useDeleteRoomComment, useEditRoomComment } from '@liveblocks/react/_private';
|
|
3
4
|
import * as TogglePrimitive from '@radix-ui/react-toggle';
|
|
4
5
|
import { forwardRef, useMemo, useCallback, useRef, useState, useEffect } from 'react';
|
|
5
6
|
import { CheckIcon } from '../icons/Check.mjs';
|
|
@@ -9,7 +10,7 @@ import { EditIcon } from '../icons/Edit.mjs';
|
|
|
9
10
|
import { EllipsisIcon } from '../icons/Ellipsis.mjs';
|
|
10
11
|
import { EmojiAddIcon } from '../icons/EmojiAdd.mjs';
|
|
11
12
|
import { useOverrides } from '../overrides.mjs';
|
|
12
|
-
import {
|
|
13
|
+
import { Mention as CommentMention$1, Link as CommentLink$1, Body as CommentBody } from '../primitives/Comment/index.mjs';
|
|
13
14
|
import { Submit as ComposerSubmit } from '../primitives/Composer/index.mjs';
|
|
14
15
|
import { Timestamp } from '../primitives/Timestamp.mjs';
|
|
15
16
|
import { useCurrentUserId } from '../shared.mjs';
|
|
@@ -20,7 +21,7 @@ import { useRefs } from '../utils/use-refs.mjs';
|
|
|
20
21
|
import { useVisibleCallback } from '../utils/use-visible.mjs';
|
|
21
22
|
import { useWindowFocus } from '../utils/use-window-focus.mjs';
|
|
22
23
|
import { Composer } from './Composer.mjs';
|
|
23
|
-
import {
|
|
24
|
+
import { MediaAttachment, FileAttachment, separateMediaAttachments } from './internal/Attachment.mjs';
|
|
24
25
|
import { Avatar } from './internal/Avatar.mjs';
|
|
25
26
|
import { Button } from './internal/Button.mjs';
|
|
26
27
|
import { Dropdown, DropdownItem } from './internal/Dropdown.mjs';
|
|
@@ -33,6 +34,7 @@ import { TooltipProvider } from '@radix-ui/react-tooltip';
|
|
|
33
34
|
import { PopoverTrigger } from '@radix-ui/react-popover';
|
|
34
35
|
import { DropdownMenuTrigger } from '@radix-ui/react-dropdown-menu';
|
|
35
36
|
|
|
37
|
+
|
|
36
38
|
const REACTIONS_TRUNCATE = 5;
|
|
37
39
|
function CommentMention({
|
|
38
40
|
userId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Comment.mjs","sources":["../../src/components/Comment.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n CommentAttachment,\n CommentData,\n CommentReaction as CommentReactionData,\n} from \"@liveblocks/core\";\nimport {\n useAddRoomCommentReaction,\n useDeleteRoomComment,\n useEditRoomComment,\n useMarkRoomThreadAsRead,\n useRemoveRoomCommentReaction,\n useRoomAttachmentUrl,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n FormEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { CheckIcon } from \"../icons/Check\";\nimport { CrossIcon } from \"../icons/Cross\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EditIcon } from \"../icons/Edit\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { EmojiAddIcon } from \"../icons/EmojiAdd\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport type { ComposerSubmitComment } from \"../primitives\";\nimport * as CommentPrimitive from \"../primitives/Comment\";\nimport type {\n CommentBodyLinkProps,\n CommentBodyMentionProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"../primitives/Comment/types\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { CommentAttachmentArgs } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { download } from \"../utils/download\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useVisibleCallback } from \"../utils/use-visible\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport {\n FileAttachment,\n MediaAttachment,\n separateMediaAttachments,\n} from \"./internal/Attachment\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport { Emoji } from \"./internal/Emoji\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { List } from \"./internal/List\";\nimport {\n ShortcutTooltip,\n ShortcutTooltipKey,\n Tooltip,\n TooltipProvider,\n} from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\nconst REACTIONS_TRUNCATE = 5;\n\nexport interface CommentProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The comment to display.\n */\n comment: CommentData;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n\n /**\n * Whether to show the comment if it was deleted. If set to `false`, it will render deleted comments as `null`.\n */\n showDeleted?: boolean;\n\n /**\n * Whether to show reactions.\n */\n showReactions?: boolean;\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n\n /**\n * Whether to show the composer's formatting controls when editing the comment.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comment's content.\n */\n indentContent?: boolean;\n\n /**\n * The event handler called when the comment is edited.\n */\n onCommentEdit?: (comment: CommentData) => void;\n\n /**\n * The event handler called when the comment is deleted.\n */\n onCommentDelete?: (comment: CommentData) => void;\n\n /**\n * The event handler called when clicking on the author.\n */\n onAuthorClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: (\n args: CommentAttachmentArgs,\n event: MouseEvent<HTMLElement>\n ) => void;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n autoMarkReadThreadId?: string;\n\n /**\n * @internal\n */\n additionalActions?: ReactNode;\n\n /**\n * @internal\n */\n additionalActionsClassName?: string;\n}\n\ninterface CommentReactionButtonProps\n extends ComponentPropsWithoutRef<typeof Button> {\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ninterface CommentReactionProps extends ComponentPropsWithoutRef<\"button\"> {\n comment: CommentData;\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ntype CommentNonInteractiveReactionProps = Omit<CommentReactionProps, \"comment\">;\n\ninterface CommentAttachmentProps extends ComponentProps<typeof FileAttachment> {\n attachment: CommentAttachment;\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n}\n\nexport function CommentMention({\n userId,\n className,\n ...props\n}: CommentBodyMentionProps & CommentMentionProps) {\n const currentId = useCurrentUserId();\n return (\n <CommentPrimitive.Mention\n className={classNames(\"lb-comment-mention\", className)}\n data-self={userId === currentId ? \"\" : undefined}\n {...props}\n >\n {MENTION_CHARACTER}\n <User userId={userId} />\n </CommentPrimitive.Mention>\n );\n}\n\nexport function CommentLink({\n href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <CommentPrimitive.Link\n className={classNames(\"lb-comment-link\", className)}\n href={href}\n {...props}\n >\n {children}\n </CommentPrimitive.Link>\n );\n}\n\nexport function CommentNonInteractiveLink({\n href: _href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <span className={classNames(\"lb-comment-link\", className)} {...props}>\n {children}\n </span>\n );\n}\n\nconst CommentReactionButton = forwardRef<\n HTMLButtonElement,\n CommentReactionButtonProps\n>(({ reaction, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n return (\n <Button\n className={classNames(\"lb-comment-reaction\", className)}\n variant=\"outline\"\n aria-label={$.COMMENT_REACTION_DESCRIPTION(\n reaction.emoji,\n reaction.users.length\n )}\n {...props}\n ref={forwardedRef}\n >\n <Emoji className=\"lb-comment-reaction-emoji\" emoji={reaction.emoji} />\n <span className=\"lb-comment-reaction-count\">{reaction.users.length}</span>\n </Button>\n );\n});\n\nexport const CommentReaction = forwardRef<\n HTMLButtonElement,\n CommentReactionProps\n>(({ comment, reaction, overrides, disabled, ...props }, forwardedRef) => {\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n const $ = useOverrides(overrides);\n const tooltipContent = useMemo(\n () => (\n <span>\n {$.COMMENT_REACTION_LIST(\n <List\n values={reaction.users.map((users) => (\n <User key={users.id} userId={users.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={REACTIONS_TRUNCATE}\n locale={$.locale}\n />,\n reaction.emoji,\n reaction.users.length\n )}\n </span>\n ),\n [$, reaction]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handlePressedChange = useCallback(\n (isPressed: boolean) => {\n if (isPressed) {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n } else {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n }\n },\n [addReaction, comment.threadId, comment.id, reaction.emoji, removeReaction]\n );\n\n return (\n <Tooltip\n content={tooltipContent}\n multiline\n className=\"lb-comment-reaction-tooltip\"\n >\n <TogglePrimitive.Root\n asChild\n pressed={isActive}\n onPressedChange={handlePressedChange}\n onClick={stopPropagation}\n disabled={disabled}\n ref={forwardedRef}\n >\n <CommentReactionButton\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n />\n </TogglePrimitive.Root>\n </Tooltip>\n );\n});\n\nexport const CommentNonInteractiveReaction = forwardRef<\n HTMLButtonElement,\n CommentNonInteractiveReactionProps\n>(({ reaction, overrides, ...props }, forwardedRef) => {\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n\n return (\n <CommentReactionButton\n disableable={false}\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nfunction openAttachment({ attachment, url }: CommentAttachmentArgs) {\n // Open the attachment in a new tab if the attachment is a PDF,\n // an image, a video, or audio. Otherwise, download it.\n if (\n attachment.mimeType === \"application/pdf\" ||\n attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\") ||\n attachment.mimeType.startsWith(\"audio/\")\n ) {\n window.open(url, \"_blank\");\n } else {\n download(url, attachment.name);\n }\n}\n\nfunction CommentMediaAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <MediaAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nfunction CommentFileAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nexport function CommentNonInteractiveFileAttachment({\n className,\n ...props\n}: CommentAttachmentProps) {\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n allowMediaPreview={false}\n {...props}\n />\n );\n}\n\n// A void component (which doesn't render anything) responsible for marking a thread\n// as read when the comment it's used in becomes visible.\n// Moving this logic into a separate component allows us to use the visibility\n// and focus hooks \"conditionally\" by conditionally rendering this component.\nfunction AutoMarkReadThreadIdHandler({\n threadId,\n roomId,\n commentRef,\n}: {\n threadId: string;\n roomId: string;\n commentRef: RefObject<HTMLElement>;\n}) {\n const markThreadAsRead = useMarkRoomThreadAsRead(roomId);\n const isWindowFocused = useWindowFocus();\n\n useVisibleCallback(\n commentRef,\n () => {\n markThreadAsRead(threadId);\n },\n {\n // The underlying IntersectionObserver is only enabled when the window is focused\n enabled: isWindowFocused,\n }\n );\n\n return null;\n}\n\n/**\n * Displays a single comment.\n *\n * @example\n * <>\n * {thread.comments.map((comment) => (\n * <Comment key={comment.id} comment={comment} />\n * ))}\n * </>\n */\nexport const Comment = forwardRef<HTMLDivElement, CommentProps>(\n (\n {\n comment,\n indentContent = true,\n showDeleted,\n showActions = \"hover\",\n showReactions = true,\n showAttachments = true,\n showComposerFormattingControls = true,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onCommentEdit,\n onCommentDelete,\n overrides,\n className,\n additionalActions,\n additionalActionsClassName,\n autoMarkReadThreadId,\n ...props\n },\n forwardedRef\n ) => {\n const ref = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, ref);\n const currentUserId = useCurrentUserId();\n const deleteComment = useDeleteRoomComment(comment.roomId);\n const editComment = useEditRoomComment(comment.roomId);\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const $ = useOverrides(overrides);\n const [isEditing, setEditing] = useState(false);\n const [isTarget, setTarget] = useState(false);\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const [isReactionActionOpen, setReactionActionOpen] = useState(false);\n const { mediaAttachments, fileAttachments } = useMemo(() => {\n return separateMediaAttachments(comment.attachments);\n }, [comment.attachments]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEdit = useCallback(() => {\n setEditing(true);\n }, []);\n\n const handleEditCancel = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setEditing(false);\n },\n []\n );\n\n const handleEditSubmit = useCallback(\n (\n { body, attachments }: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentEdit?.(comment);\n\n event.preventDefault();\n setEditing(false);\n editComment({\n commentId: comment.id,\n threadId: comment.threadId,\n body,\n attachments,\n });\n },\n [comment, editComment, onCommentEdit]\n );\n\n const handleDelete = useCallback(() => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentDelete?.(comment);\n\n deleteComment({\n commentId: comment.id,\n threadId: comment.threadId,\n });\n }, [comment, deleteComment, onCommentDelete]);\n\n const handleAuthorClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n onAuthorClick?.(comment.userId, event);\n },\n [comment.userId, onAuthorClick]\n );\n\n const handleReactionSelect = useCallback(\n (emoji: string) => {\n const reactionIndex = comment.reactions.findIndex(\n (reaction) => reaction.emoji === emoji\n );\n\n if (\n reactionIndex >= 0 &&\n currentUserId &&\n comment.reactions[reactionIndex]?.users.some(\n (user) => user.id === currentUserId\n )\n ) {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n } else {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n }\n },\n [\n addReaction,\n comment.id,\n comment.reactions,\n comment.threadId,\n removeReaction,\n currentUserId,\n ]\n );\n\n useEffect(() => {\n const isWindowDefined = typeof window !== \"undefined\";\n if (!isWindowDefined) return;\n\n const hash = window.location.hash;\n const commentId = hash.slice(1);\n\n if (commentId === comment.id) {\n setTarget(true);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!showDeleted && !comment.body) {\n return null;\n }\n\n return (\n <TooltipProvider>\n {autoMarkReadThreadId && (\n <AutoMarkReadThreadIdHandler\n commentRef={ref}\n threadId={autoMarkReadThreadId}\n roomId={comment.roomId}\n />\n )}\n <div\n id={comment.id}\n className={classNames(\n \"lb-root lb-comment\",\n indentContent && \"lb-comment:indent-content\",\n showActions === \"hover\" && \"lb-comment:show-actions-hover\",\n (isMoreActionOpen || isReactionActionOpen) &&\n \"lb-comment:action-open\",\n className\n )}\n data-deleted={!comment.body ? \"\" : undefined}\n data-editing={isEditing ? \"\" : undefined}\n // In some cases, `:target` doesn't work as expected so we also define it manually.\n data-target={isTarget ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={mergedRefs}\n >\n <div className=\"lb-comment-header\">\n <div className=\"lb-comment-details\">\n <Avatar\n className=\"lb-comment-avatar\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-details-labels\">\n <User\n className=\"lb-comment-author\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-date\">\n <Timestamp\n locale={$.locale}\n date={comment.createdAt}\n className=\"lb-date lb-comment-date-created\"\n />\n {comment.editedAt && comment.body && (\n <>\n {\" \"}\n <span className=\"lb-comment-date-edited\">\n {$.COMMENT_EDITED}\n </span>\n </>\n )}\n </span>\n </span>\n </div>\n {showActions && !isEditing && (\n <div\n className={classNames(\n \"lb-comment-actions\",\n additionalActionsClassName\n )}\n >\n {additionalActions ?? null}\n {showReactions && (\n <EmojiPicker\n onEmojiSelect={handleReactionSelect}\n onOpenChange={setReactionActionOpen}\n >\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n >\n <EmojiAddIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n )}\n {comment.userId === currentUserId && (\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n <DropdownItem\n onSelect={handleEdit}\n onClick={stopPropagation}\n >\n <EditIcon className=\"lb-dropdown-item-icon\" />\n {$.COMMENT_EDIT}\n </DropdownItem>\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n >\n <DeleteIcon className=\"lb-dropdown-item-icon\" />\n {$.COMMENT_DELETE}\n </DropdownItem>\n </>\n }\n >\n <Tooltip content={$.COMMENT_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n disabled={!comment.body}\n onClick={stopPropagation}\n aria-label={$.COMMENT_MORE}\n >\n <EllipsisIcon className=\"lb-button-icon\" />\n </Button>\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n )}\n </div>\n )}\n </div>\n <div className=\"lb-comment-content\">\n {isEditing ? (\n <Composer\n className=\"lb-comment-composer\"\n onComposerSubmit={handleEditSubmit}\n defaultValue={comment.body}\n defaultAttachments={comment.attachments}\n autoFocus\n showAttribution={false}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n actions={\n <>\n <Tooltip\n content={$.COMMENT_EDIT_COMPOSER_CANCEL}\n aria-label={$.COMMENT_EDIT_COMPOSER_CANCEL}\n >\n <Button\n className=\"lb-composer-action\"\n onClick={handleEditCancel}\n >\n <CrossIcon className=\"lb-button-icon\" />\n </Button>\n </Tooltip>\n <ShortcutTooltip\n content={$.COMMENT_EDIT_COMPOSER_SAVE}\n shortcut={<ShortcutTooltipKey name=\"enter\" />}\n >\n <ComposerPrimitive.Submit asChild>\n <Button\n variant=\"primary\"\n className=\"lb-composer-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_EDIT_COMPOSER_SAVE}\n >\n <CheckIcon className=\"lb-button-icon\" />\n </Button>\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n }\n overrides={{\n COMPOSER_PLACEHOLDER: $.COMMENT_EDIT_COMPOSER_PLACEHOLDER,\n }}\n roomId={comment.roomId}\n />\n ) : comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: ({ userId }) => (\n <CommentMention\n userId={userId}\n onClick={(event) => onMentionClick?.(userId, event)}\n />\n ),\n Link: CommentLink,\n }}\n />\n {showAttachments &&\n (mediaAttachments.length > 0 || fileAttachments.length > 0) ? (\n <div className=\"lb-comment-attachments\">\n {mediaAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {mediaAttachments.map((attachment) => (\n <CommentMediaAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n {fileAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {fileAttachments.map((attachment) => (\n <CommentFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentReaction\n key={reaction.emoji}\n comment={comment}\n reaction={reaction}\n overrides={overrides}\n />\n ))}\n <EmojiPicker onEmojiSelect={handleReactionSelect}>\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-reaction lb-comment-reaction-add\"\n variant=\"outline\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n >\n <EmojiAddIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n </TooltipProvider>\n );\n }\n);\n"],"names":["CommentPrimitive.Mention","CommentPrimitive.Link","EmojiPickerTrigger","DropdownTrigger","ComposerPrimitive.Submit","CommentPrimitive.Body"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Comment.mjs","sources":["../../src/components/Comment.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n CommentAttachment,\n CommentData,\n CommentReaction as CommentReactionData,\n} from \"@liveblocks/core\";\nimport {\n useAddRoomCommentReaction,\n useDeleteRoomComment,\n useEditRoomComment,\n useMarkRoomThreadAsRead,\n useRemoveRoomCommentReaction,\n useRoomAttachmentUrl,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n FormEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { CheckIcon } from \"../icons/Check\";\nimport { CrossIcon } from \"../icons/Cross\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EditIcon } from \"../icons/Edit\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { EmojiAddIcon } from \"../icons/EmojiAdd\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport type { ComposerSubmitComment } from \"../primitives\";\nimport * as CommentPrimitive from \"../primitives/Comment\";\nimport type {\n CommentBodyLinkProps,\n CommentBodyMentionProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"../primitives/Comment/types\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { CommentAttachmentArgs } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { download } from \"../utils/download\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useVisibleCallback } from \"../utils/use-visible\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport {\n FileAttachment,\n MediaAttachment,\n separateMediaAttachments,\n} from \"./internal/Attachment\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport { Emoji } from \"./internal/Emoji\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { List } from \"./internal/List\";\nimport {\n ShortcutTooltip,\n ShortcutTooltipKey,\n Tooltip,\n TooltipProvider,\n} from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\nconst REACTIONS_TRUNCATE = 5;\n\nexport interface CommentProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The comment to display.\n */\n comment: CommentData;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n\n /**\n * Whether to show the comment if it was deleted. If set to `false`, it will render deleted comments as `null`.\n */\n showDeleted?: boolean;\n\n /**\n * Whether to show reactions.\n */\n showReactions?: boolean;\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n\n /**\n * Whether to show the composer's formatting controls when editing the comment.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comment's content.\n */\n indentContent?: boolean;\n\n /**\n * The event handler called when the comment is edited.\n */\n onCommentEdit?: (comment: CommentData) => void;\n\n /**\n * The event handler called when the comment is deleted.\n */\n onCommentDelete?: (comment: CommentData) => void;\n\n /**\n * The event handler called when clicking on the author.\n */\n onAuthorClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: (\n args: CommentAttachmentArgs,\n event: MouseEvent<HTMLElement>\n ) => void;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n autoMarkReadThreadId?: string;\n\n /**\n * @internal\n */\n additionalActions?: ReactNode;\n\n /**\n * @internal\n */\n additionalActionsClassName?: string;\n}\n\ninterface CommentReactionButtonProps\n extends ComponentPropsWithoutRef<typeof Button> {\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ninterface CommentReactionProps extends ComponentPropsWithoutRef<\"button\"> {\n comment: CommentData;\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ntype CommentNonInteractiveReactionProps = Omit<CommentReactionProps, \"comment\">;\n\ninterface CommentAttachmentProps extends ComponentProps<typeof FileAttachment> {\n attachment: CommentAttachment;\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n}\n\nexport function CommentMention({\n userId,\n className,\n ...props\n}: CommentBodyMentionProps & CommentMentionProps) {\n const currentId = useCurrentUserId();\n return (\n <CommentPrimitive.Mention\n className={classNames(\"lb-comment-mention\", className)}\n data-self={userId === currentId ? \"\" : undefined}\n {...props}\n >\n {MENTION_CHARACTER}\n <User userId={userId} />\n </CommentPrimitive.Mention>\n );\n}\n\nexport function CommentLink({\n href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <CommentPrimitive.Link\n className={classNames(\"lb-comment-link\", className)}\n href={href}\n {...props}\n >\n {children}\n </CommentPrimitive.Link>\n );\n}\n\nexport function CommentNonInteractiveLink({\n href: _href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <span className={classNames(\"lb-comment-link\", className)} {...props}>\n {children}\n </span>\n );\n}\n\nconst CommentReactionButton = forwardRef<\n HTMLButtonElement,\n CommentReactionButtonProps\n>(({ reaction, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n return (\n <Button\n className={classNames(\"lb-comment-reaction\", className)}\n variant=\"outline\"\n aria-label={$.COMMENT_REACTION_DESCRIPTION(\n reaction.emoji,\n reaction.users.length\n )}\n {...props}\n ref={forwardedRef}\n >\n <Emoji className=\"lb-comment-reaction-emoji\" emoji={reaction.emoji} />\n <span className=\"lb-comment-reaction-count\">{reaction.users.length}</span>\n </Button>\n );\n});\n\nexport const CommentReaction = forwardRef<\n HTMLButtonElement,\n CommentReactionProps\n>(({ comment, reaction, overrides, disabled, ...props }, forwardedRef) => {\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n const $ = useOverrides(overrides);\n const tooltipContent = useMemo(\n () => (\n <span>\n {$.COMMENT_REACTION_LIST(\n <List\n values={reaction.users.map((users) => (\n <User key={users.id} userId={users.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={REACTIONS_TRUNCATE}\n locale={$.locale}\n />,\n reaction.emoji,\n reaction.users.length\n )}\n </span>\n ),\n [$, reaction]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handlePressedChange = useCallback(\n (isPressed: boolean) => {\n if (isPressed) {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n } else {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n }\n },\n [addReaction, comment.threadId, comment.id, reaction.emoji, removeReaction]\n );\n\n return (\n <Tooltip\n content={tooltipContent}\n multiline\n className=\"lb-comment-reaction-tooltip\"\n >\n <TogglePrimitive.Root\n asChild\n pressed={isActive}\n onPressedChange={handlePressedChange}\n onClick={stopPropagation}\n disabled={disabled}\n ref={forwardedRef}\n >\n <CommentReactionButton\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n />\n </TogglePrimitive.Root>\n </Tooltip>\n );\n});\n\nexport const CommentNonInteractiveReaction = forwardRef<\n HTMLButtonElement,\n CommentNonInteractiveReactionProps\n>(({ reaction, overrides, ...props }, forwardedRef) => {\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n\n return (\n <CommentReactionButton\n disableable={false}\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nfunction openAttachment({ attachment, url }: CommentAttachmentArgs) {\n // Open the attachment in a new tab if the attachment is a PDF,\n // an image, a video, or audio. Otherwise, download it.\n if (\n attachment.mimeType === \"application/pdf\" ||\n attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\") ||\n attachment.mimeType.startsWith(\"audio/\")\n ) {\n window.open(url, \"_blank\");\n } else {\n download(url, attachment.name);\n }\n}\n\nfunction CommentMediaAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <MediaAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nfunction CommentFileAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nexport function CommentNonInteractiveFileAttachment({\n className,\n ...props\n}: CommentAttachmentProps) {\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n allowMediaPreview={false}\n {...props}\n />\n );\n}\n\n// A void component (which doesn't render anything) responsible for marking a thread\n// as read when the comment it's used in becomes visible.\n// Moving this logic into a separate component allows us to use the visibility\n// and focus hooks \"conditionally\" by conditionally rendering this component.\nfunction AutoMarkReadThreadIdHandler({\n threadId,\n roomId,\n commentRef,\n}: {\n threadId: string;\n roomId: string;\n commentRef: RefObject<HTMLElement>;\n}) {\n const markThreadAsRead = useMarkRoomThreadAsRead(roomId);\n const isWindowFocused = useWindowFocus();\n\n useVisibleCallback(\n commentRef,\n () => {\n markThreadAsRead(threadId);\n },\n {\n // The underlying IntersectionObserver is only enabled when the window is focused\n enabled: isWindowFocused,\n }\n );\n\n return null;\n}\n\n/**\n * Displays a single comment.\n *\n * @example\n * <>\n * {thread.comments.map((comment) => (\n * <Comment key={comment.id} comment={comment} />\n * ))}\n * </>\n */\nexport const Comment = forwardRef<HTMLDivElement, CommentProps>(\n (\n {\n comment,\n indentContent = true,\n showDeleted,\n showActions = \"hover\",\n showReactions = true,\n showAttachments = true,\n showComposerFormattingControls = true,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onCommentEdit,\n onCommentDelete,\n overrides,\n className,\n additionalActions,\n additionalActionsClassName,\n autoMarkReadThreadId,\n ...props\n },\n forwardedRef\n ) => {\n const ref = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, ref);\n const currentUserId = useCurrentUserId();\n const deleteComment = useDeleteRoomComment(comment.roomId);\n const editComment = useEditRoomComment(comment.roomId);\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const $ = useOverrides(overrides);\n const [isEditing, setEditing] = useState(false);\n const [isTarget, setTarget] = useState(false);\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const [isReactionActionOpen, setReactionActionOpen] = useState(false);\n const { mediaAttachments, fileAttachments } = useMemo(() => {\n return separateMediaAttachments(comment.attachments);\n }, [comment.attachments]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEdit = useCallback(() => {\n setEditing(true);\n }, []);\n\n const handleEditCancel = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setEditing(false);\n },\n []\n );\n\n const handleEditSubmit = useCallback(\n (\n { body, attachments }: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentEdit?.(comment);\n\n event.preventDefault();\n setEditing(false);\n editComment({\n commentId: comment.id,\n threadId: comment.threadId,\n body,\n attachments,\n });\n },\n [comment, editComment, onCommentEdit]\n );\n\n const handleDelete = useCallback(() => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentDelete?.(comment);\n\n deleteComment({\n commentId: comment.id,\n threadId: comment.threadId,\n });\n }, [comment, deleteComment, onCommentDelete]);\n\n const handleAuthorClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n onAuthorClick?.(comment.userId, event);\n },\n [comment.userId, onAuthorClick]\n );\n\n const handleReactionSelect = useCallback(\n (emoji: string) => {\n const reactionIndex = comment.reactions.findIndex(\n (reaction) => reaction.emoji === emoji\n );\n\n if (\n reactionIndex >= 0 &&\n currentUserId &&\n comment.reactions[reactionIndex]?.users.some(\n (user) => user.id === currentUserId\n )\n ) {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n } else {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n }\n },\n [\n addReaction,\n comment.id,\n comment.reactions,\n comment.threadId,\n removeReaction,\n currentUserId,\n ]\n );\n\n useEffect(() => {\n const isWindowDefined = typeof window !== \"undefined\";\n if (!isWindowDefined) return;\n\n const hash = window.location.hash;\n const commentId = hash.slice(1);\n\n if (commentId === comment.id) {\n setTarget(true);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!showDeleted && !comment.body) {\n return null;\n }\n\n return (\n <TooltipProvider>\n {autoMarkReadThreadId && (\n <AutoMarkReadThreadIdHandler\n commentRef={ref}\n threadId={autoMarkReadThreadId}\n roomId={comment.roomId}\n />\n )}\n <div\n id={comment.id}\n className={classNames(\n \"lb-root lb-comment\",\n indentContent && \"lb-comment:indent-content\",\n showActions === \"hover\" && \"lb-comment:show-actions-hover\",\n (isMoreActionOpen || isReactionActionOpen) &&\n \"lb-comment:action-open\",\n className\n )}\n data-deleted={!comment.body ? \"\" : undefined}\n data-editing={isEditing ? \"\" : undefined}\n // In some cases, `:target` doesn't work as expected so we also define it manually.\n data-target={isTarget ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={mergedRefs}\n >\n <div className=\"lb-comment-header\">\n <div className=\"lb-comment-details\">\n <Avatar\n className=\"lb-comment-avatar\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-details-labels\">\n <User\n className=\"lb-comment-author\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-date\">\n <Timestamp\n locale={$.locale}\n date={comment.createdAt}\n className=\"lb-date lb-comment-date-created\"\n />\n {comment.editedAt && comment.body && (\n <>\n {\" \"}\n <span className=\"lb-comment-date-edited\">\n {$.COMMENT_EDITED}\n </span>\n </>\n )}\n </span>\n </span>\n </div>\n {showActions && !isEditing && (\n <div\n className={classNames(\n \"lb-comment-actions\",\n additionalActionsClassName\n )}\n >\n {additionalActions ?? null}\n {showReactions && (\n <EmojiPicker\n onEmojiSelect={handleReactionSelect}\n onOpenChange={setReactionActionOpen}\n >\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n >\n <EmojiAddIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n )}\n {comment.userId === currentUserId && (\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n <DropdownItem\n onSelect={handleEdit}\n onClick={stopPropagation}\n >\n <EditIcon className=\"lb-dropdown-item-icon\" />\n {$.COMMENT_EDIT}\n </DropdownItem>\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n >\n <DeleteIcon className=\"lb-dropdown-item-icon\" />\n {$.COMMENT_DELETE}\n </DropdownItem>\n </>\n }\n >\n <Tooltip content={$.COMMENT_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n disabled={!comment.body}\n onClick={stopPropagation}\n aria-label={$.COMMENT_MORE}\n >\n <EllipsisIcon className=\"lb-button-icon\" />\n </Button>\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n )}\n </div>\n )}\n </div>\n <div className=\"lb-comment-content\">\n {isEditing ? (\n <Composer\n className=\"lb-comment-composer\"\n onComposerSubmit={handleEditSubmit}\n defaultValue={comment.body}\n defaultAttachments={comment.attachments}\n autoFocus\n showAttribution={false}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n actions={\n <>\n <Tooltip\n content={$.COMMENT_EDIT_COMPOSER_CANCEL}\n aria-label={$.COMMENT_EDIT_COMPOSER_CANCEL}\n >\n <Button\n className=\"lb-composer-action\"\n onClick={handleEditCancel}\n >\n <CrossIcon className=\"lb-button-icon\" />\n </Button>\n </Tooltip>\n <ShortcutTooltip\n content={$.COMMENT_EDIT_COMPOSER_SAVE}\n shortcut={<ShortcutTooltipKey name=\"enter\" />}\n >\n <ComposerPrimitive.Submit asChild>\n <Button\n variant=\"primary\"\n className=\"lb-composer-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_EDIT_COMPOSER_SAVE}\n >\n <CheckIcon className=\"lb-button-icon\" />\n </Button>\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n }\n overrides={{\n COMPOSER_PLACEHOLDER: $.COMMENT_EDIT_COMPOSER_PLACEHOLDER,\n }}\n roomId={comment.roomId}\n />\n ) : comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: ({ userId }) => (\n <CommentMention\n userId={userId}\n onClick={(event) => onMentionClick?.(userId, event)}\n />\n ),\n Link: CommentLink,\n }}\n />\n {showAttachments &&\n (mediaAttachments.length > 0 || fileAttachments.length > 0) ? (\n <div className=\"lb-comment-attachments\">\n {mediaAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {mediaAttachments.map((attachment) => (\n <CommentMediaAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n {fileAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {fileAttachments.map((attachment) => (\n <CommentFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentReaction\n key={reaction.emoji}\n comment={comment}\n reaction={reaction}\n overrides={overrides}\n />\n ))}\n <EmojiPicker onEmojiSelect={handleReactionSelect}>\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-reaction lb-comment-reaction-add\"\n variant=\"outline\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n >\n <EmojiAddIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n </TooltipProvider>\n );\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAqFA;AA0GO;AAAwB;AAC7B;AACA;AAEF;AACE;AACA;AACG;AACsD;AACd;AACnC;AAEH;AAAA;AACA;AAAK;AAAgB;AAAA;AAG5B;AAEO;AAAqB;AAC1B;AACA;AACA;AAEF;AACE;AACG;AACmD;AAClD;AACI;AAEH;AAGP;AAEO;AAAmC;AAClC;AACN;AACA;AAEF;AACE;AACG;AAAuD;AAAO;AAC5D;AAGP;AAEA;AAIE;AACA;AACG;AACuD;AAC9C;AACM;AACH;AACM;AACjB;AACI;AACC;AAEL;AAAC;AAAgB;AAA4C;AAAO;AACnE;AAAe;AAA4C;AAAO;AAAA;AAGzE;AAEa;AAIX;AACA;AACA;AACA;AACE;AAA4D;AAE9D;AACA;AAAuB;AAElB;AACI;AACA;AAEI;AAAkC;AAAe;AACnD;AACkB;AACT;AACA;AACZ;AACS;AACM;AACjB;AACF;AAEU;AAGd;AACE;AAAsB;AAGxB;AAA4B;AAExB;AACE;AAAY;AACQ;AACC;AACH;AACjB;AAED;AAAe;AACK;AACC;AACH;AACjB;AACH;AACF;AAC0E;AAG5E;AACG;AACU;AACA;AACC;AAET;AACQ;AACE;AACQ;AACR;AACT;AACK;AAEJ;AAC4B;AAC3B;AACA;AACI;AACN;AACF;AAGN;AAEa;AAIX;AACA;AACE;AAA4D;AAG9D;AACG;AACc;AACc;AAC3B;AACA;AACI;AACC;AAGX;AAEA;AAGE;AAME;AAAyB;AAEzB;AAA6B;AAEjC;AAEA;AAAgC;AAC9B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEA;AAA+B;AAC7B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEO;AAA6C;AAClD;AAEF;AACE;AACG;AACyD;AACrC;AACf;AAGV;AAMA;AAAqC;AACnC;AACA;AAEF;AAKE;AACA;AAEA;AAAA;AACE;AAEE;AAAyB;AAC3B;AACA;AAEW;AACX;AAGF;AACF;AAYO;AAAgB;AAEnB;AACE;AACgB;AAChB;AACc;AACE;AACE;AACe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACE;AAAmD;AAGrD;AACE;AAAsB;AAGxB;AACE;AAAe;AAGjB;AAAyB;AAErB;AACA;AAAgB;AAClB;AACC;AAGH;AAAyB;AAMrB;AAEA;AACA;AACA;AAAY;AACS;AACD;AAClB;AACA;AACD;AACH;AACoC;AAGtC;AAEE;AAEA;AAAc;AACO;AACD;AACnB;AAGH;AAA0B;AAEtB;AAAqC;AACvC;AAC8B;AAGhC;AAA6B;AAEzB;AAAwC;AACL;AAGnC;AAG0C;AAChB;AAGxB;AAAe;AACK;AACC;AACnB;AACD;AAED;AAAY;AACQ;AACC;AACnB;AACD;AACH;AACF;AACA;AACE;AACQ;AACA;AACA;AACR;AACA;AACF;AAGF;AACE;AACA;AAAsB;AAEtB;AACA;AAEA;AACE;AAAc;AAChB;AAGF;AACE;AAAO;AAGT;AACG;AACE;AACE;AACa;AACF;AACM;AAClB;AAED;AACa;AACD;AACT;AACiB;AACU;AAEzB;AACF;AACF;AACmC;AACJ;AAEF;AACtB;AACH;AACC;AAEL;AAAC;AAAc;AACb;AAAC;AAAc;AACb;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACI;AACJ;AACZ;AAEE;AACG;AAAA;AACA;AAAe;AACX;AACL;AAAA;AACF;AAAA;AAEJ;AAAA;AACF;AAAA;AACF;AAEG;AACY;AACT;AACA;AACF;AAEC;AAAqB;AAEnB;AACgB;AACD;AAEb;AAAmB;AACjB;AAA0B;AACxB;AACW;AACD;AACK;AAEb;AAAuB;AAAiB;AAC3C;AACF;AACF;AACF;AAGC;AACO;AACQ;AACR;AAEJ;AACE;AAAC;AACW;AACD;AAET;AAAC;AAAmB;AAAwB;AACzC;AAAA;AACL;AACC;AACW;AACD;AAET;AAAC;AAAqB;AAAwB;AAC3C;AAAA;AACL;AAAA;AACF;AAGD;AAAmB;AACjB;AAAuB;AACrB;AACW;AACS;AACV;AACK;AAEb;AAAuB;AAAiB;AAC3C;AACF;AACF;AACF;AAAA;AAEJ;AAAA;AAEJ;AACC;AAAc;AAEV;AACW;AACQ;AACI;AACM;AACnB;AACQ;AACjB;AACwB;AAEtB;AACE;AAAC;AACY;AACG;AAEb;AACW;AACD;AAER;AAAoB;AAAiB;AACxC;AACF;AACC;AACY;AACA;AAAwB;AAAQ;AAE1C;AAAgC;AAC9B;AACS;AACE;AACD;AACK;AAEb;AAAoB;AAAiB;AACxC;AACF;AACF;AAAA;AACF;AAES;AACe;AAC1B;AACgB;AAGlB;AACE;AAAC;AACW;AACI;AACF;AAEP;AACC;AACkD;AACpD;AAEI;AACR;AACF;AAGG;AAAc;AACZ;AACE;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAED;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAAA;AAEJ;AAED;AAAc;AACZ;AACE;AAEC;AACA;AACA;AAEH;AACA;AAA2B;AACzB;AAAmB;AACjB;AAA0B;AACxB;AACW;AACF;AACC;AACK;AAEb;AAAuB;AAAiB;AAC3C;AACF;AACF;AACF;AAAA;AACF;AAAA;AAIH;AAAc;AACZ;AAAY;AAAwB;AAAgB;AACvD;AAEJ;AAAA;AACF;AAAA;AACF;AAGN;;"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
'use strict';
|
|
2
3
|
|
|
3
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -28,8 +29,9 @@ var Button = require('./internal/Button.js');
|
|
|
28
29
|
var EmojiPicker = require('./internal/EmojiPicker.js');
|
|
29
30
|
var Tooltip = require('./internal/Tooltip.js');
|
|
30
31
|
var User = require('./internal/User.js');
|
|
31
|
-
var TooltipPrimitive = require('@radix-ui/react-tooltip');
|
|
32
32
|
var PopoverPrimitive = require('@radix-ui/react-popover');
|
|
33
|
+
var TooltipPrimitive = require('@radix-ui/react-tooltip');
|
|
34
|
+
|
|
33
35
|
|
|
34
36
|
function ComposerInsertMentionEditorAction({
|
|
35
37
|
label,
|
|
@@ -422,7 +424,7 @@ function ComposerEditorContainer({
|
|
|
422
424
|
]
|
|
423
425
|
});
|
|
424
426
|
}
|
|
425
|
-
react.createContext(null);
|
|
427
|
+
const ComposerRoomIdContext = react.createContext(null);
|
|
426
428
|
const Composer = react.forwardRef(
|
|
427
429
|
({
|
|
428
430
|
threadId,
|
|
@@ -602,4 +604,5 @@ const Composer = react.forwardRef(
|
|
|
602
604
|
);
|
|
603
605
|
|
|
604
606
|
exports.Composer = Composer;
|
|
607
|
+
exports.ComposerRoomIdContext = ComposerRoomIdContext;
|
|
605
608
|
//# sourceMappingURL=Composer.js.map
|