@blocklet/discuss-kit 1.0.6 → 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,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
- };