@blocklet/discuss-kit-ux-lite 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -0
- package/dist/axios.d.ts +8 -0
- package/dist/blocklets.d.ts +13 -0
- package/dist/blocklets.mjs +17 -0
- package/dist/components/api-error-handler/api-error-handler.d.ts +13 -0
- package/dist/components/api-error-handler/api-error-handler.mjs +25 -0
- package/dist/components/api-error-handler/default-handler.d.ts +8 -0
- package/dist/components/api-error-handler/default-handler.mjs +69 -0
- package/dist/components/api-error-handler/index.d.ts +2 -0
- package/dist/components/api-error-handler/index.mjs +2 -0
- package/dist/components/api-error-handler/json-validation-interceptor.d.ts +2 -0
- package/dist/components/api-error-handler/json-validation-interceptor.mjs +9 -0
- package/dist/components/arcsphere/index.d.ts +16 -0
- package/dist/components/arcsphere/index.mjs +52 -0
- package/dist/components/authz/access-control.d.ts +24 -0
- package/dist/components/authz/access-control.mjs +15 -0
- package/dist/components/authz/context.d.ts +13 -0
- package/dist/components/authz/context.mjs +30 -0
- package/dist/components/authz/index.d.ts +2 -0
- package/dist/components/authz/index.mjs +2 -0
- package/dist/components/auto-translate/api.d.ts +14 -0
- package/dist/components/auto-translate/api.mjs +23 -0
- package/dist/components/auto-translate/auto-translate-button.d.ts +5 -0
- package/dist/components/auto-translate/auto-translate-button.mjs +48 -0
- package/dist/components/auto-translate/editor-store-adaptor.d.ts +1 -0
- package/dist/components/auto-translate/editor-store-adaptor.mjs +14 -0
- package/dist/components/auto-translate/index.d.ts +6 -0
- package/dist/components/auto-translate/index.mjs +6 -0
- package/dist/components/auto-translate/languages.d.ts +13 -0
- package/dist/components/auto-translate/languages.mjs +61 -0
- package/dist/components/auto-translate/post-auto-translate-plugin.d.ts +14 -0
- package/dist/components/auto-translate/post-auto-translate-plugin.mjs +32 -0
- package/dist/components/auto-translate/store.d.ts +21 -0
- package/dist/components/auto-translate/store.mjs +23 -0
- package/dist/components/auto-translate/translate.d.ts +17 -0
- package/dist/components/auto-translate/translate.mjs +103 -0
- package/dist/components/auto-translate/utils.d.ts +4 -0
- package/dist/components/auto-translate/utils.mjs +14 -0
- package/dist/components/auto-translate/with-availibility-check.d.ts +2 -0
- package/dist/components/auto-translate/with-availibility-check.mjs +10 -0
- package/dist/components/avatars/author-info.d.ts +23 -0
- package/dist/components/avatars/author-info.mjs +178 -0
- package/dist/components/avatars/avatar.d.ts +7 -0
- package/dist/components/avatars/avatar.mjs +9 -0
- package/dist/components/avatars/avatars.d.ts +10 -0
- package/dist/components/avatars/avatars.mjs +49 -0
- package/dist/components/avatars/badge.d.ts +14 -0
- package/dist/components/avatars/badge.mjs +178 -0
- package/dist/components/avatars/index.d.ts +5 -0
- package/dist/components/avatars/index.mjs +5 -0
- package/dist/components/avatars/system-user.d.ts +10 -0
- package/dist/components/avatars/system-user.mjs +58 -0
- package/dist/components/button-group/button-group.d.ts +18 -0
- package/dist/components/button-group/button-group.mjs +195 -0
- package/dist/components/button-group/index.d.ts +1 -0
- package/dist/components/button-group/index.mjs +1 -0
- package/dist/components/confirm.d.ts +29 -0
- package/dist/components/confirm.mjs +103 -0
- package/dist/components/dayjs.d.ts +3 -0
- package/dist/components/dayjs.mjs +5 -0
- package/dist/components/default-editor-config-provider.d.ts +8 -0
- package/dist/components/default-editor-config-provider.mjs +108 -0
- package/dist/components/dirty-prompt.d.ts +8 -0
- package/dist/components/dirty-prompt.mjs +117 -0
- package/dist/components/editor/blocklet-editor.d.ts +1 -0
- package/dist/components/editor/blocklet-editor.mjs +1 -0
- package/dist/components/editor/editor.d.ts +17 -0
- package/dist/components/editor/editor.mjs +35 -0
- package/dist/components/editor/index.d.ts +4 -0
- package/dist/components/editor/index.mjs +3 -0
- package/dist/components/editor/lazy-editor.d.ts +3 -0
- package/dist/components/editor/lazy-editor.mjs +14 -0
- package/dist/components/editor/viewer.d.ts +10 -0
- package/dist/components/editor/viewer.mjs +18 -0
- package/dist/components/emoji-icon.d.ts +11 -0
- package/dist/components/emoji-icon.mjs +62 -0
- package/dist/components/empty-status/empty-status.d.ts +7 -0
- package/dist/components/empty-status/empty-status.mjs +24 -0
- package/dist/components/empty-status/index.d.ts +1 -0
- package/dist/components/empty-status/index.mjs +1 -0
- package/dist/components/hooks/changed.d.ts +10 -0
- package/dist/components/hooks/changed.mjs +34 -0
- package/dist/components/hooks/index.d.ts +6 -0
- package/dist/components/hooks/index.mjs +6 -0
- package/dist/components/hooks/interval.d.ts +6 -0
- package/dist/components/hooks/interval.mjs +16 -0
- package/dist/components/hooks/locale-context.d.ts +10 -0
- package/dist/components/hooks/locale-context.mjs +12 -0
- package/dist/components/hooks/measure.d.ts +5 -0
- package/dist/components/hooks/measure.mjs +8 -0
- package/dist/components/hooks/now.d.ts +1 -0
- package/dist/components/hooks/now.mjs +10 -0
- package/dist/components/hooks/responsive.d.ts +17 -0
- package/dist/components/hooks/responsive.mjs +25 -0
- package/dist/components/hooks/session.d.ts +12 -0
- package/dist/components/hooks/session.mjs +48 -0
- package/dist/components/hooks/use-event-callback.d.ts +1 -0
- package/dist/components/hooks/use-event-callback.mjs +14 -0
- package/dist/components/icon-button.d.ts +6 -0
- package/dist/components/icon-button.mjs +37 -0
- package/dist/components/input/auto-clear-plugin.d.ts +3 -0
- package/dist/components/input/auto-clear-plugin.mjs +20 -0
- package/dist/components/input/comment-input.d.ts +11 -0
- package/dist/components/input/comment-input.mjs +108 -0
- package/dist/components/input/index.d.ts +4 -0
- package/dist/components/input/index.mjs +4 -0
- package/dist/components/input/input.d.ts +29 -0
- package/dist/components/input/input.mjs +149 -0
- package/dist/components/input/post-edit.d.ts +10 -0
- package/dist/components/input/post-edit.mjs +49 -0
- package/dist/components/input/scrollable-editor-wrapper.d.ts +9 -0
- package/dist/components/input/scrollable-editor-wrapper.mjs +18 -0
- package/dist/components/input/shortcut-plugin.d.ts +7 -0
- package/dist/components/input/shortcut-plugin.mjs +28 -0
- package/dist/components/lexical.d.ts +10 -0
- package/dist/components/lexical.mjs +56 -0
- package/dist/components/locale/en.d.ts +117 -0
- package/dist/components/locale/en.mjs +116 -0
- package/dist/components/locale/index.d.ts +236 -0
- package/dist/components/locale/index.mjs +3 -0
- package/dist/components/locale/zh.d.ts +119 -0
- package/dist/components/locale/zh.mjs +118 -0
- package/dist/components/pagination.d.ts +12 -0
- package/dist/components/pagination.mjs +44 -0
- package/dist/components/posts/comment-list/comment-list.d.ts +5 -0
- package/dist/components/posts/comment-list/comment-list.mjs +163 -0
- package/dist/components/posts/comment-list/context.d.ts +76 -0
- package/dist/components/posts/comment-list/context.mjs +318 -0
- package/dist/components/posts/comment.d.ts +16 -0
- package/dist/components/posts/comment.mjs +184 -0
- package/dist/components/posts/index.d.ts +6 -0
- package/dist/components/posts/index.mjs +6 -0
- package/dist/components/posts/menu.d.ts +14 -0
- package/dist/components/posts/menu.mjs +83 -0
- package/dist/components/posts/post-content.d.ts +16 -0
- package/dist/components/posts/post-content.mjs +63 -0
- package/dist/components/posts/post.d.ts +26 -0
- package/dist/components/posts/post.mjs +198 -0
- package/dist/components/profile-card/index.d.ts +1 -0
- package/dist/components/profile-card/index.mjs +1 -0
- package/dist/components/profile-card/profile-card.d.ts +15 -0
- package/dist/components/profile-card/profile-card.mjs +140 -0
- package/dist/components/rating/binary-thumb.d.ts +9 -0
- package/dist/components/rating/binary-thumb.mjs +162 -0
- package/dist/components/rating/github-reaction-container.d.ts +9 -0
- package/dist/components/rating/github-reaction-container.mjs +46 -0
- package/dist/components/rating/github-reaction.d.ts +18 -0
- package/dist/components/rating/github-reaction.mjs +174 -0
- package/dist/components/rating/index.d.ts +3 -0
- package/dist/components/rating/index.mjs +3 -0
- package/dist/components/rating/rater-list.d.ts +10 -0
- package/dist/components/rating/rater-list.mjs +33 -0
- package/dist/components/rating/rating.d.ts +27 -0
- package/dist/components/rating/rating.mjs +50 -0
- package/dist/components/segmented-control.d.ts +14 -0
- package/dist/components/segmented-control.mjs +55 -0
- package/dist/components/shared/relative-time.d.ts +8 -0
- package/dist/components/shared/relative-time.mjs +21 -0
- package/dist/components/toast.d.ts +8 -0
- package/dist/components/toast.mjs +44 -0
- package/dist/components/uploader/index.d.ts +13 -0
- package/dist/components/uploader/index.mjs +70 -0
- package/dist/components/uploader/utils.d.ts +1 -0
- package/dist/components/uploader/utils.mjs +16 -0
- package/dist/components/utils.d.ts +22 -0
- package/dist/components/utils.mjs +103 -0
- package/dist/components/view-more.d.ts +4 -0
- package/dist/components/view-more.mjs +50 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.mjs +14 -0
- package/dist/global.d.ts +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.mjs +29 -0
- package/dist/preferences.d.ts +2 -0
- package/dist/preferences.mjs +9 -0
- package/dist/theme/index.d.ts +8 -0
- package/dist/theme/index.mjs +96 -0
- package/dist/theme/typography.d.ts +2 -0
- package/dist/theme/typography.mjs +66 -0
- package/dist/type-override.d.ts +7 -0
- package/dist/types.d.ts +84 -0
- package/dist/types.mjs +0 -0
- package/dist/vite-env.d.ts +1 -0
- package/dist/ws.d.ts +3 -0
- package/dist/ws.mjs +39 -0
- package/package.json +81 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
3
|
+
import { EditorHolderProvider } from "@blocklet/editor/lib/ext/EditorHolderPlugin";
|
|
4
|
+
import { NavigateNext as NavigateNextIcon } from "@mui/icons-material";
|
|
5
|
+
import { Divider } from "@mui/material";
|
|
6
|
+
import Box from "@mui/material/Box";
|
|
7
|
+
import Button from "@mui/material/Button";
|
|
8
|
+
import { red } from "@mui/material/colors";
|
|
9
|
+
import MuiMenuItem from "@mui/material/MenuItem";
|
|
10
|
+
import { Suspense, useState } from "react";
|
|
11
|
+
import { Icon } from "@iconify/react";
|
|
12
|
+
import PinnedIcon from "@iconify/icons-tabler/pinned";
|
|
13
|
+
import preferences from "../../preferences.mjs";
|
|
14
|
+
import { useConfirm } from "../confirm.mjs";
|
|
15
|
+
import { useSessionContext } from "../hooks/index.mjs";
|
|
16
|
+
import { CommentInput } from "../input/index.mjs";
|
|
17
|
+
import { GithubReaction } from "../rating/index.mjs";
|
|
18
|
+
import { protectLogin } from "../utils.mjs";
|
|
19
|
+
import PostComponent from "./post.mjs";
|
|
20
|
+
import { IconButton, IconButtonGroup } from "../icon-button.mjs";
|
|
21
|
+
export default function Comment({
|
|
22
|
+
onDelete,
|
|
23
|
+
onRate,
|
|
24
|
+
onUnrate,
|
|
25
|
+
onReply,
|
|
26
|
+
onTogglePin,
|
|
27
|
+
onContentUpdate,
|
|
28
|
+
onLoadMoreReplies,
|
|
29
|
+
renderDonation,
|
|
30
|
+
renderActions,
|
|
31
|
+
renderEditorPlugins,
|
|
32
|
+
enableAutoTranslate,
|
|
33
|
+
...rest
|
|
34
|
+
}) {
|
|
35
|
+
const { session } = useSessionContext();
|
|
36
|
+
const { t } = useLocaleContext();
|
|
37
|
+
const [inputVisible, setInputVisible] = useState(false);
|
|
38
|
+
const { confirm } = useConfirm();
|
|
39
|
+
const handleDelete = async (...args) => {
|
|
40
|
+
const proceed = await confirm({
|
|
41
|
+
title: t("deleteComment.title"),
|
|
42
|
+
description: t("deleteComment.desc"),
|
|
43
|
+
okButtonProps: { color: "error" }
|
|
44
|
+
});
|
|
45
|
+
if (proceed) {
|
|
46
|
+
onDelete(...args);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const customMenu = (items, { isAuthor, isAdmin, post }) => {
|
|
50
|
+
if (isAdmin && !post.parentId) {
|
|
51
|
+
items.push(
|
|
52
|
+
/* @__PURE__ */ jsx(MuiMenuItem, { onClick: () => onTogglePin({ post, value: !post.pinnedAt }), children: t(post.pinnedAt ? "unpin" : "pin") }, "pin")
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if ((isAdmin || isAuthor) && !post.deletedAt) {
|
|
56
|
+
items.push(
|
|
57
|
+
/* @__PURE__ */ jsx(MuiMenuItem, { onClick: () => handleDelete(post), children: /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "error.main" }, children: t("delete") }) }, "delete")
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return items;
|
|
61
|
+
};
|
|
62
|
+
const render = ({ post, interactive }) => {
|
|
63
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
64
|
+
post.pinnedAt && /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "end", gap: 3, mt: 1, mb: 1 }, children: /* @__PURE__ */ jsxs(
|
|
65
|
+
Box,
|
|
66
|
+
{
|
|
67
|
+
component: "span",
|
|
68
|
+
sx: {
|
|
69
|
+
display: "inline-flex",
|
|
70
|
+
alignItems: "center",
|
|
71
|
+
gap: 0.25,
|
|
72
|
+
fontSize: 12,
|
|
73
|
+
color: red[700],
|
|
74
|
+
fontWeight: "bold",
|
|
75
|
+
bgcolor: red[50],
|
|
76
|
+
border: `1px solid ${red[100]}`,
|
|
77
|
+
borderRadius: 1,
|
|
78
|
+
px: 1.75,
|
|
79
|
+
py: 0.25
|
|
80
|
+
},
|
|
81
|
+
children: [
|
|
82
|
+
/* @__PURE__ */ jsx(Box, { component: Icon, icon: PinnedIcon, sx: { fontSize: 12 } }),
|
|
83
|
+
t("pinned")
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
) }),
|
|
87
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "end", gap: 1 }, children: [
|
|
88
|
+
/* @__PURE__ */ jsxs(IconButtonGroup, { sx: { alignItems: "flex-end" }, children: [
|
|
89
|
+
/* @__PURE__ */ jsx(
|
|
90
|
+
GithubReaction,
|
|
91
|
+
{
|
|
92
|
+
data: post?.rating || [],
|
|
93
|
+
onRate: ({ value, ratingType }) => onRate(post, value, ratingType),
|
|
94
|
+
onUnrate: () => onUnrate(post),
|
|
95
|
+
interactive
|
|
96
|
+
}
|
|
97
|
+
),
|
|
98
|
+
(!!session?.user || preferences.displayReplyButtonForAnonymousUsers) && interactive && /* @__PURE__ */ jsx(IconButton, { onClick: () => protectLogin(session, () => setInputVisible(!inputVisible)), children: /* @__PURE__ */ jsx(Icon, { icon: "feather:message-circle" }) }),
|
|
99
|
+
renderDonation && renderDonation(post)
|
|
100
|
+
] }),
|
|
101
|
+
renderActions?.(post)
|
|
102
|
+
] }),
|
|
103
|
+
inputVisible && /* @__PURE__ */ jsx(
|
|
104
|
+
Box,
|
|
105
|
+
{
|
|
106
|
+
sx: {
|
|
107
|
+
my: 2
|
|
108
|
+
},
|
|
109
|
+
children: /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(
|
|
110
|
+
CommentInput,
|
|
111
|
+
{
|
|
112
|
+
send: (content) => onReply(post, content),
|
|
113
|
+
onSuccess: () => setInputVisible(false),
|
|
114
|
+
draftKey: `post-${post.id}`
|
|
115
|
+
}
|
|
116
|
+
) })
|
|
117
|
+
}
|
|
118
|
+
),
|
|
119
|
+
/* @__PURE__ */ jsx(Divider, { sx: { mt: 3 } })
|
|
120
|
+
] });
|
|
121
|
+
};
|
|
122
|
+
const renderExtraContent = ({ post }) => {
|
|
123
|
+
if (post.replies?.length) {
|
|
124
|
+
return /* @__PURE__ */ jsxs(Box, { sx: { mt: 1, ml: { xs: 0, md: 5.5 } }, children: [
|
|
125
|
+
post.replies.map((item) => {
|
|
126
|
+
return /* @__PURE__ */ jsx(
|
|
127
|
+
Comment,
|
|
128
|
+
{
|
|
129
|
+
post: item,
|
|
130
|
+
onDelete,
|
|
131
|
+
onContentUpdate,
|
|
132
|
+
onRate,
|
|
133
|
+
onUnrate,
|
|
134
|
+
onReply,
|
|
135
|
+
onTogglePin,
|
|
136
|
+
onLoadMoreReplies,
|
|
137
|
+
allowCopyLink: rest.allowCopyLink,
|
|
138
|
+
showProfileCard: rest.showProfileCard,
|
|
139
|
+
interactive: rest.interactive,
|
|
140
|
+
resolveAuthorInfoAppend: rest.resolveAuthorInfoAppend,
|
|
141
|
+
renderDonation,
|
|
142
|
+
renderActions,
|
|
143
|
+
renderEditorPlugins,
|
|
144
|
+
enableAutoTranslate
|
|
145
|
+
},
|
|
146
|
+
item.id
|
|
147
|
+
);
|
|
148
|
+
}),
|
|
149
|
+
(post.totalReplies || 0) > post.replies.length && /* @__PURE__ */ jsx(
|
|
150
|
+
Button,
|
|
151
|
+
{
|
|
152
|
+
onClick: () => onLoadMoreReplies(post.id),
|
|
153
|
+
variant: "outlined",
|
|
154
|
+
color: "inherit",
|
|
155
|
+
size: "small",
|
|
156
|
+
endIcon: /* @__PURE__ */ jsx(NavigateNextIcon, {}),
|
|
157
|
+
sx: {
|
|
158
|
+
mt: 2,
|
|
159
|
+
ml: 5.5,
|
|
160
|
+
color: "grey.600",
|
|
161
|
+
borderColor: "grey.400",
|
|
162
|
+
fontSize: 12,
|
|
163
|
+
textTransform: "none"
|
|
164
|
+
},
|
|
165
|
+
children: t("showMoreReplies")
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
] });
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
};
|
|
172
|
+
return /* @__PURE__ */ jsx(EditorHolderProvider, { children: /* @__PURE__ */ jsx(
|
|
173
|
+
PostComponent,
|
|
174
|
+
{
|
|
175
|
+
...rest,
|
|
176
|
+
onContentUpdate,
|
|
177
|
+
customMenu,
|
|
178
|
+
render,
|
|
179
|
+
renderExtraContent,
|
|
180
|
+
editorPlugins: renderEditorPlugins?.(rest.post),
|
|
181
|
+
enableAutoTranslate
|
|
182
|
+
}
|
|
183
|
+
) });
|
|
184
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as PostContent } from './post-content';
|
|
2
|
+
export { default as Post } from './post';
|
|
3
|
+
export { default as Comment } from './comment';
|
|
4
|
+
export { default as CommentList } from './comment-list/comment-list';
|
|
5
|
+
export { default as Menu } from './menu';
|
|
6
|
+
export * from './comment-list/context';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as PostContent } from "./post-content.mjs";
|
|
2
|
+
export { default as Post } from "./post.mjs";
|
|
3
|
+
export { default as Comment } from "./comment.mjs";
|
|
4
|
+
export { default as CommentList } from "./comment-list/comment-list.mjs";
|
|
5
|
+
export { default as Menu } from "./menu.mjs";
|
|
6
|
+
export * from "./comment-list/context.mjs";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import MuiMenuItem from '@mui/material/MenuItem';
|
|
3
|
+
import { SxProps } from '@mui/material';
|
|
4
|
+
interface MenuProps {
|
|
5
|
+
items: React.ReactElement<typeof MuiMenuItem>[];
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
className?: string;
|
|
8
|
+
sx?: SxProps;
|
|
9
|
+
}
|
|
10
|
+
declare function Menu({ items, ...rest }: MenuProps): import("react").JSX.Element | null;
|
|
11
|
+
declare namespace Menu {
|
|
12
|
+
var Item: import("@mui/material").ExtendButtonBase<import("@mui/material").MenuItemTypeMap<{}, "li">>;
|
|
13
|
+
}
|
|
14
|
+
export default Menu;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { styled } from "@arcblock/ux/lib/Theme";
|
|
4
|
+
import IconButton from "@mui/material/IconButton";
|
|
5
|
+
import { MoreVert as MoreVertIcon } from "@mui/icons-material";
|
|
6
|
+
import Box from "@mui/material/Box";
|
|
7
|
+
import MuiMenu from "@mui/material/Menu";
|
|
8
|
+
import MuiMenuItem from "@mui/material/MenuItem";
|
|
9
|
+
const StyledMuiMenu = styled(MuiMenu)`
|
|
10
|
+
.MuiMenuItem-root {
|
|
11
|
+
min-height: 32px;
|
|
12
|
+
min-width: 120px;
|
|
13
|
+
font-size: 14px;
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
export default function Menu({ items = [], ...rest }) {
|
|
17
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
18
|
+
const open = Boolean(anchorEl);
|
|
19
|
+
const handleClick = (event) => {
|
|
20
|
+
setAnchorEl(event.currentTarget);
|
|
21
|
+
};
|
|
22
|
+
const handleClose = () => {
|
|
23
|
+
setAnchorEl(null);
|
|
24
|
+
};
|
|
25
|
+
const handleOnClick = (e) => {
|
|
26
|
+
const currentTarget = e.currentTarget;
|
|
27
|
+
let element = e.target;
|
|
28
|
+
while (element && element !== currentTarget) {
|
|
29
|
+
if (element.classList.contains("MuiMenuItem-root")) {
|
|
30
|
+
handleClose();
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
element = element.parentElement;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
if (!items?.length) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return /* @__PURE__ */ jsxs(
|
|
40
|
+
Box,
|
|
41
|
+
{
|
|
42
|
+
...rest,
|
|
43
|
+
onClick: handleOnClick,
|
|
44
|
+
sx: [
|
|
45
|
+
{
|
|
46
|
+
display: "inline-block"
|
|
47
|
+
},
|
|
48
|
+
...Array.isArray(rest.sx) ? rest.sx : [rest.sx]
|
|
49
|
+
],
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ jsx(
|
|
52
|
+
IconButton,
|
|
53
|
+
{
|
|
54
|
+
size: "medium",
|
|
55
|
+
className: "menu-icon",
|
|
56
|
+
onClick: handleClick,
|
|
57
|
+
sx: { p: 1, borderRadius: 1, border: 1, borderColor: "divider", height: 32, width: 32 },
|
|
58
|
+
children: /* @__PURE__ */ jsx(MoreVertIcon, { sx: { fontSize: 18 } })
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
StyledMuiMenu,
|
|
63
|
+
{
|
|
64
|
+
className: "menu-dialog",
|
|
65
|
+
anchorEl,
|
|
66
|
+
anchorOrigin: {
|
|
67
|
+
vertical: "bottom",
|
|
68
|
+
horizontal: "right"
|
|
69
|
+
},
|
|
70
|
+
transformOrigin: {
|
|
71
|
+
vertical: "top",
|
|
72
|
+
horizontal: "right"
|
|
73
|
+
},
|
|
74
|
+
open,
|
|
75
|
+
onClose: handleClose,
|
|
76
|
+
children: items
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
Menu.Item = MuiMenuItem;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { Send } from '../input/input';
|
|
3
|
+
interface Props {
|
|
4
|
+
content: string;
|
|
5
|
+
editing?: boolean;
|
|
6
|
+
onExitEditing?: () => void;
|
|
7
|
+
onSubmit?: Send;
|
|
8
|
+
autoCollapse?: boolean;
|
|
9
|
+
enableHeadingsIdPlugin?: boolean;
|
|
10
|
+
onReady?: () => void;
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
editorPrepend?: React.ReactNode;
|
|
13
|
+
editorFallback?: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export default function PostContent({ content, editing, onExitEditing, onSubmit, autoCollapse, enableHeadingsIdPlugin, onReady, children, editorPrepend, editorFallback, ...rest }: Props): import("react").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense } from "react";
|
|
3
|
+
import Box from "@mui/material/Box";
|
|
4
|
+
import { Skeleton } from "@mui/material";
|
|
5
|
+
import { BlockletEditorViewer } from "@blocklet/editor/lib/blocklet-editor-viewer";
|
|
6
|
+
import { ViewMore } from "../view-more.mjs";
|
|
7
|
+
import PostEdit from "../input/post-edit.mjs";
|
|
8
|
+
const innerHeight = parseInt(String(window.innerHeight / 3), 10);
|
|
9
|
+
export default function PostContent({
|
|
10
|
+
content,
|
|
11
|
+
editing = false,
|
|
12
|
+
onExitEditing,
|
|
13
|
+
onSubmit,
|
|
14
|
+
autoCollapse,
|
|
15
|
+
enableHeadingsIdPlugin,
|
|
16
|
+
onReady,
|
|
17
|
+
children,
|
|
18
|
+
editorPrepend,
|
|
19
|
+
editorFallback,
|
|
20
|
+
...rest
|
|
21
|
+
}) {
|
|
22
|
+
if (editing && onSubmit) {
|
|
23
|
+
return /* @__PURE__ */ jsx(
|
|
24
|
+
Box,
|
|
25
|
+
{
|
|
26
|
+
sx: {
|
|
27
|
+
".be-editable": { maxHeight: 768, overflow: "auto", minHeight: `${Math.max(innerHeight, 200)}px !important` }
|
|
28
|
+
},
|
|
29
|
+
children: /* @__PURE__ */ jsx(PostEdit, { content, onCancel: onExitEditing, send: onSubmit, onSuccess: onExitEditing })
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const fallback = editorFallback || /* @__PURE__ */ jsxs(Box, { sx: { px: 3 }, children: [
|
|
34
|
+
/* @__PURE__ */ jsx(Skeleton, {}),
|
|
35
|
+
/* @__PURE__ */ jsx(Skeleton, { width: "80%" }),
|
|
36
|
+
/* @__PURE__ */ jsx(Skeleton, { width: "60%" }),
|
|
37
|
+
/* @__PURE__ */ jsx(Skeleton, { width: "40%" })
|
|
38
|
+
] });
|
|
39
|
+
if (!autoCollapse) {
|
|
40
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback, children: /* @__PURE__ */ jsx(
|
|
41
|
+
BlockletEditorViewer,
|
|
42
|
+
{
|
|
43
|
+
editorState: content,
|
|
44
|
+
enableHeadingsIdPlugin,
|
|
45
|
+
onReady,
|
|
46
|
+
prepend: editorPrepend,
|
|
47
|
+
onCheckboxChange: onSubmit,
|
|
48
|
+
children
|
|
49
|
+
}
|
|
50
|
+
) });
|
|
51
|
+
}
|
|
52
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback, children: /* @__PURE__ */ jsx(ViewMore, { ...rest, children: /* @__PURE__ */ jsx(
|
|
53
|
+
BlockletEditorViewer,
|
|
54
|
+
{
|
|
55
|
+
editorState: content,
|
|
56
|
+
enableHeadingsIdPlugin,
|
|
57
|
+
onReady,
|
|
58
|
+
prepend: editorPrepend,
|
|
59
|
+
onCheckboxChange: onSubmit,
|
|
60
|
+
children
|
|
61
|
+
}
|
|
62
|
+
) }) });
|
|
63
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import MuiMenuItem from '@mui/material/MenuItem';
|
|
3
|
+
import type { Post } from '../../types';
|
|
4
|
+
export interface PostProps {
|
|
5
|
+
post: Post;
|
|
6
|
+
interactive?: boolean;
|
|
7
|
+
render?: (ctx: PostContext) => React.ReactNode;
|
|
8
|
+
renderExtraContent?: (ctx: PostContext) => React.ReactNode;
|
|
9
|
+
customMenu?: (menuItems: React.ReactElement<typeof MuiMenuItem>[], ctx: PostContext) => React.ReactElement<typeof MuiMenuItem>[];
|
|
10
|
+
onContentUpdate: (post: Post, content: string) => Promise<any>;
|
|
11
|
+
allowCopyLink?: boolean;
|
|
12
|
+
autoCollapse?: boolean;
|
|
13
|
+
showProfileCard?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
resolveAuthorInfoAppend?: (post: Post) => React.ReactNode;
|
|
16
|
+
editorPlugins?: React.ReactNode;
|
|
17
|
+
enableAutoTranslate?: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface PostContext {
|
|
20
|
+
isAdmin: boolean;
|
|
21
|
+
isAuthor: boolean;
|
|
22
|
+
interactive: boolean;
|
|
23
|
+
post: Post;
|
|
24
|
+
}
|
|
25
|
+
export default function PostComponent({ post, render, renderExtraContent, customMenu, interactive, onContentUpdate, allowCopyLink, autoCollapse, showProfileCard, resolveAuthorInfoAppend, editorPlugins, enableAutoTranslate, ...rest }: PostProps): JSX.Element;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import Box from "@mui/material/Box";
|
|
4
|
+
import { styled } from "@mui/material/styles";
|
|
5
|
+
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
6
|
+
import MuiMenuItem from "@mui/material/MenuItem";
|
|
7
|
+
import clsx from "clsx";
|
|
8
|
+
import { useInViewport } from "ahooks";
|
|
9
|
+
import { Icon } from "@iconify/react";
|
|
10
|
+
import ArrowForwardUpIcon from "@iconify/icons-tabler/arrow-forward-up";
|
|
11
|
+
import { Stack } from "@mui/material";
|
|
12
|
+
import RelativeTime from "../shared/relative-time.mjs";
|
|
13
|
+
import { AuthorInfo } from "../avatars/index.mjs";
|
|
14
|
+
import PostContent from "./post-content.mjs";
|
|
15
|
+
import { useSessionContext } from "../hooks/index.mjs";
|
|
16
|
+
import { copy } from "../utils.mjs";
|
|
17
|
+
import Menu from "./menu.mjs";
|
|
18
|
+
import { ProfileCardTooltip } from "../profile-card/profile-card.mjs";
|
|
19
|
+
import { PostAutoTranslatePlugin } from "../auto-translate/post-auto-translate-plugin.mjs";
|
|
20
|
+
const Root = styled(Box)`
|
|
21
|
+
.post-highlighted {
|
|
22
|
+
animation: highlighted-post-fade 3s;
|
|
23
|
+
animation-timing-function: ease-out;
|
|
24
|
+
}
|
|
25
|
+
@-webkit-keyframes highlighted-post-fade {
|
|
26
|
+
0% {
|
|
27
|
+
background-color: #fcf4d9;
|
|
28
|
+
}
|
|
29
|
+
100% {
|
|
30
|
+
background-color: rgba(255, 255, 153, 0);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
@-moz-keyframes highlighted-post-fade {
|
|
34
|
+
0% {
|
|
35
|
+
background-color: #fcf4d9;
|
|
36
|
+
}
|
|
37
|
+
100% {
|
|
38
|
+
background-color: rgba(255, 255, 153, 0);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
export default function PostComponent({
|
|
43
|
+
post,
|
|
44
|
+
render,
|
|
45
|
+
renderExtraContent,
|
|
46
|
+
customMenu,
|
|
47
|
+
interactive = true,
|
|
48
|
+
onContentUpdate,
|
|
49
|
+
allowCopyLink = false,
|
|
50
|
+
autoCollapse,
|
|
51
|
+
showProfileCard,
|
|
52
|
+
resolveAuthorInfoAppend = () => void 0,
|
|
53
|
+
editorPlugins,
|
|
54
|
+
enableAutoTranslate,
|
|
55
|
+
...rest
|
|
56
|
+
}) {
|
|
57
|
+
const { session, isAdmin } = useSessionContext();
|
|
58
|
+
const isAuthor = post.author.did === session?.user?.did;
|
|
59
|
+
const commentUrl = window.location.hash.substring(1);
|
|
60
|
+
const { t } = useLocaleContext();
|
|
61
|
+
const [editing, setEditing] = useState(false);
|
|
62
|
+
const postContext = { isAdmin, isAuthor, interactive, post };
|
|
63
|
+
const [inViewport] = useInViewport(() => document?.getElementById(post.id));
|
|
64
|
+
const [hasEnteredViewport, setHasEnteredViewport] = useState(false);
|
|
65
|
+
let menuItems = [];
|
|
66
|
+
if (isAuthor && !post.deletedAt) {
|
|
67
|
+
menuItems.push(
|
|
68
|
+
/* @__PURE__ */ jsx(MuiMenuItem, { onClick: () => setEditing(true), children: t("edit") }, "edit")
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
if (allowCopyLink) {
|
|
72
|
+
menuItems.push(
|
|
73
|
+
/* @__PURE__ */ jsx(
|
|
74
|
+
MuiMenuItem,
|
|
75
|
+
{
|
|
76
|
+
onClick: () => copy(
|
|
77
|
+
window.location.hash ? window.location.href.replace(window.location.hash, `#${post.id}`) : `${window.location.href}#${post.id}`
|
|
78
|
+
),
|
|
79
|
+
children: t("copyLink")
|
|
80
|
+
},
|
|
81
|
+
"copyLink"
|
|
82
|
+
)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
const isTargetPost = commentUrl === post.id;
|
|
86
|
+
menuItems = customMenu ? customMenu(menuItems, postContext) : menuItems;
|
|
87
|
+
const renderTime = () => {
|
|
88
|
+
if (allowCopyLink) {
|
|
89
|
+
return /* @__PURE__ */ jsx(Box, { component: "a", href: `#${post.id}`, sx: { color: "text.secondary", textDecoration: "none" }, children: /* @__PURE__ */ jsx(RelativeTime, { value: post.createdAt }) });
|
|
90
|
+
}
|
|
91
|
+
return /* @__PURE__ */ jsx(RelativeTime, { value: post.createdAt });
|
|
92
|
+
};
|
|
93
|
+
let systemTip = "";
|
|
94
|
+
if (post.deletedAt) {
|
|
95
|
+
systemTip = t("deleted");
|
|
96
|
+
} else if (!post.content) {
|
|
97
|
+
systemTip = t("emptyContent");
|
|
98
|
+
}
|
|
99
|
+
const showSystemTip = systemTip && !editing;
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (inViewport) {
|
|
102
|
+
setHasEnteredViewport(inViewport);
|
|
103
|
+
}
|
|
104
|
+
}, [inViewport]);
|
|
105
|
+
return /* @__PURE__ */ jsxs(Root, { sx: { position: "relative", mt: 2, py: 1 }, ...rest, children: [
|
|
106
|
+
/* @__PURE__ */ jsxs(
|
|
107
|
+
Box,
|
|
108
|
+
{
|
|
109
|
+
id: post.id,
|
|
110
|
+
className: clsx({ "post-highlighted": isTargetPost && hasEnteredViewport }),
|
|
111
|
+
sx: {
|
|
112
|
+
flex: "1"
|
|
113
|
+
},
|
|
114
|
+
children: [
|
|
115
|
+
/* @__PURE__ */ jsxs(
|
|
116
|
+
Box,
|
|
117
|
+
{
|
|
118
|
+
sx: {
|
|
119
|
+
display: "flex",
|
|
120
|
+
justifyContent: "space-between",
|
|
121
|
+
alignItems: "start"
|
|
122
|
+
},
|
|
123
|
+
children: [
|
|
124
|
+
/* @__PURE__ */ jsx(
|
|
125
|
+
AuthorInfo,
|
|
126
|
+
{
|
|
127
|
+
size: "sm",
|
|
128
|
+
fontSize: 14,
|
|
129
|
+
avatarSize: 32,
|
|
130
|
+
user: post.author,
|
|
131
|
+
createdAt: renderTime(),
|
|
132
|
+
showProfileCard,
|
|
133
|
+
append: resolveAuthorInfoAppend(post),
|
|
134
|
+
showDID: false
|
|
135
|
+
}
|
|
136
|
+
),
|
|
137
|
+
/* @__PURE__ */ jsx(Menu, { items: menuItems, style: { position: "absolute", right: 0, top: 0 } })
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
),
|
|
141
|
+
/* @__PURE__ */ jsxs(Box, { sx: { ml: { xs: 0, md: 5.5 } }, children: [
|
|
142
|
+
post.replyTo && /* @__PURE__ */ jsx(Box, { sx: { pt: 1 }, children: /* @__PURE__ */ jsx(ProfileCardTooltip, { user: post.replyTo, children: /* @__PURE__ */ jsxs(
|
|
143
|
+
Stack,
|
|
144
|
+
{
|
|
145
|
+
direction: "row",
|
|
146
|
+
sx: {
|
|
147
|
+
alignItems: "center",
|
|
148
|
+
gap: 0.5,
|
|
149
|
+
display: "inline-flex",
|
|
150
|
+
color: "text.secondary",
|
|
151
|
+
cursor: "pointer",
|
|
152
|
+
".did-address-text": { color: "primary.light" }
|
|
153
|
+
},
|
|
154
|
+
children: [
|
|
155
|
+
/* @__PURE__ */ jsx(Box, { component: Icon, icon: ArrowForwardUpIcon }),
|
|
156
|
+
/* @__PURE__ */ jsx("span", { children: "Reply to" }),
|
|
157
|
+
/* @__PURE__ */ jsx(Box, { component: "span", children: post.replyTo.fullName })
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
) }) }),
|
|
161
|
+
showSystemTip && /* @__PURE__ */ jsx(
|
|
162
|
+
Box,
|
|
163
|
+
{
|
|
164
|
+
sx: {
|
|
165
|
+
display: "inline-block",
|
|
166
|
+
px: 2.5,
|
|
167
|
+
py: 1,
|
|
168
|
+
my: 1,
|
|
169
|
+
fontSize: 14,
|
|
170
|
+
bgcolor: "grey.100",
|
|
171
|
+
color: "grey.600",
|
|
172
|
+
borderRadius: 1
|
|
173
|
+
},
|
|
174
|
+
children: systemTip
|
|
175
|
+
}
|
|
176
|
+
),
|
|
177
|
+
!showSystemTip && !post.deletedAt && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
|
|
178
|
+
PostContent,
|
|
179
|
+
{
|
|
180
|
+
content: post.content,
|
|
181
|
+
editing,
|
|
182
|
+
onExitEditing: () => setEditing(false),
|
|
183
|
+
onSubmit: (content) => onContentUpdate(post, content),
|
|
184
|
+
autoCollapse,
|
|
185
|
+
editorPrepend: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
186
|
+
editorPlugins,
|
|
187
|
+
enableAutoTranslate && /* @__PURE__ */ jsx(PostAutoTranslatePlugin, { postId: post.id, updatedAt: post.updatedAt || "" })
|
|
188
|
+
] })
|
|
189
|
+
}
|
|
190
|
+
) }),
|
|
191
|
+
render && /* @__PURE__ */ jsx(Box, { sx: { mt: 1 }, children: render(postContext) })
|
|
192
|
+
] })
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
),
|
|
196
|
+
renderExtraContent && renderExtraContent(postContext)
|
|
197
|
+
] });
|
|
198
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './profile-card';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./profile-card.mjs";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { User } from '../../types';
|
|
3
|
+
interface ProfileCardProps {
|
|
4
|
+
user: User;
|
|
5
|
+
click: () => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function ProfileCard({ user, click, ...rest }: ProfileCardProps): import("react").JSX.Element;
|
|
8
|
+
interface ProfileCardTooltipProps {
|
|
9
|
+
user: User;
|
|
10
|
+
children: React.ReactElement<any> | ((props: {
|
|
11
|
+
navigateToProfile: () => void;
|
|
12
|
+
}) => React.ReactElement<any>);
|
|
13
|
+
}
|
|
14
|
+
export declare function ProfileCardTooltip({ user, children }: ProfileCardTooltipProps): import("react").JSX.Element;
|
|
15
|
+
export {};
|