elseware-ui 2.31.10 → 2.31.11
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/index.css +9 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +49 -4
- package/dist/index.d.ts +49 -4
- package/dist/index.js +150 -134
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +150 -134
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -17578,9 +17578,12 @@ function CommentContent({ comment }) {
|
|
|
17578
17578
|
var CommentContent_default = CommentContent;
|
|
17579
17579
|
|
|
17580
17580
|
// src/compositions/comment-thread/utils/formatCommentDate.ts
|
|
17581
|
-
function formatCommentDate(date) {
|
|
17582
|
-
const now = /* @__PURE__ */ new Date();
|
|
17581
|
+
function formatCommentDate(date, format = "relative") {
|
|
17583
17582
|
const target = new Date(date);
|
|
17583
|
+
if (format === "absolute") {
|
|
17584
|
+
return target.toLocaleString();
|
|
17585
|
+
}
|
|
17586
|
+
const now = /* @__PURE__ */ new Date();
|
|
17584
17587
|
const seconds = Math.floor((now.getTime() - target.getTime()) / 1e3);
|
|
17585
17588
|
const intervals = [
|
|
17586
17589
|
{
|
|
@@ -17612,13 +17615,13 @@ function formatCommentDate(date) {
|
|
|
17612
17615
|
}
|
|
17613
17616
|
return "Just now";
|
|
17614
17617
|
}
|
|
17615
|
-
function CommentHeader({ comment }) {
|
|
17618
|
+
function CommentHeader({ comment, config }) {
|
|
17616
17619
|
const author = comment.author;
|
|
17617
17620
|
const displayName = author?.firstName || author?.lastName ? `${author?.firstName ?? ""} ${author?.lastName ?? ""}`.trim() : author?.username ?? "Unknown";
|
|
17618
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3
|
|
17621
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [
|
|
17619
17622
|
/* @__PURE__ */ jsx(Avatar, { src: author?.avatar, size: "sm" }),
|
|
17620
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
17621
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold text-
|
|
17623
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [
|
|
17624
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: displayName }),
|
|
17622
17625
|
author?.username && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
17623
17626
|
/* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
|
|
17624
17627
|
"@",
|
|
@@ -17626,7 +17629,7 @@ function CommentHeader({ comment }) {
|
|
|
17626
17629
|
] }),
|
|
17627
17630
|
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: "\xB7" })
|
|
17628
17631
|
] }),
|
|
17629
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: formatCommentDate(comment.createdAt) }),
|
|
17632
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: formatCommentDate(comment.createdAt, config.dateFormat) }),
|
|
17630
17633
|
comment.edited && /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500", children: "(edited)" })
|
|
17631
17634
|
] })
|
|
17632
17635
|
] });
|
|
@@ -17719,20 +17722,29 @@ var CommentMenu_default = CommentMenu;
|
|
|
17719
17722
|
function CommentRepliesToggle({
|
|
17720
17723
|
repliesCount,
|
|
17721
17724
|
collapsed,
|
|
17725
|
+
loading = false,
|
|
17722
17726
|
onToggle
|
|
17723
17727
|
}) {
|
|
17724
17728
|
if (repliesCount <= 0) {
|
|
17725
17729
|
return null;
|
|
17726
17730
|
}
|
|
17727
|
-
|
|
17731
|
+
let label = "";
|
|
17732
|
+
if (loading) {
|
|
17733
|
+
label = "Loading replies...";
|
|
17734
|
+
} else if (collapsed) {
|
|
17735
|
+
label = `View ${repliesCount} ${repliesCount === 1 ? "reply" : "replies"}`;
|
|
17736
|
+
} else {
|
|
17737
|
+
label = "Hide replies";
|
|
17738
|
+
}
|
|
17728
17739
|
return /* @__PURE__ */ jsxs(
|
|
17729
17740
|
"button",
|
|
17730
17741
|
{
|
|
17731
17742
|
type: "button",
|
|
17743
|
+
disabled: loading,
|
|
17732
17744
|
onClick: onToggle,
|
|
17733
|
-
className: "inline-flex w-fit items-center gap-1 text-sm font-medium text-blue-500 transition-colors hover:text-blue-400",
|
|
17745
|
+
className: "inline-flex w-fit items-center gap-1 text-sm font-medium text-blue-500 transition-colors hover:text-blue-400 disabled:cursor-not-allowed disabled:opacity-60",
|
|
17734
17746
|
children: [
|
|
17735
|
-
collapsed ? /* @__PURE__ */ jsx(BiChevronDown, { size: 18 }) : /* @__PURE__ */ jsx(BiChevronUp, { size: 18 }),
|
|
17747
|
+
!loading && (collapsed ? /* @__PURE__ */ jsx(BiChevronDown, { size: 18 }) : /* @__PURE__ */ jsx(BiChevronUp, { size: 18 })),
|
|
17736
17748
|
/* @__PURE__ */ jsx("span", { children: label })
|
|
17737
17749
|
]
|
|
17738
17750
|
}
|
|
@@ -17763,18 +17775,24 @@ function ReplyComposer({
|
|
|
17763
17775
|
var ReplyComposer_default = ReplyComposer;
|
|
17764
17776
|
function CommentItem({
|
|
17765
17777
|
comment,
|
|
17778
|
+
replies = [],
|
|
17779
|
+
allReplies = {},
|
|
17766
17780
|
depth = 0,
|
|
17767
17781
|
config,
|
|
17768
17782
|
components,
|
|
17769
17783
|
onLike,
|
|
17770
17784
|
onDislike,
|
|
17771
17785
|
onReply,
|
|
17786
|
+
onLoadReplies,
|
|
17772
17787
|
onEdit,
|
|
17773
17788
|
onDelete,
|
|
17774
17789
|
onReport
|
|
17775
17790
|
}) {
|
|
17776
|
-
const [collapsed, setCollapsed] = useState(
|
|
17791
|
+
const [collapsed, setCollapsed] = useState(true);
|
|
17777
17792
|
const [isReplying, setIsReplying] = useState(false);
|
|
17793
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
17794
|
+
const [loadingReplies, setLoadingReplies] = useState(false);
|
|
17795
|
+
const [repliesLoaded, setRepliesLoaded] = useState(false);
|
|
17778
17796
|
const resolvedDepth = Math.min(depth, config.maxDepth);
|
|
17779
17797
|
const {
|
|
17780
17798
|
Header: HeaderComponent = CommentHeader_default,
|
|
@@ -17787,100 +17805,108 @@ function CommentItem({
|
|
|
17787
17805
|
async function handleReply(content) {
|
|
17788
17806
|
await onReply?.(comment, content);
|
|
17789
17807
|
setIsReplying(false);
|
|
17808
|
+
setCollapsed(false);
|
|
17809
|
+
setRepliesLoaded(true);
|
|
17790
17810
|
}
|
|
17791
|
-
|
|
17792
|
-
|
|
17811
|
+
async function handleToggleReplies() {
|
|
17812
|
+
const nextCollapsed = !collapsed;
|
|
17813
|
+
if (!nextCollapsed && !repliesLoaded && onLoadReplies) {
|
|
17814
|
+
try {
|
|
17815
|
+
setLoadingReplies(true);
|
|
17816
|
+
await onLoadReplies(comment);
|
|
17817
|
+
setRepliesLoaded(true);
|
|
17818
|
+
} finally {
|
|
17819
|
+
setLoadingReplies(false);
|
|
17820
|
+
}
|
|
17821
|
+
}
|
|
17822
|
+
setCollapsed(nextCollapsed);
|
|
17823
|
+
}
|
|
17824
|
+
return /* @__PURE__ */ jsx(
|
|
17793
17825
|
"div",
|
|
17794
17826
|
{
|
|
17795
17827
|
className: "flex flex-col gap-4",
|
|
17796
17828
|
style: {
|
|
17797
17829
|
paddingLeft: resolvedDepth * config.indentation
|
|
17798
17830
|
},
|
|
17799
|
-
children: [
|
|
17800
|
-
/* @__PURE__ */
|
|
17801
|
-
/* @__PURE__ */
|
|
17802
|
-
/* @__PURE__ */ jsx(HeaderComponent, { comment }),
|
|
17803
|
-
/* @__PURE__ */ jsx(
|
|
17804
|
-
MenuComponent,
|
|
17805
|
-
{
|
|
17806
|
-
comment,
|
|
17807
|
-
open: menuOpen,
|
|
17808
|
-
setOpen: setMenuOpen,
|
|
17809
|
-
canEdit: comment.permissions?.canEdit,
|
|
17810
|
-
canDelete: comment.permissions?.canDelete,
|
|
17811
|
-
canReport: comment.permissions?.canReport,
|
|
17812
|
-
onEdit: () => onEdit?.(comment),
|
|
17813
|
-
onDelete: () => onDelete?.(comment),
|
|
17814
|
-
onReport: () => onReport?.(comment)
|
|
17815
|
-
}
|
|
17816
|
-
)
|
|
17817
|
-
] }),
|
|
17818
|
-
/* @__PURE__ */ jsx(ContentComponent, { comment }),
|
|
17831
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-3", children: [
|
|
17832
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
17833
|
+
/* @__PURE__ */ jsx(HeaderComponent, { comment, config }),
|
|
17819
17834
|
/* @__PURE__ */ jsx(
|
|
17820
|
-
|
|
17835
|
+
MenuComponent,
|
|
17821
17836
|
{
|
|
17822
17837
|
comment,
|
|
17823
|
-
|
|
17824
|
-
|
|
17825
|
-
|
|
17826
|
-
|
|
17827
|
-
|
|
17828
|
-
|
|
17829
|
-
|
|
17830
|
-
|
|
17831
|
-
avatar: comment.author?.avatar,
|
|
17832
|
-
username: comment.author?.username,
|
|
17833
|
-
placeholder: `Reply to @${comment.author?.username}`,
|
|
17834
|
-
submitLabel: "Reply",
|
|
17835
|
-
onSubmit: handleReply
|
|
17836
|
-
}
|
|
17837
|
-
),
|
|
17838
|
-
!!comment.replies?.length && /* @__PURE__ */ jsx(
|
|
17839
|
-
RepliesToggleComponent,
|
|
17840
|
-
{
|
|
17841
|
-
collapsed,
|
|
17842
|
-
repliesCount: comment.replies.length,
|
|
17843
|
-
onToggle: () => setCollapsed((prev) => !prev)
|
|
17838
|
+
open: menuOpen,
|
|
17839
|
+
setOpen: setMenuOpen,
|
|
17840
|
+
canEdit: comment.permissions?.canEdit,
|
|
17841
|
+
canDelete: comment.permissions?.canDelete,
|
|
17842
|
+
canReport: comment.permissions?.canReport,
|
|
17843
|
+
onEdit: () => onEdit?.(comment),
|
|
17844
|
+
onDelete: () => onDelete?.(comment),
|
|
17845
|
+
onReport: () => onReport?.(comment)
|
|
17844
17846
|
}
|
|
17845
17847
|
)
|
|
17846
|
-
] })
|
|
17847
|
-
|
|
17848
|
-
|
|
17848
|
+
] }),
|
|
17849
|
+
/* @__PURE__ */ jsx(ContentComponent, { comment }),
|
|
17850
|
+
/* @__PURE__ */ jsx(
|
|
17851
|
+
ActionsComponent,
|
|
17849
17852
|
{
|
|
17850
|
-
|
|
17851
|
-
|
|
17852
|
-
|
|
17853
|
-
)
|
|
17854
|
-
children: /* @__PURE__ */ jsx(
|
|
17855
|
-
CommentList_default,
|
|
17856
|
-
{
|
|
17857
|
-
comments: comment.replies,
|
|
17858
|
-
depth: depth + 1,
|
|
17859
|
-
config,
|
|
17860
|
-
components,
|
|
17861
|
-
onLike,
|
|
17862
|
-
onDislike,
|
|
17863
|
-
onReply,
|
|
17864
|
-
onEdit,
|
|
17865
|
-
onDelete,
|
|
17866
|
-
onReport
|
|
17867
|
-
}
|
|
17868
|
-
)
|
|
17853
|
+
comment,
|
|
17854
|
+
onLike: () => onLike?.(comment),
|
|
17855
|
+
onDislike: () => onDislike?.(comment),
|
|
17856
|
+
onReply: () => setIsReplying((prev) => !prev)
|
|
17869
17857
|
}
|
|
17870
|
-
)
|
|
17871
|
-
|
|
17858
|
+
),
|
|
17859
|
+
isReplying && /* @__PURE__ */ jsx(
|
|
17860
|
+
ReplyComposerComponent,
|
|
17861
|
+
{
|
|
17862
|
+
avatar: comment.author?.avatar,
|
|
17863
|
+
username: comment.author?.username,
|
|
17864
|
+
placeholder: `Reply to @${comment.author?.username}`,
|
|
17865
|
+
submitLabel: "Reply",
|
|
17866
|
+
onSubmit: handleReply
|
|
17867
|
+
}
|
|
17868
|
+
),
|
|
17869
|
+
comment.replyCount > 0 && /* @__PURE__ */ jsx(
|
|
17870
|
+
RepliesToggleComponent,
|
|
17871
|
+
{
|
|
17872
|
+
collapsed,
|
|
17873
|
+
loading: loadingReplies,
|
|
17874
|
+
repliesCount: comment.replyCount,
|
|
17875
|
+
onToggle: handleToggleReplies
|
|
17876
|
+
}
|
|
17877
|
+
),
|
|
17878
|
+
!collapsed && replies.length > 0 && /* @__PURE__ */ jsx("div", { className: "ml-5 border-l border-gray-200 pl-4 dark:border-neutral-800", children: /* @__PURE__ */ jsx(
|
|
17879
|
+
CommentList_default,
|
|
17880
|
+
{
|
|
17881
|
+
comments: replies,
|
|
17882
|
+
replies: allReplies,
|
|
17883
|
+
depth: depth + 1,
|
|
17884
|
+
config,
|
|
17885
|
+
components,
|
|
17886
|
+
onLike,
|
|
17887
|
+
onDislike,
|
|
17888
|
+
onReply,
|
|
17889
|
+
onLoadReplies,
|
|
17890
|
+
onEdit,
|
|
17891
|
+
onDelete,
|
|
17892
|
+
onReport
|
|
17893
|
+
}
|
|
17894
|
+
) })
|
|
17895
|
+
] }) })
|
|
17872
17896
|
}
|
|
17873
17897
|
);
|
|
17874
17898
|
}
|
|
17875
17899
|
var CommentItem_default = CommentItem;
|
|
17876
17900
|
function CommentList({
|
|
17877
17901
|
comments,
|
|
17902
|
+
replies = {},
|
|
17878
17903
|
depth = 0,
|
|
17879
17904
|
config,
|
|
17880
17905
|
components,
|
|
17881
17906
|
onLike,
|
|
17882
17907
|
onDislike,
|
|
17883
17908
|
onReply,
|
|
17909
|
+
onLoadReplies,
|
|
17884
17910
|
onEdit,
|
|
17885
17911
|
onDelete,
|
|
17886
17912
|
onReport
|
|
@@ -17892,12 +17918,15 @@ function CommentList({
|
|
|
17892
17918
|
CommentItem_default,
|
|
17893
17919
|
{
|
|
17894
17920
|
comment,
|
|
17921
|
+
replies: replies[comment.id] ?? [],
|
|
17922
|
+
allReplies: replies,
|
|
17895
17923
|
depth,
|
|
17896
17924
|
config,
|
|
17897
17925
|
components,
|
|
17898
17926
|
onLike,
|
|
17899
17927
|
onDislike,
|
|
17900
17928
|
onReply,
|
|
17929
|
+
onLoadReplies,
|
|
17901
17930
|
onEdit,
|
|
17902
17931
|
onDelete,
|
|
17903
17932
|
onReport
|
|
@@ -17907,64 +17936,20 @@ function CommentList({
|
|
|
17907
17936
|
}
|
|
17908
17937
|
var CommentList_default = CommentList;
|
|
17909
17938
|
|
|
17910
|
-
// src/compositions/comment-thread/utils/buildCommentTree.ts
|
|
17911
|
-
function buildCommentTree(comments) {
|
|
17912
|
-
const map = /* @__PURE__ */ new Map();
|
|
17913
|
-
const roots = [];
|
|
17914
|
-
comments.forEach((comment) => {
|
|
17915
|
-
map.set(comment.id, {
|
|
17916
|
-
...comment,
|
|
17917
|
-
replies: []
|
|
17918
|
-
});
|
|
17919
|
-
});
|
|
17920
|
-
comments.forEach((comment) => {
|
|
17921
|
-
const current = map.get(comment.id);
|
|
17922
|
-
if (!comment.parentCommentId) {
|
|
17923
|
-
roots.push(current);
|
|
17924
|
-
return;
|
|
17925
|
-
}
|
|
17926
|
-
const parent = map.get(comment.parentCommentId);
|
|
17927
|
-
if (parent) {
|
|
17928
|
-
parent.replies.push(current);
|
|
17929
|
-
}
|
|
17930
|
-
});
|
|
17931
|
-
return roots;
|
|
17932
|
-
}
|
|
17933
|
-
|
|
17934
17939
|
// src/compositions/comment-thread/utils/updateComment.ts
|
|
17935
17940
|
function updateComment(comments, commentId, updater) {
|
|
17936
|
-
return comments.map(
|
|
17937
|
-
|
|
17938
|
-
|
|
17939
|
-
}
|
|
17940
|
-
return {
|
|
17941
|
-
...comment,
|
|
17942
|
-
replies: comment.replies ? updateComment(comment.replies, commentId, updater) : []
|
|
17943
|
-
};
|
|
17944
|
-
});
|
|
17945
|
-
}
|
|
17946
|
-
|
|
17947
|
-
// src/compositions/comment-thread/utils/insertReply.ts
|
|
17948
|
-
function insertReply(comments, parentId, reply) {
|
|
17949
|
-
return comments.map((comment) => {
|
|
17950
|
-
if (comment.id === parentId) {
|
|
17951
|
-
return {
|
|
17952
|
-
...comment,
|
|
17953
|
-
replies: [...comment.replies || [], reply]
|
|
17954
|
-
};
|
|
17955
|
-
}
|
|
17956
|
-
return {
|
|
17957
|
-
...comment,
|
|
17958
|
-
replies: comment.replies ? insertReply(comment.replies, parentId, reply) : []
|
|
17959
|
-
};
|
|
17960
|
-
});
|
|
17941
|
+
return comments.map(
|
|
17942
|
+
(comment) => comment.id === commentId ? updater(comment) : comment
|
|
17943
|
+
);
|
|
17961
17944
|
}
|
|
17962
17945
|
|
|
17963
17946
|
// src/compositions/comment-thread/constants/comment.constants.ts
|
|
17964
17947
|
var DEFAULT_COMMENT_THREAD_CONFIG = {
|
|
17965
17948
|
maxDepth: 5,
|
|
17966
17949
|
indentation: 24,
|
|
17967
|
-
dateFormat: "relative"
|
|
17950
|
+
dateFormat: "relative",
|
|
17951
|
+
commentsPerPage: 20,
|
|
17952
|
+
repliesPerPage: 10
|
|
17968
17953
|
};
|
|
17969
17954
|
function CommentThread({
|
|
17970
17955
|
currentUser,
|
|
@@ -17978,6 +17963,9 @@ function CommentThread({
|
|
|
17978
17963
|
}) {
|
|
17979
17964
|
const [comments, setComments] = useState([]);
|
|
17980
17965
|
const [isLoadingComments, setIsLoadingComments] = useState(true);
|
|
17966
|
+
const [replyCache, setReplyCache] = useState(
|
|
17967
|
+
{}
|
|
17968
|
+
);
|
|
17981
17969
|
const ComposerComponent = components?.Composer ?? CommentComposer_default;
|
|
17982
17970
|
const resolvedConfig = {
|
|
17983
17971
|
...DEFAULT_COMMENT_THREAD_CONFIG,
|
|
@@ -17986,14 +17974,17 @@ function CommentThread({
|
|
|
17986
17974
|
useEffect(() => {
|
|
17987
17975
|
async function loadComments() {
|
|
17988
17976
|
try {
|
|
17989
|
-
const result = await dataSource.getComments(
|
|
17990
|
-
|
|
17977
|
+
const result = await dataSource.getComments({
|
|
17978
|
+
parentCommentId: null,
|
|
17979
|
+
limit: resolvedConfig.commentsPerPage
|
|
17980
|
+
});
|
|
17981
|
+
setComments(result.items);
|
|
17991
17982
|
} finally {
|
|
17992
17983
|
setIsLoadingComments(false);
|
|
17993
17984
|
}
|
|
17994
17985
|
}
|
|
17995
17986
|
loadComments();
|
|
17996
|
-
}, [dataSource]);
|
|
17987
|
+
}, [dataSource, resolvedConfig.commentsPerPage]);
|
|
17997
17988
|
async function handleCreateComment(content) {
|
|
17998
17989
|
const comment = await dataSource.createComment({
|
|
17999
17990
|
content,
|
|
@@ -18006,7 +17997,30 @@ function CommentThread({
|
|
|
18006
17997
|
content,
|
|
18007
17998
|
parentCommentId: parentComment.id
|
|
18008
17999
|
});
|
|
18009
|
-
|
|
18000
|
+
setReplyCache((prev) => ({
|
|
18001
|
+
...prev,
|
|
18002
|
+
[parentComment.id]: [...prev[parentComment.id] ?? [], reply]
|
|
18003
|
+
}));
|
|
18004
|
+
setComments(
|
|
18005
|
+
(prev) => prev.map(
|
|
18006
|
+
(comment) => comment.id === parentComment.id ? {
|
|
18007
|
+
...comment,
|
|
18008
|
+
replyCount: comment.replyCount + 1
|
|
18009
|
+
} : comment
|
|
18010
|
+
)
|
|
18011
|
+
);
|
|
18012
|
+
}
|
|
18013
|
+
async function handleLoadReplies(comment) {
|
|
18014
|
+
if (replyCache[comment.id]) {
|
|
18015
|
+
return;
|
|
18016
|
+
}
|
|
18017
|
+
const result = await dataSource.getReplies(comment.id, {
|
|
18018
|
+
limit: resolvedConfig.repliesPerPage
|
|
18019
|
+
});
|
|
18020
|
+
setReplyCache((prev) => ({
|
|
18021
|
+
...prev,
|
|
18022
|
+
[comment.id]: result.items
|
|
18023
|
+
}));
|
|
18010
18024
|
}
|
|
18011
18025
|
async function handleLike(comment) {
|
|
18012
18026
|
const optimistic = {
|
|
@@ -18069,11 +18083,13 @@ function CommentThread({
|
|
|
18069
18083
|
CommentList_default,
|
|
18070
18084
|
{
|
|
18071
18085
|
comments,
|
|
18072
|
-
|
|
18086
|
+
replies: replyCache,
|
|
18073
18087
|
config: resolvedConfig,
|
|
18088
|
+
components,
|
|
18074
18089
|
onLike: handleLike,
|
|
18075
18090
|
onDislike: handleDislike,
|
|
18076
18091
|
onReply: handleReply,
|
|
18092
|
+
onLoadReplies: handleLoadReplies,
|
|
18077
18093
|
onEdit,
|
|
18078
18094
|
onDelete,
|
|
18079
18095
|
onReport
|