@blocklet/discuss-kit 1.0.7 → 1.0.8

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.
@@ -1,112 +0,0 @@
1
- import { useContext, useState } from "react";
2
- import styled from "@emotion/styled";
3
- import Button from "@arcblock/ux/lib/Button";
4
- import CircularProgress from "@mui/material/CircularProgress";
5
- import { LocaleContext } from "@arcblock/ux/lib/Locale/context";
6
- import { Confirm } from "@arcblock/ux/lib/Dialog";
7
- import Comment from "./components/comment";
8
- import { useCommentsContext } from "./context";
9
- import api from "./api";
10
- import { jsx, jsxs } from "react/jsx-runtime";
11
- function CommentList() {
12
- const {
13
- comments,
14
- loadMore,
15
- hasMore,
16
- loading,
17
- removeComment
18
- } = useCommentsContext();
19
- const {
20
- t
21
- } = useContext(LocaleContext);
22
- const [waitDelRow, setWaitDelRow] = useState({});
23
- const handleConfirmDelete = async (comment) => {
24
- try {
25
- setWaitDelRow({});
26
- await api.delete(`/comments/${comment.id}`);
27
- removeComment(comment);
28
- } catch (e) {
29
- console.error(e);
30
- }
31
- };
32
- if (loading) {
33
- return /* @__PURE__ */ jsx(Center, {
34
- style: {
35
- width: "100%"
36
- },
37
- children: /* @__PURE__ */ jsx(CircularProgress, {})
38
- });
39
- }
40
- return /* @__PURE__ */ jsxs(Container, {
41
- children: [comments.length === 0 && /* @__PURE__ */ jsx("div", {
42
- className: "empty",
43
- children: t("empty")
44
- }), comments.length > 0 && comments.map((comment, index) => {
45
- return /* @__PURE__ */ jsx(Comment, {
46
- comment,
47
- index: index + 1,
48
- onDelete: setWaitDelRow
49
- }, comment.id);
50
- }), hasMore && /* @__PURE__ */ jsx("div", {
51
- className: "load-more",
52
- children: /* @__PURE__ */ jsx(Button, {
53
- onClick: loadMore,
54
- disabled: loading,
55
- variant: "outlined",
56
- color: "primary",
57
- size: "small",
58
- children: t("loadMore")
59
- })
60
- }), /* @__PURE__ */ jsx(Confirm, {
61
- open: !!waitDelRow.id,
62
- title: t("tip"),
63
- onConfirm: () => {
64
- handleConfirmDelete(waitDelRow);
65
- },
66
- confirmButton: {
67
- text: t("confirm"),
68
- props: {
69
- variant: "contained",
70
- color: "error"
71
- }
72
- },
73
- cancelButton: {
74
- text: t("cancel"),
75
- props: {
76
- color: "inherit"
77
- }
78
- },
79
- onCancel: () => {
80
- setWaitDelRow({});
81
- },
82
- children: /* @__PURE__ */ jsx("span", {
83
- children: t("deleteCommentDesc")
84
- })
85
- })]
86
- });
87
- }
88
- CommentList.propTypes = {};
89
- CommentList.defaultProps = {};
90
- const Center = styled.div`
91
- width: 100%;
92
- padding: 120px 0 0 0;
93
- display: flex;
94
- align-items: center;
95
- justify-content: center;
96
- `;
97
- const Container = styled.div`
98
- width: 100%;
99
- .empty {
100
- text-align: center;
101
- color: #9397a1;
102
- font-size: 16px;
103
- margin-top: 44px;
104
- }
105
- .load-more {
106
- text-align: center;
107
- margin: 24px 0;
108
- }
109
- `;
110
- export {
111
- CommentList as default
112
- };
@@ -1,309 +0,0 @@
1
- import * as React from "react";
2
- import { useContext, useState } from "react";
3
- import styled from "@emotion/styled";
4
- import Box from "@mui/material/Box";
5
- import Button from "@mui/material/Button";
6
- import PropTypes from "prop-types";
7
- import NavigateNextIcon from "@mui/icons-material/NavigateNext";
8
- import DIDAddress from "@arcblock/did-connect/lib/Address";
9
- import { format } from "timeago.js";
10
- import { LocaleContext } from "@arcblock/ux/lib/Locale/context";
11
- import { Avatar, PostContent, CommentInput } from "@blocklet/discuss-kit-ux";
12
- import { BinaryThumb } from "./rating";
13
- import Menu from "./menu";
14
- import api, { reply } from "../api";
15
- import { protectLogin, minDelay } from "../lib/utils";
16
- import { useCommentsContext } from "../context";
17
- import { jsx, jsxs, Fragment } from "react/jsx-runtime";
18
- const SvgMessage = (props) => /* @__PURE__ */ React.createElement("svg", {
19
- width: 32,
20
- height: 32,
21
- viewBox: "0 0 24 24",
22
- ...props
23
- }, /* @__PURE__ */ React.createElement("path", {
24
- fill: "none",
25
- stroke: "#888888",
26
- strokeLinecap: "round",
27
- strokeLinejoin: "round",
28
- strokeWidth: 2,
29
- d: "m3 20l1.3-3.9A9 8 0 1 1 7.7 19L3 20"
30
- }));
31
- function CommentReplies({
32
- comment,
33
- onDelete,
34
- ...rest
35
- }) {
36
- const {
37
- t
38
- } = useContext(LocaleContext);
39
- const {
40
- loadMoreReplies
41
- } = useCommentsContext();
42
- const {
43
- replies,
44
- totalReplies
45
- } = comment;
46
- if (!(replies == null ? void 0 : replies.length)) {
47
- return null;
48
- }
49
- return /* @__PURE__ */ jsxs(Box, {
50
- mt: 1,
51
- ...rest,
52
- children: [replies.map((item) => {
53
- return /* @__PURE__ */ jsx("div", {
54
- children: /* @__PURE__ */ jsx(Comment, {
55
- comment: item,
56
- onDelete,
57
- rootComment: comment
58
- })
59
- }, item.id);
60
- }), totalReplies > replies.length && /* @__PURE__ */ jsx(Button, {
61
- onClick: () => loadMoreReplies(comment.id),
62
- variant: "outlined",
63
- color: "inherit",
64
- size: "small",
65
- endIcon: /* @__PURE__ */ jsx(NavigateNextIcon, {}),
66
- sx: {
67
- mt: 2,
68
- ml: 6,
69
- color: "grey.600",
70
- borderColor: "grey.400",
71
- fontSize: 12,
72
- textTransform: "none"
73
- },
74
- children: t("showMoreReplies")
75
- })]
76
- });
77
- }
78
- CommentReplies.propTypes = {
79
- comment: PropTypes.object.isRequired,
80
- onDelete: PropTypes.func.isRequired
81
- };
82
- function Comment({
83
- comment,
84
- onDelete,
85
- rootComment,
86
- ...rest
87
- }) {
88
- var _a, _b, _c, _d;
89
- const {
90
- session,
91
- addComment,
92
- updateComment,
93
- manageMode,
94
- flatMode
95
- } = useCommentsContext();
96
- const {
97
- t,
98
- locale
99
- } = useContext(LocaleContext);
100
- const [inputBoxVisible, setInputBoxVisible] = useState(false);
101
- const [editMode, setEditMode] = useState(false);
102
- const isCommenter = ((_a = session == null ? void 0 : session.user) == null ? void 0 : _a.did) === comment.commenter.did;
103
- const canEditOrDelete = !comment.deletedAt && (isCommenter || manageMode);
104
- const menuItems = [...canEditOrDelete ? [{
105
- text: /* @__PURE__ */ jsx(Box, {
106
- component: "span",
107
- sx: {
108
- color: "error.main"
109
- },
110
- children: t("delete")
111
- }),
112
- onClick: () => onDelete(comment)
113
- }, {
114
- text: /* @__PURE__ */ jsx(Box, {
115
- component: "span",
116
- children: t("edit")
117
- }),
118
- onClick: () => setEditMode(true)
119
- }] : []];
120
- const sendReply = async (content) => {
121
- const commentId = (rootComment == null ? void 0 : rootComment.id) || comment.commentId || comment.id;
122
- const data = await minDelay(reply({
123
- commentId,
124
- parentId: comment.id,
125
- content
126
- }), 800);
127
- setInputBoxVisible(false);
128
- addComment(data);
129
- };
130
- const handleOnRate = async ({
131
- ratingType,
132
- value
133
- }) => {
134
- if (!session.user) {
135
- session.login();
136
- throw new Error("Unauthenticated.");
137
- }
138
- await api.post(`/objects/${comment.objectId}/comments/${comment.id}/ratings`, {
139
- ratingType,
140
- value
141
- });
142
- };
143
- const handleOnUnrate = async () => {
144
- if (!session.user) {
145
- session.login();
146
- throw new Error("Unauthenticated.");
147
- }
148
- await api.delete(`/objects/${comment.objectId}/comments/${comment.id}/ratings`);
149
- };
150
- const handleUpdateComment = async (content) => {
151
- await api.put(`/comments/${comment.id}`, {
152
- content
153
- });
154
- updateComment(comment.id, (current) => ({
155
- ...current,
156
- content
157
- }));
158
- };
159
- return /* @__PURE__ */ jsxs(Root, {
160
- ...rest,
161
- children: [/* @__PURE__ */ jsx(Avatar, {
162
- did: comment.commenter.did,
163
- src: comment.commenter.avatar,
164
- size: 36,
165
- shape: "circle",
166
- variant: "circle"
167
- }), /* @__PURE__ */ jsxs(Box, {
168
- flex: "1",
169
- pl: 2,
170
- overflow: "hidden",
171
- children: [/* @__PURE__ */ jsxs(Box, {
172
- display: "flex",
173
- justifyContent: "space-between",
174
- alignItems: "start",
175
- children: [/* @__PURE__ */ jsxs(Box, {
176
- children: [/* @__PURE__ */ jsxs(Box, {
177
- display: "flex",
178
- alignItems: "center",
179
- gap: 1,
180
- flexWrap: "wrap",
181
- color: "#333",
182
- lineHeight: 1,
183
- children: [/* @__PURE__ */ jsx("span", {
184
- children: comment.commenter.fullName || "Unknown"
185
- }), /* @__PURE__ */ jsxs("div", {
186
- children: ["(", /* @__PURE__ */ jsx(DIDAddress, {
187
- copyable: false,
188
- responsive: false,
189
- compact: true,
190
- inline: true,
191
- children: comment.commenter.did
192
- }), ")"]
193
- }), /* @__PURE__ */ jsx(Box, {
194
- width: {
195
- xs: "100%",
196
- md: "auto"
197
- },
198
- fontSize: 13,
199
- color: "grey.500",
200
- children: /* @__PURE__ */ jsx("span", {
201
- children: format(comment.createdAt, locale === "zh" ? "zh_CN" : "en_US")
202
- })
203
- })]
204
- }), ((_b = comment.replyTo) == null ? void 0 : _b.did) && (flatMode || comment.parentId !== comment.commentId) && /* @__PURE__ */ jsxs(Box, {
205
- mt: 0.5,
206
- fontSize: 13,
207
- lineHeight: 1,
208
- color: "primary.light",
209
- sx: {
210
- ".did-address-text": {
211
- color: "primary.light"
212
- }
213
- },
214
- children: ["@", /* @__PURE__ */ jsx(Box, {
215
- component: "span",
216
- mr: 1,
217
- children: comment.replyTo.fullName
218
- }), "(", /* @__PURE__ */ jsx(DIDAddress, {
219
- copyable: false,
220
- responsive: false,
221
- compact: true,
222
- inline: true,
223
- children: comment.replyTo.did
224
- }), ")"]
225
- })]
226
- }), !!(menuItems == null ? void 0 : menuItems.length) && /* @__PURE__ */ jsx(Menu, {
227
- items: menuItems,
228
- style: {
229
- position: "absolute",
230
- right: 0,
231
- top: 16
232
- }
233
- })]
234
- }), /* @__PURE__ */ jsxs(Box, {
235
- mt: 1,
236
- children: [!comment.deletedAt && /* @__PURE__ */ jsx(PostContent, {
237
- content: comment.content,
238
- editing: editMode,
239
- onExitEditing: () => setEditMode(false),
240
- onSubmit: handleUpdateComment
241
- }), comment.deletedAt && /* @__PURE__ */ jsx(Box, {
242
- display: "inline-block",
243
- px: 2,
244
- py: 1,
245
- mt: 1,
246
- fontSize: 14,
247
- bgcolor: "grey.100",
248
- color: "grey.600",
249
- borderRadius: 1,
250
- children: t("deleted")
251
- })]
252
- }), !manageMode && /* @__PURE__ */ jsxs(Fragment, {
253
- children: [/* @__PURE__ */ jsxs(Box, {
254
- display: "flex",
255
- alignItems: "center",
256
- mt: 1.5,
257
- children: [/* @__PURE__ */ jsx(BinaryThumb, {
258
- selected: (_c = comment.rating) == null ? void 0 : _c.myRating,
259
- countPerValue: (_d = comment.rating) == null ? void 0 : _d.counts,
260
- onRate: handleOnRate,
261
- onUnrate: handleOnUnrate
262
- }), /* @__PURE__ */ jsx(Box, {
263
- onClick: () => protectLogin(session, () => setInputBoxVisible(!inputBoxVisible)),
264
- sx: {
265
- lineHeight: 1,
266
- "&:hover": {
267
- cursor: "pointer"
268
- }
269
- },
270
- children: /* @__PURE__ */ jsx(SvgMessage, {
271
- style: {
272
- width: "auto",
273
- height: 16
274
- }
275
- })
276
- })]
277
- }), inputBoxVisible && /* @__PURE__ */ jsx(Box, {
278
- my: 2,
279
- children: /* @__PURE__ */ jsx(CommentInput, {
280
- send: sendReply
281
- })
282
- })]
283
- }), !comment.parentId && /* @__PURE__ */ jsx(CommentReplies, {
284
- comment,
285
- onDelete
286
- })]
287
- })]
288
- });
289
- }
290
- Comment.propTypes = {
291
- comment: PropTypes.object.isRequired,
292
- onDelete: PropTypes.func,
293
- rootComment: PropTypes.object
294
- };
295
- Comment.defaultProps = {
296
- onDelete: void 0,
297
- rootComment: void 0
298
- };
299
- const Root = styled(Box)`
300
- display: flex;
301
- position: relative;
302
- padding: 24px 0 0 0;
303
- &:first-of-type {
304
- flex-shrink: 0;
305
- }
306
- `;
307
- export {
308
- Comment as default
309
- };
@@ -1,176 +0,0 @@
1
- import PropTypes from "prop-types";
2
- import { styled } from "@arcblock/ux/lib/Theme";
3
- import Box from "@mui/material/Box";
4
- import clsx from "clsx";
5
- import * as React from "react";
6
- import Rating from "./rating";
7
- import { jsx, jsxs } from "react/jsx-runtime";
8
- const SvgThumbUp = (props) => /* @__PURE__ */ React.createElement("svg", {
9
- width: 32,
10
- height: 32,
11
- viewBox: "0 0 24 24",
12
- ...props
13
- }, /* @__PURE__ */ React.createElement("g", {
14
- fill: "none",
15
- stroke: "currentColor",
16
- strokeLinecap: "round",
17
- strokeWidth: 1.5
18
- }, /* @__PURE__ */ React.createElement("path", {
19
- d: "M16.472 20H4.1a.6.6 0 0 1-.6-.6V9.6a.6.6 0 0 1 .6-.6h2.768a2 2 0 0 0 1.715-.971l2.71-4.517a1.631 1.631 0 0 1 2.961 1.308l-1.022 3.408a.6.6 0 0 0 .574.772h4.575a2 2 0 0 1 1.93 2.526l-1.91 7A2 2 0 0 1 16.473 20Z"
20
- }), /* @__PURE__ */ React.createElement("path", {
21
- strokeLinejoin: "round",
22
- d: "M7 20V9"
23
- })));
24
- function BinaryThumb({
25
- variant,
26
- size,
27
- ...rest
28
- }) {
29
- const renderer = ({
30
- options,
31
- toggleRate
32
- }) => {
33
- return /* @__PURE__ */ jsx(Root, {
34
- children: options.map((option) => {
35
- const icon = option.value === -1 ? /* @__PURE__ */ jsx(SvgThumbUp, {
36
- style: {
37
- transform: "rotate(180deg)"
38
- }
39
- }) : /* @__PURE__ */ jsx(SvgThumbUp, {});
40
- return /* @__PURE__ */ jsx("div", {
41
- className: "reaction-item",
42
- children: /* @__PURE__ */ jsx(IconButton, {
43
- className: "reaction-item-btn",
44
- icon,
45
- text: option.count,
46
- selected: option.selected,
47
- onClick: () => toggleRate(option.value),
48
- variant,
49
- size
50
- })
51
- }, option.value);
52
- })
53
- });
54
- };
55
- return /* @__PURE__ */ jsx(Rating, {
56
- ratingType: "binary-thumb",
57
- values: [1, -1],
58
- ...rest,
59
- render: renderer
60
- });
61
- }
62
- BinaryThumb.propTypes = {
63
- variant: PropTypes.oneOf(["default", "inverse"]),
64
- size: PropTypes.oneOf(["sm", "lg"])
65
- };
66
- BinaryThumb.defaultProps = {
67
- variant: "default",
68
- size: "sm"
69
- };
70
- const Root = styled(Box)`
71
- display: flex;
72
- .reaction-item {
73
- display: flex;
74
- align-items: center;
75
- }
76
- `;
77
- function IconButton({
78
- icon,
79
- text,
80
- onClick,
81
- selected,
82
- variant,
83
- size,
84
- ...rest
85
- }) {
86
- const classes = clsx(rest.className, `reaction-btn-${size} reaction-btn-${variant}`, {
87
- "reaction-btn-selected": selected
88
- });
89
- return /* @__PURE__ */ jsxs(IconButtonRoot, {
90
- ...rest,
91
- className: classes,
92
- children: [/* @__PURE__ */ jsx("span", {
93
- className: "reaction-btn-icon",
94
- onClick,
95
- children: icon
96
- }), !!text && /* @__PURE__ */ jsx("span", {
97
- className: "reaction-btn-text",
98
- children: text
99
- })]
100
- });
101
- }
102
- IconButton.propTypes = {
103
- icon: PropTypes.node.isRequired,
104
- text: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
105
- onClick: PropTypes.func.isRequired,
106
- selected: PropTypes.bool,
107
- variant: PropTypes.oneOf(["default", "inverse"]),
108
- size: PropTypes.oneOf(["sm", "lg"])
109
- };
110
- IconButton.defaultProps = {
111
- selected: false,
112
- variant: "default",
113
- size: "sm"
114
- };
115
- const IconButtonRoot = styled("div")`
116
- display: flex;
117
- align-items: center;
118
- &.reaction-btn-selected {
119
- color: ${(props) => props.theme.palette.primary.main};
120
- }
121
- .reaction-btn-icon {
122
- display: flex;
123
- line-height: 1;
124
- &:hover {
125
- cursor: pointer;
126
- }
127
- }
128
- svg {
129
- width: auto;
130
- }
131
- .reaction-btn-text {
132
- display: inline-block;
133
- }
134
- &.reaction-btn-sm {
135
- min-width: 64px;
136
- height: 18px;
137
- font-size: 12px;
138
- svg {
139
- height: 16px;
140
- }
141
- .reaction-btn-text {
142
- margin-left: 8px;
143
- }
144
- }
145
- &.reaction-btn-lg {
146
- min-width: 100px;
147
- font-size: 14px;
148
- .reaction-btn-icon {
149
- justify-content: center;
150
- align-items: center;
151
- width: 44px;
152
- height: 44px;
153
- border-radius: 8px;
154
- }
155
- svg {
156
- height: 20px;
157
- }
158
- .reaction-btn-text {
159
- margin-left: 12px;
160
- }
161
- }
162
- &.reaction-btn-inverse {
163
- .reaction-btn-icon {
164
- background-color: ${(props) => props.theme.palette.grey[200]};
165
- }
166
- &.reaction-btn-selected {
167
- .reaction-btn-icon {
168
- color: #fff;
169
- background-color: ${(props) => props.theme.palette.primary.main};
170
- }
171
- }
172
- }
173
- `;
174
- export {
175
- BinaryThumb as default
176
- };
@@ -1,37 +0,0 @@
1
- import PropTypes from "prop-types";
2
- import Rating from "./rating";
3
- import { jsx } from "react/jsx-runtime";
4
- function EmojiBased({
5
- emojiValues
6
- }) {
7
- return /* @__PURE__ */ jsx(Rating, {
8
- ratingType: "emoji-based",
9
- children: /* @__PURE__ */ jsx("span", {
10
- children: emojiValues
11
- })
12
- });
13
- }
14
- EmojiBased.propTypes = {
15
- emojiValues: PropTypes.array
16
- };
17
- EmojiBased.defaultProps = {
18
- emojiValues: [{
19
- value: 5,
20
- emojicon: "\u{1F601}"
21
- }, {
22
- value: 4,
23
- emojicon: "\u{1F600}"
24
- }, {
25
- value: 3,
26
- emojicon: "\u{1F610}"
27
- }, {
28
- value: 2,
29
- emojicon: "\u{1F615}"
30
- }, {
31
- value: 1,
32
- emojicon: "\u{1F61E}"
33
- }]
34
- };
35
- export {
36
- EmojiBased as default
37
- };
@@ -1,4 +0,0 @@
1
- import { default as default2 } from "./binary-thumb";
2
- export {
3
- default2 as BinaryThumb
4
- };