@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.
- package/lib/cjs/components/menu.js +3 -4
- package/lib/cjs/did-comment.js +14 -5
- package/lib/es/components/menu.js +1 -1
- package/lib/es/did-comment.js +16 -6
- package/package.json +3 -3
- package/lib/cjs/comment-list.js +0 -117
- package/lib/cjs/components/comment.js +0 -335
- package/lib/cjs/components/rating/binary-thumb.js +0 -199
- package/lib/cjs/components/rating/emoji-based.js +0 -39
- package/lib/cjs/components/rating/index.js +0 -9
- package/lib/cjs/components/rating/rating.js +0 -93
- package/lib/cjs/context.js +0 -77
- package/lib/cjs/hooks.js +0 -202
- package/lib/es/comment-list.js +0 -112
- package/lib/es/components/comment.js +0 -309
- package/lib/es/components/rating/binary-thumb.js +0 -176
- package/lib/es/components/rating/emoji-based.js +0 -37
- package/lib/es/components/rating/index.js +0 -4
- package/lib/es/components/rating/rating.js +0 -91
- package/lib/es/context.js +0 -74
- package/lib/es/hooks.js +0 -197
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
|
-
import useSetState from "react-use/lib/useSetState";
|
|
4
|
-
function Rating({
|
|
5
|
-
ratingType,
|
|
6
|
-
values,
|
|
7
|
-
countPerValue,
|
|
8
|
-
selected,
|
|
9
|
-
render,
|
|
10
|
-
onRate,
|
|
11
|
-
onUnrate
|
|
12
|
-
}) {
|
|
13
|
-
const [state, setState] = useSetState({
|
|
14
|
-
selected,
|
|
15
|
-
countPerValue
|
|
16
|
-
});
|
|
17
|
-
const hasSelected = !!state.selected || state.selected === 0;
|
|
18
|
-
const increaseCount = (value, inc) => {
|
|
19
|
-
setState((prevState) => ({
|
|
20
|
-
countPerValue: {
|
|
21
|
-
...prevState.countPerValue,
|
|
22
|
-
[value]: (prevState.countPerValue[value] || 0) + inc
|
|
23
|
-
}
|
|
24
|
-
}));
|
|
25
|
-
};
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
setState({
|
|
28
|
-
countPerValue,
|
|
29
|
-
selected
|
|
30
|
-
});
|
|
31
|
-
}, [countPerValue, selected]);
|
|
32
|
-
if (!render) {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
const options = values.map((value) => {
|
|
36
|
-
var _a;
|
|
37
|
-
return {
|
|
38
|
-
value,
|
|
39
|
-
count: ((_a = state.countPerValue) == null ? void 0 : _a[value]) || 0,
|
|
40
|
-
selected: state.selected === value
|
|
41
|
-
};
|
|
42
|
-
});
|
|
43
|
-
const toggleRate = async (value) => {
|
|
44
|
-
try {
|
|
45
|
-
if (state.selected === value) {
|
|
46
|
-
await onUnrate({
|
|
47
|
-
ratingType,
|
|
48
|
-
value
|
|
49
|
-
});
|
|
50
|
-
increaseCount(value, -1);
|
|
51
|
-
setState({
|
|
52
|
-
selected: null
|
|
53
|
-
});
|
|
54
|
-
} else {
|
|
55
|
-
await onRate({
|
|
56
|
-
ratingType,
|
|
57
|
-
value
|
|
58
|
-
});
|
|
59
|
-
if (hasSelected) {
|
|
60
|
-
increaseCount(state.selected, -1);
|
|
61
|
-
}
|
|
62
|
-
increaseCount(value, 1);
|
|
63
|
-
setState({
|
|
64
|
-
selected: value
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
} catch (e) {
|
|
68
|
-
console.error("Failed to rate.", e);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
return render({
|
|
72
|
-
options,
|
|
73
|
-
toggleRate
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
Rating.propTypes = {
|
|
77
|
-
ratingType: PropTypes.oneOf(["binary-thumb", "five-star", "emoji-based"]).isRequired,
|
|
78
|
-
values: PropTypes.arrayOf(PropTypes.number).isRequired,
|
|
79
|
-
countPerValue: PropTypes.object,
|
|
80
|
-
selected: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
81
|
-
render: PropTypes.func.isRequired,
|
|
82
|
-
onRate: PropTypes.func.isRequired,
|
|
83
|
-
onUnrate: PropTypes.func.isRequired
|
|
84
|
-
};
|
|
85
|
-
Rating.defaultProps = {
|
|
86
|
-
countPerValue: {},
|
|
87
|
-
selected: void 0
|
|
88
|
-
};
|
|
89
|
-
export {
|
|
90
|
-
Rating as default
|
|
91
|
-
};
|
package/lib/es/context.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, useEffect, useMemo } from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
|
-
import { SessionContext } from "@arcblock/did-connect/lib/Session";
|
|
4
|
-
import { useComments } from "./hooks";
|
|
5
|
-
import getWsClient from "./ws";
|
|
6
|
-
import { jsx } from "react/jsx-runtime";
|
|
7
|
-
const CommentsContext = createContext();
|
|
8
|
-
function CommentsProvider({
|
|
9
|
-
prefix,
|
|
10
|
-
session,
|
|
11
|
-
object,
|
|
12
|
-
manageMode,
|
|
13
|
-
flatMode,
|
|
14
|
-
children
|
|
15
|
-
}) {
|
|
16
|
-
var _a;
|
|
17
|
-
const sessionCtx = useContext(SessionContext);
|
|
18
|
-
const _session = session || (sessionCtx == null ? void 0 : sessionCtx.session);
|
|
19
|
-
const wsClient = getWsClient(prefix);
|
|
20
|
-
const commentsState = useComments({
|
|
21
|
-
objectId: object.id,
|
|
22
|
-
flatMode
|
|
23
|
-
}, [(_a = _session == null ? void 0 : _session.user) == null ? void 0 : _a.did]);
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
wsClient.connect();
|
|
26
|
-
return () => {
|
|
27
|
-
if (wsClient.isConnected()) {
|
|
28
|
-
wsClient.disconnect();
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
}, []);
|
|
32
|
-
const value = useMemo(
|
|
33
|
-
() => ({
|
|
34
|
-
session: _session,
|
|
35
|
-
object,
|
|
36
|
-
prefix,
|
|
37
|
-
manageMode,
|
|
38
|
-
flatMode,
|
|
39
|
-
...commentsState
|
|
40
|
-
}),
|
|
41
|
-
[_session, object, prefix, commentsState]
|
|
42
|
-
);
|
|
43
|
-
return /* @__PURE__ */ jsx(CommentsContext.Provider, {
|
|
44
|
-
value,
|
|
45
|
-
children
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
CommentsProvider.propTypes = {
|
|
49
|
-
prefix: PropTypes.string,
|
|
50
|
-
session: PropTypes.object,
|
|
51
|
-
object: PropTypes.PropTypes.shape({
|
|
52
|
-
id: PropTypes.string.isRequired,
|
|
53
|
-
title: PropTypes.string,
|
|
54
|
-
desc: PropTypes.string,
|
|
55
|
-
owner: PropTypes.string
|
|
56
|
-
}).isRequired,
|
|
57
|
-
manageMode: PropTypes.bool,
|
|
58
|
-
flatMode: PropTypes.bool,
|
|
59
|
-
children: PropTypes.any.isRequired
|
|
60
|
-
};
|
|
61
|
-
CommentsProvider.defaultProps = {
|
|
62
|
-
prefix: "",
|
|
63
|
-
session: void 0,
|
|
64
|
-
manageMode: false,
|
|
65
|
-
flatMode: false
|
|
66
|
-
};
|
|
67
|
-
const useCommentsContext = () => {
|
|
68
|
-
return useContext(CommentsContext);
|
|
69
|
-
};
|
|
70
|
-
export {
|
|
71
|
-
CommentsContext,
|
|
72
|
-
CommentsProvider,
|
|
73
|
-
useCommentsContext
|
|
74
|
-
};
|
package/lib/es/hooks.js
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { useMemo, useRef, useEffect } from "react";
|
|
2
|
-
import useSetState from "react-use/lib/useSetState";
|
|
3
|
-
import uniqBy from "lodash/uniqBy";
|
|
4
|
-
import orderBy from "lodash/orderBy";
|
|
5
|
-
import Toast from "@arcblock/ux/lib/Toast";
|
|
6
|
-
import { fetchRatingStats, fetchMoreReplies, fetchComments } from "./api";
|
|
7
|
-
import { useSubscription } from "./ws";
|
|
8
|
-
const lastItem = (arr) => (arr == null ? void 0 : arr.length) ? arr[arr.length - 1] : null;
|
|
9
|
-
const getInitialState = () => ({
|
|
10
|
-
comments: [],
|
|
11
|
-
cursor: null,
|
|
12
|
-
total: 0,
|
|
13
|
-
initialized: false,
|
|
14
|
-
loading: true,
|
|
15
|
-
error: null,
|
|
16
|
-
rating: {},
|
|
17
|
-
sortType: localStorage.getItem("sortType") || "asc"
|
|
18
|
-
});
|
|
19
|
-
const useComments = ({ objectId, flatMode }, deps = []) => {
|
|
20
|
-
const [state, setState] = useSetState(getInitialState());
|
|
21
|
-
const commentsKeyById = useMemo(() => {
|
|
22
|
-
return state.comments.reduce((acc, cur) => {
|
|
23
|
-
var _a;
|
|
24
|
-
acc[cur.id] = cur;
|
|
25
|
-
if ((_a = cur.replies) == null ? void 0 : _a.length) {
|
|
26
|
-
cur.replies.forEach((item) => {
|
|
27
|
-
acc[item.id] = item;
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
return acc;
|
|
31
|
-
}, {});
|
|
32
|
-
}, [state]);
|
|
33
|
-
const hasMore = useMemo(() => !!state.cursor, [state]);
|
|
34
|
-
const fetchParamsRef = useRef({
|
|
35
|
-
objectId,
|
|
36
|
-
size: 12,
|
|
37
|
-
embed: "replies,rating",
|
|
38
|
-
...flatMode && { includeReplies: 1 }
|
|
39
|
-
});
|
|
40
|
-
const updateCommentList = () => {
|
|
41
|
-
setState({ comments: [...state.comments] });
|
|
42
|
-
};
|
|
43
|
-
const updateComment = (commentId, mapper) => {
|
|
44
|
-
const commentOrReply = commentsKeyById[commentId];
|
|
45
|
-
if (commentOrReply) {
|
|
46
|
-
const rootComment = commentsKeyById[commentOrReply.commentId];
|
|
47
|
-
if (!rootComment || flatMode) {
|
|
48
|
-
const index = state.comments.findIndex((item) => item.id === commentId);
|
|
49
|
-
if (index !== -1) {
|
|
50
|
-
state.comments[index] = mapper(state.comments[index]);
|
|
51
|
-
updateCommentList();
|
|
52
|
-
}
|
|
53
|
-
} else {
|
|
54
|
-
const index = rootComment.replies.findIndex((item) => item.id === commentId);
|
|
55
|
-
if (index !== -1) {
|
|
56
|
-
rootComment.replies[index] = mapper(rootComment.replies[index]);
|
|
57
|
-
updateComment(rootComment.id, (current) => ({
|
|
58
|
-
...current,
|
|
59
|
-
replies: [...rootComment.replies]
|
|
60
|
-
}));
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
const addComment = (commentOrReply) => {
|
|
66
|
-
if (commentsKeyById[commentOrReply.id]) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const rootComment = commentsKeyById[commentOrReply.commentId];
|
|
70
|
-
if (!rootComment || flatMode) {
|
|
71
|
-
const comments = uniqBy([...state.comments, commentOrReply], "id");
|
|
72
|
-
setState({ comments: orderBy(comments, ["createdAt"], [state.sortType]), total: state.total + 1 });
|
|
73
|
-
} else {
|
|
74
|
-
updateComment(rootComment.id, (current) => {
|
|
75
|
-
var _a;
|
|
76
|
-
const replies = uniqBy([...rootComment.replies || [], commentOrReply], "id");
|
|
77
|
-
const newComment = {
|
|
78
|
-
...current,
|
|
79
|
-
replies: orderBy(replies, ["createdAt"], ["asc"]),
|
|
80
|
-
totalReplies: (current.totalReplies || 0) + 1
|
|
81
|
-
};
|
|
82
|
-
if (!current.repliesCursor) {
|
|
83
|
-
newComment.repliesCursor = (_a = lastItem(current.replies)) == null ? void 0 : _a.createdAt;
|
|
84
|
-
}
|
|
85
|
-
return newComment;
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
const removeComment = (comment) => {
|
|
90
|
-
const isReply = comment.commentId;
|
|
91
|
-
if (isReply && !flatMode) {
|
|
92
|
-
updateComment(comment.commentId, (current) => {
|
|
93
|
-
return {
|
|
94
|
-
...current,
|
|
95
|
-
replies: (current.replies || []).map((item) => {
|
|
96
|
-
if (item.id === comment.id) {
|
|
97
|
-
return { ...item, deletedAt: new Date() };
|
|
98
|
-
}
|
|
99
|
-
return item;
|
|
100
|
-
})
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
} else {
|
|
104
|
-
updateComment(comment.id, (current) => {
|
|
105
|
-
return { ...current, deletedAt: new Date() };
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
const handlers = {
|
|
110
|
-
ADD_COMMENT: (data) => addComment(data),
|
|
111
|
-
RATING: async () => {
|
|
112
|
-
const rating = await fetchRatingStats(objectId);
|
|
113
|
-
setState({ rating });
|
|
114
|
-
},
|
|
115
|
-
RATING_COMMENT: async ({ commentId }) => {
|
|
116
|
-
const rating = await fetchRatingStats(commentId);
|
|
117
|
-
updateComment(commentId, (current) => ({
|
|
118
|
-
...current,
|
|
119
|
-
rating
|
|
120
|
-
}));
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
useSubscription(
|
|
124
|
-
objectId,
|
|
125
|
-
({ event, data }) => {
|
|
126
|
-
var _a;
|
|
127
|
-
(_a = handlers[event]) == null ? void 0 : _a.call(handlers, data);
|
|
128
|
-
},
|
|
129
|
-
[objectId, state]
|
|
130
|
-
);
|
|
131
|
-
const fetch = async () => {
|
|
132
|
-
try {
|
|
133
|
-
setState({ loading: true });
|
|
134
|
-
return fetchComments({ ...fetchParamsRef.current, order: state.sortType, cursor: state.cursor });
|
|
135
|
-
} catch (e) {
|
|
136
|
-
Toast.warning("Failed to load comments data.");
|
|
137
|
-
setState({ error: e });
|
|
138
|
-
return { comments: [], total: 0, cursor: null };
|
|
139
|
-
} finally {
|
|
140
|
-
setState({ loading: false });
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
const loadMore = async () => {
|
|
144
|
-
if (hasMore) {
|
|
145
|
-
const { data: comments, total, nextCursor } = await fetch();
|
|
146
|
-
const sorted = orderBy([...state.comments, ...comments], ["createdAt"], [state.sortType]);
|
|
147
|
-
setState({ comments: sorted, total, cursor: nextCursor });
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
const loadMoreReplies = async (commentId) => {
|
|
151
|
-
var _a;
|
|
152
|
-
const rootComment = commentsKeyById[commentId];
|
|
153
|
-
const cursor = rootComment.repliesCursor || ((_a = lastItem(rootComment.replies)) == null ? void 0 : _a.createdAt);
|
|
154
|
-
const data = await fetchMoreReplies({
|
|
155
|
-
commentId,
|
|
156
|
-
cursor,
|
|
157
|
-
embed: "rating"
|
|
158
|
-
});
|
|
159
|
-
const loadedReplies = data.data;
|
|
160
|
-
let replies = uniqBy([...rootComment.replies || [], ...loadedReplies || []], "id");
|
|
161
|
-
replies = orderBy(replies, ["createdAt"], ["asc"]);
|
|
162
|
-
updateComment(commentId, (current) => {
|
|
163
|
-
var _a2;
|
|
164
|
-
return {
|
|
165
|
-
...current,
|
|
166
|
-
replies,
|
|
167
|
-
totalReplies: data.total,
|
|
168
|
-
repliesCursor: (_a2 = lastItem(loadedReplies)) == null ? void 0 : _a2.createdAt
|
|
169
|
-
};
|
|
170
|
-
});
|
|
171
|
-
};
|
|
172
|
-
const sort = (sortType) => {
|
|
173
|
-
setState({ sortType, cursor: null });
|
|
174
|
-
localStorage.setItem("sortType", sortType);
|
|
175
|
-
};
|
|
176
|
-
useEffect(() => {
|
|
177
|
-
const init = async () => {
|
|
178
|
-
setState({ ...getInitialState(), initialized: false });
|
|
179
|
-
const [{ data: comments, total, nextCursor }, rating] = await Promise.all([fetch(), fetchRatingStats(objectId)]);
|
|
180
|
-
setState({ comments, total, cursor: nextCursor, rating, initialized: true });
|
|
181
|
-
};
|
|
182
|
-
init();
|
|
183
|
-
}, [objectId, state.sortType, ...deps || []]);
|
|
184
|
-
return {
|
|
185
|
-
...state,
|
|
186
|
-
hasMore,
|
|
187
|
-
loadMore,
|
|
188
|
-
sort,
|
|
189
|
-
addComment,
|
|
190
|
-
updateComment,
|
|
191
|
-
loadMoreReplies,
|
|
192
|
-
removeComment
|
|
193
|
-
};
|
|
194
|
-
};
|
|
195
|
-
export {
|
|
196
|
-
useComments
|
|
197
|
-
};
|