@blocklet/discuss-kit 1.0.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/README.md +15 -0
- package/lib/cjs/api.js +45 -0
- package/lib/cjs/comment-list.js +117 -0
- package/lib/cjs/components/comment.js +335 -0
- package/lib/cjs/components/error-fallback.js +26 -0
- package/lib/cjs/components/menu.js +84 -0
- package/lib/cjs/components/rating/binary-thumb.js +199 -0
- package/lib/cjs/components/rating/emoji-based.js +39 -0
- package/lib/cjs/components/rating/index.js +9 -0
- package/lib/cjs/components/rating/rating.js +93 -0
- package/lib/cjs/context.js +77 -0
- package/lib/cjs/did-comment-with-session.js +25 -0
- package/lib/cjs/did-comment.js +389 -0
- package/lib/cjs/hooks.js +202 -0
- package/lib/cjs/index.js +21 -0
- package/lib/cjs/lib/utils.js +17 -0
- package/lib/cjs/locales/en.js +27 -0
- package/lib/cjs/locales/index.js +10 -0
- package/lib/cjs/locales/zh.js +27 -0
- package/lib/cjs/session.js +14 -0
- package/lib/cjs/theme-provider.js +48 -0
- package/lib/cjs/ws.js +39 -0
- package/lib/es/api.js +43 -0
- package/lib/es/comment-list.js +112 -0
- package/lib/es/components/comment.js +309 -0
- package/lib/es/components/error-fallback.js +23 -0
- package/lib/es/components/menu.js +77 -0
- package/lib/es/components/rating/binary-thumb.js +176 -0
- package/lib/es/components/rating/emoji-based.js +37 -0
- package/lib/es/components/rating/index.js +4 -0
- package/lib/es/components/rating/rating.js +91 -0
- package/lib/es/context.js +74 -0
- package/lib/es/did-comment-with-session.js +24 -0
- package/lib/es/did-comment.js +377 -0
- package/lib/es/hooks.js +197 -0
- package/lib/es/index.js +8 -0
- package/lib/es/lib/utils.js +17 -0
- package/lib/es/locales/en.js +26 -0
- package/lib/es/locales/index.js +7 -0
- package/lib/es/locales/zh.js +26 -0
- package/lib/es/session.js +14 -0
- package/lib/es/theme-provider.js +46 -0
- package/lib/es/ws.js +37 -0
- package/package.json +79 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const react = require("react");
|
|
3
|
+
const styled = require("@emotion/styled");
|
|
4
|
+
const joinUrl = require("url-join");
|
|
5
|
+
const PropTypes = require("prop-types");
|
|
6
|
+
const useAsyncRetry = require("react-use/lib/useAsyncRetry");
|
|
7
|
+
const SessionManager = require("@arcblock/did-connect/lib/SessionManager");
|
|
8
|
+
const Session = require("@arcblock/did-connect/lib/Session");
|
|
9
|
+
const Button = require("@arcblock/ux/lib/Button");
|
|
10
|
+
const Box = require("@mui/material/Box");
|
|
11
|
+
const CircularProgress = require("@mui/material/CircularProgress");
|
|
12
|
+
const ButtonGroup = require("@mui/material/ButtonGroup");
|
|
13
|
+
const context = require("@arcblock/ux/lib/Locale/context");
|
|
14
|
+
const reactErrorBoundary = require("react-error-boundary");
|
|
15
|
+
const discussKitUx = require("@blocklet/discuss-kit-ux");
|
|
16
|
+
const ErrorFallback = require("./components/error-fallback");
|
|
17
|
+
const locales = require("./locales");
|
|
18
|
+
const getWsClient = require("./ws");
|
|
19
|
+
const api = require("./api");
|
|
20
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
21
|
+
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
|
|
22
|
+
const styled__default = /* @__PURE__ */ _interopDefaultLegacy(styled);
|
|
23
|
+
const joinUrl__default = /* @__PURE__ */ _interopDefaultLegacy(joinUrl);
|
|
24
|
+
const PropTypes__default = /* @__PURE__ */ _interopDefaultLegacy(PropTypes);
|
|
25
|
+
const useAsyncRetry__default = /* @__PURE__ */ _interopDefaultLegacy(useAsyncRetry);
|
|
26
|
+
const SessionManager__default = /* @__PURE__ */ _interopDefaultLegacy(SessionManager);
|
|
27
|
+
const Button__default = /* @__PURE__ */ _interopDefaultLegacy(Button);
|
|
28
|
+
const Box__default = /* @__PURE__ */ _interopDefaultLegacy(Box);
|
|
29
|
+
const CircularProgress__default = /* @__PURE__ */ _interopDefaultLegacy(CircularProgress);
|
|
30
|
+
const ButtonGroup__default = /* @__PURE__ */ _interopDefaultLegacy(ButtonGroup);
|
|
31
|
+
const ErrorFallback__default = /* @__PURE__ */ _interopDefaultLegacy(ErrorFallback);
|
|
32
|
+
const getWsClient__default = /* @__PURE__ */ _interopDefaultLegacy(getWsClient);
|
|
33
|
+
const api__default = /* @__PURE__ */ _interopDefaultLegacy(api);
|
|
34
|
+
const getPrefix = () => {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
const service = (_b = (_a = window.blocklet) == null ? void 0 : _a.componentMountPoints) == null ? void 0 : _b.find((x) => x.name === "did-comments");
|
|
37
|
+
return service ? joinUrl__default.default(service.mountPoint, "/") : "";
|
|
38
|
+
};
|
|
39
|
+
const formatComment = (comment) => {
|
|
40
|
+
var _a;
|
|
41
|
+
return {
|
|
42
|
+
...comment,
|
|
43
|
+
rootId: comment.commentId,
|
|
44
|
+
author: comment.commenter,
|
|
45
|
+
createdAt: comment.createdAt ? new Date(comment.createdAt) : null,
|
|
46
|
+
updatedAt: comment.updatedAt ? new Date(comment.updatedAt) : null,
|
|
47
|
+
deletedAt: comment.deletedAt ? new Date(comment.deletedAt) : null,
|
|
48
|
+
replies: (_a = comment.replies) == null ? void 0 : _a.map(formatComment)
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const commentAPI = {
|
|
52
|
+
fetchComments: async (params) => {
|
|
53
|
+
const copy = {
|
|
54
|
+
...params,
|
|
55
|
+
embed: params.rootId ? "rating" : "replies,rating",
|
|
56
|
+
size: params.limit
|
|
57
|
+
};
|
|
58
|
+
const {
|
|
59
|
+
data: {
|
|
60
|
+
data,
|
|
61
|
+
nextCursor,
|
|
62
|
+
total
|
|
63
|
+
}
|
|
64
|
+
} = await api__default.default.get("/comments", {
|
|
65
|
+
params: copy
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
data: data == null ? void 0 : data.map(formatComment),
|
|
69
|
+
nextCursor,
|
|
70
|
+
total
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
fetchCommentPosition: async ({
|
|
74
|
+
id,
|
|
75
|
+
...params
|
|
76
|
+
}) => {
|
|
77
|
+
const {
|
|
78
|
+
data
|
|
79
|
+
} = await api__default.default.get(`/comments/${id}/position`, {
|
|
80
|
+
params
|
|
81
|
+
});
|
|
82
|
+
return data;
|
|
83
|
+
},
|
|
84
|
+
deleteComment: async ({
|
|
85
|
+
id
|
|
86
|
+
}) => {
|
|
87
|
+
const {
|
|
88
|
+
data
|
|
89
|
+
} = await api__default.default.delete(`/comments/${id}`);
|
|
90
|
+
return data;
|
|
91
|
+
},
|
|
92
|
+
updateComment: async ({
|
|
93
|
+
id
|
|
94
|
+
}, content) => {
|
|
95
|
+
await api__default.default.put(`/comments/${id}`, {
|
|
96
|
+
content
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
reply: async ({
|
|
100
|
+
id,
|
|
101
|
+
rootId
|
|
102
|
+
}, content) => {
|
|
103
|
+
const {
|
|
104
|
+
data
|
|
105
|
+
} = await api__default.default.post(`/comments/${rootId || id}/replies`, {
|
|
106
|
+
content,
|
|
107
|
+
parentId: id
|
|
108
|
+
});
|
|
109
|
+
return formatComment(data);
|
|
110
|
+
},
|
|
111
|
+
rate: async (comment, value, ratingType) => {
|
|
112
|
+
await api__default.default.post(`/objects/${comment.objectId}/comments/${comment.id}/ratings`, {
|
|
113
|
+
ratingType,
|
|
114
|
+
value
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
unrate: async (comment) => {
|
|
118
|
+
await api__default.default.delete(`/objects/${comment.objectId}/comments/${comment.id}/ratings`);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
function DIDComment({
|
|
122
|
+
showConnectBtn,
|
|
123
|
+
object,
|
|
124
|
+
onChange
|
|
125
|
+
}) {
|
|
126
|
+
const {
|
|
127
|
+
session
|
|
128
|
+
} = react.useContext(Session.SessionContext) || {};
|
|
129
|
+
const {
|
|
130
|
+
state,
|
|
131
|
+
sort,
|
|
132
|
+
add,
|
|
133
|
+
updateCommentState
|
|
134
|
+
} = discussKitUx.useCommentsContext();
|
|
135
|
+
const {
|
|
136
|
+
total,
|
|
137
|
+
order,
|
|
138
|
+
initialized
|
|
139
|
+
} = state;
|
|
140
|
+
const {
|
|
141
|
+
t
|
|
142
|
+
} = context.useLocaleContext();
|
|
143
|
+
const objectRatingState = useAsyncRetry__default.default(() => api.fetchRatingStats(object.id));
|
|
144
|
+
const handlers = {
|
|
145
|
+
ADD_COMMENT: (data) => add(formatComment(data)),
|
|
146
|
+
RATING: () => objectRatingState.retry(),
|
|
147
|
+
RATING_COMMENT: async ({
|
|
148
|
+
commentId
|
|
149
|
+
}) => {
|
|
150
|
+
const rating = await api.fetchRatingStats(commentId);
|
|
151
|
+
updateCommentState(commentId, (current) => ({
|
|
152
|
+
...current,
|
|
153
|
+
rating
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
getWsClient.useSubscription(object.id, ({
|
|
158
|
+
event,
|
|
159
|
+
data
|
|
160
|
+
}) => {
|
|
161
|
+
var _a;
|
|
162
|
+
(_a = handlers[event]) == null ? void 0 : _a.call(handlers, data);
|
|
163
|
+
}, [object.id, state]);
|
|
164
|
+
if (!initialized) {
|
|
165
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CircularProgress__default.default, {});
|
|
166
|
+
}
|
|
167
|
+
const sendComment = async (content) => {
|
|
168
|
+
const {
|
|
169
|
+
data
|
|
170
|
+
} = await api__default.default.post("/comments", {
|
|
171
|
+
content,
|
|
172
|
+
object
|
|
173
|
+
});
|
|
174
|
+
add(formatComment(data));
|
|
175
|
+
onChange();
|
|
176
|
+
};
|
|
177
|
+
const handleOnRate = async ({
|
|
178
|
+
ratingType,
|
|
179
|
+
value
|
|
180
|
+
}) => {
|
|
181
|
+
if (!session.user) {
|
|
182
|
+
session.login();
|
|
183
|
+
throw new Error("Unauthenticated.");
|
|
184
|
+
}
|
|
185
|
+
await api__default.default.post(`/objects/${object.id}/ratings`, {
|
|
186
|
+
ratingType,
|
|
187
|
+
value
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
const handleOnUnrate = async () => {
|
|
191
|
+
if (!session.user) {
|
|
192
|
+
session.login();
|
|
193
|
+
throw new Error("Unauthenticated.");
|
|
194
|
+
}
|
|
195
|
+
await api__default.default.delete(`/objects/${object.id}/ratings`);
|
|
196
|
+
};
|
|
197
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Container, {
|
|
198
|
+
children: [/* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
199
|
+
children: [/* @__PURE__ */ jsxRuntime.jsxs(Box__default.default, {
|
|
200
|
+
display: "flex",
|
|
201
|
+
justifyContent: "space-between",
|
|
202
|
+
alignItems: "center",
|
|
203
|
+
children: [/* @__PURE__ */ jsxRuntime.jsx(Box__default.default, {
|
|
204
|
+
mb: 1,
|
|
205
|
+
children: objectRatingState.value && /* @__PURE__ */ jsxRuntime.jsx(discussKitUx.BinaryThumb, {
|
|
206
|
+
selectedValue: objectRatingState.value.myRating,
|
|
207
|
+
countPerValue: objectRatingState.value.counts,
|
|
208
|
+
onRate: handleOnRate,
|
|
209
|
+
onUnrate: handleOnUnrate,
|
|
210
|
+
variant: "inverse",
|
|
211
|
+
size: "lg"
|
|
212
|
+
})
|
|
213
|
+
}), showConnectBtn && (session.user ? /* @__PURE__ */ jsxRuntime.jsx(SessionManager__default.default, {
|
|
214
|
+
style: {
|
|
215
|
+
padding: 0
|
|
216
|
+
},
|
|
217
|
+
showText: true,
|
|
218
|
+
showRole: true,
|
|
219
|
+
session
|
|
220
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(Button__default.default, {
|
|
221
|
+
size: "medium",
|
|
222
|
+
variant: "contained",
|
|
223
|
+
color: "primary",
|
|
224
|
+
onClick: () => session.login(),
|
|
225
|
+
children: t("connect")
|
|
226
|
+
})), !showConnectBtn && !session.user && /* @__PURE__ */ jsxRuntime.jsx(Button__default.default, {
|
|
227
|
+
size: "medium",
|
|
228
|
+
variant: "contained",
|
|
229
|
+
color: "primary",
|
|
230
|
+
onClick: () => session.login(),
|
|
231
|
+
children: t("connect")
|
|
232
|
+
})]
|
|
233
|
+
}), !session.user && /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
234
|
+
className: "input-no-connect",
|
|
235
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("span", {
|
|
236
|
+
className: "connect-tip",
|
|
237
|
+
children: [t("connectDIDWallet"), " ", /* @__PURE__ */ jsxRuntime.jsx("a", {
|
|
238
|
+
className: "down-load-wallet",
|
|
239
|
+
href: "https://www.didwallet.io/",
|
|
240
|
+
target: "_blank",
|
|
241
|
+
rel: "noreferrer",
|
|
242
|
+
children: t("installDIDWallet")
|
|
243
|
+
})]
|
|
244
|
+
})
|
|
245
|
+
}), session.user && /* @__PURE__ */ jsxRuntime.jsx(Box__default.default, {
|
|
246
|
+
mt: 2.5,
|
|
247
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(discussKitUx.CommentInput, {
|
|
248
|
+
send: sendComment
|
|
249
|
+
})
|
|
250
|
+
})]
|
|
251
|
+
}), !!total && /* @__PURE__ */ jsxRuntime.jsxs(Box__default.default, {
|
|
252
|
+
display: "flex",
|
|
253
|
+
justifyContent: "space-between",
|
|
254
|
+
mt: 4,
|
|
255
|
+
children: [/* @__PURE__ */ jsxRuntime.jsxs("span", {
|
|
256
|
+
children: [total > 0 ? `${total} ${t("comments")}` : t("comment"), " "]
|
|
257
|
+
}), /* @__PURE__ */ jsxRuntime.jsxs(ButtonGroup__default.default, {
|
|
258
|
+
children: [/* @__PURE__ */ jsxRuntime.jsx(Button__default.default, {
|
|
259
|
+
variant: "contained",
|
|
260
|
+
color: order !== "desc" ? "primary" : "inherit",
|
|
261
|
+
size: "small",
|
|
262
|
+
onClick: () => sort("asc"),
|
|
263
|
+
children: t("oldest")
|
|
264
|
+
}), /* @__PURE__ */ jsxRuntime.jsx(Button__default.default, {
|
|
265
|
+
variant: "contained",
|
|
266
|
+
color: order === "desc" ? "primary" : "inherit",
|
|
267
|
+
size: "small",
|
|
268
|
+
onClick: () => sort("desc"),
|
|
269
|
+
children: t("newest")
|
|
270
|
+
})]
|
|
271
|
+
})]
|
|
272
|
+
}), /* @__PURE__ */ jsxRuntime.jsx(discussKitUx.CommentList, {})]
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
DIDComment.propTypes = {
|
|
276
|
+
showConnectBtn: PropTypes__default.default.bool,
|
|
277
|
+
object: PropTypes__default.default.object.isRequired,
|
|
278
|
+
onChange: PropTypes__default.default.func
|
|
279
|
+
};
|
|
280
|
+
DIDComment.defaultProps = {
|
|
281
|
+
showConnectBtn: false,
|
|
282
|
+
onChange: () => {
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
function Wrapper({
|
|
286
|
+
target,
|
|
287
|
+
prefix,
|
|
288
|
+
flatView,
|
|
289
|
+
...rest
|
|
290
|
+
}) {
|
|
291
|
+
if (!(target == null ? void 0 : target.id)) {
|
|
292
|
+
throw new Error("target is required.");
|
|
293
|
+
}
|
|
294
|
+
const {
|
|
295
|
+
locale
|
|
296
|
+
} = context.useLocaleContext();
|
|
297
|
+
const object = react.useMemo(
|
|
298
|
+
() => ({
|
|
299
|
+
...target,
|
|
300
|
+
link: window.location.href
|
|
301
|
+
}),
|
|
302
|
+
[target]
|
|
303
|
+
);
|
|
304
|
+
const _prefix = prefix || getPrefix();
|
|
305
|
+
if (!_prefix) {
|
|
306
|
+
throw new Error("prefix is required.");
|
|
307
|
+
}
|
|
308
|
+
const wsClient = getWsClient__default.default(_prefix);
|
|
309
|
+
react.useEffect(() => {
|
|
310
|
+
wsClient.connect();
|
|
311
|
+
return () => {
|
|
312
|
+
if (wsClient.isConnected()) {
|
|
313
|
+
wsClient.disconnect();
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
}, []);
|
|
317
|
+
api__default.default.defaults.baseURL = joinUrl__default.default(_prefix, "/api/");
|
|
318
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactErrorBoundary.ErrorBoundary, {
|
|
319
|
+
FallbackComponent: ErrorFallback__default.default,
|
|
320
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(context.LocaleProvider, {
|
|
321
|
+
translations: locales.translations,
|
|
322
|
+
locale,
|
|
323
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(discussKitUx.InternalThemeProvider, {
|
|
324
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(discussKitUx.CommentsProvider, {
|
|
325
|
+
target: object,
|
|
326
|
+
api: commentAPI,
|
|
327
|
+
flatView,
|
|
328
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DIDComment, {
|
|
329
|
+
...rest,
|
|
330
|
+
object
|
|
331
|
+
})
|
|
332
|
+
})
|
|
333
|
+
})
|
|
334
|
+
})
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
Wrapper.propTypes = {
|
|
338
|
+
target: PropTypes__default.default.shape({
|
|
339
|
+
id: PropTypes__default.default.string.isRequired,
|
|
340
|
+
title: PropTypes__default.default.string,
|
|
341
|
+
desc: PropTypes__default.default.string,
|
|
342
|
+
owner: PropTypes__default.default.string
|
|
343
|
+
}).isRequired,
|
|
344
|
+
showConnectBtn: PropTypes__default.default.bool,
|
|
345
|
+
onChange: PropTypes__default.default.func,
|
|
346
|
+
prefix: PropTypes__default.default.string,
|
|
347
|
+
flatView: PropTypes__default.default.bool
|
|
348
|
+
};
|
|
349
|
+
Wrapper.defaultProps = {
|
|
350
|
+
showConnectBtn: false,
|
|
351
|
+
onChange: () => {
|
|
352
|
+
},
|
|
353
|
+
prefix: "",
|
|
354
|
+
flatView: false
|
|
355
|
+
};
|
|
356
|
+
const Container = styled__default.default.div`
|
|
357
|
+
background-color: #fff;
|
|
358
|
+
width: 100%;
|
|
359
|
+
margin: 0 auto;
|
|
360
|
+
box-sizing: border-box;
|
|
361
|
+
padding: ${(props) => props.padding ? "20px" : "0"};
|
|
362
|
+
color: #25292f;
|
|
363
|
+
border: ${(props) => props.border ? "1px solid rgb(208, 215, 222)" : "none"};
|
|
364
|
+
border-radius: 6px;
|
|
365
|
+
.input-no-connect {
|
|
366
|
+
margin: 24px 0 0 0;
|
|
367
|
+
display: flex;
|
|
368
|
+
font-size: 16px;
|
|
369
|
+
width: 100%;
|
|
370
|
+
text-align: start;
|
|
371
|
+
word-break: break-all;
|
|
372
|
+
flex-direction: column;
|
|
373
|
+
.connect-tip {
|
|
374
|
+
background: #f2f3f5;
|
|
375
|
+
padding: 10px;
|
|
376
|
+
border-radius: 4px;
|
|
377
|
+
box-sizing: border-box;
|
|
378
|
+
color: #c4c5ca;
|
|
379
|
+
margin-bottom: 10px;
|
|
380
|
+
}
|
|
381
|
+
.down-load-wallet {
|
|
382
|
+
color: #6bbdfe;
|
|
383
|
+
}
|
|
384
|
+
@media (max-width: 768px) {
|
|
385
|
+
font-size: 14px;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
`;
|
|
389
|
+
module.exports = Wrapper;
|
package/lib/cjs/hooks.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const react = require("react");
|
|
4
|
+
const useSetState = require("react-use/lib/useSetState");
|
|
5
|
+
const uniqBy = require("lodash/uniqBy");
|
|
6
|
+
const orderBy = require("lodash/orderBy");
|
|
7
|
+
const Toast = require("@arcblock/ux/lib/Toast");
|
|
8
|
+
const api = require("./api");
|
|
9
|
+
const ws = require("./ws");
|
|
10
|
+
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
|
|
11
|
+
const useSetState__default = /* @__PURE__ */ _interopDefaultLegacy(useSetState);
|
|
12
|
+
const uniqBy__default = /* @__PURE__ */ _interopDefaultLegacy(uniqBy);
|
|
13
|
+
const orderBy__default = /* @__PURE__ */ _interopDefaultLegacy(orderBy);
|
|
14
|
+
const Toast__default = /* @__PURE__ */ _interopDefaultLegacy(Toast);
|
|
15
|
+
const lastItem = (arr) => (arr == null ? void 0 : arr.length) ? arr[arr.length - 1] : null;
|
|
16
|
+
const getInitialState = () => ({
|
|
17
|
+
comments: [],
|
|
18
|
+
cursor: null,
|
|
19
|
+
total: 0,
|
|
20
|
+
initialized: false,
|
|
21
|
+
loading: true,
|
|
22
|
+
error: null,
|
|
23
|
+
rating: {},
|
|
24
|
+
sortType: localStorage.getItem("sortType") || "asc"
|
|
25
|
+
});
|
|
26
|
+
const useComments = ({ objectId, flatMode }, deps = []) => {
|
|
27
|
+
const [state, setState] = useSetState__default.default(getInitialState());
|
|
28
|
+
const commentsKeyById = react.useMemo(() => {
|
|
29
|
+
return state.comments.reduce((acc, cur) => {
|
|
30
|
+
var _a;
|
|
31
|
+
acc[cur.id] = cur;
|
|
32
|
+
if ((_a = cur.replies) == null ? void 0 : _a.length) {
|
|
33
|
+
cur.replies.forEach((item) => {
|
|
34
|
+
acc[item.id] = item;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return acc;
|
|
38
|
+
}, {});
|
|
39
|
+
}, [state]);
|
|
40
|
+
const hasMore = react.useMemo(() => !!state.cursor, [state]);
|
|
41
|
+
const fetchParamsRef = react.useRef({
|
|
42
|
+
objectId,
|
|
43
|
+
size: 12,
|
|
44
|
+
embed: "replies,rating",
|
|
45
|
+
...flatMode && { includeReplies: 1 }
|
|
46
|
+
});
|
|
47
|
+
const updateCommentList = () => {
|
|
48
|
+
setState({ comments: [...state.comments] });
|
|
49
|
+
};
|
|
50
|
+
const updateComment = (commentId, mapper) => {
|
|
51
|
+
const commentOrReply = commentsKeyById[commentId];
|
|
52
|
+
if (commentOrReply) {
|
|
53
|
+
const rootComment = commentsKeyById[commentOrReply.commentId];
|
|
54
|
+
if (!rootComment || flatMode) {
|
|
55
|
+
const index = state.comments.findIndex((item) => item.id === commentId);
|
|
56
|
+
if (index !== -1) {
|
|
57
|
+
state.comments[index] = mapper(state.comments[index]);
|
|
58
|
+
updateCommentList();
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
const index = rootComment.replies.findIndex((item) => item.id === commentId);
|
|
62
|
+
if (index !== -1) {
|
|
63
|
+
rootComment.replies[index] = mapper(rootComment.replies[index]);
|
|
64
|
+
updateComment(rootComment.id, (current) => ({
|
|
65
|
+
...current,
|
|
66
|
+
replies: [...rootComment.replies]
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const addComment = (commentOrReply) => {
|
|
73
|
+
if (commentsKeyById[commentOrReply.id]) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const rootComment = commentsKeyById[commentOrReply.commentId];
|
|
77
|
+
if (!rootComment || flatMode) {
|
|
78
|
+
const comments = uniqBy__default.default([...state.comments, commentOrReply], "id");
|
|
79
|
+
setState({ comments: orderBy__default.default(comments, ["createdAt"], [state.sortType]), total: state.total + 1 });
|
|
80
|
+
} else {
|
|
81
|
+
updateComment(rootComment.id, (current) => {
|
|
82
|
+
var _a;
|
|
83
|
+
const replies = uniqBy__default.default([...rootComment.replies || [], commentOrReply], "id");
|
|
84
|
+
const newComment = {
|
|
85
|
+
...current,
|
|
86
|
+
replies: orderBy__default.default(replies, ["createdAt"], ["asc"]),
|
|
87
|
+
totalReplies: (current.totalReplies || 0) + 1
|
|
88
|
+
};
|
|
89
|
+
if (!current.repliesCursor) {
|
|
90
|
+
newComment.repliesCursor = (_a = lastItem(current.replies)) == null ? void 0 : _a.createdAt;
|
|
91
|
+
}
|
|
92
|
+
return newComment;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const removeComment = (comment) => {
|
|
97
|
+
const isReply = comment.commentId;
|
|
98
|
+
if (isReply && !flatMode) {
|
|
99
|
+
updateComment(comment.commentId, (current) => {
|
|
100
|
+
return {
|
|
101
|
+
...current,
|
|
102
|
+
replies: (current.replies || []).map((item) => {
|
|
103
|
+
if (item.id === comment.id) {
|
|
104
|
+
return { ...item, deletedAt: new Date() };
|
|
105
|
+
}
|
|
106
|
+
return item;
|
|
107
|
+
})
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
updateComment(comment.id, (current) => {
|
|
112
|
+
return { ...current, deletedAt: new Date() };
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const handlers = {
|
|
117
|
+
ADD_COMMENT: (data) => addComment(data),
|
|
118
|
+
RATING: async () => {
|
|
119
|
+
const rating = await api.fetchRatingStats(objectId);
|
|
120
|
+
setState({ rating });
|
|
121
|
+
},
|
|
122
|
+
RATING_COMMENT: async ({ commentId }) => {
|
|
123
|
+
const rating = await api.fetchRatingStats(commentId);
|
|
124
|
+
updateComment(commentId, (current) => ({
|
|
125
|
+
...current,
|
|
126
|
+
rating
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
ws.useSubscription(
|
|
131
|
+
objectId,
|
|
132
|
+
({ event, data }) => {
|
|
133
|
+
var _a;
|
|
134
|
+
(_a = handlers[event]) == null ? void 0 : _a.call(handlers, data);
|
|
135
|
+
},
|
|
136
|
+
[objectId, state]
|
|
137
|
+
);
|
|
138
|
+
const fetch = async () => {
|
|
139
|
+
try {
|
|
140
|
+
setState({ loading: true });
|
|
141
|
+
return api.fetchComments({ ...fetchParamsRef.current, order: state.sortType, cursor: state.cursor });
|
|
142
|
+
} catch (e) {
|
|
143
|
+
Toast__default.default.warning("Failed to load comments data.");
|
|
144
|
+
setState({ error: e });
|
|
145
|
+
return { comments: [], total: 0, cursor: null };
|
|
146
|
+
} finally {
|
|
147
|
+
setState({ loading: false });
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
const loadMore = async () => {
|
|
151
|
+
if (hasMore) {
|
|
152
|
+
const { data: comments, total, nextCursor } = await fetch();
|
|
153
|
+
const sorted = orderBy__default.default([...state.comments, ...comments], ["createdAt"], [state.sortType]);
|
|
154
|
+
setState({ comments: sorted, total, cursor: nextCursor });
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const loadMoreReplies = async (commentId) => {
|
|
158
|
+
var _a;
|
|
159
|
+
const rootComment = commentsKeyById[commentId];
|
|
160
|
+
const cursor = rootComment.repliesCursor || ((_a = lastItem(rootComment.replies)) == null ? void 0 : _a.createdAt);
|
|
161
|
+
const data = await api.fetchMoreReplies({
|
|
162
|
+
commentId,
|
|
163
|
+
cursor,
|
|
164
|
+
embed: "rating"
|
|
165
|
+
});
|
|
166
|
+
const loadedReplies = data.data;
|
|
167
|
+
let replies = uniqBy__default.default([...rootComment.replies || [], ...loadedReplies || []], "id");
|
|
168
|
+
replies = orderBy__default.default(replies, ["createdAt"], ["asc"]);
|
|
169
|
+
updateComment(commentId, (current) => {
|
|
170
|
+
var _a2;
|
|
171
|
+
return {
|
|
172
|
+
...current,
|
|
173
|
+
replies,
|
|
174
|
+
totalReplies: data.total,
|
|
175
|
+
repliesCursor: (_a2 = lastItem(loadedReplies)) == null ? void 0 : _a2.createdAt
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
const sort = (sortType) => {
|
|
180
|
+
setState({ sortType, cursor: null });
|
|
181
|
+
localStorage.setItem("sortType", sortType);
|
|
182
|
+
};
|
|
183
|
+
react.useEffect(() => {
|
|
184
|
+
const init = async () => {
|
|
185
|
+
setState({ ...getInitialState(), initialized: false });
|
|
186
|
+
const [{ data: comments, total, nextCursor }, rating] = await Promise.all([fetch(), api.fetchRatingStats(objectId)]);
|
|
187
|
+
setState({ comments, total, cursor: nextCursor, rating, initialized: true });
|
|
188
|
+
};
|
|
189
|
+
init();
|
|
190
|
+
}, [objectId, state.sortType, ...deps || []]);
|
|
191
|
+
return {
|
|
192
|
+
...state,
|
|
193
|
+
hasMore,
|
|
194
|
+
loadMore,
|
|
195
|
+
sort,
|
|
196
|
+
addComment,
|
|
197
|
+
updateComment,
|
|
198
|
+
loadMoreReplies,
|
|
199
|
+
removeComment
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
exports.useComments = useComments;
|
package/lib/cjs/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const didComment = require("./did-comment");
|
|
4
|
+
const didCommentWithSession = require("./did-comment-with-session");
|
|
5
|
+
const themeProvider = require("./theme-provider");
|
|
6
|
+
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
|
|
7
|
+
const didComment__default = /* @__PURE__ */ _interopDefaultLegacy(didComment);
|
|
8
|
+
const didCommentWithSession__default = /* @__PURE__ */ _interopDefaultLegacy(didCommentWithSession);
|
|
9
|
+
const themeProvider__default = /* @__PURE__ */ _interopDefaultLegacy(themeProvider);
|
|
10
|
+
Object.defineProperty(exports, "DIDComment", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: () => didComment__default.default
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(exports, "DIDCommentWithSession", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: () => didCommentWithSession__default.default
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "ThemeProvider", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: () => themeProvider__default.default
|
|
21
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const protectLogin = (session, action) => {
|
|
4
|
+
if (session.user) {
|
|
5
|
+
return action();
|
|
6
|
+
}
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
session.login(() => resolve(action()));
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
12
|
+
const minDelay = (promise, ms) => {
|
|
13
|
+
return Promise.all([promise, sleep(ms)]).then(([result]) => result);
|
|
14
|
+
};
|
|
15
|
+
exports.minDelay = minDelay;
|
|
16
|
+
exports.protectLogin = protectLogin;
|
|
17
|
+
exports.sleep = sleep;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const flat = require("flat");
|
|
3
|
+
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
|
|
4
|
+
const flat__default = /* @__PURE__ */ _interopDefaultLegacy(flat);
|
|
5
|
+
const en = flat__default.default({
|
|
6
|
+
comments: "Comments",
|
|
7
|
+
comment: "Comment",
|
|
8
|
+
poweredBy: "- powered by DID Comments",
|
|
9
|
+
connect: "Connect",
|
|
10
|
+
inputPlaceHolder: "Write a comment",
|
|
11
|
+
oldest: "Oldest",
|
|
12
|
+
newest: "Newest",
|
|
13
|
+
loadMore: "Click To Load More",
|
|
14
|
+
connectDIDWallet: "Please connect DID Wallet.",
|
|
15
|
+
installDIDWallet: "Click to get your own DID Wallet\u2192",
|
|
16
|
+
empty: "Be the first to leave a comment.",
|
|
17
|
+
delete: "Delete",
|
|
18
|
+
edit: "Edit",
|
|
19
|
+
confirm: "Confirm",
|
|
20
|
+
cancel: "Cancel",
|
|
21
|
+
tip: "Tip",
|
|
22
|
+
deleteCommentDesc: "Confirm delete this comment?",
|
|
23
|
+
readMore: "Read more",
|
|
24
|
+
showMoreReplies: "Show more replies",
|
|
25
|
+
deleted: "This comment has been deleted"
|
|
26
|
+
});
|
|
27
|
+
module.exports = en;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const discussKitUx = require("@blocklet/discuss-kit-ux");
|
|
4
|
+
const en = require("./en");
|
|
5
|
+
const zh = require("./zh");
|
|
6
|
+
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
|
|
7
|
+
const en__default = /* @__PURE__ */ _interopDefaultLegacy(en);
|
|
8
|
+
const zh__default = /* @__PURE__ */ _interopDefaultLegacy(zh);
|
|
9
|
+
const translations = { zh: { ...zh__default.default, ...discussKitUx.translations.zh }, en: { ...en__default.default, ...discussKitUx.translations.en } };
|
|
10
|
+
exports.translations = translations;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const flat = require("flat");
|
|
3
|
+
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
|
|
4
|
+
const flat__default = /* @__PURE__ */ _interopDefaultLegacy(flat);
|
|
5
|
+
const zh = flat__default.default({
|
|
6
|
+
comments: "\u6761\u8BC4\u8BBA",
|
|
7
|
+
comment: "\u8BC4\u8BBA",
|
|
8
|
+
poweredBy: "- \u7531 DID Comments \u63D0\u4F9B\u652F\u6301",
|
|
9
|
+
connect: "\u8FDE\u63A5",
|
|
10
|
+
inputPlaceHolder: "\u5199\u8BC4\u8BBA",
|
|
11
|
+
oldest: "\u6700\u65E7",
|
|
12
|
+
newest: "\u6700\u65B0",
|
|
13
|
+
loadMore: "\u70B9\u51FB\u52A0\u8F7D\u66F4\u591A",
|
|
14
|
+
connectDIDWallet: "\u8BF7\u5148\u8FDE\u63A5 DID Wallet.",
|
|
15
|
+
installDIDWallet: "\u70B9\u51FB\u62E5\u6709\u4F60\u7684 DID Wallet\u2192",
|
|
16
|
+
empty: "\u6210\u4E3A\u7B2C\u4E00\u4E2A\u7559\u4E0B\u8BC4\u8BBA\u7684\u4EBA.",
|
|
17
|
+
delete: "\u5220\u9664",
|
|
18
|
+
edit: "\u7F16\u8F91",
|
|
19
|
+
confirm: "\u786E\u8BA4",
|
|
20
|
+
cancel: "\u53D6\u6D88",
|
|
21
|
+
tip: "\u63D0\u793A",
|
|
22
|
+
deleteCommentDesc: "\u786E\u8BA4\u5220\u9664\u8FD9\u6761\u8BC4\u8BBA?",
|
|
23
|
+
readMore: "\u66F4\u591A\u5185\u5BB9",
|
|
24
|
+
showMoreReplies: "\u663E\u793A\u66F4\u591A\u56DE\u590D",
|
|
25
|
+
deleted: "\u8BE5\u8BC4\u8BBA\u5DF2\u88AB\u5220\u9664"
|
|
26
|
+
});
|
|
27
|
+
module.exports = zh;
|