elseware-ui 2.31.0 → 2.31.2
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/LICENSE +21 -0
- package/README.md +69 -80
- package/dist/index.css +63 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +89 -3
- package/dist/index.d.ts +89 -3
- package/dist/index.js +821 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +821 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ var reactBeautifulDnd = require('react-beautiful-dnd');
|
|
|
24
24
|
var md = require('react-icons/md');
|
|
25
25
|
require('@mdxeditor/editor/style.css');
|
|
26
26
|
var editor = require('@mdxeditor/editor');
|
|
27
|
+
var bi = require('react-icons/bi');
|
|
27
28
|
|
|
28
29
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
29
30
|
|
|
@@ -15741,7 +15742,7 @@ function Tags({
|
|
|
15741
15742
|
var Tags_default = Tags;
|
|
15742
15743
|
function TextArea({
|
|
15743
15744
|
placeholder,
|
|
15744
|
-
limit,
|
|
15745
|
+
limit = 1e3,
|
|
15745
15746
|
styles,
|
|
15746
15747
|
shape,
|
|
15747
15748
|
...props
|
|
@@ -17485,6 +17486,824 @@ function ShowMore({ text, limit }) {
|
|
|
17485
17486
|
] });
|
|
17486
17487
|
}
|
|
17487
17488
|
var ShowMore_default = ShowMore;
|
|
17489
|
+
function CommentComposer({
|
|
17490
|
+
avatar,
|
|
17491
|
+
placeholder = "Add a comment...",
|
|
17492
|
+
submitLabel = "Comment",
|
|
17493
|
+
disabled,
|
|
17494
|
+
loading,
|
|
17495
|
+
onSubmit
|
|
17496
|
+
}) {
|
|
17497
|
+
const [value, setValue] = React4.useState("");
|
|
17498
|
+
const [focused, setFocused] = React4.useState(false);
|
|
17499
|
+
async function handleSubmit() {
|
|
17500
|
+
const content = value.trim();
|
|
17501
|
+
if (!content) {
|
|
17502
|
+
return;
|
|
17503
|
+
}
|
|
17504
|
+
await onSubmit?.(content);
|
|
17505
|
+
setValue("");
|
|
17506
|
+
setFocused(false);
|
|
17507
|
+
}
|
|
17508
|
+
function handleCancel() {
|
|
17509
|
+
setValue("");
|
|
17510
|
+
setFocused(false);
|
|
17511
|
+
}
|
|
17512
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4", children: [
|
|
17513
|
+
/* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: avatar, size: "md" }),
|
|
17514
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col gap-3", children: [
|
|
17515
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17516
|
+
"textarea",
|
|
17517
|
+
{
|
|
17518
|
+
value,
|
|
17519
|
+
disabled: disabled || loading,
|
|
17520
|
+
placeholder,
|
|
17521
|
+
onFocus: () => setFocused(true),
|
|
17522
|
+
onChange: (e) => setValue(e.target.value),
|
|
17523
|
+
className: "\n w-full\n min-h-[56px]\n resize-none\n bg-transparent\n border-b\n border-gray-300\n dark:border-neutral-700\n outline-none\n pb-2\n text-sm\n "
|
|
17524
|
+
}
|
|
17525
|
+
),
|
|
17526
|
+
(focused || value.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
17527
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17528
|
+
Button_default,
|
|
17529
|
+
{
|
|
17530
|
+
text: "Cancel",
|
|
17531
|
+
variant: "secondary",
|
|
17532
|
+
appearance: "ghost",
|
|
17533
|
+
disabled: loading,
|
|
17534
|
+
onClick: handleCancel
|
|
17535
|
+
}
|
|
17536
|
+
),
|
|
17537
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17538
|
+
Button_default,
|
|
17539
|
+
{
|
|
17540
|
+
text: submitLabel,
|
|
17541
|
+
variant: "primary",
|
|
17542
|
+
loading,
|
|
17543
|
+
disabled: !value.trim(),
|
|
17544
|
+
onClick: handleSubmit
|
|
17545
|
+
}
|
|
17546
|
+
)
|
|
17547
|
+
] })
|
|
17548
|
+
] })
|
|
17549
|
+
] });
|
|
17550
|
+
}
|
|
17551
|
+
var CommentComposer_default = CommentComposer;
|
|
17552
|
+
function CommentActions({
|
|
17553
|
+
likes = 0,
|
|
17554
|
+
dislikes = 0,
|
|
17555
|
+
liked = false,
|
|
17556
|
+
disliked = false,
|
|
17557
|
+
canReply = true,
|
|
17558
|
+
onLike,
|
|
17559
|
+
onDislike,
|
|
17560
|
+
onReply
|
|
17561
|
+
}) {
|
|
17562
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17563
|
+
"div",
|
|
17564
|
+
{
|
|
17565
|
+
className: "\n flex\n items-center\n gap-5\n text-sm\n text-gray-500\n dark:text-gray-400\n ",
|
|
17566
|
+
children: [
|
|
17567
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17568
|
+
"button",
|
|
17569
|
+
{
|
|
17570
|
+
onClick: onLike,
|
|
17571
|
+
className: `
|
|
17572
|
+
inline-flex
|
|
17573
|
+
items-center
|
|
17574
|
+
gap-1
|
|
17575
|
+
transition-colors
|
|
17576
|
+
${liked ? "text-blue-500" : "hover:text-gray-900 dark:hover:text-gray-100"}
|
|
17577
|
+
`,
|
|
17578
|
+
children: [
|
|
17579
|
+
liked ? /* @__PURE__ */ jsxRuntime.jsx(bi.BiSolidLike, { size: 18 }) : /* @__PURE__ */ jsxRuntime.jsx(bi.BiLike, { size: 18 }),
|
|
17580
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: likes })
|
|
17581
|
+
]
|
|
17582
|
+
}
|
|
17583
|
+
),
|
|
17584
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17585
|
+
"button",
|
|
17586
|
+
{
|
|
17587
|
+
onClick: onDislike,
|
|
17588
|
+
className: `
|
|
17589
|
+
inline-flex
|
|
17590
|
+
items-center
|
|
17591
|
+
gap-1
|
|
17592
|
+
transition-colors
|
|
17593
|
+
${disliked ? "text-red-500" : "hover:text-gray-900 dark:hover:text-gray-100"}
|
|
17594
|
+
`,
|
|
17595
|
+
children: [
|
|
17596
|
+
disliked ? /* @__PURE__ */ jsxRuntime.jsx(bi.BiSolidDislike, { size: 18 }) : /* @__PURE__ */ jsxRuntime.jsx(bi.BiDislike, { size: 18 }),
|
|
17597
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: dislikes })
|
|
17598
|
+
]
|
|
17599
|
+
}
|
|
17600
|
+
),
|
|
17601
|
+
canReply && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17602
|
+
"button",
|
|
17603
|
+
{
|
|
17604
|
+
onClick: onReply,
|
|
17605
|
+
className: "\n font-medium\n transition-colors\n hover:text-gray-900\n dark:hover:text-gray-100\n ",
|
|
17606
|
+
children: "Reply"
|
|
17607
|
+
}
|
|
17608
|
+
)
|
|
17609
|
+
]
|
|
17610
|
+
}
|
|
17611
|
+
);
|
|
17612
|
+
}
|
|
17613
|
+
var CommentActions_default = CommentActions;
|
|
17614
|
+
function CommentContent({ content }) {
|
|
17615
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17616
|
+
"div",
|
|
17617
|
+
{
|
|
17618
|
+
className: "\n text-sm\n leading-relaxed\n whitespace-pre-wrap\n break-words\n text-gray-700\n dark:text-gray-300\n ",
|
|
17619
|
+
children: content
|
|
17620
|
+
}
|
|
17621
|
+
);
|
|
17622
|
+
}
|
|
17623
|
+
var CommentContent_default = CommentContent;
|
|
17624
|
+
|
|
17625
|
+
// src/compositions/comment-thread/utils/formatCommentDate.ts
|
|
17626
|
+
function formatCommentDate(date) {
|
|
17627
|
+
const now = /* @__PURE__ */ new Date();
|
|
17628
|
+
const target = new Date(date);
|
|
17629
|
+
const seconds = Math.floor((now.getTime() - target.getTime()) / 1e3);
|
|
17630
|
+
const intervals = [
|
|
17631
|
+
{
|
|
17632
|
+
label: "year",
|
|
17633
|
+
seconds: 31536e3
|
|
17634
|
+
},
|
|
17635
|
+
{
|
|
17636
|
+
label: "month",
|
|
17637
|
+
seconds: 2592e3
|
|
17638
|
+
},
|
|
17639
|
+
{
|
|
17640
|
+
label: "day",
|
|
17641
|
+
seconds: 86400
|
|
17642
|
+
},
|
|
17643
|
+
{
|
|
17644
|
+
label: "hour",
|
|
17645
|
+
seconds: 3600
|
|
17646
|
+
},
|
|
17647
|
+
{
|
|
17648
|
+
label: "minute",
|
|
17649
|
+
seconds: 60
|
|
17650
|
+
}
|
|
17651
|
+
];
|
|
17652
|
+
for (const interval of intervals) {
|
|
17653
|
+
const count = Math.floor(seconds / interval.seconds);
|
|
17654
|
+
if (count >= 1) {
|
|
17655
|
+
return `${count} ${interval.label}${count > 1 ? "s" : ""} ago`;
|
|
17656
|
+
}
|
|
17657
|
+
}
|
|
17658
|
+
return "Just now";
|
|
17659
|
+
}
|
|
17660
|
+
function CommentHeader({
|
|
17661
|
+
avatar,
|
|
17662
|
+
username,
|
|
17663
|
+
firstName,
|
|
17664
|
+
lastName,
|
|
17665
|
+
createdAt,
|
|
17666
|
+
edited
|
|
17667
|
+
}) {
|
|
17668
|
+
const displayName = firstName || lastName ? `${firstName ?? ""} ${lastName ?? ""}`.trim() : username;
|
|
17669
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
17670
|
+
/* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: avatar, size: "sm" }),
|
|
17671
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap min-w-0", children: [
|
|
17672
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-sm text-gray-900 dark:text-gray-100", children: displayName }),
|
|
17673
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
|
|
17674
|
+
"@",
|
|
17675
|
+
username
|
|
17676
|
+
] }),
|
|
17677
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: "\xB7" }),
|
|
17678
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: formatCommentDate(createdAt) }),
|
|
17679
|
+
edited && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500", children: "(edited)" })
|
|
17680
|
+
] })
|
|
17681
|
+
] });
|
|
17682
|
+
}
|
|
17683
|
+
var CommentHeader_default = CommentHeader;
|
|
17684
|
+
function CommentMenu({
|
|
17685
|
+
canEdit,
|
|
17686
|
+
canDelete,
|
|
17687
|
+
canReport,
|
|
17688
|
+
onEdit,
|
|
17689
|
+
onDelete,
|
|
17690
|
+
onReport
|
|
17691
|
+
}) {
|
|
17692
|
+
const [open, setOpen] = React4.useState(false);
|
|
17693
|
+
const ref = React4.useRef(null);
|
|
17694
|
+
React4.useEffect(() => {
|
|
17695
|
+
function handleOutsideClick(event) {
|
|
17696
|
+
if (ref.current && !ref.current.contains(event.target)) {
|
|
17697
|
+
setOpen(false);
|
|
17698
|
+
}
|
|
17699
|
+
}
|
|
17700
|
+
document.addEventListener("mousedown", handleOutsideClick);
|
|
17701
|
+
return () => document.removeEventListener("mousedown", handleOutsideClick);
|
|
17702
|
+
}, []);
|
|
17703
|
+
const hasActions = canEdit || canDelete || canReport;
|
|
17704
|
+
if (!hasActions) {
|
|
17705
|
+
return null;
|
|
17706
|
+
}
|
|
17707
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: "relative", children: [
|
|
17708
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17709
|
+
"button",
|
|
17710
|
+
{
|
|
17711
|
+
type: "button",
|
|
17712
|
+
onClick: () => setOpen((prev) => !prev),
|
|
17713
|
+
className: "\n text-gray-500\n hover:text-gray-900\n dark:hover:text-gray-100\n transition-colors\n ",
|
|
17714
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(bi.BiDotsVerticalRounded, { size: 18 })
|
|
17715
|
+
}
|
|
17716
|
+
),
|
|
17717
|
+
open && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17718
|
+
"div",
|
|
17719
|
+
{
|
|
17720
|
+
className: "\n absolute\n right-0\n top-full\n mt-2\n min-w-[180px]\n overflow-hidden\n rounded-xl\n border\n border-gray-200\n dark:border-neutral-800\n bg-white\n dark:bg-neutral-900\n shadow-xl\n z-50\n ",
|
|
17721
|
+
children: [
|
|
17722
|
+
canEdit && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17723
|
+
"button",
|
|
17724
|
+
{
|
|
17725
|
+
type: "button",
|
|
17726
|
+
onClick: () => {
|
|
17727
|
+
setOpen(false);
|
|
17728
|
+
onEdit?.();
|
|
17729
|
+
},
|
|
17730
|
+
className: "\n w-full\n flex\n items-center\n gap-2\n px-4\n py-3\n text-sm\n hover:bg-gray-100\n dark:hover:bg-neutral-800\n ",
|
|
17731
|
+
children: [
|
|
17732
|
+
/* @__PURE__ */ jsxRuntime.jsx(bi.BiEdit, {}),
|
|
17733
|
+
"Edit"
|
|
17734
|
+
]
|
|
17735
|
+
}
|
|
17736
|
+
),
|
|
17737
|
+
canDelete && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17738
|
+
"button",
|
|
17739
|
+
{
|
|
17740
|
+
type: "button",
|
|
17741
|
+
onClick: () => {
|
|
17742
|
+
setOpen(false);
|
|
17743
|
+
onDelete?.();
|
|
17744
|
+
},
|
|
17745
|
+
className: "\n w-full\n flex\n items-center\n gap-2\n px-4\n py-3\n text-sm\n text-red-500\n hover:bg-gray-100\n dark:hover:bg-neutral-800\n ",
|
|
17746
|
+
children: [
|
|
17747
|
+
/* @__PURE__ */ jsxRuntime.jsx(bi.BiTrash, {}),
|
|
17748
|
+
"Delete"
|
|
17749
|
+
]
|
|
17750
|
+
}
|
|
17751
|
+
),
|
|
17752
|
+
canReport && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17753
|
+
"button",
|
|
17754
|
+
{
|
|
17755
|
+
type: "button",
|
|
17756
|
+
onClick: () => {
|
|
17757
|
+
setOpen(false);
|
|
17758
|
+
onReport?.();
|
|
17759
|
+
},
|
|
17760
|
+
className: "\n w-full\n flex\n items-center\n gap-2\n px-4\n py-3\n text-sm\n hover:bg-gray-100\n dark:hover:bg-neutral-800\n ",
|
|
17761
|
+
children: [
|
|
17762
|
+
/* @__PURE__ */ jsxRuntime.jsx(bi.BiFlag, {}),
|
|
17763
|
+
"Report"
|
|
17764
|
+
]
|
|
17765
|
+
}
|
|
17766
|
+
)
|
|
17767
|
+
]
|
|
17768
|
+
}
|
|
17769
|
+
)
|
|
17770
|
+
] });
|
|
17771
|
+
}
|
|
17772
|
+
var CommentMenu_default = CommentMenu;
|
|
17773
|
+
function CommentRepliesToggle({
|
|
17774
|
+
repliesCount,
|
|
17775
|
+
collapsed,
|
|
17776
|
+
onToggle
|
|
17777
|
+
}) {
|
|
17778
|
+
if (repliesCount <= 0) {
|
|
17779
|
+
return null;
|
|
17780
|
+
}
|
|
17781
|
+
const label = collapsed ? `View ${repliesCount} ${repliesCount === 1 ? "reply" : "replies"}` : "Hide replies";
|
|
17782
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17783
|
+
"button",
|
|
17784
|
+
{
|
|
17785
|
+
type: "button",
|
|
17786
|
+
onClick: onToggle,
|
|
17787
|
+
className: "\n inline-flex\n items-center\n gap-1\n w-fit\n text-sm\n font-medium\n text-blue-500\n hover:text-blue-400\n transition-colors\n ",
|
|
17788
|
+
children: [
|
|
17789
|
+
collapsed ? /* @__PURE__ */ jsxRuntime.jsx(bi.BiChevronDown, { size: 18 }) : /* @__PURE__ */ jsxRuntime.jsx(bi.BiChevronUp, { size: 18 }),
|
|
17790
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: label })
|
|
17791
|
+
]
|
|
17792
|
+
}
|
|
17793
|
+
);
|
|
17794
|
+
}
|
|
17795
|
+
var CommentRepliesToggle_default = CommentRepliesToggle;
|
|
17796
|
+
function ReplyComposer({
|
|
17797
|
+
avatar,
|
|
17798
|
+
username,
|
|
17799
|
+
loading,
|
|
17800
|
+
onSubmit
|
|
17801
|
+
}) {
|
|
17802
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17803
|
+
CommentComposer_default,
|
|
17804
|
+
{
|
|
17805
|
+
avatar,
|
|
17806
|
+
loading,
|
|
17807
|
+
submitLabel: "Reply",
|
|
17808
|
+
placeholder: `Reply to @${username}`,
|
|
17809
|
+
onSubmit
|
|
17810
|
+
}
|
|
17811
|
+
) });
|
|
17812
|
+
}
|
|
17813
|
+
var ReplyComposer_default = ReplyComposer;
|
|
17814
|
+
|
|
17815
|
+
// src/compositions/comment-thread/constants/comment.constants.ts
|
|
17816
|
+
var MAX_COMMENT_DEPTH = 5;
|
|
17817
|
+
var COMMENT_INDENTATION = 24;
|
|
17818
|
+
function CommentItem({
|
|
17819
|
+
comment,
|
|
17820
|
+
depth = 0,
|
|
17821
|
+
onLike,
|
|
17822
|
+
onDislike,
|
|
17823
|
+
onReply,
|
|
17824
|
+
onEdit,
|
|
17825
|
+
onDelete,
|
|
17826
|
+
onReport
|
|
17827
|
+
}) {
|
|
17828
|
+
const [collapsed, setCollapsed] = React4.useState(false);
|
|
17829
|
+
const [isReplying, setIsReplying] = React4.useState(false);
|
|
17830
|
+
const resolvedDepth = Math.min(depth, MAX_COMMENT_DEPTH);
|
|
17831
|
+
async function handleReply(content) {
|
|
17832
|
+
await onReply?.(comment, content);
|
|
17833
|
+
setIsReplying(false);
|
|
17834
|
+
}
|
|
17835
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17836
|
+
"div",
|
|
17837
|
+
{
|
|
17838
|
+
className: "flex flex-col gap-4",
|
|
17839
|
+
style: {
|
|
17840
|
+
paddingLeft: resolvedDepth * COMMENT_INDENTATION
|
|
17841
|
+
},
|
|
17842
|
+
children: [
|
|
17843
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col gap-3 min-w-0", children: [
|
|
17844
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
17845
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17846
|
+
CommentHeader_default,
|
|
17847
|
+
{
|
|
17848
|
+
avatar: comment.author?.avatar,
|
|
17849
|
+
username: comment.author?.username ?? "unknown",
|
|
17850
|
+
firstName: comment.author?.firstName,
|
|
17851
|
+
lastName: comment.author?.lastName,
|
|
17852
|
+
createdAt: comment.createdAt,
|
|
17853
|
+
edited: comment.edited
|
|
17854
|
+
}
|
|
17855
|
+
),
|
|
17856
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17857
|
+
CommentMenu_default,
|
|
17858
|
+
{
|
|
17859
|
+
canEdit: comment.permissions?.canEdit,
|
|
17860
|
+
canDelete: comment.permissions?.canDelete,
|
|
17861
|
+
canReport: comment.permissions?.canReport,
|
|
17862
|
+
onEdit: () => onEdit?.(comment),
|
|
17863
|
+
onDelete: () => onDelete?.(comment),
|
|
17864
|
+
onReport: () => onReport?.(comment)
|
|
17865
|
+
}
|
|
17866
|
+
)
|
|
17867
|
+
] }),
|
|
17868
|
+
/* @__PURE__ */ jsxRuntime.jsx(CommentContent_default, { content: comment.content }),
|
|
17869
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17870
|
+
CommentActions_default,
|
|
17871
|
+
{
|
|
17872
|
+
likes: comment.likes,
|
|
17873
|
+
dislikes: comment.dislikes,
|
|
17874
|
+
liked: comment.liked,
|
|
17875
|
+
disliked: comment.disliked,
|
|
17876
|
+
canReply: comment.permissions?.canReply,
|
|
17877
|
+
onLike: () => onLike?.(comment),
|
|
17878
|
+
onDislike: () => onDislike?.(comment),
|
|
17879
|
+
onReply: () => setIsReplying((prev) => !prev)
|
|
17880
|
+
}
|
|
17881
|
+
),
|
|
17882
|
+
isReplying && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17883
|
+
ReplyComposer_default,
|
|
17884
|
+
{
|
|
17885
|
+
avatar: comment.author?.avatar,
|
|
17886
|
+
username: comment.author?.username,
|
|
17887
|
+
onSubmit: handleReply
|
|
17888
|
+
}
|
|
17889
|
+
),
|
|
17890
|
+
!!comment.replies?.length && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17891
|
+
CommentRepliesToggle_default,
|
|
17892
|
+
{
|
|
17893
|
+
collapsed,
|
|
17894
|
+
repliesCount: comment.replies.length,
|
|
17895
|
+
onToggle: () => setCollapsed((prev) => !prev)
|
|
17896
|
+
}
|
|
17897
|
+
)
|
|
17898
|
+
] }) }),
|
|
17899
|
+
!collapsed && !!comment.replies?.length && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17900
|
+
"div",
|
|
17901
|
+
{
|
|
17902
|
+
className: cn(
|
|
17903
|
+
"border-l border-gray-200 dark:border-neutral-800",
|
|
17904
|
+
"pl-4 ml-5"
|
|
17905
|
+
),
|
|
17906
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17907
|
+
CommentList_default,
|
|
17908
|
+
{
|
|
17909
|
+
comments: comment.replies,
|
|
17910
|
+
depth: depth + 1,
|
|
17911
|
+
onLike,
|
|
17912
|
+
onDislike,
|
|
17913
|
+
onReply,
|
|
17914
|
+
onEdit,
|
|
17915
|
+
onDelete,
|
|
17916
|
+
onReport
|
|
17917
|
+
}
|
|
17918
|
+
)
|
|
17919
|
+
}
|
|
17920
|
+
)
|
|
17921
|
+
]
|
|
17922
|
+
}
|
|
17923
|
+
);
|
|
17924
|
+
}
|
|
17925
|
+
var CommentItem_default = CommentItem;
|
|
17926
|
+
function CommentList({
|
|
17927
|
+
comments,
|
|
17928
|
+
depth = 0,
|
|
17929
|
+
onLike,
|
|
17930
|
+
onDislike,
|
|
17931
|
+
onReply,
|
|
17932
|
+
onEdit,
|
|
17933
|
+
onDelete,
|
|
17934
|
+
onReport
|
|
17935
|
+
}) {
|
|
17936
|
+
if (!comments.length) {
|
|
17937
|
+
return null;
|
|
17938
|
+
}
|
|
17939
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-8", children: comments.map((comment) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
17940
|
+
CommentItem_default,
|
|
17941
|
+
{
|
|
17942
|
+
comment,
|
|
17943
|
+
depth,
|
|
17944
|
+
onLike,
|
|
17945
|
+
onDislike,
|
|
17946
|
+
onReply,
|
|
17947
|
+
onEdit,
|
|
17948
|
+
onDelete,
|
|
17949
|
+
onReport
|
|
17950
|
+
},
|
|
17951
|
+
comment.id
|
|
17952
|
+
)) });
|
|
17953
|
+
}
|
|
17954
|
+
var CommentList_default = CommentList;
|
|
17955
|
+
function EditCommentModal({
|
|
17956
|
+
show,
|
|
17957
|
+
comment,
|
|
17958
|
+
handleCloseModal,
|
|
17959
|
+
onSubmit
|
|
17960
|
+
}) {
|
|
17961
|
+
if (!comment) return null;
|
|
17962
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Modal_default, { title: "Edit Comment", show, handleOnClose: handleCloseModal, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17963
|
+
Form,
|
|
17964
|
+
{
|
|
17965
|
+
enableReinitialize: true,
|
|
17966
|
+
initialValues: {
|
|
17967
|
+
content: comment.content
|
|
17968
|
+
},
|
|
17969
|
+
onSubmit: async (values) => {
|
|
17970
|
+
await onSubmit?.(comment, values.content);
|
|
17971
|
+
handleCloseModal();
|
|
17972
|
+
},
|
|
17973
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
17974
|
+
/* @__PURE__ */ jsxRuntime.jsx(TextArea_default, { name: "content", rows: 5, placeholder: "Comment" }),
|
|
17975
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button_default, { type: "submit", variant: "success", text: "Save Changes" })
|
|
17976
|
+
] })
|
|
17977
|
+
}
|
|
17978
|
+
) });
|
|
17979
|
+
}
|
|
17980
|
+
var EditCommentModal_default = EditCommentModal;
|
|
17981
|
+
function DeleteCommentModal({
|
|
17982
|
+
show,
|
|
17983
|
+
comment,
|
|
17984
|
+
handleCloseModal,
|
|
17985
|
+
onDelete
|
|
17986
|
+
}) {
|
|
17987
|
+
if (!comment) return null;
|
|
17988
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Modal_default, { title: "Delete Comment", show, handleOnClose: handleCloseModal, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
17989
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography.Paragraph, { children: "Are you sure you want to permanently delete this comment?" }),
|
|
17990
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3 justify-end", children: [
|
|
17991
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button_default, { text: "Cancel", appearance: "ghost", onClick: handleCloseModal }),
|
|
17992
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17993
|
+
Button_default,
|
|
17994
|
+
{
|
|
17995
|
+
text: "Delete",
|
|
17996
|
+
variant: "danger",
|
|
17997
|
+
onClick: async () => {
|
|
17998
|
+
await onDelete?.(comment);
|
|
17999
|
+
handleCloseModal();
|
|
18000
|
+
}
|
|
18001
|
+
}
|
|
18002
|
+
)
|
|
18003
|
+
] })
|
|
18004
|
+
] }) });
|
|
18005
|
+
}
|
|
18006
|
+
var DeleteCommentModal_default = DeleteCommentModal;
|
|
18007
|
+
var REPORT_REASONS = [
|
|
18008
|
+
{
|
|
18009
|
+
label: "Spam",
|
|
18010
|
+
value: "spam"
|
|
18011
|
+
},
|
|
18012
|
+
{
|
|
18013
|
+
label: "Harassment",
|
|
18014
|
+
value: "harassment"
|
|
18015
|
+
},
|
|
18016
|
+
{
|
|
18017
|
+
label: "Hate Speech",
|
|
18018
|
+
value: "hate_speech"
|
|
18019
|
+
},
|
|
18020
|
+
{
|
|
18021
|
+
label: "Misleading Information",
|
|
18022
|
+
value: "misleading_information"
|
|
18023
|
+
},
|
|
18024
|
+
{
|
|
18025
|
+
label: "Other",
|
|
18026
|
+
value: "other"
|
|
18027
|
+
}
|
|
18028
|
+
];
|
|
18029
|
+
function ReportCommentModal({
|
|
18030
|
+
show,
|
|
18031
|
+
comment,
|
|
18032
|
+
handleCloseModal,
|
|
18033
|
+
onSubmit
|
|
18034
|
+
}) {
|
|
18035
|
+
if (!comment) return null;
|
|
18036
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Modal_default, { title: "Report Comment", show, handleOnClose: handleCloseModal, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
18037
|
+
Form,
|
|
18038
|
+
{
|
|
18039
|
+
initialValues: {
|
|
18040
|
+
reason: "",
|
|
18041
|
+
description: ""
|
|
18042
|
+
},
|
|
18043
|
+
onSubmit: async (values) => {
|
|
18044
|
+
await onSubmit?.(comment, {
|
|
18045
|
+
reason: values.reason,
|
|
18046
|
+
description: values.description
|
|
18047
|
+
});
|
|
18048
|
+
handleCloseModal();
|
|
18049
|
+
},
|
|
18050
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
18051
|
+
/* @__PURE__ */ jsxRuntime.jsx(Select_default, { name: "reason", placeholder: "Reason", options: REPORT_REASONS }),
|
|
18052
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18053
|
+
TextArea_default,
|
|
18054
|
+
{
|
|
18055
|
+
name: "description",
|
|
18056
|
+
rows: 4,
|
|
18057
|
+
placeholder: "Additional details"
|
|
18058
|
+
}
|
|
18059
|
+
),
|
|
18060
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button_default, { type: "submit", variant: "danger", text: "Submit Report" })
|
|
18061
|
+
] })
|
|
18062
|
+
}
|
|
18063
|
+
) });
|
|
18064
|
+
}
|
|
18065
|
+
var ReportCommentModal_default = ReportCommentModal;
|
|
18066
|
+
function useCommentModals() {
|
|
18067
|
+
const [showEditModal, setShowEditModal] = React4.useState(false);
|
|
18068
|
+
const [showDeleteModal, setShowDeleteModal] = React4.useState(false);
|
|
18069
|
+
const [showReportModal, setShowReportModal] = React4.useState(false);
|
|
18070
|
+
return {
|
|
18071
|
+
showEditModal,
|
|
18072
|
+
openEditModal: () => setShowEditModal(true),
|
|
18073
|
+
closeEditModal: () => setShowEditModal(false),
|
|
18074
|
+
showDeleteModal,
|
|
18075
|
+
openDeleteModal: () => setShowDeleteModal(true),
|
|
18076
|
+
closeDeleteModal: () => setShowDeleteModal(false),
|
|
18077
|
+
showReportModal,
|
|
18078
|
+
openReportModal: () => setShowReportModal(true),
|
|
18079
|
+
closeReportModal: () => setShowReportModal(false)
|
|
18080
|
+
};
|
|
18081
|
+
}
|
|
18082
|
+
function useCommentSelection() {
|
|
18083
|
+
const [selectedComment, setSelectedComment] = React4.useState(
|
|
18084
|
+
null
|
|
18085
|
+
);
|
|
18086
|
+
function selectComment(comment) {
|
|
18087
|
+
setSelectedComment(comment);
|
|
18088
|
+
}
|
|
18089
|
+
function clearSelection() {
|
|
18090
|
+
setSelectedComment(null);
|
|
18091
|
+
}
|
|
18092
|
+
return {
|
|
18093
|
+
selectedComment,
|
|
18094
|
+
selectComment,
|
|
18095
|
+
clearSelection
|
|
18096
|
+
};
|
|
18097
|
+
}
|
|
18098
|
+
|
|
18099
|
+
// src/compositions/comment-thread/utils/buildCommentTree.ts
|
|
18100
|
+
function buildCommentTree(comments) {
|
|
18101
|
+
const map = /* @__PURE__ */ new Map();
|
|
18102
|
+
const roots = [];
|
|
18103
|
+
comments.forEach((comment) => {
|
|
18104
|
+
map.set(comment.id, {
|
|
18105
|
+
...comment,
|
|
18106
|
+
replies: []
|
|
18107
|
+
});
|
|
18108
|
+
});
|
|
18109
|
+
comments.forEach((comment) => {
|
|
18110
|
+
const current = map.get(comment.id);
|
|
18111
|
+
if (!comment.parentCommentId) {
|
|
18112
|
+
roots.push(current);
|
|
18113
|
+
return;
|
|
18114
|
+
}
|
|
18115
|
+
const parent = map.get(comment.parentCommentId);
|
|
18116
|
+
if (parent) {
|
|
18117
|
+
parent.replies.push(current);
|
|
18118
|
+
}
|
|
18119
|
+
});
|
|
18120
|
+
return roots;
|
|
18121
|
+
}
|
|
18122
|
+
|
|
18123
|
+
// src/compositions/comment-thread/utils/updateComment.ts
|
|
18124
|
+
function updateComment(comments, commentId, updater) {
|
|
18125
|
+
return comments.map((comment) => {
|
|
18126
|
+
if (comment.id === commentId) {
|
|
18127
|
+
return updater(comment);
|
|
18128
|
+
}
|
|
18129
|
+
return {
|
|
18130
|
+
...comment,
|
|
18131
|
+
replies: comment.replies ? updateComment(comment.replies, commentId, updater) : []
|
|
18132
|
+
};
|
|
18133
|
+
});
|
|
18134
|
+
}
|
|
18135
|
+
|
|
18136
|
+
// src/compositions/comment-thread/utils/removeComment.ts
|
|
18137
|
+
function removeComment(comments, commentId) {
|
|
18138
|
+
return comments.filter((comment) => comment.id !== commentId).map((comment) => ({
|
|
18139
|
+
...comment,
|
|
18140
|
+
replies: comment.replies ? removeComment(comment.replies, commentId) : []
|
|
18141
|
+
}));
|
|
18142
|
+
}
|
|
18143
|
+
|
|
18144
|
+
// src/compositions/comment-thread/utils/insertReply.ts
|
|
18145
|
+
function insertReply(comments, parentId, reply) {
|
|
18146
|
+
return comments.map((comment) => {
|
|
18147
|
+
if (comment.id === parentId) {
|
|
18148
|
+
return {
|
|
18149
|
+
...comment,
|
|
18150
|
+
replies: [...comment.replies || [], reply]
|
|
18151
|
+
};
|
|
18152
|
+
}
|
|
18153
|
+
return {
|
|
18154
|
+
...comment,
|
|
18155
|
+
replies: comment.replies ? insertReply(comment.replies, parentId, reply) : []
|
|
18156
|
+
};
|
|
18157
|
+
});
|
|
18158
|
+
}
|
|
18159
|
+
function CommentThread({
|
|
18160
|
+
postId,
|
|
18161
|
+
currentUser,
|
|
18162
|
+
dataSource,
|
|
18163
|
+
loading = false,
|
|
18164
|
+
onEdit,
|
|
18165
|
+
onDelete,
|
|
18166
|
+
onReport
|
|
18167
|
+
}) {
|
|
18168
|
+
const [comments, setComments] = React4.useState([]);
|
|
18169
|
+
const [isLoadingComments, setIsLoadingComments] = React4.useState(true);
|
|
18170
|
+
const selection = useCommentSelection();
|
|
18171
|
+
const modals = useCommentModals();
|
|
18172
|
+
React4.useEffect(() => {
|
|
18173
|
+
async function loadComments() {
|
|
18174
|
+
try {
|
|
18175
|
+
const result = await dataSource.getComments();
|
|
18176
|
+
setComments(buildCommentTree(result));
|
|
18177
|
+
} finally {
|
|
18178
|
+
setIsLoadingComments(false);
|
|
18179
|
+
}
|
|
18180
|
+
}
|
|
18181
|
+
loadComments();
|
|
18182
|
+
}, [dataSource]);
|
|
18183
|
+
async function handleCreateComment(content) {
|
|
18184
|
+
const comment = await dataSource.createComment({
|
|
18185
|
+
content,
|
|
18186
|
+
parentCommentId: null
|
|
18187
|
+
});
|
|
18188
|
+
setComments((prev) => [comment, ...prev]);
|
|
18189
|
+
}
|
|
18190
|
+
async function handleReply(parentComment, content) {
|
|
18191
|
+
const reply = await dataSource.createComment({
|
|
18192
|
+
content,
|
|
18193
|
+
parentCommentId: parentComment.id
|
|
18194
|
+
});
|
|
18195
|
+
setComments((prev) => insertReply(prev, parentComment.id, reply));
|
|
18196
|
+
}
|
|
18197
|
+
async function handleLike(comment) {
|
|
18198
|
+
const result = await dataSource.toggleLike(comment.id);
|
|
18199
|
+
setComments(
|
|
18200
|
+
(prev) => updateComment(prev, comment.id, (item) => ({
|
|
18201
|
+
...item,
|
|
18202
|
+
likes: result.likes,
|
|
18203
|
+
dislikes: result.dislikes,
|
|
18204
|
+
liked: result.liked,
|
|
18205
|
+
disliked: result.disliked
|
|
18206
|
+
}))
|
|
18207
|
+
);
|
|
18208
|
+
}
|
|
18209
|
+
async function handleDislike(comment) {
|
|
18210
|
+
const result = await dataSource.toggleDislike(comment.id);
|
|
18211
|
+
setComments(
|
|
18212
|
+
(prev) => updateComment(prev, comment.id, (item) => ({
|
|
18213
|
+
...item,
|
|
18214
|
+
likes: result.likes,
|
|
18215
|
+
dislikes: result.dislikes,
|
|
18216
|
+
liked: result.liked,
|
|
18217
|
+
disliked: result.disliked
|
|
18218
|
+
}))
|
|
18219
|
+
);
|
|
18220
|
+
}
|
|
18221
|
+
async function handleUpdateComment(comment, content) {
|
|
18222
|
+
const updated = await dataSource.updateComment({
|
|
18223
|
+
id: comment.id,
|
|
18224
|
+
content
|
|
18225
|
+
});
|
|
18226
|
+
setComments((prev) => updateComment(prev, comment.id, () => updated));
|
|
18227
|
+
}
|
|
18228
|
+
async function handleDeleteComment(comment) {
|
|
18229
|
+
await dataSource.deleteComment(comment.id);
|
|
18230
|
+
setComments((prev) => removeComment(prev, comment.id));
|
|
18231
|
+
onDelete?.(comment);
|
|
18232
|
+
}
|
|
18233
|
+
async function handleReportComment(comment, payload) {
|
|
18234
|
+
await dataSource.reportComment?.(
|
|
18235
|
+
comment.id,
|
|
18236
|
+
payload.reason,
|
|
18237
|
+
payload.description
|
|
18238
|
+
);
|
|
18239
|
+
onReport?.(comment);
|
|
18240
|
+
}
|
|
18241
|
+
if (loading || isLoadingComments) {
|
|
18242
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-6", children: "Loading comments..." });
|
|
18243
|
+
}
|
|
18244
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
18245
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-8", children: [
|
|
18246
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18247
|
+
CommentComposer_default,
|
|
18248
|
+
{
|
|
18249
|
+
avatar: currentUser.avatar,
|
|
18250
|
+
onSubmit: handleCreateComment
|
|
18251
|
+
}
|
|
18252
|
+
),
|
|
18253
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18254
|
+
CommentList_default,
|
|
18255
|
+
{
|
|
18256
|
+
comments,
|
|
18257
|
+
onLike: handleLike,
|
|
18258
|
+
onDislike: handleDislike,
|
|
18259
|
+
onReply: handleReply,
|
|
18260
|
+
onEdit: (comment) => {
|
|
18261
|
+
selection.selectComment(comment);
|
|
18262
|
+
onEdit?.(comment);
|
|
18263
|
+
modals.openEditModal();
|
|
18264
|
+
},
|
|
18265
|
+
onDelete: (comment) => {
|
|
18266
|
+
selection.selectComment(comment);
|
|
18267
|
+
modals.openDeleteModal();
|
|
18268
|
+
},
|
|
18269
|
+
onReport: (comment) => {
|
|
18270
|
+
selection.selectComment(comment);
|
|
18271
|
+
onReport?.(comment);
|
|
18272
|
+
modals.openReportModal();
|
|
18273
|
+
}
|
|
18274
|
+
}
|
|
18275
|
+
)
|
|
18276
|
+
] }),
|
|
18277
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18278
|
+
EditCommentModal_default,
|
|
18279
|
+
{
|
|
18280
|
+
show: modals.showEditModal,
|
|
18281
|
+
comment: selection.selectedComment,
|
|
18282
|
+
handleCloseModal: modals.closeEditModal,
|
|
18283
|
+
onSubmit: handleUpdateComment
|
|
18284
|
+
}
|
|
18285
|
+
),
|
|
18286
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18287
|
+
DeleteCommentModal_default,
|
|
18288
|
+
{
|
|
18289
|
+
show: modals.showDeleteModal,
|
|
18290
|
+
comment: selection.selectedComment,
|
|
18291
|
+
handleCloseModal: modals.closeDeleteModal,
|
|
18292
|
+
onDelete: handleDeleteComment
|
|
18293
|
+
}
|
|
18294
|
+
),
|
|
18295
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18296
|
+
ReportCommentModal_default,
|
|
18297
|
+
{
|
|
18298
|
+
show: modals.showReportModal,
|
|
18299
|
+
comment: selection.selectedComment,
|
|
18300
|
+
handleCloseModal: modals.closeReportModal,
|
|
18301
|
+
onSubmit: handleReportComment
|
|
18302
|
+
}
|
|
18303
|
+
)
|
|
18304
|
+
] });
|
|
18305
|
+
}
|
|
18306
|
+
var CommentThread_default = CommentThread;
|
|
17488
18307
|
function DataViewTable({
|
|
17489
18308
|
title,
|
|
17490
18309
|
columns,
|
|
@@ -18322,6 +19141,7 @@ exports.CloudinaryImage = CloudinaryImage_default;
|
|
|
18322
19141
|
exports.CloudinaryProvider = CloudinaryProvider;
|
|
18323
19142
|
exports.CloudinaryVideo = CloudinaryVideo_default;
|
|
18324
19143
|
exports.Code = Code;
|
|
19144
|
+
exports.CommentThread = CommentThread_default;
|
|
18325
19145
|
exports.Content = Content;
|
|
18326
19146
|
exports.ContentArea = ContentArea_default;
|
|
18327
19147
|
exports.DataView = DataView;
|