@liveblocks/react-ui
Version:
A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.
227 lines (220 loc) • 8.73 kB
JavaScript
"use client";
;
var jsxRuntime = require('react/jsx-runtime');
var react$1 = require('@liveblocks/react');
var _private = require('@liveblocks/react/_private');
var TogglePrimitive = require('@radix-ui/react-toggle');
var react = require('react');
var ArrowDown = require('../icons/ArrowDown.cjs');
var Resolve = require('../icons/Resolve.cjs');
var Resolved = require('../icons/Resolved.cjs');
var overrides = require('../overrides.cjs');
var classNames = require('../utils/class-names.cjs');
var findLastIndex = require('../utils/find-last-index.cjs');
var Comment = require('./Comment.cjs');
var Composer = require('./Composer.cjs');
var Button = require('./internal/Button.cjs');
var Tooltip = require('./internal/Tooltip.cjs');
var TooltipPrimitive = require('@radix-ui/react-tooltip');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var TogglePrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(TogglePrimitive);
const Thread = react.forwardRef(
({
thread,
indentCommentContent = true,
showActions = "hover",
showDeletedComments,
showResolveAction = true,
showReactions = true,
showComposer = "collapsed",
showAttachments = true,
showComposerFormattingControls = true,
onResolvedChange,
onCommentEdit,
onCommentDelete,
onThreadDelete,
onAuthorClick,
onMentionClick,
onAttachmentClick,
onComposerSubmit,
overrides: overrides$1,
className,
...props
}, forwardedRef) => {
const markThreadAsResolved = _private.useMarkRoomThreadAsResolved(thread.roomId);
const markThreadAsUnresolved = _private.useMarkRoomThreadAsUnresolved(thread.roomId);
const $ = overrides.useOverrides(overrides$1);
const firstCommentIndex = react.useMemo(() => {
return showDeletedComments ? 0 : thread.comments.findIndex((comment) => comment.body);
}, [showDeletedComments, thread.comments]);
const lastCommentIndex = react.useMemo(() => {
return showDeletedComments ? thread.comments.length - 1 : findLastIndex.findLastIndex(thread.comments, (comment) => comment.body);
}, [showDeletedComments, thread.comments]);
const { status: subscriptionStatus, unreadSince } = react$1.useThreadSubscription(
thread.id
);
const unreadIndex = react.useMemo(() => {
if (subscriptionStatus !== "subscribed") {
return;
}
if (unreadSince === null) {
return firstCommentIndex;
}
const unreadIndex2 = thread.comments.findIndex(
(comment) => (showDeletedComments ? true : comment.body) && comment.createdAt > unreadSince
);
return unreadIndex2 >= 0 && unreadIndex2 < thread.comments.length ? unreadIndex2 : void 0;
}, [
firstCommentIndex,
showDeletedComments,
subscriptionStatus,
thread.comments,
unreadSince
]);
const [newIndex, setNewIndex] = react.useState();
const newIndicatorIndex = newIndex === void 0 ? unreadIndex : newIndex;
react.useEffect(() => {
if (unreadIndex) {
setNewIndex(
(persistedUnreadIndex) => Math.min(persistedUnreadIndex ?? Infinity, unreadIndex)
);
}
}, [unreadIndex]);
const stopPropagation = react.useCallback((event) => {
event.stopPropagation();
}, []);
const handleResolvedChange = react.useCallback(
(resolved) => {
onResolvedChange?.(resolved);
if (resolved) {
markThreadAsResolved(thread.id);
} else {
markThreadAsUnresolved(thread.id);
}
},
[
markThreadAsResolved,
markThreadAsUnresolved,
onResolvedChange,
thread.id
]
);
const handleCommentDelete = react.useCallback(
(comment) => {
onCommentDelete?.(comment);
const filteredComments = thread.comments.filter(
(comment2) => comment2.body
);
if (filteredComments.length <= 1) {
onThreadDelete?.(thread);
}
},
[onCommentDelete, onThreadDelete, thread]
);
return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive.TooltipProvider, {
children: /* @__PURE__ */ jsxRuntime.jsxs("div", {
className: classNames.classNames(
"lb-root lb-thread",
showActions === "hover" && "lb-thread:show-actions-hover",
className
),
"data-resolved": thread.resolved ? "" : void 0,
"data-unread": unreadIndex !== void 0 ? "" : void 0,
dir: $.dir,
...props,
ref: forwardedRef,
children: [
/* @__PURE__ */ jsxRuntime.jsx("div", {
className: "lb-thread-comments",
children: thread.comments.map((comment, index) => {
const isFirstComment = index === firstCommentIndex;
const isUnread = unreadIndex !== void 0 && index >= unreadIndex;
const children = /* @__PURE__ */ jsxRuntime.jsx(Comment.Comment, {
overrides: overrides$1,
className: "lb-thread-comment",
"data-unread": isUnread ? "" : void 0,
comment,
indentContent: indentCommentContent,
showDeleted: showDeletedComments,
showActions,
showReactions,
showAttachments,
showComposerFormattingControls,
onCommentEdit,
onCommentDelete: handleCommentDelete,
onAuthorClick,
onMentionClick,
onAttachmentClick,
autoMarkReadThreadId: index === lastCommentIndex && isUnread ? thread.id : void 0,
additionalActionsClassName: isFirstComment ? "lb-thread-actions" : void 0,
additionalActions: isFirstComment && showResolveAction ? /* @__PURE__ */ jsxRuntime.jsx(Tooltip.Tooltip, {
content: thread.resolved ? $.THREAD_UNRESOLVE : $.THREAD_RESOLVE,
children: /* @__PURE__ */ jsxRuntime.jsx(TogglePrimitive__namespace.Root, {
pressed: thread.resolved,
onPressedChange: handleResolvedChange,
asChild: true,
children: /* @__PURE__ */ jsxRuntime.jsx(Button.Button, {
className: "lb-comment-action",
onClick: stopPropagation,
"aria-label": thread.resolved ? $.THREAD_UNRESOLVE : $.THREAD_RESOLVE,
icon: thread.resolved ? /* @__PURE__ */ jsxRuntime.jsx(Resolved.ResolvedIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(Resolve.ResolveIcon, {})
})
})
}) : null
}, comment.id);
return index === newIndicatorIndex && newIndicatorIndex !== firstCommentIndex && newIndicatorIndex <= lastCommentIndex ? /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, {
children: [
/* @__PURE__ */ jsxRuntime.jsx("div", {
className: "lb-thread-new-indicator",
"aria-label": $.THREAD_NEW_INDICATOR_DESCRIPTION,
children: /* @__PURE__ */ jsxRuntime.jsxs("span", {
className: "lb-thread-new-indicator-label",
children: [
/* @__PURE__ */ jsxRuntime.jsx(ArrowDown.ArrowDownIcon, {
className: "lb-thread-new-indicator-label-icon"
}),
$.THREAD_NEW_INDICATOR
]
})
}),
children
]
}, comment.id) : children;
})
}),
showComposer && /* @__PURE__ */ jsxRuntime.jsx(Composer.Composer, {
className: "lb-thread-composer",
threadId: thread.id,
defaultCollapsed: showComposer === "collapsed" ? true : void 0,
showAttachments,
showFormattingControls: showComposerFormattingControls,
onComposerSubmit,
overrides: {
COMPOSER_PLACEHOLDER: $.THREAD_COMPOSER_PLACEHOLDER,
COMPOSER_SEND: $.THREAD_COMPOSER_SEND,
...overrides$1
},
roomId: thread.roomId
})
]
})
});
}
);
exports.Thread = Thread;
//# sourceMappingURL=Thread.cjs.map